[cfe-commits] r144963 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_32-arguments-darwin.c

Eli Friedman eli.friedman at gmail.com
Thu Nov 17 18:12:10 PST 2011


Author: efriedma
Date: Thu Nov 17 20:12:09 2011
New Revision: 144963

URL: http://llvm.org/viewvc/llvm-project?rev=144963&view=rev
Log:
A bunch of fixes to argument passing and va_arg on Darwin x86-32 for structures containing an SSE vector.


Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=144963&r1=144962&r2=144963&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Nov 17 20:12:09 2011
@@ -620,7 +620,7 @@
        i != e; ++i) {
     QualType FT = i->getType();
 
-    if (FT->getAs<VectorType>() && Context.getTypeSize(Ty) == 128)
+    if (FT->getAs<VectorType>() && Context.getTypeSize(FT) == 128)
       return true;
 
     if (isRecordWithSSEVectorType(Context, FT))
@@ -644,7 +644,7 @@
   }
 
   // Otherwise, if the type contains an SSE vector type, the alignment is 16.
-  if (isRecordWithSSEVectorType(getContext(), Ty))
+  if (Align >= 16 && isRecordWithSSEVectorType(getContext(), Ty))
     return 16;
 
   return MinABIStackAlignInBytes;
@@ -739,12 +739,30 @@
   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
                                                        "ap");
   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+
+  // Compute if the address needs to be aligned
+  unsigned Align = CGF.getContext().getTypeAlignInChars(Ty).getQuantity();
+  Align = getTypeStackAlignInBytes(Ty, Align);
+  Align = std::max(Align, 4U);
+  if (Align > 4) {
+    // addr = (addr + align - 1) & -align;
+    llvm::Value *Offset =
+      llvm::ConstantInt::get(CGF.Int32Ty, Align - 1);
+    Addr = CGF.Builder.CreateGEP(Addr, Offset);
+    llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(Addr,
+                                                    CGF.Int32Ty);
+    llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -Align);
+    Addr = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask),
+                                      Addr->getType(),
+                                      "ap.cur.aligned");
+  }
+
   llvm::Type *PTy =
     llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
   llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
 
   uint64_t Offset =
-    llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4);
+    llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, Align);
   llvm::Value *NextAddr =
     Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset),
                       "ap.next");

Modified: cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c?rev=144963&r1=144962&r2=144963&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c Thu Nov 17 20:12:09 2011
@@ -292,3 +292,27 @@
 // CHECK: define void @f60(%struct.s60* byval align 4, i32 %y)
 struct s60 { int x __attribute((aligned(8))); };
 void f60(struct s60 x, int y) {}
+
+// CHECK: define void @f61(i32 %x, %struct.s61* byval align 16 %y)
+typedef int T61 __attribute((vector_size(16)));
+struct s61 { T61 x; int y; };
+void f61(int x, struct s61 y) {}
+
+// CHECK: define void @f62(i32 %x, %struct.s62* byval align 4)
+typedef int T62 __attribute((vector_size(16)));
+struct s62 { T62 x; int y; } __attribute((packed, aligned(8)));
+void f62(int x, struct s62 y) {}
+
+// CHECK: define i32 @f63
+// CHECK: ptrtoint
+// CHECK: and {{.*}}, -16
+// CHECK: inttoptr
+typedef int T63 __attribute((vector_size(16)));
+struct s63 { T63 x; int y; };
+int f63(int i, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap, i);
+  struct s63 s = __builtin_va_arg(ap, struct s63);
+  __builtin_va_end(ap);
+  return s.y;
+}





More information about the cfe-commits mailing list