summaryrefslogtreecommitdiff
path: root/test/CodeGen
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-05-04 16:12:48 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-05-04 16:12:48 +0000
commit0883ccd9eac3b974df00e6548ee319a7dd3646f4 (patch)
treed6a70c3518b8dea8be7062438d7e8676820ed17f /test/CodeGen
parent60bfabcd8ce617297c0d231f77d14ab507e98796 (diff)
Notes
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/2009-10-20-GlobalDebug.c8
-rw-r--r--test/CodeGen/arm-arguments.c30
-rw-r--r--test/CodeGen/arm_asm_clobber.c21
-rw-r--r--test/CodeGen/asm-errors.c8
-rw-r--r--test/CodeGen/asm.c21
-rw-r--r--test/CodeGen/asm_arm.c32
-rw-r--r--test/CodeGen/bitfield-2.c368
-rw-r--r--test/CodeGen/blocks.c2
-rw-r--r--test/CodeGen/builtins-ppc-altivec.c332
-rw-r--r--test/CodeGen/catch-undef-behavior.c7
-rw-r--r--test/CodeGen/const-unordered-compare.c7
-rw-r--r--test/CodeGen/decl.c32
-rw-r--r--test/CodeGen/designated-initializers.c37
-rw-r--r--test/CodeGen/functions.c12
-rw-r--r--test/CodeGen/global-init.c30
-rw-r--r--test/CodeGen/init.c6
-rw-r--r--test/CodeGen/libcalls.c50
-rw-r--r--test/CodeGen/palignr.c19
-rw-r--r--test/CodeGen/struct-passing.c4
-rw-r--r--test/CodeGen/union-init2.c11
-rw-r--r--test/CodeGen/x86_32-arguments.c126
-rw-r--r--test/CodeGen/x86_64-arguments.c81
22 files changed, 1080 insertions, 164 deletions
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
index 99be46996ed55..1db37de4bb27a 100644
--- a/test/CodeGen/2009-10-20-GlobalDebug.c
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -1,4 +1,8 @@
// RUN: %clang -ccc-host-triple i386-apple-darwin10 -S -g -dA %s -o - | FileCheck %s
int global;
-// CHECK: asciz "global" ## External Name
-int main() { return 0;}
+// CHECK: asciz "global" ## External Name
+// CHECK: asciz "localstatic" ## External Name
+int main() {
+ static int localstatic;
+ return 0;
+}
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
index d313a9b3310f6..72fd7c3f8b71d 100644
--- a/test/CodeGen/arm-arguments.c
+++ b/test/CodeGen/arm-arguments.c
@@ -28,13 +28,13 @@ struct s4 { struct s4_0 { int f0; } f0; };
struct s4 f4(void) {}
// APCS-GNU: define arm_apcscc void @f5(
-// APCS-GNU: struct.s5* noalias sret
+// APCS-GNU: struct.s5* sret
// AAPCS: define arm_aapcscc i32 @f5()
struct s5 { struct { } f0; int f1; };
struct s5 f5(void) {}
// APCS-GNU: define arm_apcscc void @f6(
-// APCS-GNU: struct.s6* noalias sret
+// APCS-GNU: struct.s6* sret
// AAPCS: define arm_aapcscc i32 @f6()
struct s6 { int f0[1]; };
struct s6 f6(void) {}
@@ -45,7 +45,7 @@ struct s7 { struct { int : 0; } f0; };
struct s7 f7(void) {}
// APCS-GNU: define arm_apcscc void @f8(
-// APCS-GNU: struct.s8* noalias sret
+// APCS-GNU: struct.s8* sret
// AAPCS: define arm_aapcscc void @f8()
struct s8 { struct { int : 0; } f0[1]; };
struct s8 f8(void) {}
@@ -61,7 +61,7 @@ struct s10 { int f0; int : 0; int : 0; };
struct s10 f10(void) {}
// APCS-GNU: define arm_apcscc void @f11(
-// APCS-GNU: struct.s10* noalias sret
+// APCS-GNU: struct.s10* sret
// AAPCS: define arm_aapcscc i32 @f11()
struct s11 { int : 0; int f0; };
struct s11 f11(void) {}
@@ -72,7 +72,7 @@ union u12 { char f0; short f1; int f2; };
union u12 f12(void) {}
// APCS-GNU: define arm_apcscc void @f13(
-// APCS-GNU: struct.s13* noalias sret
+// APCS-GNU: struct.s13* sret
// FIXME: This should return a float.
// AAPCS-FIXME: define arm_aapcscc float @f13()
@@ -80,7 +80,7 @@ struct s13 { float f0; };
struct s13 f13(void) {}
// APCS-GNU: define arm_apcscc void @f14(
-// APCS-GNU: struct.s13* noalias sret
+// APCS-GNU: struct.s13* sret
// AAPCS: define arm_aapcscc i32 @f14()
union u14 { float f0; };
union u14 f14(void) {}
@@ -104,18 +104,18 @@ struct s18 { short f0; char f1 : 4; };
struct s18 f18(void) {}
// APCS-GNU: define arm_apcscc void @f19(
-// APCS-GNU: struct.s19* noalias sret
+// APCS-GNU: struct.s19* sret
// AAPCS: define arm_aapcscc i32 @f19()
struct s19 { int f0; struct s8 f1; };
struct s19 f19(void) {}
// APCS-GNU: define arm_apcscc void @f20(
-// APCS-GNU: struct.s20* noalias sret
+// APCS-GNU: struct.s20* sret
// AAPCS: define arm_aapcscc i32 @f20()
struct s20 { struct s8 f1; int f0; };
struct s20 f20(void) {}
-// APCS-GNU: define arm_apcscc i32 @f21()
+// APCS-GNU: define arm_apcscc i8 @f21()
// AAPCS: define arm_aapcscc i32 @f21()
struct s21 { struct {} f1; int f0 : 4; };
struct s21 f21(void) {}
@@ -128,10 +128,10 @@ struct s21 f21(void) {}
// APCS-GNU: define arm_apcscc i128 @f27()
// AAPCS: define arm_aapcscc i16 @f22()
// AAPCS: define arm_aapcscc i32 @f23()
-// AAPCS: define arm_aapcscc void @f24({{.*}} noalias sret
-// AAPCS: define arm_aapcscc void @f25({{.*}} noalias sret
-// AAPCS: define arm_aapcscc void @f26({{.*}} noalias sret
-// AAPCS: define arm_aapcscc void @f27({{.*}} noalias sret
+// AAPCS: define arm_aapcscc void @f24({{.*}} sret
+// AAPCS: define arm_aapcscc void @f25({{.*}} sret
+// AAPCS: define arm_aapcscc void @f26({{.*}} sret
+// AAPCS: define arm_aapcscc void @f27({{.*}} sret
_Complex char f22(void) {}
_Complex short f23(void) {}
_Complex int f24(void) {}
@@ -149,7 +149,7 @@ struct s28 f28() {}
struct s29 { _Complex short f0; };
struct s29 f29() {}
-// APCS-GNU: define arm_apcscc void @f30({{.*}} noalias sret
-// AAPCS: define arm_aapcscc void @f30({{.*}} noalias sret
+// APCS-GNU: define arm_apcscc void @f30({{.*}} sret
+// AAPCS: define arm_aapcscc void @f30({{.*}} sret
struct s30 { _Complex int f0; };
struct s30 f30() {}
diff --git a/test/CodeGen/arm_asm_clobber.c b/test/CodeGen/arm_asm_clobber.c
deleted file mode 100644
index a7ca0b5332b02..0000000000000
--- a/test/CodeGen/arm_asm_clobber.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -triple armv6-unknown-unknown -emit-llvm -o %t %s
-
-void test0(void) {
- asm volatile("mov r0, r0" :: );
-}
-void test1(void) {
- asm volatile("mov r0, r0" :::
- "cc", "memory" );
-}
-void test2(void) {
- asm volatile("mov r0, r0" :::
- "r0", "r1", "r2", "r3");
- asm volatile("mov r0, r0" :::
- "r4", "r5", "r6", "r8");
-}
-void test3(void) {
- asm volatile("mov r0, r0" :::
- "a1", "a2", "a3", "a4");
- asm volatile("mov r0, r0" :::
- "v1", "v2", "v3", "v5");
-}
diff --git a/test/CodeGen/asm-errors.c b/test/CodeGen/asm-errors.c
new file mode 100644
index 0000000000000..7323e61b591a2
--- /dev/null
+++ b/test/CodeGen/asm-errors.c
@@ -0,0 +1,8 @@
+// RUN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s > %t 2>&1
+// RUN: FileCheck %s < %t
+
+int test1(int X) {
+// CHECK: error: unrecognized instruction
+ __asm__ ("abc incl %0" : "+r" (X));
+ return X;
+}
diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c
index ace0db9af6d4e..507702887866b 100644
--- a/test/CodeGen/asm.c
+++ b/test/CodeGen/asm.c
@@ -147,3 +147,24 @@ int t19(unsigned data) {
// CHECK: = call {{.*}}asm "x$(abc$|def$|ghi$)z"
}
+
+// PR6845 - Mismatching source/dest fp types.
+double t20(double x) {
+ register long double result;
+ __asm __volatile ("frndint" : "=t" (result) : "0" (x));
+ return result;
+
+ // CHECK: @t20
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK-NEXT: call x86_fp80 asm sideeffect "frndint"
+ // CHECK: fptrunc x86_fp80 {{.*}} to double
+}
+
+float t21(long double x) {
+ register float result;
+ __asm __volatile ("frndint" : "=t" (result) : "0" (x));
+ return result;
+ // CHECK: @t21
+ // CHECK: call x86_fp80 asm sideeffect "frndint"
+ // CHECK-NEXT: fptrunc x86_fp80 {{.*}} to float
+}
diff --git a/test/CodeGen/asm_arm.c b/test/CodeGen/asm_arm.c
new file mode 100644
index 0000000000000..aac47d57dc5ab
--- /dev/null
+++ b/test/CodeGen/asm_arm.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple armv6-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+void test0(void) {
+ asm volatile("mov r0, r0" :: );
+}
+void test1(void) {
+ asm volatile("mov r0, r0" :::
+ "cc", "memory" );
+}
+void test2(void) {
+ asm volatile("mov r0, r0" :::
+ "r0", "r1", "r2", "r3");
+ asm volatile("mov r0, r0" :::
+ "r4", "r5", "r6", "r8");
+}
+void test3(void) {
+ asm volatile("mov r0, r0" :::
+ "a1", "a2", "a3", "a4");
+ asm volatile("mov r0, r0" :::
+ "v1", "v2", "v3", "v5");
+}
+
+
+// {} should not be treated as asm variants.
+void test4(float *a, float *b) {
+ // CHECK: @test4
+ // CHECK: call void asm sideeffect "vld1.32 {d8[],d9[]},
+ __asm__ volatile (
+ "vld1.32 {d8[],d9[]}, [%1,:32] \n\t"
+ "vst1.32 {q4}, [%0,:128] \n\t"
+ :: "r"(a), "r"(b));
+}
diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c
new file mode 100644
index 0000000000000..e91859fb72875
--- /dev/null
+++ b/test/CodeGen/bitfield-2.c
@@ -0,0 +1,368 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -O3 -o %t.opt.ll %s \
+// RUN: -fdump-record-layouts 2> %t.dump.txt
+// RUN: FileCheck -check-prefix=CHECK-RECORD < %t.dump.txt %s
+// RUN: FileCheck -check-prefix=CHECK-OPT < %t.opt.ll %s
+
+/****/
+
+// Check that we don't read off the end a packed 24-bit structure.
+// PR6176
+
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: struct s0
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD: LLVMType:<{ [3 x i8] }>
+// CHECK-RECORD: ContainsPointerToDataMember:0
+// CHECK-RECORD: BitFields:[
+// CHECK-RECORD: <CGBitFieldInfo Size:24 IsSigned:1
+// CHECK-RECORD: NumComponents:2 Components: [
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
+// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:16>
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
+// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:16 TargetBitWidth:8>
+struct __attribute((packed)) s0 {
+ int f0 : 24;
+};
+
+struct s0 g0 = { 0xdeadbeef };
+
+int f0_load(struct s0 *a0) {
+ int size_check[sizeof(struct s0) == 3 ? 1 : -1];
+ return a0->f0;
+}
+int f0_store(struct s0 *a0) {
+ return (a0->f0 = 1);
+}
+int f0_reload(struct s0 *a0) {
+ return (a0->f0 += 1);
+}
+
+// CHECK-OPT: define i64 @test_0()
+// CHECK-OPT: ret i64 1
+// CHECK-OPT: }
+unsigned long long test_0() {
+ struct s0 g0 = { 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g0.f0;
+ res ^= f0_load(&g0) ^ f0_store(&g0) ^ f0_reload(&g0);
+ res ^= g0.f0;
+ return res;
+}
+
+/****/
+
+// PR5591
+
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: struct s1
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD: LLVMType:<{ [2 x i8], i8 }>
+// CHECK-RECORD: ContainsPointerToDataMember:0
+// CHECK-RECORD: BitFields:[
+// CHECK-RECORD: <CGBitFieldInfo Size:10 IsSigned:1
+// CHECK-RECORD: NumComponents:1 Components: [
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
+// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:10>
+// CHECK-RECORD: ]>
+// CHECK-RECORD: <CGBitFieldInfo Size:10 IsSigned:1
+// CHECK-RECORD: NumComponents:2 Components: [
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:10 AccessWidth:16
+// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:6>
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
+// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:6 TargetBitWidth:4>
+
+#pragma pack(push)
+#pragma pack(1)
+struct __attribute((packed)) s1 {
+ signed f0 : 10;
+ signed f1 : 10;
+};
+#pragma pack(pop)
+
+struct s1 g1 = { 0xdeadbeef, 0xdeadbeef };
+
+int f1_load(struct s1 *a0) {
+ int size_check[sizeof(struct s1) == 3 ? 1 : -1];
+ return a0->f1;
+}
+int f1_store(struct s1 *a0) {
+ return (a0->f1 = 1234);
+}
+int f1_reload(struct s1 *a0) {
+ return (a0->f1 += 1234);
+}
+
+// CHECK-OPT: define i64 @test_1()
+// CHECK-OPT: ret i64 210
+// CHECK-OPT: }
+unsigned long long test_1() {
+ struct s1 g1 = { 0xdeadbeef, 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g1.f0 ^ g1.f1;
+ res ^= f1_load(&g1) ^ f1_store(&g1) ^ f1_reload(&g1);
+ res ^= g1.f0 ^ g1.f1;
+ return res;
+}
+
+/****/
+
+// Check that we don't access beyond the bounds of a union.
+//
+// PR5567
+
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: union u2
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD: LLVMType:<{ i8 }>
+// CHECK-RECORD: ContainsPointerToDataMember:0
+// CHECK-RECORD: BitFields:[
+// CHECK-RECORD: <CGBitFieldInfo Size:3 IsSigned:0
+// CHECK-RECORD: NumComponents:1 Components: [
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:8
+// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:3>
+
+union __attribute__((packed)) u2 {
+ unsigned long long f0 : 3;
+};
+
+union u2 g2 = { 0xdeadbeef };
+
+int f2_load(union u2 *a0) {
+ return a0->f0;
+}
+int f2_store(union u2 *a0) {
+ return (a0->f0 = 1234);
+}
+int f2_reload(union u2 *a0) {
+ return (a0->f0 += 1234);
+}
+
+// CHECK-OPT: define i64 @test_2()
+// CHECK-OPT: ret i64 2
+// CHECK-OPT: }
+unsigned long long test_2() {
+ union u2 g2 = { 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g2.f0;
+ res ^= f2_load(&g2) ^ f2_store(&g2) ^ f2_reload(&g2);
+ res ^= g2.f0;
+ return res;
+}
+
+/***/
+
+// PR5039
+
+struct s3 {
+ long long f0 : 32;
+ long long f1 : 32;
+};
+
+struct s3 g3 = { 0xdeadbeef, 0xdeadbeef };
+
+int f3_load(struct s3 *a0) {
+ a0->f0 = 1;
+ return a0->f0;
+}
+int f3_store(struct s3 *a0) {
+ a0->f0 = 1;
+ return (a0->f0 = 1234);
+}
+int f3_reload(struct s3 *a0) {
+ a0->f0 = 1;
+ return (a0->f0 += 1234);
+}
+
+// CHECK-OPT: define i64 @test_3()
+// CHECK-OPT: ret i64 -559039940
+// CHECK-OPT: }
+unsigned long long test_3() {
+ struct s3 g3 = { 0xdeadbeef, 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g3.f0 ^ g3.f1;
+ res ^= f3_load(&g3) ^ f3_store(&g3) ^ f3_reload(&g3);
+ res ^= g3.f0 ^ g3.f1;
+ return res;
+}
+
+/***/
+
+// This is a case where the bitfield access will straddle an alignment boundary
+// of its underlying type.
+
+struct s4 {
+ unsigned f0 : 16;
+ unsigned f1 : 28 __attribute__ ((packed));
+};
+
+struct s4 g4 = { 0xdeadbeef, 0xdeadbeef };
+
+int f4_load(struct s4 *a0) {
+ return a0->f0 ^ a0->f1;
+}
+int f4_store(struct s4 *a0) {
+ return (a0->f0 = 1234) ^ (a0->f1 = 5678);
+}
+int f4_reload(struct s4 *a0) {
+ return (a0->f0 += 1234) ^ (a0->f1 += 5678);
+}
+
+// CHECK-OPT: define i64 @test_4()
+// CHECK-OPT: ret i64 4860
+// CHECK-OPT: }
+unsigned long long test_4() {
+ struct s4 g4 = { 0xdeadbeef, 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g4.f0 ^ g4.f1;
+ res ^= f4_load(&g4) ^ f4_store(&g4) ^ f4_reload(&g4);
+ res ^= g4.f0 ^ g4.f1;
+ return res;
+}
+
+/***/
+
+struct s5 {
+ unsigned f0 : 2;
+ _Bool f1 : 1;
+ _Bool f2 : 1;
+};
+
+struct s5 g5 = { 0xdeadbeef, 0xdeadbeef };
+
+int f5_load(struct s5 *a0) {
+ return a0->f0 ^ a0->f1;
+}
+int f5_store(struct s5 *a0) {
+ return (a0->f0 = 0xF) ^ (a0->f1 = 0xF) ^ (a0->f2 = 0xF);
+}
+int f5_reload(struct s5 *a0) {
+ return (a0->f0 += 0xF) ^ (a0->f1 += 0xF) ^ (a0->f2 += 0xF);
+}
+
+// CHECK-OPT: define i64 @test_5()
+// CHECK-OPT: ret i64 2
+// CHECK-OPT: }
+unsigned long long test_5() {
+ struct s5 g5 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g5.f0 ^ g5.f1 ^ g5.f2;
+ res ^= f5_load(&g5) ^ f5_store(&g5) ^ f5_reload(&g5);
+ res ^= g5.f0 ^ g5.f1 ^ g5.f2;
+ return res;
+}
+
+/***/
+
+struct s6 {
+ _Bool f0 : 2;
+};
+
+struct s6 g6 = { 0xF };
+
+int f6_load(struct s6 *a0) {
+ return a0->f0;
+}
+int f6_store(struct s6 *a0) {
+ return a0->f0 = 0x0;
+}
+int f6_reload(struct s6 *a0) {
+ return (a0->f0 += 0xF);
+}
+
+// CHECK-OPT: define zeroext i1 @test_6()
+// CHECK-OPT: ret i1 true
+// CHECK-OPT: }
+_Bool test_6() {
+ struct s6 g6 = { 0xF };
+ unsigned long long res = 0;
+ res ^= g6.f0;
+ res ^= f6_load(&g6);
+ res ^= g6.f0;
+ return res;
+}
+
+/***/
+
+// Check that we compute the best alignment possible for each access.
+//
+// CHECK-RECORD: *** Dumping IRgen Record Layout
+// CHECK-RECORD: Record: struct s7
+// CHECK-RECORD: Layout: <CGRecordLayout
+// CHECK-RECORD: LLVMType:{ i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] }
+// CHECK-RECORD: ContainsPointerToDataMember:0
+// CHECK-RECORD: BitFields:[
+// CHECK-RECORD: <CGBitFieldInfo Size:5 IsSigned:1
+// CHECK-RECORD: NumComponents:1 Components: [
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:12 FieldBitStart:0 AccessWidth:32
+// CHECK-RECORD: AccessAlignment:4 TargetBitOffset:0 TargetBitWidth:5>
+// CHECK-RECORD: ]>
+// CHECK-RECORD: <CGBitFieldInfo Size:29 IsSigned:1
+// CHECK-RECORD: NumComponents:1 Components: [
+// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:16 FieldBitStart:0 AccessWidth:32
+// CHECK-RECORD: AccessAlignment:16 TargetBitOffset:0 TargetBitWidth:29>
+
+struct __attribute__((aligned(16))) s7 {
+ int a, b, c;
+ int f0 : 5;
+ int f1 : 29;
+};
+
+int f7_load(struct s7 *a0) {
+ return a0->f0;
+}
+
+/***/
+
+// This is a case where we narrow the access width immediately.
+
+struct __attribute__((packed)) s8 {
+ char f0 : 4;
+ char f1;
+ int f2 : 4;
+ char f3 : 4;
+};
+
+struct s8 g8 = { 0xF };
+
+int f8_load(struct s8 *a0) {
+ return a0->f0 ^ a0 ->f2 ^ a0->f3;
+}
+int f8_store(struct s8 *a0) {
+ return (a0->f0 = 0xFD) ^ (a0->f2 = 0xFD) ^ (a0->f3 = 0xFD);
+}
+int f8_reload(struct s8 *a0) {
+ return (a0->f0 += 0xFD) ^ (a0->f2 += 0xFD) ^ (a0->f3 += 0xFD);
+}
+
+// CHECK-OPT: define i32 @test_8()
+// CHECK-OPT: ret i32 -3
+// CHECK-OPT: }
+unsigned test_8() {
+ struct s8 g8 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
+ unsigned long long res = 0;
+ res ^= g8.f0 ^ g8.f2 ^ g8.f3;
+ res ^= f8_load(&g8) ^ f8_store(&g8) ^ f8_reload(&g8);
+ res ^= g8.f0 ^ g8.f2 ^ g8.f3;
+ return res;
+}
+
+/***/
+
+// This is another case where we narrow the access width immediately.
+//
+// <rdar://problem/7893760>
+
+struct __attribute__((packed)) s9 {
+ unsigned f0 : 7;
+ unsigned f1 : 7;
+ unsigned f2 : 7;
+ unsigned f3 : 7;
+ unsigned f4 : 7;
+ unsigned f5 : 7;
+ unsigned f6 : 7;
+ unsigned f7 : 7;
+};
+
+int f9_load(struct s9 *a0) {
+ return a0->f7;
+}
diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c
index 0ef10c14e0092..e7625b19542cd 100644
--- a/test/CodeGen/blocks.c
+++ b/test/CodeGen/blocks.c
@@ -12,7 +12,7 @@ struct s0 {
int a[64];
};
-// RUN: grep 'internal void @__f2_block_invoke_(.struct.s0\* noalias sret .*, .*, .* byval .*)' %t
+// RUN: grep 'internal void @__f2_block_invoke_(.struct.s0\* sret .*, .*, .* byval .*)' %t
struct s0 f2(struct s0 a0) {
return ^(struct s0 a1){ return a1; }(a0);
}
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
new file mode 100644
index 0000000000000..04249cc1ee703
--- /dev/null
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -0,0 +1,332 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+#include "altivec.h"
+
+int main ()
+{
+ vector signed char vsc = { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 };
+ vector unsigned char vuc = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ vector short vs = { -1, 2, -3, 4, -5, 6, -7, 8 };
+ vector unsigned short vus = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ vector int vi = { -1, 2, -3, 4 };
+ vector unsigned int vui = { 1, 2, 3, 4 };
+ vector float vf = { -1.5, 2.5, -3.5, 4.5 };
+
+ vector signed char res_vsc;
+ vector unsigned char res_vuc;
+ vector short res_vs;
+ vector unsigned short res_vus;
+ vector int res_vi;
+ vector unsigned int res_vui;
+ vector float res_vf;
+
+ int param_i;
+ int res_i;
+
+ /* vec_abs */
+ vsc = vec_abs(vsc); // CHECK: sub <16 x i8> zeroinitializer
+ // CHECK: @llvm.ppc.altivec.vmaxsb
+
+ vs = __builtin_vec_abs(vs); // CHECK: sub <8 x i16> zeroinitializer
+ // CHECK: @llvm.ppc.altivec.vmaxsh
+
+ vi = vec_abs(vi); // CHECK: sub <4 x i32> zeroinitializer
+ // CHECK: @llvm.ppc.altivec.vmaxsw
+
+ vf = vec_abs(vf); // CHECK: store <4 x i32> <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
+ // CHECK: and <4 x i32>
+
+ /* vec_abs */
+ vsc = vec_abss(vsc); // CHECK: @llvm.ppc.altivec.vsubsbs
+ // CHECK: @llvm.ppc.altivec.vmaxsb
+
+ vs = __builtin_vec_abss(vs); // CHECK: @llvm.ppc.altivec.vsubshs
+ // CHECK: @llvm.ppc.altivec.vmaxsh
+
+ vi = vec_abss(vi); // CHECK: @llvm.ppc.altivec.vsubsws
+ // CHECK: @llvm.ppc.altivec.vmaxsw
+
+ /* vec_add */
+ res_vsc = vec_add(vsc, vsc); // CHECK: add nsw <16 x i8>
+ res_vuc = vec_vaddubm(vuc, vuc); // CHECK: add <16 x i8>
+ res_vs = __builtin_altivec_vadduhm(vs, vs); // CHECK: add nsw <8 x i16>
+ res_vus = vec_vadduhm(vus, vus); // CHECK: add <8 x i16>
+ res_vi = __builtin_vec_vadduwm(vi, vi); // CHECK: add nsw <4 x i32>
+ res_vui = vec_vadduwm(vui, vui); // CHECK: add <4 x i32>
+ res_vf = __builtin_vec_vaddfp(vf, vf); // CHECK: fadd <4 x float>
+
+ /* vec_addc */
+ res_vui = vec_vaddcuw(vui, vui); // HECK: @llvm.ppc.altivec.vaddcuw
+
+ /* vec_adds */
+ res_vsc = vec_adds(vsc, vsc); // CHECK: @llvm.ppc.altivec.vaddsbs
+ res_vuc = vec_vaddubs(vuc, vuc); // CHECK: @llvm.ppc.altivec.vaddubs
+ res_vs = __builtin_vec_vaddshs(vs, vs); // CHECK: @llvm.ppc.altivec.vaddshs
+ res_vus = vec_vadduhs(vus, vus); // CHECK: @llvm.ppc.altivec.vadduhs
+ res_vi = __builtin_vec_vaddsws(vi, vi); // CHECK: @llvm.ppc.altivec.vaddsws
+ res_vui = vec_vadduws(vui, vui); // CHECK: @llvm.ppc.altivec.vadduws
+
+ /* vec_sub */
+ res_vsc = vec_sub(vsc, vsc); // CHECK: sub nsw <16 x i8>
+ res_vuc = vec_vsububm(vuc, vuc); // CHECK: sub <16 x i8>
+ res_vs = __builtin_altivec_vsubuhm(vs, vs); // CHECK: sub nsw <8 x i16>
+ res_vus = vec_vsubuhm(vus, vus); // CHECK: sub <8 x i16>
+ res_vi = __builtin_vec_vsubuwm(vi, vi); // CHECK: sub nsw <4 x i32>
+ res_vui = vec_vsubuwm(vui, vui); // CHECK: sub <4 x i32>
+ res_vf = __builtin_vec_vsubfp(vf, vf); // CHECK: fsub <4 x float>
+
+ /* vec_subs */
+ res_vsc = vec_subs(vsc, vsc); // CHECK: @llvm.ppc.altivec.vsubsbs
+ res_vuc = vec_vsububs(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsububs
+ res_vs = __builtin_vec_vsubshs(vs, vs); // CHECK: @llvm.ppc.altivec.vsubshs
+ res_vus = vec_vsubuhs(vus, vus); // CHECK: @llvm.ppc.altivec.vsubuhs
+ res_vi = __builtin_vec_vsubsws(vi, vi); // CHECK: @llvm.ppc.altivec.vsubsws
+ res_vui = vec_vsubuws(vui, vui); // CHECK: @llvm.ppc.altivec.vsubuws
+
+ /* vec_avg */
+ res_vsc = vec_avg(vsc, vsc); // CHECK: @llvm.ppc.altivec.vavgsb
+ res_vuc = __builtin_vec_vavgub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vavgub
+ res_vs = vec_vavgsh(vs, vs); // CHECK: @llvm.ppc.altivec.vavgsh
+ res_vus = __builtin_vec_vavguh(vus, vus); // CHECK: @llvm.ppc.altivec.vavguh
+ res_vi = vec_vavgsw(vi, vi); // CHECK: @llvm.ppc.altivec.vavgsw
+ res_vui = __builtin_vec_vavguw(vui, vui); // CHECK: @llvm.ppc.altivec.vavguw
+
+ /* vec_st */
+ param_i = 5;
+ vec_st(vsc, 0, &res_vsc); // CHECK: @llvm.ppc.altivec.stvx
+ __builtin_vec_st(vuc, param_i, &res_vuc); // CHECK: @llvm.ppc.altivec.stvx
+ vec_stvx(vs, 1, &res_vs); // CHECK: @llvm.ppc.altivec.stvx
+ vec_st(vus, 1000, &res_vus); // CHECK: @llvm.ppc.altivec.stvx
+ vec_st(vi, 0, &res_vi); // CHECK: @llvm.ppc.altivec.stvx
+ vec_st(vui, 0, &res_vui); // CHECK: @llvm.ppc.altivec.stvx
+ vec_st(vf, 0, &res_vf); // CHECK: @llvm.ppc.altivec.stvx
+
+ /* vec_stl */
+ param_i = 10000;
+ vec_stl(vsc, param_i, &res_vsc); // CHECK: @llvm.ppc.altivec.stvxl
+ __builtin_vec_stl(vuc, 1, &res_vuc); // CHECK: @llvm.ppc.altivec.stvxl
+ vec_stvxl(vs, 0, &res_vs); // CHECK: @llvm.ppc.altivec.stvxl
+ vec_stl(vus, 0, &res_vus); // CHECK: @llvm.ppc.altivec.stvxl
+ vec_stl(vi, 0, &res_vi); // CHECK: @llvm.ppc.altivec.stvxl
+ vec_stl(vui, 0, &res_vui); // CHECK: @llvm.ppc.altivec.stvxl
+ vec_stl(vf, 0, &res_vf); // CHECK: @llvm.ppc.altivec.stvxl
+
+ /* vec_ste */
+ param_i = 10000;
+ vec_ste(vsc, param_i, &res_vsc); // CHECK: @llvm.ppc.altivec.stvebx
+ vec_stvebx(vuc, 1, &res_vuc); // CHECK: @llvm.ppc.altivec.stvebx
+ __builtin_vec_stvehx(vs, 0, &res_vs); // CHECK: @llvm.ppc.altivec.stvehx
+ vec_stvehx(vus, 0, &res_vus); // CHECK: @llvm.ppc.altivec.stvehx
+ vec_stvewx(vi, 0, &res_vi); // CHECK: @llvm.ppc.altivec.stvewx
+ __builtin_vec_stvewx(vui, 0, &res_vui); // CHECK: @llvm.ppc.altivec.stvewx
+ vec_stvewx(vf, 0, &res_vf); // CHECK: @llvm.ppc.altivec.stvewx
+
+ /* vec_cmpb */
+ res_vi = vec_vcmpbfp(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp
+
+ /* vec_cmpeq */
+ res_vi = vec_cmpeq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb
+ res_vi = __builtin_vec_cmpeq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb
+ res_vi = vec_cmpeq(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh
+ res_vi = vec_cmpeq(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh
+ res_vi = vec_cmpeq(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw
+ res_vi = vec_cmpeq(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw
+ res_vi = vec_cmpeq(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp
+
+ /* vec_cmpge */
+ res_vi = __builtin_vec_cmpge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp
+
+ /* vec_cmpgt */
+ res_vi = vec_cmpgt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb
+ res_vi = vec_vcmpgtub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub
+ res_vi = __builtin_vec_vcmpgtsh(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh
+ res_vi = vec_cmpgt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh
+ res_vi = vec_cmpgt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw
+ res_vi = vec_cmpgt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw
+ res_vi = vec_cmpgt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp
+
+ /* vec_cmple */
+ res_vi = __builtin_vec_cmple(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp
+
+ /* vec_cmplt */
+ res_vi = vec_cmplt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb
+ res_vi = __builtin_vec_cmplt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub
+ res_vi = vec_cmplt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh
+ res_vi = vec_cmplt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh
+ res_vi = vec_cmplt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw
+ res_vi = vec_cmplt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw
+ res_vi = vec_cmplt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp
+
+ /* vec_max */
+ res_vsc = vec_max(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmaxsb
+ res_vuc = __builtin_vec_vmaxub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmaxub
+ res_vs = vec_vmaxsh(vs, vs); // CHECK: @llvm.ppc.altivec.vmaxsh
+ res_vus = vec_max(vus, vus); // CHECK: @llvm.ppc.altivec.vmaxuh
+ res_vi = __builtin_vec_vmaxsw(vi, vi); // CHECK: @llvm.ppc.altivec.vmaxsw
+ res_vui = vec_vmaxuw(vui, vui); // CHECK: @llvm.ppc.altivec.vmaxuw
+ res_vf = __builtin_vec_max(vf, vf); // CHECK: @llvm.ppc.altivec.vmaxfp
+
+ /* vec_mfvscr */
+ vf = vec_mfvscr(); // CHECK: @llvm.ppc.altivec.mfvscr
+
+ /* vec_min */
+ res_vsc = vec_min(vsc, vsc); // CHECK: @llvm.ppc.altivec.vminsb
+ res_vuc = __builtin_vec_vminub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vminub
+ res_vs = vec_vminsh(vs, vs); // CHECK: @llvm.ppc.altivec.vminsh
+ res_vus = vec_min(vus, vus); // CHECK: @llvm.ppc.altivec.vminuh
+ res_vi = __builtin_vec_vminsw(vi, vi); // CHECK: @llvm.ppc.altivec.vminsw
+ res_vui = vec_vminuw(vui, vui); // CHECK: @llvm.ppc.altivec.vminuw
+ res_vf = __builtin_vec_min(vf, vf); // CHECK: @llvm.ppc.altivec.vminfp
+
+ /* vec_mtvscr */
+ vec_mtvscr(vsc); // CHECK: @llvm.ppc.altivec.mtvscr
+
+ /* ------------------------------ predicates -------------------------------------- */
+
+ res_i = __builtin_vec_vcmpeq_p(__CR6_EQ, vsc, vui); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+ res_i = __builtin_vec_vcmpge_p(__CR6_EQ, vs, vi); // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+ res_i = __builtin_vec_vcmpgt_p(__CR6_EQ, vuc, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_all_eq */
+ res_i = vec_all_eq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_all_eq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_all_eq(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_all_eq(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_all_eq(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_all_eq(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_all_eq(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_all_ge */
+ res_i = vec_all_ge(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_all_ge(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_all_ge(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_all_ge(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_all_ge(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_all_ge(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_all_ge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_all_gt */
+ res_i = vec_all_gt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_all_gt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_all_gt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_all_gt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_all_gt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_all_gt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_all_gt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_all_in */
+ res_i = vec_all_in(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+
+ /* vec_all_le */
+ res_i = vec_all_le(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_all_le(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_all_le(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_all_le(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_all_le(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_all_le(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_all_le(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_all_nan */
+ res_i = vec_all_nan(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_all_ne */
+ res_i = vec_all_ne(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_all_ne(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_all_ne(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_all_ne(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_all_ne(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_all_ne(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_all_ne(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_all_nge */
+ res_i = vec_all_nge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+ /* vec_all_ngt */
+ res_i = vec_all_ngt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_all_nle */
+ res_i = vec_all_nle(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+ /* vec_all_nlt */
+ res_i = vec_all_nlt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_all_numeric */
+ res_i = vec_all_numeric(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_any_eq */
+ res_i = vec_any_eq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_any_eq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_any_eq(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_any_eq(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_any_eq(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_any_eq(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_any_eq(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_any_ge */
+ res_i = vec_any_ge(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_any_ge(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_any_ge(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_any_ge(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_any_ge(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_any_ge(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_any_ge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_any_gt */
+ res_i = vec_any_gt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_any_gt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_any_gt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_any_gt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_any_gt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_any_gt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_any_gt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_any_le */
+ res_i = vec_any_le(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_any_le(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_any_le(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_any_le(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_any_le(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_any_le(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_any_le(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_any_lt */
+ res_i = vec_any_lt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+ res_i = vec_any_lt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+ res_i = vec_any_lt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+ res_i = vec_any_lt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+ res_i = vec_any_lt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+ res_i = vec_any_lt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+ res_i = vec_any_lt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_any_nan */
+ res_i = vec_any_nan(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_any_ne */
+ res_i = vec_any_ne(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_any_ne(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p
+ res_i = vec_any_ne(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_any_ne(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p
+ res_i = vec_any_ne(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_any_ne(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p
+ res_i = vec_any_ne(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_any_nge */
+ res_i = vec_any_nge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+ /* vec_any_ngt */
+ res_i = vec_any_ngt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_any_nle */
+ res_i = vec_any_nle(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+ /* vec_any_nlt */
+ res_i = vec_any_nlt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+
+ /* vec_any_numeric */
+ res_i = vec_any_numeric(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+
+ /* vec_any_out */
+ res_i = vec_any_out(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+
+ return 0;
+}
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
new file mode 100644
index 0000000000000..fef1587fad007
--- /dev/null
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fcatch-undefined-behavior -emit-llvm-only %s
+
+// PR6805
+void foo() {
+ union { int i; } u;
+ u.i=1;
+}
diff --git a/test/CodeGen/const-unordered-compare.c b/test/CodeGen/const-unordered-compare.c
new file mode 100644
index 0000000000000..ac7d35bcd5422
--- /dev/null
+++ b/test/CodeGen/const-unordered-compare.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// Checks folding of an unordered comparison
+int nan_ne_check() {
+ // CHECK: store i32 1
+ return (__builtin_nanf("") != __builtin_nanf("")) ? 1 : 0;
+}
diff --git a/test/CodeGen/decl.c b/test/CodeGen/decl.c
index 6d068134b5893..7ffb7006b05b1 100644
--- a/test/CodeGen/decl.c
+++ b/test/CodeGen/decl.c
@@ -1,10 +1,14 @@
-// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -w -emit-llvm < %s | FileCheck %s
// CHECK: @test1.x = internal constant [12 x i32] [i32 1
// CHECK: @test2.x = internal constant [13 x i32] [i32 1,
// CHECK: @test5w = global %0 { i32 2, [4 x i8] undef }
// CHECK: @test5y = global %union.test5u { double 7.300000e+0{{[0]*}}1 }
+// CHECK: @test6.x = internal constant %struct.SelectDest { i8 1, i8 2, i32 3, i32 0 }
+
+// CHECK: @test7 = global [2 x %struct.test7s] [%struct.test7s { i32 1, i32 2 }, %struct.test7s { i32 4, i32 0 }]
+
void test1() {
// This should codegen as a "@test1.x" global.
const int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23 };
@@ -59,3 +63,29 @@ void test5() {
union test5u test5w = (union test5u)2;
union test5u test5y = (union test5u)73.0;
+
+
+// PR6660 - sqlite miscompile
+struct SelectDest {
+ unsigned char eDest;
+ unsigned char affinity;
+ int iParm;
+ int iMem;
+};
+
+void test6() {
+ struct SelectDest x = {1, 2, 3};
+ test6f(&x);
+}
+
+// rdar://7657600
+struct test7s { int a; int b; } test7[] = {
+ {1, 2},
+ {4},
+};
+
+// rdar://7872531
+#pragma pack(push, 2)
+struct test8s { int f0; char f1; } test8g = {};
+
+
diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c
index 652238f06d56a..49f57ad062c53 100644
--- a/test/CodeGen/designated-initializers.c
+++ b/test/CodeGen/designated-initializers.c
@@ -1,22 +1,37 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o %t
-// RUN: grep "{ i8\* null, i32 1024 }" %t
-// RUN: grep "i32 0, i32 22" %t
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
struct foo {
void *a;
int b;
};
+// CHECK: @u = global %union.anon zeroinitializer
union { int i; float f; } u = { };
-int main(int argc, char **argv)
-{
- union { int i; float f; } u2 = { };
- static struct foo foo = {
- .b = 1024,
- };
-}
+// CHECK: @u2 = global %0 { i32 0, [4 x i8] undef }
+union { int i; double f; } u2 = { };
+// CHECK: @u3 = global %1 zeroinitializer
+union { double f; int i; } u3 = { };
+
+// CHECK: @b = global [2 x i32] [i32 0, i32 22]
int b[2] = {
- [1] 22
+ [1] = 22
};
+
+int main(int argc, char **argv)
+{
+ // CHECK: internal global %struct.foo { i8* null, i32 1024 }
+ static struct foo foo = {
+ .b = 1024,
+ };
+
+ // CHECK: bitcast %union.anon* %u2
+ // CHECK: call void @llvm.memset
+ union { int i; float f; } u2 = { };
+
+ // CHECK-NOT: call void @llvm.memset
+ union { int i; float f; } u3;
+
+ // CHECK: ret i32
+}
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
index 5629ef582a607..a2c692d0ce3ea 100644
--- a/test/CodeGen/functions.c
+++ b/test/CodeGen/functions.c
@@ -47,3 +47,15 @@ void f7(float f, float g) {
// CHECK: define void @f7(float{{.*}}, float{{.*}})
// CHECK: call void @f6(float{{.*}}, float{{.*}})
}
+
+// PR6911 - incomplete function types
+struct Incomplete;
+void f8_callback(struct Incomplete);
+void f8_user(void (*callback)(struct Incomplete));
+void f8_test() {
+ f8_user(&f8_callback);
+// CHECK: define void @f8_test()
+// CHECK: call void @f8_user({{.*}}* bitcast (void ()* @f8_callback to {{.*}}*))
+// CHECK: declare void @f8_user({{.*}}*)
+// CHECK: declare void @f8_callback()
+}
diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c
index e166fb44659d3..351ca9e35ac72 100644
--- a/test/CodeGen/global-init.c
+++ b/test/CodeGen/global-init.c
@@ -12,19 +12,41 @@ int c __attribute__((weak))= 0;
// CHECK: @c = weak global i32 0
-
// Since this is marked const, it should get weak_odr linkage, since all
// definitions have to be the same.
// CHECK: @d = weak_odr constant i32 0
const int d __attribute__((weak))= 0;
+// PR6168 "too many undefs"
+struct ManyFields {
+ int a;
+ int b;
+ int c;
+ char d;
+ int e;
+ int f;
+};
+
+// CHECK: global %0 { i32 1, i32 2, i32 0, i8 0, i32 0, i32 0 }
+struct ManyFields FewInits = {1, 2};
+
+
+// PR6766
+// CHECK: @l = global %1 { [24 x i8] c"f\00\00\00o\00\00\00o\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", i32 1 }
+typedef __WCHAR_TYPE__ wchar_t;
+struct K {
+ wchar_t L[6];
+ int M;
+} l = { { L"foo" }, 1 };
+
+
+// CHECK: @yuv_types = global [4 x [6 x i8]] {{\[}}[6 x i8] c"4:0:0\00", [6 x i8] c"4:2:0\00", [6 x i8] c"4:2:2\00", [6 x i8] c"4:4:4\00"]
+char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
// NOTE: tentative definitions are processed at the end of the translation unit.
// This shouldn't be emitted as common because it has an explicit section.
// rdar://7119244
-int b __attribute__((section("foo")));
-
// CHECK: @b = global i32 0, section "foo"
-
+int b __attribute__((section("foo")));
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
index 13ffad173137d..d48e723c58a1a 100644
--- a/test/CodeGen/init.c
+++ b/test/CodeGen/init.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o %t
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
void f1() {
// Scalars in braces.
@@ -22,8 +22,8 @@ void f3() {
}
// Constants
-// RUN: grep '@g3 = constant i32 10' %t
-// RUN: grep '@f4.g4 = internal constant i32 12' %t
+// CHECK: @g3 = constant i32 10
+// CHECK: @f4.g4 = internal constant i32 12
const int g3 = 10;
int f4() {
static const int g4 = 12;
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index a96176afe5be8..828d7de6cb086 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -1,22 +1,52 @@
-// RUN: %clang_cc1 -fmath-errno -emit-llvm -o %t %s -triple i386-unknown-unknown
-// RUN: grep "declare " %t | count 6
-// RUN: grep "declare " %t | grep "@llvm." | count 1
-// RUN: %clang_cc1 -emit-llvm -o %t %s -triple i386-unknown-unknown
-// RUN: grep "declare " %t | count 6
-// RUN: grep "declare " %t | grep -v "@llvm." | count 0
-
-// IRgen only pays attention to const; it should always call llvm for
-// this.
-float sqrtf(float) __attribute__((const));
+// RUN: %clang_cc1 -fmath-errno -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix YES %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix NO %s
+// CHECK-YES: define void @test_sqrt
+// CHECK-NO: define void @test_sqrt
void test_sqrt(float a0, double a1, long double a2) {
+ // Following llvm-gcc's lead, we never emit these as intrinsics;
+ // no-math-errno isn't good enough. We could probably use intrinsics
+ // with appropriate guards if it proves worthwhile.
+
+ // CHECK-YES: call float @sqrtf
+ // CHECK-NO: call float @sqrtf
float l0 = sqrtf(a0);
+
+ // CHECK-YES: call double @sqrt
+ // CHECK-NO: call double @sqrt
double l1 = sqrt(a1);
+
+ // CHECK-YES: call x86_fp80 @sqrtl
+ // CHECK-NO: call x86_fp80 @sqrtl
long double l2 = sqrtl(a2);
}
+// CHECK-YES: declare float @sqrtf(float)
+// CHECK-YES: declare double @sqrt(double)
+// CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80)
+// CHECK-NO: declare float @sqrtf(float) readnone
+// CHECK-NO: declare double @sqrt(double) readnone
+// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) readnone
+
+// CHECK-YES: define void @test_pow
+// CHECK-NO: define void @test_pow
void test_pow(float a0, double a1, long double a2) {
+ // CHECK-YES: call float @powf
+ // CHECK-NO: call float @llvm.pow.f32
float l0 = powf(a0, a0);
+
+ // CHECK-YES: call double @pow
+ // CHECK-NO: call double @llvm.pow.f64
double l1 = pow(a1, a1);
+
+ // CHECK-YES: call x86_fp80 @powl
+ // CHECK-NO: call x86_fp80 @llvm.pow.f80
long double l2 = powl(a2, a2);
}
+
+// CHECK-YES: declare float @powf(float, float)
+// CHECK-YES: declare double @pow(double, double)
+// CHECK-YES: declare x86_fp80 @powl(x86_fp80, x86_fp80)
+// CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly
+// CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly
+// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly
diff --git a/test/CodeGen/palignr.c b/test/CodeGen/palignr.c
index 627e309bd940c..6297b2e990f40 100644
--- a/test/CodeGen/palignr.c
+++ b/test/CodeGen/palignr.c
@@ -1,13 +1,9 @@
// RUN: %clang_cc1 %s -triple=i686-apple-darwin -target-feature +ssse3 -O1 -S -o - | FileCheck %s
#define _mm_alignr_epi8(a, b, n) (__builtin_ia32_palignr128((a), (b), (n)))
-#define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n*8)))
-typedef __attribute__((vector_size(8))) int int2;
typedef __attribute__((vector_size(16))) int int4;
// CHECK: palignr
-int2 mmx_align1(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 7); }
-// CHECK: palignr
int4 align1(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 15); }
// CHECK: ret
// CHECK: ret
@@ -17,3 +13,18 @@ int4 align2(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 16); }
int4 align3(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 17); }
// CHECK: xor
int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); }
+
+#define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n)))
+typedef __attribute__((vector_size(8))) int int2;
+
+// CHECK-NOT: palignr
+int2 align5(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 8); }
+
+// CHECK: psrlq
+int2 align6(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 9); }
+
+// CHECK: xor
+int2 align7(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 16); }
+
+// CHECK: palignr
+int2 align8(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 7); } \ No newline at end of file
diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c
index b351d8148e910..409d14e22d39a 100644
--- a/test/CodeGen/struct-passing.c
+++ b/test/CodeGen/struct-passing.c
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s
// RUN: grep 'declare i32 @f0() readnone$' %t
// RUN: grep 'declare i32 @f1() readonly$' %t
-// RUN: grep 'declare void @f2(.* noalias sret)$' %t
-// RUN: grep 'declare void @f3(.* noalias sret)$' %t
+// RUN: grep 'declare void @f2(.* sret)$' %t
+// RUN: grep 'declare void @f3(.* sret)$' %t
// RUN: grep 'declare void @f4(.* byval)$' %t
// RUN: grep 'declare void @f5(.* byval)$' %t
// PR3835
diff --git a/test/CodeGen/union-init2.c b/test/CodeGen/union-init2.c
index ac469cd4b5125..1386c27cc0bd4 100644
--- a/test/CodeGen/union-init2.c
+++ b/test/CodeGen/union-init2.c
@@ -1,4 +1,13 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | grep "bitcast (%0\* @r to %union.x\*), \[4 x i8\] undef"
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
// Make sure we generate something sane instead of a ptrtoint
+// CHECK: bitcast (%0* @r to %union.x*), [4 x i8] undef
union x {long long b;union x* a;} r = {.a = &r};
+
+
+// CHECK: global %1 { [3 x i8] zeroinitializer, [5 x i8] undef }
+union z {
+ char a[3];
+ long long b;
+};
+union z y = {};
diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c
index eb98e1a2282a8..01c3e236f3bdc 100644
--- a/test/CodeGen/x86_32-arguments.c
+++ b/test/CodeGen/x86_32-arguments.c
@@ -1,45 +1,45 @@
// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s
-// RUN: grep 'define signext i8 @f0()' %t
-// RUN: grep 'define signext i16 @f1()' %t
-// RUN: grep 'define i32 @f2()' %t
-// RUN: grep 'define float @f3()' %t
-// RUN: grep 'define double @f4()' %t
-// RUN: grep 'define x86_fp80 @f5()' %t
-// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t
-// RUN: grep 'define void @f7(i32 %a0)' %t
-// RUN: grep 'define i64 @f8_1()' %t
-// RUN: grep 'define void @f8_2(i32 %a0.0, i32 %a0.1)' %t
+// RUN: FileCheck < %t %s
+// CHECK: define signext i8 @f0()
char f0(void) {
return 0;
}
+// CHECK: define signext i16 @f1()
short f1(void) {
return 0;
}
+// CHECK: define i32 @f2()
int f2(void) {
return 0;
}
+// CHECK: define float @f3()
float f3(void) {
return 0;
}
+// CHECK: define double @f4()
double f4(void) {
return 0;
}
+// CHECK: define x86_fp80 @f5()
long double f5(void) {
return 0;
}
+// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
void f6(char a0, short a1, int a2, long long a3, void *a4) {}
-typedef enum { A, B, C } E;
-
-void f7(E a0) {}
+// CHECK: define void @f7(i32 %a0)
+typedef enum { A, B, C } e7;
+void f7(e7 a0) {}
+// CHECK: define i64 @f8_1()
+// CHECK: define void @f8_2(i32 %a0.0, i32 %a0.1)
struct s8 {
int a;
int b;
@@ -49,11 +49,11 @@ void f8_2(struct s8 a0) {}
// This should be passed just as s8.
-// RUN: grep 'define i64 @f9_1()' %t
+// CHECK: define i64 @f9_1()
// FIXME: llvm-gcc expands this, this may have some value for the
// backend in terms of optimization but doesn't change the ABI.
-// RUN: grep 'define void @f9_2(%.truct.s9\* byval %a0)' %t
+// CHECK: define void @f9_2(%struct.s9* byval %a0)
struct s9 {
int a : 17;
int b;
@@ -63,7 +63,7 @@ void f9_2(struct s9 a0) {}
// Return of small structures and unions
-// RUN: grep 'float @f10()' %t
+// CHECK: float @f10()
struct s10 {
union { };
float f;
@@ -71,12 +71,12 @@ struct s10 {
// Small vectors and 1 x {i64,double} are returned in registers
-// RUN: grep 'i32 @f11()' %t
-// RUN: grep -F 'void @f12(<2 x i32>* noalias sret %agg.result)' %t
-// RUN: grep 'i64 @f13()' %t
-// RUN: grep 'i64 @f14()' %t
-// RUN: grep '<2 x i64> @f15()' %t
-// RUN: grep '<2 x i64> @f16()' %t
+// CHECK: i32 @f11()
+// CHECK: void @f12(<2 x i32>* sret %agg.result)
+// CHECK: i64 @f13()
+// CHECK: i64 @f14()
+// CHECK: <2 x i64> @f15()
+// CHECK: <2 x i64> @f16()
typedef short T11 __attribute__ ((vector_size (4)));
T11 f11(void) { while (1) {} }
typedef int T12 __attribute__ ((vector_size (8)));
@@ -93,12 +93,12 @@ T16 f16(void) { while (1) {} }
// And when the single element in a struct (but not for 64 and
// 128-bits).
-// RUN: grep 'i32 @f17()' %t
-// RUN: grep -F 'void @f18(%2* noalias sret %agg.result)' %t
-// RUN: grep -F 'void @f19(%3* noalias sret %agg.result)' %t
-// RUN: grep -F 'void @f20(%4* noalias sret %agg.result)' %t
-// RUN: grep -F 'void @f21(%5* noalias sret %agg.result)' %t
-// RUN: grep -F 'void @f22(%6* noalias sret %agg.result)' %t
+// CHECK: i32 @f17()
+// CHECK: void @f18(%2* sret %agg.result)
+// CHECK: void @f19(%3* sret %agg.result)
+// CHECK: void @f20(%4* sret %agg.result)
+// CHECK: void @f21(%5* sret %agg.result)
+// CHECK: void @f22(%6* sret %agg.result)
struct { T11 a; } f17(void) { while (1) {} }
struct { T12 a; } f18(void) { while (1) {} }
struct { T13 a; } f19(void) { while (1) {} }
@@ -108,97 +108,109 @@ struct { T16 a; } f22(void) { while (1) {} }
// Single element structures are handled specially
-// RUN: grep -F 'float @f23()' %t
-// RUN: grep -F 'float @f24()' %t
-// RUN: grep -F 'float @f25()' %t
+// CHECK: float @f23()
+// CHECK: float @f24()
+// CHECK: float @f25()
struct { float a; } f23(void) { while (1) {} }
struct { float a[1]; } f24(void) { while (1) {} }
struct { struct {} a; struct { float a[1]; } b; } f25(void) { while (1) {} }
// Small structures are handled recursively
-// RUN: grep -F 'i32 @f26()' %t
-// RUN: grep 'void @f27(%.truct.s27\* noalias sret %agg.result)' %t
+// CHECK: i32 @f26()
+// CHECK: void @f27(%struct.s27* sret %agg.result)
struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) { while (1) {} }
struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) { while (1) {} }
-// RUN: grep 'void @f28(%.truct.s28\* noalias sret %agg.result)' %t
+// CHECK: void @f28(%struct.s28* sret %agg.result)
struct s28 { int a; int b[]; } f28(void) { while (1) {} }
-// RUN: grep 'define i16 @f29()' %t
+// CHECK: define i16 @f29()
struct s29 { struct { } a[1]; char b; char c; } f29(void) { while (1) {} }
-// RUN: grep 'define i16 @f30()' %t
+// CHECK: define i16 @f30()
struct s30 { char a; char b : 4; } f30(void) { while (1) {} }
-// RUN: grep 'define float @f31()' %t
+// CHECK: define float @f31()
struct s31 { char : 0; float b; char : 0; } f31(void) { while (1) {} }
-// RUN: grep 'define i32 @f32()' %t
+// CHECK: define i32 @f32()
struct s32 { char a; unsigned : 0; } f32(void) { while (1) {} }
-// RUN: grep 'define float @f33()' %t
+// CHECK: define float @f33()
struct s33 { float a; long long : 0; } f33(void) { while (1) {} }
-// RUN: grep 'define float @f34()' %t
+// CHECK: define float @f34()
struct s34 { struct { int : 0; } a; float b; } f34(void) { while (1) {} }
-// RUN: grep 'define i16 @f35()' %t
+// CHECK: define i16 @f35()
struct s35 { struct { int : 0; } a; char b; char c; } f35(void) { while (1) {} }
-// RUN: grep 'define i16 @f36()' %t
+// CHECK: define i16 @f36()
struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) { while (1) {} }
-// RUN: grep 'define float @f37()' %t
+// CHECK: define float @f37()
struct s37 { float c[1][1]; } f37(void) { while (1) {} }
-// RUN: grep 'define void @f38(.struct.s38. noalias sret .agg.result)' %t
+// CHECK: define void @f38(%struct.s38* sret %agg.result)
struct s38 { char a[3]; short b; } f38(void) { while (1) {} }
-// RUN: grep 'define void @f39(.struct.s39. byval align 16 .x)' %t
+// CHECK: define void @f39(%struct.s39* byval align 16 %x)
typedef int v39 __attribute((vector_size(16)));
struct s39 { v39 x; };
void f39(struct s39 x) {}
// <rdar://problem/7247671>
-// RUN: grep 'define i32 @f40()' %t
+// CHECK: define i32 @f40()
enum e40 { ec0 = 0 };
enum e40 f40(void) { }
-// RUN: grep 'define void ()\* @f41()' %t
+// CHECK: define void ()* @f41()
typedef void (^vvbp)(void);
vvbp f41(void) { }
-// RUN: grep 'define i32 @f42()' %t
+// CHECK: define i32 @f42()
struct s42 { enum e40 f0; } f42(void) { }
-// RUN: grep 'define i64 @f43()' %t
+// CHECK: define i64 @f43()
struct s43 { enum e40 f0; int f1; } f43(void) { }
-// RUN: grep 'define i32 @f44()' %t
+// CHECK: define i32 @f44()
struct s44 { vvbp f0; } f44(void) { }
-// RUN: grep 'define i64 @f45()' %t
+// CHECK: define i64 @f45()
struct s45 { vvbp f0; int f1; } f45(void) { }
-// RUN: grep 'define void @f46(i32 %a0)' %t
+// CHECK: define void @f46(i32 %a0)
void f46(enum e40 a0) { }
-// RUN: grep 'define void @f47(void ()\* %a1)' %t
+// CHECK: define void @f47(void ()* %a1)
void f47(vvbp a1) { }
-// RUN: grep 'define void @f48(i32 %a0.0)' %t
+// CHECK: define void @f48(i32 %a0.0)
struct s48 { enum e40 f0; };
void f48(struct s48 a0) { }
-// RUN: grep 'define void @f49(i32 %a0.0, i32 %a0.1)' %t
+// CHECK: define void @f49(i32 %a0.0, i32 %a0.1)
struct s49 { enum e40 f0; int f1; };
void f49(struct s49 a0) { }
-// RUN: grep 'define void @f50(void ()\* %a0.0)' %t
+// CHECK: define void @f50(void ()* %a0.0)
struct s50 { vvbp f0; };
void f50(struct s50 a0) { }
-// RUN: grep 'define void @f51(void ()\* %a0.0, i32 %a0.1)' %t
+// CHECK: define void @f51(void ()* %a0.0, i32 %a0.1)
struct s51 { vvbp f0; int f1; };
void f51(struct s51 a0) { }
+// CHECK: define void @f52(%struct.s52* byval align 16 %x)
+struct s52 {
+ long double a;
+};
+void f52(struct s52 x) {}
+
+// CHECK: define void @f53(%struct.s53* byval align 32 %x)
+struct __attribute__((aligned(32))) s53 {
+ int x;
+ int y;
+};
+void f53(struct s53 x) {}
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index d6b9b2936045f..47b2eb1585e21 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -1,49 +1,51 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
-// RUN: grep 'define signext i8 @f0()' %t
-// RUN: grep 'define signext i16 @f1()' %t
-// RUN: grep 'define i32 @f2()' %t
-// RUN: grep 'define float @f3()' %t
-// RUN: grep 'define double @f4()' %t
-// RUN: grep 'define x86_fp80 @f5()' %t
-// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t
-// RUN: grep 'define void @f7(i32 %a0)' %t
-// RUN: grep '.0 = type { i64, double }' %t
-// RUN: grep 'define .0 @f8_1()' %t
-// RUN: grep 'define void @f8_2(.0)' %t
+// RUN: FileCheck < %t %s
+// CHECK: %0 = type { i64, double }
+
+// CHECK: define signext i8 @f0()
char f0(void) {
return 0;
}
+// CHECK: define signext i16 @f1()
short f1(void) {
return 0;
}
+// CHECK: define i32 @f2()
int f2(void) {
return 0;
}
+// CHECK: define float @f3()
float f3(void) {
return 0;
}
+// CHECK: define double @f4()
double f4(void) {
return 0;
}
+// CHECK: define x86_fp80 @f5()
long double f5(void) {
return 0;
}
+// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
void f6(char a0, short a1, int a2, long long a3, void *a4) {
}
-typedef enum { A, B, C } E;
-
-void f7(E a0) {
+// CHECK: define void @f7(i32 %a0)
+typedef enum { A, B, C } e7;
+void f7(e7 a0) {
}
// Test merging/passing of upper eightbyte with X87 class.
+//
+// CHECK: define %0 @f8_1()
+// CHECK: define void @f8_2(%0)
union u8 {
long double a;
int b;
@@ -51,48 +53,63 @@ union u8 {
union u8 f8_1() { while (1) {} }
void f8_2(union u8 a0) {}
-// RUN: grep 'define i64 @f9()' %t
+// CHECK: define i64 @f9()
struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
-// RUN: grep 'define void @f10(i64)' %t
+// CHECK: define void @f10(i64)
struct s10 { int a; int b; int : 0; };
void f10(struct s10 a0) {}
-// RUN: grep 'define void @f11(.union.anon. noalias sret .agg.result)' %t
+// CHECK: define void @f11(%struct.s19* sret %agg.result)
union { long double a; float b; } f11() { while (1) {} }
-// RUN: grep 'define i64 @f12_0()' %t
-// RUN: grep 'define void @f12_1(i64)' %t
+// CHECK: define i64 @f12_0()
+// CHECK: define void @f12_1(i64)
struct s12 { int a __attribute__((aligned(16))); };
struct s12 f12_0(void) { while (1) {} }
void f12_1(struct s12 a0) {}
// Check that sret parameter is accounted for when checking available integer
// registers.
-// RUN: grep 'define void @f13(.struct.s13_0. noalias sret .agg.result, i32 .a, i32 .b, i32 .c, i32 .d, .struct.s13_1. byval .e, i32 .f)' %t
+// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, %struct.s13_1* byval %e, i32 %f)
struct s13_0 { long long f0[3]; };
struct s13_1 { long long f0[2]; };
-struct s13_0 f13(int a, int b, int c, int d,
+struct s13_0 f13(int a, int b, int c, int d,
struct s13_1 e, int f) { while (1) {} }
-// RUN: grep 'define void @f14(.*, i8 signext .X)' %t
-void f14(int a, int b, int c, int d, int e, int f,
- char X) {}
-// RUN: grep 'define void @f15(.*, i8\* .X)' %t
-void f15(int a, int b, int c, int d, int e, int f,
- void *X) {}
-// RUN: grep 'define void @f16(.*, float .X)' %t
+// CHECK: define void @f14({{.*}}, i8 signext %X)
+void f14(int a, int b, int c, int d, int e, int f, char X) {}
+
+// CHECK: define void @f15({{.*}}, i8* %X)
+void f15(int a, int b, int c, int d, int e, int f, void *X) {}
+
+// CHECK: define void @f16({{.*}}, float %X)
void f16(float a, float b, float c, float d, float e, float f, float g, float h,
float X) {}
-// RUN: grep 'define void @f17(.*, x86_fp80 .X)' %t
+
+// CHECK: define void @f17({{.*}}, x86_fp80 %X)
void f17(float a, float b, float c, float d, float e, float f, float g, float h,
long double X) {}
// Check for valid coercion.
-// RUN: grep '.. = bitcast i64. .* to .struct.f18_s0.' %t
-// RUN: grep '.. = load .struct.f18_s0. .., align 1' %t
-// RUN: grep 'store .struct.f18_s0 .., .struct.f18_s0. .f18_arg1' %t
+// CHECK: [[f18_t0:%.*]] = bitcast i64* {{.*}} to %struct.f18_s0*
+// CHECK: [[f18_t1:%.*]] = load %struct.f18_s0* [[f18_t0]], align 1
+// CHECK: store %struct.f18_s0 [[f18_t1]], %struct.f18_s0* %f18_arg1
struct f18_s0 { int f0; };
void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
+// Check byval alignment.
+
+// CHECK: define void @f19(%struct.s19* byval align 16 %x)
+struct s19 {
+ long double a;
+};
+void f19(struct s19 x) {}
+
+// CHECK: define void @f20(%struct.s20* byval align 32 %x)
+struct __attribute__((aligned(32))) s20 {
+ int x;
+ int y;
+};
+void f20(struct s20 x) {}