[cfe-commits] r150238 - in /cfe/trunk: lib/CodeGen/CGCall.cpp test/CodeGen/arm-arguments.c

Evgeniy Stepanov eugeni.stepanov at gmail.com
Fri Feb 10 01:30:15 PST 2012


Author: eugenis
Date: Fri Feb 10 03:30:15 2012
New Revision: 150238

URL: http://llvm.org/viewvc/llvm-project?rev=150238&view=rev
Log:
Fix function prolog codegen whe coerce-to type is a struct.

This changes function prolog in such a way as to avoid out-of-bounds
stack store in the case when coerce-to type has a larger storage size
than the real argument type.

Fixes PR11905.


Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/test/CodeGen/arm-arguments.c

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=150238&r1=150237&r2=150238&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Feb 10 03:30:15 2012
@@ -1013,7 +1013,7 @@
         break;
       }
 
-      llvm::AllocaInst *Alloca = CreateMemTemp(Ty, "coerce");
+      llvm::AllocaInst *Alloca = CreateMemTemp(Ty, Arg->getName());
 
       // The alignment we need to use is the max of the requested alignment for
       // the argument plus the alignment required by our access code below.
@@ -1037,15 +1037,36 @@
       // If the coerce-to type is a first class aggregate, we flatten it and
       // pass the elements. Either way is semantically identical, but fast-isel
       // and the optimizer generally likes scalar values better than FCAs.
-      if (llvm::StructType *STy =
-            dyn_cast<llvm::StructType>(ArgI.getCoerceToType())) {
-        Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy));
+      llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
+      if (STy && STy->getNumElements() > 1) {
+        uint64_t SrcSize = CGM.getTargetData().getTypeAllocSize(STy);
+        llvm::Type *DstTy =
+          cast<llvm::PointerType>(Ptr->getType())->getElementType();
+        uint64_t DstSize = CGM.getTargetData().getTypeAllocSize(DstTy);
+
+        if (SrcSize <= DstSize) {
+          Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy));
+
+          for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+            assert(AI != Fn->arg_end() && "Argument mismatch!");
+            AI->setName(Arg->getName() + ".coerce" + Twine(i));
+            llvm::Value *EltPtr = Builder.CreateConstGEP2_32(Ptr, 0, i);
+            Builder.CreateStore(AI++, EltPtr);
+          }
+        } else {
+          llvm::AllocaInst *TempAlloca =
+            CreateTempAlloca(ArgI.getCoerceToType(), "coerce");
+          TempAlloca->setAlignment(AlignmentToUse);
+          llvm::Value *TempV = TempAlloca;
+
+          for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+            assert(AI != Fn->arg_end() && "Argument mismatch!");
+            AI->setName(Arg->getName() + ".coerce" + Twine(i));
+            llvm::Value *EltPtr = Builder.CreateConstGEP2_32(TempV, 0, i);
+            Builder.CreateStore(AI++, EltPtr);
+          }
 
-        for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-          assert(AI != Fn->arg_end() && "Argument mismatch!");
-          AI->setName(Arg->getName() + ".coerce" + Twine(i));
-          llvm::Value *EltPtr = Builder.CreateConstGEP2_32(Ptr, 0, i);
-          Builder.CreateStore(AI++, EltPtr);
+          Builder.CreateMemCpy(Ptr, TempV, DstSize, AlignmentToUse);
         }
       } else {
         // Simple case, just do a coerced store of the argument into the alloca.

Modified: cfe/trunk/test/CodeGen/arm-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-arguments.c?rev=150238&r1=150237&r2=150238&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-arguments.c (original)
+++ cfe/trunk/test/CodeGen/arm-arguments.c Fri Feb 10 03:30:15 2012
@@ -153,3 +153,15 @@
 // AAPCS: define arm_aapcscc void @f30({{.*}} noalias sret
 struct s30 { _Complex int f0; };
 struct s30 f30() {}
+
+// PR11905
+struct s31 { char x; };
+void f31(struct s31 s) { }
+// AAPCS: @f31([1 x i32] %s.coerce)
+// AAPCS: %s = alloca %struct.s31, align 4
+// AAPCS: %tmp = alloca [1 x i32]
+// AAPCS: store [1 x i32] %s.coerce, [1 x i32]* %tmp
+// APCS-GNU: @f31([1 x i32] %s.coerce)
+// APCS-GNU: %s = alloca %struct.s31, align 4
+// APCS-GNU: %tmp = alloca [1 x i32]
+// APCS-GNU: store [1 x i32] %s.coerce, [1 x i32]* %tmp





More information about the cfe-commits mailing list