summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGen/x86_32-align-linux.c
diff options
context:
space:
mode:
authorPengfei Wang <pengfei.wang@intel.com>2019-05-29 08:42:35 +0000
committerPengfei Wang <pengfei.wang@intel.com>2019-05-29 08:42:35 +0000
commitd61cb749f4ac2c90244906d756e80a5c4a7ffa89 (patch)
tree19ae589c7adcebd0b0ec17507e2e44cc0002a591 /clang/test/CodeGen/x86_32-align-linux.c
parent4f58ad4e720df4c265271907758b3daffbf764d2 (diff)
downloadbcm5719-llvm-d61cb749f4ac2c90244906d756e80a5c4a7ffa89.tar.gz
bcm5719-llvm-d61cb749f4ac2c90244906d756e80a5c4a7ffa89.zip
[X86] Fix i386 struct and union parameter alignment
According to i386 System V ABI 2.1: Structures and unions assume the alignment of their most strictly aligned component. But current implementation always takes them as 4-byte aligned which will result in incorrect code, e.g: 1 #include <immintrin.h> 2 typedef union { 3 int d[4]; 4 __m128 m; 5 } M128; 6 extern void foo(int, ...); 7 void test(void) 8 { 9 M128 a; 10 foo(1, a); 11 foo(1, a.m); 12 } The first call (line 10) takes the second arg as 4-byte aligned while the second call (line 11) takes the second arg as 16-byte aligned. There is oxymoron for the alignment of the 2 calls because they should be the same. This patch fixes the bug by following i386 System V ABI and apply it to Linux only since other System V OS (e.g Darwin, PS4 and FreeBSD) don't want to spend any effort dealing with the ramifications of ABI breaks at present. Patch by Wei Xiao (wxiao3) Differential Revision: https://reviews.llvm.org/D60748 llvm-svn: 361934
Diffstat (limited to 'clang/test/CodeGen/x86_32-align-linux.c')
-rw-r--r--clang/test/CodeGen/x86_32-align-linux.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/test/CodeGen/x86_32-align-linux.c b/clang/test/CodeGen/x86_32-align-linux.c
new file mode 100644
index 00000000000..5fce3f5f295
--- /dev/null
+++ b/clang/test/CodeGen/x86_32-align-linux.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -w -fblocks -ffreestanding -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: FileCheck < %t %s
+
+#include <immintrin.h>
+
+typedef union {
+ int d[4];
+ __m128 m;
+} M128;
+
+extern void foo(int, ...);
+
+M128 a;
+
+// CHECK-LABEL: define void @test
+// CHECK: entry:
+// CHECK: call void (i32, ...) @foo(i32 1, %union.M128* byval align 16
+// CHECK: call void (i32, ...) @foo(i32 1, <4 x float>
+
+void test(void)
+{
+ foo(1, a);
+ foo(1, a.m);
+}
+
OpenPOWER on IntegriCloud