diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | dbe13110f59f48b4dbb7552b3ac2935acdeece7f (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /test/CodeGen | |
parent | 9da628931ebf2609493570f87824ca22402cc65f (diff) |
Notes
Diffstat (limited to 'test/CodeGen')
95 files changed, 3368 insertions, 226 deletions
diff --git a/test/CodeGen/2005-05-06-CountBuiltins.c b/test/CodeGen/2005-05-06-CountBuiltins.c deleted file mode 100644 index 4c12100dc50cf..0000000000000 --- a/test/CodeGen/2005-05-06-CountBuiltins.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 %s -emit-llvm -o %t -// RUN: not grep call*__builtin %t - -int G, H, I; -void foo(int P) { - G = __builtin_clz(P); - H = __builtin_ctz(P); - I = __builtin_popcount(P); -} - -long long g, h, i; -void fooll(float P) { - g = __builtin_clzll(P); - g = __builtin_clzll(P); - h = __builtin_ctzll(P); - i = __builtin_popcountll(P); -} diff --git a/test/CodeGen/2007-09-28-PackedUnionMember.c b/test/CodeGen/2007-09-28-PackedUnionMember.c index 943480e4d8828..f0183063ddbfc 100644 --- a/test/CodeGen/2007-09-28-PackedUnionMember.c +++ b/test/CodeGen/2007-09-28-PackedUnionMember.c @@ -27,6 +27,7 @@ extern long bork(FuncPtr handler, const struct E *list); static long hndlr() { struct H cmd = { 4, 412 }; + struct H cmd2 = { 4, 412, 0 }; return 0; } void foo(void *inWindow) { @@ -35,4 +36,3 @@ void foo(void *inWindow) { }; bork(hndlr, events); } - diff --git a/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c b/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c index 21b47052813e9..8787bd453e657 100644 --- a/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c +++ b/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c @@ -1,6 +1,5 @@ -// RUN: %clang_cc1 %s -m32 -emit-llvm -o - | grep {i32 32} | count 3 +// RUN: %clang_cc1 %s -triple powerpc-pc-linux -emit-llvm -o - | grep {i32 32} | count 3 // XFAIL: * -// XTARGET: powerpc // Every printf has 'i32 0' for the GEP of the string; no point counting those. typedef unsigned int Foo __attribute__((aligned(32))); typedef union{Foo:0;}a; diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c index 42f020e39e889..8828eef40d650 100644 --- a/test/CodeGen/2009-10-20-GlobalDebug.c +++ b/test/CodeGen/2009-10-20-GlobalDebug.c @@ -1,9 +1,10 @@ // REQUIRES: x86-registered-target -// RUN: %clang -ccc-host-triple i386-apple-darwin10 -S -g -dA %s -o - | FileCheck %s +// RUN: %clang -target i386-apple-darwin10 -flto -S -g %s -o - | FileCheck %s int global; -// CHECK: ascii "localstatic" ## DW_AT_name -// CHECK: asciz "global" ## External Name int main() { static int localstatic; return 0; } + +// CHECK: !14 = metadata !{i32 {{.*}}, i32 0, metadata !5, metadata !"localstatic", metadata !"localstatic", metadata !"", metadata !6, i32 5, metadata !9, i32 1, i32 1, i32* @main.localstatic} ; [ DW_TAG_variable ] +// CHECK: !15 = metadata !{i32 {{.*}}, i32 0, null, metadata !"global", metadata !"global", metadata !"", metadata !6, i32 3, metadata !9, i32 0, i32 1, i32* @global} ; [ DW_TAG_variable ] diff --git a/test/CodeGen/3dnow-builtins.c b/test/CodeGen/3dnow-builtins.c new file mode 100644 index 0000000000000..294fbc0579ebc --- /dev/null +++ b/test/CodeGen/3dnow-builtins.c @@ -0,0 +1,156 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-unknown-unknown -target-feature +3dnow -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +__m64 test_m_pavgusb(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pavgusb + // CHECK: @llvm.x86.3dnow.pavgusb + return _m_pavgusb(m1, m2); +} + +__m64 test_m_pf2id(__m64 m) { + // CHECK: define i64 @test_m_pf2id + // CHECK: @llvm.x86.3dnow.pf2id + return _m_pf2id(m); +} + +__m64 test_m_pfacc(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfacc + // CHECK: @llvm.x86.3dnow.pfacc + return _m_pfacc(m1, m2); +} + +__m64 test_m_pfadd(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfadd + // CHECK: @llvm.x86.3dnow.pfadd + return _m_pfadd(m1, m2); +} + +__m64 test_m_pfcmpeq(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfcmpeq + // CHECK: @llvm.x86.3dnow.pfcmpeq + return _m_pfcmpeq(m1, m2); +} + +__m64 test_m_pfcmpge(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfcmpge + // CHECK: @llvm.x86.3dnow.pfcmpge + return _m_pfcmpge(m1, m2); +} + +__m64 test_m_pfcmpgt(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfcmpgt + // CHECK: @llvm.x86.3dnow.pfcmpgt + return _m_pfcmpgt(m1, m2); +} + +__m64 test_m_pfmax(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfmax + // CHECK: @llvm.x86.3dnow.pfmax + return _m_pfmax(m1, m2); +} + +__m64 test_m_pfmin(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfmin + // CHECK: @llvm.x86.3dnow.pfmin + return _m_pfmin(m1, m2); +} + +__m64 test_m_pfmul(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfmul + // CHECK: @llvm.x86.3dnow.pfmul + return _m_pfmul(m1, m2); +} + +__m64 test_m_pfrcp(__m64 m) { + // CHECK: define i64 @test_m_pfrcp + // CHECK: @llvm.x86.3dnow.pfrcp + return _m_pfrcp(m); +} + +__m64 test_m_pfrcpit1(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfrcpit1 + // CHECK: @llvm.x86.3dnow.pfrcpit1 + return _m_pfrcpit1(m1, m2); +} + +__m64 test_m_pfrcpit2(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfrcpit2 + // CHECK: @llvm.x86.3dnow.pfrcpit2 + return _m_pfrcpit2(m1, m2); +} + +__m64 test_m_pfrsqrt(__m64 m) { + // CHECK: define i64 @test_m_pfrsqrt + // CHECK: @llvm.x86.3dnow.pfrsqrt + return _m_pfrsqrt(m); +} + +__m64 test_m_pfrsqrtit1(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfrsqrtit1 + // CHECK: @llvm.x86.3dnow.pfrsqit1 + return _m_pfrsqrtit1(m1, m2); +} + +__m64 test_m_pfsub(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfsub + // CHECK: @llvm.x86.3dnow.pfsub + return _m_pfsub(m1, m2); +} + +__m64 test_m_pfsubr(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfsubr + // CHECK: @llvm.x86.3dnow.pfsubr + return _m_pfsubr(m1, m2); +} + +__m64 test_m_pi2fd(__m64 m) { + // CHECK: define i64 @test_m_pi2fd + // CHECK: @llvm.x86.3dnow.pi2fd + return _m_pi2fd(m); +} + +__m64 test_m_pmulhrw(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pmulhrw + // CHECK: @llvm.x86.3dnow.pmulhrw + return _m_pmulhrw(m1, m2); +} + +__m64 test_m_pf2iw(__m64 m) { + // CHECK: define i64 @test_m_pf2iw + // CHECK: @llvm.x86.3dnowa.pf2iw + return _m_pf2iw(m); +} + +__m64 test_m_pfnacc(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfnacc + // CHECK: @llvm.x86.3dnowa.pfnacc + return _m_pfnacc(m1, m2); +} + +__m64 test_m_pfpnacc(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfpnacc + // CHECK: @llvm.x86.3dnowa.pfpnacc + return _m_pfpnacc(m1, m2); +} + +__m64 test_m_pi2fw(__m64 m) { + // CHECK: define i64 @test_m_pi2fw + // CHECK: @llvm.x86.3dnowa.pi2fw + return _m_pi2fw(m); +} + +__m64 test_m_pswapdsf(__m64 m) { + // CHECK: define i64 @test_m_pswapdsf + // CHECK: @llvm.x86.3dnowa.pswapd + return _m_pswapdsf(m); +} + +__m64 test_m_pswapdsi(__m64 m) { + // CHECK: define i64 @test_m_pswapdsi + // CHECK: @llvm.x86.3dnowa.pswapd + return _m_pswapdsi(m); +} diff --git a/test/CodeGen/Inputs/stdio.h b/test/CodeGen/Inputs/stdio.h new file mode 100644 index 0000000000000..cfe359597b7b2 --- /dev/null +++ b/test/CodeGen/Inputs/stdio.h @@ -0,0 +1,9 @@ +struct FILE; +extern int vfprintf(struct FILE *s, const char *format, __builtin_va_list arg); +extern int vprintf(const char *format, __builtin_va_list arg); + +extern __inline __attribute__((gnu_inline,always_inline)) int +vprintf(const char *x, __builtin_va_list y) +{ + return vfprintf (0, 0, 0); +} diff --git a/test/CodeGen/address-safety-attr.cpp b/test/CodeGen/address-safety-attr.cpp new file mode 100644 index 0000000000000..9d0fb9596330a --- /dev/null +++ b/test/CodeGen/address-safety-attr.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - %s -faddress-sanitizer | FileCheck -check-prefix ASAN %s + +// The address_safety attribute should be attached to functions +// when AddressSanitizer is enabled, unless no_address_safety_analysis attribute +// is present. + +// CHECK-NOT: NoAddressSafety1{{.*}} address_safety +// ASAN-NOT: NoAddressSafety1{{.*}} address_safety +__attribute__((no_address_safety_analysis)) +int NoAddressSafety1(int *a) { return *a; } + +// CHECK-NOT: NoAddressSafety2{{.*}} address_safety +// ASAN-NOT: NoAddressSafety2{{.*}} address_safety +__attribute__((no_address_safety_analysis)) +int NoAddressSafety2(int *a); +int NoAddressSafety2(int *a) { return *a; } + +// CHECK-NOT: AddressSafetyOk{{.*}} address_safety +// ASAN: AddressSafetyOk{{.*}} address_safety +int AddressSafetyOk(int *a) { return *a; } + +// CHECK-NOT: TemplateNoAddressSafety{{.*}} address_safety +// ASAN-NOT: TemplateNoAddressSafety{{.*}} address_safety +template<int i> +__attribute__((no_address_safety_analysis)) +int TemplateNoAddressSafety() { return i; } + +// CHECK-NOT: TemplateAddressSafetyOk{{.*}} address_safety +// ASAN: TemplateAddressSafetyOk{{.*}} address_safety +template<int i> +int TemplateAddressSafetyOk() { return i; } + +int force_instance = TemplateAddressSafetyOk<42>() + + TemplateNoAddressSafety<42>(); diff --git a/test/CodeGen/align-param.c b/test/CodeGen/align-param.c new file mode 100644 index 0000000000000..8907f66409a10 --- /dev/null +++ b/test/CodeGen/align-param.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-apple-macosx10.7.2 < %s | FileCheck %s + +// The preferred alignment for a long long on x86-32 is 8; make sure the +// alloca for x uses that alignment. +int test (long long x) { + return (int)x; +} +// CHECK: define i32 @test +// CHECK: alloca i64, align 8 + + +// Make sure we honor the aligned attribute. +struct X { int x,y,z,a; }; +int test2(struct X x __attribute((aligned(16)))) { + return x.z; +} +// CHECK: define i32 @test2 +// CHECK: alloca %struct.X, align 16 diff --git a/test/CodeGen/alignment.c b/test/CodeGen/alignment.c new file mode 100644 index 0000000000000..8882c91d03e1a --- /dev/null +++ b/test/CodeGen/alignment.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +__attribute((aligned(16))) float a[128]; +union {int a[4]; __attribute((aligned(16))) float b[4];} b; + +// CHECK: @a = {{.*}}zeroinitializer, align 16 +// CHECK: @b = {{.*}}zeroinitializer, align 16 + + + +// PR5279 - Reduced alignment on typedef. +typedef int myint __attribute__((aligned(1))); + +void test1(myint *p) { + *p = 0; +} +// CHECK: @test1( +// CHECK: store i32 0, i32* {{.*}}, align 1 +// CHECK: ret void + +int test1a(myint *p) { + return *p; +} +// CHECK: @test1a( +// CHECK: load i32* {{.*}}, align 1 +// CHECK: ret i32 + + +// PR5279 - Reduced alignment on typedef. +typedef float __attribute__((vector_size(16), aligned(4))) packedfloat4; + +void test2(packedfloat4 *p) { + *p = (packedfloat4) { 3.2f, 2.3f, 0.1f, 0.0f }; +} +// CHECK: @test2( +// CHECK: store <4 x float> {{.*}}, align 4 +// CHECK: ret void + + +// PR5279 - Reduced alignment on typedef. +typedef float __attribute__((ext_vector_type(3), aligned(4))) packedfloat3; +void test3(packedfloat3 *p) { + *p = (packedfloat3) { 3.2f, 2.3f, 0.1f }; +} +// CHECK: @test3( +// CHECK: store <3 x float> {{.*}}, align 4 +// CHECK: ret void + + + +typedef float __attribute__((vector_size(16), aligned(64))) float4align64; + +// rdar://10639962 - Typedef alignment lost in p[]-style dereferencing +void test4(float4align64 *p) { + p[0] = (float4align64){ 3.2f, 2.3f, 0.1f, 0.0f }; +} +// CHECK: @test4( +// CHECK: store <4 x float> {{.*}}, <4 x float>* {{.*}}, align 64 + diff --git a/test/CodeGen/altivec.c b/test/CodeGen/altivec.c index c3b1f42e06d8a..29823031b56ad 100644 --- a/test/CodeGen/altivec.c +++ b/test/CodeGen/altivec.c @@ -5,6 +5,15 @@ vector int test0 = (vector int)(1); // CHECK: @test0 = global <4 x i32> <i32 1, i32 1, i32 1, i32 1> vector float test1 = (vector float)(1.0); // CHECK: @test1 = global <4 x float> <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}> +// CHECK: @v1 = global <16 x i8> <i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 3, i8 0, i8 0, i8 0, i8 4> +vector char v1 = (vector char)((vector int)(1, 2, 3, 4)); +// CHECK: @v2 = global <16 x i8> <i8 63, i8 -128, i8 0, i8 0, i8 64, i8 0, i8 0, i8 0, i8 64, i8 64, i8 0, i8 0, i8 64, i8 -128, i8 0, i8 0> +vector char v2 = (vector char)((vector float)(1.0f, 2.0f, 3.0f, 4.0f)); +// CHECK: @v3 = global <16 x i8> <i8 0, i8 0, i8 0, i8 97, i8 0, i8 0, i8 0, i8 98, i8 0, i8 0, i8 0, i8 99, i8 0, i8 0, i8 0, i8 100> +vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd')); +// CHECK: @v4 = global <4 x i32> <i32 16909060, i32 0, i32 0, i32 0> +vector int v4 = (vector char){1, 2, 3, 4}; + void test2() { vector int vi; diff --git a/test/CodeGen/arm-aapcs-vfp.c b/test/CodeGen/arm-aapcs-vfp.c index 20b8a742dd414..017c14524e975 100644 --- a/test/CodeGen/arm-aapcs-vfp.c +++ b/test/CodeGen/arm-aapcs-vfp.c @@ -12,10 +12,10 @@ struct homogeneous_struct { float f3; float f4; }; -// CHECK: define arm_aapcs_vfpcc void @test_struct(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}) -extern void struct_callee(struct homogeneous_struct); -void test_struct(struct homogeneous_struct arg) { - struct_callee(arg); +// CHECK: define arm_aapcs_vfpcc %struct.homogeneous_struct @test_struct(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}) +extern struct homogeneous_struct struct_callee(struct homogeneous_struct); +struct homogeneous_struct test_struct(struct homogeneous_struct arg) { + return struct_callee(arg); } struct nested_array { diff --git a/test/CodeGen/arm-aapcs-zerolength-bitfield.c b/test/CodeGen/arm-aapcs-zerolength-bitfield.c new file mode 100644 index 0000000000000..9fece197fa820 --- /dev/null +++ b/test/CodeGen/arm-aapcs-zerolength-bitfield.c @@ -0,0 +1,236 @@ +// RUN: %clang_cc1 -target-abi aapcs -triple armv7-apple-darwin10 %s -verify + +#include <stddef.h> + +struct t1 +{ + int foo : 1; + char : 0; + char bar; +}; +static int arr1_offset[(offsetof(struct t1, bar) == 1) ? 0 : -1]; +static int arr1_sizeof[(sizeof(struct t1) == 4) ? 0 : -1]; + +struct t2 +{ + int foo : 1; + short : 0; + char bar; +}; +static int arr2_offset[(offsetof(struct t2, bar) == 2) ? 0 : -1]; +static int arr2_sizeof[(sizeof(struct t2) == 4) ? 0 : -1]; + +struct t3 +{ + int foo : 1; + int : 0; + char bar; +}; +static int arr3_offset[(offsetof(struct t3, bar) == 4) ? 0 : -1]; +static int arr3_sizeof[(sizeof(struct t3) == 8) ? 0 : -1]; + +struct t4 +{ + int foo : 1; + long : 0; + char bar; +}; +static int arr4_offset[(offsetof(struct t4, bar) == 4) ? 0 : -1]; +static int arr4_sizeof[(sizeof(struct t4) == 8) ? 0 : -1]; + +struct t5 +{ + int foo : 1; + long long : 0; + char bar; +}; +static int arr5_offset[(offsetof(struct t5, bar) == 8) ? 0 : -1]; +static int arr5_sizeof[(sizeof(struct t5) == 16) ? 0 : -1]; + +struct t6 +{ + int foo : 1; + char : 0; + char bar : 1; + char bar2; +}; +static int arr6_offset[(offsetof(struct t6, bar2) == 2) ? 0 : -1]; +static int arr6_sizeof[(sizeof(struct t6) == 4) ? 0 : -1]; + +struct t7 +{ + int foo : 1; + short : 0; + char bar1 : 1; + char bar2; +}; +static int arr7_offset[(offsetof(struct t7, bar2) == 3) ? 0 : -1]; +static int arr7_sizeof[(sizeof(struct t7) == 4) ? 0 : -1]; + +struct t8 +{ + int foo : 1; + int : 0; + char bar1 : 1; + char bar2; +}; +static int arr8_offset[(offsetof(struct t8, bar2) == 5) ? 0 : -1]; +static int arr8_sizeof[(sizeof(struct t8) == 8) ? 0 : -1]; + +struct t9 +{ + int foo : 1; + long : 0; + char bar1 : 1; + char bar2; +}; +static int arr9_offset[(offsetof(struct t9, bar2) == 5) ? 0 : -1]; +static int arr9_sizeof[(sizeof(struct t9) == 8) ? 0 : -1]; + +struct t10 +{ + int foo : 1; + long long : 0; + char bar1 : 1; + char bar2; +}; +static int arr10_offset[(offsetof(struct t10, bar2) == 9) ? 0 : -1]; +static int arr10_sizeof[(sizeof(struct t10) == 16) ? 0 : -1]; + +struct t11 +{ + int foo : 1; + long long : 0; + char : 0; + char bar1 : 1; + char bar2; +}; +static int arr11_offset[(offsetof(struct t11, bar2) == 9) ? 0 : -1]; +static int arr11_sizeof[(sizeof(struct t11) == 16) ? 0 : -1]; + +struct t12 +{ + int foo : 1; + char : 0; + long long : 0; + char : 0; + char bar; +}; +static int arr12_offset[(offsetof(struct t12, bar) == 8) ? 0 : -1]; +static int arr12_sizeof[(sizeof(struct t12) == 16) ? 0 : -1]; + +struct t13 +{ + char foo; + long : 0; + char bar; +}; +static int arr13_offset[(offsetof(struct t13, bar) == 4) ? 0 : -1]; +static int arr13_sizeof[(sizeof(struct t13) == 8) ? 0 : -1]; + +struct t14 +{ + char foo1; + int : 0; + char foo2 : 1; + short foo3 : 16; + char : 0; + short foo4 : 16; + char bar1; + int : 0; + char bar2; +}; +static int arr14_bar1_offset[(offsetof(struct t14, bar1) == 10) ? 0 : -1]; +static int arr14_bar2_offset[(offsetof(struct t14, bar2) == 12) ? 0 : -1]; +static int arr14_sizeof[(sizeof(struct t14) == 16) ? 0 : -1]; + +struct t15 +{ + char foo; + char : 0; + int : 0; + char bar; + long : 0; + char : 0; +}; +static int arr15_offset[(offsetof(struct t15, bar) == 4) ? 0 : -1]; +static int arr15_sizeof[(sizeof(struct t15) == 8) ? 0 : -1]; + +struct t16 +{ + long : 0; + char bar; +}; +static int arr16_offset[(offsetof(struct t16, bar) == 0) ? 0 : -1]; +static int arr16_sizeof[(sizeof(struct t16) == 4) ? 0 : -1]; + +struct t17 +{ + char foo; + long : 0; + long : 0; + char : 0; + char bar; +}; +static int arr17_offset[(offsetof(struct t17, bar) == 4) ? 0 : -1]; +static int arr17_sizeof[(sizeof(struct t17) == 8) ? 0 : -1]; + +struct t18 +{ + long : 0; + long : 0; + char : 0; +}; +static int arr18_sizeof[(sizeof(struct t18) == 0) ? 0 : -1]; + +struct t19 +{ + char foo1; + long foo2 : 1; + char : 0; + long foo3 : 32; + char bar; +}; +static int arr19_offset[(offsetof(struct t19, bar) == 8) ? 0 : -1]; +static int arr19_sizeof[(sizeof(struct t19) == 12) ? 0 : -1]; + +struct t20 +{ + short : 0; + int foo : 1; + long : 0; + char bar; +}; +static int arr20_offset[(offsetof(struct t20, bar) == 4) ? 0 : -1]; +static int arr20_sizeof[(sizeof(struct t20) == 8) ? 0 : -1]; + +struct t21 +{ + short : 0; + int foo1 : 1; + char : 0; + int foo2 : 16; + long : 0; + char bar1; + int bar2; + long bar3; + char foo3 : 8; + char : 0; + long : 0; + int foo4 : 32; + short foo5: 1; + long bar4; + short foo6: 16; + short foo7: 16; + short foo8: 16; +}; +static int arr21_bar1_offset[(offsetof(struct t21, bar1) == 4) ? 0 : -1]; +static int arr21_bar2_offset[(offsetof(struct t21, bar2) == 8) ? 0 : -1]; +static int arr21_bar3_offset[(offsetof(struct t21, bar3) == 12) ? 0 : -1]; +static int arr21_bar4_offset[(offsetof(struct t21, bar4) == 28) ? 0 : -1]; +static int arr21_sizeof[(sizeof(struct t21) == 40) ? 0 : -1]; + +int main() { + return 0; +} + diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c index 3ae3b8ecd21fb..4686d4ab95936 100644 --- a/test/CodeGen/arm-arguments.c +++ b/test/CodeGen/arm-arguments.c @@ -153,3 +153,15 @@ struct s29 f29() {} // AAPCS: define arm_aapcscc void @f30({{.*}} noalias sret struct s30 { _Complex int f0; }; struct s30 f30() {} + +// PR11905 +struct s31 { char x; }; +void f31(struct s31 s) { } +// AAPCS: @f31([1 x i32] %s.coerce) +// AAPCS: %s = alloca %struct.s31, align 4 +// AAPCS: alloca [1 x i32] +// AAPCS: store [1 x i32] %s.coerce, [1 x i32]* +// APCS-GNU: @f31([1 x i32] %s.coerce) +// APCS-GNU: %s = alloca %struct.s31, align 4 +// APCS-GNU: alloca [1 x i32] +// APCS-GNU: store [1 x i32] %s.coerce, [1 x i32]* diff --git a/test/CodeGen/arm-vector-align.c b/test/CodeGen/arm-vector-align.c index c1119cb5b736e..b481a0c97f8f6 100644 --- a/test/CodeGen/arm-vector-align.c +++ b/test/CodeGen/arm-vector-align.c @@ -12,8 +12,18 @@ // intrinsics. typedef float AlignedAddr __attribute__ ((aligned (16))); void t1(AlignedAddr *addr1, AlignedAddr *addr2) { +// CHECK: @t1 // CHECK: call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %{{.*}}, i32 16) float32x4_t a = vld1q_f32(addr1); // CHECK: call void @llvm.arm.neon.vst1.v4f32(i8* %{{.*}}, <4 x float> %{{.*}}, i32 16) vst1q_f32(addr2, a); } + +// Radar 10538555: Make sure unaligned load/stores do not gain alignment. +void t2(char *addr) { +// CHECK: @t2 +// CHECK: load i32* %{{.*}}, align 1 + int32x2_t vec = vld1_dup_s32(addr); +// CHECK: store i32 %{{.*}}, i32* {{.*}}, align 1 + vst1_lane_s32(addr, vec, 1); +} diff --git a/test/CodeGen/asm-inout.c b/test/CodeGen/asm-inout.c index ce524fe70fe97..c7d1aeceb92f9 100644 --- a/test/CodeGen/asm-inout.c +++ b/test/CodeGen/asm-inout.c @@ -19,21 +19,30 @@ void test2() { } // PR7338 +// CHECK: @test3 void test3(int *vout, int vin) { // CHECK: call void asm "opr $0,$1", "=*r|m|r,r|m|r,~{edi},~{dirflag},~{fpsr},~{flags}" -asm( - "opr %[vout],%[vin]" - : [vout] "=r,=m,=r" (*vout) - : [vin] "r,m,r" (vin) - : "edi" - ); + asm ("opr %[vout],%[vin]" + : [vout] "=r,=m,=r" (*vout) + : [vin] "r,m,r" (vin) + : "edi"); } // PR8959 - This should implicitly truncate the immediate to a byte. +// CHECK: @test4 int test4(volatile int *addr) { unsigned char oldval; + // CHECK: call i8 asm "frob $0", "=r,0{{.*}}"(i8 -1) __asm__ ("frob %0" : "=r"(oldval) : "0"(0xff)); return (int)oldval; -// CHECK: call i8 asm "frob $0", "=r,0{{.*}}"(i8 -1) +} + +// <rdar://problem/10919182> - This should have both inputs be of type x86_mmx. +// CHECK: @test5 +typedef long long __m64 __attribute__((__vector_size__(8))); +__m64 test5(__m64 __A, __m64 __B) { + // CHECK: call x86_mmx asm "pmulhuw $1, $0\0A\09", "=y,y,0,~{dirflag},~{fpsr},~{flags}"(x86_mmx %{{.*}}, x86_mmx %{{.*}}) + asm ("pmulhuw %1, %0\n\t" : "+y" (__A) : "y" (__B)); + return __A; } diff --git a/test/CodeGen/asm-label.c b/test/CodeGen/asm-label.c index 7be2ad3cc7a5e..c06f11fd2d24d 100644 --- a/test/CodeGen/asm-label.c +++ b/test/CodeGen/asm-label.c @@ -2,11 +2,18 @@ // RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm %s -o - | FileCheck %s --check-prefix=DARWIN char *strerror(int) asm("alias"); +int x __asm("foo"); -void test(void) -{ - strerror(-1); +int *test(void) { + static int y __asm("bar"); + strerror(-1); + return &y; } +// LINUX: @bar = internal global i32 0 +// LINUX: @foo = common global i32 0 // LINUX: declare i8* @alias(i32) + +// DARWIN: @"\01bar" = internal global i32 0 +// DARWIN: @"\01foo" = common global i32 0 // DARWIN: declare i8* @"\01alias"(i32) diff --git a/test/CodeGen/asm-variable.c b/test/CodeGen/asm-variable.c index a37132d16c236..dc087bd9e211e 100644 --- a/test/CodeGen/asm-variable.c +++ b/test/CodeGen/asm-variable.c @@ -57,3 +57,9 @@ unsigned long long foo2(unsigned long long addr, double a0, } // CHECK: call i64 asm "call *$1", "={rax},r,{xmm0},{xmm1},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},~{dirflag},~{fpsr},~{flags} + +int randomvar asm("randomvar"); +void foo3() { + asm("vartest %0" : : "r"(randomvar)); +} +// CHECK: call void asm sideeffect "vartest $0", "r,~{dirflag},~{fpsr},~{flags}" diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c index 019eb9ca3e673..84f26e1013c13 100644 --- a/test/CodeGen/asm.c +++ b/test/CodeGen/asm.c @@ -63,7 +63,6 @@ void t10(int r) { // CHECK:PR3908 $1 $3 $2 $0 } - // PR3373 unsigned t11(signed char input) { unsigned output; @@ -101,9 +100,6 @@ unsigned long t15(int x, struct large *P) { return x; } - - - // bitfield destination of an asm. struct S { int a : 4; @@ -113,7 +109,6 @@ void t14(struct S *P) { __asm__("abc %0" : "=r"(P->a) ); } - // PR4938 int t16() { int a,b; @@ -145,7 +140,6 @@ int t18(unsigned data) { // CHECK-NEXT: extractvalue } - // PR6780 int t19(unsigned data) { int a, b; @@ -156,7 +150,6 @@ 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; @@ -209,9 +202,8 @@ void *t24(char c) { return addr; } - // PR10299 - fpsr, fpcr -void test(void) +void t25(void) { __asm__ __volatile__( \ "finit" \ @@ -222,3 +214,9 @@ void test(void) "fpsr","fpcr" \ ); } + +// rdar://10510405 - AVX registers +typedef long long __m256i __attribute__((__vector_size__(32))); +void t26 (__m256i *p) { + __asm__ volatile("vmovaps %0, %%ymm0" :: "m" (*(__m256i*)p) : "ymm0"); +} diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index e2904cf10e811..1a9ed36ee23e9 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -1,8 +1,13 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s -// Basic IRGen tests for __atomic_* +// Also test serialization of atomic operations here, to avoid duplicating the +// test. +// RUN: %clang_cc1 %s -emit-pch -o %t -triple=i686-apple-darwin9 +// RUN: %clang_cc1 %s -include-pch %t -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s +#ifndef ALREADY_INCLUDED +#define ALREADY_INCLUDED -// FIXME: Need to implement __atomic_is_lock_free +// Basic IRGen tests for __c11_atomic_* and GNU __atomic_* typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, @@ -12,66 +17,298 @@ typedef enum memory_order { int fi1(_Atomic(int) *i) { // CHECK: @fi1 // CHECK: load atomic i32* {{.*}} seq_cst - return __atomic_load(i, memory_order_seq_cst); + return __c11_atomic_load(i, memory_order_seq_cst); +} + +int fi1a(int *i) { + // CHECK: @fi1a + // CHECK: load atomic i32* {{.*}} seq_cst + int v; + __atomic_load(i, &v, memory_order_seq_cst); + return v; +} + +int fi1b(int *i) { + // CHECK: @fi1b + // CHECK: load atomic i32* {{.*}} seq_cst + return __atomic_load_n(i, memory_order_seq_cst); } void fi2(_Atomic(int) *i) { // CHECK: @fi2 // CHECK: store atomic i32 {{.*}} seq_cst - __atomic_store(i, 1, memory_order_seq_cst); + __c11_atomic_store(i, 1, memory_order_seq_cst); +} + +void fi2a(int *i) { + // CHECK: @fi2a + // CHECK: store atomic i32 {{.*}} seq_cst + int v = 1; + __atomic_store(i, &v, memory_order_seq_cst); } -void fi3(_Atomic(int) *i) { +void fi2b(int *i) { + // CHECK: @fi2b + // CHECK: store atomic i32 {{.*}} seq_cst + __atomic_store_n(i, 1, memory_order_seq_cst); +} + +int fi3(_Atomic(int) *i) { // CHECK: @fi3 // CHECK: atomicrmw and - __atomic_fetch_and(i, 1, memory_order_seq_cst); + // CHECK-NOT: and + return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); +} + +int fi3a(int *i) { + // CHECK: @fi3a + // CHECK: atomicrmw xor + // CHECK-NOT: xor + return __atomic_fetch_xor(i, 1, memory_order_seq_cst); +} + +int fi3b(int *i) { + // CHECK: @fi3b + // CHECK: atomicrmw add + // CHECK: add + return __atomic_add_fetch(i, 1, memory_order_seq_cst); +} + +int fi3c(int *i) { + // CHECK: @fi3c + // CHECK: atomicrmw nand + // CHECK-NOT: and + return __atomic_fetch_nand(i, 1, memory_order_seq_cst); } -void fi4(_Atomic(int) *i) { +int fi3d(int *i) { + // CHECK: @fi3d + // CHECK: atomicrmw nand + // CHECK: and + // CHECK: xor + return __atomic_nand_fetch(i, 1, memory_order_seq_cst); +} + +_Bool fi4(_Atomic(int) *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire); +} + +_Bool fi4a(int *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + int desired = 1; + return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire); +} + +_Bool fi4b(int *i) { // CHECK: @fi4 // CHECK: cmpxchg i32* int cmp = 0; - __atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire); + return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire); } float ff1(_Atomic(float) *d) { // CHECK: @ff1 // CHECK: load atomic i32* {{.*}} monotonic - return __atomic_load(d, memory_order_relaxed); + return __c11_atomic_load(d, memory_order_relaxed); } void ff2(_Atomic(float) *d) { // CHECK: @ff2 // CHECK: store atomic i32 {{.*}} release - __atomic_store(d, 1, memory_order_release); + __c11_atomic_store(d, 1, memory_order_release); } float ff3(_Atomic(float) *d) { - return __atomic_exchange(d, 2, memory_order_seq_cst); + return __c11_atomic_exchange(d, 2, memory_order_seq_cst); } int* fp1(_Atomic(int*) *p) { // CHECK: @fp1 // CHECK: load atomic i32* {{.*}} seq_cst - return __atomic_load(p, memory_order_seq_cst); + return __c11_atomic_load(p, memory_order_seq_cst); } int* fp2(_Atomic(int*) *p) { // CHECK: @fp2 // CHECK: store i32 4 // CHECK: atomicrmw add {{.*}} monotonic - return __atomic_fetch_add(p, 1, memory_order_relaxed); + return __c11_atomic_fetch_add(p, 1, memory_order_relaxed); +} + +int *fp2a(int **p) { + // CHECK: @fp2a + // CHECK: store i32 4 + // CHECK: atomicrmw sub {{.*}} monotonic + // Note, the GNU builtins do not multiply by sizeof(T)! + return __atomic_fetch_sub(p, 4, memory_order_relaxed); } _Complex float fc(_Atomic(_Complex float) *c) { // CHECK: @fc // CHECK: atomicrmw xchg i64* - return __atomic_exchange(c, 2, memory_order_seq_cst); + return __c11_atomic_exchange(c, 2, memory_order_seq_cst); } typedef struct X { int x; } X; X fs(_Atomic(X) *c) { // CHECK: @fs // CHECK: atomicrmw xchg i32* - return __atomic_exchange(c, (X){2}, memory_order_seq_cst); + return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst); +} + +X fsa(X *c, X *d) { + // CHECK: @fsa + // CHECK: atomicrmw xchg i32* + X ret; + __atomic_exchange(c, d, &ret, memory_order_seq_cst); + return ret; } + +_Bool fsb(_Bool *c) { + // CHECK: @fsb + // CHECK: atomicrmw xchg i8* + return __atomic_exchange_n(c, 1, memory_order_seq_cst); +} + +char flag1; +volatile char flag2; +void test_and_set() { + // CHECK: atomicrmw xchg i8* @flag1, i8 1 seq_cst + __atomic_test_and_set(&flag1, memory_order_seq_cst); + // CHECK: atomicrmw volatile xchg i8* @flag2, i8 1 acquire + __atomic_test_and_set(&flag2, memory_order_acquire); + // CHECK: store atomic volatile i8 0, i8* @flag2 release + __atomic_clear(&flag2, memory_order_release); + // CHECK: store atomic i8 0, i8* @flag1 seq_cst + __atomic_clear(&flag1, memory_order_seq_cst); +} + +struct Sixteen { + char c[16]; +} sixteen; +struct Seventeen { + char c[17]; +} seventeen; + +int lock_free(struct Incomplete *incomplete) { + // CHECK: @lock_free + + // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null) + __c11_atomic_is_lock_free(3); + + // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) + __atomic_is_lock_free(16, &sixteen); + + // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) + __atomic_is_lock_free(17, &seventeen); + + // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + __atomic_is_lock_free(4, incomplete); + + char cs[20]; + // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + __atomic_is_lock_free(4, cs+1); + + // CHECK-NOT: call + __atomic_always_lock_free(3, 0); + __atomic_always_lock_free(16, 0); + __atomic_always_lock_free(17, 0); + __atomic_always_lock_free(16, &sixteen); + __atomic_always_lock_free(17, &seventeen); + + int n; + __atomic_is_lock_free(4, &n); + + // CHECK: ret i32 1 + return __c11_atomic_is_lock_free(sizeof(_Atomic(int))); +} + +// Tests for atomic operations on big values. These should call the functions +// defined here: +// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface + +struct foo { + int big[128]; +}; +struct bar { + char c[3]; +}; + +struct bar smallThing, thing1, thing2; +struct foo bigThing; +_Atomic(struct foo) bigAtomic; + +void structAtomicStore() { + // CHECK: @structAtomicStore + struct foo f = {0}; + __c11_atomic_store(&bigAtomic, f, 5); + // CHECK: call void @__atomic_store(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), + + struct bar b = {0}; + __atomic_store(&smallThing, &b, 5); + // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing + + __atomic_store(&bigThing, &f, 5); + // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing +} +void structAtomicLoad() { + // CHECK: @structAtomicLoad + struct foo f = __c11_atomic_load(&bigAtomic, 5); + // CHECK: call void @__atomic_load(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), + + struct bar b; + __atomic_load(&smallThing, &b, 5); + // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing + + __atomic_load(&bigThing, &f, 5); + // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing +} +struct foo structAtomicExchange() { + // CHECK: @structAtomicExchange + struct foo f = {0}; + struct foo old; + __atomic_exchange(&f, &bigThing, &old, 5); + // CHECK: call void @__atomic_exchange(i32 512, {{.*}}, i8* bitcast ({{.*}} @bigThing to i8*), + + return __c11_atomic_exchange(&bigAtomic, f, 5); + // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), +} +int structAtomicCmpExchange() { + // CHECK: @structAtomicCmpExchange + _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5); + // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2 + + struct foo f = {0}; + struct foo g = {0}; + g.big[12] = 12; + return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5); + // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), +} + +// Check that no atomic operations are used in any initialisation of _Atomic +// types. +_Atomic(int) atomic_init_i = 42; + +// CHECK: @atomic_init_foo +void atomic_init_foo() +{ + // CHECK-NOT: } + // CHECK-NOT: atomic + // CHECK: store + _Atomic(int) j = 12; + + // CHECK-NOT: } + // CHECK-NOT: atomic + // CHECK: store + __c11_atomic_init(&j, 42); + + // CHECK-NOT: atomic + // CHECK: } +} + +#endif diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c index c8f4fd09bbc51..ac3848f02f9e6 100644 --- a/test/CodeGen/atomic.c +++ b/test/CodeGen/atomic.c @@ -8,6 +8,7 @@ int atomic(void) { _Bool valb = 0; unsigned int uval = 1; int cmp = 0; + int* ptrval; old = __sync_fetch_and_add(&val, 1); // CHECK: atomicrmw add i32* %val, i32 1 seq_cst @@ -75,8 +76,11 @@ int atomic(void) { // CHECK: cmpxchg i32* null, i32 0, i32 0 seq_cst __sync_lock_release(&val); - // CHECK: store atomic {{.*}} release, align 4 - + // CHECK: store atomic i32 0, {{.*}} release, align 4 + + __sync_lock_release(&ptrval); + // CHECK: store atomic i32 0, {{.*}} release, align 4 + __sync_synchronize (); // CHECK: fence seq_cst diff --git a/test/CodeGen/atomic_ops.c b/test/CodeGen/atomic_ops.c new file mode 100644 index 0000000000000..9a18c9e94492e --- /dev/null +++ b/test/CodeGen/atomic_ops.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo(void) +{ + _Atomic(int) i = 0; + // Check that multiply / divides on atomics produce a cmpxchg loop + i *= 2; // CHECK: cmpxchg + i /= 2; // CHECK: cmpxchg + // These should be emitting atomicrmw instructions, but they aren't yet + i += 2; // CHECK: cmpxchg + i -= 2; // CHECK: cmpxchg + i++; // CHECK: cmpxchg + i--; // CHECK: cmpxchg +} diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c new file mode 100644 index 0000000000000..b963c97cc18a6 --- /dev/null +++ b/test/CodeGen/avx-builtins.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +// +// Test LLVM IR codegen of shuffle instructions +// + +__m256 test__mm256_loadu_ps(void* p) { + // CHECK: load <8 x float>* %{{.*}}, align 1 + return _mm256_loadu_ps(p); +} + +__m256d test__mm256_loadu_pd(void* p) { + // CHECK: load <4 x double>* %{{.*}}, align 1 + return _mm256_loadu_pd(p); +} + +__m256i test__mm256_loadu_si256(void* p) { + // CHECK: load <4 x i64>* %{{.+}}, align 1 + return _mm256_loadu_si256(p); +} diff --git a/test/CodeGen/avx-shuffle-builtins.c b/test/CodeGen/avx-shuffle-builtins.c index c11780a5e392f..538ae50c938de 100644 --- a/test/CodeGen/avx-shuffle-builtins.c +++ b/test/CodeGen/avx-shuffle-builtins.c @@ -14,3 +14,52 @@ __m256 x(__m256 a, __m256 b) { // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 8, i32 11, i32 7, i32 6, i32 12, i32 15> return _mm256_shuffle_ps(a, b, 203); } + +__m128d test_mm_permute_pd(__m128d a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 1, i32 0> + return _mm_permute_pd(a, 1); +} + +__m256d test_mm256_permute_pd(__m256d a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 1, i32 0, i32 3, i32 2> + return _mm256_permute_pd(a, 5); +} + +__m128 test_mm_permute_ps(__m128 a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0> + return _mm_permute_ps(a, 0x1b); +} + +// Test case for PR12401 +__m128 test_mm_permute_ps2(__m128 a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 2, i32 1, i32 2, i32 3> + return _mm_permute_ps(a, 0xe6); +} + +__m256 test_mm256_permute_ps(__m256 a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4> + return _mm256_permute_ps(a, 0x1b); +} + +__m256d test_mm256_permute2f128_pd(__m256d a, __m256d b) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 2, i32 3, i32 6, i32 7> + return _mm256_permute2f128_pd(a, b, 0x31); +} + +__m256 test_mm256_permute2f128_ps(__m256 a, __m256 b) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 12, i32 13, i32 14, i32 15, i32 4, i32 5, i32 6, i32 7> + return _mm256_permute2f128_ps(a, b, 0x13); +} + +__m256i test_mm256_permute2f128_si256(__m256i a, __m256i b) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> + return _mm256_permute2f128_si256(a, b, 0x20); +} diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c new file mode 100644 index 0000000000000..a5ddc8eb2ed82 --- /dev/null +++ b/test/CodeGen/avx2-builtins.c @@ -0,0 +1,782 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx2 -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +__m256i test_mm256_mpsadbw_epu8(__m256i x, __m256i y) { + // CHECK: @llvm.x86.avx2.mpsadbw({{.*}}, {{.*}}, i32 3) + return _mm256_mpsadbw_epu8(x, y, 3); +} + +__m256i test_mm256_abs_epi8(__m256i a) { + // CHECK: @llvm.x86.avx2.pabs.b + return _mm256_abs_epi8(a); +} + +__m256i test_mm256_abs_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.pabs.w + return _mm256_abs_epi16(a); +} + +__m256i test_mm256_abs_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.pabs.d + return _mm256_abs_epi32(a); +} + +__m256i test_mm256_packs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packsswb + return _mm256_packs_epi16(a, b); +} + +__m256i test_mm256_packs_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packssdw + return _mm256_packs_epi32(a, b); +} + +__m256i test_mm256_packs_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packuswb + return _mm256_packus_epi16(a, b); +} + +__m256i test_mm256_packs_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packusdw + return _mm256_packus_epi32(a, b); +} + +__m256i test_mm256_add_epi8(__m256i a, __m256i b) { + // CHECK: add <32 x i8> + return _mm256_add_epi8(a, b); +} + +__m256i test_mm256_add_epi16(__m256i a, __m256i b) { + // CHECK: add <16 x i16> + return _mm256_add_epi16(a, b); +} + +__m256i test_mm256_add_epi32(__m256i a, __m256i b) { + // CHECK: add <8 x i32> + return _mm256_add_epi32(a, b); +} + +__m256i test_mm256_add_epi64(__m256i a, __m256i b) { + // CHECK: add <4 x i64> + return _mm256_add_epi64(a, b); +} + +__m256i test_mm256_adds_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.padds.b + return _mm256_adds_epi8(a, b); +} + +__m256i test_mm256_adds_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.padds.w + return _mm256_adds_epi16(a, b); +} + +__m256i test_mm256_adds_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.paddus.b + return _mm256_adds_epu8(a, b); +} + +__m256i test_mm256_adds_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.paddus.w + return _mm256_adds_epu16(a, b); +} + +__m256i test_mm256_alignr_epi8(__m256i a, __m256i b) { + // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <32 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 32, i32 33, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 48, i32 49> + return _mm256_alignr_epi8(a, b, 2); +} + +__m256i test2_mm256_alignr_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrl.dq({{.*}}, i32 8) + return _mm256_alignr_epi8(a, b, 17); +} + +__m256i test_mm256_sub_epi8(__m256i a, __m256i b) { + // CHECK: sub <32 x i8> + return _mm256_sub_epi8(a, b); +} + +__m256i test_mm256_sub_epi16(__m256i a, __m256i b) { + // CHECK: sub <16 x i16> + return _mm256_sub_epi16(a, b); +} + +__m256i test_mm256_sub_epi32(__m256i a, __m256i b) { + // CHECK: sub <8 x i32> + return _mm256_sub_epi32(a, b); +} + +__m256i test_mm256_sub_epi64(__m256i a, __m256i b) { + // CHECK: sub <4 x i64> + return _mm256_sub_epi64(a, b); +} + +__m256i test_mm256_subs_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubs.b + return _mm256_subs_epi8(a, b); +} + +__m256i test_mm256_subs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubs.w + return _mm256_subs_epi16(a, b); +} + +__m256i test_mm256_subs_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubus.b + return _mm256_subs_epu8(a, b); +} + +__m256i test_mm256_subs_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubus.w + return _mm256_subs_epu16(a, b); +} + +__m256i test_mm256_and_si256(__m256i a, __m256i b) { + // CHECK: and <4 x i64> + return _mm256_and_si256(a, b); +} + +__m256i test_mm256_andnot_si256(__m256i a, __m256i b) { + // CHECK: xor <4 x i64> + // CHECK: and <4 x i64> + return _mm256_andnot_si256(a, b); +} + +__m256i test_mm256_or_si256(__m256i a, __m256i b) { + // CHECK: or <4 x i64> + return _mm256_or_si256(a, b); +} + +__m256i test_mm256_xor_si256(__m256i a, __m256i b) { + // CHECK: xor <4 x i64> + return _mm256_xor_si256(a, b); +} + +__m256i test_mm256_avg_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pavg.b + return _mm256_avg_epu8(a, b); +} + +__m256i test_mm256_avg_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pavg.w + return _mm256_avg_epu16(a, b); +} + +__m256i test_mm256_blendv_epi8(__m256i a, __m256i b, __m256i m) { + // CHECK: @llvm.x86.avx2.pblendvb + return _mm256_blendv_epi8(a, b, m); +} + +__m256i test_mm256_blend_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pblendw(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, i32 2) + return _mm256_blend_epi16(a, b, 2); +} + +__m256i test_mm256_cmpeq_epi8(__m256i a, __m256i b) { + // CHECK: icmp eq <32 x i8> + return _mm256_cmpeq_epi8(a, b); +} + +__m256i test_mm256_cmpeq_epi16(__m256i a, __m256i b) { + // CHECK: icmp eq <16 x i16> + return _mm256_cmpeq_epi16(a, b); +} + +__m256i test_mm256_cmpeq_epi32(__m256i a, __m256i b) { + // CHECK: icmp eq <8 x i32> + return _mm256_cmpeq_epi32(a, b); +} + +__m256i test_mm256_cmpeq_epi64(__m256i a, __m256i b) { + // CHECK: icmp eq <4 x i64> + return _mm256_cmpeq_epi64(a, b); +} + +__m256i test_mm256_cmpgt_epi8(__m256i a, __m256i b) { + // CHECK: icmp sgt <32 x i8> + return _mm256_cmpgt_epi8(a, b); +} + +__m256i test_mm256_cmpgt_epi16(__m256i a, __m256i b) { + // CHECK: icmp sgt <16 x i16> + return _mm256_cmpgt_epi16(a, b); +} + +__m256i test_mm256_cmpgt_epi32(__m256i a, __m256i b) { + // CHECK: icmp sgt <8 x i32> + return _mm256_cmpgt_epi32(a, b); +} + +__m256i test_mm256_cmpgt_epi64(__m256i a, __m256i b) { + // CHECK: icmp sgt <4 x i64> + return _mm256_cmpgt_epi64(a, b); +} + +__m256i test_mm256_hadd_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phadd.w + return _mm256_hadd_epi16(a, b); +} + +__m256i test_mm256_hadd_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phadd.d + return _mm256_hadd_epi32(a, b); +} + +__m256i test_mm256_hadds_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phadd.sw + return _mm256_hadds_epi16(a, b); +} + +__m256i test_mm256_hsub_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phsub.w + return _mm256_hsub_epi16(a, b); +} + +__m256i test_mm256_hsub_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phsub.d + return _mm256_hsub_epi32(a, b); +} + +__m256i test_mm256_hsubs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phsub.sw + return _mm256_hsubs_epi16(a, b); +} + +__m256i test_mm256_maddubs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmadd.ub.sw + return _mm256_maddubs_epi16(a, b); +} + +__m256i test_mm256_madd_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmadd.wd + return _mm256_madd_epi16(a, b); +} + +__m256i test_mm256_max_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxs.b + return _mm256_max_epi8(a, b); +} + +__m256i test_mm256_max_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxs.w + return _mm256_max_epi16(a, b); +} + +__m256i test_mm256_max_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxs.d + return _mm256_max_epi32(a, b); +} + +__m256i test_mm256_max_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxu.b + return _mm256_max_epu8(a, b); +} + +__m256i test_mm256_max_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxu.w + return _mm256_max_epu16(a, b); +} + +__m256i test_mm256_max_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxu.d + return _mm256_max_epu32(a, b); +} + +__m256i test_mm256_min_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmins.b + return _mm256_min_epi8(a, b); +} + +__m256i test_mm256_min_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmins.w + return _mm256_min_epi16(a, b); +} + +__m256i test_mm256_min_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmins.d + return _mm256_min_epi32(a, b); +} + +__m256i test_mm256_min_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pminu.b + return _mm256_min_epu8(a, b); +} + +__m256i test_mm256_min_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pminu.w + return _mm256_min_epu16(a, b); +} + +__m256i test_mm256_min_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pminu.d + return _mm256_min_epu32(a, b); +} + +int test_mm256_movemask_epi8(__m256i a) { + // CHECK: @llvm.x86.avx2.pmovmskb + return _mm256_movemask_epi8(a); +} + +__m256i test_mm256_cvtepi8_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxbw + return _mm256_cvtepi8_epi16(a); +} + +__m256i test_mm256_cvtepi8_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxbd + return _mm256_cvtepi8_epi32(a); +} + +__m256i test_mm256_cvtepi8_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxbq + return _mm256_cvtepi8_epi64(a); +} + +__m256i test_mm256_cvtepi16_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxwd + return _mm256_cvtepi16_epi32(a); +} + +__m256i test_mm256_cvtepi16_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxwq + return _mm256_cvtepi16_epi64(a); +} + +__m256i test_mm256_cvtepi32_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxdq + return _mm256_cvtepi32_epi64(a); +} + +__m256i test_mm256_cvtepu8_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxbw + return _mm256_cvtepu8_epi16(a); +} + +__m256i test_mm256_cvtepu8_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxbd + return _mm256_cvtepu8_epi32(a); +} + +__m256i test_mm256_cvtepu8_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxbq + return _mm256_cvtepu8_epi64(a); +} + +__m256i test_mm256_cvtepu16_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxwd + return _mm256_cvtepu16_epi32(a); +} + +__m256i test_mm256_cvtepu16_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxwq + return _mm256_cvtepu16_epi64(a); +} + +__m256i test_mm256_cvtepu32_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxdq + return _mm256_cvtepu32_epi64(a); +} + +__m256i test_mm256_mul_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmul.dq + return _mm256_mul_epi32(a, b); +} + +__m256i test_mm256_mulhrs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmul.hr.sw + return _mm256_mulhrs_epi16(a, b); +} + +__m256i test_mm256_mulhi_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmulhu.w + return _mm256_mulhi_epu16(a, b); +} + +__m256i test_mm256_mulhi_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmulh.w + return _mm256_mulhi_epi16(a, b); +} + +__m256i test_mm256_mullo_epi16(__m256i a, __m256i b) { + // CHECK: mul <16 x i16> + return _mm256_mullo_epi16(a, b); +} + +__m256i test_mm256_mullo_epi32(__m256i a, __m256i b) { + // CHECK: mul <8 x i32> + return _mm256_mullo_epi32(a, b); +} + +__m256i test_mm256_mul_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmulu.dq + return _mm256_mul_epu32(a, b); +} + +__m256i test_mm256_shuffle_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pshuf.b + return _mm256_shuffle_epi8(a, b); +} + +__m256i test_mm256_shuffle_epi32(__m256i a) { + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> undef, <8 x i32> <i32 3, i32 3, i32 0, i32 0, i32 7, i32 7, i32 4, i32 4> + return _mm256_shuffle_epi32(a, 15); +} + +__m256i test_mm256_shufflehi_epi16(__m256i a) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 7, i32 6, i32 6, i32 5, i32 8, i32 9, i32 10, i32 11, i32 15, i32 14, i32 14, i32 13> + return _mm256_shufflehi_epi16(a, 107); +} + +__m256i test_mm256_shufflelo_epi16(__m256i a) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> undef, <16 x i32> <i32 3, i32 0, i32 1, i32 1, i32 4, i32 5, i32 6, i32 7, i32 11, i32 8, i32 9, i32 9, i32 12, i32 13, i32 14, i32 15> + return _mm256_shufflelo_epi16(a, 83); +} + +__m256i test_mm256_sign_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psign.b + return _mm256_sign_epi8(a, b); +} + +__m256i test_mm256_sign_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psign.w + return _mm256_sign_epi16(a, b); +} + +__m256i test_mm256_sign_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psign.d + return _mm256_sign_epi32(a, b); +} + +__m256i test_mm256_slli_si256(__m256i a) { + // CHECK: @llvm.x86.avx2.psll.dq + return _mm256_slli_si256(a, 3); +} + +__m256i test_mm256_slli_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.pslli.w + return _mm256_slli_epi16(a, 3); +} + +__m256i test_mm256_sll_epi16(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psll.w + return _mm256_sll_epi16(a, b); +} + +__m256i test_mm256_slli_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.pslli.d + return _mm256_slli_epi32(a, 3); +} + +__m256i test_mm256_sll_epi32(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psll.d + return _mm256_sll_epi32(a, b); +} + +__m256i test_mm256_slli_epi64(__m256i a) { + // CHECK: @llvm.x86.avx2.pslli.q + return _mm256_slli_epi64(a, 3); +} + +__m256i test_mm256_sll_epi64(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psll.q + return _mm256_sll_epi64(a, b); +} + +__m256i test_mm256_srai_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.psrai.w + return _mm256_srai_epi16(a, 3); +} + +__m256i test_mm256_sra_epi16(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psra.w + return _mm256_sra_epi16(a, b); +} + +__m256i test_mm256_srai_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.psrai.d + return _mm256_srai_epi32(a, 3); +} + +__m256i test_mm256_sra_epi32(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psra.d + return _mm256_sra_epi32(a, b); +} + +__m256i test_mm256_srli_si256(__m256i a) { + // CHECK: @llvm.x86.avx2.psrl.dq + return _mm256_srli_si256(a, 3); +} + +__m256i test_mm256_srli_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.psrli.w + return _mm256_srli_epi16(a, 3); +} + +__m256i test_mm256_srl_epi16(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrl.w + return _mm256_srl_epi16(a, b); +} + +__m256i test_mm256_srli_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.psrli.d + return _mm256_srli_epi32(a, 3); +} + +__m256i test_mm256_srl_epi32(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrl.d + return _mm256_srl_epi32(a, b); +} + +__m256i test_mm256_srli_epi64(__m256i a) { + // CHECK: @llvm.x86.avx2.psrli.q + return _mm256_srli_epi64(a, 3); +} + +__m256i test_mm256_srl_epi64(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrl.q + return _mm256_srl_epi64(a, b); +} + +__m256i test_mm256_unpackhi_epi8(__m256i a, __m256i b) { + // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <32 x i32> <i32 8, i32 40, i32 9, i32 41, i32 10, i32 42, i32 11, i32 43, i32 12, i32 44, i32 13, i32 45, i32 14, i32 46, i32 15, i32 47, i32 24, i32 56, i32 25, i32 57, i32 26, i32 58, i32 27, i32 59, i32 28, i32 60, i32 29, i32 61, i32 30, i32 62, i32 31, i32 63> + return _mm256_unpackhi_epi8(a, b); +} + +__m256i test_mm256_unpackhi_epi16(__m256i a, __m256i b) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23, i32 12, i32 28, i32 13, i32 29, i32 14, i32 30, i32 15, i32 31> + return _mm256_unpackhi_epi16(a, b); +} + +__m256i test_mm256_unpackhi_epi32(__m256i a, __m256i b) { + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 2, i32 10, i32 3, i32 11, i32 6, i32 14, i32 7, i32 15> + return _mm256_unpackhi_epi32(a, b); +} + +__m256i test_mm256_unpackhi_epi64(__m256i a, __m256i b) { + // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + return _mm256_unpackhi_epi64(a, b); +} + +__m256i test_mm256_unpacklo_epi8(__m256i a, __m256i b) { + // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <32 x i32> <i32 0, i32 32, i32 1, i32 33, i32 2, i32 34, i32 3, i32 35, i32 4, i32 36, i32 5, i32 37, i32 6, i32 38, i32 7, i32 39, i32 16, i32 48, i32 17, i32 49, i32 18, i32 50, i32 19, i32 51, i32 20, i32 52, i32 21, i32 53, i32 22, i32 54, i32 23, i32 55> + return _mm256_unpacklo_epi8(a, b); +} + +__m256i test_mm256_unpacklo_epi16(__m256i a, __m256i b) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 8, i32 24, i32 9, i32 25, i32 10, i32 26, i32 11, i32 27> + return _mm256_unpacklo_epi16(a, b); +} + +__m256i test_mm256_unpacklo_epi32(__m256i a, __m256i b) { + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 0, i32 8, i32 1, i32 9, i32 4, i32 12, i32 5, i32 13> + return _mm256_unpacklo_epi32(a, b); +} + +__m256i test_mm256_unpacklo_epi64(__m256i a, __m256i b) { + // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 0, i32 4, i32 2, i32 6> + return _mm256_unpacklo_epi64(a, b); +} + +__m256i test_mm256_stream_load_si256(__m256i *a) { + // CHECK: @llvm.x86.avx2.movntdqa + return _mm256_stream_load_si256(a); +} + +__m128 test_mm_broadcastss_ps(__m128 a) { + // CHECK: @llvm.x86.avx2.vbroadcast.ss.ps + return _mm_broadcastss_ps(a); +} + +__m256 test_mm256_broadcastss_ps(__m128 a) { + // CHECK: @llvm.x86.avx2.vbroadcast.ss.ps.256 + return _mm256_broadcastss_ps(a); +} + +__m256d test_mm256_broadcastsd_pd(__m128d a) { + // check: @llvm.x86.avx2.vbroadcast.sd.pd.256 + return _mm256_broadcastsd_pd(a); +} + +__m256i test_mm_broadcastsi128_si256(__m128i *a) { + // CHECK: @llvm.x86.avx2.vbroadcasti128 + return _mm_broadcastsi128_si256(a); +} + +__m128i test_mm_blend_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.pblendd.128 + return _mm_blend_epi32(a, b, 57); +} + +__m256i test_mm256_blend_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pblendd.256 + return _mm256_blend_epi32(a, b, 57); +} + +__m256i test_mm256_broadcastb_epi8(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastb.256 + return _mm256_broadcastb_epi8(a); +} + +__m256i test_mm256_broadcastw_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastw.256 + return _mm256_broadcastw_epi16(a); +} + +__m256i test_mm256_broadcastd_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastd.256 + return _mm256_broadcastd_epi32(a); +} + +__m256i test_mm256_broadcastq_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastq.256 + return _mm256_broadcastq_epi64(a); +} + +__m128i test_mm_broadcastb_epi8(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastb.128 + return _mm_broadcastb_epi8(a); +} + +__m128i test_mm_broadcastw_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastw.128 + return _mm_broadcastw_epi16(a); +} + +__m128i test_mm_broadcastd_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastd.128 + return _mm_broadcastd_epi32(a); +} + +__m128i test_mm_broadcastq_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastq.128 + return _mm_broadcastq_epi64(a); +} + +__m256i test_mm256_permutevar8x32_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.permd + return _mm256_permutevar8x32_epi32(a, b); +} + +__m256d test_mm256_permute4x64_pd(__m256d a) { + // CHECK: @llvm.x86.avx2.permpd + return _mm256_permute4x64_pd(a, 25); +} + +__m256 test_mm256_permutevar8x32_ps(__m256 a, __m256 b) { + // CHECK: @llvm.x86.avx2.permps + return _mm256_permutevar8x32_ps(a, b); +} + +__m256i test_mm256_permute4x64_epi64(__m256i a) { + // CHECK: @llvm.x86.avx2.permq + return _mm256_permute4x64_epi64(a, 35); +} + +__m256i test_mm256_permute2x128_si256(__m256i a, __m256i b) { + // CHECK: shufflevector{{.*}}<i32 2, i32 3, i32 6, i32 7> + return _mm256_permute2x128_si256(a, b, 0x31); +} + +__m128i test_mm256_extracti128_si256(__m256i a) { + // CHECK: @llvm.x86.avx2.vextracti128 + return _mm256_extracti128_si256(a, 1); +} + +__m256i test_mm256_inserti128_si256(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.vinserti128 + return _mm256_inserti128_si256(a, b, 1); +} + +__m256i test_mm256_maskload_epi32(int const *a, __m256i m) { + // CHECK: @llvm.x86.avx2.maskload.d.256 + return _mm256_maskload_epi32(a, m); +} + +__m256i test_mm256_maskload_epi64(long long const *a, __m256i m) { + // CHECK: @llvm.x86.avx2.maskload.q.256 + return _mm256_maskload_epi64(a, m); +} + +__m128i test_mm_maskload_epi32(int const *a, __m128i m) { + // CHECK: @llvm.x86.avx2.maskload.d + return _mm_maskload_epi32(a, m); +} + +__m128i test_mm_maskload_epi64(long long const *a, __m128i m) { + // CHECK: @llvm.x86.avx2.maskload.q + return _mm_maskload_epi64(a, m); +} + +void test_mm256_maskstore_epi32(int *a, __m256i m, __m256i b) { + // CHECK: @llvm.x86.avx2.maskstore.d.256 + _mm256_maskstore_epi32(a, m, b); +} + +void test_mm256_maskstore_epi64(long long *a, __m256i m, __m256i b) { + // CHECK: @llvm.x86.avx2.maskstore.q.256 + _mm256_maskstore_epi64(a, m, b); +} + +void test_mm_maskstore_epi32(int *a, __m128i m, __m128i b) { + // CHECK: @llvm.x86.avx2.maskstore.d + _mm_maskstore_epi32(a, m, b); +} + +void test_mm_maskstore_epi64(long long *a, __m128i m, __m128i b) { + // CHECK: @llvm.x86.avx2.maskstore.q + _mm_maskstore_epi64(a, m, b); +} + +__m256i test_mm256_sllv_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psllv.d.256 + return _mm256_sllv_epi32(a, b); +} + +__m128i test_mm_sllv_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psllv.d + return _mm_sllv_epi32(a, b); +} + +__m256i test_mm256_sllv_epi64(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psllv.q.256 + return _mm256_sllv_epi64(a, b); +} + +__m128i test_mm_sllv_epi64(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psllv.q + return _mm_sllv_epi64(a, b); +} + +__m256i test_mm256_srav_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrav.d.256 + return _mm256_srav_epi32(a, b); +} + +__m128i test_mm_srav_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrav.d + return _mm_srav_epi32(a, b); +} + +__m256i test_mm256_srlv_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrlv.d.256 + return _mm256_srlv_epi32(a, b); +} + +__m128i test_mm_srlv_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrlv.d + return _mm_srlv_epi32(a, b); +} + +__m256i test_mm256_srlv_epi64(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrlv.q.256 + return _mm256_srlv_epi64(a, b); +} + +__m128i test_mm_srlv_epi64(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrlv.q + return _mm_srlv_epi64(a, b); +} diff --git a/test/CodeGen/bmi-builtins.c b/test/CodeGen/bmi-builtins.c new file mode 100644 index 0000000000000..47b0da204ee93 --- /dev/null +++ b/test/CodeGen/bmi-builtins.c @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned short test__tzcnt16(unsigned short __X) { + // CHECK: @llvm.cttz.i16 + return __tzcnt16(__X); +} + +unsigned int test__andn_u32(unsigned int __X, unsigned int __Y) { + // CHECK: [[DEST:%.*]] = xor i32 %{{.*}}, -1 + // CHECK-NEXT: %{{.*}} = and i32 %{{.*}}, [[DEST]] + return __andn_u32(__X, __Y); +} + +unsigned int test__bextr_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.bextr.32 + return __bextr_u32(__X, __Y); +} + +unsigned int test__blsi_u32(unsigned int __X) { + // CHECK: [[DEST:%.*]] = sub i32 0, [[SRC:%.*]] + // CHECK-NEXT: %{{.*}} = and i32 [[SRC]], [[DEST]] + return __blsi_u32(__X); +} + +unsigned int test__blsmsk_u32(unsigned int __X) { + // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = xor i32 [[DEST]], [[SRC]] + return __blsmsk_u32(__X); +} + +unsigned int test__blsr_u32(unsigned int __X) { + // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = and i32 [[DEST]], [[SRC]] + return __blsr_u32(__X); +} + +unsigned int test_tzcnt32(unsigned int __X) { + // CHECK: @llvm.cttz.i32 + return __tzcnt32(__X); +} + +unsigned long long test__andn_u64(unsigned long __X, unsigned long __Y) { + // CHECK: [[DEST:%.*]] = xor i64 %{{.*}}, -1 + // CHECK-NEXT: %{{.*}} = and i64 %{{.*}}, [[DEST]] + return __andn_u64(__X, __Y); +} + +unsigned long long test__bextr_u64(unsigned long __X, unsigned long __Y) { + // CHECK: @llvm.x86.bmi.bextr.64 + return __bextr_u64(__X, __Y); +} + +unsigned long long test__blsi_u64(unsigned long long __X) { + // CHECK: [[DEST:%.*]] = sub i64 0, [[SRC:%.*]] + // CHECK-NEXT: %{{.*}} = and i64 [[SRC]], [[DEST]] + return __blsi_u64(__X); +} + +unsigned long long test__blsmsk_u64(unsigned long long __X) { + // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = xor i64 [[DEST]], [[SRC]] + return __blsmsk_u64(__X); +} + +unsigned long long test__blsr_u64(unsigned long long __X) { + // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = and i64 [[DEST]], [[SRC]] + return __blsr_u64(__X); +} + +unsigned long long test__tzcnt64(unsigned long long __X) { + // CHECK: @llvm.cttz.i64 + return __tzcnt64(__X); +} diff --git a/test/CodeGen/bmi2-builtins.c b/test/CodeGen/bmi2-builtins.c new file mode 100644 index 0000000000000..18b2319f9f97f --- /dev/null +++ b/test/CodeGen/bmi2-builtins.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned int test_bzhi_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.bzhi.32 + return _bzhi_u32(__X, __Y); +} + +unsigned int test_pdep_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.pdep.32 + return _pdep_u32(__X, __Y); +} + +unsigned int test_pext_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.pext.32 + return _pext_u32(__X, __Y); +} + +unsigned long long test_bzhi_u64(unsigned long long __X, unsigned long long __Y) { + // CHECK: @llvm.x86.bmi.bzhi.64 + return _bzhi_u64(__X, __Y); +} + +unsigned long long test_pdep_u64(unsigned long long __X, unsigned long long __Y) { + // CHECK: @llvm.x86.bmi.pdep.64 + return _pdep_u64(__X, __Y); +} + +unsigned long long test_pext_u64(unsigned long long __X, unsigned long long __Y) { + // CHECK: @llvm.x86.bmi.pext.64 + return _pext_u64(__X, __Y); +} diff --git a/test/CodeGen/builtin-count-zeros.c b/test/CodeGen/builtin-count-zeros.c index 5a0be2fb867f4..acd22e69a7c6b 100644 --- a/test/CodeGen/builtin-count-zeros.c +++ b/test/CodeGen/builtin-count-zeros.c @@ -1,4 +1,8 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'cttz' | count 2 -// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'ctlz' | count 2 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-ARM int a(int a) {return __builtin_ctz(a) + __builtin_clz(a);} +// CHECK: call i32 @llvm.cttz.i32({{.*}}, i1 true) +// CHECK: call i32 @llvm.ctlz.i32({{.*}}, i1 true) +// CHECK-ARM: call i32 @llvm.cttz.i32({{.*}}, i1 false) +// CHECK-ARM: call i32 @llvm.ctlz.i32({{.*}}, i1 false) diff --git a/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c index fb4d7200752de..72d340619f379 100644 --- a/test/CodeGen/builtin-memfns.c +++ b/test/CodeGen/builtin-memfns.c @@ -48,3 +48,18 @@ void test5(char *P, char *Q) { int test6(char *X) { return __builtin___memcpy_chk(X, X, 42, 42) != 0; } + +// CHECK: @test7 +// PR12094 +int test7(int *p) { + struct snd_pcm_hw_params_t* hwparams; // incomplete type. + + // CHECK: call void @llvm.memset{{.*}}256, i32 4, i1 false) + __builtin_memset(p, 0, 256); // Should be alignment = 4 + + // CHECK: call void @llvm.memset{{.*}}256, i32 1, i1 false) + __builtin_memset((char*)p, 0, 256); // Should be alignment = 1 + + __builtin_memset(hwparams, 0, 256); // No crash alignment = 1 + // CHECK: call void @llvm.memset{{.*}}256, i32 1, i1 false) +} diff --git a/test/CodeGen/builtin-recursive.cc b/test/CodeGen/builtin-recursive.cc new file mode 100644 index 0000000000000..81e9b9a37c256 --- /dev/null +++ b/test/CodeGen/builtin-recursive.cc @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -nostdsysteminc -nobuiltininc -isystem Inputs -emit-llvm-only %s + +// This used to cause a read past the end of a global variable. + +#include <stdio.h> + +void testcase(void) { + vprintf(0, 0); +} + diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c index 728ade34c10b0..30138d6374fd6 100644 --- a/test/CodeGen/builtins-x86.c +++ b/test/CodeGen/builtins-x86.c @@ -199,12 +199,6 @@ void f0() { tmp_V8s = __builtin_ia32_pmulhw128(tmp_V8s, tmp_V8s); tmp_V16c = __builtin_ia32_pavgb128(tmp_V16c, tmp_V16c); tmp_V8s = __builtin_ia32_pavgw128(tmp_V8s, tmp_V8s); - tmp_V16c = __builtin_ia32_pcmpeqb128(tmp_V16c, tmp_V16c); - tmp_V8s = __builtin_ia32_pcmpeqw128(tmp_V8s, tmp_V8s); - tmp_V4i = __builtin_ia32_pcmpeqd128(tmp_V4i, tmp_V4i); - tmp_V16c = __builtin_ia32_pcmpgtb128(tmp_V16c, tmp_V16c); - tmp_V8s = __builtin_ia32_pcmpgtw128(tmp_V8s, tmp_V8s); - tmp_V4i = __builtin_ia32_pcmpgtd128(tmp_V4i, tmp_V4i); tmp_V16c = __builtin_ia32_pmaxub128(tmp_V16c, tmp_V16c); tmp_V8s = __builtin_ia32_pmaxsw128(tmp_V8s, tmp_V8s); tmp_V16c = __builtin_ia32_pminub128(tmp_V16c, tmp_V16c); @@ -420,13 +414,6 @@ void f0() { tmp_V4i = __builtin_ia32_cvttpd2dq256(tmp_V4d); tmp_V4i = __builtin_ia32_cvtpd2dq256(tmp_V4d); tmp_V8i = __builtin_ia32_cvttps2dq256(tmp_V8f); - tmp_V4d = __builtin_ia32_vperm2f128_pd256(tmp_V4d, tmp_V4d, 0x7); - tmp_V8f = __builtin_ia32_vperm2f128_ps256(tmp_V8f, tmp_V8f, 0x7); - tmp_V8i = __builtin_ia32_vperm2f128_si256(tmp_V8i, tmp_V8i, 0x7); - tmp_V2d = __builtin_ia32_vpermilpd(tmp_V2d, 0x7); - tmp_V4f = __builtin_ia32_vpermilps(tmp_V4f, 0x7); - tmp_V4d = __builtin_ia32_vpermilpd256(tmp_V4d, 0x7); - tmp_V8f = __builtin_ia32_vpermilps256(tmp_V8f, 0x7); tmp_V4d = __builtin_ia32_vinsertf128_pd256(tmp_V4d, tmp_V2d, 0x7); tmp_V8f = __builtin_ia32_vinsertf128_ps256(tmp_V8f, tmp_V4f, 0x7); tmp_V8i = __builtin_ia32_vinsertf128_si256(tmp_V8i, tmp_V4i, 0x7); @@ -434,8 +421,8 @@ void f0() { tmp_V8f = __builtin_ia32_sqrtps256(tmp_V8f); tmp_V8f = __builtin_ia32_rsqrtps256(tmp_V8f); tmp_V8f = __builtin_ia32_rcpps256(tmp_V8f); - tmp_V4d = __builtin_ia32_roundpd256(tmp_V4d, tmp_i); - tmp_V8f = __builtin_ia32_roundps256(tmp_V8f, tmp_i); + tmp_V4d = __builtin_ia32_roundpd256(tmp_V4d, 0x1); + tmp_V8f = __builtin_ia32_roundps256(tmp_V8f, 0x1); tmp_i = __builtin_ia32_vtestzpd(tmp_V2d, tmp_V2d); tmp_i = __builtin_ia32_vtestcpd(tmp_V2d, tmp_V2d); tmp_i = __builtin_ia32_vtestnzcpd(tmp_V2d, tmp_V2d); @@ -460,11 +447,8 @@ void f0() { tmp_V8f = __builtin_ia32_vbroadcastss256(tmp_fCp); tmp_V4d = __builtin_ia32_vbroadcastf128_pd256(tmp_V2dCp); tmp_V8f = __builtin_ia32_vbroadcastf128_ps256(tmp_V4fCp); - tmp_V4d = __builtin_ia32_loadupd256(tmp_dCp); - tmp_V8f = __builtin_ia32_loadups256(tmp_fCp); __builtin_ia32_storeupd256(tmp_dp, tmp_V4d); __builtin_ia32_storeups256(tmp_fp, tmp_V8f); - tmp_V32c = __builtin_ia32_loaddqu256(tmp_cCp); __builtin_ia32_storedqu256(tmp_cp, tmp_V32c); tmp_V32c = __builtin_ia32_lddqu256(tmp_cCp); __builtin_ia32_movntdq256(tmp_V4LLip, tmp_V4LLi); @@ -495,7 +479,6 @@ void f0() { tmp_V2f = __builtin_ia32_pfrcpit2(tmp_V2f, tmp_V2f); tmp_V2f = __builtin_ia32_pfrsqrt(tmp_V2f); tmp_V2f = __builtin_ia32_pfrsqit1(tmp_V2f, tmp_V2f); - tmp_V2f = __builtin_ia32_pfrsqrtit1(tmp_V2f, tmp_V2f); tmp_V2f = __builtin_ia32_pfsub(tmp_V2f, tmp_V2f); tmp_V2f = __builtin_ia32_pfsubr(tmp_V2f, tmp_V2f); tmp_V2f = __builtin_ia32_pi2fd(tmp_V2i); diff --git a/test/CodeGen/builtinshufflevector2.c b/test/CodeGen/builtinshufflevector2.c new file mode 100644 index 0000000000000..faf7a3ec1a1f9 --- /dev/null +++ b/test/CodeGen/builtinshufflevector2.c @@ -0,0 +1,35 @@ +// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s + +typedef float float4 __attribute__((ext_vector_type(4))); +typedef unsigned int uint4 __attribute__((ext_vector_type(4))); + +// CHECK: define void @clang_shufflevector_v_v( +void clang_shufflevector_v_v( float4* A, float4 x, uint4 mask ) { +// CHECK: [[MASK:%.*]] = and <4 x i32> {{%.*}}, <i32 3, i32 3, i32 3, i32 3> +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 0 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X:%.*]], i32 [[I]] +// +// Here is where ToT Clang code generation makes a mistake. +// It uses [[I]] as the insertion index instead of 0. +// Similarly on the remaining insertelement. +// CHECK: [[V:%[a-zA-Z0-9._]+]] = insertelement <4 x float> undef, float [[E]], i32 0 + +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 1 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]] +// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 1 +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 2 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]] +// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 2 +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 3 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]] +// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 3 +// CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}}, + *A = __builtin_shufflevector( x, mask ); +} + +// CHECK: define void @clang_shufflevector_v_v_c( +void clang_shufflevector_v_v_c( float4* A, float4 x, float4 y, uint4 mask ) { +// CHECK: [[V:%.*]] = shufflevector <4 x float> {{%.*}}, <4 x float> {{%.*}}, <4 x i32> <i32 0, i32 4, i32 1, i32 5> +// CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}} + *A = __builtin_shufflevector( x, y, 0, 4, 1, 5 ); +} diff --git a/test/CodeGen/cfstring.c b/test/CodeGen/cfstring.c index 1f0977f0398ac..9d98b56e6b843 100644 --- a/test/CodeGen/cfstring.c +++ b/test/CodeGen/cfstring.c @@ -1,4 +1,14 @@ // RUN: %clang_cc1 -emit-llvm %s -o %t + +// <rdar://problem/10657500>: Check that the backing store of CFStrings are +// constant with the -fwritable-strings flag. +// +// RUN: %clang_cc1 -fwritable-strings -emit-llvm %s -o - | FileCheck %s +// +// CHECK: @.str = linker_private unnamed_addr constant [14 x i8] c"Hello, World!\00", align 1 +// CHECK: @.str1 = linker_private unnamed_addr constant [7 x i8] c"yo joe\00", align 1 +// CHECK: @.str3 = linker_private unnamed_addr constant [16 x i8] c"Goodbye, World!\00", align 1 + #define CFSTR __builtin___CFStringMakeConstantString void f() { diff --git a/test/CodeGen/char-literal.c b/test/CodeGen/char-literal.c index 5963ede392aff..237d4b2010ee3 100644 --- a/test/CodeGen/char-literal.c +++ b/test/CodeGen/char-literal.c @@ -9,11 +9,26 @@ int main() { // CHECK-CPP0X: store i8 97 char a = 'a'; - // Should pick second character. + // Should truncate value (equal to last character). // CHECK-C: store i8 98 // CHECK-CPP0X: store i8 98 char b = 'ab'; + // Should get concatenated characters + // CHECK-C: store i32 24930 + // CHECK-CPP0X: store i32 24930 + int b1 = 'ab'; + + // Should get concatenated characters + // CHECK-C: store i32 808464432 + // CHECK-CPP0X: store i32 808464432 + int b2 = '0000'; + + // Should get truncated value (last four characters concatenated) + // CHECK-C: store i32 1919512167 + // CHECK-CPP0X: store i32 1919512167 + int b3 = 'somesillylongstring'; + // CHECK-C: store i32 97 // CHECK-CPP0X: store i32 97 wchar_t wa = L'a'; @@ -27,25 +42,24 @@ int main() { // CHECK-CPP0X: store i16 97 char16_t ua = u'a'; - // Should pick second character. - // CHECK-CPP0X: store i16 98 - char16_t ub = u'ab'; - // CHECK-CPP0X: store i32 97 char32_t Ua = U'a'; - // Should pick second character. - // CHECK-CPP0X: store i32 98 - char32_t Ub = U'ab'; -#endif + // CHECK-CPP0X: store i16 1047 + char16_t ua1 = u'З'; + // CHECK-CPP0X: store i16 12538 + char16_t ua2 = u'ヺ'; + // CHECK-CPP0X: store i16 -27177 + char16_t ua3 = u'闗'; - // Should pick last character and store its lowest byte. - // This does not match gcc, which takes the last character, converts it to - // utf8, and then picks the second-lowest byte of that (they probably store - // the utf8 in uint16_ts internally and take the lower byte of that). - // CHECK-C: store i8 48 - // CHECK-CPP0X: store i8 48 - char c = '\u1120\u0220\U00102030'; + // CHECK-CPP0X: store i32 181 + char32_t Ua1 = U'µ'; + // CHECK-CPP0X: store i32 38359 + char32_t Ua2 = U'闗'; + // CHECK-CPP0X: store i32 128128 + char32_t Ua3 = U'💀'; + +#endif // CHECK-C: store i32 61451 // CHECK-CPP0X: store i32 61451 @@ -65,13 +79,6 @@ int main() { wchar_t wd = L'\U0010F00B'; #if __cplusplus >= 201103L - // Should take lower word of the 4byte UNC sequence. This does not match - // gcc. I don't understand what gcc does (it looks like it converts to utf16, - // then takes the second (!) utf16 word, swaps the lower two nibbles, and - // stores that?). - // CHECK-CPP0X: store i16 -4085 - char16_t ud = u'\U0010F00B'; // has utf16 encoding dbc8 dcb0 - // CHECK-CPP0X: store i32 1110027 char32_t Ud = U'\U0010F00B'; #endif @@ -80,14 +87,4 @@ int main() { // CHECK-C: store i32 1110027 // CHECK-CPP0X: store i32 1110027 wchar_t we = L'\u1234\U0010F00B'; - -#if __cplusplus >= 201103L - // Should pick second character. - // CHECK-CPP0X: store i16 -4085 - char16_t ue = u'\u1234\U0010F00B'; - - // Should pick second character. - // CHECK-CPP0X: store i32 1110027 - char32_t Ue = U'\u1234\U0010F00B'; -#endif } diff --git a/test/CodeGen/complex-indirect.c b/test/CodeGen/complex-indirect.c index 45eb1954842f2..0daa970e760aa 100644 --- a/test/CodeGen/complex-indirect.c +++ b/test/CodeGen/complex-indirect.c @@ -1,10 +1,12 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin10 +// RUN: FileCheck < %t %s -// Make sure this doesn't crash, and that we don't generate a byval alloca -// with insufficient alignment. +// Make sure this doesn't crash. We used to generate a byval here and wanted to +// verify a valid alignment, but we now realize we can use an i16 and let the +// backend guarantee the alignment. void a(int,int,int,int,int,int,__complex__ char); void b(__complex__ char *y) { a(0,0,0,0,0,0,*y); } // CHECK: define void @b // CHECK: alloca { i8, i8 }*, align 8 -// CHECK: call void @a(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, { i8, i8 }* byval align 8 +// CHECK: call void @a(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i16 {{.*}}) diff --git a/test/CodeGen/complex-init-list.c b/test/CodeGen/complex-init-list.c index 819d4f9432de6..99c1c62b58844 100644 --- a/test/CodeGen/complex-init-list.c +++ b/test/CodeGen/complex-init-list.c @@ -9,4 +9,10 @@ _Complex float x = { 1.0f, 1.0f/0.0f }; _Complex float f(float x, float y) { _Complex float z = { x, y }; return z; } // CHECK: define <2 x float> @f -// CHECK: alloca { float, float }
\ No newline at end of file +// CHECK: alloca { float, float } +// CHECK: alloca { float, float } + +_Complex float f2(float x, float y) { return (_Complex float){ x, y }; } +// CHECK: define <2 x float> @f2 +// CHECK: alloca { float, float } +// CHECK: alloca { float, float } diff --git a/test/CodeGen/compound-literal.c b/test/CodeGen/compound-literal.c index 0164c2b738621..969c5affe0b20 100644 --- a/test/CodeGen/compound-literal.c +++ b/test/CodeGen/compound-literal.c @@ -2,8 +2,9 @@ int* a = &(int){1}; struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; -// Not working; complex constants are broken -// _Complex double * x = &(_Complex double){1.0f}; +_Complex double * x = &(_Complex double){1.0f}; +typedef int v4i32 __attribute((vector_size(16))); +v4i32 *y = &(v4i32){1,2,3,4}; void xxx() { int* a = &(int){1}; diff --git a/test/CodeGen/conditional.c b/test/CodeGen/conditional.c index 15e15f11e35fd..88538a2042a76 100644 --- a/test/CodeGen/conditional.c +++ b/test/CodeGen/conditional.c @@ -66,3 +66,9 @@ int test11(int c) { double test12(int c) { return c ? 4.0 : 2.0; } +// CHECK: @test13 +// CHECK: call {{.*}} @f2( +int f2(void); +void test13() { + f2() ? (void)0 : (void)0; +} diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c index 9bc3bbafdeff4..4f3f7ab553308 100644 --- a/test/CodeGen/const-init.c +++ b/test/CodeGen/const-init.c @@ -132,3 +132,15 @@ int g25() { void g27() { // PR8073 static void *x = &x; } + +void g28() { + typedef long long v1i64 __attribute((vector_size(8))); + typedef short v12i16 __attribute((vector_size(24))); + typedef long double v2f80 __attribute((vector_size(24))); + // CHECK: @g28.a = internal global <1 x i64> <i64 10> + // CHECK: @g28.b = internal global <12 x i16> <i16 0, i16 0, i16 0, i16 -32768, i16 16383, i16 0, i16 0, i16 0, i16 0, i16 -32768, i16 16384, i16 0> + // CHECK: @g28.c = internal global <2 x x86_fp80> <x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000>, align 32 + static v1i64 a = (v1i64)10LL; + static v12i16 b = (v2f80){1,2}; + static v2f80 c = (v12i16){0,0,0,-32768,16383,0,0,0,0,-32768,16384,0}; +} diff --git a/test/CodeGen/count-builtins.c b/test/CodeGen/count-builtins.c new file mode 100644 index 0000000000000..e6133c5cf0bd5 --- /dev/null +++ b/test/CodeGen/count-builtins.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +int leading, trailing, pop; + +void test_i16(short P) { + leading = __builtin_clzs(P); + trailing = __builtin_ctzs(P); + +// CHECK: @test_i16 +// CHECK: call i16 @llvm.ctlz.i16 +// CHECK: call i16 @llvm.cttz.i16 +} + +void test_i32(int P) { + leading = __builtin_clz(P); + trailing = __builtin_ctz(P); + pop = __builtin_popcount(P); + +// CHECK: @test_i32 +// CHECK: call i32 @llvm.ctlz.i32 +// CHECK: call i32 @llvm.cttz.i32 +// CHECK: call i32 @llvm.ctpop.i32 +} + +void test_i64(float P) { + leading = __builtin_clzll(P); + trailing = __builtin_ctzll(P); + pop = __builtin_popcountll(P); +// CHECK: @test_i64 +// CHECK: call i64 @llvm.ctlz.i64 +// CHECK: call i64 @llvm.cttz.i64 +// CHECK: call i64 @llvm.ctpop.i64 +} diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c index 6f9e0d2a63edf..968386a90e985 100644 --- a/test/CodeGen/darwin-string-literals.c +++ b/test/CodeGen/darwin-string-literals.c @@ -2,13 +2,16 @@ // CHECK-LSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" // CHECK-LSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00" -// CHECK-LSB: @.str2 = internal unnamed_addr constant [36 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00\00", align 2 +// CHECK-LSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2 +// CHECK-LSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2 + // RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix MSB %s // CHECK-MSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" // CHECK-MSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00" -// CHECK-MSB: @.str2 = internal unnamed_addr constant [36 x i8] c"\00h\00e\00l\00l\00o\00 !\92\00 &\03\00 !\90\00 \00w\00o\00r\00l\00d\00\00", align 2 +// CHECK-MSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2 +// CHECK-MSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2 const char *g0 = "string0"; const void *g1 = __builtin___CFStringMakeConstantString("string1"); diff --git a/test/CodeGen/debug-info-args.c b/test/CodeGen/debug-info-args.c new file mode 100644 index 0000000000000..1d4ea10f17df6 --- /dev/null +++ b/test/CodeGen/debug-info-args.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -g %s | FileCheck %s + +int somefunc(char *x, int y, double z) { + + // CHECK: {{.*metadata !8, i32 0, i32 0}.*DW_TAG_subroutine_type}} + // CHECK: {{!8 = .*metadata ![^,]*, metadata ![^,]*, metadata ![^,]*, metadata ![^,]*}} + + return y; +} diff --git a/test/CodeGen/debug-info-block.c b/test/CodeGen/debug-info-block.c new file mode 100644 index 0000000000000..403e4aaccb8ca --- /dev/null +++ b/test/CodeGen/debug-info-block.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fblocks -g -emit-llvm -o - %s | FileCheck %s +// APPLE LOCAL file 5939894 */ +// Verify that the desired debugging type is generated for a structure +// member that is a pointer to a block. + +// CHECK: __block_literal_generic{{.*}}DW_TAG_structure_type +// CHECK: __block_descriptor{{.*}}DW_TAG_structure_type +struct inStruct { + void (^genericBlockPtr)(); +} is; + diff --git a/test/CodeGen/debug-info-compilation-dir.c b/test/CodeGen/debug-info-compilation-dir.c new file mode 100644 index 0000000000000..4b472991498c4 --- /dev/null +++ b/test/CodeGen/debug-info-compilation-dir.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fdebug-compilation-dir /nonsense -emit-llvm -g %s -o - | FileCheck -check-prefix=CHECK-NONSENSE %s +// CHECK-NONSENSE: nonsense + +// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck -check-prefix=CHECK-DIR %s +// CHECK-DIR: CodeGen + diff --git a/test/CodeGen/debug-info-iv.c b/test/CodeGen/debug-info-iv.c index 1d9bf32c2cdac..6684fe346992d 100644 --- a/test/CodeGen/debug-info-iv.c +++ b/test/CodeGen/debug-info-iv.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -Os -S -g -o - %s | FileCheck %s +// REQUIRES: x86-registered-target int calculate(int); static void test_indvars(int *Array1, int Array2[100][200]) { @@ -26,7 +27,7 @@ int main() { Array[i][j] = 0; test_indvars(Array[0], Array); -//CHECK: .loc 2 30 8 +//CHECK: .loc 2 31 8 for (i=0; i < 100; i+=2) for (j=0; j < 200; j++) sum += Array[i][j]; diff --git a/test/CodeGen/debug-info-static.c b/test/CodeGen/debug-info-static.c new file mode 100644 index 0000000000000..e75d20fbacc29 --- /dev/null +++ b/test/CodeGen/debug-info-static.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s + +// CHECK: xyzzy} ; [ DW_TAG_variable ] +void f(void) +{ + static int xyzzy; + xyzzy += 3; +} diff --git a/test/CodeGen/debug-line-1.c b/test/CodeGen/debug-line-1.c new file mode 100644 index 0000000000000..00d4f421f8a10 --- /dev/null +++ b/test/CodeGen/debug-line-1.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -o - -emit-llvm -g %s | FileCheck %s +// REQUIRES: asserts +// PR9796 + +// Check to make sure that we emit the block for the break so that we can count the line. +// CHECK: sw.bb: ; preds = %entry +// CHECK: br label %sw.epilog, !dbg !21 + +extern int atoi(const char *); + +int f(char* arg) { + int x = atoi(arg); + + switch(x) { + case 1: + break; + } + + return 0; +} diff --git a/test/CodeGen/decl-in-prototype.c b/test/CodeGen/decl-in-prototype.c new file mode 100644 index 0000000000000..949793da445a8 --- /dev/null +++ b/test/CodeGen/decl-in-prototype.c @@ -0,0 +1,21 @@ +// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s + +const int AA = 5; + +// CHECK: define i32 @f1 +int f1(enum {AA,BB} E) { + // CHECK: ret i32 1 + return BB; +} + +// CHECK: define i32 @f2 +int f2(enum {AA=7,BB} E) { + // CHECK: ret i32 7 + return AA; +} + +// Check nested function declarators work. +int f(void (*g)(), enum {AA,BB} h) { + // CHECK: ret i32 0 + return AA; +} diff --git a/test/CodeGen/ext-vector-member-alignment.c b/test/CodeGen/ext-vector-member-alignment.c new file mode 100644 index 0000000000000..49e69977fffdc --- /dev/null +++ b/test/CodeGen/ext-vector-member-alignment.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +typedef float float4 __attribute__((ext_vector_type(4))); + +struct __attribute__((packed, aligned(4))) struct1 { + float4 position; +}; +int x = __alignof(struct struct1); + +float4 f(struct struct1* x) { return x->position; } + +void func(struct struct1* p, float *a, float *b, float c) { + p->position.x = c; + *a = p->position.y; + *b = p->position[0]; + p->position[2] = c; + // FIXME: We should be able to come up with a more aggressive alignment + // estimate. + // CHECK: @func + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: store <4 x float> {{%.*}}, <4 x float>* {{%.*}}, align 1 + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: store <4 x float> {{%.*}}, <4 x float>* {{%.*}}, align 1 + // CHECK: ret void +} diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c index a222f9445e089..a9fa1511758be 100644 --- a/test/CodeGen/ext-vector.c +++ b/test/CodeGen/ext-vector.c @@ -252,7 +252,8 @@ int4 test13(int4 *V) { void test14(uint4 *ap, uint4 *bp, unsigned c) { uint4 a = *ap; uint4 b = *bp; - + int4 d; + // CHECK: udiv <4 x i32> // CHECK: urem <4 x i32> a = a / b; @@ -269,10 +270,19 @@ void test14(uint4 *ap, uint4 *bp, unsigned c) { // CHECK: icmp uge // CHECK: icmp eq // CHECK: icmp ne - a = a < b; - a = a <= b; - a = a > b; - a = a >= b; - a = a == b; - a = a != b; + d = a < b; + d = a <= b; + d = a > b; + d = a >= b; + d = a == b; + d = a != b; +} + +// CHECK: @test15 +int4 test15(uint4 V0) { + // CHECK: icmp eq <4 x i32> + int4 V = !V0; + V = V && V; + V = V || V; + return V; } diff --git a/test/CodeGen/fma4-builtins.c b/test/CodeGen/fma4-builtins.c new file mode 100644 index 0000000000000..ddbaba748391a --- /dev/null +++ b/test/CodeGen/fma4-builtins.c @@ -0,0 +1,166 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +fma4 -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +__m128 test_mm_macc_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmadd.ps + return _mm_macc_ps(a, b, c); +} + +__m128d test_mm_macc_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmadd.pd + return _mm_macc_pd(a, b, c); +} + +__m128 test_mm_macc_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmadd.ss + return _mm_macc_ss(a, b, c); +} + +__m128d test_mm_macc_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmadd.sd + return _mm_macc_sd(a, b, c); +} + +__m128 test_mm_msub_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmsub.ps + return _mm_msub_ps(a, b, c); +} + +__m128d test_mm_msub_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmsub.pd + return _mm_msub_pd(a, b, c); +} + +__m128 test_mm_msub_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmsub.ss + return _mm_msub_ss(a, b, c); +} + +__m128d test_mm_msub_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmsub.sd + return _mm_msub_sd(a, b, c); +} + +__m128 test_mm_nmacc_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmadd.ps + return _mm_nmacc_ps(a, b, c); +} + +__m128d test_mm_nmacc_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmadd.pd + return _mm_nmacc_pd(a, b, c); +} + +__m128 test_mm_nmacc_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmadd.ss + return _mm_nmacc_ss(a, b, c); +} + +__m128d test_mm_nmacc_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmadd.sd + return _mm_nmacc_sd(a, b, c); +} + +__m128 test_mm_nmsub_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmsub.ps + return _mm_nmsub_ps(a, b, c); +} + +__m128d test_mm_nmsub_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmsub.pd + return _mm_nmsub_pd(a, b, c); +} + +__m128 test_mm_nmsub_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmsub.ss + return _mm_nmsub_ss(a, b, c); +} + +__m128d test_mm_nmsub_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmsub.sd + return _mm_nmsub_sd(a, b, c); +} + +__m128 test_mm_maddsub_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.ps + return _mm_maddsub_ps(a, b, c); +} + +__m128d test_mm_maddsub_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.pd + return _mm_maddsub_pd(a, b, c); +} + +__m128 test_mm_msubadd_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.ps + return _mm_msubadd_ps(a, b, c); +} + +__m128d test_mm_msubadd_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.pd + return _mm_msubadd_pd(a, b, c); +} + +__m256 test_mm256_macc_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmadd.ps.256 + return _mm256_macc_ps(a, b, c); +} + +__m256d test_mm256_macc_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmadd.pd.256 + return _mm256_macc_pd(a, b, c); +} + +__m256 test_mm256_msub_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmsub.ps.256 + return _mm256_msub_ps(a, b, c); +} + +__m256d test_mm256_msub_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmsub.pd.256 + return _mm256_msub_pd(a, b, c); +} + +__m256 test_mm256_nmacc_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfnmadd.ps.256 + return _mm256_nmacc_ps(a, b, c); +} + +__m256d test_mm256_nmacc_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfnmadd.pd.256 + return _mm256_nmacc_pd(a, b, c); +} + +__m256 test_mm256_nmsub_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfnmsub.ps.256 + return _mm256_nmsub_ps(a, b, c); +} + +__m256d test_mm256_nmsub_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfnmsub.pd.256 + return _mm256_nmsub_pd(a, b, c); +} + +__m256 test_mm256_maddsub_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.ps.256 + return _mm256_maddsub_ps(a, b, c); +} + +__m256d test_mm256_maddsub_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.pd.256 + return _mm256_maddsub_pd(a, b, c); +} + +__m256 test_mm256_msubadd_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.ps.256 + return _mm256_msubadd_ps(a, b, c); +} + +__m256d test_mm256_msubadd_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.pd.256 + return _mm256_msubadd_pd(a, b, c); +} diff --git a/test/CodeGen/frame-pointer-elim.c b/test/CodeGen/frame-pointer-elim.c index 4e8e946210deb..b105a199f1a90 100644 --- a/test/CodeGen/frame-pointer-elim.c +++ b/test/CodeGen/frame-pointer-elim.c @@ -1,6 +1,6 @@ // REQUIRES: x86-registered-target -// RUN: %clang -ccc-host-triple i386-apple-darwin -S -o - %s | \ +// RUN: %clang -target i386-apple-darwin -S -o - %s | \ // RUN: FileCheck --check-prefix=DARWIN %s // DARWIN: f0: // DARWIN: pushl %ebp @@ -9,7 +9,7 @@ // DARWIN: pushl %ebp // DARWIN: ret -// RUN: %clang -ccc-host-triple i386-pc-linux-gnu -S -o - %s | \ +// RUN: %clang -target i386-pc-linux-gnu -S -o - %s | \ // RUN: FileCheck --check-prefix=LINUX %s // LINUX: f0: // LINUX-NOT: pushl %ebp @@ -18,7 +18,7 @@ // LINUX: pushl %ebp // LINUX: ret -// RUN: %clang -ccc-host-triple i386-darwin -S -o - -fomit-frame-pointer %s | \ +// RUN: %clang -target i386-darwin -S -o - -fomit-frame-pointer %s | \ // RUN: FileCheck --check-prefix=OMIT_ALL %s // OMIT_ALL: f0: // OMIT_ALL-NOT: pushl %ebp @@ -27,7 +27,7 @@ // OMIT_ALL-NOT: pushl %ebp // OMIT_ALL: ret -// RUN: %clang -ccc-host-triple i386-darwin -S -o - -momit-leaf-frame-pointer %s | \ +// RUN: %clang -target i386-darwin -S -o - -momit-leaf-frame-pointer %s | \ // RUN: FileCheck --check-prefix=OMIT_LEAF %s // OMIT_LEAF: f0: // OMIT_LEAF-NOT: pushl %ebp diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c index 074c2a065a860..dab5a07d614f0 100644 --- a/test/CodeGen/global-init.c +++ b/test/CodeGen/global-init.c @@ -32,7 +32,7 @@ struct ManyFields FewInits = {1, 2}; // PR6766 -// CHECK: @l = global { [24 x i8], i32 } { [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 } +// CHECK: @l = global %struct.K { [6 x i32] [i32 102, i32 111, i32 111, i32 0, i32 0, i32 0], i32 1 } typedef __WCHAR_TYPE__ wchar_t; struct K { wchar_t L[6]; diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c index 599b4f23dbdc1..426233d8dfd32 100644 --- a/test/CodeGen/init.c +++ b/test/CodeGen/init.c @@ -123,3 +123,10 @@ struct test12 { struct test12 (*p)(void); } test12g; + +void test13(int x) { + struct X { int a; int b : 10; int c; }; + struct X y = {.c = x}; + // CHECK: @test13 + // CHECK: and i32 {{.*}}, -1024 +} diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c index 6bc583df8c966..2a01f255dc01c 100644 --- a/test/CodeGen/inline.c +++ b/test/CodeGen/inline.c @@ -13,8 +13,14 @@ // RUN: grep "define available_externally i32 @test4" %t // RUN: grep "define available_externally i32 @test5" %t // RUN: grep "define i32 @test6" %t - -// RUN: echo "\nC99 tests:" +// RUN: grep "define void @test7" %t +// RUN: grep "define i.. @strlcpy" %t +// RUN: not grep test9 %t +// RUN: grep "define void @testA" %t +// RUN: grep "define void @testB" %t +// RUN: grep "define void @testC" %t + +// RUN: echo "C99 tests:" // RUN: %clang %s -O1 -emit-llvm -S -o %t -std=gnu99 // RUN: grep "define i32 @ei()" %t // RUN: grep "define available_externally i32 @foo()" %t @@ -29,9 +35,14 @@ // RUN: grep "define available_externally i32 @test4" %t // RUN: grep "define available_externally i32 @test5" %t // RUN: grep "define i32 @test6" %t +// RUN: grep "define void @test7" %t // RUN: grep "define available_externally i.. @strlcpy" %t +// RUN: grep "define void @test9" %t +// RUN: grep "define void @testA" %t +// RUN: grep "define void @testB" %t +// RUN: grep "define void @testC" %t -// RUN: echo "\nC++ tests:" +// RUN: echo "C++ tests:" // RUN: %clang -x c++ %s -O1 -emit-llvm -S -o %t -std=c++98 // RUN: grep "define linkonce_odr i32 @_Z2eiv()" %t // RUN: grep "define linkonce_odr i32 @_Z3foov()" %t @@ -102,3 +113,17 @@ void test7(); // PR11062; the fact that the function is named strlcpy matters here. inline __typeof(sizeof(int)) strlcpy(char *dest, const char *src, __typeof(sizeof(int)) size) { return 3; } void test8() { strlcpy(0,0,0); } + +// PR10657; the test crashed in C99 mode +extern inline void test9() { } +void test9(); + +inline void testA() {} +void testA(); + +void testB(); +inline void testB() {} +extern void testB(); + +extern inline void testC() {} +inline void testC(); diff --git a/test/CodeGen/kr-call.c b/test/CodeGen/kr-call.c deleted file mode 100644 index ea4e3d3d70f07..0000000000000 --- a/test/CodeGen/kr-call.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -triple s390x-unknown-linux -emit-llvm -o - %s | FileCheck %s - -// Test that we don't crash. The s390x-unknown-linux target happens -// to need to set a sext argument attribute on this call, and we need -// to make sure that rewriting it correctly keeps that attribute. -void test0_helper(); -void test0() { - // CHECK: call void bitcast (void ()* @test0_helper to void (i32)*)(i32 signext 1) - test0_helper(1); -} -void test0_helper() {} - diff --git a/test/CodeGen/libcalls-fno-builtin.c b/test/CodeGen/libcalls-fno-builtin.c new file mode 100644 index 0000000000000..ce10759b0c5f1 --- /dev/null +++ b/test/CodeGen/libcalls-fno-builtin.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -S -O3 -fno-builtin -o - %s | FileCheck %s +// rdar://10551066 + +double ceil(double x); +double copysign(double,double); +double cos(double x); +double fabs(double x); +double floor(double x); + +double t1(double x) { return ceil(x); } +// CHECK: t1 +// CHECK: ceil + +double t2(double x, double y) { return copysign(x,y); } +// CHECK: t2 +// CHECK: copysign + +double t3(double x) { return cos(x); } +// CHECK: t3 +// CHECK: cos + +double t4(double x) { return fabs(x); } +// CHECK: t4 +// CHECK: fabs + +double t5(double x) { return floor(x); } +// CHECK: t5 +// CHECK: floor diff --git a/test/CodeGen/lifetime.c b/test/CodeGen/lifetime.c new file mode 100644 index 0000000000000..2203840d4b806 --- /dev/null +++ b/test/CodeGen/lifetime.c @@ -0,0 +1,23 @@ +// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0 +// RUN: %clang -S -emit-llvm -o - -O1 %s | FileCheck %s -check-prefix=O1 +// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2 +// RUN: %clang -S -emit-llvm -o - -O3 %s | FileCheck %s -check-prefix=O3 + +extern void use(char *a); + +__attribute__((always_inline)) void helper_no_markers() { + char a; + use(&a); +} + +void lifetime_test() { +// O0: lifetime_test +// O1: lifetime_test +// O2: lifetime_test +// O3: lifetime_test +// O0-NOT: @llvm.lifetime.start +// O1: @llvm.lifetime.start +// O2: @llvm.lifetime.start +// O3: @llvm.lifetime.start + helper_no_markers(); +} diff --git a/test/CodeGen/link-bitcode-file.c b/test/CodeGen/link-bitcode-file.c new file mode 100644 index 0000000000000..77404062ecdd3 --- /dev/null +++ b/test/CodeGen/link-bitcode-file.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -DBITCODE -emit-llvm-bc -o %t.bc %s +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -mlink-bitcode-file %t.bc -O3 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NO-BC %s +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -DBITCODE -mlink-bitcode-file %t.bc -O3 -emit-llvm -o - %s 2>&1 | FileCheck -check-prefix=CHECK-BC %s + +int f(void); + +#ifdef BITCODE + +// CHECK-BC: 'f': symbol multiply defined +int f(void) { + return 42; +} + +#else + +// CHECK-NO-BC: define i32 @g +// CHECK-NO-BC: ret i32 42 +int g(void) { + return f(); +} + +// CHECK-NO-BC: define i32 @f + +#endif diff --git a/test/CodeGen/lzcnt-builtins.c b/test/CodeGen/lzcnt-builtins.c new file mode 100644 index 0000000000000..a43c4eede4521 --- /dev/null +++ b/test/CodeGen/lzcnt-builtins.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +lzcnt -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned short test__lzcnt16(unsigned short __X) +{ + // CHECK: @llvm.ctlz.i16 + return __lzcnt16(__X); +} + +unsigned int test_lzcnt32(unsigned int __X) +{ + // CHECK: @llvm.ctlz.i32 + return __lzcnt32(__X); +} + +unsigned long long test__lzcnt64(unsigned long long __X) +{ + // CHECK: @llvm.ctlz.i64 + return __lzcnt64(__X); +} diff --git a/test/CodeGen/mips-clobber-reg.c b/test/CodeGen/mips-clobber-reg.c new file mode 100644 index 0000000000000..2a06e53b39a51 --- /dev/null +++ b/test/CodeGen/mips-clobber-reg.c @@ -0,0 +1,80 @@ +// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s + +/* + This checks that the frontend will accept both + enumerated and symbolic Mips GPR register names. + + Any bad names will make the frontend choke. + */ + +main() +{ + + __asm__ __volatile__ (".set noat \n\t addi $7,$at,77":::"at"); + __asm__ __volatile__ ("addi $7,$v0,77":::"v0"); + __asm__ __volatile__ ("addi $7,$v1,77":::"v1"); + __asm__ __volatile__ ("addi $7,$a0,77":::"a0"); + __asm__ __volatile__ ("addi $7,$a1,77":::"a1"); + __asm__ __volatile__ ("addi $7,$a2,77":::"a2"); + __asm__ __volatile__ ("addi $7,$a3,77":::"a3"); + __asm__ __volatile__ ("addi $7,$t0,77":::"t0"); + __asm__ __volatile__ ("addi $7,$t1,77":::"t1"); + __asm__ __volatile__ ("addi $7,$t2,77":::"t2"); + __asm__ __volatile__ ("addi $7,$t3,77":::"t3"); + __asm__ __volatile__ ("addi $7,$t4,77":::"t4"); + __asm__ __volatile__ ("addi $7,$t5,77":::"t5"); + __asm__ __volatile__ ("addi $7,$t6,77":::"t6"); + __asm__ __volatile__ ("addi $7,$t7,77":::"t7"); + __asm__ __volatile__ ("addi $7,$s0,77":::"s0"); + __asm__ __volatile__ ("addi $7,$s1,77":::"s1"); + __asm__ __volatile__ ("addi $7,$s2,77":::"s2"); + __asm__ __volatile__ ("addi $7,$s3,77":::"s3"); + __asm__ __volatile__ ("addi $7,$s4,77":::"s4"); + __asm__ __volatile__ ("addi $7,$s5,77":::"s5"); + __asm__ __volatile__ ("addi $7,$s6,77":::"s6"); + __asm__ __volatile__ ("addi $7,$s7,77":::"s7"); + __asm__ __volatile__ ("addi $7,$t8,77":::"t8"); + __asm__ __volatile__ ("addi $7,$t9,77":::"t9"); + __asm__ __volatile__ ("addi $7,$k0,77":::"k0"); + __asm__ __volatile__ ("addi $7,$k1,77":::"k1"); + __asm__ __volatile__ ("addi $7,$gp,77":::"gp"); + __asm__ __volatile__ ("addi $7,$sp,77":::"sp"); + __asm__ __volatile__ ("addi $7,$fp,77":::"fp"); + __asm__ __volatile__ ("addi $7,$sp,77":::"$sp"); + __asm__ __volatile__ ("addi $7,$fp,77":::"$fp"); + __asm__ __volatile__ ("addi $7,$ra,77":::"ra"); + + __asm__ __volatile__ ("addi $7,$0,77":::"$0"); + __asm__ __volatile__ (".set noat \n\t addi $7,$1,77":::"$1"); + __asm__ __volatile__ ("addi $7,$2,77":::"$2"); + __asm__ __volatile__ ("addi $7,$3,77":::"$3"); + __asm__ __volatile__ ("addi $7,$4,77":::"$4"); + __asm__ __volatile__ ("addi $7,$5,77":::"$5"); + __asm__ __volatile__ ("addi $7,$6,77":::"$6"); + __asm__ __volatile__ ("addi $7,$7,77":::"$7"); + __asm__ __volatile__ ("addi $7,$8,77":::"$8"); + __asm__ __volatile__ ("addi $7,$9,77":::"$9"); + __asm__ __volatile__ ("addi $7,$10,77":::"$10"); + __asm__ __volatile__ ("addi $7,$11,77":::"$10"); + __asm__ __volatile__ ("addi $7,$12,77":::"$12"); + __asm__ __volatile__ ("addi $7,$13,77":::"$13"); + __asm__ __volatile__ ("addi $7,$14,77":::"$14"); + __asm__ __volatile__ ("addi $7,$15,77":::"$15"); + __asm__ __volatile__ ("addi $7,$16,77":::"$16"); + __asm__ __volatile__ ("addi $7,$17,77":::"$17"); + __asm__ __volatile__ ("addi $7,$18,77":::"$18"); + __asm__ __volatile__ ("addi $7,$19,77":::"$19"); + __asm__ __volatile__ ("addi $7,$20,77":::"$20"); + __asm__ __volatile__ ("addi $7,$21,77":::"$21"); + __asm__ __volatile__ ("addi $7,$22,77":::"$22"); + __asm__ __volatile__ ("addi $7,$23,77":::"$23"); + __asm__ __volatile__ ("addi $7,$24,77":::"$24"); + __asm__ __volatile__ ("addi $7,$25,77":::"$25"); + __asm__ __volatile__ ("addi $7,$26,77":::"$26"); + __asm__ __volatile__ ("addi $7,$27,77":::"$27"); + __asm__ __volatile__ ("addi $7,$28,77":::"$28"); + __asm__ __volatile__ ("addi $7,$29,77":::"$29"); + __asm__ __volatile__ ("addi $7,$30,77":::"$30"); + __asm__ __volatile__ ("addi $7,$31,77":::"$31"); + +} diff --git a/test/CodeGen/mips-constraint-regs.c b/test/CodeGen/mips-constraint-regs.c new file mode 100644 index 0000000000000..075be058dc3e5 --- /dev/null +++ b/test/CodeGen/mips-constraint-regs.c @@ -0,0 +1,44 @@ +// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s + +// This checks that the frontend will accept inline asm constraints +// c', 'l' and 'x'. Semantic checking will happen in the +// llvm backend. Any bad constraint letters will cause the frontend to +// error out. + +int main() +{ + // 'c': 16 bit address register for Mips16, GPR for all others + // I am using 'c' to constrain both the target and one of the source + // registers. We are looking for syntactical correctness. + int __s, __v = 17; + int __t; + __asm__ __volatile__( + "addi %0,%1,%2 \n\t\t" + : "=c" (__t) + : "c" (__s), "I" (__v)); + + // 'l': lo register + // We are making it clear that destination register is lo with the + // use of the 'l' constraint ("=l"). + int i_temp = 44; + int i_result; + __asm__ __volatile__( + "mtlo %1 \n\t\t" + : "=l" (i_result) + : "r" (i_temp) + : "lo"); + + // 'x': Combined lo/hi registers + // We are specifying that destination registers are the hi/lo pair with the + // use of the 'x' constraint ("=x"). + int i_hi = 3; + int i_lo = 2; + long long ll_result = 0; + __asm__ __volatile__( + "mthi %1 \n\t\t" + "mtlo %2 \n\t\t" + : "=x" (ll_result) + : "r" (i_hi), "r" (i_lo) + : ); + return 0; +} diff --git a/test/CodeGen/mips64-class-return.cpp b/test/CodeGen/mips64-class-return.cpp new file mode 100644 index 0000000000000..dc9ec0f5be4e6 --- /dev/null +++ b/test/CodeGen/mips64-class-return.cpp @@ -0,0 +1,46 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +class B0 { + double d; +}; + +class D0 : public B0 { + float f; +}; + +class B1 { +}; + +class D1 : public B1 { + double d; + float f; +}; + +class D2 : public B0 { + double d2; +}; + +extern D0 gd0; +extern D1 gd1; +extern D2 gd2; + +// CHECK: define { i64, i64 } @_Z4foo1v() +D0 foo1(void) { + return gd0; +} + +// CHECK: define { double, float } @_Z4foo2v() +D1 foo2(void) { + return gd1; +} + +// CHECK: define void @_Z4foo32D2(i64 %a0.coerce0, double %a0.coerce1) +void foo3(D2 a0) { + gd2 = a0; +} + +// CHECK: define void @_Z4foo42D0(%class.D0* nocapture byval %a0) +void foo4(D0 a0) { + gd0 = a0; +} + diff --git a/test/CodeGen/mips64-f128-literal.c b/test/CodeGen/mips64-f128-literal.c new file mode 100644 index 0000000000000..2f01520a4f5f7 --- /dev/null +++ b/test/CodeGen/mips64-f128-literal.c @@ -0,0 +1,9 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +typedef long double LD; + +// CHECK: ret fp128 + +LD foo0() { + return 2.625L; +} diff --git a/test/CodeGen/mips64-nontrivial-return.cpp b/test/CodeGen/mips64-nontrivial-return.cpp new file mode 100644 index 0000000000000..8aff9ab32f0f1 --- /dev/null +++ b/test/CodeGen/mips64-nontrivial-return.cpp @@ -0,0 +1,17 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +class B { +public: + virtual ~B() {} +}; + +class D : public B { +}; + +extern D gd0; + +// CHECK: _Z4foo1v(%class.D* noalias nocapture sret + +D foo1(void) { + return gd0; +} diff --git a/test/CodeGen/mips64-padding-arg.c b/test/CodeGen/mips64-padding-arg.c new file mode 100644 index 0000000000000..b4dcfbace9d47 --- /dev/null +++ b/test/CodeGen/mips64-padding-arg.c @@ -0,0 +1,43 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +typedef struct { + double d; + long double ld; +} S0; + +// Insert padding to ensure arguments of type S0 are aligned to 16-byte boundaries. + +// CHECK: define void @foo1(i32 %a0, i64, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 %b, i64, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3) +// CHECK: tail call void @foo2(i32 1, i32 2, i32 %a0, i64 undef, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 3, i64 undef, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3) +// CHECK: declare void @foo2(i32, i32, i32, i64, double, i64, i64, i64, double, i64, i64, i64, i32, i64, double, i64, i64, i64) + +extern void foo2(int, int, int, S0, S0, int, S0); + +void foo1(int a0, S0 a1, S0 a2, int b, S0 a3) { + foo2(1, 2, a0, a1, a2, 3, a3); +} + +// Insert padding before long double argument. +// +// CHECK: define void @foo3(i32 %a0, i64, fp128 %a1) +// CHECK: tail call void @foo4(i32 1, i32 2, i32 %a0, i64 undef, fp128 %a1) +// CHECK: declare void @foo4(i32, i32, i32, i64, fp128) + +extern void foo4(int, int, int, long double); + +void foo3(int a0, long double a1) { + foo4(1, 2, a0, a1); +} + +// Insert padding after hidden argument. +// +// CHECK: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0) +// CHECK: call void @foo6(%struct.S0* sret %agg.result, i32 1, i32 2, i64 undef, fp128 %a0) +// CHECK: declare void @foo6(%struct.S0* sret, i32, i32, i64, fp128) + +extern S0 foo6(int, int, long double); + +S0 foo5(long double a0) { + return foo6(1, 2, a0); +} + diff --git a/test/CodeGen/mmx-inline-asm.c b/test/CodeGen/mmx-inline-asm.c index 5d1371ed90a17..635e2a6b71efc 100644 --- a/test/CodeGen/mmx-inline-asm.c +++ b/test/CodeGen/mmx-inline-asm.c @@ -1,4 +1,4 @@ -// RUN: %clang -mmmx -ccc-host-triple i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s +// RUN: %clang -mmmx -target i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s // <rdar://problem/9091220> #include <mmintrin.h> diff --git a/test/CodeGen/mmx-shift-with-immediate.c b/test/CodeGen/mmx-shift-with-immediate.c index f430d2e4a2534..ecd1881c4875c 100644 --- a/test/CodeGen/mmx-shift-with-immediate.c +++ b/test/CodeGen/mmx-shift-with-immediate.c @@ -1,4 +1,4 @@ -// RUN: %clang -mmmx -ccc-host-triple i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s +// RUN: %clang -mmmx -target i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s #include <mmintrin.h> void shift(__m64 a, __m64 b, int c) { diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c new file mode 100644 index 0000000000000..d3235aee43644 --- /dev/null +++ b/test/CodeGen/ms-declspecs.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s + +// CHECK: define void @t3() nounwind noinline naked { +__declspec(naked) void t3() {} + +// CHECK: define void @t22() nounwind +void __declspec(nothrow) t22(); +void t22() {} + +// CHECK: define void @t2() nounwind noinline { +__declspec(noinline) void t2() {} + +// CHECK: call void @f20_t() +// CHECK: noreturn +__declspec(noreturn) void f20_t(void); +void f20(void) { f20_t(); } diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c index 9ae1bbfcb1f66..1665f9caa03f2 100644 --- a/test/CodeGen/mult-alt-generic.c +++ b/test/CodeGen/mult-alt-generic.c @@ -1,14 +1,12 @@ // RUN: %clang_cc1 -triple i686 %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple x86_64 %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple arm %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -triple bfin %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple cellspu %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple mblaze %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple mips %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple mipsel %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple powerpc %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple powerpc64 %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -triple s390x %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s diff --git a/test/CodeGen/noinline.c b/test/CodeGen/noinline.c new file mode 100644 index 0000000000000..e64a1a539f4b4 --- /dev/null +++ b/test/CodeGen/noinline.c @@ -0,0 +1,14 @@ +// Make sure -fno-inline-functions is behaving correctly. +// rdar://10972766 + +// RUN: %clang_cc1 -O3 -fno-inline -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s + +inline int dont_inline_me(int a, int b) { return(a+b); } + +volatile int *pa = (int*) 0x1000; +void foo() { +// NOINLINE: @foo +// NOINLINE: dont_inline_me +// NOINLINE-NOT: inlinehint + pa[0] = dont_inline_me(pa[1],pa[2]); +} diff --git a/test/CodeGen/object-size.c b/test/CodeGen/object-size.c index 287d742b877d5..1f16d02d7d64f 100644 --- a/test/CodeGen/object-size.c +++ b/test/CodeGen/object-size.c @@ -55,8 +55,7 @@ void test6() { // CHECK: define void @test7 void test7() { int i; - // CHECK-NOT: __strcpy_chk - // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i64 @llvm.objectsize.i64(i8* {{.*}}@gbuf{{.*}}, i1 false) strcpy((++i, gbuf), "Hi there"); } diff --git a/test/CodeGen/override-layout.c b/test/CodeGen/override-layout.c new file mode 100644 index 0000000000000..99c2cd656ec08 --- /dev/null +++ b/test/CodeGen/override-layout.c @@ -0,0 +1,174 @@ +// RUN: %clang_cc1 -w -fdump-record-layouts %s 2> %t.layouts +// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.before 2>&1 +// RUN: %clang_cc1 -w -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after 2>&1 +// RUN: diff %t.before %t.after +// RUN: FileCheck %s < %t.after + +// If not explicitly disabled, set PACKED to the packed attribute. +#ifndef PACKED +# define PACKED __attribute__((packed)) +#endif + +// If not explicitly disabled, set ALIGNED16 to 16-byte alignment. +#ifndef ALIGNED16 +# define ALIGNED16 __attribute__((aligned(16))) +#endif + +// CHECK: Type: struct X0 +struct X0 { + int x[6] PACKED; +}; + +// CHECK: Type: struct X1 +struct X1 { + char x[13]; + struct X0 y; +} PACKED; + +// CHECK: Type: struct X2 +struct PACKED X2 { + short x; + int y; +}; + +// CHECK: Type: struct X3 +struct X3 { + short x PACKED; + int y; +}; + +#pragma pack(push,2) +// CHECK: Type: struct X4 +struct X4 { + int x; + int y; +}; +#pragma pack(pop) + +// CHECK: Type: struct X5 +struct PACKED X5 { double a[19]; signed char b; }; + +// CHECK: Type: struct X6 +struct PACKED X6 { long double a; char b; }; + +// CHECK: Type: struct X7 +struct X7 { + unsigned x; + unsigned char y; +} PACKED; + +// CHECK: Type: union X8 +union X8 { + struct X7 x; + unsigned y; +} PACKED; + +// CHECK: Type: struct X9 +struct X9 { + unsigned int x[2] PACKED; + unsigned int y; + unsigned int z PACKED; +}; + +// CHECK: Type: struct X10 +struct X10 { + unsigned int x[2] PACKED; + unsigned int y PACKED; + unsigned int z PACKED; +}; + +// CHECK: Type: struct X11 +struct PACKED X11 { + unsigned int x[2]; + unsigned int y; + unsigned int z; +}; + +// CHECK: Type: struct X12 +struct PACKED X12 { + int x : 24; +}; + +// CHECK: Type: struct X13 +struct PACKED X13 { + signed x : 10; + signed y : 10; +}; + +// CHECK: Type: union X14 +union PACKED X14 { + unsigned long long x : 3; +}; + +// CHECK: Type: struct X15 +struct X15 { + unsigned x : 16; + unsigned y : 28 PACKED; +}; + +// CHECK: Type: struct X16 +struct ALIGNED16 X16 { + int a, b, c; + int x : 5; + int y : 29; +}; + +void use_structs() { + struct X0 x0; + x0.x[5] = sizeof(struct X0); + + struct X1 x1; + x1.x[5] = sizeof(struct X1); + + struct X2 x2; + x2.y = sizeof(struct X2); + + struct X3 x3; + x3.y = sizeof(struct X3); + + struct X4 x4; + x4.y = sizeof(struct X4); + + struct X5 x5; + x5.b = sizeof(struct X5); + + struct X6 x6; + x6.b = sizeof(struct X6); + + struct X7 x7; + typedef int X7array[sizeof(struct X7)]; + x7.x = sizeof(struct X7); + x7.y = x7.x; + + union X8 x8; + typedef int X8array[sizeof(union X8)]; + x8.y = sizeof(union X8); + x8.x.x = x8.y; + + struct X9 x9; + typedef int X9array[sizeof(struct X9)]; + x9.y = sizeof(struct X9); + + struct X10 x10; + typedef int X10array[sizeof(struct X10)]; + x10.y = sizeof(struct X10); + + struct X11 x11; + typedef int X11array[sizeof(struct X11)]; + x11.y = sizeof(struct X11); + + struct X12 x12; + x12.x = sizeof(struct X12); + + struct X13 x13; + x13.x = sizeof(struct X13); + + union X14 x14; + x14.x = sizeof(union X14); + + struct X15 x15; + x15.x = sizeof(struct X15); + + struct X16 x16; + x16.x = sizeof(struct X16); +} diff --git a/test/CodeGen/packed-nest-unpacked.c b/test/CodeGen/packed-nest-unpacked.c new file mode 100644 index 0000000000000..af1508ae81de9 --- /dev/null +++ b/test/CodeGen/packed-nest-unpacked.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-macosx10.7.2 -emit-llvm -o - | FileCheck %s +// <rdar://problem/10463337> + +struct X { int x[6]; }; +struct Y { char x[13]; struct X y; } __attribute((packed)); +struct Y g; +void f(struct X); + +struct X test1() { + // CHECK: @test1 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false) + return g.y; +} +struct X test2() { + // CHECK: @test2 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false) + struct X a = g.y; + return a; +} + +void test3(struct X a) { + // CHECK: @test3 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i8* {{.*}}, i64 24, i32 1, i1 false) + g.y = a; +} + +void test4() { + // CHECK: @test4 + // FIXME: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false) + f(g.y); +} diff --git a/test/CodeGen/pascal-wchar-string.c b/test/CodeGen/pascal-wchar-string.c index a6b619643e1f1..626fc99f15fb0 100644 --- a/test/CodeGen/pascal-wchar-string.c +++ b/test/CodeGen/pascal-wchar-string.c @@ -29,8 +29,8 @@ int main(int argc, char* argv[]) return 0; } -// CHECK: c"\03\00b\00a\00r\00\00\00" -// CHECK: c"\04\00g\00o\00r\00f\00\00\00" +// CHECK: [i16 3, i16 98, i16 97, i16 114, i16 0] +// CHECK: [i16 4, i16 103, i16 111, i16 114, i16 102, i16 0] // PR8856 - -fshort-wchar makes wchar_t be unsigned. diff --git a/test/CodeGen/popcnt-builtins.c b/test/CodeGen/popcnt-builtins.c new file mode 100644 index 0000000000000..f072b29cd1d5b --- /dev/null +++ b/test/CodeGen/popcnt-builtins.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned int test_mm_popcnt_u32(unsigned int __X) { + // CHECK: @llvm.ctpop.i32 + return _mm_popcnt_u32(__X); +} + +unsigned long long test_mm_popcnt_u64(unsigned long long __X) { + // CHECK: @llvm.ctpop.i64 + return _mm_popcnt_u64(__X); +} diff --git a/test/CodeGen/va_list_test.c b/test/CodeGen/powerpc_types.c index 74f7837d2d3c6..b7d0f5de49859 100644 --- a/test/CodeGen/va_list_test.c +++ b/test/CodeGen/powerpc_types.c @@ -4,3 +4,7 @@ int va_list_size = sizeof(va_list); // SVR4-CHECK: va_list_size = global i32 12, align 4 +int long_double_size = sizeof(long double); +// SVR4-CHECK: long_double_size = global i32 8, align 4 +int double_size = sizeof(double); +// SVR4-CHECK: double_size = global i32 8, align 4 diff --git a/test/CodeGen/pr12251.c b/test/CodeGen/pr12251.c new file mode 100644 index 0000000000000..a644bb79da550 --- /dev/null +++ b/test/CodeGen/pr12251.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -o - | FileCheck %s + +enum e1 {e1_a = -1 }; +enum e1 g1(enum e1 *x) { + return *x; +} + +// CHECK: define i32 @g1 +// CHECK: load i32* %x, align 4 +// CHECK-NOT: range +// CHECK: ret diff --git a/test/CodeGen/pr9614.c b/test/CodeGen/pr9614.c index 8c767766832da..8fdb2f299ce0a 100644 --- a/test/CodeGen/pr9614.c +++ b/test/CodeGen/pr9614.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -O1 -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s extern void foo_alias (void) __asm ("foo"); inline void foo (void) { @@ -8,15 +8,22 @@ extern void bar_alias (void) __asm ("bar"); inline __attribute__ ((__always_inline__)) void bar (void) { return bar_alias (); } +extern char *strrchr_foo (const char *__s, int __c) __asm ("strrchr"); +extern inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * strrchr_foo (const char *__s, int __c) { + return __builtin_strrchr (__s, __c); +} void f(void) { foo(); bar(); + strrchr_foo("", '.'); } // CHECK: define void @f() // CHECK: call void @foo() // CHECK-NEXT: call void @bar() +// CHECK-NEXT: call i8* @strrchr( // CHECK-NEXT: ret void // CHECK: declare void @foo() // CHECK: declare void @bar() +// CHECK: declare i8* @strrchr(i8*, i32) diff --git a/test/CodeGen/redefine_extname.c b/test/CodeGen/redefine_extname.c new file mode 100644 index 0000000000000..e73a3ad8dfcee --- /dev/null +++ b/test/CodeGen/redefine_extname.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s + +#pragma redefine_extname fake real +#pragma redefine_extname name alias + +extern int fake(void); + +int name; + +// __PRAGMA_REDEFINE_EXTNAME should be defined. This will fail if it isn't... +int fish() { return fake() + __PRAGMA_REDEFINE_EXTNAME + name; } +// Check that the call to fake() is emitted as a call to real() +// CHECK: call i32 @real() +// Check that this also works with variables names +// CHECK: load i32* @alias diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c index 64ee4c970fe0e..2d5742515553a 100644 --- a/test/CodeGen/sse-builtins.c +++ b/test/CodeGen/sse-builtins.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -ffreestanding -triple i386-apple-darwin9 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s #include <emmintrin.h> +#include <smmintrin.h> __m128 test_loadl_pi(__m128 x, void* y) { // CHECK: define {{.*}} @test_loadl_pi @@ -102,3 +103,51 @@ __m128i test_loadl_epi64(void* y) { // CHECK: load i64* {{.*}}, align 1{{$}} return _mm_loadl_epi64(y); } + +__m128i test_mm_minpos_epu16(__m128i x) { + // CHECK: define {{.*}} @test_mm_minpos_epu16 + // CHECK: @llvm.x86.sse41.phminposuw + return _mm_minpos_epu16(x); +} + +__m128i test_mm_mpsadbw_epu8(__m128i x, __m128i y) { + // CHECK: define {{.*}} @test_mm_mpsadbw_epu8 + // CHECK: @llvm.x86.sse41.mpsadbw + return _mm_mpsadbw_epu8(x, y, 1); +} + +__m128 test_mm_dp_ps(__m128 x, __m128 y) { + // CHECK: define {{.*}} @test_mm_dp_ps + // CHECK: @llvm.x86.sse41.dpps + return _mm_dp_ps(x, y, 2); +} + +__m128d test_mm_dp_pd(__m128d x, __m128d y) { + // CHECK: define {{.*}} @test_mm_dp_pd + // CHECK: @llvm.x86.sse41.dppd + return _mm_dp_pd(x, y, 2); +} + +__m128 test_mm_round_ps(__m128 x) { + // CHECK: define {{.*}} @test_mm_round_ps + // CHECK: @llvm.x86.sse41.round.ps + return _mm_round_ps(x, 2); +} + +__m128 test_mm_round_ss(__m128 x, __m128 y) { + // CHECK: define {{.*}} @test_mm_round_ss + // CHECK: @llvm.x86.sse41.round.ss + return _mm_round_ss(x, y, 2); +} + +__m128d test_mm_round_pd(__m128d x) { + // CHECK: define {{.*}} @test_mm_round_pd + // CHECK: @llvm.x86.sse41.round.pd + return _mm_round_pd(x, 2); +} + +__m128d test_mm_round_sd(__m128d x, __m128d y) { + // CHECK: define {{.*}} @test_mm_round_sd + // CHECK: @llvm.x86.sse41.round.sd + return _mm_round_sd(x, y, 2); +} diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c index 1d4f633f61726..e2bbb5a90a818 100644 --- a/test/CodeGen/statements.c +++ b/test/CodeGen/statements.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wreturn-type %s -emit-llvm-only +// RUN: %clang_cc1 -Wno-error=return-type %s -emit-llvm-only void test1(int x) { switch (x) { diff --git a/test/CodeGen/string-literal-short-wstring.c b/test/CodeGen/string-literal-short-wstring.c index 770c3d4268713..88e4a1e4008aa 100644 --- a/test/CodeGen/string-literal-short-wstring.c +++ b/test/CodeGen/string-literal-short-wstring.c @@ -6,11 +6,11 @@ int main() { // CHECK: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 char b[10] = "\u1120\u0220\U00102030"; - // CHECK: private unnamed_addr constant [6 x i8] c"A\00B\00\00\00" + // CHECK: private unnamed_addr constant [3 x i16] [i16 65, i16 66, i16 0] const wchar_t *foo = L"AB"; // This should convert to utf16. - // CHECK: private unnamed_addr constant [10 x i8] c" \11 \02\C8\DB0\DC\00\00" + // CHECK: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0] const wchar_t *bar = L"\u1120\u0220\U00102030"; @@ -29,15 +29,4 @@ int main() { // -4085 == 0xf00b // CHECK: store i16 -4085 wchar_t wc = L'\uF00B'; - - // Should take lower word of the 4byte UNC sequence. This does not match - // gcc. I don't understand what gcc does (it looks like it converts to utf16, - // then takes the second (!) utf16 word, swaps the lower two nibbles, and - // stores that?). - // CHECK: store i16 -4085 - wchar_t wd = L'\U0010F00B'; // has utf16 encoding dbc8 dcb0 - - // Should pick second character. (gcc: -9205) - // CHECK: store i16 -4085 - wchar_t we = L'\u1234\U0010F00B'; } diff --git a/test/CodeGen/string-literal-unicode-conversion.c b/test/CodeGen/string-literal-unicode-conversion.c new file mode 100644 index 0000000000000..3e5b7fb041129 --- /dev/null +++ b/test/CodeGen/string-literal-unicode-conversion.c @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s +// RUN: %clang_cc1 -x c++ -std=c++0x -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CPP0X %s +// RUN: %clang_cc1 -x c++ -std=c++0x -fshort-wchar -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=SHORTWCHAR %s + +// This file contains a mix of ISO-8859-1 and UTF-8 encoded data. +// the literal assigned to 'aa' should be the ISO-8859-1 encoding for the code +// points U+00C0 U+00E9 U+00EE U+00F5 U+00FC + +// The rest of the literals should contain the UTF-8 encoding for U+041A U+043E +// U+0448 U+043A U+0430 + +#ifndef __cplusplus +#include <stddef.h> +#endif + +#ifdef __cplusplus +extern "C" +#endif +void f() { + // CHECK-C: private unnamed_addr constant [6 x i8] c"\C0\E9\EE\F5\FC\00", align 1 + // CHECK-CPP0X: private unnamed_addr constant [6 x i8] c"\C0\E9\EE\F5\FC\00", align 1 + char const *aa = "Àéîõü"; + + // CHECK-C: private unnamed_addr constant [11 x i8] c"\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + // CHECK-CPP0X: private unnamed_addr constant [11 x i8] c"\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + char const *a = "Кошка"; + + // CHECK-C: private unnamed_addr constant [6 x i32] [i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + // CHECK-SHORTWCHAR: private unnamed_addr constant [6 x i16] [i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + // CHECK-CPP0X: private unnamed_addr constant [6 x i32] [i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + wchar_t const *b = L"Кошка"; + + // CHECK-C: private unnamed_addr constant [4 x i32] [i32 20320, i32 22909, i32 66304, i32 0], align 4 + // CHECK-SHORTWCHAR: private unnamed_addr constant [4 x i16] [i16 20320, i16 22909, i16 768, i16 0], align 2 + // CHECK-CPP0X: private unnamed_addr constant [4 x i32] [i32 20320, i32 22909, i32 66304, i32 0], align 4 + wchar_t const *b2 = L"\x4f60\x597d\x10300"; + +#if __cplusplus >= 201103L + + // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"1\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + char const *c = u8"1Кошка"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i16] [i16 50, i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + char16_t const *e = u"2Кошка"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i32] [i32 51, i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + char32_t const *f = U"3Кошка"; + + // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"4\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + char const *d = u8R"(4Кошка)"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i16] [i16 53, i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + char16_t const *g = uR"(5Кошка)"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i32] [i32 54, i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + char32_t const *h = UR"(6Кошка)"; + + // CHECK-SHORTWCHAR: private unnamed_addr constant [7 x i16] [i16 55, i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + // CHECK-CPP0X: private unnamed_addr constant [7 x i32] [i32 55, i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + wchar_t const *i = LR"(7Кошка)"; + +#endif +} diff --git a/test/CodeGen/string-literal.c b/test/CodeGen/string-literal.c index fa8f28a766c47..12d431a45434b 100644 --- a/test/CodeGen/string-literal.c +++ b/test/CodeGen/string-literal.c @@ -14,37 +14,37 @@ int main() { // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 char b[10] = "\u1120\u0220\U00102030"; - // CHECK-C: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00", align 4 - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00", align 4 + // CHECK-C: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4 const wchar_t *foo = L"AB"; - // CHECK-C: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00", align 4 - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00", align 4 + // CHECK-C: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4 const wchar_t *bar = L"\u1234\U0010F00B"; - // CHECK-C: private unnamed_addr constant [12 x i8] c"4\12\00\00\0C\F0\10\00\00\00\00\00", align 4 - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"4\12\00\00\0C\F0\10\00\00\00\00\00", align 4 + // CHECK-C: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4 const wchar_t *baz = L"\u1234" "\U0010F00C"; #if __cplusplus >= 201103L - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"C\00\00\00D\00\00\00\00\00\00\00", align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 67, i32 68, i32 0], align 4 const char32_t *c = U"CD"; - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"5\12\00\00\0C\F0\10\00\00\00\00\00", align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110028, i32 0], align 4 const char32_t *d = U"\u1235\U0010F00C"; - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"5\12\00\00\0B\F0\10\00\00\00\00\00", align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110027, i32 0], align 4 const char32_t *o = "\u1235" U"\U0010F00B"; - // CHECK-CPP0X: private unnamed_addr constant [6 x i8] c"E\00F\00\00\00", align 2 + // CHECK-CPP0X: private unnamed_addr constant [3 x i16] [i16 69, i16 70, i16 0], align 2 const char16_t *e = u"EF"; // This should convert to utf16. - // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c" \11 \02\C8\DB0\DC\00\00", align 2 + // CHECK-CPP0X: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0], align 2 const char16_t *f = u"\u1120\u0220\U00102030"; // This should convert to utf16. - // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c" \11 \03\C8\DB0\DC\00\00", align 2 + // CHECK-CPP0X: private unnamed_addr constant [5 x i16] [i16 4384, i16 800, i16 -9272, i16 -9168, i16 0], align 2 const char16_t *p = u"\u1120\u0320" "\U00102030"; // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"def\00", align 1 @@ -56,13 +56,13 @@ int main() { // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"jkl\00", align 1 const char *i = u8R"bar(jkl)bar"; - // CHECK-CPP0X: private unnamed_addr constant [6 x i8] c"G\00H\00\00\00", align 2 + // CHECK-CPP0X: private unnamed_addr constant [3 x i16] [i16 71, i16 72, i16 0], align 2 const char16_t *j = uR"foo(GH)foo"; - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"I\00\00\00J\00\00\00\00\00\00\00", align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 73, i32 74, i32 0], align 4 const char32_t *k = UR"bar(IJ)bar"; - // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"K\00\00\00L\00\00\00\00\00\00\00", align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 75, i32 76, i32 0], align 4 const wchar_t *l = LR"bar(KL)bar"; // CHECK-CPP0X: private unnamed_addr constant [9 x i8] c"abc\5Cndef\00", align 1 diff --git a/test/CodeGen/switch-dce.c b/test/CodeGen/switch-dce.c index bbb5f7e5aa365..a18d3bc89e7d3 100644 --- a/test/CodeGen/switch-dce.c +++ b/test/CodeGen/switch-dce.c @@ -216,32 +216,19 @@ void test12() { } } - -// rdar://9289524 - Check that the empty cases don't produce an empty block. +// Verify that case 42 only calls test14 once. // CHECK: @test13 -// CHECK: switch -// CHECK: i32 42, label [[EPILOG:%[0-9.a-z]+]] -// CHECK: i32 11, label [[EPILOG]] +// CHECK: call void @test13(i32 97) +// CHECK-NEXT: br label %[[EPILOG2:[0-9.a-z]+]] +// CHECK: [[EPILOG2]] +// CHECK-NEXT: br label [[EPILOG:%[0-9.a-z]+]] +// CHECK: call void @test13(i32 42) +// CHECK-NEXT: br label [[EPILOG]] void test13(int x) { switch (x) { - case 42: break; // No empty block please. - case 11: break; // No empty block please. - default: test13(42); break; - } -} - - -// Verify that case 42 only calls test14 once. -// CHECK: @test14 -// CHECK: call void @test14(i32 97) -// CHECK-NEXT: br label [[EPILOG2:%[0-9.a-z]+]] -// CHECK: call void @test14(i32 42) -// CHECK-NEXT: br label [[EPILOG2]] -void test14(int x) { - switch (x) { - case 42: test14(97); // fallthrough + case 42: test13(97); // fallthrough case 11: break; - default: test14(42); break; + default: test13(42); break; } } diff --git a/test/CodeGen/tbaa-for-vptr.cpp b/test/CodeGen/tbaa-for-vptr.cpp new file mode 100644 index 0000000000000..f4885f805d27d --- /dev/null +++ b/test/CodeGen/tbaa-for-vptr.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s +// Check that we generate TBAA for vtable pointer loads and stores. +struct A { + virtual int foo() const ; + virtual ~A(); +}; + +void CreateA() { + new A; +} + +void CallFoo(A *a) { + a->foo(); +} + +// CHECK: %{{.*}} = load {{.*}} !tbaa !0 +// CHECK: store {{.*}} !tbaa !0 +// CHECK: !0 = metadata !{metadata !"vtable pointer", metadata !1} +// CHECK: !1 = metadata !{metadata !"Simple C/C++ TBAA", null} diff --git a/test/CodeGen/utf16-cfstrings.c b/test/CodeGen/utf16-cfstrings.c new file mode 100644 index 0000000000000..d4f214b0d644a --- /dev/null +++ b/test/CodeGen/utf16-cfstrings.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s +// <rdar://problem/10655949> + +// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 252, i16 98, i16 101, i16 114, i16 104, i16 117, i16 110, i16 100, i16 0], align 2 + +#define CFSTR __builtin___CFStringMakeConstantString + +void foo() { + CFSTR("überhund"); +} diff --git a/test/CodeGen/var-align.c b/test/CodeGen/var-align.c deleted file mode 100644 index fefd35ab634d1..0000000000000 --- a/test/CodeGen/var-align.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - | grep "align 16" | count 2 - -__attribute((aligned(16))) float a[128]; -union {int a[4]; __attribute((aligned(16))) float b[4];} u; diff --git a/test/CodeGen/vla-4.c b/test/CodeGen/vla-4.c new file mode 100644 index 0000000000000..6e4ca985a6acc --- /dev/null +++ b/test/CodeGen/vla-4.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +int f(); +int h(); + +void t1() { + _Atomic(typeof((int (*)[f()]) h())) v; + // CHECK: [[N:%.*]] = alloca i32*, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} + +void t2() { + typeof(typeof((int (*)[f()]) h())) v; + // CHECK: [[N:%.*]] = alloca i32*, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} + +void t3(typeof((int (*)[f()]) h()) v) { + // CHECK: store i32* %v, i32** %{{[.0-9A-Za-z]+}}, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c index c9612bc16032c..9e62da52e0266 100644 --- a/test/CodeGen/vla.c +++ b/test/CodeGen/vla.c @@ -116,9 +116,6 @@ int test4(unsigned n, char (*p)[n][n+1][6]) { // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1 - // __typeof. FIXME: does this really need to be loaded? - // CHECK-NEXT: load [6 x i8]** [[P]] - // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P]], align 4 // CHECK-NEXT: [[T1:%.*]] = load i32* [[N]], align 4 // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 diff --git a/test/CodeGen/vld_dup.c b/test/CodeGen/vld_dup.c new file mode 100644 index 0000000000000..e1d63cca25063 --- /dev/null +++ b/test/CodeGen/vld_dup.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple armv7a-linux-gnueabi \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -emit-llvm -O0 -o - %s | FileCheck %s +#include <arm_neon.h> +int main(){ + int32_t v0[3]; + int32x2x3_t v1; + int32_t v2[4]; + int32x2x4_t v3; + int64x1x3_t v4; + int64x1x4_t v5; + int64_t v6[3]; + int64_t v7[4]; + + v1 = vld3_dup_s32(v0); +// CHECK: [[T168:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld3lane.v2i32(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) +// CHECK-NEXT: [[T169:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T168]], 0 +// CHECK-NEXT: [[T170:%.*]] = shufflevector <2 x i32> [[T169]], <2 x i32> [[T169]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T171:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T168]], <2 x i32> [[T170]], 0 +// CHECK-NEXT: [[T172:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T171]], 1 +// CHECK-NEXT: [[T173:%.*]] = shufflevector <2 x i32> [[T172]], <2 x i32> [[T172]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T174:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T171]], <2 x i32> [[T173]], 1 +// CHECK-NEXT: [[T175:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T174]], 2 +// CHECK-NEXT: [[T176:%.*]] = shufflevector <2 x i32> [[T175]], <2 x i32> [[T175]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T177:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T174]], <2 x i32> [[T176]], 2 + + v3 = vld4_dup_s32(v2); +// CHECK: [[T178:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld4lane.v2i32(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) +// CHECK-NEXT: [[T179:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T178]], 0 +// CHECK-NEXT: [[T180:%.*]] = shufflevector <2 x i32> [[T179]], <2 x i32> [[T179]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T181:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T178]], <2 x i32> [[T180]], 0 +// CHECK-NEXT: [[T182:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T181]], 1 +// CHECK-NEXT: [[T183:%.*]] = shufflevector <2 x i32> [[T182]], <2 x i32> [[T182]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T184:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T181]], <2 x i32> [[T183]], 1 +// CHECK-NEXT: [[T185:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T184]], 2 +// CHECK-NEXT: [[T186:%.*]] = shufflevector <2 x i32> [[T185]], <2 x i32> [[T185]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T187:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T184]], <2 x i32> [[T186]], 2 +// CHECK-NEXT: [[T188:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T187]], 3 +// CHECK-NEXT: [[T189:%.*]] = shufflevector <2 x i32> [[T188]], <2 x i32> [[T188]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T190:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T187]], <2 x i32> [[T189]], 3 + + v4 = vld3_dup_s64(v6); +// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld3.v1i64(i8* {{.*}}, i32 {{[0-9]+}}) + + v5 = vld4_dup_s64(v7); +// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld4.v1i64(i8* {{.*}}, i32 {{[0-9]+}}) + + return 0; +} diff --git a/test/CodeGen/wchar-const.c b/test/CodeGen/wchar-const.c index b672b15360a20..a9e7e523f96d3 100644 --- a/test/CodeGen/wchar-const.c +++ b/test/CodeGen/wchar-const.c @@ -14,8 +14,8 @@ typedef __WCHAR_TYPE__ wchar_t; #endif -// CHECK-DAR: private unnamed_addr constant [72 x i8] c" -// CHECK-WIN: private unnamed_addr constant [36 x i8] c" +// CHECK-DAR: private unnamed_addr constant [18 x i32] [i32 84, +// CHECK-WIN: private unnamed_addr constant [18 x i16] [i16 84, extern void foo(const wchar_t* p); int main (int argc, const char * argv[]) { diff --git a/test/CodeGen/x86_32-arguments-darwin.c b/test/CodeGen/x86_32-arguments-darwin.c index 7727c43f6e8db..0ac18b792f9f3 100644 --- a/test/CodeGen/x86_32-arguments-darwin.c +++ b/test/CodeGen/x86_32-arguments-darwin.c @@ -173,7 +173,7 @@ struct s42 { enum e40 f0; } f42(void) { } // CHECK: define i64 @f43() struct s43 { enum e40 f0; int f1; } f43(void) { } -// CHECK: define i32 @f44() +// CHECK: define void ()* @f44() struct s44 { vvbp f0; } f44(void) { } // CHECK: define i64 @f45() @@ -275,3 +275,52 @@ void f56(char a0, struct s56_0 a1, f56_0(1, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); } + +// CHECK: define void @f57(i32 %x.0, i32 %x.1) +// CHECK: call void @f57( +struct s57 { _Complex int x; }; +void f57(struct s57 x) {} void f57a(void) { f57((struct s57){1}); } + +// CHECK: define void @f58() +union u58 {}; +void f58(union u58 x) {} + +// CHECK: define i64 @f59() +struct s59 { float x __attribute((aligned(8))); }; +struct s59 f59() { while (1) {} } + +// CHECK: define void @f60(%struct.s60* byval align 4, i32 %y) +struct s60 { int x __attribute((aligned(8))); }; +void f60(struct s60 x, int y) {} + +// CHECK: define void @f61(i32 %x, %struct.s61* byval align 16 %y) +typedef int T61 __attribute((vector_size(16))); +struct s61 { T61 x; int y; }; +void f61(int x, struct s61 y) {} + +// CHECK: define void @f62(i32 %x, %struct.s62* byval align 4) +typedef int T62 __attribute((vector_size(16))); +struct s62 { T62 x; int y; } __attribute((packed, aligned(8))); +void f62(int x, struct s62 y) {} + +// CHECK: define i32 @f63 +// CHECK: ptrtoint +// CHECK: and {{.*}}, -16 +// CHECK: inttoptr +typedef int T63 __attribute((vector_size(16))); +struct s63 { T63 x; int y; }; +int f63(int i, ...) { + __builtin_va_list ap; + __builtin_va_start(ap, i); + struct s63 s = __builtin_va_arg(ap, struct s63); + __builtin_va_end(ap); + return s.y; +} + +// CHECK: define void @f64(%struct.s64* byval align 4 %x) +struct s64 { signed char a[0]; signed char b[]; }; +void f64(struct s64 x) {} + +// CHECK: define float @f65() +struct s65 { signed char a[0]; float b; }; +struct s65 f65() { return (struct s65){{},2}; } diff --git a/test/CodeGen/x86_32-arguments-win32.c b/test/CodeGen/x86_32-arguments-win32.c new file mode 100644 index 0000000000000..f18bb30fa4748 --- /dev/null +++ b/test/CodeGen/x86_32-arguments-win32.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s + +// CHECK: define i64 @f1_1() +// CHECK: define void @f1_2(i32 %a0.0, i32 %a0.1) +struct s1 { + int a; + int b; +}; +struct s1 f1_1(void) { while (1) {} } +void f1_2(struct s1 a0) {} + +// CHECK: define i32 @f2_1() +struct s2 { + short a; + short b; +}; +struct s2 f2_1(void) { while (1) {} } + +// CHECK: define i16 @f3_1() +struct s3 { + char a; + char b; +}; +struct s3 f3_1(void) { while (1) {} } + +// CHECK: define i8 @f4_1() +struct s4 { + char a:4; + char b:4; +}; +struct s4 f4_1(void) { while (1) {} } + +// CHECK: define i64 @f5_1() +// CHECK: define void @f5_2(double %a0.0) +struct s5 { + double a; +}; +struct s5 f5_1(void) { while (1) {} } +void f5_2(struct s5 a0) {} + +// CHECK: define i32 @f6_1() +// CHECK: define void @f6_2(float %a0.0) +struct s6 { + float a; +}; +struct s6 f6_1(void) { while (1) {} } +void f6_2(struct s6 a0) {} + diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index 8571ac9655528..f73e1f026a837 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX #include <stdarg.h> // CHECK: define signext i8 @f0() @@ -263,8 +264,10 @@ void f9122143() typedef unsigned v2i32 __attribute((__vector_size__(8))); v2i32 f36(v2i32 arg) { return arg; } -// CHECK: declare void @f38(<8 x float>) -// CHECK: declare void @f37(<8 x float>) +// AVX: declare void @f38(<8 x float>) +// AVX: declare void @f37(<8 x float>) +// CHECK: declare void @f38(%struct.s256* byval align 32) +// CHECK: declare void @f37(<8 x float>* byval align 32) typedef float __m256 __attribute__ ((__vector_size__ (32))); typedef struct { __m256 m; @@ -304,3 +307,50 @@ extern void func42(SA s); void func43(SA s) { func42(s); } + +// CHECK: define i32 @f44 +// CHECK: ptrtoint +// CHECK-NEXT: and {{.*}}, -32 +// CHECK-NEXT: inttoptr +typedef int T44 __attribute((vector_size(32))); +struct s44 { T44 x; int y; }; +int f44(int i, ...) { + __builtin_va_list ap; + __builtin_va_start(ap, i); + struct s44 s = __builtin_va_arg(ap, struct s44); + __builtin_va_end(ap); + return s.y; +} + +// Text that vec3 returns the correct LLVM IR type. +// AVX: define i32 @foo(<3 x i64> %X) +typedef long long3 __attribute((ext_vector_type(3))); +int foo(long3 X) +{ + return 0; +} + +// Make sure we don't use a varargs convention for a function without a +// prototype where AVX types are involved. +// AVX: @test45 +// AVX: call i32 bitcast (i32 (...)* @f45 to i32 (<8 x float>)*) +int f45(); +__m256 x45; +void test45() { f45(x45); } + +// Make sure we use byval to pass 64-bit vectors in memory; the LLVM call +// lowering can't handle this case correctly because it runs after legalization. +// CHECK: @test46 +// CHECK: call void @f46({{.*}}<2 x float>* byval align 8 {{.*}}, <2 x float>* byval align 8 {{.*}}) +typedef float v46 __attribute((vector_size(8))); +void f46(v46,v46,v46,v46,v46,v46,v46,v46,v46,v46); +void test46() { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); } + +// Check that we pass the struct below without using byval, which helps out +// codegen. +// +// CHECK: @test47 +// CHECK: call void @f47(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}) +struct s47 { unsigned a; }; +void f47(int,int,int,int,int,int,struct s47); +void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); } |