[cfe-commits] r166052 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/arm-abi-vector.c

Manman Ren mren at apple.com
Tue Oct 16 12:51:49 PDT 2012


Author: mren
Date: Tue Oct 16 14:51:48 2012
New Revision: 166052

URL: http://llvm.org/viewvc/llvm-project?rev=166052&view=rev
Log:
ARM ABI: fix ABI alignment issues in varargs.

We generalize r166040 to handle ABI alignment issues for all types.

rdar://12439123

Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/arm-abi-vector.c

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=166052&r1=166051&r2=166052&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Oct 16 14:51:48 2012
@@ -3213,13 +3213,11 @@
 
   // The ABI alignment for 64-bit or 128-bit vectors is 8 for AAPCS and 4 for
   // APCS. For AAPCS, the ABI alignment is at least 4-byte and at most 8-byte.
-  if (Ty->getAs<VectorType>()) {
-    if (getABIKind() == ARMABIInfo::AAPCS_VFP ||
-        getABIKind() == ARMABIInfo::AAPCS)
-      TyAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8);
-    else
-      TyAlign = 4;
-  }
+  if (getABIKind() == ARMABIInfo::AAPCS_VFP ||
+      getABIKind() == ARMABIInfo::AAPCS)
+    TyAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8);
+  else
+    TyAlign = 4;
   // Use indirect if size of the illegal vector is bigger than 16 bytes.
   if (isIllegalVectorType(Ty) && Size > 16) {
     IsIndirect = true;
@@ -3246,8 +3244,7 @@
 
   if (IsIndirect)
     Addr = Builder.CreateLoad(Builder.CreateBitCast(Addr, BPP));
-  else if (Ty->getAs<VectorType>() &&
-           (TyAlign < CGF.getContext().getTypeAlign(Ty) / 8)) {
+  else if (TyAlign < CGF.getContext().getTypeAlign(Ty) / 8) {
     // We can't directly cast ap.cur to pointer to a vector type, since ap.cur
     // may not be correctly aligned for the vector type. We create an aligned
     // temporary space and copy the content over from ap.cur to the temporary

Modified: cfe/trunk/test/CodeGen/arm-abi-vector.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-abi-vector.c?rev=166052&r1=166051&r2=166052&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-abi-vector.c (original)
+++ cfe/trunk/test/CodeGen/arm-abi-vector.c Tue Oct 16 14:51:48 2012
@@ -226,3 +226,38 @@
 // APCS-GNU: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> %3)
   return varargs_vec_5s(5, *in);
 }
+
+// Pass struct as varargs.
+typedef struct
+{
+  __int2 i2;
+  float f;
+} StructWithVec;
+
+double varargs_struct(int fixed, ...) {
+// CHECK: varargs_struct
+// CHECK: %3 = and i32 %2, -8
+// CHECK: %ap.align = inttoptr i32 %3 to i8*
+// CHECK: %ap.next = getelementptr i8* %ap.align, i32 16
+// CHECK: bitcast i8* %ap.align to %struct.StructWithVec*
+// APCS-GNU: varargs_struct
+// APCS-GNU: %var.align = alloca %struct.StructWithVec
+// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 16
+// APCS-GNU: %1 = bitcast %struct.StructWithVec* %var.align to i8*
+// APCS-GNU: call void @llvm.memcpy
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  StructWithVec c3 = va_arg(ap, StructWithVec);
+  sum = sum + c3.i2.x + c3.i2.y + c3.f;
+  va_end(ap);
+  return sum;
+}
+
+double test_struct(StructWithVec* d) {
+// CHECK: test_struct
+// CHECK: call arm_aapcscc double (i32, ...)* @varargs_struct(i32 3, [2 x i64] %3)
+// APCS-GNU: test_struct
+// APCS-GNU: call double (i32, ...)* @varargs_struct(i32 3, [2 x i64] %3)
+  return varargs_struct(3, *d);
+}





More information about the cfe-commits mailing list