diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-04 16:12:48 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-04 16:12:48 +0000 |
commit | 0883ccd9eac3b974df00e6548ee319a7dd3646f4 (patch) | |
tree | d6a70c3518b8dea8be7062438d7e8676820ed17f /test/CodeGen | |
parent | 60bfabcd8ce617297c0d231f77d14ab507e98796 (diff) |
Notes
Diffstat (limited to 'test/CodeGen')
-rw-r--r-- | test/CodeGen/2009-10-20-GlobalDebug.c | 8 | ||||
-rw-r--r-- | test/CodeGen/arm-arguments.c | 30 | ||||
-rw-r--r-- | test/CodeGen/arm_asm_clobber.c | 21 | ||||
-rw-r--r-- | test/CodeGen/asm-errors.c | 8 | ||||
-rw-r--r-- | test/CodeGen/asm.c | 21 | ||||
-rw-r--r-- | test/CodeGen/asm_arm.c | 32 | ||||
-rw-r--r-- | test/CodeGen/bitfield-2.c | 368 | ||||
-rw-r--r-- | test/CodeGen/blocks.c | 2 | ||||
-rw-r--r-- | test/CodeGen/builtins-ppc-altivec.c | 332 | ||||
-rw-r--r-- | test/CodeGen/catch-undef-behavior.c | 7 | ||||
-rw-r--r-- | test/CodeGen/const-unordered-compare.c | 7 | ||||
-rw-r--r-- | test/CodeGen/decl.c | 32 | ||||
-rw-r--r-- | test/CodeGen/designated-initializers.c | 37 | ||||
-rw-r--r-- | test/CodeGen/functions.c | 12 | ||||
-rw-r--r-- | test/CodeGen/global-init.c | 30 | ||||
-rw-r--r-- | test/CodeGen/init.c | 6 | ||||
-rw-r--r-- | test/CodeGen/libcalls.c | 50 | ||||
-rw-r--r-- | test/CodeGen/palignr.c | 19 | ||||
-rw-r--r-- | test/CodeGen/struct-passing.c | 4 | ||||
-rw-r--r-- | test/CodeGen/union-init2.c | 11 | ||||
-rw-r--r-- | test/CodeGen/x86_32-arguments.c | 126 | ||||
-rw-r--r-- | test/CodeGen/x86_64-arguments.c | 81 |
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) {} |