diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
commit | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (patch) | |
tree | a9243275843fbeaa590afc07ee888e006b8d54ea /test/CodeGen | |
parent | 69b4eca4a4255ba43baa5c1d9bbdec3ec17f479e (diff) | |
download | FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.zip FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.tar.gz |
Vendor import of clang trunk r126079:
http://llvm.org/svn/llvm-project/cfe/trunk@126079
Diffstat (limited to 'test/CodeGen')
74 files changed, 3571 insertions, 179 deletions
diff --git a/test/CodeGen/2008-07-17-no-emit-on-error.c b/test/CodeGen/2008-07-17-no-emit-on-error.c index 0452325..855ede7 100644 --- a/test/CodeGen/2008-07-17-no-emit-on-error.c +++ b/test/CodeGen/2008-07-17-no-emit-on-error.c @@ -1,6 +1,7 @@ // RUN: rm -f %t1.bc // RUN: %clang_cc1 -DPASS %s -emit-llvm-bc -o %t1.bc // RUN: test -f %t1.bc +// RUN: rm -f %t1.bc // RUN: not %clang_cc1 %s -emit-llvm-bc -o %t1.bc // RUN: not test -f %t1.bc diff --git a/test/CodeGen/2008-07-29-override-alias-decl.c b/test/CodeGen/2008-07-29-override-alias-decl.c index dbe10b3..0c2d0c6 100644 --- a/test/CodeGen/2008-07-29-override-alias-decl.c +++ b/test/CodeGen/2008-07-29-override-alias-decl.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s int x() { return 1; } diff --git a/test/CodeGen/2010-03-09-DbgInfo.c b/test/CodeGen/2010-03-09-DbgInfo.c index 04ee02e..3541e5f 100644 --- a/test/CodeGen/2010-03-09-DbgInfo.c +++ b/test/CodeGen/2010-03-09-DbgInfo.c @@ -1,2 +1,2 @@ -// RUN: %clang -dA -S -O0 -g %s -o - | grep DW_TAG_variable +// RUN: %clang -emit-llvm -S -O0 -g %s -o - | grep DW_TAG_variable unsigned char ctable1[1] = { 0001 }; diff --git a/test/CodeGen/annotate.c b/test/CodeGen/annotate.c index 84d564a..ffaeebb 100644 --- a/test/CodeGen/annotate.c +++ b/test/CodeGen/annotate.c @@ -5,4 +5,6 @@ void a(char *a) { __attribute__((annotate("bar"))) static char bar; } +// CHECK: private unnamed_addr global +// CHECK: private unnamed_addr global // CHECK: @llvm.global.annotations = appending global [2 x %0] diff --git a/test/CodeGen/arm-vector-arguments.c b/test/CodeGen/arm-vector-arguments.c new file mode 100644 index 0000000..c5ac0a7 --- /dev/null +++ b/test/CodeGen/arm-vector-arguments.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple thumbv7-apple-darwin9 \ +// RUN: -target-abi apcs-gnu \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -mfloat-abi soft \ +// RUN: -target-feature +soft-float-abi \ +// RUN: -ffreestanding \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + +#include <arm_neon.h> + +// CHECK: define void @f0(%struct.int8x16x2_t* sret %agg.result, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) +int8x16x2_t f0(int8x16_t a0, int8x16_t a1) { + return vzipq_s8(a0, a1); +} + +// Test direct vector passing. + +typedef float T_float32x2 __attribute__ ((__vector_size__ (8))); +typedef float T_float32x4 __attribute__ ((__vector_size__ (16))); +typedef float T_float32x8 __attribute__ ((__vector_size__ (32))); +typedef float T_float32x16 __attribute__ ((__vector_size__ (64))); + +// CHECK: define <2 x float> @f1_0(<2 x float> %{{.*}}) +T_float32x2 f1_0(T_float32x2 a0) { return a0; } +// CHECK: define <4 x float> @f1_1(<4 x float> %{{.*}}) +T_float32x4 f1_1(T_float32x4 a0) { return a0; } +// CHECK: define void @f1_2(<8 x float>* sret %{{.*}}, <8 x float> %{{.*}}) +T_float32x8 f1_2(T_float32x8 a0) { return a0; } +// CHECK: define void @f1_3(<16 x float>* sret %{{.*}}, <16 x float> %{{.*}}) +T_float32x16 f1_3(T_float32x16 a0) { return a0; } diff --git a/test/CodeGen/asm-errors.c b/test/CodeGen/asm-errors.c index aea5cb2..c5b36c7 100644 --- a/test/CodeGen/asm-errors.c +++ b/test/CodeGen/asm-errors.c @@ -2,7 +2,7 @@ // RUN: FileCheck %s < %t int test1(int X) { -// CHECK: error: unrecognized instruction +// CHECK: error: invalid instruction mnemonic 'abc' __asm__ ("abc incl %0" : "+r" (X)); return X; } diff --git a/test/CodeGen/asm-inout.c b/test/CodeGen/asm-inout.c index f042766..5b0a5f7 100644 --- a/test/CodeGen/asm-inout.c +++ b/test/CodeGen/asm-inout.c @@ -17,3 +17,15 @@ void test2() { // CHECK: store i32 {{%[a-zA-Z0-9\.]+}}, i32* [[REGCALLRESULT]] asm ("foobar" : "+r"(*foo())); } + +// PR7338 +void test3(int *vout, int vin) +{ + // CHECK: call void asm "opr $0,$1", "=*r|m|r,r|m|r,~{di},~{dirflag},~{fpsr},~{flags}" +asm( + "opr %[vout],%[vin]" + : [vout] "=r,=m,=r" (*vout) + : [vin] "r,m,r" (vin) + : "edi" + ); +} diff --git a/test/CodeGen/asm-variable.c b/test/CodeGen/asm-variable.c new file mode 100644 index 0000000..a37132d --- /dev/null +++ b/test/CodeGen/asm-variable.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +unsigned long long foo(unsigned long long addr, unsigned long long a0, + unsigned long long a1, unsigned long long a2, + unsigned long long a3, unsigned long long a4, + unsigned long long a5) { + register unsigned long long result asm("rax"); + register unsigned long long b0 asm("rdi"); + register unsigned long long b1 asm("rsi"); + register unsigned long long b2 asm("rdx"); + register unsigned long long b3 asm("rcx"); + register unsigned long long b4 asm("r8"); + register unsigned long long b5 asm("r9"); + + b0 = a0; + b1 = a1; + b2 = a2; + b3 = a3; + b4 = a4; + b5 = a5; + + asm("call *%1" : "=r" (result) + : "r"(addr), "r" (b0), "r" (b1), "r" (b2), "r" (b3), "r" (b4), "r" (b5)); + return result; +} + +// CHECK: call i64 asm "call *$1", "={rax},r,{rdi},{rsi},{rdx},{rcx},{r8},{r9},~{dirflag},~{fpsr},~{flags}" + +unsigned long long foo2(unsigned long long addr, double a0, + double a1, double a2, + double a3, double a4, + double a5, double a6, double a7) { + register double b0 asm("xmm0"); + register double b1 asm("xmm1"); + register double b2 asm("xmm2"); + register double b3 asm("xmm3"); + register double b4 asm("xmm4"); + register double b5 asm("xmm5"); + register double b6 asm("xmm6"); + register double b7 asm("xmm7"); + + register unsigned long long result asm("rax"); + + b0 = a0; + b1 = a1; + b2 = a2; + b3 = a3; + b4 = a4; + b5 = a5; + b6 = a6; + b7 = a7; + + asm("call *%1" : "=r" (result) + : "r"(addr), "x" (b0), "x" (b1), "x" (b2), "x" (b3), "x" (b4), "x" (b5), "x" (b6), + "x" (b7)); + return result; +} + +// CHECK: call i64 asm "call *$1", "={rax},r,{xmm0},{xmm1},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},~{dirflag},~{fpsr},~{flags} diff --git a/test/CodeGen/assign.c b/test/CodeGen/assign.c index eab3d35..05141bb 100644 --- a/test/CodeGen/assign.c +++ b/test/CodeGen/assign.c @@ -15,15 +15,15 @@ void f0() { y = (x = 1); } -// Check that we do generate reloads for volatile access. +// This used to test that we generate reloads for volatile access, +// but that does not appear to be correct behavior for C. // // CHECK: define void @f1() // CHECK: [[x_1:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[y_1:%.*]] = alloca i32, align 4 // CHECK-NEXT: volatile store i32 1, i32* [[x_1]] // CHECK-NEXT: volatile store i32 1, i32* [[x_1]] -// CHECK-NEXT: [[tmp_1:%.*]] = volatile load i32* [[x_1]] -// CHECK-NEXT: volatile store i32 [[tmp_1]], i32* [[y_1]] +// CHECK-NEXT: volatile store i32 1, i32* [[y_1]] // CHECK: } void f1() { volatile int x, y; diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c index d0a7e04..4a7c13f 100644 --- a/test/CodeGen/atomic.c +++ b/test/CodeGen/atomic.c @@ -1,20 +1,6 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 > %t1 -// RUN: grep @llvm.memory.barrier %t1 | count 42 -// RUN: grep @llvm.atomic.load.add.i32 %t1 | count 3 -// RUN: grep @llvm.atomic.load.sub.i8 %t1 | count 2 -// RUN: grep @llvm.atomic.load.min.i32 %t1 -// RUN: grep @llvm.atomic.load.max.i32 %t1 -// RUN: grep @llvm.atomic.load.umin.i32 %t1 -// RUN: grep @llvm.atomic.load.umax.i32 %t1 -// RUN: grep @llvm.atomic.swap.i32 %t1 -// RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 5 -// RUN: grep @llvm.atomic.load.and.i32 %t1 -// RUN: grep @llvm.atomic.load.or.i8 %t1 -// RUN: grep @llvm.atomic.load.xor.i8 %t1 - - -int atomic(void) -{ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s + +int atomic(void) { // non-sensical test for sync functions int old; int val = 1; @@ -24,38 +10,144 @@ int atomic(void) int cmp = 0; old = __sync_fetch_and_add(&val, 1); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.add.i32.p0i32(i32* %val, i32 1) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_sub(&valc, 2); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i8 @llvm.atomic.load.sub.i8.p0i8(i8* %valc, i8 2) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_min(&val, 3); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.min.i32.p0i32(i32* %val, i32 3) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_max(&val, 4); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.max.i32.p0i32(i32* %val, i32 4) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_umin(&uval, 5u); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.umin.i32.p0i32(i32* %uval, i32 5) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_umax(&uval, 6u); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.umax.i32.p0i32(i32* %uval, i32 6) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_lock_test_and_set(&val, 7); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.swap.i32.p0i32(i32* %val, i32 7) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_val_compare_and_swap(&val, 4, 1976); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* %val, i32 4, i32 1976) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_bool_compare_and_swap(&val, 4, 1976); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* %val, i32 4, i32 1976) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_and(&val, 0x9); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.and.i32.p0i32(i32* %val, i32 9) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_or(&val, 0xa); - old = __sync_fetch_and_xor(&val, 0xb); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.or.i32.p0i32(i32* %val, i32 10) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_fetch_and_xor(&val, 0xb); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.xor.i32.p0i32(i32* %val, i32 11) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_add_and_fetch(&val, 1); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.add.i32.p0i32(i32* %val, i32 1) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_sub_and_fetch(&val, 2); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %val, i32 2) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_and_and_fetch(&valc, 3); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i8 @llvm.atomic.load.and.i8.p0i8(i8* %valc, i8 3) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_or_and_fetch(&valc, 4); - old = __sync_xor_and_fetch(&valc, 5); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i8 @llvm.atomic.load.or.i8.p0i8(i8* %valc, i8 4) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + old = __sync_xor_and_fetch(&valc, 5); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i8 @llvm.atomic.load.xor.i8.p0i8(i8* %valc, i8 5) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* null, i32 0, i32 0) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + if ( __sync_val_compare_and_swap(&valb, 0, 1)) { + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* %valb, i8 0, i8 1) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) old = 42; } + __sync_bool_compare_and_swap((void **)0, (void *)0, (void *)0); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* null, i32 0, i32 0) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) __sync_lock_release(&val); + // CHECK: volatile store i32 0, i32* + __sync_synchronize (); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false) return old; } +// CHECK: @release_return void release_return(int *lock) { // Ensure this is actually returning void all the way through. return __sync_lock_release(lock); + // CHECK: volatile store i32 0, i32* +} + + +// rdar://8461279 - Atomics with address spaces. +// CHECK: @addrspace +void addrspace(int __attribute__((address_space(256))) * P) { + __sync_bool_compare_and_swap(P, 0, 1); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p256i32(i32 addrspace(256)*{{.*}}, i32 0, i32 1) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + + + __sync_val_compare_and_swap(P, 0, 1); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p256i32(i32 addrspace(256)*{{.*}}, i32 0, i32 1) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + + + __sync_xor_and_fetch(P, 123); + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + // CHECK: call i32 @llvm.atomic.load.xor.i32.p256i32(i32 addrspace(256)* {{.*}}, i32 123) + // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + } + diff --git a/test/CodeGen/attr-naked.c b/test/CodeGen/attr-naked.c new file mode 100644 index 0000000..bccacc9 --- /dev/null +++ b/test/CodeGen/attr-naked.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -g -emit-llvm -o %t %s +// RUN: grep 'naked' %t + +void t1() __attribute__((naked)); + +void t1() +{ +} + diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index 71b4de8..350f7a3 100644 --- a/test/CodeGen/blocks-1.c +++ b/test/CodeGen/blocks-1.c @@ -1,9 +1,9 @@ // RUN: %clang_cc1 %s -emit-llvm -o %t -fblocks // RUN: grep "_Block_object_dispose" %t | count 17 -// RUN: grep "__copy_helper_block_" %t | count 16 -// RUN: grep "__destroy_helper_block_" %t | count 16 -// RUN: grep "__Block_byref_id_object_copy_" %t | count 2 -// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 +// RUN: grep "__copy_helper_block_" %t | count 14 +// RUN: grep "__destroy_helper_block_" %t | count 14 +// RUN: grep "__Block_byref_object_copy_" %t | count 2 +// RUN: grep "__Block_byref_object_dispose_" %t | count 2 // RUN: grep "i32 135)" %t | count 2 // RUN: grep "_Block_object_assign" %t | count 10 @@ -14,7 +14,7 @@ void test1() { int b=2; a=1; printf("a is %d, b is %d\n", a, b); - ^{ a = 10; printf("a is %d, b is %d\n", a, b); }(); + ^{ a = 10; printf("a is %d, b is %d\n", a, b); }(); // needs copy/dispose printf("a is %d, b is %d\n", a, b); a = 1; printf("a is %d, b is %d\n", a, b); @@ -24,8 +24,8 @@ void test2() { __block int a; a=1; printf("a is %d\n", a); - ^{ - ^{ + ^{ // needs copy/dispose + ^{ // needs copy/dispose a = 10; }(); }(); @@ -37,13 +37,13 @@ void test2() { void test3() { __block int k; __block int (^j)(int); - ^{j=0; k=0;}(); + ^{j=0; k=0;}(); // needs copy/dispose } int test4() { extern int g; static int i = 1; - ^(int j){ i = j; g = 0; }(0); + ^(int j){ i = j; g = 0; }(0); // does not need copy/dispose return i + g; } @@ -51,19 +51,19 @@ int g; void test5() { __block struct { int i; } i; - ^{ (void)i; }(); + ^{ (void)i; }(); // needs copy/dispose } void test6() { __block int i; - ^{ i=1; }(); - ^{}(); + ^{ i=1; }(); // needs copy/dispose + ^{}(); // does not need copy/dispose } void test7() { - ^{ + ^{ // does not need copy/dispose __block int i; - ^{ i = 1; }(); + ^{ i = 1; }(); // needs copy/dispose }(); } diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c index 6888356..b7b6a2d 100644 --- a/test/CodeGen/blocks.c +++ b/test/CodeGen/blocks.c @@ -33,3 +33,10 @@ typedef double ftype(double); ftype ^test2 = ^ftype { return 0; }; + +// rdar://problem/8605032 +void f3_helper(void (^)(void)); +void f3() { + _Bool b = 0; + f3_helper(^{ if (b) {} }); +} diff --git a/test/CodeGen/blocksignature.c b/test/CodeGen/blocksignature.c index 6ed8750..7526f19 100644 --- a/test/CodeGen/blocksignature.c +++ b/test/CodeGen/blocksignature.c @@ -1,14 +1,16 @@ // RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64 // RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32 -// X64: @.str = private constant [6 x i8] c"v8@?0\00" +// X64: @.str = private unnamed_addr constant [6 x i8] c"v8@?0\00" // X64: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280, -// X64: @.str1 = private constant [12 x i8] c"i16@?0c8f12\00" +// X64: @.str1 = private unnamed_addr constant [12 x i8] c"i16@?0c8f12\00" // X64: store i32 1073741824, i32* -// X32: @.str = private constant [6 x i8] c"v4@?0\00" -// X32: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280, -// X32: @.str1 = private constant [11 x i8] c"i12@?0c4f8\00" +// X32: [[STR1:@.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00" +// X32: @__block_descriptor_tmp = internal constant [[FULL_DESCRIPTOR_T:%.*]] { i32 0, i32 20, i8* getelementptr inbounds ([6 x i8]* [[STR1]], i32 0, i32 0), i8* null } +// X32: @__block_literal_global = internal constant [[GLOBAL_LITERAL_T:%.*]] { i8** @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8* bitcast (void (i8*)* @__block_global_{{.*}} to i8*), [[DESCRIPTOR_T:%.*]]* bitcast ([[FULL_DESCRIPTOR_T]]* @__block_descriptor_tmp to {{%.*}}*) } +// X32: [[STR2:@.*]] = private unnamed_addr constant [11 x i8] c"i12@?0c4f8\00" +// X32: @__block_descriptor_tmp{{.*}} = internal constant [[FULL_DESCRIPTOR_T]] { i32 0, i32 24, i8* getelementptr inbounds ([11 x i8]* [[STR2]], i32 0, i32 0), i8* null } // X32: store i32 1073741824, i32* // rdar://7635294 diff --git a/test/CodeGen/blockstret.c b/test/CodeGen/blockstret.c index f630f22..e49b52a 100644 --- a/test/CodeGen/blockstret.c +++ b/test/CodeGen/blockstret.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64 // RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32 -// X64: internal constant %2 { i8** @_NSConcreteGlobalBlock, i32 1879048192 +// X64: internal constant {{%.*}} { i8** @_NSConcreteGlobalBlock, i32 1879048192 // X64: store i32 1610612736, i32* %want // X32: @_NSConcreteGlobalBlock, i32 1879048192, i32 0, diff --git a/test/CodeGen/blockwithlocalstatic.c b/test/CodeGen/blockwithlocalstatic.c new file mode 100644 index 0000000..1fdaaf37a --- /dev/null +++ b/test/CodeGen/blockwithlocalstatic.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -emit-llvm -o - %s | FileCheck %s +// pr8707 + +// CHECK: @__block_global_0.test = internal global i32 +int (^block)(void) = ^ { + static int test=0; + return test; +}; +// CHECK: @__block_global_1.test = internal global i32 +void (^block1)(void) = ^ { + static int test = 2; + return; +}; +// CHECK: @__block_global_2.test = internal global i32 +int (^block2)(void) = ^ { + static int test = 5; + return test; +}; + diff --git a/test/CodeGen/bool_test.c b/test/CodeGen/bool_test.c new file mode 100644 index 0000000..ffaaef8 --- /dev/null +++ b/test/CodeGen/bool_test.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple powerpc-apple-darwin -emit-llvm -o - %s| FileCheck -check-prefix=DARWINPPC-CHECK %s + +int boolsize = sizeof(_Bool); +//DARWINPPC-CHECK: boolsize = global i32 4, align 4 + diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c index 8627499..e03e69c 100644 --- a/test/CodeGen/builtins-ppc-altivec.c +++ b/test/CodeGen/builtins-ppc-altivec.c @@ -32,7 +32,13 @@ int param_i; unsigned int param_ui; float param_f; +int res_sc; +int res_uc; +int res_s; +int res_us; int res_i; +int res_ui; +int res_f; // CHECK: define void @test1 void test1() { @@ -1761,9 +1767,958 @@ void test6() { res_vf = vec_vxor(vbi, vf); // CHECK: xor <4 x i32> res_vf = vec_vxor(vf, vbi); // CHECK: xor <4 x i32> + /* ------------------------------ extensions -------------------------------------- */ + + /* vec_extract */ + res_sc = vec_extract(vsc, param_i); // CHECK: extractelement <16 x i8> + res_uc = vec_extract(vuc, param_i); // CHECK: extractelement <16 x i8> + res_s = vec_extract(vs, param_i); // CHECK: extractelement <8 x i16> + res_us = vec_extract(vus, param_i); // CHECK: extractelement <8 x i16> + res_i = vec_extract(vi, param_i); // CHECK: extractelement <4 x i32> + res_ui = vec_extract(vui, param_i); // CHECK: extractelement <4 x i32> + res_f = vec_extract(vf, param_i); // CHECK: extractelement <4 x float> + + /* vec_insert */ + res_vsc = vec_insert(param_sc, vsc, param_i); // CHECK: insertelement <16 x i8> + res_vuc = vec_insert(param_uc, vuc, param_i); // CHECK: insertelement <16 x i8> + res_vs = vec_insert(param_s, vs, param_i); // CHECK: insertelement <8 x i16> + res_vus = vec_insert(param_us, vus, param_i); // CHECK: insertelement <8 x i16> + res_vi = vec_insert(param_i, vi, param_i); // CHECK: insertelement <4 x i32> + res_vui = vec_insert(param_ui, vui, param_i); // CHECK: insertelement <4 x i32> + res_vf = vec_insert(param_f, vf, param_i); // CHECK: insertelement <4 x float> + + /* vec_lvlx */ + res_vsc = vec_lvlx(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvlx(0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlx(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlx(0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvlx(0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlx(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlx(0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlx(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlx(0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvlx(0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvlx(0, &vp); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlx(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlx(0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlx(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlx(0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvlx(0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvlx(0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_lvlxl */ + res_vsc = vec_lvlxl(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvlxl(0, &vsc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlxl(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlxl(0, &vuc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvlxl(0, &vbc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlxl(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlxl(0, &vs); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlxl(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlxl(0, &vus); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvlxl(0, &vbs); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvlxl(0, &vp); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlxl(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlxl(0, &vi); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlxl(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlxl(0, &vui); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvlxl(0, &vbi); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvlxl(0, &vf); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_lvrx */ + res_vsc = vec_lvrx(0, ¶m_sc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvrx(0, &vsc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrx(0, ¶m_uc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrx(0, &vuc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvrx(0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrx(0, ¶m_s); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrx(0, &vs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrx(0, ¶m_us); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrx(0, &vus); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvrx(0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvrx(0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrx(0, ¶m_i); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrx(0, &vi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrx(0, ¶m_ui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrx(0, &vui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvrx(0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvrx(0, &vf); // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_lvrxl */ + res_vsc = vec_lvrxl(0, ¶m_sc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvrxl(0, &vsc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrxl(0, ¶m_uc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrxl(0, &vuc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvrxl(0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrxl(0, ¶m_s); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrxl(0, &vs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrxl(0, ¶m_us); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrxl(0, &vus); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvrxl(0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvrxl(0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrxl(0, ¶m_i); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrxl(0, &vi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrxl(0, ¶m_ui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrxl(0, &vui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvrxl(0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvrxl(0, &vf); // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_stvlx */ + vec_stvlx(vsc, 0, ¶m_sc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vsc, 0, &vsc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vuc, 0, ¶m_uc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vuc, 0, &vuc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vbc, 0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vs, 0, ¶m_s); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vs, 0, &vs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vus, 0, ¶m_us); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vus, 0, &vus); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vbs, 0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vp, 0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vi, 0, ¶m_i); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vi, 0, &vi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vui, 0, ¶m_ui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vui, 0, &vui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vbi, 0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vf, 0, &vf); // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + /* vec_stvlxl */ + vec_stvlxl(vsc, 0, ¶m_sc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vsc, 0, &vsc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vuc, 0, ¶m_uc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vuc, 0, &vuc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vbc, 0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vs, 0, ¶m_s); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vs, 0, &vs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vus, 0, ¶m_us); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vus, 0, &vus); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vbs, 0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vp, 0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vi, 0, ¶m_i); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vi, 0, &vi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vui, 0, ¶m_ui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vui, 0, &vui); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vbi, 0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vf, 0, &vf); // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + /* vec_stvrx */ + vec_stvrx(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + /* vec_stvrxl */ + vec_stvrxl(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + /* vec_promote */ + res_vsc = vec_promote(param_sc, 0); // CHECK: store <16 x i8> zeroinitializer + // CHECK: insertelement <16 x i8> + + res_vuc = vec_promote(param_uc, 0); // CHECK: store <16 x i8> zeroinitializer + // CHECK: insertelement <16 x i8> + + res_vs = vec_promote(param_s, 0); // CHECK: store <8 x i16> zeroinitializer + // CHECK: insertelement <8 x i16> + + res_vus = vec_promote(param_us, 0); // CHECK: store <8 x i16> zeroinitializer + // CHECK: insertelement <8 x i16> + + res_vi = vec_promote(param_i, 0); // CHECK: store <4 x i32> zeroinitializer + // CHECK: insertelement <4 x i32> + + res_vui = vec_promote(param_ui, 0); // CHECK: store <4 x i32> zeroinitializer + // CHECK: insertelement <4 x i32> + + res_vf = vec_promote(param_f, 0); // CHECK: store <4 x float> zeroinitializer + // CHECK: insertelement <4 x float> + + /* vec_splats */ + res_vsc = vec_splats(param_sc); // CHECK: insertelement <16 x i8> + + res_vuc = vec_splats(param_uc); // CHECK: insertelement <16 x i8> + + res_vs = vec_splats(param_s); // CHECK: insertelement <8 x i16> + + res_vus = vec_splats(param_us); // CHECK: insertelement <8 x i16> + + res_vi = vec_splats(param_i); // CHECK: insertelement <4 x i32> + + res_vui = vec_splats(param_ui); // CHECK: insertelement <4 x i32> + + res_vf = vec_splats(param_f); // CHECK: insertelement <4 x float> + /* ------------------------------ predicates -------------------------------------- */ - /* vec_all_eq */ + /* vec_all_eq */ res_i = vec_all_eq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p res_i = vec_all_eq(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p res_i = vec_all_eq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p @@ -2097,3 +3052,75 @@ void test6() { /* vec_any_out */ res_i = vec_any_out(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp.p } + +/* ------------------------------ Relational Operators------------------------------- */ +// CHECK: define void @test7 +void test7() { + vector signed char vsc1 = (vector signed char)(-1); + vector signed char vsc2 = (vector signed char)(-2); + res_i = (vsc1 == vsc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2 + res_i = (vsc1 != vsc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0 + res_i = (vsc1 < vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2 + res_i = (vsc1 > vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2 + res_i = (vsc1 <= vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0 + res_i = (vsc1 >= vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0 + vector unsigned char vuc1 = (vector unsigned char)(1); + vector unsigned char vuc2 = (vector unsigned char)(2); + res_i = (vuc1 == vuc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2 + res_i = (vuc1 != vuc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0 + res_i = (vuc1 < vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2 + res_i = (vuc1 > vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2 + res_i = (vuc1 <= vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0 + res_i = (vuc1 >= vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0 + vector short vs1 = (vector short)(-1); + vector short vs2 = (vector short)(-2); + res_i = (vs1 == vs2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2 + res_i = (vs1 != vs2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0 + res_i = (vs1 < vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2 + res_i = (vs1 > vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2 + res_i = (vs1 <= vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0 + res_i = (vs1 >= vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0 + vector unsigned short vus1 = (vector unsigned short)(1); + vector unsigned short vus2 = (vector unsigned short)(2); + res_i = (vus1 == vus2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2 + res_i = (vus1 != vus2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0 + res_i = (vus1 < vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2 + res_i = (vus1 > vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2 + res_i = (vus1 <= vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0 + res_i = (vus1 >= vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0 + vector int vi1 = (vector int)(-1); + vector int vi2 = (vector int)(-2); + res_i = (vi1 == vi2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2 + res_i = (vi1 != vi2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0 + res_i = (vi1 < vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2 + res_i = (vi1 > vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2 + res_i = (vi1 <= vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0 + res_i = (vi1 >= vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0 + vector unsigned int vui1 = (vector unsigned int)(1); + vector unsigned int vui2 = (vector unsigned int)(2); + res_i = (vui1 == vui2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2 + res_i = (vui1 != vui2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0 + res_i = (vui1 < vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2 + res_i = (vui1 > vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2 + res_i = (vui1 <= vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0 + res_i = (vui1 >= vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0 + vector float vf1 = (vector float)(1.0); + vector float vf2 = (vector float)(2.0); + res_i = (vf1 == vf2); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2 + res_i = (vf1 != vf2); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0 + res_i = (vf1 < vf2); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2 + res_i = (vf1 > vf2); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2 + res_i = (vf1 <= vf2); // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2 + res_i = (vf1 >= vf2); // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2 +} + +/* ------------------------------- increment/decrement: ----------------------------- */ +// CHECK: define void @test8 +void test8() { + vector int vi; + vi++; // CHECK: add nsw <4 x i32> {{.*}} <i32 1, i32 1, i32 1, i32 1> + vector unsigned int vui; + --vui; // CHECK: add <4 x i32> {{.*}} <i32 -1, i32 -1, i32 -1, i32 -1> + vector float vf; + vf++; // CHECK: fadd <4 x float> {{.*}} <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}> +} diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c index 1b4e68b..56f220b 100644 --- a/test/CodeGen/builtins-x86.c +++ b/test/CodeGen/builtins-x86.c @@ -261,6 +261,7 @@ void f0() { tmp_V8c = __builtin_ia32_packsswb(tmp_V4s, tmp_V4s); tmp_V4s = __builtin_ia32_packssdw(tmp_V2i, tmp_V2i); tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s); + tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, 0); (void) __builtin_ia32_ldmxcsr(tmp_Ui); tmp_Ui = __builtin_ia32_stmxcsr(); diff --git a/test/CodeGen/char-literal.c b/test/CodeGen/char-literal.c new file mode 100644 index 0000000..aff76d2 --- /dev/null +++ b/test/CodeGen/char-literal.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -x c++ -triple i386-unknown-unkown -emit-llvm %s -o - | FileCheck %s +// Runs in c++ mode so that wchar_t is available. + +int main() { + // CHECK: store i8 97 + char a = 'a'; + + // Should pick second character. + // CHECK: store i8 98 + char b = 'ab'; + + // CHECK: store i32 97 + wchar_t wa = L'a'; + + // Should pick second character. + // CHECK: store i32 98 + wchar_t wb = L'ab'; + + // Should pick last character and store its lowest byte. + // This does not match gcc, which takes the last character, converts it to + // utf8, and then picks the second-lowest byte of that (they probably store + // the utf8 in uint16_ts internally and take the lower byte of that). + // CHECK: store i8 48 + char c = '\u1120\u0220\U00102030'; + + // CHECK: store i32 61451 + wchar_t wc = L'\uF00B'; + + // CHECK: store i32 1110027 + wchar_t wd = L'\U0010F00B'; + + // Should pick second character. + // CHECK: store i32 1110027 + wchar_t we = L'\u1234\U0010F00B'; +} diff --git a/test/CodeGen/conditional-gnu-ext.c b/test/CodeGen/conditional-gnu-ext.c index f4ac81b..2e32d3a 100644 --- a/test/CodeGen/conditional-gnu-ext.c +++ b/test/CodeGen/conditional-gnu-ext.c @@ -10,3 +10,27 @@ float test(float x, int Y) { return Y != 0 ? : x; } +// rdar://8446940 +extern void abort(); +void test1 () { + char x[1]; + char *y = x ? : 0; + + if (x != y) + abort(); +} + +// rdar://8453812 +_Complex int getComplex(_Complex int val) { + static int count; + if (count++) + abort(); + return val; +} + +_Complex int complx() { + _Complex int cond; + _Complex int rhs; + + return getComplex(1+2i) ? : rhs; +} diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c index ac26b65..32b762d 100644 --- a/test/CodeGen/const-init.c +++ b/test/CodeGen/const-init.c @@ -118,7 +118,7 @@ struct g23 {char a; short b; char c; struct g22 d;}; struct g23 g24 = {1,2,3,4}; // CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8]* @__func__.g25, i32 0, i32 0) -// CHECK: @__func__.g25 = private constant [4 x i8] c"g25\00" +// CHECK: @__func__.g25 = private unnamed_addr constant [4 x i8] c"g25\00" int g25() { static const char *g26 = __func__; return *g26; diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c index 8734295..ef5601e 100644 --- a/test/CodeGen/darwin-string-literals.c +++ b/test/CodeGen/darwin-string-literals.c @@ -1,14 +1,14 @@ // RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix LSB %s -// CHECK-LSB: @.str = private constant [8 x i8] c"string0\00" -// CHECK-LSB: @.str1 = private constant [8 x i8] c"string1\00" -// CHECK-LSB: @.str2 = internal constant [36 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00\00", align 2 +// CHECK-LSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" +// CHECK-LSB: @.str1 = private unnamed_addr constant [8 x i8] c"string1\00" +// CHECK-LSB: @.str2 = internal unnamed_addr constant [36 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00\00", align 2 // RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix MSB %s -// CHECK-MSB: @.str = private constant [8 x i8] c"string0\00" -// CHECK-MSB: @.str1 = private constant [8 x i8] c"string1\00" -// CHECK-MSB: @.str2 = internal constant [36 x i8] c"\00h\00e\00l\00l\00o\00 !\92\00 &\03\00 !\90\00 \00w\00o\00r\00l\00d\00\00", align 2 +// CHECK-MSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" +// CHECK-MSB: @.str1 = private unnamed_addr constant [8 x i8] c"string1\00" +// CHECK-MSB: @.str2 = internal unnamed_addr constant [36 x i8] c"\00h\00e\00l\00l\00o\00 !\92\00 &\03\00 !\90\00 \00w\00o\00r\00l\00d\00\00", align 2 const char *g0 = "string0"; const void *g1 = __builtin___CFStringMakeConstantString("string1"); diff --git a/test/CodeGen/debug-info-crash.c b/test/CodeGen/debug-info-crash.c index e0c9dd4..8d6a360 100644 --- a/test/CodeGen/debug-info-crash.c +++ b/test/CodeGen/debug-info-crash.c @@ -19,3 +19,12 @@ dispatch_item_t LEGACY_dispatch_call(dispatch_queue_t dq, } ); } + +// radar://9008853 +typedef struct P { + int x; +} PS; +# 1 "" +void foo() { + PS p2; +} diff --git a/test/CodeGen/debug-info-line.c b/test/CodeGen/debug-info-line.c new file mode 100644 index 0000000..b255d90 --- /dev/null +++ b/test/CodeGen/debug-info-line.c @@ -0,0 +1,15 @@ +// RUN: %clang -emit-llvm -S -g %s -o %t +// RUN: grep DW_TAG_lexical_block %t | count 3 + +// Radar 8396182 +// There are three lexical blocks in this test case. + +int foo() { + int i = 1; +# 4 "m.c" +# 1 "m.h" 1 + int j = 2; +# 2 "m.h" +# 5 "m.c" 2 + return i + j; +} diff --git a/test/CodeGen/debug-info-var-location.c b/test/CodeGen/debug-info-var-location.c new file mode 100644 index 0000000..12edb08 --- /dev/null +++ b/test/CodeGen/debug-info-var-location.c @@ -0,0 +1,21 @@ +// RUN: %clang -S -g -fverbose-asm %s -o - | FileCheck %s +// Radar 8461032 +// CHECK: DW_AT_location +// CHECK-NEXT: byte 145 + +// 145 is DW_OP_fbreg +struct s { + int a; + struct s *next; +}; + +int foo(struct s *s) { + switch (s->a) { + case 1: + case 2: { + struct s *sp = s->next; + } + break; + } + return 1; +} diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c index 312d785..d928296 100644 --- a/test/CodeGen/designated-initializers.c +++ b/test/CodeGen/designated-initializers.c @@ -19,6 +19,39 @@ int b[2] = { [1] = 22 }; +// PR6955 + +struct ds { + struct { + struct { + short a; + }; + short b; + struct { + short c; + }; + }; +}; + +// Traditional C anonymous member init +struct ds ds0 = { { { .a = 0 } } }; +// C1X lookup-based anonymous member init cases +struct ds ds1 = { { .a = 1 } }; +struct ds ds2 = { { .b = 1 } }; +struct ds ds3 = { .a = 0 }; +// CHECK: @ds4 = global %3 { %4 { %struct.anon zeroinitializer, i16 0, %struct.anon { i16 1 } } } +struct ds ds4 = { .c = 1 }; +struct ds ds5 = { { { .a = 0 } }, .b = 1 }; +struct ds ds6 = { { .a = 0, .b = 1 } }; +// CHECK: @ds7 = global %3 { %4 { %struct.anon { i16 2 }, i16 3, %struct.anon zeroinitializer } } +struct ds ds7 = { + { { + .a = 1 + } }, + .a = 2, + .b = 3 +}; + void test1(int argc, char **argv) { // CHECK: internal global %struct.foo { i8* null, i32 1024 } diff --git a/test/CodeGen/enum.c b/test/CodeGen/enum.c index 87b0e1e..0e239f1 100644 --- a/test/CodeGen/enum.c +++ b/test/CodeGen/enum.c @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown %s -O3 -emit-llvm -o - | grep 'ret i32 6' // RUN: %clang_cc1 -triple i386-unknown-unknown -x c++ %s -O3 -emit-llvm -o - | grep 'ret i32 7' +// This test case illustrates a peculiarity of the promotion of +// enumeration types in C and C++. In particular, the enumeration type +// "z" below promotes to an unsigned int in C but int in C++. static enum { foo, bar = 1U } z; int main (void) diff --git a/test/CodeGen/exceptions.c b/test/CodeGen/exceptions.c new file mode 100644 index 0000000..018b975 --- /dev/null +++ b/test/CodeGen/exceptions.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fexceptions -fblocks | FileCheck %s +// RUN: %clang_cc1 -triple armv7-apple-unknown -emit-llvm -o - %s -fexceptions -fsjlj-exceptions -fblocks | FileCheck %s -check-prefix=CHECK-ARM + +// rdar://problem/8621849 +void test1() { + extern void test1_helper(void (^)(int)); + + // CHECK: define void @test1() + // CHECK-ARM: define arm_aapcscc void @test1() + + __block int x = 10; + + // CHECK: invoke void @test1_helper( + // CHECK-ARM: invoke arm_aapcscc void @test1_helper( + test1_helper(^(int v) { x = v; }); + + // CHECK: call {{.*}} @llvm.eh.selector({{.*}}, i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*) + // CHECK-ARM: call {{.*}} @llvm.eh.selector({{.*}}, i8* bitcast (i32 (...)* @__gcc_personality_sj0 to i8*) +} diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index c9978b8..cc03be6 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -147,8 +147,30 @@ double f13(double X) { } // Check operations on incomplete types. -struct s14; -void f14(struct s13 *a) { +void f14(struct s14 *a) { (void) &*a; } +// CHECK: define void @f15 +void f15() { + extern void f15_start(void); + f15_start(); + // CHECK: call void @f15_start() + + extern void *f15_v(void); + extern const void *f15_cv(void); + extern volatile void *f15_vv(void); + *f15_v(); *f15_v(), *f15_v(); f15_v() ? *f15_v() : *f15_v(); + *f15_cv(); *f15_cv(), *f15_cv(); f15_cv() ? *f15_cv() : *f15_cv(); + *f15_vv(); *f15_vv(), *f15_vv(); f15_vv() ? *f15_vv() : *f15_vv(); + // CHECK-NOT: load + // CHECK: ret void +} + +// PR8967: this was crashing +// CHECK: define void @f16() +void f16() { + __extension__({ goto lbl; }); + lbl: + ; +} diff --git a/test/CodeGen/ext-vector-shuffle.c b/test/CodeGen/ext-vector-shuffle.c deleted file mode 100644 index 1d147a3..0000000 --- a/test/CodeGen/ext-vector-shuffle.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 %s -x cl -emit-llvm -o - | not grep 'extractelement' -// RUN: %clang_cc1 %s -x cl -emit-llvm -o - | not grep 'insertelement' -// RUN: %clang_cc1 %s -x cl -emit-llvm -o - | grep 'shufflevector' - -typedef __attribute__(( ext_vector_type(2) )) float float2; -typedef __attribute__(( ext_vector_type(4) )) float float4; - -float2 test1(float4 V) { - return V.xy + V.wz; -} - -float4 test2(float4 V) { - float2 W = V.ww; - return W.xyxy + W.yxyx; -} - -float4 test3(float4 V1, float4 V2) { return (float4)(V1.zw, V2.xy); } diff --git a/test/CodeGen/frame-pointer-elim.c b/test/CodeGen/frame-pointer-elim.c index 79c0599..e9dc22b 100644 --- a/test/CodeGen/frame-pointer-elim.c +++ b/test/CodeGen/frame-pointer-elim.c @@ -1,13 +1,22 @@ -// RUN: %clang -ccc-host-triple i386 -S -o - %s | \ -// RUN: FileCheck --check-prefix=DEFAULT %s -// DEFAULT: f0: -// DEFAULT: pushl %ebp -// DEFAULT: ret -// DEFAULT: f1: -// DEFAULT: pushl %ebp -// DEFAULT: ret +// RUN: %clang -ccc-host-triple i386-apple-darwin -S -o - %s | \ +// RUN: FileCheck --check-prefix=DARWIN %s +// DARWIN: f0: +// DARWIN: pushl %ebp +// DARWIN: ret +// DARWIN: f1: +// DARWIN: pushl %ebp +// DARWIN: ret -// RUN: %clang -ccc-host-triple i386 -S -o - -fomit-frame-pointer %s | \ +// RUN: %clang -ccc-host-triple i386-pc-linux-gnu -S -o - %s | \ +// RUN: FileCheck --check-prefix=LINUX %s +// LINUX: f0: +// LINUX-NOT: pushl %ebp +// LINUX: ret +// LINUX: f1: +// LINUX: pushl %ebp +// LINUX: ret + +// RUN: %clang -ccc-host-triple i386-darwin -S -o - -fomit-frame-pointer %s | \ // RUN: FileCheck --check-prefix=OMIT_ALL %s // OMIT_ALL: f0: // OMIT_ALL-NOT: pushl %ebp @@ -16,7 +25,7 @@ // OMIT_ALL-NOT: pushl %ebp // OMIT_ALL: ret -// RUN: %clang -ccc-host-triple i386 -S -o - -momit-leaf-frame-pointer %s | \ +// RUN: %clang -ccc-host-triple i386-darwin -S -o - -momit-leaf-frame-pointer %s | \ // RUN: FileCheck --check-prefix=OMIT_LEAF %s // OMIT_LEAF: f0: // OMIT_LEAF-NOT: pushl %ebp diff --git a/test/CodeGen/func-in-block.c b/test/CodeGen/func-in-block.c index 7e65ff9..1900135 100644 --- a/test/CodeGen/func-in-block.c +++ b/test/CodeGen/func-in-block.c @@ -15,5 +15,5 @@ int main() return 0; // not reached } -// CHECK: @__func__.__main_block_invoke_0 = private constant [22 x i8] c"__main_block_invoke_0\00" +// CHECK: @__func__.__main_block_invoke_0 = private unnamed_addr constant [22 x i8] c"__main_block_invoke_0\00" // CHECK: call void @PRINTF({{.*}}@__func__.__main_block_invoke_ diff --git a/test/CodeGen/illegal-UTF8.m b/test/CodeGen/illegal-UTF8.m index 871e6e5..4762e80 100644 --- a/test/CodeGen/illegal-UTF8.m +++ b/test/CodeGen/illegal-UTF8.m @@ -2,7 +2,5 @@ @class NSString; -// FIXME: GCC emits the following warning: -// CodeGen/illegal-UTF8.m:4: warning: input conversion stopped due to an input byte that does not belong to the input codeset UTF-8 -NSString *S = @"\xff\xff___WAIT___"; +NSString *S = @"\xff\xff___WAIT___"; // expected-warning {{input conversion stopped due to an input byte that does not belong to the input codeset UTF-8}} diff --git a/test/CodeGen/imaginary.c b/test/CodeGen/imaginary.c new file mode 100644 index 0000000..2649ceb --- /dev/null +++ b/test/CodeGen/imaginary.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -verify -emit-llvm-only %s + +// Just verify that we don't crash until we support _Imaginary. +double _Imaginary foo; // expected-error {{imaginary types are not supported}} diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c index c8de99d90..0f94729 100644 --- a/test/CodeGen/init.c +++ b/test/CodeGen/init.c @@ -46,3 +46,72 @@ void f6() { int x; long ids[] = { (long) &x }; } + + + + +// CHECK: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } +// PR8217 +struct a7 { + int b; + char v[]; +}; + +struct a7 test7 = { .b = 0, .v = "bar" }; + + +// PR279 comment #3 +char test8(int X) { + char str[100000] = "abc"; // tail should be memset. + return str[X]; +// CHECK: @test8( +// CHECK: call void @llvm.memset +// CHECK: store i8 97 +// CHECK: store i8 98 +// CHECK: store i8 99 +} + +void bar(void*); + +// PR279 +int test9(int X) { + int Arr[100] = { X }; // Should use memset + bar(Arr); +// CHECK: @test9 +// CHECK: call void @llvm.memset +// CHECK-NOT: store i32 0 +// CHECK: call void @bar +} + +struct a { + int a, b, c, d, e, f, g, h, i, j, k, *p; +}; + +struct b { + struct a a,b,c,d,e,f,g; +}; + +int test10(int X) { + struct b S = { .a.a = X, .d.e = X, .f.e = 0, .f.f = 0, .f.p = 0 }; + bar(&S); + + // CHECK: @test10 + // CHECK: call void @llvm.memset + // CHECK-NOT: store i32 0 + // CHECK: call void @bar +} + + +// PR9257 +struct test11S { + int A[10]; +}; +void test11(struct test11S *P) { + *P = (struct test11S) { .A = { [0 ... 3] = 4 } }; + // CHECK: @test11 + // CHECK: store i32 4 + // CHECK: store i32 4 + // CHECK: store i32 4 + // CHECK: store i32 4 + // CHECK: ret void +} diff --git a/test/CodeGen/integer-overflow.c b/test/CodeGen/integer-overflow.c index 9bed741..103cc84 100644 --- a/test/CodeGen/integer-overflow.c +++ b/test/CodeGen/integer-overflow.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT // RUN: %clang_cc1 %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV // RUN: %clang_cc1 %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV +// RUN: %clang_cc1 %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER // Tests for signed integer overflow stuff. @@ -14,21 +15,25 @@ void test1() { // DEFAULT: add nsw i32 // WRAPV: add i32 // TRAPV: llvm.sadd.with.overflow.i32 + // TRAPV_HANDLER: foo( f11G = a + b; // DEFAULT: sub nsw i32 // WRAPV: sub i32 // TRAPV: llvm.ssub.with.overflow.i32 + // TRAPV_HANDLER: foo( f11G = a - b; // DEFAULT: mul nsw i32 // WRAPV: mul i32 // TRAPV: 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 + // TRAPV_HANDLER: foo( f11G = -a; // PR7426 - Overflow checking for increments. @@ -36,10 +41,12 @@ void test1() { // DEFAULT: add nsw i32 {{.*}}, 1 // WRAPV: add i32 {{.*}}, 1 // TRAPV: 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) + // TRAPV_HANDLER: foo( --a; } diff --git a/test/CodeGen/lineno-dbginfo.c b/test/CodeGen/lineno-dbginfo.c index 176d415..72fa337 100644 --- a/test/CodeGen/lineno-dbginfo.c +++ b/test/CodeGen/lineno-dbginfo.c @@ -1,4 +1,4 @@ -// RUN: echo "#include <stdio.h>" > %t.h +// RUN: echo "#include <stddef.h>" > %t.h // RUN: %clang -S -g -include %t.h %s -emit-llvm -o %t.ll // RUN: grep "i32 5" %t.ll // outer is at line number 5. diff --git a/test/CodeGen/mangle.c b/test/CodeGen/mangle.c index 93d424a..3bbd9c8 100644 --- a/test/CodeGen/mangle.c +++ b/test/CodeGen/mangle.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s -// CHECK: @"\01foo" +// CHECK: @foo // Make sure we mangle overloadable, even in C system headers. # 1 "somesystemheader.h" 1 3 4 @@ -9,7 +9,7 @@ void __attribute__((__overloadable__)) f0(int a) {} // CHECK: @_Z2f0l void __attribute__((__overloadable__)) f0(long b) {} -// CHECK: @"\01bar" +// CHECK: @bar // These should get merged. void foo() __asm__("bar"); @@ -55,7 +55,7 @@ float foo8 __asm__("foo7") = 42; int func(void); extern int func (void) __asm__ ("FUNC"); -// CHECK: @"\01FUNC" +// CHECK: @FUNC int func(void) { return 42; } diff --git a/test/CodeGen/may-alias.c b/test/CodeGen/may-alias.c new file mode 100644 index 0000000..f3ea792 --- /dev/null +++ b/test/CodeGen/may-alias.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o %t %s +// RUN: FileCheck < %t %s + +// Types with the may_alias attribute should be considered equivalent +// to char for aliasing. + +typedef int __attribute__((may_alias)) aliasing_int; + +void test0(aliasing_int *ai, int *i) +{ + *ai = 0; + *i = 1; +} + +// CHECK: store i32 0, i32* %{{.*}}, !tbaa !1 +// CHECK: store i32 1, i32* %{{.*}}, !tbaa !3 + +// CHECK: !0 = metadata !{metadata !"any pointer", metadata !1} +// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} +// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA", null} +// CHECK: !3 = metadata !{metadata !"int", metadata !1} diff --git a/test/CodeGen/mcount.c b/test/CodeGen/mcount.c new file mode 100644 index 0000000..1cf3d6a --- /dev/null +++ b/test/CodeGen/mcount.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s +void foo(void) { +// CHECK: call void @mcount() +} diff --git a/test/CodeGen/mms-bitfields.c b/test/CodeGen/mms-bitfields.c new file mode 100644 index 0000000..1617e8a --- /dev/null +++ b/test/CodeGen/mms-bitfields.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -mms-bitfields -emit-llvm %s -o - | FileCheck %s + +struct s1 { + int f32; + long long f64; +} s1; + +// CHECK: %struct.s1 = type { i32, [4 x i8], i64 } + +struct s2 { + int f32; + long long f64[4]; +} s2; + +// CHECK: %struct.s2 = type { i32, [4 x i8], [4 x i64] } + +struct s3 { + int f32; + struct s1 s; +} s3; + +// CHECK: %struct.s3 = type { i32, [4 x i8], %struct.s1 } diff --git a/test/CodeGen/mmx-builtins.c b/test/CodeGen/mmx-builtins.c new file mode 100644 index 0000000..7934e77 --- /dev/null +++ b/test/CodeGen/mmx-builtins.c @@ -0,0 +1,452 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +ssse3 -S -o - | FileCheck %s + +// FIXME: Disable inclusion of mm_malloc.h, our current implementation is broken +// on win32 since we don't generally know how to find errno.h. +#define __MM_MALLOC_H + +#include <tmmintrin.h> + +__m64 test1(__m64 a, __m64 b) { + // CHECK: phaddw + return _mm_hadd_pi16(a, b); +} + +__m64 test2(__m64 a, __m64 b) { + // CHECK: phaddd + return _mm_hadd_pi32(a, b); +} + +__m64 test3(__m64 a, __m64 b) { + // CHECK: phaddsw + return _mm_hadds_pi16(a, b); +} + +__m64 test4(__m64 a, __m64 b) { + // CHECK: phsubw + return _mm_hsub_pi16(a, b); +} + +__m64 test5(__m64 a, __m64 b) { + // CHECK: phsubd + return _mm_hsub_pi32(a, b); +} + +__m64 test6(__m64 a, __m64 b) { + // CHECK: phsubsw + return _mm_hsubs_pi16(a, b); +} + +__m64 test7(__m64 a, __m64 b) { + // CHECK: pmaddubsw + return _mm_maddubs_pi16(a, b); +} + +__m64 test8(__m64 a, __m64 b) { + // CHECK: pmulhrsw + return _mm_mulhrs_pi16(a, b); +} + +__m64 test9(__m64 a, __m64 b) { + // CHECK: pshufb + return _mm_shuffle_pi8(a, b); +} + +__m64 test10(__m64 a, __m64 b) { + // CHECK: psignb + return _mm_sign_pi8(a, b); +} + +__m64 test11(__m64 a, __m64 b) { + // CHECK: psignw + return _mm_sign_pi16(a, b); +} + +__m64 test12(__m64 a, __m64 b) { + // CHECK: psignd + return _mm_sign_pi32(a, b); +} + +__m64 test13(__m64 a) { + // CHECK: pabsb + return _mm_abs_pi8(a); +} + +__m64 test14(__m64 a) { + // CHECK: pabsw + return _mm_abs_pi16(a); +} + +__m64 test15(__m64 a) { + // CHECK: pabsd + return _mm_abs_pi32(a); +} + +__m64 test16(__m64 a, __m64 b) { + // CHECK: palignr + return _mm_alignr_pi8(a, b, 2); +} + +__m64 test17(__m128d a) { + // CHECK: cvtpd2pi + return _mm_cvtpd_pi32(a); +} + +__m64 test18(__m128d a) { + // CHECK: cvttpd2pi + return _mm_cvttpd_pi32(a); +} + +__m128d test19(__m64 a) { + // CHECK: cvtpi2pd + return _mm_cvtpi32_pd(a); +} + +__m64 test20(__m64 a, __m64 b) { + // CHECK: pmuludq + return _mm_mul_su32(a, b); +} + +__m64 test21(__m64 a) { + // CHECK: pshufw + return _mm_shuffle_pi16(a, 3); +} + +__m64 test22(__m64 a, __m64 b) { + // CHECK: pmulhuw + return _mm_mulhi_pu16(a, b); +} + +void test23(__m64 d, __m64 n, char *p) { + // CHECK: maskmovq + _mm_maskmove_si64(d, n, p); +} + +int test24(__m64 a) { + // CHECK: pmovmskb + return _mm_movemask_pi8(a); +} + +void test25(__m64 *p, __m64 a) { + // CHECK: movntq + _mm_stream_pi(p, a); +} + +__m64 test26(__m64 a, __m64 b) { + // CHECK: pavgb + return _mm_avg_pu8(a, b); +} + +__m64 test27(__m64 a, __m64 b) { + // CHECK: pavgw + return _mm_avg_pu16(a, b); +} + +__m64 test28(__m64 a, __m64 b) { + // CHECK: pmaxub + return _mm_max_pu8(a, b); +} + +__m64 test29(__m64 a, __m64 b) { + // CHECK: pmaxsw + return _mm_max_pi16(a, b); +} + +__m64 test30(__m64 a, __m64 b) { + // CHECK: pminub + return _mm_min_pu8(a, b); +} + +__m64 test31(__m64 a, __m64 b) { + // CHECK: pminsw + return _mm_min_pi16(a, b); +} + +__m64 test32(__m64 a, __m64 b) { + // CHECK: psadbw + return _mm_sad_pu8(a, b); +} + +__m64 test33(__m64 a, __m64 b) { + // CHECK: paddb + return _mm_add_pi8(a, b); +} + +__m64 test34(__m64 a, __m64 b) { + // CHECK: paddw + return _mm_add_pi16(a, b); +} + +__m64 test35(__m64 a, __m64 b) { + // CHECK: paddd + return _mm_add_pi32(a, b); +} + +__m64 test36(__m64 a, __m64 b) { + // CHECK: paddq + return __builtin_ia32_paddq(a, b); +} + +__m64 test37(__m64 a, __m64 b) { + // CHECK: paddsb + return _mm_adds_pi8(a, b); +} + +__m64 test38(__m64 a, __m64 b) { + // CHECK: paddsw + return _mm_adds_pi16(a, b); +} + +__m64 test39(__m64 a, __m64 b) { + // CHECK: paddusb + return _mm_adds_pu8(a, b); +} + +__m64 test40(__m64 a, __m64 b) { + // CHECK: paddusw + return _mm_adds_pu16(a, b); +} + +__m64 test41(__m64 a, __m64 b) { + // CHECK: psubb + return _mm_sub_pi8(a, b); +} + +__m64 test42(__m64 a, __m64 b) { + // CHECK: psubw + return _mm_sub_pi16(a, b); +} + +__m64 test43(__m64 a, __m64 b) { + // CHECK: psubd + return _mm_sub_pi32(a, b); +} + +__m64 test44(__m64 a, __m64 b) { + // CHECK: psubq + return __builtin_ia32_psubq(a, b); +} + +__m64 test45(__m64 a, __m64 b) { + // CHECK: psubsb + return _mm_subs_pi8(a, b); +} + +__m64 test46(__m64 a, __m64 b) { + // CHECK: psubsw + return _mm_subs_pi16(a, b); +} + +__m64 test47(__m64 a, __m64 b) { + // CHECK: psubusb + return _mm_subs_pu8(a, b); +} + +__m64 test48(__m64 a, __m64 b) { + // CHECK: psubusw + return _mm_subs_pu16(a, b); +} + +__m64 test49(__m64 a, __m64 b) { + // CHECK: pmaddwd + return _mm_madd_pi16(a, b); +} + +__m64 test50(__m64 a, __m64 b) { + // CHECK: pmulhw + return _mm_mulhi_pi16(a, b); +} + +__m64 test51(__m64 a, __m64 b) { + // CHECK: pmullw + return _mm_mullo_pi16(a, b); +} + +__m64 test52(__m64 a, __m64 b) { + // CHECK: pmullw + return _mm_mullo_pi16(a, b); +} + +__m64 test53(__m64 a, __m64 b) { + // CHECK: pand + return _mm_and_si64(a, b); +} + +__m64 test54(__m64 a, __m64 b) { + // CHECK: pandn + return _mm_andnot_si64(a, b); +} + +__m64 test55(__m64 a, __m64 b) { + // CHECK: por + return _mm_or_si64(a, b); +} + +__m64 test56(__m64 a, __m64 b) { + // CHECK: pxor + return _mm_xor_si64(a, b); +} + +__m64 test57(__m64 a, __m64 b) { + // CHECK: pavgb + return _mm_avg_pu8(a, b); +} + +__m64 test58(__m64 a, __m64 b) { + // CHECK: pavgw + return _mm_avg_pu16(a, b); +} + +__m64 test59(__m64 a, __m64 b) { + // CHECK: psllw + return _mm_sll_pi16(a, b); +} + +__m64 test60(__m64 a, __m64 b) { + // CHECK: pslld + return _mm_sll_pi32(a, b); +} + +__m64 test61(__m64 a, __m64 b) { + // CHECK: psllq + return _mm_sll_si64(a, b); +} + +__m64 test62(__m64 a, __m64 b) { + // CHECK: psrlw + return _mm_srl_pi16(a, b); +} + +__m64 test63(__m64 a, __m64 b) { + // CHECK: psrld + return _mm_srl_pi32(a, b); +} + +__m64 test64(__m64 a, __m64 b) { + // CHECK: psrlq + return _mm_srl_si64(a, b); +} + +__m64 test65(__m64 a, __m64 b) { + // CHECK: psraw + return _mm_sra_pi16(a, b); +} + +__m64 test66(__m64 a, __m64 b) { + // CHECK: psrad + return _mm_sra_pi32(a, b); +} + +__m64 test67(__m64 a) { + // CHECK: psllw + return _mm_slli_pi16(a, 3); +} + +__m64 test68(__m64 a) { + // CHECK: pslld + return _mm_slli_pi32(a, 3); +} + +__m64 test69(__m64 a) { + // CHECK: psllq + return _mm_slli_si64(a, 3); +} + +__m64 test70(__m64 a) { + // CHECK: psrlw + return _mm_srli_pi16(a, 3); +} + +__m64 test71(__m64 a) { + // CHECK: psrld + return _mm_srli_pi32(a, 3); +} + +__m64 test72(__m64 a) { + // CHECK: psrlq + return _mm_srli_si64(a, 3); +} + +__m64 test73(__m64 a) { + // CHECK: psraw + return _mm_srai_pi16(a, 3); +} + +__m64 test74(__m64 a) { + // CHECK: psrad + return _mm_srai_pi32(a, 3); +} + +__m64 test75(__m64 a, __m64 b) { + // CHECK: packsswb + return _mm_packs_pi16(a, b); +} + +__m64 test76(__m64 a, __m64 b) { + // CHECK: packssdw + return _mm_packs_pi32(a, b); +} + +__m64 test77(__m64 a, __m64 b) { + // CHECK: packuswb + return _mm_packs_pu16(a, b); +} + +__m64 test78(__m64 a, __m64 b) { + // CHECK: punpckhbw + return _mm_unpackhi_pi8(a, b); +} + +__m64 test79(__m64 a, __m64 b) { + // CHECK: punpckhwd + return _mm_unpackhi_pi16(a, b); +} + +__m64 test80(__m64 a, __m64 b) { + // CHECK: punpckhdq + return _mm_unpackhi_pi32(a, b); +} + +__m64 test81(__m64 a, __m64 b) { + // CHECK: punpcklbw + return _mm_unpacklo_pi8(a, b); +} + +__m64 test82(__m64 a, __m64 b) { + // CHECK: punpcklwd + return _mm_unpacklo_pi16(a, b); +} + +__m64 test83(__m64 a, __m64 b) { + // CHECK: punpckldq + return _mm_unpacklo_pi32(a, b); +} + +__m64 test84(__m64 a, __m64 b) { + // CHECK: pcmpeqb + return _mm_cmpeq_pi8(a, b); +} + +__m64 test85(__m64 a, __m64 b) { + // CHECK: pcmpeqw + return _mm_cmpeq_pi16(a, b); +} + +__m64 test86(__m64 a, __m64 b) { + // CHECK: pcmpeqd + return _mm_cmpeq_pi32(a, b); +} + +__m64 test87(__m64 a, __m64 b) { + // CHECK: pcmpgtb + return _mm_cmpgt_pi8(a, b); +} + +__m64 test88(__m64 a, __m64 b) { + // CHECK: pcmpgtw + return _mm_cmpgt_pi16(a, b); +} + +__m64 test89(__m64 a, __m64 b) { + // CHECK: pcmpgtd + return _mm_cmpgt_pi32(a, b); +} diff --git a/test/CodeGen/mmx-shift-with-immediate.c b/test/CodeGen/mmx-shift-with-immediate.c new file mode 100644 index 0000000..f430d2e --- /dev/null +++ b/test/CodeGen/mmx-shift-with-immediate.c @@ -0,0 +1,23 @@ +// RUN: %clang -mmmx -ccc-host-triple i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s +#include <mmintrin.h> + +void shift(__m64 a, __m64 b, int c) { + // CHECK: x86_mmx @llvm.x86.mmx.pslli.w(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_slli_pi16(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.pslli.d(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_slli_pi32(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.pslli.q(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_slli_si64(a, c); + + // CHECK: x86_mmx @llvm.x86.mmx.psrli.w(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srli_pi16(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.psrli.d(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srli_pi32(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.psrli.q(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srli_si64(a, c); + + // CHECK: x86_mmx @llvm.x86.mmx.psrai.w(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srai_pi16(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.psrai.d(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srai_pi32(a, c); +} diff --git a/test/CodeGen/ms-anonymous-struct.c b/test/CodeGen/ms-anonymous-struct.c new file mode 100644 index 0000000..3afe440 --- /dev/null +++ b/test/CodeGen/ms-anonymous-struct.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -fms-extensions -emit-llvm -o - %s | FileCheck %s + +// CHECK: %struct.nested1 = type { i32, i32 } +typedef struct nested1 { + int a1; + int b1; +} NESTED1; + +// CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 } +struct nested2 { + int a; + NESTED1; + int b; +}; + +// CHECK: %struct.test = type { i32, %struct.nested2, i32 } +struct test { + int x; + struct nested2; + int y; +}; + + +void foo() +{ + // CHECK: %var = alloca %struct.test, align 4 + struct test var; + + // CHECK: getelementptr inbounds %struct.test* %var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.a; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.b; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.a1; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.b1; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.x; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.y; +} + +void foo2(struct test* var) +{ + // CHECK: alloca %struct.test*, align + // CHECK-NEXT: store %struct.test* %var, %struct.test** %{{.*}}, align + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->a; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->b; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->a1; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->b1; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->x; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->y; +} diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c new file mode 100644 index 0000000..9ae1bbf --- /dev/null +++ b/test/CodeGen/mult-alt-generic.c @@ -0,0 +1,283 @@ +// RUN: %clang_cc1 -triple i686 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple bfin %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple cellspu %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple mblaze %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple mips %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple mipsel %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple powerpc %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple s390x %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s + +int mout0; +int min1; +int marray[2]; + +// CHECK: @single_m +void single_m() +{ + // CHECK: call void asm "foo $1,$0", "=*m,*m[[CLOBBERS:[a-zA-Z0-9@%{},~_ ]*\"]](i32* {{[a-zA-Z0-9@%]+}}, i32* {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=m" (mout0) : "m" (min1)); +} + +// CHECK: @single_o +void single_o() +{ + register int out0 = 0; + register int index = 1; + // Doesn't really do an offset... + //asm("foo %1, %2,%0" : "=r" (out0) : "o" (min1)); +} + +// CHECK: @single_V +void single_V() +{ +// asm("foo %1,%0" : "=m" (mout0) : "V" (min1)); +} + +// CHECK: @single_lt +void single_lt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,<r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "<r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,r<[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "r<" (in1)); +} + +// CHECK: @single_gt +void single_gt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,>r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : ">r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,r>[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "r>" (in1)); +} + +// CHECK: @single_r +void single_r() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "r" (in1)); +} + +// CHECK: @single_i +void single_i() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r,i[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "i" (1)); +} + +// CHECK: @single_n +void single_n() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r,n[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "n" (1)); +} + +// CHECK: @single_E +void single_E() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r,E[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "E" (1.0e+01)); +} + +// CHECK: @single_F +void single_F() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r,F[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "F" (1.0)); +} + +// CHECK: @single_s +void single_s() +{ + register int out0 = 0; + //asm("foo %1,%0" : "=r" (out0) : "s" (single_s)); +} + +// CHECK: @single_g +void single_g() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "g" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "g" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r,imr[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "g" (1)); +} + +// CHECK: @single_X +void single_X() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "X" (1)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r" (out0) : "X" (marray)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (1.0e+01)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (1.0)); +} + +// CHECK: @single_p +void single_p() +{ + register int out0 = 0; + // Constraint converted differently on different platforms moved to platform-specific. + // : call i32 asm "foo $1,$0", "=r,im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r" (out0) : "p" (marray)); +} + +// CHECK: @multi_m +void multi_m() +{ + // CHECK: call void asm "foo $1,$0", "=*m|r,m|r[[CLOBBERS]](i32* {{[a-zA-Z0-9@%]+}}, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=m,r" (mout0) : "m,r" (min1)); +} + +// CHECK: @multi_o +void multi_o() +{ + register int out0 = 0; + register int index = 1; + // Doesn't really do an offset... + //asm("foo %1, %2,%0" : "=r,r" (out0) : "r,o" (min1)); +} + +// CHECK: @multi_V +void multi_V() +{ +// asm("foo %1,%0" : "=m,r" (mout0) : "r,V" (min1)); +} + +// CHECK: @multi_lt +void multi_lt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|<r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,<r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|r<[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,r<" (in1)); +} + +// CHECK: @multi_gt +void multi_gt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|>r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,>r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|r>[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,r>" (in1)); +} + +// CHECK: @multi_r +void multi_r() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|m[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,m" (in1)); +} + +// CHECK: @multi_i +void multi_i() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|i[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,i" (1)); +} + +// CHECK: @multi_n +void multi_n() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|n[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,n" (1)); +} + +// CHECK: @multi_E +void multi_E() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r|r,r|E[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,E" (1.0e+01)); +} + +// CHECK: @multi_F +void multi_F() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r|r,r|F[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,F" (1.0)); +} + +// CHECK: @multi_s +void multi_s() +{ + register int out0 = 0; + //asm("foo %1,%0" : "=r,r" (out0) : "r,s" (multi_s)); +} + +// CHECK: @multi_g +void multi_g() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,g" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,g" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|imr[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,g" (1)); +} + +// CHECK: @multi_X +void multi_X() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (marray)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0e+01)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0)); +} + +// CHECK: @multi_p +void multi_p() +{ + register int out0 = 0; + // Constraint converted differently on different platforms moved to platform-specific. + // : call i32 asm "foo $1,$0", "=r|r,r|im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r,r" (out0) : "r,p" (marray)); +} diff --git a/test/CodeGen/mult-alt-x86.c b/test/CodeGen/mult-alt-x86.c new file mode 100644 index 0000000..84011f2 --- /dev/null +++ b/test/CodeGen/mult-alt-x86.c @@ -0,0 +1,374 @@ +// RUN: %clang_cc1 -triple i686 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64 -emit-llvm %s -o - | FileCheck %s + +int mout0; +int min1; +int marray[2]; +double dout0; +double din1; + +// CHECK: @single_R +void single_R() +{ + // CHECK: asm "foo $1,$0", "=R,R[[CLOBBERS:[a-zA-Z0-9@%{},~_ ]*\"]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=R" (mout0) : "R" (min1)); +} + +// CHECK: @single_q +void single_q() +{ + // CHECK: asm "foo $1,$0", "=q,q[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=q" (mout0) : "q" (min1)); +} + +// CHECK: @single_Q +void single_Q() +{ + // CHECK: asm "foo $1,$0", "=Q,Q[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=Q" (mout0) : "Q" (min1)); +} + +// CHECK: @single_a +void single_a() +{ + // CHECK: asm "foo $1,$0", "={ax},{ax}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=a" (mout0) : "a" (min1)); +} + +// CHECK: @single_b +void single_b() +{ + // CHECK: asm "foo $1,$0", "={bx},{bx}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=b" (mout0) : "b" (min1)); +} + +// CHECK: @single_c +void single_c() +{ + // CHECK: asm "foo $1,$0", "={cx},{cx}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=c" (mout0) : "c" (min1)); +} + +// CHECK: @single_d +void single_d() +{ + // CHECK: asm "foo $1,$0", "={dx},{dx}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=d" (mout0) : "d" (min1)); +} + +// CHECK: @single_S +void single_S() +{ + // CHECK: asm "foo $1,$0", "={si},{si}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=S" (mout0) : "S" (min1)); +} + +// CHECK: @single_D +void single_D() +{ + // CHECK: asm "foo $1,$0", "={di},{di}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=D" (mout0) : "D" (min1)); +} + +// CHECK: @single_A +void single_A() +{ + // CHECK: asm "foo $1,$0", "=A,A[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=A" (mout0) : "A" (min1)); +} + +// CHECK: @single_f +void single_f() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @single_t +void single_t() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @single_u +void single_u() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @single_y +void single_y() +{ + // CHECK: call double asm "foo $1,$0", "=y,y[[CLOBBERS]](double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=y" (dout0) : "y" (din1)); +} + +// CHECK: @single_x +void single_x() +{ + // CHECK: asm "foo $1,$0", "=x,x[[CLOBBERS]](double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=x" (dout0) : "x" (din1)); +} + +// CHECK: @single_Y +void single_Y0() +{ + // Y constraint currently broken. + //asm("foo %1,%0" : "=Y0" (mout0) : "Y0" (min1)); + //asm("foo %1,%0" : "=Yz" (mout0) : "Yz" (min1)); + //asm("foo %1,%0" : "=Yt" (mout0) : "Yt" (min1)); + //asm("foo %1,%0" : "=Yi" (mout0) : "Yi" (min1)); + //asm("foo %1,%0" : "=Ym" (mout0) : "Ym" (min1)); +} + +// CHECK: @single_I +void single_I() +{ + // CHECK: asm "foo $1,$0", "=*m,I[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "I" (1)); +} + +// CHECK: @single_J +void single_J() +{ + // CHECK: asm "foo $1,$0", "=*m,J[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "J" (1)); +} + +// CHECK: @single_K +void single_K() +{ + // CHECK: asm "foo $1,$0", "=*m,K[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "K" (1)); +} + +// CHECK: @single_L +void single_L() +{ + // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "L" (1)); +} + +// CHECK: @single_M +void single_M() +{ + // CHECK: asm "foo $1,$0", "=*m,M[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "M" (1)); +} + +// CHECK: @single_N +void single_N() +{ + // CHECK: asm "foo $1,$0", "=*m,N[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "N" (1)); +} + +// CHECK: @single_G +void single_G() +{ + // CHECK: asm "foo $1,$0", "=*m,G[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=m" (mout0) : "G" (1.0)); +} + +// CHECK: @single_C +void single_C() +{ + // CHECK: asm "foo $1,$0", "=*m,C[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=m" (mout0) : "C" (1.0)); +} + +// CHECK: @single_e +void single_e() +{ + // CHECK: asm "foo $1,$0", "=*m,e[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "e" (1)); +} + +// CHECK: @single_Z +void single_Z() +{ + // CHECK: asm "foo $1,$0", "=*m,Z[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "Z" (1)); +} + +// CHECK: @multi_R +void multi_R() +{ + // CHECK: asm "foo $1,$0", "=*r|R|m,r|R|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=R,=m" (mout0) : "r,R,m" (min1)); +} + +// CHECK: @multi_q +void multi_q() +{ + // CHECK: asm "foo $1,$0", "=*r|q|m,r|q|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=q,=m" (mout0) : "r,q,m" (min1)); +} + +// CHECK: @multi_Q +void multi_Q() +{ + // CHECK: asm "foo $1,$0", "=*r|Q|m,r|Q|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=Q,=m" (mout0) : "r,Q,m" (min1)); +} + +// CHECK: @multi_a +void multi_a() +{ + // CHECK: asm "foo $1,$0", "=*r|{ax}|m,r|{ax}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=a,=m" (mout0) : "r,a,m" (min1)); +} + +// CHECK: @multi_b +void multi_b() +{ + // CHECK: asm "foo $1,$0", "=*r|{bx}|m,r|{bx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=b,=m" (mout0) : "r,b,m" (min1)); +} + +// CHECK: @multi_c +void multi_c() +{ + // CHECK: asm "foo $1,$0", "=*r|{cx}|m,r|{cx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=c,=m" (mout0) : "r,c,m" (min1)); +} + +// CHECK: @multi_d +void multi_d() +{ + // CHECK: asm "foo $1,$0", "=*r|{dx}|m,r|{dx}[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=d,=m" (mout0) : "r,d" (min1)); +} + +// CHECK: @multi_S +void multi_S() +{ + // CHECK: asm "foo $1,$0", "=*r|{si}|m,r|{si}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=S,=m" (mout0) : "r,S,m" (min1)); +} + +// CHECK: @multi_D +void multi_D() +{ + // CHECK: asm "foo $1,$0", "=*r|{di}|m,r|{di}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=D,=m" (mout0) : "r,D,m" (min1)); +} + +// CHECK: @multi_A +void multi_A() +{ + // CHECK: asm "foo $1,$0", "=*r|A|m,r|A|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=A,=m" (mout0) : "r,A,m" (min1)); +} + +// CHECK: @multi_f +void multi_f() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @multi_t +void multi_t() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @multi_u +void multi_u() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @multi_y +void multi_y() +{ + // CHECK: asm "foo $1,$0", "=*r|y|m,r|y|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=y,=m" (dout0) : "r,y,m" (din1)); +} + +// CHECK: @multi_x +void multi_x() +{ + // CHECK: asm "foo $1,$0", "=*r|x|m,r|x|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,=x,=m" (dout0) : "r,x,m" (din1)); +} + +// CHECK: @multi_Y +void multi_Y0() +{ + // Y constraint currently broken. + //asm("foo %1,%0" : "=r,=Y0,=m" (mout0) : "r,Y0,m" (min1)); + //asm("foo %1,%0" : "=r,=Yz,=m" (mout0) : "r,Yz,m" (min1)); + //asm("foo %1,%0" : "=r,=Yt,=m" (mout0) : "r,Yt,m" (min1)); + //asm("foo %1,%0" : "=r,=Yi,=m" (mout0) : "r,Yi,m" (min1)); + //asm("foo %1,%0" : "=r,=Ym,=m" (mout0) : "r,Ym,m" (min1)); +} + +// CHECK: @multi_I +void multi_I() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|I|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,I,m" (1)); +} + +// CHECK: @multi_J +void multi_J() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|J|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,J,m" (1)); +} + +// CHECK: @multi_K +void multi_K() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|K|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,K,m" (1)); +} + +// CHECK: @multi_L +void multi_L() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|L|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,L,m" (1)); +} + +// CHECK: @multi_M +void multi_M() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|M|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,M,m" (1)); +} + +// CHECK: @multi_N +void multi_N() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|N|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,N,m" (1)); +} + +// CHECK: @multi_G +void multi_G() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|G|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,G,m" (1.0)); +} + +// CHECK: @multi_C +void multi_C() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|C|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,C,m" (1.0)); +} + +// CHECK: @multi_e +void multi_e() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|e|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,e,m" (1)); +} + +// CHECK: @multi_Z +void multi_Z() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|Z|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,=m,=m" (mout0) : "r,Z,m" (1)); +} diff --git a/test/CodeGen/no-common.c b/test/CodeGen/no-common.c index 03a5bb0..7beefc7 100644 --- a/test/CodeGen/no-common.c +++ b/test/CodeGen/no-common.c @@ -1,6 +1,15 @@ -// RUN: %clang -emit-llvm -S -o %t %s -// RUN: grep '@x = common global' %t -// RUN: %clang -fno-common -emit-llvm -S -o %t %s -// RUN: grep '@x = global' %t +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT +// RUN: %clang_cc1 %s -fno-common -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-NOCOMMON +// CHECK-DEFAULT: @x = common global +// CHECK-NOCOMMON: @x = global int x; + +// CHECK-DEFAULT: @ABC = global +// CHECK-NOCOMMON: @ABC = global +typedef void* (*fn_t)(long a, long b, char *f, int c); +fn_t ABC __attribute__ ((nocommon)); + +// CHECK-DEFAULT: @y = common global +// CHECK-NOCOMMON: @y = common global +int y __attribute__((common));
\ No newline at end of file diff --git a/test/CodeGen/packed-structure.c b/test/CodeGen/packed-structure.c index 2934d01..731a50b 100644 --- a/test/CodeGen/packed-structure.c +++ b/test/CodeGen/packed-structure.c @@ -87,3 +87,16 @@ int s2_load_y(struct s2 *a) { return a->y; } // CHECK-FUNCTIONS: define void @s2_copy // CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 2, i1 false) void s2_copy(struct s2 *a, struct s2 *b) { *b = *a; } + +struct __attribute__((packed, aligned)) s3 { + short aShort; + int anInt; +}; +// CHECK-GLOBAL: @s3_1 = global i32 2 +int s3_1 = __alignof(((struct s3*) 0)->anInt); +// CHECK-FUNCTIONS: define i32 @test3( +int test3(struct s3 *ptr) { + // CHECK-FUNCTIONS: [[PTR:%.*]] = getelementptr inbounds {{%.*}}* {{%.*}}, i32 0, i32 1 + // CHECK-FUNCTIONS-NEXT: load i32* [[PTR]], align 2 + return ptr->anInt; +} diff --git a/test/CodeGen/palignr.c b/test/CodeGen/palignr.c index e9c1dbd..ed86c9e 100644 --- a/test/CodeGen/palignr.c +++ b/test/CodeGen/palignr.c @@ -17,13 +17,13 @@ int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); } #define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n))) typedef __attribute__((vector_size(8))) int int2; -// CHECK-NOT: palignr +// CHECK: palignr int2 align5(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 8); } -// CHECK: psrlq +// CHECK: palignr int2 align6(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 9); } -// CHECK: xor +// CHECK: palignr int2 align7(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 16); } // CHECK: palignr diff --git a/test/CodeGen/pascal-wchar-string.c b/test/CodeGen/pascal-wchar-string.c index 89e4de4..7a03463 100644 --- a/test/CodeGen/pascal-wchar-string.c +++ b/test/CodeGen/pascal-wchar-string.c @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings -fshort-wchar | FileCheck %s -// rdar: // 8020384 +// rdar://8020384 + +#include <stddef.h> extern void abort (void); @@ -29,3 +31,11 @@ int main(int argc, char* argv[]) // CHECK: c"\03\00b\00a\00r\00\00\00" // CHECK: c"\04\00g\00o\00r\00f\00\00\00" + + +// PR8856 - -fshort-wchar makes wchar_t be unsigned. +// CHECK: @test2 +// CHECK: volatile store i32 1, i32* %isUnsigned +void test2() { + volatile int isUnsigned = (wchar_t)-1 > (wchar_t)0; +} diff --git a/test/CodeGen/pointer-arithmetic.c b/test/CodeGen/pointer-arithmetic.c index 33465e0..f67a36d 100644 --- a/test/CodeGen/pointer-arithmetic.c +++ b/test/CodeGen/pointer-arithmetic.c @@ -9,6 +9,7 @@ int f1(const char *a, char *b) { return b - a; } // GNU extensions typedef void (*FP)(void); void *f2(void *a, int b) { return a + b; } +void *f2_0(void *a, int b) { return &a[b]; } void *f2_1(void *a, int b) { return (a += b); } void *f3(int a, void *b) { return a + b; } void *f3_1(int a, void *b) { return (a += b); } @@ -20,3 +21,5 @@ FP f6(int a, FP b) { return a + b; } FP f6_1(int a, FP b) { return (a += b); } FP f7(FP a, int b) { return a - b; } FP f7_1(FP a, int b) { return (a -= b); } +void f8(void *a, int b) { return *(a + b); } +void f8_1(void *a, int b) { return a[b]; } diff --git a/test/CodeGen/pointer-signext.c b/test/CodeGen/pointer-signext.c new file mode 100644 index 0000000..e809eff --- /dev/null +++ b/test/CodeGen/pointer-signext.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm -O2 -o - %s | FileCheck %s + +// Under Windows 64, int and long are 32-bits. Make sure pointer math doesn't +// cause any sign extensions. + +// CHECK: [[P:%.*]] = add i64 %param, -8 +// CHECK-NEXT: [[Q:%.*]] = inttoptr i64 [[P]] to [[R:%.*\*]] +// CHECK-NEXT: {{%.*}} = getelementptr inbounds [[R]] [[Q]], i64 0, i32 0 + +#define CR(Record, TYPE, Field) \ + ((TYPE *) ((unsigned char *) (Record) - (unsigned char *) &(((TYPE *) 0)->Field))) + +typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *ForwardLink; + struct _LIST_ENTRY *BackLink; +} LIST_ENTRY; + +typedef struct { + unsigned long long Signature; + LIST_ENTRY Link; +} MEMORY_MAP; + +int test(unsigned long long param) +{ + LIST_ENTRY *Link; + MEMORY_MAP *Entry; + + Link = (LIST_ENTRY *) param; + + Entry = CR (Link, MEMORY_MAP, Link); + return (int) Entry->Signature; +} diff --git a/test/CodeGen/pragma-weak.c b/test/CodeGen/pragma-weak.c index 5c2866e..1de60e1 100644 --- a/test/CodeGen/pragma-weak.c +++ b/test/CodeGen/pragma-weak.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -verify | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm %s -o - -verify | FileCheck %s // CHECK: @weakvar = weak global // CHECK: @__weakvar_alias = common global diff --git a/test/CodeGen/predefined-expr.c b/test/CodeGen/predefined-expr.c index 9be5754..e2826b6 100644 --- a/test/CodeGen/predefined-expr.c +++ b/test/CodeGen/predefined-expr.c @@ -1,13 +1,13 @@ // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -// CHECK: @__func__.plainFunction = private constant [14 x i8] c"plainFunction\00" -// CHECK: @__PRETTY_FUNCTION__.plainFunction = private constant [21 x i8] c"void plainFunction()\00" -// CHECK: @__func__.externFunction = private constant [15 x i8] c"externFunction\00" -// CHECK: @__PRETTY_FUNCTION__.externFunction = private constant [22 x i8] c"void externFunction()\00" -// CHECK: @__func__.privateExternFunction = private constant [22 x i8] c"privateExternFunction\00" -// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private constant [29 x i8] c"void privateExternFunction()\00" -// CHECK: @__func__.staticFunction = private constant [15 x i8] c"staticFunction\00" -// CHECK: @__PRETTY_FUNCTION__.staticFunction = private constant [22 x i8] c"void staticFunction()\00" +// CHECK: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00" +// CHECK: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [21 x i8] c"void plainFunction()\00" +// CHECK: @__func__.externFunction = private unnamed_addr constant [15 x i8] c"externFunction\00" +// CHECK: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [22 x i8] c"void externFunction()\00" +// CHECK: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00" +// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [29 x i8] c"void privateExternFunction()\00" +// CHECK: @__func__.staticFunction = private unnamed_addr constant [15 x i8] c"staticFunction\00" +// CHECK: @__PRETTY_FUNCTION__.staticFunction = private unnamed_addr constant [22 x i8] c"void staticFunction()\00" int printf(const char *, ...); diff --git a/test/CodeGen/regparm-flag.c b/test/CodeGen/regparm-flag.c new file mode 100644 index 0000000..f37239e --- /dev/null +++ b/test/CodeGen/regparm-flag.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -mregparm 4 %s -emit-llvm -o %t +// RUN: FileCheck < %t %s + +void f1(int a, int b, int c, int d, + int e, int f, int g, int h); + +void f0() { +// CHECK: call void @f1(i32 inreg 1, i32 inreg 2, i32 inreg 3, i32 inreg 4, +// CHECK: i32 5, i32 6, i32 7, i32 8) + f1(1, 2, 3, 4, 5, 6, 7, 8); +} + +// CHECK: declare void @f1(i32 inreg, i32 inreg, i32 inreg, i32 inreg, +// CHECK: i32, i32, i32, i32) + diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c index ec5cbab..d628b68 100644 --- a/test/CodeGen/regparm.c +++ b/test/CodeGen/regparm.c @@ -11,8 +11,7 @@ typedef struct { typedef void (*FType)(int, int) __attribute ((regparm (3), stdcall)); FType bar; -static void FASTCALL -reduced(char b, double c, foo* d, double e, int f); +extern void FASTCALL reduced(char b, double c, foo* d, double e, int f); // PR7025 void FASTCALL f1(int i, int j, int k); @@ -21,7 +20,7 @@ void f1(int i, int j, int k) { } int main(void) { - // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.anon* inreg null + // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.foo* inreg null reduced(0, 0.0, 0, 0.0, 0); // CHECK: call x86_stdcallcc void {{.*}}(i32 inreg 1, i32 inreg 2) bar(1,2); diff --git a/test/CodeGen/sizeof-vla.c b/test/CodeGen/sizeof-vla.c index b0c514f..c5fc912 100644 --- a/test/CodeGen/sizeof-vla.c +++ b/test/CodeGen/sizeof-vla.c @@ -2,7 +2,7 @@ // PR3442 -static void *g(unsigned long len); +void *g(unsigned long len); void f(int n) diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c index 0ea0597..1d4f633 100644 --- a/test/CodeGen/statements.c +++ b/test/CodeGen/statements.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wreturn-type %s -emit-llvm -o /dev/null +// RUN: %clang_cc1 -Wreturn-type %s -emit-llvm-only void test1(int x) { switch (x) { diff --git a/test/CodeGen/string-literal-short-wstring.c b/test/CodeGen/string-literal-short-wstring.c new file mode 100644 index 0000000..8c2e412 --- /dev/null +++ b/test/CodeGen/string-literal-short-wstring.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -x c++ -emit-llvm -fshort-wchar %s -o - | FileCheck %s +// Runs in c++ mode so that wchar_t is available. + +int main() { + // This should convert to utf8. + // CHECK: internal constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 + char b[10] = "\u1120\u0220\U00102030"; + + // CHECK: private unnamed_addr constant [6 x i8] c"A\00B\00\00\00" + const wchar_t *foo = L"AB"; + + // This should convert to utf16. + // CHECK: private unnamed_addr constant [10 x i8] c" \11 \02\C8\DB0\DC\00\00" + const wchar_t *bar = L"\u1120\u0220\U00102030"; + + + + // Should pick second character. + // CHECK: store i8 98 + char c = 'ab'; + + // CHECK: store i16 97 + wchar_t wa = L'a'; + + // Should pick second character. + // CHECK: store i16 98 + wchar_t wb = L'ab'; + + // -4085 == 0xf00b + // CHECK: store i16 -4085 + wchar_t wc = L'\uF00B'; + + // Should take lower word of the 4byte UNC sequence. This does not match + // gcc. I don't understand what gcc does (it looks like it converts to utf16, + // then takes the second (!) utf16 word, swaps the lower two nibbles, and + // stores that?). + // CHECK: store i16 -4085 + wchar_t wd = L'\U0010F00B'; // has utf16 encoding dbc8 dcb0 + + // Should pick second character. (gcc: -9205) + // CHECK: store i16 -4085 + wchar_t we = L'\u1234\U0010F00B'; +} diff --git a/test/CodeGen/string-literal.c b/test/CodeGen/string-literal.c index 22a81e7..6d02b0f 100644 --- a/test/CodeGen/string-literal.c +++ b/test/CodeGen/string-literal.c @@ -1,7 +1,16 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s int main() { + // CHECK: internal constant [10 x i8] c"abc\00\00\00\00\00\00\00", align 1 char a[10] = "abc"; + // This should convert to utf8. + // CHECK: internal constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 + char b[10] = "\u1120\u0220\U00102030"; + + // CHECK: private unnamed_addr constant [12 x i8] c"A\00\00\00B\00\00\00\00\00\00\00" void *foo = L"AB"; + + // CHECK: private unnamed_addr constant [12 x i8] c"4\12\00\00\0B\F0\10\00\00\00\00\00" + void *bar = L"\u1234\U0010F00B"; } diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c index 926e5a7..861c41e 100644 --- a/test/CodeGen/struct-init.c +++ b/test/CodeGen/struct-init.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - +// RUN: %clang_cc1 %s -emit-llvm-only typedef struct _zend_ini_entry zend_ini_entry; struct _zend_ini_entry { @@ -18,3 +18,14 @@ struct GLGENH { }; struct GLGENH ABHFBF = {1}; + +typedef __attribute__(( ext_vector_type(2) )) unsigned int uint2; +typedef __attribute__(( __vector_size__(8) )) unsigned int __neon_uint32x2_t; + +// rdar://8183908 +typedef struct __simd64_uint32_t { + __neon_uint32x2_t val; +} uint32x2_t; +void foo() { + const uint32x2_t signBit = { (uint2) 0x80000000 }; +} diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c index cbc14d5..3e173be 100644 --- a/test/CodeGen/struct-passing.c +++ b/test/CodeGen/struct-passing.c @@ -1,11 +1,8 @@ -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o %t %s -// RUN: grep 'declare i32 @f0() readnone' %t -// RUN: grep 'declare i32 @f1() readonly' %t -// RUN: grep 'declare void @f2(.* sret)' %t -// RUN: grep 'declare void @f3(.* sret)' %t -// RUN: grep 'declare void @f4(.* byval)' %t -// RUN: grep 'declare void @f5(.* byval)' %t -// PR3835 +// This verifies that structs returned from functions by value are passed +// correctly according to their attributes and the ABI. +// SEE: PR3835 + +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s typedef int T0; typedef struct { int a[16]; } T1; @@ -18,3 +15,10 @@ void __attribute__((const)) f4(T1 a); void __attribute__((pure)) f5(T1 a); void *ps[] = { f0, f1, f2, f3, f4, f5 }; + +// CHECK: declare i32 @f0() readnone +// CHECK: declare i32 @f1() readonly +// CHECK: declare void @f2({{.*}} sret) +// CHECK: declare void @f3({{.*}} sret) +// CHECK: declare void @f4({{.*}} byval) +// CHECK: declare void @f5({{.*}} byval) diff --git a/test/CodeGen/switch.c b/test/CodeGen/switch.c index dc2d27b..8b94a09 100644 --- a/test/CodeGen/switch.c +++ b/test/CodeGen/switch.c @@ -194,3 +194,20 @@ int f13(unsigned x) { return 0; } } + +// Don't delete a basic block that we want to introduce later references to. +// This isn't really specific to switches, but it's easy to show with them. +// rdar://problem/8837067 +int f14(int x) { + switch (x) { + + // case range so that the case block has no predecessors + case 0 ... 15: + // any expression which doesn't introduce a new block + (void) 0; + // kaboom + + default: + return x; + } +} diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c index a16103f..a1f3e16 100644 --- a/test/CodeGen/thread-specifier.c +++ b/test/CodeGen/thread-specifier.c @@ -1,11 +1,15 @@ -// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | grep thread_local | count 4 -// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | not grep common +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s +// CHECK: @b = external thread_local global +// CHECK: @d.e = internal thread_local global +// CHECK: @d.f = internal thread_local global +// CHECK: @a = thread_local global __thread int a; extern __thread int b; -int c() { return &b; } +int c() { return *&b; } int d() { __thread static int e; __thread static union {float a; int b;} f = {.b = 1}; + return 0; } diff --git a/test/CodeGen/transparent-union.c b/test/CodeGen/transparent-union.c new file mode 100644 index 0000000..97a7318 --- /dev/null +++ b/test/CodeGen/transparent-union.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -o %t %s +// RUN: FileCheck < %t %s +// +// FIXME: Note that we don't currently get the ABI right here. f0() should be +// f0(i8*). + +typedef union { + void *f0; +} transp_t0 __attribute__((transparent_union)); + +void f0(transp_t0 obj); + +// CHECK: define void @f1_0(i32* %a0) +// CHECK: call void @f0(%union.transp_t0* byval %{{.*}}) +// CHECK: call void %{{.*}}(i8* %{{[a-z0-9]*}}) +// CHECK: } +void f1_0(int *a0) { + void (*f0p)(void *) = f0; + f0(a0); + f0p(a0); +} + +void f1_1(int *a0) { + f0((transp_t0) { a0 }); +} diff --git a/test/CodeGen/va_list_test.c b/test/CodeGen/va_list_test.c new file mode 100644 index 0000000..74f7837 --- /dev/null +++ b/test/CodeGen/va_list_test.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple powerpc-unknown-freebsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s + +#include <stdarg.h> + +int va_list_size = sizeof(va_list); +// SVR4-CHECK: va_list_size = global i32 12, align 4 diff --git a/test/CodeGen/visibility.c b/test/CodeGen/visibility.c index 8f81c8f..fa4b599 100644 --- a/test/CodeGen/visibility.c +++ b/test/CodeGen/visibility.c @@ -1,33 +1,38 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility default -emit-llvm -o %t %s -// RUN: grep '@g_com = common global i32 0' %t -// RUN: grep '@g_def = global i32 0' %t -// RUN: grep '@g_ext = external global i32' %t -// RUN: grep '@g_deferred = internal global' %t -// RUN: grep 'declare void @f_ext()' %t -// RUN: grep 'define internal void @f_deferred()' %t -// RUN: grep 'define i32 @f_def()' %t -// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility protected -emit-llvm -o %t %s -// RUN: grep '@g_com = common protected global i32 0' %t -// RUN: grep '@g_def = protected global i32 0' %t -// RUN: grep '@g_ext = external global i32' %t -// RUN: grep '@g_deferred = internal global' %t -// RUN: grep 'declare void @f_ext()' %t -// RUN: grep 'define internal void @f_deferred()' %t -// RUN: grep 'define protected i32 @f_def()' %t -// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility hidden -emit-llvm -o %t %s -// RUN: grep '@g_com = common hidden global i32 0' %t -// RUN: grep '@g_def = hidden global i32 0' %t -// RUN: grep '@g_ext = external global i32' %t -// RUN: grep '@g_deferred = internal global' %t -// RUN: grep 'declare void @f_ext()' %t -// RUN: grep 'define internal void @f_deferred()' %t -// RUN: grep 'define hidden i32 @f_def()' %t +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN +// CHECK-DEFAULT: @g_def = global i32 0 +// CHECK-DEFAULT: @g_com = common global i32 0 +// CHECK-DEFAULT: @g_ext = external global i32 +// CHECK-DEFAULT: @g_deferred = internal global +// CHECK-PROTECTED: @g_def = protected global i32 0 +// CHECK-PROTECTED: @g_com = common protected global i32 0 +// CHECK-PROTECTED: @g_ext = external global i32 +// CHECK-PROTECTED: @g_deferred = internal global +// CHECK-HIDDEN: @g_def = hidden global i32 0 +// CHECK-HIDDEN: @g_com = common hidden global i32 0 +// CHECK-HIDDEN: @g_ext = external global i32 +// CHECK-HIDDEN: @g_deferred = internal global int g_com; int g_def = 0; extern int g_ext; static char g_deferred[] = "hello"; +// CHECK-DEFAULT: @test4 = hidden global i32 10 +// CHECK-PROTECTED: @test4 = hidden global i32 10 +// CHECK-HIDDEN: @test4 = hidden global i32 10 + +// CHECK-DEFAULT: define i32 @f_def() +// CHECK-DEFAULT: declare void @f_ext() +// CHECK-DEFAULT: define internal void @f_deferred() +// CHECK-PROTECTED: define protected i32 @f_def() +// CHECK-PROTECTED: declare void @f_ext() +// CHECK-PROTECTED: define internal void @f_deferred() +// CHECK-HIDDEN: define hidden i32 @f_def() +// CHECK-HIDDEN: declare void @f_ext() +// CHECK-HIDDEN: define internal void @f_deferred() + extern void f_ext(void); static void f_deferred(void) { @@ -38,3 +43,27 @@ int f_def(void) { f_deferred(); return g_com + g_def + g_ext + g_deferred[0]; } + +// PR8457 +// CHECK-DEFAULT: define void @test1( +// CHECK-PROTECTED: define void @test1( +// CHECK-HIDDEN: define void @test1( +struct Test1 { int field; }; +void __attribute__((visibility("default"))) test1(struct Test1 *v) { } + +// rdar://problem/8595231 +// CHECK-DEFAULT: define void @test2() +// CHECK-PROTECTED: define void @test2() +// CHECK-HIDDEN: define void @test2() +void test2(void); +void __attribute__((visibility("default"))) test2(void) {} + +// CHECK-DEFAULT: define hidden void @test3() +// CHECK-PROTECTED: define hidden void @test3() +// CHECK-HIDDEN: define hidden void @test3() +extern void test3(void); +__private_extern__ void test3(void) {} + +// Top of file. +extern int test4; +__private_extern__ int test4 = 10; diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c index 0c53900..e5114a5 100644 --- a/test/CodeGen/vla.c +++ b/test/CodeGen/vla.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o %t +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s int b(char* x); @@ -35,3 +35,66 @@ void g(int count) { int (*a[5])[count]; int (*b)[][count]; } + +// rdar://8403108 +// CHECK: define void @f_8403108 +void f_8403108(unsigned x) { + // CHECK: call i8* @llvm.stacksave() + char s1[x]; + while (1) { + // CHECK: call i8* @llvm.stacksave() + char s2[x]; + if (1) + break; + // CHECK: call void @llvm.stackrestore(i8* + } + // CHECK: call void @llvm.stackrestore(i8* +} + +// pr7827 +void function(short width, int data[][width]) {} // expected-note {{passing argument to parameter 'data' here}} + +void test() { + int bork[4][13]; + // CHECK: call void @function(i16 signext 1, i32* null) + function(1, 0); + // CHECK: call void @function(i16 signext 1, i32* inttoptr + function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}} + // CHECK: call void @function(i16 signext 1, i32* {{.*}}) + function(1, bork); +} + +void function1(short width, int data[][width][width]) {} +void test1() { + int bork[4][13][15]; + // CHECK: call void @function1(i16 signext 1, i32* {{.*}}) + function1(1, bork); + // CHECK: call void @function(i16 signext 1, i32* {{.*}}) + function(1, bork[2]); +} + +// rdar://8476159 +static int GLOB; +int test2(int n) +{ + GLOB = 0; + char b[1][n+3]; /* Variable length array. */ + // CHECK: [[tmp_1:%.*]] = load i32* @GLOB, align 4 + // CHECK-NEXT: add nsw i32 [[tmp_1]], 1 + __typeof__(b[GLOB++]) c; + return GLOB; +} + +// http://llvm.org/PR8567 +// CHECK: define double @test_PR8567 +double test_PR8567(int n, double (*p)[n][5]) { + // CHECK: store [[vla_type:.*]] %p, + // CHECK: load i32* + // CHECK-NEXT: mul i32 40 + // CHECK-NEXT: [[byte_idx:%.*]] = mul i32 1 + // CHECK-NEXT: [[tmp_1:%.*]] = load [[vla_type]]* + // CHECK-NEXT: [[tmp_2:%.*]] = bitcast [[vla_type]] [[tmp_1]] to i8* + // CHECK-NEXT: [[idx:%.*]] = getelementptr inbounds i8* [[tmp_2]], i32 [[byte_idx]] + // CHECK-NEXT: bitcast i8* [[idx]] to [[vla_type]] + return p[1][2][3]; +} diff --git a/test/CodeGen/volatile-1.c b/test/CodeGen/volatile-1.c index e0c672b..f54afff 100644 --- a/test/CodeGen/volatile-1.c +++ b/test/CodeGen/volatile-1.c @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -Wno-unused-value -emit-llvm < %s -o %t -// RUN: grep volatile %t | count 145 -// RUN: grep memcpy %t | count 4 +// RUN: %clang_cc1 -Wno-return-type -Wno-unused-value -emit-llvm %s -o - | FileCheck %s +// CHECK: @i = common global [[INT:i[0-9]+]] 0 volatile int i, j, k; volatile int ar[5]; volatile char c; +// CHECK: @ci = common global [[CINT:%.*]] zeroinitializer volatile _Complex int ci; volatile struct S { #ifdef __cplusplus @@ -16,67 +16,190 @@ volatile struct S { //void operator =(volatile struct S&o1, volatile struct S&o2) volatile; int printf(const char *, ...); -int main() { - // A use. + +// Note that these test results are very much specific to C! +// Assignments in C++ yield l-values, not r-values, and the situations +// that do implicit lvalue-to-rvalue conversion are substantially +// reduced. + +// CHECK: define void @test() +void test() { + // CHECK: volatile load [[INT]]* @i i; - // A use of the real part + // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: sitofp [[INT]] (float)(ci); - // A use. + // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) (void)ci; - // A use. + // CHECK-NEXT: bitcast + // CHECK-NEXT: memcpy (void)a; - // Not a use. + // CHECK-NEXT: [[R:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) (void)(ci=ci); - // Not a use. + // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* @j + // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* @i (void)(i=j); + // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // Not sure why they're ordered this way. + // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] + // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] + // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) ci+=ci; + + // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] + // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] + // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // These additions can be elided + // CHECK-NEXT: add [[INT]] [[R]], [[R2]] + // CHECK-NEXT: add [[INT]] [[I]], [[I2]] (ci += ci) + ci; + // CHECK-NEXT: call void asm asm("nop"); + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: add nsw [[INT]] + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile load + // CHECK-NEXT: add nsw [[INT]] (i += j) + k; + // CHECK-NEXT: call void asm asm("nop"); - // A use + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: add nsw [[INT]] + // CHECK-NEXT: volatile store + // CHECK-NEXT: add nsw [[INT]] (i += j) + 1; + // CHECK-NEXT: call void asm asm("nop"); + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: add [[INT]] + // CHECK-NEXT: add [[INT]] ci+ci; - // A use. + + // CHECK-NEXT: volatile load __real i; - // A use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load +ci; + // CHECK-NEXT: call void asm asm("nop"); - // Not a use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store (void)(i=i); + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: sitofp (float)(i=i); - // A use. + // CHECK-NEXT: volatile load (void)i; + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store i=i; + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store i=i=i; #ifndef __cplusplus - // Not a use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store (void)__builtin_choose_expr(0, i=i, j=j); #endif - // A use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: icmp + // CHECK-NEXT: br i1 + // CHECK: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: br label + // CHECK: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: br label k ? (i=i) : (j=j); + // CHECK: phi + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store (void)(i,(i=i)); + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile load i=i,i; + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store (i=j,k=j); + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile load (i=j,k); + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load (i,j); + // CHECK-NEXT: volatile load + // CHECK-NEXT: trunc + // CHECK-NEXT: volatile store + // CHECK-NEXT: sext + // CHECK-NEXT: volatile store i=c=k; + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: add nsw [[INT]] + // CHECK-NEXT: volatile store i+=k; - // A use of both. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load ci; #ifndef __cplusplus - // A use of _real. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load (int)ci; - // A use of both. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: icmp ne + // CHECK-NEXT: icmp ne + // CHECK-NEXT: or i1 (_Bool)ci; #endif + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store ci=ci; + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store ci=ci=ci; + // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) __imag ci = __imag ci = __imag ci; - // Not a use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store __real (i = j); - // Not a use. + // CHECK-NEXT: volatile load __imag i; // ============================================================ @@ -91,6 +214,9 @@ int main() { // gcc. // Not a use. gcc forgets to do the assignment. + // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true ((a=a),a); // Not a use. gcc gets this wrong, it doesn't emit the copy! @@ -98,38 +224,72 @@ int main() { // Not a use. gcc got this wrong in 4.2 and omitted the side effects // entirely, but it is fixed in 4.4.0. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store __imag (i = j); #ifndef __cplusplus // A use of the real part + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store + // CHECK-NEXT: sitofp (float)(ci=ci); // Not a use, bug? gcc treats this as not a use, that's probably a bug due to // tree folding ignoring volatile. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store (int)(ci=ci); #endif // A use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: sitofp (float)(i=i); // A use. gcc treats this as not a use, that's probably a bug due to tree // folding ignoring volatile. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store (int)(i=i); // A use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: sub -(i=j); // A use. gcc treats this a not a use, that's probably a bug due to tree // folding ignoring volatile. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store +(i=k); // A use. gcc treats this a not a use, that's probably a bug due to tree // folding ignoring volatile. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile store __real (ci=ci); // A use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: add i + 0; // A use. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: volatile load + // CHECK-NEXT: add (i=j) + i; // A use. gcc treats this as not a use, that's probably a bug due to tree // folding ignoring volatile. + // CHECK-NEXT: volatile load + // CHECK-NEXT: volatile store + // CHECK-NEXT: add (i=j) + 0; #ifdef __cplusplus @@ -141,3 +301,15 @@ int main() { printf("s.x is at %p\n", &((s = s1).x)); #endif } + +extern volatile enum X x; +// CHECK: define void @test1() +void test1() { + extern void test1_helper(void); + test1_helper(); + // CHECK: call void @test1_helper() + // CHECK-NEXT: ret void + x; + (void) x; + return x; +} diff --git a/test/CodeGen/volatile-2.c b/test/CodeGen/volatile-2.c new file mode 100644 index 0000000..1ceaf17 --- /dev/null +++ b/test/CodeGen/volatile-2.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +void test0() { + // CHECK: define void @test0() + // CHECK: [[F:%.*]] = alloca float + // CHECK-NEXT: [[REAL:%.*]] = volatile load float* getelementptr inbounds ({{%.*}} @test0_v, i32 0, i32 0) + // CHECK-NEXT: volatile load float* getelementptr inbounds ({{%.*}} @test0_v, i32 0, i32 1) + // CHECK-NEXT: store float [[REAL]], float* [[F]], align 4 + // CHECK-NEXT: ret void + extern volatile _Complex float test0_v; + float f = (float) test0_v; +} + +void test1() { + // CHECK: define void @test1() + // CHECK: [[REAL:%.*]] = volatile load float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 0) + // CHECK-NEXT: [[IMAG:%.*]] = volatile load float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 1) + // CHECK-NEXT: volatile store float [[REAL]], float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 0) + // CHECK-NEXT: volatile store float [[IMAG]], float* getelementptr inbounds ({{%.*}} @test1_v, i32 0, i32 1) + // CHECK-NEXT: ret void + extern volatile _Complex float test1_v; + test1_v = test1_v; +} diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments-darwin.c index 75dfb82..cf89de3 100644 --- a/test/CodeGen/x86_32-arguments.c +++ b/test/CodeGen/x86_32-arguments-darwin.c @@ -94,11 +94,11 @@ T16 f16(void) { while (1) {} } // 128-bits). // CHECK: i32 @f17() -// CHECK: void @f18(%2* sret %agg.result) -// CHECK: void @f19(%3* sret %agg.result) -// CHECK: void @f20(%4* sret %agg.result) -// CHECK: void @f21(%5* sret %agg.result) -// CHECK: void @f22(%6* sret %agg.result) +// CHECK: void @f18(%{{.*}}* sret %agg.result) +// CHECK: void @f19(%{{.*}}* sret %agg.result) +// CHECK: void @f20(%{{.*}}* sret %agg.result) +// CHECK: void @f21(%{{.*}}* sret %agg.result) +// CHECK: void @f22(%{{.*}}* sret %agg.result) struct { T11 a; } f17(void) { while (1) {} } struct { T12 a; } f18(void) { while (1) {} } struct { T13 a; } f19(void) { while (1) {} } @@ -202,13 +202,13 @@ void f50(struct s50 a0) { } struct s51 { vvbp f0; int f1; }; void f51(struct s51 a0) { } -// CHECK: define void @f52(%struct.s52* byval align 16 %x) +// CHECK: define void @f52(%struct.s52* byval align 4) struct s52 { long double a; }; void f52(struct s52 x) {} -// CHECK: define void @f53(%struct.s53* byval align 32 %x) +// CHECK: define void @f53(%struct.s53* byval align 4) struct __attribute__((aligned(32))) s53 { int x; int y; @@ -228,3 +228,51 @@ typedef int v4i32 __attribute__((__vector_size__(16))); // PR8029 v4i32 f55(v4i32 arg) { return arg+arg; } +// CHECK: define void @f56( +// CHECK: i8 signext %a0, %struct.s56_0* byval %a1, +// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, +// CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4, +// CHECK: <4 x i32> %a6, %struct.s39* byval align 16 %a7, +// CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9, +// CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, +// CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) + +// CHECK: call void (i32, ...)* @f56_0(i32 1, +// CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval %{{[^ ]*}}, +// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, +// CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s39* byval align 16 %{{[^ ]*}}, +// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}}, +// CHECK: <8 x i32> {{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x double> {{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}}) +// CHECK: } +// +// <rdar://problem/7964854> [i386] clang misaligns long double in structures +// when passed byval +// <rdar://problem/8431367> clang misaligns parameters on stack +typedef int __attribute__((vector_size (8))) t56_v2i; +typedef double __attribute__((vector_size (8))) t56_v1d; +typedef int __attribute__((vector_size (16))) t56_v4i; +typedef double __attribute__((vector_size (16))) t56_v2d; +typedef int __attribute__((vector_size (32))) t56_v8i; +typedef double __attribute__((vector_size (32))) t56_v4d; + +struct s56_0 { char a; }; +struct s56_1 { t56_v2i a; }; +struct s56_2 { t56_v1d a; }; +struct s56_3 { t56_v4i a; }; +struct s56_4 { t56_v2d a; }; +struct s56_5 { t56_v8i a; }; +struct s56_6 { t56_v4d a; }; + +void f56(char a0, struct s56_0 a1, + t56_v2i a2, struct s56_1 a3, + t56_v1d a4, struct s56_2 a5, + t56_v4i a6, struct s56_3 a7, + t56_v2d a8, struct s56_4 a9, + t56_v8i a10, struct s56_5 a11, + t56_v4d a12, struct s56_6 a13) { + extern void f56_0(int x, ...); + f56_0(1, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13); +} diff --git a/test/CodeGen/x86_32-arguments-linux.c b/test/CodeGen/x86_32-arguments-linux.c new file mode 100644 index 0000000..230a20d --- /dev/null +++ b/test/CodeGen/x86_32-arguments-linux.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -w -fblocks -triple i386-pc-linux-gnu -emit-llvm -o %t %s +// RUN: FileCheck < %t %s + +// CHECK: define void @f56( +// CHECK: i8 signext %a0, %struct.s56_0* byval %a1, +// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, +// CHECK: <1 x double> %a4, %struct.s56_2* byval align 4, +// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 4, +// CHECK: <2 x double> %a8, %struct.s56_4* byval align 4, +// CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, +// CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) + +// CHECK: call void (i32, ...)* @f56_0(i32 1, +// CHECK: i32 %{{.*}}, %struct.s56_0* byval %{{[^ ]*}}, +// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, +// CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 4 %{{[^ ]*}}, +// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 4 %{{[^ ]*}}, +// CHECK: <8 x i32> %{{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x double> %{{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}}) +// CHECK: } +// +// <rdar://problem/7964854> [i386] clang misaligns long double in structures +// when passed byval +// <rdar://problem/8431367> clang misaligns parameters on stack +typedef int __attribute__((vector_size (8))) t56_v2i; +typedef double __attribute__((vector_size (8))) t56_v1d; +typedef int __attribute__((vector_size (16))) t56_v4i; +typedef double __attribute__((vector_size (16))) t56_v2d; +typedef int __attribute__((vector_size (32))) t56_v8i; +typedef double __attribute__((vector_size (32))) t56_v4d; + +struct s56_0 { char a; }; +struct s56_1 { t56_v2i a; }; +struct s56_2 { t56_v1d a; }; +struct s56_3 { t56_v4i a; }; +struct s56_4 { t56_v2d a; }; +struct s56_5 { t56_v8i a; }; +struct s56_6 { t56_v4d a; }; + +void f56(char a0, struct s56_0 a1, + t56_v2i a2, struct s56_1 a3, + t56_v1d a4, struct s56_2 a5, + t56_v4i a6, struct s56_3 a7, + t56_v2d a8, struct s56_4 a9, + t56_v8i a10, struct s56_5 a11, + t56_v4d a12, struct s56_6 a13) { + extern void f56_0(int x, ...); + f56_0(1, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13); +} diff --git a/test/CodeGen/x86_32-arguments-realign.c b/test/CodeGen/x86_32-arguments-realign.c new file mode 100644 index 0000000..b08862e --- /dev/null +++ b/test/CodeGen/x86_32-arguments-realign.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s +// RUN: FileCheck < %t %s + +// CHECK: define void @f0(%struct.s0* byval align 4) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 16, i32 4, i1 false) +// CHECK: } +struct s0 { long double a; }; +void f0(struct s0 a0) { + extern long double f0_g0; + f0_g0 = a0.a; +} |