diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 13cc256e404620c1de0cbcc4e43ce1e2dbbc4898 (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /test/CodeGen | |
parent | 657bc3d9848e3be92029b2416031340988cd0111 (diff) | |
download | src-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.tar.gz src-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.zip |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):vendor/clang/clang-release_32-r168974
Notes
Notes:
svn path=/vendor/clang/dist/; revision=243791
svn path=/vendor/clang/clang-release_32-r168974/; revision=243792; tag=vendor/clang/clang-release_32-r168974
Diffstat (limited to 'test/CodeGen')
84 files changed, 2395 insertions, 125 deletions
diff --git a/test/CodeGen/2004-03-16-AsmRegisterCrash.c b/test/CodeGen/2004-03-16-AsmRegisterCrash.c index 515d2436b1a8..492e24853dec 100644 --- a/test/CodeGen/2004-03-16-AsmRegisterCrash.c +++ b/test/CodeGen/2004-03-16-AsmRegisterCrash.c @@ -1,6 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -// XFAIL: * -// XTARGET: arm, i386, i686, x86_64 +// RUN: %clang_cc1 -triple armv7-unknown-unknown %s -o /dev/null +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -o /dev/null int foo() { #ifdef __arm__ diff --git a/test/CodeGen/2008-01-25-ByValReadNone.c b/test/CodeGen/2008-01-25-ByValReadNone.c index d977139b2120..ca21f6c443a0 100644 --- a/test/CodeGen/2008-01-25-ByValReadNone.c +++ b/test/CodeGen/2008-01-25-ByValReadNone.c @@ -1,7 +1,9 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | not grep readonly -// RUN: %clang_cc1 -emit-llvm -o - %s | not grep readnone +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -// XFAIL: arm,mips +// XFAIL: mips + +// CHECK-NOT: readonly +// CHECK-NOT: readnone // The struct being passed byval means that we cannot mark the // function readnone. Readnone would allow stores to the arg to diff --git a/test/CodeGen/2008-01-25-ZeroSizedAggregate.c b/test/CodeGen/2008-01-25-ZeroSizedAggregate.c index d9059856254f..3ffcc7b0c578 100644 --- a/test/CodeGen/2008-01-25-ZeroSizedAggregate.c +++ b/test/CodeGen/2008-01-25-ZeroSizedAggregate.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -o - +// REQUIRES: LP64 // Aggregates of size zero should be dropped from argument list. typedef long int Tlong; diff --git a/test/CodeGen/2008-12-23-AsmIntPointerTie.c b/test/CodeGen/2008-12-23-AsmIntPointerTie.c index df646b7801f7..04b285e6866c 100644 --- a/test/CodeGen/2008-12-23-AsmIntPointerTie.c +++ b/test/CodeGen/2008-12-23-AsmIntPointerTie.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -O1 -o - +// REQUIRES: LP64 typedef long intptr_t; int test(void *b) { diff --git a/test/CodeGen/2009-06-01-addrofknr.c b/test/CodeGen/2009-06-01-addrofknr.c index 17d6fdf5d89f..f987e3270c87 100644 --- a/test/CodeGen/2009-06-01-addrofknr.c +++ b/test/CodeGen/2009-06-01-addrofknr.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -o %t -emit-llvm -verify +// expected-no-diagnostics // PR4289 struct funcptr { diff --git a/test/CodeGen/2010-06-17-asmcrash.c b/test/CodeGen/2010-06-17-asmcrash.c index 8e9485bba9b8..1b5efd3cfeb1 100644 --- a/test/CodeGen/2010-06-17-asmcrash.c +++ b/test/CodeGen/2010-06-17-asmcrash.c @@ -1,6 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | llc -mtriple=x86_64-apple-darwin | FileCheck %s -// XFAIL: * -// XTARGET: x86,i386,i686 +// REQUIRES: x86-64-registered-target +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O1 -S -o - %s | FileCheck %s typedef long long int64_t; typedef unsigned char uint8_t; diff --git a/test/CodeGen/PR3589-freestanding-libcalls.c b/test/CodeGen/PR3589-freestanding-libcalls.c index 8b8282fb80b9..40e5fb11214b 100644 --- a/test/CodeGen/PR3589-freestanding-libcalls.c +++ b/test/CodeGen/PR3589-freestanding-libcalls.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1 -// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1 -// RUN: %clang_cc1 -ffreestanding -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 0 +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1 +// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1 +// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 0 int printf(const char *, ...); diff --git a/test/CodeGen/a15.c b/test/CodeGen/a15.c new file mode 100644 index 000000000000..e4986d885391 --- /dev/null +++ b/test/CodeGen/a15.c @@ -0,0 +1,5 @@ +// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a15 -emit-llvm -S %s -o /dev/null + +int main() { + return 0; +} diff --git a/test/CodeGen/address-safety-attr.cpp b/test/CodeGen/address-safety-attr.cpp index da68b1d703fa..5c9862d85b5e 100644 --- a/test/CodeGen/address-safety-attr.cpp +++ b/test/CodeGen/address-safety-attr.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -o - %s -faddress-sanitizer | FileCheck -check-prefix ASAN %s +// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=address | FileCheck -check-prefix ASAN %s // The address_safety attribute should be attached to functions // when AddressSanitizer is enabled, unless no_address_safety_analysis attribute diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c index f2e87a5dafbc..0ccbca645157 100644 --- a/test/CodeGen/alias.c +++ b/test/CodeGen/alias.c @@ -1,32 +1,46 @@ -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s -// RUN: grep '@g0 = common global i32 0' %t -// RUN: grep '@f1 = alias void ()\* @f0' %t -// RUN: grep '@g1 = alias i32\* @g0' %t -// RUN: grep 'define void @f0() nounwind {' %t - -void f0(void) { } -extern void f1(void); -extern void f1(void) __attribute((alias("f0"))); +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECKBASIC %s +// RUN: %clang_cc1 -triple armv7a-eabi -mfloat-abi hard -emit-llvm -o - %s | FileCheck -check-prefix=CHECKCC %s int g0; +// CHECKBASIC: @g0 = common global i32 0 +static int bar1 = 42; +// CHECKBASIC: @bar1 = internal global i32 42 + extern int g1; extern int g1 __attribute((alias("g0"))); +// CHECKBASIC: @g1 = alias i32* @g0 + +void f0(void) { } +extern void f1(void); +extern void f1(void) __attribute((alias("f0"))); +// CHECKBASIC: @f1 = alias void ()* @f0 +// CHECKBASIC: define void @f0() nounwind { // Make sure that aliases cause referenced values to be emitted. // PR3200 -// RUN: grep 'define internal i32 @foo1()' %t static inline int foo1() { return 0; } +// CHECKBASIC: define internal i32 @foo1() int foo() __attribute__((alias("foo1"))); - - -// RUN: grep '@bar1 = internal global i32 42' %t -static int bar1 = 42; int bar() __attribute__((alias("bar1"))); - extern int test6(); void test7() { test6(); } // test6 is emitted as extern. // test6 changes to alias. int test6() __attribute__((alias("test7"))); +static int inner(int a) { return 0; } +static int inner_weak(int a) { return 0; } +extern __typeof(inner) inner_a __attribute__((alias("inner"))); +static __typeof(inner_weak) inner_weak_a __attribute__((weakref, alias("inner_weak"))); +// CHECKCC: @inner_a = alias i32 (i32)* @inner +// CHECKCC: define internal arm_aapcs_vfpcc i32 @inner(i32 %a) nounwind { + +int outer(int a) { return inner(a); } +// CHECKCC: define arm_aapcs_vfpcc i32 @outer(i32 %a) nounwind { +// CHECKCC: call arm_aapcs_vfpcc i32 @inner(i32 %{{.*}}) + +int outer_weak(int a) { return inner_weak_a(a); } +// CHECKCC: define arm_aapcs_vfpcc i32 @outer_weak(i32 %a) nounwind { +// CHECKCC: call arm_aapcs_vfpcc i32 @inner_weak(i32 %{{.*}}) +// CHECKCC: define internal arm_aapcs_vfpcc i32 @inner_weak(i32 %a) nounwind { diff --git a/test/CodeGen/arm-aapcs-vfp.c b/test/CodeGen/arm-aapcs-vfp.c index 614b52dad576..7210229f377b 100644 --- a/test/CodeGen/arm-aapcs-vfp.c +++ b/test/CodeGen/arm-aapcs-vfp.c @@ -6,6 +6,12 @@ // RUN: -ffreestanding \ // RUN: -emit-llvm -w -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple armv7-unknown-nacl-gnueabi \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -mfloat-abi hard \ +// RUN: -ffreestanding \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + #include <arm_neon.h> struct homogeneous_struct { diff --git a/test/CodeGen/arm-aapcs-zerolength-bitfield.c b/test/CodeGen/arm-aapcs-zerolength-bitfield.c index 140ff6c42436..2855045c1e78 100644 --- a/test/CodeGen/arm-aapcs-zerolength-bitfield.c +++ b/test/CodeGen/arm-aapcs-zerolength-bitfield.c @@ -1,5 +1,6 @@ // REQUIRES: arm-registered-target // RUN: %clang_cc1 -target-abi aapcs -triple armv7-apple-darwin10 %s -verify +// expected-no-diagnostics #include <stddef.h> diff --git a/test/CodeGen/arm-abi-vector.c b/test/CodeGen/arm-abi-vector.c new file mode 100644 index 000000000000..12e38ba43419 --- /dev/null +++ b/test/CodeGen/arm-abi-vector.c @@ -0,0 +1,263 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi aapcs -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi apcs-gnu -emit-llvm -o - %s | FileCheck -check-prefix=APCS-GNU %s + +#include <stdarg.h> + +typedef __attribute__(( ext_vector_type(2) )) int __int2; +typedef __attribute__(( ext_vector_type(3) )) char __char3; +typedef __attribute__(( ext_vector_type(5) )) char __char5; +typedef __attribute__(( ext_vector_type(9) )) char __char9; +typedef __attribute__(( ext_vector_type(19) )) char __char19; +typedef __attribute__(( ext_vector_type(3) )) short __short3; +typedef __attribute__(( ext_vector_type(5) )) short __short5; + +// Passing legal vector types as varargs. +double varargs_vec_2i(int fixed, ...) { +// CHECK: varargs_vec_2i +// CHECK: alloca <2 x i32>, align 8 +// CHECK: [[ALIGN:%.*]] = and i32 [[VAR:%.*]], -8 +// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8* +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 8 +// CHECK: bitcast i8* [[AP_ALIGN]] to <2 x i32>* +// APCS-GNU: varargs_vec_2i +// APCS-GNU: alloca <2 x i32>, align 8 +// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <2 x i32> +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 8 +// APCS-GNU: bitcast <2 x i32>* [[VAR_ALIGN]] to i8* +// APCS-GNU: call void @llvm.memcpy +// APCS-GNU: load <2 x i32>* [[VAR_ALIGN]] + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __int2 c3 = va_arg(ap, __int2); + sum = sum + c3.x + c3.y; + va_end(ap); + return sum; +} + +double test_2i(__int2 *in) { +// CHECK: test_2i +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> {{%.*}}) +// APCS-GNU: test_2i +// APCS-GNU: call double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> {{%.*}}) + return varargs_vec_2i(3, *in); +} + +double varargs_vec_3c(int fixed, ...) { +// CHECK: varargs_vec_3c +// CHECK: alloca <3 x i8>, align 4 +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4 +// CHECK: bitcast i8* [[AP]] to <3 x i8>* +// APCS-GNU: varargs_vec_3c +// APCS-GNU: alloca <3 x i8>, align 4 +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4 +// APCS-GNU: bitcast i8* [[AP]] to <3 x i8>* + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __char3 c3 = va_arg(ap, __char3); + sum = sum + c3.x + c3.y; + va_end(ap); + return sum; +} + +double test_3c(__char3 *in) { +// CHECK: test_3c +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}}) +// APCS-GNU: test_3c +// APCS-GNU: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}}) + return varargs_vec_3c(3, *in); +} + +double varargs_vec_5c(int fixed, ...) { +// CHECK: varargs_vec_5c +// CHECK: alloca <5 x i8>, align 8 +// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8 +// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8* +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 8 +// CHECK: bitcast i8* [[AP_ALIGN]] to <5 x i8>* +// APCS-GNU: varargs_vec_5c +// APCS-GNU: alloca <5 x i8>, align 8 +// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <5 x i8> +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 8 +// APCS-GNU: bitcast <5 x i8>* [[VAR_ALIGN]] to i8* +// APCS-GNU: call void @llvm.memcpy +// APCS-GNU: load <5 x i8>* [[VAR_ALIGN]] + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __char5 c5 = va_arg(ap, __char5); + sum = sum + c5.x + c5.y; + va_end(ap); + return sum; +} + +double test_5c(__char5 *in) { +// CHECK: test_5c +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) +// APCS-GNU: test_5c +// APCS-GNU: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}}) + return varargs_vec_5c(5, *in); +} + +double varargs_vec_9c(int fixed, ...) { +// CHECK: varargs_vec_9c +// CHECK: alloca <9 x i8>, align 16 +// CHECK: [[VAR_ALIGN:%.*]] = alloca <9 x i8> +// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8 +// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8* +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16 +// CHECK: bitcast <9 x i8>* [[VAR_ALIGN]] to i8* +// CHECK: call void @llvm.memcpy +// CHECK: load <9 x i8>* [[VAR_ALIGN]] +// APCS-GNU: varargs_vec_9c +// APCS-GNU: alloca <9 x i8>, align 16 +// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <9 x i8> +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 16 +// APCS-GNU: bitcast <9 x i8>* [[VAR_ALIGN]] to i8* +// APCS-GNU: call void @llvm.memcpy +// APCS-GNU: load <9 x i8>* [[VAR_ALIGN]] + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __char9 c9 = va_arg(ap, __char9); + sum = sum + c9.x + c9.y; + va_end(ap); + return sum; +} + +double test_9c(__char9 *in) { +// CHECK: test_9c +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) +// APCS-GNU: test_9c +// APCS-GNU: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}}) + return varargs_vec_9c(9, *in); +} + +double varargs_vec_19c(int fixed, ...) { +// CHECK: varargs_vec_19c +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4 +// CHECK: [[VAR:%.*]] = bitcast i8* [[AP]] to i8** +// CHECK: [[VAR2:%.*]] = load i8** [[VAR]] +// CHECK: bitcast i8* [[VAR2]] to <19 x i8>* +// APCS-GNU: varargs_vec_19c +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4 +// APCS-GNU: [[VAR:%.*]] = bitcast i8* [[AP]] to i8** +// APCS-GNU: [[VAR2:%.*]] = load i8** [[VAR]] +// APCS-GNU: bitcast i8* [[VAR2]] to <19 x i8>* + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __char19 c19 = va_arg(ap, __char19); + sum = sum + c19.x + c19.y; + va_end(ap); + return sum; +} + +double test_19c(__char19 *in) { +// CHECK: test_19c +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) +// APCS-GNU: test_19c +// APCS-GNU: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}}) + return varargs_vec_19c(19, *in); +} + +double varargs_vec_3s(int fixed, ...) { +// CHECK: varargs_vec_3s +// CHECK: alloca <3 x i16>, align 8 +// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8 +// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8* +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 8 +// CHECK: bitcast i8* [[AP_ALIGN]] to <3 x i16>* +// APCS-GNU: varargs_vec_3s +// APCS-GNU: alloca <3 x i16>, align 8 +// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <3 x i16> +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 8 +// APCS-GNU: bitcast <3 x i16>* [[VAR_ALIGN]] to i8* +// APCS-GNU: call void @llvm.memcpy +// APCS-GNU: load <3 x i16>* [[VAR_ALIGN]] + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __short3 c3 = va_arg(ap, __short3); + sum = sum + c3.x + c3.y; + va_end(ap); + return sum; +} + +double test_3s(__short3 *in) { +// CHECK: test_3s +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) +// APCS-GNU: test_3s +// APCS-GNU: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}}) + return varargs_vec_3s(3, *in); +} + +double varargs_vec_5s(int fixed, ...) { +// CHECK: varargs_vec_5s +// CHECK: alloca <5 x i16>, align 16 +// CHECK: [[VAR_ALIGN:%.*]] = alloca <5 x i16> +// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8 +// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8* +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16 +// CHECK: bitcast <5 x i16>* [[VAR_ALIGN]] to i8* +// CHECK: call void @llvm.memcpy +// CHECK: load <5 x i16>* [[VAR_ALIGN]] +// APCS-GNU: varargs_vec_5s +// APCS-GNU: alloca <5 x i16>, align 16 +// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <5 x i16> +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 16 +// APCS-GNU: bitcast <5 x i16>* [[VAR_ALIGN]] to i8* +// APCS-GNU: call void @llvm.memcpy +// APCS-GNU: load <5 x i16>* [[VAR_ALIGN]] + va_list ap; + double sum = fixed; + va_start(ap, fixed); + __short5 c5 = va_arg(ap, __short5); + sum = sum + c5.x + c5.y; + va_end(ap); + return sum; +} + +double test_5s(__short5 *in) { +// CHECK: test_5s +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) +// APCS-GNU: test_5s +// APCS-GNU: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}}) + return varargs_vec_5s(5, *in); +} + +// Pass struct as varargs. +typedef struct +{ + __int2 i2; + float f; +} StructWithVec; + +double varargs_struct(int fixed, ...) { +// CHECK: varargs_struct +// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8 +// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8* +// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16 +// CHECK: bitcast i8* [[AP_ALIGN]] to %struct.StructWithVec* +// APCS-GNU: varargs_struct +// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca %struct.StructWithVec +// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 16 +// APCS-GNU: bitcast %struct.StructWithVec* [[VAR_ALIGN]] to i8* +// APCS-GNU: call void @llvm.memcpy + va_list ap; + double sum = fixed; + va_start(ap, fixed); + StructWithVec c3 = va_arg(ap, StructWithVec); + sum = sum + c3.i2.x + c3.i2.y + c3.f; + va_end(ap); + return sum; +} + +double test_struct(StructWithVec* d) { +// CHECK: test_struct +// CHECK: call arm_aapcscc double (i32, ...)* @varargs_struct(i32 3, [2 x i64] {{%.*}}) +// APCS-GNU: test_struct +// APCS-GNU: call double (i32, ...)* @varargs_struct(i32 3, [2 x i64] {{%.*}}) + return varargs_struct(3, *d); +} diff --git a/test/CodeGen/arm-apcs-zerolength-bitfield.c b/test/CodeGen/arm-apcs-zerolength-bitfield.c index 049ffae4dc6f..763db65063fc 100644 --- a/test/CodeGen/arm-apcs-zerolength-bitfield.c +++ b/test/CodeGen/arm-apcs-zerolength-bitfield.c @@ -1,5 +1,6 @@ // REQUIRES: arm-registered-target // RUN: %clang_cc1 -target-abi apcs-gnu -triple armv7-apple-darwin10 %s -verify +// expected-no-diagnostics // // Note: gcc forces the alignment to 4 bytes, regardless of the type of the // zero length bitfield. diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c index 2ec729eb9b3d..63ecd4c5990b 100644 --- a/test/CodeGen/arm-arguments.c +++ b/test/CodeGen/arm-arguments.c @@ -178,3 +178,48 @@ struct s33 { char buf[32*32]; }; void f33(struct s33 s) { } // APCS-GNU: define void @f33(%struct.s33* byval %s) // AAPCS: define arm_aapcscc void @f33(%struct.s33* byval %s) + +// PR14048 +struct s34 { char c; }; +void f34(struct s34 s); +void g34(struct s34 *s) { f34(*s); } +// APCS-GNU: @g34(%struct.s34* %s) +// APCS-GNU: %[[a:.*]] = alloca { [1 x i32] } +// APCS-GNU: %[[gep:.*]] = getelementptr { [1 x i32] }* %[[a]], i32 0, i32 0 +// APCS-GNU: load [1 x i32]* %[[gep]] +// AAPCS: @g34(%struct.s34* %s) +// AAPCS: %[[a:.*]] = alloca { [1 x i32] } +// AAPCS: %[[gep:.*]] = getelementptr { [1 x i32] }* %[[a]], i32 0, i32 0 +// AAPCS: load [1 x i32]* %[[gep]] + +// rdar://12596507 +struct s35 +{ + float v[18]; //make sure byval is on. +} __attribute__((aligned(16))); +typedef struct s35 s35_with_align; + +typedef __attribute__((neon_vector_type(4))) float float32x4_t; +static __attribute__((__always_inline__, __nodebug__)) float32x4_t vaddq_f32( + float32x4_t __a, float32x4_t __b) { + return __a + __b; +} +float32x4_t f35(int i, s35_with_align s1, s35_with_align s2) { + float32x4_t v = vaddq_f32(*(float32x4_t *)&s1, + *(float32x4_t *)&s2); + return v; +} +// APCS-GNU: define <4 x float> @f35(i32 %i, %struct.s35* byval, %struct.s35* byval) +// APCS-GNU: %[[a:.*]] = alloca %struct.s35, align 16 +// APCS-GNU: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8* +// APCS-GNU: %[[c:.*]] = bitcast %struct.s35* %0 to i8* +// APCS-GNU: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[b]], i8* %[[c]] +// APCS-GNU: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>* +// APCS-GNU: load <4 x float>* %[[d]], align 16 +// AAPCS: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval, %struct.s35* byval) +// AAPCS: %[[a:.*]] = alloca %struct.s35, align 16 +// AAPCS: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8* +// AAPCS: %[[c:.*]] = bitcast %struct.s35* %0 to i8* +// AAPCS: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[b]], i8* %[[c]] +// AAPCS: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>* +// AAPCS: load <4 x float>* %[[d]], align 16 diff --git a/test/CodeGen/arm-asm-warn.c b/test/CodeGen/arm-asm-warn.c new file mode 100644 index 000000000000..0c4e97aba0d1 --- /dev/null +++ b/test/CodeGen/arm-asm-warn.c @@ -0,0 +1,18 @@ +// REQUIRES: arm-registered-target +// RUN: %clang_cc1 -triple armv7 %s -emit-llvm -o /dev/null +// <rdar://problem/12284092> + +typedef __attribute__((neon_vector_type(2))) long long int64x2_t; +typedef struct int64x2x4_t { + int64x2_t val[4]; +} int64x2x4_t; +int64x2x4_t t2(const long long a[]) { + int64x2x4_t r; + __asm__("vldm %[a], { %q[r0], %q[r1], %q[r2], %q[r3] }" + : [r0] "=r"(r.val[0]), // expected-warning {{the size being stored is truncated, use a modifier to specify the size}} + [r1] "=r"(r.val[1]), // expected-warning {{the size being stored is truncated, use a modifier to specify the size}} + [r2] "=r"(r.val[2]), // expected-warning {{the size being stored is truncated, use a modifier to specify the size}} + [r3] "=r"(r.val[3]) // expected-warning {{the size being stored is truncated, use a modifier to specify the size}} + : [a] "r"(a)); + return r; +} diff --git a/test/CodeGen/arm-homogenous.c b/test/CodeGen/arm-homogenous.c index b8d046af9722..5d21088eba8e 100644 --- a/test/CodeGen/arm-homogenous.c +++ b/test/CodeGen/arm-homogenous.c @@ -156,6 +156,47 @@ void test_return_union_with_struct_with_fundamental_elems(void) { } // CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems() +// Make sure HAs that can be partially fit into VFP registers will be allocated +// on stack and that later VFP candidates will go on stack as well. +typedef struct { + double x; + double a2; + double a3; + double a4; +} struct_of_four_doubles; +extern void takes_struct_of_four_doubles(double a, struct_of_four_doubles b, struct_of_four_doubles c, double d); +struct_of_four_doubles g_s4d; + +void test_struct_of_four_doubles(void) { +// CHECK: test_struct_of_four_doubles +// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [6 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}) + takes_struct_of_four_doubles(3.0, g_s4d, g_s4d, 4.0); +} + +extern void takes_struct_with_backfill(float f1, double a, float f2, struct_of_four_doubles b, struct_of_four_doubles c, double d); +void test_struct_with_backfill(void) { +// CHECK: test_struct_with_backfill +// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [4 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}) + takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d, g_s4d, 4.0); +} + +typedef __attribute__(( ext_vector_type(8) )) char __char8; +typedef __attribute__(( ext_vector_type(4) )) short __short4; +typedef struct { + __char8 a1; + __short4 a2; + __char8 a3; + __short4 a4; +} struct_of_vecs; +extern void takes_struct_of_vecs(double a, struct_of_vecs b, struct_of_vecs c, double d); +struct_of_vecs g_vec; + +void test_struct_of_vecs(void) { +// CHECK: test_struct_of_vecs +// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [6 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}}) + takes_struct_of_vecs(3.0, g_vec, g_vec, 4.0); +} + // FIXME: Tests necessary: // - Vectors // - C++ stuff diff --git a/test/CodeGen/arm-pnaclcall.c b/test/CodeGen/arm-pnaclcall.c new file mode 100644 index 000000000000..50259957eb15 --- /dev/null +++ b/test/CodeGen/arm-pnaclcall.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple armv7-unknown-nacl-gnueabi \ +// RUN: -ffreestanding -mfloat-abi hard -target-cpu cortex-a8 \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + +// Test that functions with pnaclcall attribute generate portable bitcode +// like the le32 arch target + +typedef struct { + int a; + int b; +} s1; +// CHECK: define i32 @f48(%struct.s1* byval %s) +int __attribute__((pnaclcall)) f48(s1 s) { return s.a; } + +// CHECK: define void @f49(%struct.s1* noalias sret %agg.result) +s1 __attribute__((pnaclcall)) f49() { s1 s; s.a = s.b = 1; return s; } + +union simple_union { + int a; + char b; +}; +// Unions should be passed as byval structs +// CHECK: define void @f50(%union.simple_union* byval %s) +void __attribute__((pnaclcall)) f50(union simple_union s) {} + +typedef struct { + int b4 : 4; + int b3 : 3; + int b8 : 8; +} bitfield1; +// Bitfields should be passed as byval structs +// CHECK: define void @f51(%struct.bitfield1* byval %bf1) +void __attribute__((pnaclcall)) f51(bitfield1 bf1) {} diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c index b0097368ec28..670c24405d33 100644 --- a/test/CodeGen/asm.c +++ b/test/CodeGen/asm.c @@ -230,3 +230,12 @@ void t27(void) { // CHECK-NOT: ia_nsdialect // CHECK: ret void } + +// Check handling of '*' and '#' constraint modifiers. +void t28(void) +{ + asm volatile ("/* %0 */" : : "i#*X,*r" (1)); +// CHECK: @t28 +// CHECK: call void asm sideeffect "/* $0 */", "i|r,~{dirflag},~{fpsr},~{flags}"(i32 1) +} + diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index 1a9ed36ee23e..d79f40522344 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -311,4 +311,13 @@ void atomic_init_foo() // CHECK: } } +// CHECK: @invalid_atomic +void invalid_atomic(_Atomic(int) *i) { + __c11_atomic_store(i, 1, memory_order_consume); + __c11_atomic_store(i, 1, memory_order_acquire); + __c11_atomic_store(i, 1, memory_order_acq_rel); + __c11_atomic_load(i, memory_order_release); + __c11_atomic_load(i, memory_order_acq_rel); +} + #endif diff --git a/test/CodeGen/attr-minsize.cpp b/test/CodeGen/attr-minsize.cpp new file mode 100644 index 000000000000..a422a62f2535 --- /dev/null +++ b/test/CodeGen/attr-minsize.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -Oz -emit-llvm %s -o - | FileCheck %s -check-prefix=Oz +// RUN: %clang_cc1 -O0 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -O1 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -O3 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -Os -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// Check that we set the minsize attribute on each function +// when Oz optimization level is set. + +int test1() { + return 42; +// Oz: @{{.*}}test1{{.*}}minsize +// Oz: ret +// OTHER: @{{.*}}test1 +// OTHER-NOT: minsize +// OTHER: ret +} + +int test2() { + return 42; +// Oz: @{{.*}}test2{{.*}}minsize +// Oz: ret +// OTHER: @{{.*}}test2 +// OTHER-NOT: minsize +// OTHER: ret +} + +__attribute__((minsize)) +int test3() { + return 42; +// Oz: @{{.*}}test3{{.*}}minsize +// OTHER: @{{.*}}test3{{.*}}minsize +} + +// Check that the minsize attribute is well propagated through +// template instantiation + +template<typename T> +__attribute__((minsize)) +void test4(T arg) { + return; +} + +template +void test4<int>(int arg); +// Oz: define{{.*}}void @{{.*}}test4 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test4 +// OTHER: minsize + +template +void test4<float>(float arg); +// Oz: define{{.*}}void @{{.*}}test4 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test4 +// OTHER: minsize + +template<typename T> +void test5(T arg) { + return; +} + +template +void test5<int>(int arg); +// Oz: define{{.*}}void @{{.*}}test5 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test5 +// OTHER-NOT: minsize + +template +void test5<float>(float arg); +// Oz: define{{.*}}void @{{.*}}test5 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test5 +// OTHER-NOT: minsize diff --git a/test/CodeGen/attr-weakref.c b/test/CodeGen/attr-weakref.c index c1cc03b668d9..560d39141ca9 100644 --- a/test/CodeGen/attr-weakref.c +++ b/test/CodeGen/attr-weakref.c @@ -53,6 +53,12 @@ void test6_foo(void) { test6_f(); } +// CHECK: declare extern_weak void @test8_f() +static void test8_g(void) __attribute__((weakref("test8_f"))); +void test8_h(void) { + if (test8_g) + test8_g(); +} // CHECK: declare extern_weak void @test7_f() void test7_f(void); static void test7_g(void) __attribute__((weakref("test7_f"))); diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c index e971a793473a..00688dc72b5b 100644 --- a/test/CodeGen/attributes.c +++ b/test/CodeGen/attributes.c @@ -80,7 +80,7 @@ void t21(void) { fptr(10); } // CHECK: [[FPTRVAR:%[a-z0-9]+]] = load void (i32)** @fptr -// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 10) +// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 inreg 10) // PR9356: We might want to err on this, but for now at least make sure we diff --git a/test/CodeGen/bitfield-promote.c b/test/CodeGen/bitfield-promote.c index 4c3292c48feb..93aaa9d8b7a0 100644 --- a/test/CodeGen/bitfield-promote.c +++ b/test/CodeGen/bitfield-promote.c @@ -1,18 +1,22 @@ -// RUN: %clang -O3 -emit-llvm -S -o %t %s -// RUN: grep 'ret i64 4294967292' %t | count 2 -// RUN: grep 'ret i64 -4' %t | count 1 +// RUN: %clang -O3 -emit-llvm -S -o - %s | FileCheck %s long long f0(void) { struct { unsigned f0 : 32; } x = { 18 }; return (long long) (x.f0 - (int) 22); } +// CHECK: @f0() +// CHECK: ret i64 4294967292 long long f1(void) { struct { unsigned f0 : 31; } x = { 18 }; return (long long) (x.f0 - (int) 22); } +// CHECK: @f1() +// CHECK: ret i64 -4 long long f2(void) { struct { unsigned f0 ; } x = { 18 }; return (long long) (x.f0 - (int) 22); } +// CHECK: @f2() +// CHECK: ret i64 4294967292 diff --git a/test/CodeGen/bmi2-builtins.c b/test/CodeGen/bmi2-builtins.c index 18b2319f9f97..201cac63b9fe 100644 --- a/test/CodeGen/bmi2-builtins.c +++ b/test/CodeGen/bmi2-builtins.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -O3 -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32 // Don't include mm_malloc.h, it's system specific. #define __MM_MALLOC_H @@ -20,6 +21,15 @@ unsigned int test_pext_u32(unsigned int __X, unsigned int __Y) { return _pext_u32(__X, __Y); } +unsigned int test_mulx_u32(unsigned int __X, unsigned int __Y, + unsigned int *__P) { + // CHECK: @test_mulx_u32 + // CHECK-NOT: mul i64 + // B32: @test_mulx_u32 + // B32: mul i64 + return _mulx_u32(__X, __Y, __P); +} + 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); @@ -34,3 +44,10 @@ 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); } + +unsigned long long test_mulx_u64(unsigned long long __X, unsigned long long __Y, + unsigned long long *__P) { + // CHECK: @test_mulx_u64 + // CHECK: mul i128 + return _mulx_u64(__X, __Y, __P); +} diff --git a/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c index 72d340619f37..4a06160ccbc6 100644 --- a/test/CodeGen/builtin-memfns.c +++ b/test/CodeGen/builtin-memfns.c @@ -63,3 +63,23 @@ int test7(int *p) { __builtin_memset(hwparams, 0, 256); // No crash alignment = 1 // CHECK: call void @llvm.memset{{.*}}256, i32 1, i1 false) } + +// <rdar://problem/11314941> +// Make sure we don't over-estimate the alignment of fields of +// packed structs. +struct PS { + int modes[4]; +} __attribute__((packed)); +struct PS ps; +void test8(int *arg) { + // CHECK: @test8 + // CHECK: call void @llvm.memcpy{{.*}} 16, i32 1, i1 false) + __builtin_memcpy(arg, ps.modes, sizeof(struct PS)); +} + +__attribute((aligned(16))) int x[4], y[4]; +void test9() { + // CHECK: @test9 + // CHECK: call void @llvm.memcpy{{.*}} 16, i32 16, i1 false) + __builtin_memcpy(x, y, sizeof(y)); +} diff --git a/test/CodeGen/builtin-ms-noop.cpp b/test/CodeGen/builtin-ms-noop.cpp new file mode 100644 index 000000000000..42c25016b138 --- /dev/null +++ b/test/CodeGen/builtin-ms-noop.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck %s + +class A { + public: + ~A() {} +}; + +void f() { +// CHECK: @_Z1fv +// CHECK-NOT: call void @_ZN1AD1Ev +// CHECK: ret void + __noop(A()); +}; + diff --git a/test/CodeGen/builtins-mips-args.c b/test/CodeGen/builtins-mips-args.c index a961b36a9533..fd3e31443ecf 100644 --- a/test/CodeGen/builtins-mips-args.c +++ b/test/CodeGen/builtins-mips-args.c @@ -11,4 +11,27 @@ void foo() { __builtin_mips_rddsp(-1); // expected-error{{argument should be a value from 0 to 63}} __builtin_mips_wrdsp(2052, 64); // expected-error{{argument should be a value from 0 to 63}} __builtin_mips_rddsp(64); // expected-error{{argument should be a value from 0 to 63}} + + // MIPS DSP Rev 2 + + __builtin_mips_append(1, 2, a); // expected-error{{argument to '__builtin_mips_append' must be a constant integer}} + __builtin_mips_balign(1, 2, a); // expected-error{{argument to '__builtin_mips_balign' must be a constant integer}} + __builtin_mips_precr_sra_ph_w(1, 2, a); // expected-error{{argument to '__builtin_mips_precr_sra_ph_w' must be a constant integer}} + __builtin_mips_precr_sra_r_ph_w(1, 2, a); // expected-error{{argument to '__builtin_mips_precr_sra_r_ph_w' must be a constant integer}} + __builtin_mips_prepend(1, 2, a); // expected-error{{argument to '__builtin_mips_prepend' must be a constant integer}} + + __builtin_mips_append(1, 2, -1); // expected-error{{argument should be a value from 0 to 31}} + __builtin_mips_append(1, 2, 32); // expected-error{{argument should be a value from 0 to 31}} + + __builtin_mips_balign(1, 2, -1); // expected-error{{argument should be a value from 0 to 3}} + __builtin_mips_balign(1, 2, 4); // expected-error{{argument should be a value from 0 to 3}} + + __builtin_mips_precr_sra_ph_w(1, 2, -1); // expected-error{{argument should be a value from 0 to 31}} + __builtin_mips_precr_sra_ph_w(1, 2, 32); // expected-error{{argument should be a value from 0 to 31}} + + __builtin_mips_precr_sra_r_ph_w(1, 2, -1); // expected-error{{argument should be a value from 0 to 31}} + __builtin_mips_precr_sra_r_ph_w(1, 2, 32); // expected-error{{argument should be a value from 0 to 31}} + + __builtin_mips_prepend(1, 2, -1); // expected-error{{argument should be a value from 0 to 31}} + __builtin_mips_prepend(1, 2, -1); // expected-error{{argument should be a value from 0 to 31}} } diff --git a/test/CodeGen/builtins-mips.c b/test/CodeGen/builtins-mips.c index 8155a43c20f0..ef4662cd5946 100644 --- a/test/CodeGen/builtins-mips.c +++ b/test/CodeGen/builtins-mips.c @@ -8,10 +8,14 @@ typedef unsigned int ui32; typedef long long a64; typedef signed char v4i8 __attribute__ ((vector_size(4))); +typedef signed char v4q7 __attribute__ ((vector_size(4))); +typedef short v2i16 __attribute__ ((vector_size(4))); typedef short v2q15 __attribute__ ((vector_size(4))); void foo() { v2q15 v2q15_r, v2q15_a, v2q15_b, v2q15_c; + v2i16 v2i16_r, v2i16_a, v2i16_b, v2i16_c; + v4q7 v4q7_r, v4q7_a, v4q7_b; v4i8 v4i8_r, v4i8_a, v4i8_b, v4i8_c; q31 q31_r, q31_a, q31_b, q31_c; i32 i32_r, i32_a, i32_b, i32_c; @@ -321,4 +325,210 @@ void foo() { int array_c[100]; i32_r = __builtin_mips_lwx(array_c, 20); // CHECK: call i32 @llvm.mips.lwx + + // MIPS DSP Rev 2 + + v4q7_a = (v4q7) {0x81, 0xff, 0x80, 0x23}; + v4q7_r = __builtin_mips_absq_s_qb (v4q7_a); +// CHECK: call <4 x i8> @llvm.mips.absq.s.qb + + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_r = __builtin_mips_addqh_ph(v2q15_a, v2q15_b); +// CHECK: call <2 x i16> @llvm.mips.addqh.ph + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_r = __builtin_mips_addqh_r_ph(v2q15_a, v2q15_b); +// CHECK: call <2 x i16> @llvm.mips.addqh.r.ph + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_r = __builtin_mips_addqh_w(q31_a, q31_b); +// CHECK: call i32 @llvm.mips.addqh.w + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_r = __builtin_mips_addqh_r_w(q31_a, q31_b); +// CHECK: call i32 @llvm.mips.addqh.r.w + + v2i16_a = (v2i16) {0xffff, 0x2468}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_r = __builtin_mips_addu_ph(v2i16_a, v2i16_b); +// CHECK: call <2 x i16> @llvm.mips.addu.ph + v2i16_a = (v2i16) {0xffff, 0x2468}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_r = __builtin_mips_addu_s_ph(v2i16_a, v2i16_b); +// CHECK: call <2 x i16> @llvm.mips.addu.s.ph + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0xff}; + v4i8_b = (v4i8) {0x11, 0x33, 0x99, 0xff}; + v4i8_r = __builtin_mips_adduh_qb(v4i8_a, v4i8_b); +// CHECK: call <4 x i8> @llvm.mips.adduh.qb + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0xff}; + v4i8_b = (v4i8) {0x11, 0x33, 0x99, 0xff}; + v4i8_r = __builtin_mips_adduh_r_qb(v4i8_a, v4i8_b); +// CHECK: call <4 x i8> @llvm.mips.adduh.r.qb + + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_r = __builtin_mips_append(i32_a, i32_b, 16); +// CHECK: call i32 @llvm.mips.append + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_r = __builtin_mips_balign(i32_a, i32_b, 3); +// CHECK: call i32 @llvm.mips.balign + + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0x44}; + v4i8_b = (v4i8) {0x11, 0x33, 0x33, 0x44}; + i32_r = __builtin_mips_cmpgdu_eq_qb(v4i8_a, v4i8_b); +// CHECK: call i32 @llvm.mips.cmpgdu.eq.qb + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0x44}; + v4i8_b = (v4i8) {0x11, 0x33, 0x33, 0x44}; + i32_r = __builtin_mips_cmpgdu_lt_qb(v4i8_a, v4i8_b); +// CHECK: call i32 @llvm.mips.cmpgdu.lt.qb + v4i8_a = (v4i8) {0x11, 0x22, 0x33, 0x54}; + v4i8_b = (v4i8) {0x11, 0x33, 0x33, 0x44}; + i32_r = __builtin_mips_cmpgdu_le_qb(v4i8_a, v4i8_b); +// CHECK: call i32 @llvm.mips.cmpgdu.le.qb + + a64_a = 0x12345678; + v2i16_b = (v2i16) {0xffff, 0x1555}; + v2i16_c = (v2i16) {0x1234, 0x3322}; + a64_r = __builtin_mips_dpa_w_ph(a64_a, v2i16_b, v2i16_c); +// CHECK: call i64 @llvm.mips.dpa.w.ph + a64_a = 0x12345678; + v2i16_b = (v2i16) {0xffff, 0x1555}; + v2i16_c = (v2i16) {0x1234, 0x3322}; + a64_r = __builtin_mips_dps_w_ph(a64_a, v2i16_b, v2i16_c); +// CHECK: call i64 @llvm.mips.dps.w.ph + + a64_a = 0x70000000; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_r = __builtin_mips_dpaqx_s_w_ph(a64_a, v2q15_b, v2q15_c); +// CHECK: call i64 @llvm.mips.dpaqx.s.w.ph + a64_a = 0x70000000; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_r = __builtin_mips_dpaqx_sa_w_ph(a64_a, v2q15_b, v2q15_c); +// CHECK: call i64 @llvm.mips.dpaqx.sa.w.ph + a64_a = 0x1111222212345678LL; + v2i16_b = (v2i16) {0x1, 0x2}; + v2i16_c = (v2i16) {0x3, 0x4}; + a64_r = __builtin_mips_dpax_w_ph(a64_a, v2i16_b, v2i16_c); +// CHECK: call i64 @llvm.mips.dpax.w.ph + a64_a = 0x9999111112345678LL; + v2i16_b = (v2i16) {0x1, 0x2}; + v2i16_c = (v2i16) {0x3, 0x4}; + a64_r = __builtin_mips_dpsx_w_ph(a64_a, v2i16_b, v2i16_c); +// CHECK: call i64 @llvm.mips.dpsx.w.ph + a64_a = 0x70000000; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_r = __builtin_mips_dpsqx_s_w_ph(a64_a, v2q15_b, v2q15_c); +// CHECK: call i64 @llvm.mips.dpsqx.s.w.ph + a64_a = 0xFFFFFFFF80000000LL; + v2q15_b = (v2q15) {0x4000, 0x2000}; + v2q15_c = (v2q15) {0x2000, 0x4000}; + a64_r = __builtin_mips_dpsqx_sa_w_ph(a64_a, v2q15_b, v2q15_c); +// CHECK: call i64 @llvm.mips.dpsqx.sa.w.ph + + v2i16_a = (v2i16) {0xffff, 0x2468}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_r = __builtin_mips_mul_ph(v2i16_a, v2i16_b); +// CHECK: call <2 x i16> @llvm.mips.mul.ph + v2i16_a = (v2i16) {0x8000, 0x7fff}; + v2i16_b = (v2i16) {0x1234, 0x1111}; + v2i16_r = __builtin_mips_mul_s_ph(v2i16_a, v2i16_b); +// CHECK: call <2 x i16> @llvm.mips.mul.s.ph + + q31_a = 0x80000000; + q31_b = 0x80000000; + q31_r = __builtin_mips_mulq_rs_w(q31_a, q31_b); +// CHECK: call i32 @llvm.mips.mulq.rs.w + v2q15_a = (v2q15) {0xffff, 0x8000}; + v2q15_b = (v2q15) {0x1111, 0x8000}; + v2q15_r = __builtin_mips_mulq_s_ph(v2q15_a, v2q15_b); +// CHECK: call <2 x i16> @llvm.mips.mulq.s.ph + q31_a = 0x00000002; + q31_b = 0x80000000; + q31_r = __builtin_mips_mulq_s_w(q31_a, q31_b); +// CHECK: call i32 @llvm.mips.mulq.s.w + a64_a = 0x19848419; + v2i16_b = (v2i16) {0xffff, 0x8000}; + v2i16_c = (v2i16) {0x1111, 0x8000}; + a64_r = __builtin_mips_mulsa_w_ph(a64_a, v2i16_b, v2i16_c); +// CHECK: call i64 @llvm.mips.mulsa.w.ph + + v2i16_a = (v2i16) {0x1234, 0x5678}; + v2i16_b = (v2i16) {0x2233, 0x5566}; + v4i8_r = __builtin_mips_precr_qb_ph(v2i16_a, v2i16_b); +// CHECK: call <4 x i8> @llvm.mips.precr.qb.ph + i32_a = 0x12345678; + i32_b = 0x33334444; + v2i16_r = __builtin_mips_precr_sra_ph_w(i32_a, i32_b, 4); +// CHECK: call <2 x i16> @llvm.mips.precr.sra.ph.w + i32_a = 0x12345678; + i32_b = 0x33334444; + v2i16_r = __builtin_mips_precr_sra_r_ph_w(i32_a, i32_b, 4); +// CHECK: call <2 x i16> @llvm.mips.precr.sra.r.ph.w + + i32_a = 0x12345678; + i32_b = 0x87654321; + i32_r = __builtin_mips_prepend(i32_a, i32_b, 16); +// CHECK: call i32 @llvm.mips.prepend + + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + v4i8_r = __builtin_mips_shra_qb(v4i8_a, 1); +// CHECK: call <4 x i8> @llvm.mips.shra.qb + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + i32_b = 1; + v4i8_r = __builtin_mips_shra_qb(v4i8_a, i32_b); +// CHECK: call <4 x i8> @llvm.mips.shra.qb + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + v4i8_r = __builtin_mips_shra_r_qb(v4i8_a, 1); +// CHECK: call <4 x i8> @llvm.mips.shra.r.qb + v4i8_a = (v4i8) {0x12, 0x45, 0x77, 0x99}; + i32_b = 1; + v4i8_r = __builtin_mips_shra_r_qb(v4i8_a, i32_b); +// CHECK: call <4 x i8> @llvm.mips.shra.r.qb + v2i16_a = (v2i16) {0x1357, 0x2468}; + v2i16_r = __builtin_mips_shrl_ph(v2i16_a, 4); +// CHECK: call <2 x i16> @llvm.mips.shrl.ph + v2i16_a = (v2i16) {0x1357, 0x2468}; + i32_b = 8; + v2i16_r = __builtin_mips_shrl_ph (v2i16_a, i32_b); +// CHECK: call <2 x i16> @llvm.mips.shrl.ph + + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_r = __builtin_mips_subqh_ph(v2q15_a, v2q15_b); +// CHECK: call <2 x i16> @llvm.mips.subqh.ph + v2q15_a = (v2q15) {0x3334, 0x4444}; + v2q15_b = (v2q15) {0x1111, 0x2222}; + v2q15_r = __builtin_mips_subqh_r_ph(v2q15_a, v2q15_b); +// CHECK: call <2 x i16> @llvm.mips.subqh.r.ph + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_r = __builtin_mips_subqh_w(q31_a, q31_b); +// CHECK: call i32 @llvm.mips.subqh.w + q31_a = 0x11111112; + q31_b = 0x99999999; + q31_r = __builtin_mips_subqh_r_w(q31_a, q31_b); +// CHECK: call i32 @llvm.mips.subqh.r.w + + v2i16_a = (v2i16) {0x1357, 0x4455}; + v2i16_b = (v2i16) {0x3333, 0x4444}; + v2i16_r = __builtin_mips_subu_ph(v2i16_a, v2i16_b); +// CHECK: call <2 x i16> @llvm.mips.subu.ph + v2i16_a = (v2i16) {0x1357, 0x4455}; + v2i16_b = (v2i16) {0x3333, 0x4444}; + v2i16_r = __builtin_mips_subu_s_ph(v2i16_a, v2i16_b); +// CHECK: call <2 x i16> @llvm.mips.subu.s.ph + + v4i8_a = (v4i8) {0x33 ,0x44, 0x55, 0x66}; + v4i8_b = (v4i8) {0x99 ,0x15, 0x85, 0xff}; + v4i8_r = __builtin_mips_subuh_qb(v4i8_a, v4i8_b); +// CHECK: call <4 x i8> @llvm.mips.subuh.qb + v4i8_a = (v4i8) {0x33 ,0x44, 0x55, 0x66}; + v4i8_b = (v4i8) {0x99 ,0x15, 0x85, 0xff}; + v4i8_r = __builtin_mips_subuh_r_qb(v4i8_a, v4i8_b); +// CHECK: call <4 x i8> @llvm.mips.subuh.r.qb } diff --git a/test/CodeGen/builtins-nvptx.c b/test/CodeGen/builtins-nvptx.c index fa6b14c1ca7d..2c7e0c136769 100644 --- a/test/CodeGen/builtins-nvptx.c +++ b/test/CodeGen/builtins-nvptx.c @@ -1,8 +1,15 @@ -// RUN: %clang_cc1 -triple nvptx-unknown-unknown -emit-llvm -o %t %s -// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -emit-llvm -o %t %s +// REQUIRES: nvptx-registered-target +// REQUIRES: nvptx64-registered-target +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s int read_tid() { +// CHECK: call i32 @llvm.ptx.read.tid.x() +// CHECK: call i32 @llvm.ptx.read.tid.y() +// CHECK: call i32 @llvm.ptx.read.tid.z() +// CHECK: call i32 @llvm.ptx.read.tid.w() + int x = __builtin_ptx_read_tid_x(); int y = __builtin_ptx_read_tid_y(); int z = __builtin_ptx_read_tid_z(); @@ -14,6 +21,11 @@ int read_tid() { int read_ntid() { +// CHECK: call i32 @llvm.ptx.read.ntid.x() +// CHECK: call i32 @llvm.ptx.read.ntid.y() +// CHECK: call i32 @llvm.ptx.read.ntid.z() +// CHECK: call i32 @llvm.ptx.read.ntid.w() + int x = __builtin_ptx_read_ntid_x(); int y = __builtin_ptx_read_ntid_y(); int z = __builtin_ptx_read_ntid_z(); @@ -25,6 +37,11 @@ int read_ntid() { int read_ctaid() { +// CHECK: call i32 @llvm.ptx.read.ctaid.x() +// CHECK: call i32 @llvm.ptx.read.ctaid.y() +// CHECK: call i32 @llvm.ptx.read.ctaid.z() +// CHECK: call i32 @llvm.ptx.read.ctaid.w() + int x = __builtin_ptx_read_ctaid_x(); int y = __builtin_ptx_read_ctaid_y(); int z = __builtin_ptx_read_ctaid_z(); @@ -36,6 +53,11 @@ int read_ctaid() { int read_nctaid() { +// CHECK: call i32 @llvm.ptx.read.nctaid.x() +// CHECK: call i32 @llvm.ptx.read.nctaid.y() +// CHECK: call i32 @llvm.ptx.read.nctaid.z() +// CHECK: call i32 @llvm.ptx.read.nctaid.w() + int x = __builtin_ptx_read_nctaid_x(); int y = __builtin_ptx_read_nctaid_y(); int z = __builtin_ptx_read_nctaid_z(); @@ -47,6 +69,13 @@ int read_nctaid() { int read_ids() { +// CHECK: call i32 @llvm.ptx.read.laneid() +// CHECK: call i32 @llvm.ptx.read.warpid() +// CHECK: call i32 @llvm.ptx.read.nwarpid() +// CHECK: call i32 @llvm.ptx.read.smid() +// CHECK: call i32 @llvm.ptx.read.nsmid() +// CHECK: call i32 @llvm.ptx.read.gridid() + int a = __builtin_ptx_read_laneid(); int b = __builtin_ptx_read_warpid(); int c = __builtin_ptx_read_nwarpid(); @@ -60,6 +89,12 @@ int read_ids() { int read_lanemasks() { +// CHECK: call i32 @llvm.ptx.read.lanemask.eq() +// CHECK: call i32 @llvm.ptx.read.lanemask.le() +// CHECK: call i32 @llvm.ptx.read.lanemask.lt() +// CHECK: call i32 @llvm.ptx.read.lanemask.ge() +// CHECK: call i32 @llvm.ptx.read.lanemask.gt() + int a = __builtin_ptx_read_lanemask_eq(); int b = __builtin_ptx_read_lanemask_le(); int c = __builtin_ptx_read_lanemask_lt(); @@ -73,6 +108,9 @@ int read_lanemasks() { long read_clocks() { +// CHECK: call i32 @llvm.ptx.read.clock() +// CHECK: call i64 @llvm.ptx.read.clock64() + int a = __builtin_ptx_read_clock(); long b = __builtin_ptx_read_clock64(); @@ -82,6 +120,11 @@ long read_clocks() { int read_pms() { +// CHECK: call i32 @llvm.ptx.read.pm0() +// CHECK: call i32 @llvm.ptx.read.pm1() +// CHECK: call i32 @llvm.ptx.read.pm2() +// CHECK: call i32 @llvm.ptx.read.pm3() + int a = __builtin_ptx_read_pm0(); int b = __builtin_ptx_read_pm1(); int c = __builtin_ptx_read_pm2(); @@ -93,6 +136,33 @@ int read_pms() { void sync() { +// CHECK: call void @llvm.ptx.bar.sync(i32 0) + __builtin_ptx_bar_sync(0); } + + +// NVVM intrinsics + +// The idea is not to test all intrinsics, just that Clang is recognizing the +// builtins defined in BuiltinsNVPTX.def +void nvvm_math(float f1, float f2, double d1, double d2) { +// CHECK: call float @llvm.nvvm.fmax.f + float t1 = __nvvm_fmax_f(f1, f2); +// CHECK: call float @llvm.nvvm.fmin.f + float t2 = __nvvm_fmin_f(f1, f2); +// CHECK: call float @llvm.nvvm.sqrt.rn.f + float t3 = __nvvm_sqrt_rn_f(f1); +// CHECK: call float @llvm.nvvm.rcp.rn.f + float t4 = __nvvm_rcp_rn_f(f2); + +// CHECK: call double @llvm.nvvm.fmax.d + double td1 = __nvvm_fmax_d(d1, d2); +// CHECK: call double @llvm.nvvm.fmin.d + double td2 = __nvvm_fmin_d(d1, d2); +// CHECK: call double @llvm.nvvm.sqrt.rn.d + double td3 = __nvvm_sqrt_rn_d(d1); +// CHECK: call double @llvm.nvvm.rcp.rn.d + double td4 = __nvvm_rcp_rn_d(d2); +} diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c index 65b9ad111fd8..9ba12bbf2fec 100644 --- a/test/CodeGen/builtins.c +++ b/test/CodeGen/builtins.c @@ -113,6 +113,7 @@ int main() { // Whatever + P(bswap16, (N)); P(bswap32, (N)); P(bswap64, (N)); // FIXME diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c index ee0b6586dd84..4198b62ea56c 100644 --- a/test/CodeGen/catch-undef-behavior.c +++ b/test/CodeGen/catch-undef-behavior.c @@ -1,17 +1,248 @@ -// RUN: %clang_cc1 -fcatch-undefined-behavior -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,divide-by-zero -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -fsanitize=null -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW + +// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" } + +// FIXME: When we only emit each type once, use [[INT]] more below. +// CHECK: @[[LINE_100:.*]] = private unnamed_addr constant {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i64 4, i8 1 +// CHECK: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i64 4, i8 0 +// CHECK: @[[LINE_300_A:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} +// CHECK: @[[LINE_300_B:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} +// CHECK: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} +// CHECK: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i64 4, i8 0 } +// CHECK: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i64 4, i8 1 } + +// CHECK: @[[STRUCT_S:.*]] = private unnamed_addr constant { i16, i16, [11 x i8] } { i16 -1, i16 0, [11 x i8] c"'struct S'\00" } + +// CHECK: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i64 4, i8 3 } +// CHECK: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} } +// CHECK: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} } + +// CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr constant {{.*}}, i32 100, i32 5 {{.*}} // PR6805 // CHECK: @foo +// CHECK-NULL: @foo void foo() { union { int i; } u; - // CHECK: objectsize - // CHECK: icmp uge + // CHECK: %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null + + // CHECK: %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8* + // CHECK-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64(i8* %[[I8PTR]], i1 false) + // CHECK-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4 + // CHECK-NEXT: %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]] + + // CHECK: %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64 + // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3 + // CHECK-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0 + + // CHECK: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]] + // CHECK-NEXT: br i1 %[[OK]] + + // CHECK: %[[ARG:.*]] = ptrtoint {{.*}} %[[PTR]] to i64 + // CHECK-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %[[ARG]]) noreturn nounwind + + // With -fsanitize=null, only perform the null check. + // CHECK-NULL: %[[NULL:.*]] = icmp ne {{.*}}, null + // CHECK-NULL: br i1 %[[NULL]] + // CHECK-NULL: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %{{.*}}) noreturn nounwind +#line 100 u.i=1; } // CHECK: @bar int bar(int *a) { - // CHECK: objectsize - // CHECK: icmp uge + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 + // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 + + // CHECK: %[[PTRINT:.*]] = ptrtoint + // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 + // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + + // CHECK: %[[ARG:.*]] = ptrtoint + // CHECK-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]]) noreturn nounwind +#line 200 + return *a; +} + +// CHECK: @addr_space +int addr_space(int __attribute__((address_space(256))) *a) { + // CHECK-NOT: __ubsan return *a; } + +// CHECK: @lsh_overflow +int lsh_overflow(int a, int b) { + // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 + // CHECK-NEXT: br i1 %[[INBOUNDS]] + + // FIXME: Only emit one trap block here. + // CHECK: %[[ARG1:.*]] = zext + // CHECK-NEXT: %[[ARG2:.*]] = zext + // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300_A]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind + + // CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] + // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]] + // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT]], 0 + // CHECK-NEXT: br i1 %[[NO_OVERFLOW]] + + // CHECK: %[[ARG1:.*]] = zext + // CHECK-NEXT: %[[ARG2:.*]] = zext + // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300_B]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind + + // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]] + // CHECK-NEXT: ret i32 %[[RET]] +#line 300 + return a << b; +} + +// CHECK: @rsh_inbounds +int rsh_inbounds(int a, int b) { + // CHECK: %[[INBOUNDS:.*]] = icmp ult i32 %[[RHS:.*]], 32 + // CHECK: br i1 %[[INBOUNDS]] + + // CHECK: %[[ARG1:.*]] = zext + // CHECK-NEXT: %[[ARG2:.*]] = zext + // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_400]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind + + // CHECK: %[[RET:.*]] = ashr i32 %[[LHS]], %[[RHS]] + // CHECK-NEXT: ret i32 %[[RET]] +#line 400 + return a >> b; +} + +// CHECK: @load +int load(int *p) { + // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}}) noreturn nounwind +#line 500 + return *p; +} + +// CHECK: @store +void store(int *p, int q) { + // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}}) noreturn nounwind +#line 600 + *p = q; +} + +struct S { int k; }; + +// CHECK: @member_access +int *member_access(struct S *p) { + // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}}) noreturn nounwind +#line 700 + return &p->k; +} + +// CHECK: @signed_overflow +int signed_overflow(int a, int b) { + // CHECK: %[[ARG1:.*]] = zext + // CHECK-NEXT: %[[ARG2:.*]] = zext + // CHECK-NEXT: call void @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_800]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind +#line 800 + return a + b; +} + +// CHECK: @no_return +int no_return() { + // Reaching the end of a noreturn function is fine in C. + // FIXME: If the user explicitly requests -fsanitize=return, we should catch + // that here even though it's not undefined behavior. + // CHECK-NOT: call + // CHECK-NOT: unreachable + // CHECK: ret i32 +} + +// CHECK: @vla_bound +void vla_bound(int n) { + // CHECK: icmp sgt i32 %[[PARAM:.*]], 0 + // + // CHECK: %[[ARG:.*]] = zext i32 %[[PARAM]] to i64 + // CHECK-NEXT: call void @__ubsan_handle_vla_bound_not_positive(i8* bitcast ({{.*}} @[[LINE_900]] to i8*), i64 %[[ARG]]) noreturn nounwind +#line 900 + int arr[n * 3]; +} + +// CHECK: @int_float_no_overflow +float int_float_no_overflow(__int128 n) { + // CHECK-NOT: call void @__ubsan_handle + return n; +} + +// CHECK: @int_float_overflow +float int_float_overflow(unsigned __int128 n) { + // This is 2**104. FLT_MAX is 2**128 - 2**104. + // CHECK: icmp ule i128 %{{.*}}, -20282409603651670423947251286016 + // CHECK: call void @__ubsan_handle_float_cast_overflow( + return n; +} + +// CHECK: @int_fp16_overflow +void int_fp16_overflow(int n, __fp16 *p) { + // CHECK: %[[GE:.*]] = icmp sge i32 %{{.*}}, -65504 + // CHECK: %[[LE:.*]] = icmp sle i32 %{{.*}}, 65504 + // CHECK: and i1 %[[GE]], %[[LE]] + // CHECK: call void @__ubsan_handle_float_cast_overflow( + *p = n; +} + +// CHECK: @float_int_overflow +int float_int_overflow(float f) { + // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0xC1E0000000000000 + // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41DFFFFFE0000000 + // CHECK: and i1 %[[GE]], %[[LE]] + // CHECK: call void @__ubsan_handle_float_cast_overflow( + return f; +} + +// CHECK: @float_uint_overflow +unsigned float_uint_overflow(float f) { + // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0.{{0*}}e+00 + // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41EFFFFFE0000000 + // CHECK: and i1 %[[GE]], %[[LE]] + // CHECK: call void @__ubsan_handle_float_cast_overflow( + return f; +} + +// CHECK: @fp16_char_overflow +signed char fp16_char_overflow(__fp16 *p) { + // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], -1.28{{0*}}e+02 + // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 1.27{{0*}}e+02 + // CHECK: and i1 %[[GE]], %[[LE]] + // CHECK: call void @__ubsan_handle_float_cast_overflow( + return *p; +} + +// CHECK: @float_float_overflow +float float_float_overflow(double f) { + // CHECK: %[[GE:.*]] = fcmp oge double %[[F:.*]], 0xC7EFFFFFE0000000 + // CHECK: %[[LE:.*]] = fcmp ole double %[[F]], 0x47EFFFFFE0000000 + // CHECK: and i1 %[[GE]], %[[LE]] + // CHECK: call void @__ubsan_handle_float_cast_overflow( + return f; +} + +// CHECK: @int_divide_overflow +// CHECK-OVERFLOW: @int_divide_overflow +int int_divide_overflow(int a, int b) { + // CHECK: %[[ZERO:.*]] = icmp ne i32 %[[B:.*]], 0 + // CHECK-OVERFLOW-NOT: icmp ne i32 %{{.*}}, 0 + + // CHECK: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648 + // CHECK-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B]], -1 + // CHECK-NEXT: %[[OVER:.*]] = or i1 %[[AOK]], %[[BOK]] + + // CHECK-OVERFLOW: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648 + // CHECK-OVERFLOW-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B:.*]], -1 + // CHECK-OVERFLOW-NEXT: %[[OK:.*]] = or i1 %[[AOK]], %[[BOK]] + + // CHECK: %[[OK:.*]] = and i1 %[[ZERO]], %[[OVER]] + + // CHECK: br i1 %[[OK]] + // CHECK-OVERFLOW: br i1 %[[OK]] + return a / b; + + // CHECK: } + // CHECK-OVERFLOW: } +} diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c index 4f3f7ab55330..5f729b8df428 100644 --- a/test/CodeGen/const-init.c +++ b/test/CodeGen/const-init.c @@ -144,3 +144,18 @@ void g28() { static v12i16 b = (v2f80){1,2}; static v2f80 c = (v12i16){0,0,0,-32768,16383,0,0,0,0,-32768,16384,0}; } + +// PR13643 +void g29() { + typedef char DCC_PASSWD[2]; + typedef struct + { + DCC_PASSWD passwd; + } DCC_SRVR_NM; + // CHECK: @g29.a = internal global %struct.DCC_SRVR_NM { [2 x i8] c"@\00" }, align 1 + // CHECK: @g29.b = internal global [1 x i32] [i32 ptrtoint ([5 x i8]* @.str to i32)], align 4 + // CHECK: @g29.c = internal global [1 x i32] [i32 97], align 4 + static DCC_SRVR_NM a = { {"@"} }; + static int b[1] = { "asdf" }; + static int c[1] = { L"a" }; +} diff --git a/test/CodeGen/const-label-addr.c b/test/CodeGen/const-label-addr.c index 9d99f88c8a65..e606c3b2cda2 100644 --- a/test/CodeGen/const-label-addr.c +++ b/test/CodeGen/const-label-addr.c @@ -1,4 +1,17 @@ -// RUN: %clang_cc1 %s -emit-llvm -o %t +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// REQUIRES: asserts + +// CHECK: @a.a = internal global i8* blockaddress(@a, %A) int a() { A:;static void* a = &&A; } + +// PR14005 +// CHECK: @b.ar = internal global {{.*}} sub (i{{..}} ptrtoint (i8* blockaddress(@b, %l2) to i{{..}}), i{{..}} ptrtoint (i8* blockaddress(@b, %l1) to i{{..}})) +int b() { + static int ar = &&l2 - &&l1; +l1: + return 10; +l2: + return 11; +} diff --git a/test/CodeGen/debug-info-iv.c b/test/CodeGen/debug-info-iv.c index 6684fe346992..aafd71d2ec2a 100644 --- a/test/CodeGen/debug-info-iv.c +++ b/test/CodeGen/debug-info-iv.c @@ -27,7 +27,7 @@ int main() { Array[i][j] = 0; test_indvars(Array[0], Array); -//CHECK: .loc 2 31 8 +//CHECK: .loc 2 31 for (i=0; i < 100; i+=2) for (j=0; j < 200; j++) sum += Array[i][j]; diff --git a/test/CodeGen/debug-info-line3.c b/test/CodeGen/debug-info-line3.c index a4e35e753d74..d01b023b82d3 100644 --- a/test/CodeGen/debug-info-line3.c +++ b/test/CodeGen/debug-info-line3.c @@ -12,5 +12,5 @@ void func(char c, char* d) } -// CHECK: ret void, !dbg !17 -// CHECK: !17 = metadata !{i32 6, +// CHECK: ret void, !dbg [[LINE:.*]] +// CHECK: [[LINE]] = metadata !{i32 6, diff --git a/test/CodeGen/debug-info-line4.c b/test/CodeGen/debug-info-line4.c new file mode 100644 index 000000000000..004176c7a507 --- /dev/null +++ b/test/CodeGen/debug-info-line4.c @@ -0,0 +1,11 @@ +// RUN: %clang %s -g -gcolumn-info -S -emit-llvm -o - | FileCheck %s +// Checks that clang emits column information when -gcolumn-info is passed. + +int foo(int a, int b) { int c = a + b; + + + return c; +} + +// Without column information we wouldn't change locations for b. +// CHECK: metadata !{i32 4, i32 20, diff --git a/test/CodeGen/debug-info.c b/test/CodeGen/debug-info.c index af2ce969bceb..12ba6058d39e 100644 --- a/test/CodeGen/debug-info.c +++ b/test/CodeGen/debug-info.c @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unk-unk -o %t -emit-llvm -g %s -// RUN: FileCheck --input-file=%t %s +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -g %s | FileCheck %s // PR3023 void convert(void) { @@ -8,7 +7,7 @@ void convert(void) { // PR2784 -struct OPAQUE; +struct OPAQUE; // CHECK: DW_TAG_structure_type typedef struct OPAQUE *PTR; PTR p; diff --git a/test/CodeGen/debug-line-1.c b/test/CodeGen/debug-line-1.c index 0c2d18583298..be1da0820931 100644 --- a/test/CodeGen/debug-line-1.c +++ b/test/CodeGen/debug-line-1.c @@ -4,7 +4,7 @@ // 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 !19 +// CHECK: br label %sw.epilog, !dbg ! extern int atoi(const char *); diff --git a/test/CodeGen/decl-in-prototype.c b/test/CodeGen/decl-in-prototype.c index 949793da445a..2c0fc4fc3b17 100644 --- a/test/CodeGen/decl-in-prototype.c +++ b/test/CodeGen/decl-in-prototype.c @@ -1,4 +1,4 @@ -// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s +// RUN: %clang -target i386-unknown-unknown -emit-llvm -S -o - %s | FileCheck %s const int AA = 5; diff --git a/test/CodeGen/dostmt.c b/test/CodeGen/dostmt.c index 1a2e02a78e6b..54973dc99b6e 100644 --- a/test/CodeGen/dostmt.c +++ b/test/CodeGen/dostmt.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s int bar(); int test0() { @@ -66,5 +66,11 @@ void test5() { do { break; } while(0); } - +// PR14191 +void test6f(void); +void test6() { + do { + } while (test6f(), 0); + // CHECK: call void @test6f() +} diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index cc03be6a922a..f8f28330ab77 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -174,3 +174,13 @@ void f16() { lbl: ; } + +// PR13704: negative increment in i128 is not preserved. +// CHECK: define void @f17() +void f17() { + extern void extfunc(__int128); + __int128 x = 2; + x--; + extfunc(x); +// CHECK: add nsw i128 %{{.}}, -1 +} diff --git a/test/CodeGen/extern-inline.c b/test/CodeGen/extern-inline.c index e3df9968bfd2..77cb270191a0 100644 --- a/test/CodeGen/extern-inline.c +++ b/test/CodeGen/extern-inline.c @@ -1,5 +1,5 @@ -// RUN: %clang -S -emit-llvm -std=gnu89 -o - %s | FileCheck %s -// RUN: %clang -S -emit-llvm -fgnu89-inline -o - %s | FileCheck %s +// RUN: %clang -target i386-unknown-unknown -S -emit-llvm -std=gnu89 -o - %s | FileCheck %s +// RUN: %clang -target i386-unknown-unknown -S -emit-llvm -fgnu89-inline -o - %s | FileCheck %s // PR5253 // If an extern inline function is redefined, functions should call the diff --git a/test/CodeGen/f16c-builtins.c b/test/CodeGen/f16c-builtins.c new file mode 100644 index 000000000000..28430d52f661 --- /dev/null +++ b/test/CodeGen/f16c-builtins.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +f16c -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_cvtph_ps(__m128i a) { + // CHECK: @llvm.x86.vcvtph2ps.128 + return _mm_cvtph_ps(a); +} + +__m256 test_mm256_cvtph_ps(__m128i a) { + // CHECK: @llvm.x86.vcvtph2ps.256 + return _mm256_cvtph_ps(a); +} + +__m128i test_mm_cvtps_ph(__m128 a) { + // CHECK: @llvm.x86.vcvtps2ph.128 + return _mm_cvtps_ph(a, 0); +} + +__m128i test_mm256_cvtps_ph(__m256 a) { + // CHECK: @llvm.x86.vcvtps2ph.256 + return _mm256_cvtps_ph(a, 0); +} diff --git a/test/CodeGen/fp-contract.c b/test/CodeGen/ffp-contract-option.c index eb95f1e21775..eb95f1e21775 100644 --- a/test/CodeGen/fp-contract.c +++ b/test/CodeGen/ffp-contract-option.c diff --git a/test/CodeGen/fold-const-declref.c b/test/CodeGen/fold-const-declref.c index 5a7ba8e26a77..f49611cda79a 100644 --- a/test/CodeGen/fold-const-declref.c +++ b/test/CodeGen/fold-const-declref.c @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify -emit-llvm-only +// RUN: %clang_cc1 -verify -emit-llvm-only %s // PR7242: Check that this doesn't crash. int main(void) { int __negative = 1; const int __max = __negative && 0 ; - __max / 0; + __max / 0; // expected-warning{{expression result unused}} expected-warning{{division by zero is undefined}} } diff --git a/test/CodeGen/fp-contract-pragma.cpp b/test/CodeGen/fp-contract-pragma.cpp new file mode 100644 index 000000000000..afd8c43121e6 --- /dev/null +++ b/test/CodeGen/fp-contract-pragma.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -O3 -emit-llvm -o - %s | FileCheck %s + +// Is FP_CONTRACT is honored in a simple case? +float fp_contract_1(float a, float b, float c) { +// CHECK: _Z13fp_contract_1fff +// CHECK: tail call float @llvm.fmuladd + #pragma STDC FP_CONTRACT ON + return a * b + c; +} + +// Is FP_CONTRACT state cleared on exiting compound statements? +float fp_contract_2(float a, float b, float c) { +// CHECK: _Z13fp_contract_2fff +// CHECK: %[[M:.+]] = fmul float %a, %b +// CHECK-NEXT: fadd float %[[M]], %c + { + #pragma STDC FP_CONTRACT ON + } + return a * b + c; +} + +// Does FP_CONTRACT survive template instatiation? +class Foo {}; +Foo operator+(Foo, Foo); + +template <typename T> +T template_muladd(T a, T b, T c) { + #pragma STDC FP_CONTRACT ON + return a * b + c; +} + +float fp_contract_3(float a, float b, float c) { +// CHECK: _Z13fp_contract_3fff +// CHECK: tail call float @llvm.fmuladd + return template_muladd<float>(a, b, c); +} + +template<typename T> class fp_contract_4 { + float method(float a, float b, float c) { + #pragma STDC FP_CONTRACT ON + return a * b + c; + } +}; + +template class fp_contract_4<int>; +// CHECK: _ZN13fp_contract_4IiE6methodEfff +// CHECK: tail call float @llvm.fmuladd + +// Check file-scoped FP_CONTRACT +#pragma STDC FP_CONTRACT ON +float fp_contract_5(float a, float b, float c) { +// CHECK: _Z13fp_contract_5fff +// CHECK: tail call float @llvm.fmuladd + return a * b + c; +} + +#pragma STDC FP_CONTRACT OFF +float fp_contract_6(float a, float b, float c) { +// CHECK: _Z13fp_contract_6fff +// CHECK: %[[M:.+]] = fmul float %a, %b +// CHECK-NEXT: fadd float %[[M]], %c + return a * b + c; +} + diff --git a/test/CodeGen/func-ptr-cast-decl.c b/test/CodeGen/func-ptr-cast-decl.c index e6307964294a..28364dec9aae 100644 --- a/test/CodeGen/func-ptr-cast-decl.c +++ b/test/CodeGen/func-ptr-cast-decl.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm-only %s -verify +// expected-no-diagnostics // PR5882 int q_sk_num(void *a); diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c index 426233d8dfd3..259d34d5951c 100644 --- a/test/CodeGen/init.c +++ b/test/CodeGen/init.c @@ -69,6 +69,8 @@ char test8(int X) { // CHECK: store i8 97 // CHECK: store i8 98 // CHECK: store i8 99 +// CHECK-NOT: getelementptr +// CHECK: load } void bar(void*); diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c index 2a01f255dc01..addb30bde42a 100644 --- a/test/CodeGen/inline.c +++ b/test/CodeGen/inline.c @@ -1,5 +1,5 @@ // RUN: echo "GNU89 tests:" -// RUN: %clang %s -O1 -emit-llvm -S -o %t -std=gnu89 +// RUN: %clang %s -target i386-unknown-unknown -O1 -emit-llvm -S -o %t -std=gnu89 // RUN: grep "define available_externally i32 @ei()" %t // RUN: grep "define i32 @foo()" %t // RUN: grep "define i32 @bar()" %t @@ -21,7 +21,7 @@ // RUN: grep "define void @testC" %t // RUN: echo "C99 tests:" -// RUN: %clang %s -O1 -emit-llvm -S -o %t -std=gnu99 +// RUN: %clang %s -target i386-unknown-unknown -O1 -emit-llvm -S -o %t -std=gnu99 // RUN: grep "define i32 @ei()" %t // RUN: grep "define available_externally i32 @foo()" %t // RUN: grep "define i32 @bar()" %t @@ -43,7 +43,7 @@ // RUN: grep "define void @testC" %t // RUN: echo "C++ tests:" -// RUN: %clang -x c++ %s -O1 -emit-llvm -S -o %t -std=c++98 +// RUN: %clang -x c++ %s -target i386-unknown-unknown -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 // RUN: grep "define i32 @_Z3barv()" %t diff --git a/test/CodeGen/integer-overflow.c b/test/CodeGen/integer-overflow.c index d7fff4ee4a2a..ed2dede7814c 100644 --- a/test/CodeGen/integer-overflow.c +++ b/test/CodeGen/integer-overflow.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CATCH_UB // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER @@ -15,24 +16,28 @@ void test1() { // DEFAULT: add nsw i32 // WRAPV: add i32 // TRAPV: llvm.sadd.with.overflow.i32 + // CATCH_UB: llvm.sadd.with.overflow.i32 // TRAPV_HANDLER: foo( f11G = a + b; // DEFAULT: sub nsw i32 // WRAPV: sub i32 // TRAPV: llvm.ssub.with.overflow.i32 + // CATCH_UB: llvm.ssub.with.overflow.i32 // TRAPV_HANDLER: foo( f11G = a - b; // DEFAULT: mul nsw i32 // WRAPV: mul i32 // TRAPV: llvm.smul.with.overflow.i32 + // CATCH_UB: llvm.smul.with.overflow.i32 // TRAPV_HANDLER: foo( f11G = a * b; // DEFAULT: sub nsw i32 0, // WRAPV: sub i32 0, // TRAPV: llvm.ssub.with.overflow.i32(i32 0 + // CATCH_UB: llvm.ssub.with.overflow.i32(i32 0 // TRAPV_HANDLER: foo( f11G = -a; @@ -41,12 +46,14 @@ void test1() { // DEFAULT: add nsw i32 {{.*}}, 1 // WRAPV: add i32 {{.*}}, 1 // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 1) + // CATCH_UB: llvm.sadd.with.overflow.i32({{.*}}, i32 1) // TRAPV_HANDLER: foo( ++a; // DEFAULT: add nsw i32 {{.*}}, -1 // WRAPV: add i32 {{.*}}, -1 // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 -1) + // CATCH_UB: llvm.sadd.with.overflow.i32({{.*}}, i32 -1) // TRAPV_HANDLER: foo( --a; @@ -56,11 +63,13 @@ void test1() { // DEFAULT: getelementptr inbounds i32* // WRAPV: getelementptr i32* // TRAPV: getelementptr inbounds i32* + // CATCH_UB: getelementptr inbounds i32* // PR9350: char increment never overflows. extern volatile signed char PR9350; // DEFAULT: add i8 {{.*}}, 1 // WRAPV: add i8 {{.*}}, 1 // TRAPV: add i8 {{.*}}, 1 + // CATCH_UB: add i8 {{.*}}, 1 ++PR9350; } diff --git a/test/CodeGen/le32-arguments.c b/test/CodeGen/le32-arguments.c new file mode 100644 index 000000000000..2cbbc0fbea45 --- /dev/null +++ b/test/CodeGen/le32-arguments.c @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s + +// Basic argument/attribute tests for le32/PNaCl + +// CHECK: define void @f0(i32 %i, i32 %j, double %k) +void f0(int i, long j, double k) {} + +typedef struct { + int aa; + int bb; +} s1; +// Structs should be passed byval and not split up +// CHECK: define void @f1(%struct.s1* byval %i) +void f1(s1 i) {} + +typedef struct { + int cc; +} s2; +// Structs should be returned sret and not simplified by the frontend +// CHECK: define void @f2(%struct.s2* noalias sret %agg.result) +s2 f2() { + s2 foo; + return foo; +} + +// CHECK: define void @f3(i64 %i) +void f3(long long i) {} + +// i8/i16 should be signext, i32 and higher should not +// CHECK: define void @f4(i8 signext %a, i16 signext %b) +void f4(char a, short b) {} + +// CHECK: define void @f5(i8 zeroext %a, i16 zeroext %b) +void f5(unsigned char a, unsigned short b) {} + + +enum my_enum { + ENUM1, + ENUM2, + ENUM3, +}; +// Enums should be treated as the underlying i32 +// CHECK: define void @f6(i32 %a) +void f6(enum my_enum a) {} + +union simple_union { + int a; + char b; +}; +// Unions should be passed as byval structs +// CHECK: define void @f7(%union.simple_union* byval %s) +void f7(union simple_union s) {} + +typedef struct { + int b4 : 4; + int b3 : 3; + int b8 : 8; +} bitfield1; +// Bitfields should be passed as byval structs +// CHECK: define void @f8(%struct.bitfield1* byval %bf1) +void f8(bitfield1 bf1) {} diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c new file mode 100644 index 000000000000..6ab5a11106b1 --- /dev/null +++ b/test/CodeGen/le32-regparm.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s + +#define FASTCALL __attribute__((regparm(2))) + +typedef struct { + int aaa; + double bbbb; + int ccc[200]; +} foo; + +// 2 inreg arguments are supported. +void FASTCALL f1(int i, int j, int k); +// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k) +void f1(int i, int j, int k) { } + +// inreg structs are not supported. +// CHECK: define void @f2(%struct.foo* inreg %a) +void __attribute__((regparm(1))) f2(foo* a) {} + +// Only the first 2 arguments can be passed inreg, and the first +// non-integral type consumes remaining available registers. +// CHECK: define void @f3(%struct.foo* byval %a, i32 %b) +void __attribute__((regparm(2))) f3(foo a, int b) {} + +// Only 64 total bits are supported +// CHECK: define void @f4(i64 inreg %g, i32 %h) +void __attribute__((regparm(2))) f4(long long g, int h) {} + +typedef void (*FType)(int, int) __attribute ((regparm (2))); +FType bar; +extern void FASTCALL reduced(char b, double c, foo* d, double e, int f); + +int +main(void) { + // The presence of double c means that foo* d is not passed inreg. This + // behavior is different from current x86-32 behavior + // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.foo* null + reduced(0, 0.0, 0, 0.0, 0); + // CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2) + bar(1,2); +} diff --git a/test/CodeGen/libcall-declarations.c b/test/CodeGen/libcall-declarations.c new file mode 100644 index 000000000000..4517643e4c4e --- /dev/null +++ b/test/CodeGen/libcall-declarations.c @@ -0,0 +1,191 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=CHECK-NOERRNO +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=CHECK-ERRNO + +// Prototypes. +double acos(double); +long double acosl(long double); +float acosf(float); +double asin(double); +long double asinl(long double); +float asinf(float); +double atan(double); +long double atanl(long double); +float atanf(float); +double atan2(double, double); +long double atan2l(long double, long double); +float atan2f(float, float); +double ceil(double); +long double ceill(long double); +float ceilf(float); +double copysign(double, double); +long double copysignl(long double, long double); +float copysignf(float, float); +double cos(double); +long double cosl(long double); +float cosf(float); +double exp(double); +long double expl(long double); +float expf(float); +double exp2(double); +long double exp2l(long double); +float exp2f(float); +double fabs(double); +long double fabsl(long double); +float fabsf(float); +double floor(double); +long double floorl(long double); +float floorf(float); +double fma(double, double, double); +long double fmal(long double, long double, long double); +float fmaf(float, float, float); +double fmax(double, double); +long double fmaxl(long double, long double); +float fmaxf(float, float); +double fmin(double, double); +long double fminl(long double, long double); +float fminf(float, float); +double log(double); +long double logl(long double); +float logf(float); +double log2(double); +long double log2l(long double); +float log2f(float); +double nearbyint(double); +long double nearbyintl(long double); +float nearbyintf(float); +double pow(double, double); +long double powl(long double, long double); +float powf(float, float); +double rint(double); +long double rintl(long double); +float rintf(float); +double round(double); +long double roundl(long double); +float roundf(float); +double sin(double); +long double sinl(long double); +float sinf(float); +double sqrt(double); +long double sqrtl(long double); +float sqrtf(float); +double tan(double); +long double tanl(long double); +float tanf(float); +double trunc(double); +long double truncl(long double); +float truncf(float); + +// Force emission of the declare statements. +void *use[] = { + acos, acosl, acosf, asin, asinl, asinf, atan, atanl, atanf, atan2, atan2l, + atan2f, ceil, ceill, ceilf, copysign, copysignl, copysignf, cos, cosl, cosf, + exp, expl, expf, exp2, exp2l, exp2f, fabs, fabsl, fabsf, floor, floorl, + floorf, fma, fmal, fmaf, fmax, fmaxl, fmaxf, fmin, fminl, fminf, log, logl, + logf, log2, log2l, log2f, nearbyint, nearbyintl, nearbyintf, pow, powl, powf, + rint, rintl, rintf, round, roundl, roundf, sin, sinl, sinf, sqrt, sqrtl, + sqrtf, tan, tanl, tanf, trunc, truncl, truncf +}; + +// CHECK-NOERRNO: declare double @acos(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @acosl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @acosf(float) nounwind readnone +// CHECK-NOERRNO: declare double @asin(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @asinl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @asinf(float) nounwind readnone +// CHECK-NOERRNO: declare double @atan(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @atanl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @atanf(float) nounwind readnone +// CHECK-NOERRNO: declare double @atan2(double, double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @atan2f(float, float) nounwind readnone +// CHECK-NOERRNO: declare double @ceil(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @ceill(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @ceilf(float) nounwind readnone +// CHECK-NOERRNO: declare double @copysign(double, double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @copysignf(float, float) nounwind readnone +// CHECK-NOERRNO: declare double @cos(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @cosl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @cosf(float) nounwind readnone +// CHECK-NOERRNO: declare double @exp(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @expl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @expf(float) nounwind readnone +// CHECK-NOERRNO: declare double @exp2(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @exp2l(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @exp2f(float) nounwind readnone +// CHECK-NOERRNO: declare double @fabs(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @fabsl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @fabsf(float) nounwind readnone +// CHECK-NOERRNO: declare double @floor(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @floorl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @floorf(float) nounwind readnone +// CHECK-NOERRNO: declare double @fma(double, double, double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @fmaf(float, float, float) nounwind readnone +// CHECK-NOERRNO: declare double @fmax(double, double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @fmaxf(float, float) nounwind readnone +// CHECK-NOERRNO: declare double @fmin(double, double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @fminf(float, float) nounwind readnone +// CHECK-NOERRNO: declare double @log(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @logl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @logf(float) nounwind readnone +// CHECK-NOERRNO: declare double @log2(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @log2l(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @log2f(float) nounwind readnone +// CHECK-NOERRNO: declare double @nearbyint(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @nearbyintl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @nearbyintf(float) nounwind readnone +// CHECK-NOERRNO: declare double @pow(double, double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @powf(float, float) nounwind readnone +// CHECK-NOERRNO: declare double @rint(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @rintl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @rintf(float) nounwind readnone +// CHECK-NOERRNO: declare double @round(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @roundl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @roundf(float) nounwind readnone +// CHECK-NOERRNO: declare double @sin(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @sinl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @sinf(float) nounwind readnone +// CHECK-NOERRNO: declare double @sqrt(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @sqrtl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @sqrtf(float) nounwind readnone +// CHECK-NOERRNO: declare double @tan(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @tanl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @tanf(float) nounwind readnone +// CHECK-NOERRNO: declare double @trunc(double) nounwind readnone +// CHECK-NOERRNO: declare x86_fp80 @truncl(x86_fp80) nounwind readnone +// CHECK-NOERRNO: declare float @truncf(float) nounwind readnone + +// CHECK-ERRNO: declare double @ceil(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @ceill(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @ceilf(float) nounwind readnone +// CHECK-ERRNO: declare double @copysign(double, double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @copysignf(float, float) nounwind readnone +// CHECK-ERRNO: declare double @fabs(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @fabsl(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @fabsf(float) nounwind readnone +// CHECK-ERRNO: declare double @floor(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @floorl(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @floorf(float) nounwind readnone +// CHECK-ERRNO: declare double @fmax(double, double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @fmaxf(float, float) nounwind readnone +// CHECK-ERRNO: declare double @fmin(double, double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @fminf(float, float) nounwind readnone +// CHECK-ERRNO: declare double @nearbyint(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @nearbyintf(float) nounwind readnone +// CHECK-ERRNO: declare double @rint(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @rintl(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @rintf(float) nounwind readnone +// CHECK-ERRNO: declare double @round(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @roundl(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @roundf(float) nounwind readnone +// CHECK-ERRNO: declare double @trunc(double) nounwind readnone +// CHECK-ERRNO: declare x86_fp80 @truncl(x86_fp80) nounwind readnone +// CHECK-ERRNO: declare float @truncf(float) nounwind readnone diff --git a/test/CodeGen/libcalls-fno-builtin.c b/test/CodeGen/libcalls-fno-builtin.c index ce10759b0c5f..e7f3ef7b41d3 100644 --- a/test/CodeGen/libcalls-fno-builtin.c +++ b/test/CodeGen/libcalls-fno-builtin.c @@ -1,11 +1,32 @@ // RUN: %clang_cc1 -S -O3 -fno-builtin -o - %s | FileCheck %s // rdar://10551066 +typedef __SIZE_TYPE__ size_t; + double ceil(double x); double copysign(double,double); double cos(double x); double fabs(double x); double floor(double x); +char *strcat(char *s1, const char *s2); +char *strncat(char *s1, const char *s2, size_t n); +char *strchr(const char *s, int c); +char *strrchr(const char *s, int c); +int strcmp(const char *s1, const char *s2); +int strncmp(const char *s1, const char *s2, size_t n); +char *strcpy(char *s1, const char *s2); +char *stpcpy(char *s1, const char *s2); +char *strncpy(char *s1, const char *s2, size_t n); +size_t strlen(const char *s); +char *strpbrk(const char *s1, const char *s2); +size_t strspn(const char *s1, const char *s2); +double strtod(const char *nptr, char **endptr); +float strtof(const char *nptr, char **endptr); +long double strtold(const char *nptr, char **endptr); +long int strtol(const char *nptr, char **endptr, int base); +long long int strtoll(const char *nptr, char **endptr, int base); +unsigned long int strtoul(const char *nptr, char **endptr, int base); +unsigned long long int strtoull(const char *nptr, char **endptr, int base); double t1(double x) { return ceil(x); } // CHECK: t1 @@ -26,3 +47,79 @@ double t4(double x) { return fabs(x); } double t5(double x) { return floor(x); } // CHECK: t5 // CHECK: floor + +char *t6(char *x) { return strcat(x, ""); } +// CHECK: t6 +// CHECK: strcat + +char *t7(char *x) { return strncat(x, "", 1); } +// CHECK: t7 +// CHECK: strncat + +char *t8(void) { return strchr("hello, world", 'w'); } +// CHECK: t8 +// CHECK: strchr + +char *t9(void) { return strrchr("hello, world", 'w'); } +// CHECK: t9 +// CHECK: strrchr + +int t10(void) { return strcmp("foo", "bar"); } +// CHECK: t10 +// CHECK: strcmp + +int t11(void) { return strncmp("foo", "bar", 3); } +// CHECK: t11 +// CHECK: strncmp + +char *t12(char *x) { return strcpy(x, "foo"); } +// CHECK: t12 +// CHECK: strcpy + +char *t13(char *x) { return stpcpy(x, "foo"); } +// CHECK: t13 +// CHECK: stpcpy + +char *t14(char *x) { return strncpy(x, "foo", 3); } +// CHECK: t14 +// CHECK: strncpy + +size_t t15(void) { return strlen("foo"); } +// CHECK: t15 +// CHECK: strlen + +char *t16(char *x) { return strpbrk(x, ""); } +// CHECK: t16 +// CHECK: strpbrk + +size_t t17(char *x) { return strspn(x, ""); } +// CHECK: t17 +// CHECK: strspn + +double t18(char **x) { return strtod("123.4", x); } +// CHECK: t18 +// CHECK: strtod + +float t19(char **x) { return strtof("123.4", x); } +// CHECK: t19 +// CHECK: strtof + +long double t20(char **x) { return strtold("123.4", x); } +// CHECK: t20 +// CHECK: strtold + +long int t21(char **x) { return strtol("1234", x, 10); } +// CHECK: t21 +// CHECK: strtol + +long int t22(char **x) { return strtoll("1234", x, 10); } +// CHECK: t22 +// CHECK: strtoll + +long int t23(char **x) { return strtoul("1234", x, 10); } +// CHECK: t23 +// CHECK: strtoul + +long int t24(char **x) { return strtoull("1234", x, 10); } +// CHECK: t24 +// CHECK: strtoull diff --git a/test/CodeGen/long-double-x86-nacl.c b/test/CodeGen/long-double-x86-nacl.c new file mode 100644 index 000000000000..175129cb6a2a --- /dev/null +++ b/test/CodeGen/long-double-x86-nacl.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-unknown-nacl | FileCheck %s + +long double x = 0; +int checksize[sizeof(x) == 8 ? 1 : -1]; + +// CHECK: define void @s1(double %a) +void s1(long double a) {} diff --git a/test/CodeGen/microsoft-call-conv-x64.c b/test/CodeGen/microsoft-call-conv-x64.c new file mode 100644 index 000000000000..97a1d99d6b6d --- /dev/null +++ b/test/CodeGen/microsoft-call-conv-x64.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm < %s | FileCheck %s + +void __fastcall f1(void); +void __stdcall f2(void); +void __fastcall f4(void) { +// CHECK: define void @f4() + f1(); +// CHECK: call void @f1() +} +void __stdcall f5(void) { +// CHECK: define void @f5() + f2(); +// CHECK: call void @f2() +} + +// PR5280 +void (__fastcall *pf1)(void) = f1; +void (__stdcall *pf2)(void) = f2; +void (__fastcall *pf4)(void) = f4; +void (__stdcall *pf5)(void) = f5; + +int main(void) { + f4(); f5(); + // CHECK: call void @f4() + // CHECK: call void @f5() + pf1(); pf2(); pf4(); pf5(); + // CHECK: call void %{{.*}}() + // CHECK: call void %{{.*}}() + // CHECK: call void %{{.*}}() + // CHECK: call void %{{.*}}() + return 0; +} + +// PR7117 +void __stdcall f7(foo) int foo; {} +void f8(void) { + f7(0); + // CHECK: call void @f7(i32 0) +} diff --git a/test/CodeGen/microsoft-call-conv.c b/test/CodeGen/microsoft-call-conv.c index 390c3be05e61..64d10fb4f4ff 100644 --- a/test/CodeGen/microsoft-call-conv.c +++ b/test/CodeGen/microsoft-call-conv.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-pc-linux -emit-llvm < %s | FileCheck %s void __fastcall f1(void); void __stdcall f2(void); diff --git a/test/CodeGen/mips-byval-arg.c b/test/CodeGen/mips-byval-arg.c index 4e5f41a14972..41ccd60e8f3e 100644 --- a/test/CodeGen/mips-byval-arg.c +++ b/test/CodeGen/mips-byval-arg.c @@ -1,5 +1,5 @@ -// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32 -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64 +// RUN: %clang -target mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32 +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64 typedef struct { float f[3]; diff --git a/test/CodeGen/mips-clobber-reg.c b/test/CodeGen/mips-clobber-reg.c index 2a06e53b39a5..be18353af820 100644 --- a/test/CodeGen/mips-clobber-reg.c +++ b/test/CodeGen/mips-clobber-reg.c @@ -1,4 +1,4 @@ -// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s +// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s /* This checks that the frontend will accept both diff --git a/test/CodeGen/mips-constraint-regs.c b/test/CodeGen/mips-constraint-regs.c index 075be058dc3e..ea063b50d5ce 100644 --- a/test/CodeGen/mips-constraint-regs.c +++ b/test/CodeGen/mips-constraint-regs.c @@ -1,4 +1,5 @@ -// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s +// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s \ +// RUN: | FileCheck %s // This checks that the frontend will accept inline asm constraints // c', 'l' and 'x'. Semantic checking will happen in the @@ -10,6 +11,7 @@ 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. + // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "addi $0,$1,$2 \0A\09\09", "=c,c,I"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}} int __s, __v = 17; int __t; __asm__ __volatile__( @@ -20,6 +22,7 @@ int main() // 'l': lo register // We are making it clear that destination register is lo with the // use of the 'l' constraint ("=l"). + // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "mtlo $1 \0A\09\09", "=l,r,~{lo}"(i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}} int i_temp = 44; int i_result; __asm__ __volatile__( @@ -31,6 +34,7 @@ int main() // 'x': Combined lo/hi registers // We are specifying that destination registers are the hi/lo pair with the // use of the 'x' constraint ("=x"). + // CHECK: %{{[0-9]+}} = call i64 asm sideeffect "mthi $1 \0A\09\09mtlo $2 \0A\09\09", "=x,r,r"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}} int i_hi = 3; int i_lo = 2; long long ll_result = 0; @@ -40,5 +44,6 @@ int main() : "=x" (ll_result) : "r" (i_hi), "r" (i_lo) : ); + return 0; } diff --git a/test/CodeGen/mips-vector-arg.c b/test/CodeGen/mips-vector-arg.c index 39998d91a64a..584192faf070 100644 --- a/test/CodeGen/mips-vector-arg.c +++ b/test/CodeGen/mips-vector-arg.c @@ -1,5 +1,5 @@ -// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32 -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64 +// RUN: %clang -target mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32 +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64 // check that // 1. vector arguments are passed in integer registers diff --git a/test/CodeGen/mips-vector-return.c b/test/CodeGen/mips-vector-return.c index 12e71fadf87b..0bff96969000 100644 --- a/test/CodeGen/mips-vector-return.c +++ b/test/CodeGen/mips-vector-return.c @@ -1,5 +1,5 @@ -// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32 -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64 +// RUN: %clang -target mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32 +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64 // vectors larger than 16-bytes are returned via the hidden pointer argument. // N64/N32 returns vectors whose size is equal to or smaller than 16-bytes in diff --git a/test/CodeGen/mips64-class-return.cpp b/test/CodeGen/mips64-class-return.cpp index 8e32d5cbd6f0..2a786df3effa 100644 --- a/test/CodeGen/mips64-class-return.cpp +++ b/test/CodeGen/mips64-class-return.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s class B0 { double d; diff --git a/test/CodeGen/mips64-f128-literal.c b/test/CodeGen/mips64-f128-literal.c index 2f01520a4f5f..9121169b726e 100644 --- a/test/CodeGen/mips64-f128-literal.c +++ b/test/CodeGen/mips64-f128-literal.c @@ -1,4 +1,4 @@ -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s typedef long double LD; diff --git a/test/CodeGen/mips64-nontrivial-return.cpp b/test/CodeGen/mips64-nontrivial-return.cpp index 8aff9ab32f0f..2164b20c184a 100644 --- a/test/CodeGen/mips64-nontrivial-return.cpp +++ b/test/CodeGen/mips64-nontrivial-return.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s class B { public: diff --git a/test/CodeGen/mips64-padding-arg.c b/test/CodeGen/mips64-padding-arg.c index b4dcfbace9d4..9d7f8774f6e7 100644 --- a/test/CodeGen/mips64-padding-arg.c +++ b/test/CodeGen/mips64-padding-arg.c @@ -1,4 +1,4 @@ -// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s +// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s typedef struct { double d; diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c new file mode 100644 index 000000000000..a74ede09e001 --- /dev/null +++ b/test/CodeGen/ms-inline-asm-64.c @@ -0,0 +1,16 @@ +// REQUIRES: x86-64-registered-target +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O0 -fms-extensions -fenable-experimental-ms-inline-asm -w -emit-llvm -o - | FileCheck %s + +void t1() { + int var = 10; + __asm mov rax, offset var ; rax = address of myvar +// CHECK: t1 +// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind +} + +void t2() { + int var = 10; + __asm mov [eax], offset var +// CHECK: t2 +// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind +} diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c index c140d60551d9..7f43da891e90 100644 --- a/test/CodeGen/ms-inline-asm.c +++ b/test/CodeGen/ms-inline-asm.c @@ -1,17 +1,18 @@ -// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O0 -fms-extensions -fenable-experimental-ms-inline-asm -w -emit-llvm -o - | FileCheck %s +// REQUIRES: x86-64-registered-target +// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -O0 -fms-extensions -fenable-experimental-ms-inline-asm -w -emit-llvm -o - | FileCheck %s void t1() { // CHECK: @t1 -// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() nounwind // CHECK: ret void __asm {} } void t2() { // CHECK: @t2 -// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind // CHECK: ret void __asm nop __asm nop @@ -20,15 +21,15 @@ void t2() { void t3() { // CHECK: @t3 -// CHECK: call void asm sideeffect "nop\0Anop\0Anop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() nounwind // CHECK: ret void __asm nop __asm nop __asm nop } void t4(void) { // CHECK: @t4 -// CHECK: call void asm sideeffect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -// CHECK: call void asm sideeffect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind // CHECK: ret void __asm mov ebx, eax __asm mov ecx, ebx @@ -36,7 +37,7 @@ void t4(void) { void t5(void) { // CHECK: @t5 -// CHECK: call void asm sideeffect "mov ebx, eax\0Amov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind // CHECK: ret void __asm mov ebx, eax __asm mov ecx, ebx } @@ -44,77 +45,158 @@ void t5(void) { void t6(void) { __asm int 0x2c // CHECK: t6 -// CHECK: call void asm sideeffect "int 0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind } -void* t7(void) { - __asm mov eax, fs:[0x10] -// CHECK: t7 -// CHECK: call void asm sideeffect "mov eax, fs:[0x10]", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -} - -void t8() { +void t7() { __asm { int 0x2c ; } asm comments are fun! }{ } __asm {} -// CHECK: t8 -// CHECK: call void asm sideeffect "int 0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: t7 +// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() nounwind } -int t9() { - __asm int 3 ; } comments for single-line asm + +int t8() { + __asm int 4 ; } comments for single-line asm __asm {} __asm int 4 return 10; -// CHECK: t9 -// CHECK: call void asm sideeffect "int 3", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect -// CHECK: call void asm sideeffect "int 4", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: t8 +// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() nounwind // CHECK: ret i32 10 } -void t10() { + +void t9() { __asm { push ebx mov ebx, 0x07 pop ebx } -// CHECK: t10 -// CHECK: call void asm sideeffect "push ebx\0Amov ebx, 0x07\0Apop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: t9 +// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind } -unsigned t11(void) { +unsigned t10(void) { unsigned i = 1, j; __asm { mov eax, i mov j, eax } return j; -// CHECK: t11 +// CHECK: t10 // CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: store i32 1, i32* [[I]], align 4 -// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) nounwind // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } -void t12(void) { - __asm EVEN - __asm ALIGN +void t11(void) { + __asm mov eax, 1 +// CHECK: t11 +// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind +} + +unsigned t12(void) { + unsigned i = 1, j, l = 1, m; + __asm { + mov eax, i + mov j, eax + mov eax, l + mov m, eax + } + return j + m; +// CHECK: t12 +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) nounwind +} + +void t13() { + char i = 1; + short j = 2; + __asm movzx eax, i + __asm movzx eax, j +// CHECK: t13 +// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}) nounwind +// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}}) nounwind +} + +void t14() { + unsigned i = 1, j = 2; + __asm { + .if 1 + mov eax, i + .else + mov ebx, j + .endif + } +// CHECK: t14 +// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind +} + +void t15() { + int var = 10; + __asm mov eax, var ; eax = 10 + __asm mov eax, offset var ; eax = address of myvar +// CHECK: t15 +// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind +} + +void t16() { + int var = 10; + __asm mov [eax], offset var +// CHECK: t16 +// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind +} + +void t17() { + __asm _emit 0x4A + __asm _emit 0x43 + __asm _emit 0x4B +// CHECK: t17 +// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"() nounwind +// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() nounwind +} + +struct t18_type { int a, b; }; + +int t18() { + struct t18_type foo; + foo.a = 1; + foo.b = 2; + __asm { + lea ebx, foo + mov eax, [ebx].0 + mov [ebx].4, ecx + } + return foo.b; +// CHECK: t18 +// CHECK: call void asm sideeffect inteldialect "lea ebx, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind } -void t13(void) { +int t19() { + struct t18_type foo; + foo.a = 1; + foo.b = 2; __asm { - _emit 0x4A - _emit 0x43 - _emit 0x4B + lea ebx, foo + mov eax, [ebx].foo.a + mov [ebx].foo.b, ecx } + return foo.b; +// CHECK: t19 +// CHECK: call void asm sideeffect inteldialect "lea ebx, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind } -void t14(void) { - unsigned arr[10]; - __asm LENGTH arr ; sizeof(arr)/sizeof(arr[0]) - __asm SIZE arr ; sizeof(arr) - __asm TYPE arr ; sizeof(arr[0]) +void t20() { + int foo; + __asm mov eax, TYPE foo +// CHECK: t20 +// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind } diff --git a/test/CodeGen/ppc-atomics.c b/test/CodeGen/ppc-atomics.c new file mode 100644 index 000000000000..3fcb0fbec963 --- /dev/null +++ b/test/CodeGen/ppc-atomics.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=32 +// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=64 + +unsigned char c1, c2; +unsigned short s1, s2; +unsigned int i1, i2; +unsigned long long ll1, ll2; + +enum memory_order { + memory_order_relaxed, + memory_order_consume, + memory_order_acquire, + memory_order_release, + memory_order_acq_rel, + memory_order_seq_cst +}; + +void test1(void) { + (void)__atomic_load(&c1, &c2, memory_order_seq_cst); + (void)__atomic_load(&s1, &s2, memory_order_seq_cst); + (void)__atomic_load(&i1, &i2, memory_order_seq_cst); + (void)__atomic_load(&ll1, &ll2, memory_order_seq_cst); + +// 32: define void @test1 +// 32: load atomic i8* @c1 seq_cst +// 32: load atomic i16* @s1 seq_cst +// 32: load atomic i32* @i1 seq_cst +// 32: call void @__atomic_load(i32 8, i8* bitcast (i64* @ll1 to i8*) + +// 64: define void @test1 +// 64: load atomic i8* @c1 seq_cst +// 64: load atomic i16* @s1 seq_cst +// 64: load atomic i32* @i1 seq_cst +// 64: load atomic i64* @ll1 seq_cst +} diff --git a/test/CodeGen/ppc64-align-long-double.c b/test/CodeGen/ppc64-align-long-double.c new file mode 100644 index 000000000000..c4dcfa072367 --- /dev/null +++ b/test/CodeGen/ppc64-align-long-double.c @@ -0,0 +1,18 @@ +// REQUIRES: ppc64-registered-target +// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK: -f128:128:128- + +struct S { + double a; + long double b; +}; + +// CHECK: %struct.{{[a-zA-Z0-9]+}} = type { double, ppc_fp128 } + +long double test (struct S x) +{ + return x.b; +} + +// CHECK: %{{[0-9]}} = load ppc_fp128* %{{[a-zA-Z0-9]+}}, align 16 diff --git a/test/CodeGen/ppc64-extend.c b/test/CodeGen/ppc64-extend.c new file mode 100644 index 000000000000..f4d6bf9c68df --- /dev/null +++ b/test/CodeGen/ppc64-extend.c @@ -0,0 +1,15 @@ +// REQUIRES: ppc64-registered-target +// RUN: %clang_cc1 -O0 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void f1(int x) { return; } +// CHECK: define void @f1(i32 signext %x) nounwind + +void f2(unsigned int x) { return; } +// CHECK: define void @f2(i32 zeroext %x) nounwind + +int f3(void) { return 0; } +// CHECK: define signext i32 @f3() nounwind + +unsigned int f4(void) { return 0; } +// CHECK: define zeroext i32 @f4() nounwind + diff --git a/test/CodeGen/ppc64-struct-onefloat.c b/test/CodeGen/ppc64-struct-onefloat.c new file mode 100644 index 000000000000..4f9e1949cea3 --- /dev/null +++ b/test/CodeGen/ppc64-struct-onefloat.c @@ -0,0 +1,49 @@ +// REQUIRES: ppc64-registered-target +// RUN: %clang_cc1 -O0 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +typedef struct s1 { float f; } Sf; +typedef struct s2 { double d; } Sd; +typedef struct s4 { Sf fs; } SSf; +typedef struct s5 { Sd ds; } SSd; + +void bar(Sf a, Sd b, SSf d, SSd e) {} + +// CHECK: define void @bar +// CHECK: %a = alloca %struct.s1, align 4 +// CHECK: %b = alloca %struct.s2, align 8 +// CHECK: %d = alloca %struct.s4, align 4 +// CHECK: %e = alloca %struct.s5, align 8 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s1* %a, i32 0, i32 0 +// CHECK: store float %a.coerce, float* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s2* %b, i32 0, i32 0 +// CHECK: store double %b.coerce, double* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s4* %d, i32 0, i32 0 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s1* %{{[a-zA-Z0-9.]+}}, i32 0, i32 0 +// CHECK: store float %d.coerce, float* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s5* %e, i32 0, i32 0 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s2* %{{[a-zA-Z0-9.]+}}, i32 0, i32 0 +// CHECK: store double %e.coerce, double* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: ret void + +void foo(void) +{ + Sf p1 = { 22.63f }; + Sd p2 = { 19.47 }; + SSf p4 = { { 22.63f } }; + SSd p5 = { { 19.47 } }; + bar(p1, p2, p4, p5); +} + +// CHECK: define void @foo +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s1* %p1, i32 0, i32 0 +// CHECK: %{{[0-9]+}} = load float* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s2* %p2, i32 0, i32 0 +// CHECK: %{{[0-9]+}} = load double* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s4* %p4, i32 0, i32 0 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s1* %{{[a-zA-Z0-9.]+}}, i32 0, i32 0 +// CHECK: %{{[0-9]+}} = load float* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s5* %p5, i32 0, i32 0 +// CHECK: %{{[a-zA-Z0-9.]+}} = getelementptr %struct.s2* %{{[a-zA-Z0-9.]+}}, i32 0, i32 0 +// CHECK: %{{[0-9]+}} = load double* %{{[a-zA-Z0-9.]+}}, align 1 +// CHECK: call void @bar(float inreg %{{[0-9]+}}, double inreg %{{[0-9]+}}, float inreg %{{[0-9]+}}, double inreg %{{[0-9]+}}) +// CHECK: ret void diff --git a/test/CodeGen/ppc64-varargs-struct.c b/test/CodeGen/ppc64-varargs-struct.c new file mode 100644 index 000000000000..61c33b052980 --- /dev/null +++ b/test/CodeGen/ppc64-varargs-struct.c @@ -0,0 +1,30 @@ +// REQUIRES: ppc64-registered-target +// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +#include <stdarg.h> + +struct x { + long a; + double b; +}; + +void testva (int n, ...) +{ + va_list ap; + + struct x t = va_arg (ap, struct x); +// CHECK: bitcast i8* %{{[a-z.0-9]*}} to %struct.x* +// CHECK: bitcast %struct.x* %t to i8* +// CHECK: bitcast %struct.x* %{{[0-9]+}} to i8* +// CHECK: call void @llvm.memcpy + + int v = va_arg (ap, int); +// CHECK: ptrtoint i8* %{{[a-z.0-9]*}} to i64 +// CHECK: add i64 %{{[0-9]+}}, 4 +// CHECK: inttoptr i64 %{{[0-9]+}} to i8* +// CHECK: bitcast i8* %{{[0-9]+}} to i32* + + __int128_t u = va_arg (ap, __int128_t); +// CHECK: bitcast i8* %{{[a-z.0-9]+}} to i128* +// CHECK-NEXT: load i128* %{{[0-9]+}} +} diff --git a/test/CodeGen/pragma-weak.c b/test/CodeGen/pragma-weak.c index 7ad2b77d8e7e..2efc2ebc28d8 100644 --- a/test/CodeGen/pragma-weak.c +++ b/test/CodeGen/pragma-weak.c @@ -157,6 +157,15 @@ void PR10878() { SHA384Pad(0); } // CHECK: call void @SHA384Pad(i8* null) +// PR14046: Parse #pragma weak in function-local context +extern int PR14046e(void); +void PR14046f() { +#pragma weak PR14046e + PR14046e(); +} +// CHECK: declare extern_weak i32 @PR14046e() + + ///////////// TODO: stuff that still doesn't work // due to the fact that disparate TopLevelDecls cannot affect each other diff --git a/test/CodeGen/rtm-builtins.c b/test/CodeGen/rtm-builtins.c new file mode 100644 index 000000000000..c4939a9a3d9f --- /dev/null +++ b/test/CodeGen/rtm-builtins.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +rtm -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +unsigned int test_xbegin(void) { + // CHECK: i32 @llvm.x86.xbegin() + return _xbegin(); +} + +void +test_xend(void) { + // CHECK: void @llvm.x86.xend() + _xend(); +} + +void +test_xabort(void) { + // CHECK: void @llvm.x86.xabort(i8 2) + _xabort(2); +} diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c index 0e48560b0869..400209fca291 100644 --- a/test/CodeGen/sse-builtins.c +++ b/test/CodeGen/sse-builtins.c @@ -1,8 +1,39 @@ // RUN: %clang_cc1 -ffreestanding -triple i386-apple-darwin9 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s +#include <xmmintrin.h> #include <emmintrin.h> #include <smmintrin.h> +__m128 test_rsqrt_ss(__m128 x) { + // CHECK: define {{.*}} @test_rsqrt_ss + // CHECK: call <4 x float> @llvm.x86.sse.rsqrt.ss + // CHECK: extractelement <4 x float> {{.*}}, i32 0 + // CHECK: extractelement <4 x float> {{.*}}, i32 1 + // CHECK: extractelement <4 x float> {{.*}}, i32 2 + // CHECK: extractelement <4 x float> {{.*}}, i32 3 + return _mm_rsqrt_ss(x); +} + +__m128 test_rcp_ss(__m128 x) { + // CHECK: define {{.*}} @test_rcp_ss + // CHECK: call <4 x float> @llvm.x86.sse.rcp.ss + // CHECK: extractelement <4 x float> {{.*}}, i32 0 + // CHECK: extractelement <4 x float> {{.*}}, i32 1 + // CHECK: extractelement <4 x float> {{.*}}, i32 2 + // CHECK: extractelement <4 x float> {{.*}}, i32 3 + return _mm_rcp_ss(x); +} + +__m128 test_sqrt_ss(__m128 x) { + // CHECK: define {{.*}} @test_sqrt_ss + // CHECK: call <4 x float> @llvm.x86.sse.sqrt.ss + // CHECK: extractelement <4 x float> {{.*}}, i32 0 + // CHECK: extractelement <4 x float> {{.*}}, i32 1 + // CHECK: extractelement <4 x float> {{.*}}, i32 2 + // CHECK: extractelement <4 x float> {{.*}}, i32 3 + return _mm_sqrt_ss(x); +} + __m128 test_loadl_pi(__m128 x, void* y) { // CHECK: define {{.*}} @test_loadl_pi // CHECK: load <2 x float>* {{.*}}, align 1{{$}} diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c index e2bbb5a90a81..5affb9a83513 100644 --- a/test/CodeGen/statements.c +++ b/test/CodeGen/statements.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -Wno-error=return-type %s -emit-llvm-only +// REQUIRES: LP64 void test1(int x) { switch (x) { diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c index 3de7b6727bc2..d51817882283 100644 --- a/test/CodeGen/stdcall-fastcall.c +++ b/test/CodeGen/stdcall-fastcall.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm < %s | FileCheck %s void __attribute__((fastcall)) f1(void); void __attribute__((stdcall)) f2(void); @@ -48,3 +48,99 @@ void f8(void) { f7(0); // CHECK: call x86_stdcallcc void @f7(i32 0) } + +void __attribute__((fastcall)) foo1(int y); +void bar1(int y) { + // CHECK: define void @bar1 + // CHECK: call x86_fastcallcc void @foo1(i32 inreg % + foo1(y); +} + +struct S1 { + int x; +}; +void __attribute__((fastcall)) foo2(struct S1 y); +void bar2(struct S1 y) { + // CHECK: define void @bar2 + // CHECK: call x86_fastcallcc void @foo2(i32 inreg undef, i32 % + foo2(y); +} + +void __attribute__((fastcall)) foo3(int *y); +void bar3(int *y) { + // CHECK: define void @bar3 + // CHECK: call x86_fastcallcc void @foo3(i32* inreg % + foo3(y); +} + +enum Enum {Eval}; +void __attribute__((fastcall)) foo4(enum Enum y); +void bar4(enum Enum y) { + // CHECK: define void @bar4 + // CHECK: call x86_fastcallcc void @foo4(i32 inreg % + foo4(y); +} + +struct S2 { + int x1; + double x2; + double x3; +}; +void __attribute__((fastcall)) foo5(struct S2 y); +void bar5(struct S2 y) { + // CHECK: define void @bar5 + // CHECK: call x86_fastcallcc void @foo5(%struct.S2* byval align 4 % + foo5(y); +} + +void __attribute__((fastcall)) foo6(long long y); +void bar6(long long y) { + // CHECK: define void @bar6 + // CHECK: call x86_fastcallcc void @foo6(i64 % + foo6(y); +} + +void __attribute__((fastcall)) foo7(int a, struct S1 b, int c); +void bar7(int a, struct S1 b, int c) { + // CHECK: define void @bar7 + // CHECK: call x86_fastcallcc void @foo7(i32 inreg %{{.*}}, i32 %{{.*}}, i32 %{{.*}} + foo7(a, b, c); +} + +void __attribute__((fastcall)) foo8(struct S1 a, int b); +void bar8(struct S1 a, int b) { + // CHECK: define void @bar8 + // CHECK: call x86_fastcallcc void @foo8(i32 inreg undef, i32 %{{.*}}, i32 inreg % + foo8(a, b); +} + +void __attribute__((fastcall)) foo9(struct S2 a, int b); +void bar9(struct S2 a, int b) { + // CHECK: define void @bar9 + // CHECK: call x86_fastcallcc void @foo9(%struct.S2* byval align 4 %{{.*}}, i32 % + foo9(a, b); +} + +void __attribute__((fastcall)) foo10(float y, int x); +void bar10(float y, int x) { + // CHECK: define void @bar10 + // CHECK: call x86_fastcallcc void @foo10(float %{{.*}}, i32 inreg % + foo10(y, x); +} + +void __attribute__((fastcall)) foo11(double y, int x); +void bar11(double y, int x) { + // CHECK: define void @bar11 + // CHECK: call x86_fastcallcc void @foo11(double %{{.*}}, i32 inreg % + foo11(y, x); +} + +struct S3 { + float x; +}; +void __attribute__((fastcall)) foo12(struct S3 y, int x); +void bar12(struct S3 y, int x) { + // CHECK: define void @bar12 + // CHECK: call x86_fastcallcc void @foo12(float %{{.*}}, i32 inreg % + foo12(y, x); +} diff --git a/test/CodeGen/tbaa-for-vptr.cpp b/test/CodeGen/tbaa-for-vptr.cpp index b9a68fe0eae1..93690361906b 100644 --- a/test/CodeGen/tbaa-for-vptr.cpp +++ b/test/CodeGen/tbaa-for-vptr.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -emit-llvm -o - -O0 -fthread-sanitizer %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -O0 -fsanitize=thread %s | FileCheck %s // RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -o - -O1 -relaxed-aliasing -fthread-sanitizer %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -O1 -relaxed-aliasing -fsanitize=thread %s | FileCheck %s // // RUN: %clang_cc1 -emit-llvm -o - -O0 %s | FileCheck %s --check-prefix=NOTBAA // RUN: %clang_cc1 -emit-llvm -o - -O2 -relaxed-aliasing %s | FileCheck %s --check-prefix=NOTBAA @@ -21,7 +21,7 @@ void CallFoo(A *a) { a->foo(); } -// CHECK: %{{.*}} = load {{.*}} !tbaa !0 -// CHECK: store {{.*}} !tbaa !0 -// CHECK: = metadata !{metadata !"vtable pointer", metadata !{{.*}}} +// CHECK: %{{.*}} = load {{.*}} !tbaa ![[NUM:[0-9]+]] +// CHECK: store {{.*}} !tbaa ![[NUM]] +// CHECK: [[NUM]] = metadata !{metadata !"vtable pointer", metadata !{{.*}}} // NOTBAA-NOT: = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp new file mode 100644 index 000000000000..8b30aa0a495a --- /dev/null +++ b/test/CodeGen/tbaa-struct.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s +// +// Check that we generate !tbaa.struct metadata for struct copies. +struct A { + short s; + int i; + char c; + int j; +}; + +void copy(struct A *a, struct A *b) { + *a = *b; +} + +// CHECK: target datalayout = "{{.*}}p:[[P:64|32]] +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]] +// CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}} diff --git a/test/CodeGen/trapv.c b/test/CodeGen/trapv.c index f52dad556485..bc8bc700636c 100644 --- a/test/CodeGen/trapv.c +++ b/test/CodeGen/trapv.c @@ -17,7 +17,8 @@ void test0() { // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 - // CHECK-NEXT: br i1 [[T5]] + // CHECK-NEXT: [[T6:%.*]] = xor i1 [[T5]], true + // CHECK-NEXT: br i1 [[T6]] // CHECK: call void @llvm.trap() i = j + k; } @@ -31,7 +32,8 @@ void test1() { // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 - // CHECK-NEXT: br i1 [[T4]] + // CHECK-NEXT: [[T5:%.*]] = xor i1 [[T4]], true + // CHECK-NEXT: br i1 [[T5]] // CHECK: call void @llvm.trap() } @@ -44,6 +46,16 @@ void test2() { // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 - // CHECK-NEXT: br i1 [[T4]] + // CHECK-NEXT: [[T5:%.*]] = xor i1 [[T4]], true + // CHECK-NEXT: br i1 [[T5]] // CHECK: call void @llvm.trap() } + +// CHECK: define void @test3( +void test3(int a, int b, float c, float d) { + // CHECK-NOT: @llvm.trap + (void)(a / b); + (void)(a % b); + (void)(c / d); + // CHECK: } +} diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c index c588ca8e1b60..7a79cb6047a1 100644 --- a/test/CodeGen/unwind-attr.c +++ b/test/CodeGen/unwind-attr.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fexceptions -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix NOEXC %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -fexceptions -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix NOEXC %s int opaque(); diff --git a/test/CodeGen/x86_64-arguments-nacl.c b/test/CodeGen/x86_64-arguments-nacl.c new file mode 100644 index 000000000000..8f756caba757 --- /dev/null +++ b/test/CodeGen/x86_64-arguments-nacl.c @@ -0,0 +1,120 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-nacl -emit-llvm -o - %s| FileCheck %s +#include <stdarg.h> +// Test for x86-64 structure representation (instead of pnacl representation), +// in particular for unions. Also crib a few tests from x86 Linux. + +union PP_VarValue { + int as_int; + double as_double; + long long as_i64; +}; + +struct PP_Var { + int type; + int padding; + union PP_VarValue value; +}; + +// CHECK: define { i64, i64 } @f0() +struct PP_Var f0() { + struct PP_Var result = { 0, 0, 0 }; + return result; +} + +// CHECK: define void @f1(i64 %p1.coerce0, i64 %p1.coerce1) +void f1(struct PP_Var p1) { while(1) {} } + +// long doubles are 64 bits on NaCl +// CHECK: define double @f5() +long double f5(void) { + return 0; +} + +// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4) +void f6(char a0, short a1, int a2, long long a3, void *a4) { +} + +// CHECK: define i64 @f8_1() +// CHECK: define void @f8_2(i64 %a0.coerce) +union u8 { + long double a; + int b; +}; +union u8 f8_1() { while (1) {} } +void f8_2(union u8 a0) {} + +// CHECK: define i64 @f9() +struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } + +// CHECK: define void @f10(i64 %a0.coerce) +struct s10 { int a; int b; int : 0; }; +void f10(struct s10 a0) {} + +// CHECK: define double @f11() +union { long double a; float b; } f11() { while (1) {} } + +// CHECK: define i32 @f12_0() +// CHECK: define void @f12_1(i32 %a0.coerce) +struct s12 { int a __attribute__((aligned(16))); }; +struct s12 f12_0(void) { while (1) {} } +void f12_1(struct s12 a0) {} + +// Check that sret parameter is accounted for when checking available integer +// registers. +// CHECK: define void @f13(%struct.s13_0* noalias sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f) + +struct s13_0 { long long f0[3]; }; +struct s13_1 { long long f0[2]; }; +struct s13_0 f13(int a, int b, int c, int d, + struct s13_1 e, int f) { while (1) {} } + +// CHECK: define void @f20(%struct.s20* byval align 32 %x) +struct __attribute__((aligned(32))) s20 { + int x; + int y; +}; +void f20(struct s20 x) {} + + +// CHECK: declare void @func(i64) +typedef struct _str { + union { + long double a; + long c; + }; +} str; + +void func(str s); +str ss; +void f9122143() +{ + func(ss); +} + + +typedef struct { + int a; + int b; +} s1; +// CHECK: define i32 @f48(%struct.s1* byval %s) +int __attribute__((pnaclcall)) f48(s1 s) { return s.a; } + +// CHECK: define void @f49(%struct.s1* noalias sret %agg.result) +s1 __attribute__((pnaclcall)) f49() { s1 s; s.a = s.b = 1; return s; } + +union simple_union { + int a; + char b; +}; +// Unions should be passed as byval structs +// CHECK: define void @f50(%union.simple_union* byval %s) +void __attribute__((pnaclcall)) f50(union simple_union s) {} + +typedef struct { + int b4 : 4; + int b3 : 3; + int b8 : 8; +} bitfield1; +// Bitfields should be passed as byval structs +// CHECK: define void @f51(%struct.bitfield1* byval %bf1) +void __attribute__((pnaclcall)) f51(bitfield1 bf1) {} |