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

Daniel Dunbar daniel at zuster.org
Thu Sep 16 13:42:06 PDT 2010


Author: ddunbar
Date: Thu Sep 16 15:42:06 2010
New Revision: 114115

URL: http://llvm.org/viewvc/llvm-project?rev=114115&view=rev
Log:
IRgen/ABI/x86-32: Realign indirect arguments when the ABI requires us to pass
them with a smaller alignment than the rest of codegen expects.

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

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=114115&r1=114114&r2=114115&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Sep 16 15:42:06 2010
@@ -353,7 +353,7 @@
   ABIArgInfo getIndirectResult(QualType Ty, bool ByVal = true) const;
 
   /// \brief Return the alignment to use for the given type on the stack.
-  unsigned getTypeStackAlignInBytes(QualType Ty) const;
+  unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const;
 
 public:
 
@@ -580,16 +580,18 @@
   return false;
 }
 
-unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty) const {
-  // On non-Darwin, the stack type alignment is always 4.
-  if (!IsDarwinVectorABI)
-    return MinABIStackAlignInBytes;
-
-  // Otherwise, if the alignment is less than or equal to 4, use the minimum ABI
-  // alignment.
-  unsigned Align = getContext().getTypeAlign(Ty) / 8;
+unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty,
+                                                 unsigned Align) const {
+  // Otherwise, if the alignment is less than or equal to the minimum ABI
+  // alignment, just use the default; the backend will handle this.
   if (Align <= MinABIStackAlignInBytes)
+    return 0; // Use default alignment.
+
+  // On non-Darwin, the stack type alignment is always 4.
+  if (!IsDarwinVectorABI) {
+    // Set explicit alignment, since we may need to realign the top.
     return MinABIStackAlignInBytes;
+  }
 
   // Otherwise, if the type contains an SSE vector type, the alignment is 16.
   if (isRecordWithSSEVectorType(getContext(), Ty))
@@ -602,12 +604,19 @@
   if (!ByVal)
     return ABIArgInfo::getIndirect(0, false);
 
-  // Compute the byval alignment. We trust the back-end to honor the
-  // minimum ABI alignment for byval, to make cleaner IR.
-  unsigned Align = getTypeStackAlignInBytes(Ty);
-  if (Align > MinABIStackAlignInBytes)
-    return ABIArgInfo::getIndirect(Align);
-  return ABIArgInfo::getIndirect(0);
+  // Compute the byval alignment.
+  unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
+  unsigned StackAlign = getTypeStackAlignInBytes(Ty, TypeAlign);
+  if (StackAlign == 0)
+    return ABIArgInfo::getIndirect(0);
+
+  // If the stack alignment is less than the type alignment, realign the
+  // argument.
+  if (StackAlign < TypeAlign)
+    return ABIArgInfo::getIndirect(StackAlign, /*ByVal=*/true,
+                                   /*Realign=*/true);
+
+  return ABIArgInfo::getIndirect(StackAlign);
 }
 
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const {

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=114115&r1=114114&r2=114115&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c Thu Sep 16 15:42:06 2010
@@ -202,13 +202,13 @@
 struct s51 { vvbp f0; int f1; };
 void f51(struct s51 a0) { }
 
-// CHECK: define void @f52(%struct.s52* byval %x)
+// CHECK: define void @f52(%struct.s52* byval align 4)
 struct s52 {
   long double a;
 };
 void f52(struct s52 x) {}
 
-// CHECK: define void @f53(%struct.s53* byval %x)
+// CHECK: define void @f53(%struct.s53* byval align 4)
 struct __attribute__((aligned(32))) s53 {
   int x;
   int y;
@@ -230,21 +230,21 @@
 
 // CHECK: define void @f56(
 // CHECK: i8 signext %a0, %struct.s56_0* byval %a1,
-// CHECK: <2 x i32> %a2, %struct.s56_1* byval %a3,
-// CHECK: i64 %a4.coerce, %struct.s56_2* byval %a5,
+// CHECK: <2 x i32> %a2, %struct.s56_1* byval align 4,
+// CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4,
 // CHECK: <4 x i32> %a6, %struct.s39* byval align 16 %a7,
 // CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9,
-// CHECK: <8 x i32> %a10, %struct.s56_5* byval %a11,
-// CHECK: <4 x double> %a12, %struct.s56_6* byval %a13)
+// CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4,
+// CHECK: <4 x double> %a12, %struct.s56_6* byval align 4)
 
 // CHECK:   call void (i32, ...)* @f56_0(i32 1,
 // CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval %{{[^ ]*}},
-// CHECK: <2 x i32> %{{[^ ]*}}, %struct.s56_1* byval %{{[^ ]*}},
-// CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval %{{[^ ]*}},
+// CHECK: <2 x i32> %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
+// CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}},
 // CHECK: <4 x i32> %{{[^ ]*}}, %struct.s39* byval align 16 %{{[^ ]*}},
 // CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}},
-// CHECK: <8 x i32> {{[^ ]*}}, %struct.s56_5* byval %{{[^ ]*}},
-// CHECK: <4 x double> {{[^ ]*}}, %struct.s56_6* byval %{{[^ ]*}})
+// CHECK: <8 x i32> {{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}},
+// CHECK: <4 x double> {{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}})
 // CHECK: }
 //
 // <rdar://problem/7964854> [i386] clang misaligns long double in structures

Modified: cfe/trunk/test/CodeGen/x86_32-arguments-linux.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments-linux.c?rev=114115&r1=114114&r2=114115&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-linux.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-linux.c Thu Sep 16 15:42:06 2010
@@ -3,21 +3,21 @@
 
 // CHECK: define void @f56(
 // CHECK: i8 signext %a0, %struct.s56_0* byval %a1,
-// CHECK: <2 x i32> %a2, %struct.s56_1* byval %a3,
-// CHECK: <1 x double> %a4, %struct.s56_2* byval %a5,
-// CHECK: <4 x i32> %a6, %struct.s56_3* byval %a7,
-// CHECK: <2 x double> %a8, %struct.s56_4* byval %a9,
-// CHECK: <8 x i32> %a10, %struct.s56_5* byval %a11,
-// CHECK: <4 x double> %a12, %struct.s56_6* byval %a13)
+// CHECK: <2 x i32> %a2, %struct.s56_1* byval align 4,
+// CHECK: <1 x double> %a4, %struct.s56_2* byval align 4,
+// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 4,
+// CHECK: <2 x double> %a8, %struct.s56_4* byval align 4,
+// CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4,
+// CHECK: <4 x double> %a12, %struct.s56_6* byval align 4)
 
 // CHECK: call void (i32, ...)* @f56_0(i32 1,
 // CHECK: i32 %{{.*}}, %struct.s56_0* byval %{{[^ ]*}},
-// CHECK: <2 x i32> %{{[^ ]*}}, %struct.s56_1* byval %{{[^ ]*}},
-// CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval %{{[^ ]*}},
-// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval %{{[^ ]*}},
-// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval %{{[^ ]*}},
-// CHECK: <8 x i32> %{{[^ ]*}}, %struct.s56_5* byval %{{[^ ]*}},
-// CHECK: <4 x double> %{{[^ ]*}}, %struct.s56_6* byval %{{[^ ]*}})
+// CHECK: <2 x i32> %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
+// CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}},
+// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 4 %{{[^ ]*}},
+// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 4 %{{[^ ]*}},
+// CHECK: <8 x i32> %{{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}},
+// CHECK: <4 x double> %{{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}})
 // CHECK: }
 //
 // <rdar://problem/7964854> [i386] clang misaligns long double in structures

Added: cfe/trunk/test/CodeGen/x86_32-arguments-realign.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments-realign.c?rev=114115&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-realign.c (added)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-realign.c Thu Sep 16 15:42:06 2010
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: FileCheck < %t %s
+
+// CHECK: define void @f0(%struct.s0* byval align 4)
+// CHECK:   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 16, i32 4, i1 false)
+// CHECK: }
+struct s0 { long double a; };
+void f0(struct s0 a0) {
+  extern long double f0_g0;
+  f0_g0 = a0.a;
+}





More information about the cfe-commits mailing list