r203660 - ARM: Correct alignment of structs passed as byval pointer

Oliver Stannard oliver.stannard at arm.com
Wed Mar 12 07:02:50 PDT 2014


Author: olista01
Date: Wed Mar 12 09:02:50 2014
New Revision: 203660

URL: http://llvm.org/viewvc/llvm-project?rev=203660&view=rev
Log:
ARM: Correct alignment of structs passed as byval pointer

When a struct has bitfields overlapping with other members
(as required by the AAPCS), clang uses a packed struct to
represent this. If such a struct is large enough for clang to
pass it as a byval pointer (>64 bytes), we need to set the
alignment of the argument to match the original type.


Added:
    cfe/trunk/test/CodeGen/arm-byval-align.c
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/arm-aapcs-vfp.c
    cfe/trunk/test/CodeGen/arm-arguments.c

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=203660&r1=203659&r2=203660&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Mar 12 09:02:50 2014
@@ -3649,7 +3649,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
   if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) {
       // Update Allocated GPRs
     markAllocatedGPRs(1, 1);
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/true,
+    return ABIArgInfo::getIndirect(TyAlign, /*ByVal=*/true,
            /*Realign=*/TyAlign > ABIAlign);
   }
 

Modified: cfe/trunk/test/CodeGen/arm-aapcs-vfp.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-aapcs-vfp.c?rev=203660&r1=203659&r2=203660&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-aapcs-vfp.c (original)
+++ cfe/trunk/test/CodeGen/arm-aapcs-vfp.c Wed Mar 12 09:02:50 2014
@@ -100,7 +100,7 @@ void test_neon(struct neon_struct arg) {
   neon_callee(arg);
 }
 
-// CHECK-LABEL: define arm_aapcs_vfpcc void @f33(%struct.s33* byval %s)
+// CHECK-LABEL: define arm_aapcs_vfpcc void @f33(%struct.s33* byval align 1 %s)
 struct s33 { char buf[32*32]; };
 void f33(struct s33 s) { }
 

Modified: cfe/trunk/test/CodeGen/arm-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-arguments.c?rev=203660&r1=203659&r2=203660&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-arguments.c (original)
+++ cfe/trunk/test/CodeGen/arm-arguments.c Wed Mar 12 09:02:50 2014
@@ -176,8 +176,8 @@ void f32(struct s32 s) { }
 // PR13350
 struct s33 { char buf[32*32]; };
 void f33(struct s33 s) { }
-// APCS-GNU-LABEL: define void @f33(%struct.s33* byval %s)
-// AAPCS-LABEL: define arm_aapcscc void @f33(%struct.s33* byval %s)
+// APCS-GNU-LABEL: define void @f33(%struct.s33* byval align 1 %s)
+// AAPCS-LABEL: define arm_aapcscc void @f33(%struct.s33* byval align 1 %s)
 
 // PR14048
 struct s34 { char c; };
@@ -209,14 +209,14 @@ float32x4_t f35(int i, s35_with_align s1
                             *(float32x4_t *)&s2);
   return v;
 }
-// APCS-GNU-LABEL: define <4 x float> @f35(i32 %i, %struct.s35* byval, %struct.s35* byval)
+// APCS-GNU-LABEL: define <4 x float> @f35(i32 %i, %struct.s35* byval align 16, %struct.s35* byval align 16)
 // APCS-GNU: %[[a:.*]] = alloca %struct.s35, align 16
 // APCS-GNU: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8*
 // APCS-GNU: %[[c:.*]] = bitcast %struct.s35* %0 to i8*
 // APCS-GNU: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[b]], i8* %[[c]]
 // APCS-GNU: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>*
 // APCS-GNU: load <4 x float>* %[[d]], align 16
-// AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval, %struct.s35* byval)
+// AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval align 16, %struct.s35* byval align 16)
 // AAPCS: %[[a:.*]] = alloca %struct.s35, align 16
 // AAPCS: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8*
 // AAPCS: %[[c:.*]] = bitcast %struct.s35* %0 to i8*

Added: cfe/trunk/test/CodeGen/arm-byval-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-byval-align.c?rev=203660&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/arm-byval-align.c (added)
+++ cfe/trunk/test/CodeGen/arm-byval-align.c Wed Mar 12 09:02:50 2014
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple=armv7-none-eabi < %s -S -emit-llvm | FileCheck %s
+
+struct foo {
+  long long a;
+  char b;
+  int c:16;
+  int d[16];
+};
+
+// CHECK: %struct.foo* byval align 8 %z
+long long bar(int a, int b, int c, int d, int e,
+              struct foo z) {
+  return z.a;
+}





More information about the cfe-commits mailing list