]> granicus.if.org Git - clang/commitdiff
Merging r261422:
authorHans Wennborg <hans@hanshq.net>
Mon, 22 Feb 2016 18:48:10 +0000 (18:48 +0000)
committerHans Wennborg <hans@hanshq.net>
Mon, 22 Feb 2016 18:48:10 +0000 (18:48 +0000)
------------------------------------------------------------------------
r261422 | rdivacky | 2016-02-20 00:31:24 -0800 (Sat, 20 Feb 2016) | 10 lines

Fix handling of vaargs on PPC32 when going from regsave to overflow.

It can happen that when we only have 1 more register left in the regsave
area we need to store a value bigger than 1 register and therefore we
go to the overflow area. In this case we have to leave the last slot
in the regsave area unused and keep using overflow area. Do this
by storing a limit value to the used register counter in the overflow block.

Issue diagnosed by and solution tested by Mark Millard!

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_38@261553 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TargetInfo.cpp
test/CodeGen/ppc-varargs-struct.c

index cdb325f256f2f85c184ef72d7aacb47af34e47c5..3d1ddef94657a97f9c5f0de55c3ba9dc075d78d6 100644 (file)
@@ -3475,6 +3475,7 @@ public:
 
 Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
                                       QualType Ty) const {
+  const unsigned OverflowLimit = 8;
   if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
     // TODO: Implement this. For now ignore.
     (void)CTy;
@@ -3517,7 +3518,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
   }
 
   llvm::Value *CC =
-      Builder.CreateICmpULT(NumRegs, Builder.getInt8(8), "cond");
+      Builder.CreateICmpULT(NumRegs, Builder.getInt8(OverflowLimit), "cond");
 
   llvm::BasicBlock *UsingRegs = CGF.createBasicBlock("using_regs");
   llvm::BasicBlock *UsingOverflow = CGF.createBasicBlock("using_overflow");
@@ -3569,6 +3570,8 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
   {
     CGF.EmitBlock(UsingOverflow);
 
+    Builder.CreateStore(Builder.getInt8(OverflowLimit), NumRegsAddr);
+
     // Everything in the overflow area is rounded up to a size of at least 4.
     CharUnits OverflowAreaAlign = CharUnits::fromQuantity(4);
 
index 1ad57c26b48535d498cfbccd8ab2be4e65a95e4b..d7936a1269606c74ad3ec16d903a951572a8bcd2 100644 (file)
@@ -37,6 +37,7 @@ void testva (int n, ...)
 // CHECK-PPC-NEXT:  br label %[[CONT:[a-z0-9]+]]
 //
 // CHECK-PPC:[[USING_OVERFLOW]]
+// CHECK-PPC-NEXT:  store i8 8, i8* [[GPRPTR]], align 4
 // CHECK-PPC-NEXT:  [[OVERFLOW_AREA_P:%[0-9]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* [[ARRAYDECAY]], i32 0, i32 3
 // CHECK-PPC-NEXT:  [[OVERFLOW_AREA:%.+]] = load i8*, i8** [[OVERFLOW_AREA_P]], align 4
 // CHECK-PPC-NEXT:  %{{[0-9]+}} =  ptrtoint i8* %argp.cur to i32
@@ -76,6 +77,7 @@ void testva (int n, ...)
 // CHECK-PPC-NEXT:  br label %[[CONT:[a-z0-9]+]]
 //
 // CHECK-PPC:[[USING_OVERFLOW]]
+// CHECK-PPC-NEXT:  store i8 8, i8* [[GPRPTR]], align 4
 // CHECK-PPC-NEXT:  [[OVERFLOW_AREA_P:%[0-9]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* [[ARRAYDECAY]], i32 0, i32 3
 // CHECK-PPC-NEXT:  [[OVERFLOW_AREA:%.+]] = load i8*, i8** [[OVERFLOW_AREA_P]], align 4
 // CHECK-PPC-NEXT:  [[MEMADDR:%.+]] = bitcast i8* [[OVERFLOW_AREA]] to i32*