summaryrefslogtreecommitdiffstats
path: root/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/2008-07-17-no-emit-on-error.c1
-rw-r--r--test/CodeGen/2008-07-29-override-alias-decl.c2
-rw-r--r--test/CodeGen/2010-03-09-DbgInfo.c2
-rw-r--r--test/CodeGen/annotate.c2
-rw-r--r--test/CodeGen/arm-vector-arguments.c30
-rw-r--r--test/CodeGen/asm-errors.c2
-rw-r--r--test/CodeGen/asm-inout.c12
-rw-r--r--test/CodeGen/asm-variable.c59
-rw-r--r--test/CodeGen/assign.c6
-rw-r--r--test/CodeGen/atomic.c130
-rw-r--r--test/CodeGen/attr-naked.c9
-rw-r--r--test/CodeGen/blocks-1.c28
-rw-r--r--test/CodeGen/blocks.c7
-rw-r--r--test/CodeGen/blocksignature.c12
-rw-r--r--test/CodeGen/blockstret.c2
-rw-r--r--test/CodeGen/blockwithlocalstatic.c19
-rw-r--r--test/CodeGen/bool_test.c5
-rw-r--r--test/CodeGen/builtins-ppc-altivec.c1029
-rw-r--r--test/CodeGen/builtins-x86.c1
-rw-r--r--test/CodeGen/char-literal.c35
-rw-r--r--test/CodeGen/conditional-gnu-ext.c24
-rw-r--r--test/CodeGen/const-init.c2
-rw-r--r--test/CodeGen/darwin-string-literals.c12
-rw-r--r--test/CodeGen/debug-info-crash.c9
-rw-r--r--test/CodeGen/debug-info-line.c15
-rw-r--r--test/CodeGen/debug-info-var-location.c21
-rw-r--r--test/CodeGen/designated-initializers.c33
-rw-r--r--test/CodeGen/enum.c3
-rw-r--r--test/CodeGen/exceptions.c19
-rw-r--r--test/CodeGen/exprs.c26
-rw-r--r--test/CodeGen/ext-vector-shuffle.c17
-rw-r--r--test/CodeGen/frame-pointer-elim.c29
-rw-r--r--test/CodeGen/func-in-block.c2
-rw-r--r--test/CodeGen/illegal-UTF8.m4
-rw-r--r--test/CodeGen/imaginary.c4
-rw-r--r--test/CodeGen/init.c69
-rw-r--r--test/CodeGen/integer-overflow.c7
-rw-r--r--test/CodeGen/lineno-dbginfo.c2
-rw-r--r--test/CodeGen/mangle.c6
-rw-r--r--test/CodeGen/may-alias.c21
-rw-r--r--test/CodeGen/mcount.c4
-rw-r--r--test/CodeGen/mms-bitfields.c22
-rw-r--r--test/CodeGen/mmx-builtins.c452
-rw-r--r--test/CodeGen/mmx-shift-with-immediate.c23
-rw-r--r--test/CodeGen/ms-anonymous-struct.c99
-rw-r--r--test/CodeGen/mult-alt-generic.c283
-rw-r--r--test/CodeGen/mult-alt-x86.c374
-rw-r--r--test/CodeGen/no-common.c17
-rw-r--r--test/CodeGen/packed-structure.c13
-rw-r--r--test/CodeGen/palignr.c6
-rw-r--r--test/CodeGen/pascal-wchar-string.c12
-rw-r--r--test/CodeGen/pointer-arithmetic.c3
-rw-r--r--test/CodeGen/pointer-signext.c32
-rw-r--r--test/CodeGen/pragma-weak.c2
-rw-r--r--test/CodeGen/predefined-expr.c16
-rw-r--r--test/CodeGen/regparm-flag.c15
-rw-r--r--test/CodeGen/regparm.c5
-rw-r--r--test/CodeGen/sizeof-vla.c2
-rw-r--r--test/CodeGen/statements.c2
-rw-r--r--test/CodeGen/string-literal-short-wstring.c43
-rw-r--r--test/CodeGen/string-literal.c11
-rw-r--r--test/CodeGen/struct-init.c13
-rw-r--r--test/CodeGen/struct-passing.c20
-rw-r--r--test/CodeGen/switch.c17
-rw-r--r--test/CodeGen/thread-specifier.c10
-rw-r--r--test/CodeGen/transparent-union.c25
-rw-r--r--test/CodeGen/va_list_test.c6
-rw-r--r--test/CodeGen/visibility.c77
-rw-r--r--test/CodeGen/vla.c65
-rw-r--r--test/CodeGen/volatile-1.c216
-rw-r--r--test/CodeGen/volatile-2.c23
-rw-r--r--test/CodeGen/x86_32-arguments-darwin.c (renamed from test/CodeGen/x86_32-arguments.c)62
-rw-r--r--test/CodeGen/x86_32-arguments-linux.c51
-rw-r--r--test/CodeGen/x86_32-arguments-realign.c11
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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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;
+}
OpenPOWER on IntegriCloud