[llvm-commits] [llvm-gcc-4.2] r50539 - in /llvm-gcc-4.2/branches/Apple/Tak/gcc: config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp llvm-abi.h llvm-convert.cpp llvm-types.cpp

Devang Patel dpatel at apple.com
Thu May 1 14:15:57 PDT 2008


Author: dpatel
Date: Thu May  1 16:15:57 2008
New Revision: 50539

URL: http://llvm.org/viewvc/llvm-project?rev=50539&view=rev
Log:
Do not acess extra bytes when struct is passed in multiple registers. This can happen when a struct does not occupy all bytes, for example 12 byte struct is passed using two i64s.

This patch fixes reamining failues in abi-x86_64 tests on darwin target.

Modified:
    llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386-target.h
    llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386.cpp
    llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-abi.h
    llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-convert.cpp
    llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386-target.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386-target.h?rev=50539&r1=50538&r2=50539&view=diff

==============================================================================
--- llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386-target.h (original)
+++ llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386-target.h Thu May  1 16:15:57 2008
@@ -178,6 +178,24 @@
    llvm_x86_64_aggregate_partially_passed_in_regs((E), (SE)) : \
    false)
 
+/* llvm_store_scalar_argument - Store scalar argument ARGVAL of type
+   LLVMTY at location LOC.  */
+extern void llvm_x86_store_scalar_argument(Value *Loc, Value *ArgVal,
+                                           const llvm::Type *LLVMTy,
+                                           unsigned RealSize,
+                                           IRBuilder &Builder);
+#define LLVM_STORE_SCALAR_ARGUMENT(LOC,ARG,TYPE,SIZE,BUILDER)   \
+  llvm_x86_store_scalar_argument((LOC),(ARG),(TYPE),(SIZE),(BUILDER))
+
+
+/* llvm_load_scalar_argument - Load value located at LOC. */
+extern Value *llvm_x86_load_scalar_argument(Value *L,
+                                            const llvm::Type *LLVMTy,
+                                            unsigned RealSize,
+                                            IRBuilder &Builder);
+#define LLVM_LOAD_SCALAR_ARGUMENT(LOC,TY,SIZE,BUILDER) \
+  llvm_x86_load_scalar_argument((LOC),(TY),(SIZE),(BUILDER))
+
 #endif /* LLVM_ABI_H */
 
 /* LLVM LOCAL end (ENTIRE FILE!)  */

Modified: llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386.cpp?rev=50539&r1=50538&r2=50539&view=diff

==============================================================================
--- llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/branches/Apple/Tak/gcc/config/i386/llvm-i386.cpp Thu May  1 16:15:57 2008
@@ -1346,4 +1346,52 @@
     ++DNO;
   }
 }
+
+/// llvm_store_scalar_argument - Store scalar argument ARGVAL of type
+/// LLVMTY at location LOC.
+void llvm_x86_store_scalar_argument(Value *Loc, Value *ArgVal,
+                                const llvm::Type *LLVMTy,
+                                unsigned RealSize,
+                                IRBuilder &Builder) {
+  if (RealSize) {
+    // Do byte wise store because actaul argument type does not match LLVMTy.
+    Loc = Builder.CreateBitCast(Loc, 
+                                PointerType::getUnqual(llvm::Type::Int8Ty), "bc");
+    Value *ShAmt = ConstantInt::get(LLVMTy, 8);
+    for (unsigned i = 0; i < RealSize; ++i) {
+      Value *AVT = Builder.CreateTrunc(ArgVal, llvm::Type::Int8Ty, "byte");
+      Builder.CreateStore(AVT, Loc);
+      ArgVal = Builder.CreateLShr(ArgVal, ShAmt, "shft");
+      Loc = Builder.CreateGEP(Loc, ConstantInt::get(llvm::Type::Int32Ty, 1), 
+                              "Loc");
+    }
+  } else {
+    // This cast only involves pointers, therefore BitCast.
+    Loc = Builder.CreateBitCast(Loc, PointerType::getUnqual(LLVMTy), "tmp");
+    Builder.CreateStore(ArgVal, Loc);
+  }
+}
+
+/// llvm_load_scalar_argument - Load value located at LOC.
+Value *llvm_x86_load_scalar_argument(Value *L,
+                                     const llvm::Type *LLVMTy,
+                                     unsigned RealSize,
+                                     IRBuilder &Builder) {
+  Value *Loc = NULL;
+  L = Builder.CreateBitCast(L, PointerType::getUnqual(llvm::Type::Int8Ty), "bc");
+  // Load eacy byte individually.
+  for (unsigned i = 0; i < RealSize; ++i) {
+    Value *V = Builder.CreateLoad(L, "val");
+    Value *V2 = Builder.CreateZExt(V, LLVMTy);
+    if (Loc == NULL)
+      Loc = V2;
+    else {
+      Value *ShAmt = ConstantInt::get(LLVMTy, 8*i);
+      Loc = Builder.CreateOr(Loc, Builder.CreateShl(V2, ShAmt, "shl"), "loc");
+    }
+    L = Builder.CreateGEP(L, ConstantInt::get(llvm::Type::Int32Ty, 1), "gep");
+  }
+  return Loc;
+}
+
 /* LLVM LOCAL end (ENTIRE FILE!)  */

Modified: llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-abi.h?rev=50539&r1=50538&r2=50539&view=diff

==============================================================================
--- llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-abi.h Thu May  1 16:15:57 2008
@@ -79,7 +79,10 @@
 
   /// HandleScalarArgument - This is the primary callback that specifies an
   /// LLVM argument to pass.  It is only used for first class types.
-  void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) {}
+  /// If RealSize is non Zero then it specifies number of bytes to access
+  /// from LLVMTy. 
+  void HandleScalarArgument(const llvm::Type *LLVMTy, tree type,
+                            unsigned RealSize = 0) {}
 
   /// HandleByInvisibleReferenceArgument - This callback is invoked if a pointer
   /// (of type PtrTy) to the argument is passed rather than the argument itself.
@@ -589,9 +592,27 @@
                             std::vector<const Type*> &Elts,
                             std::vector<const Type*> &ScalarElts) {
     const StructType *STy = StructType::get(Elts, false);
+    unsigned Size = getTargetData().getABITypeSize(STy);
+    const StructType *InSTy = dyn_cast<StructType>(Ty);
+    unsigned InSize = 0;
+    // If Ty and STy size does not match then last element is accessing
+    // extra bits.
+    unsigned LastEltSizeDiff = 0;
+    if (InSTy) {
+      InSize = getTargetData().getABITypeSize(InSTy);
+      if (InSize < Size) {
+        unsigned N = STy->getNumElements();
+        const llvm::Type *LastEltTy = STy->getElementType(N-1);
+        LastEltSizeDiff = 
+          getTargetData().getABITypeSize(LastEltTy) - (Size - InSize);
+      }
+    }
     for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
       C.EnterField(i, STy);
-      C.HandleScalarArgument(Elts[i], 0);
+      unsigned RealSize = 0;
+      if (LastEltSizeDiff && i == (e - 1))
+        RealSize = LastEltSizeDiff;
+      C.HandleScalarArgument(Elts[i], 0, RealSize);
       ScalarElts.push_back(Elts[i]);
       C.ExitField();
     }

Modified: llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-convert.cpp?rev=50539&r1=50538&r2=50539&view=diff

==============================================================================
--- llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-convert.cpp Thu May  1 16:15:57 2008
@@ -398,6 +398,24 @@
   return NewBB;
 }
 
+/// llvm_store_scalar_argument - Store scalar argument ARGVAL of type
+/// LLVMTY at location LOC.
+static void llvm_store_scalar_argument(Value *Loc, Value *ArgVal,
+                                       const llvm::Type *LLVMTy,
+                                       unsigned RealSize,
+                                       IRBuilder &Builder) {
+  assert (RealSize == 0 &&
+          "The target should handle this argument!");
+  // This cast only involves pointers, therefore BitCast.
+  Loc = Builder.CreateBitCast(Loc, PointerType::getUnqual(LLVMTy), "tmp");
+  Builder.CreateStore(ArgVal, Loc);
+}
+
+#ifndef LLVM_STORE_SCALAR_ARGUMENT
+#define LLVM_STORE_SCALAR_ARGUMENT(LOC,ARG,TYPE,SIZE,BUILDER)   \
+  llvm_store_scalar_argument((LOC),(ARG),(TYPE),(SIZE),(BUILDER))
+#endif
+
 namespace {
   /// FunctionPrologArgumentConversion - This helper class is driven by the ABI
   /// definition for this target to figure out how to retrieve arguments from
@@ -468,7 +486,8 @@
       ++AI;
     }
 
-    void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) {
+    void HandleScalarArgument(const llvm::Type *LLVMTy, tree type,
+                              unsigned RealSize = 0) {
       Value *ArgVal = AI;
       if (ArgVal->getType() != LLVMTy) {
         if (isa<PointerType>(ArgVal->getType()) && isa<PointerType>(LLVMTy)) {
@@ -491,10 +510,7 @@
       }
       assert(!LocStack.empty());
       Value *Loc = LocStack.back();
-      // This cast only involves pointers, therefore BitCast.
-      Loc = Builder.CreateBitCast(Loc, PointerType::getUnqual(LLVMTy), "tmp");
-
-      Builder.CreateStore(ArgVal, Loc);
+      LLVM_STORE_SCALAR_ARGUMENT(Loc,ArgVal,LLVMTy,RealSize,Builder);
       AI->setName(NameStack.back());
       ++AI;
     }
@@ -2319,6 +2335,20 @@
   return Result;
 }
 
+/// llvm_load_scalar_argument - Load value located at LOC.
+static Value *llvm_load_scalar_argument(Value *L,
+                                        const llvm::Type *LLVMTy,
+                                        unsigned RealSize,
+                                        IRBuilder &Builder) {
+  assert (0 && "The target should override this routine!");
+  return NULL;
+}
+
+#ifndef LLVM_LOAD_SCALAR_ARGUMENT
+#define LLVM_LOAD_SCALAR_ARGUMENT(LOC,TY,SIZE,BUILDER) \
+  llvm_load_scalar_argument((LOC),(TY),(SIZE),(BUILDER))
+#endif
+
 namespace {
   /// FunctionCallArgumentConversion - This helper class is driven by the ABI
   /// definition for this target to figure out how to pass arguments into the
@@ -2482,8 +2512,14 @@
 
     /// HandleScalarArgument - This is the primary callback that specifies an
     /// LLVM argument to pass.  It is only used for first class types.
-    void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) {
-      Value *Loc = getValue(LLVMTy);
+    void HandleScalarArgument(const llvm::Type *LLVMTy, tree type,
+                              unsigned RealSize = 0) {
+      Value *Loc = NULL;
+      if (RealSize) {
+        Value *L = LocStack.back();
+        Loc = LLVM_LOAD_SCALAR_ARGUMENT(L,LLVMTy,RealSize,Builder);
+      } else
+        Loc = getValue(LLVMTy);
 
       // Perform any implicit type conversions.
       if (CallOperands.size() < FTy->getNumParams()) {

Modified: llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-types.cpp?rev=50539&r1=50538&r2=50539&view=diff

==============================================================================
--- llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/branches/Apple/Tak/gcc/llvm-types.cpp Thu May  1 16:15:57 2008
@@ -994,7 +994,8 @@
       HandleShadowArgument(PtrArgTy, RetPtr);
     }
 
-    void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) {
+    void HandleScalarArgument(const llvm::Type *LLVMTy, tree type,
+                              unsigned RealSize = 0) {
       if (KNRPromotion) {
         if (LLVMTy == Type::FloatTy)
           LLVMTy = Type::DoubleTy;





More information about the llvm-commits mailing list