summaryrefslogtreecommitdiffstats
path: root/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/2006-01-13-StackSave.c4
-rw-r--r--test/CodeGen/2007-06-18-SextAttrAggregate.c8
-rw-r--r--test/CodeGen/2008-01-07-UnusualIntSize.c7
-rw-r--r--test/CodeGen/2008-04-08-NoExceptions.c6
-rw-r--r--test/CodeGen/2008-07-30-implicit-initialization.c14
-rw-r--r--test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c8
-rw-r--r--test/CodeGen/2009-10-20-GlobalDebug.c4
-rw-r--r--test/CodeGen/2010-02-16-DbgScopes.c6
-rw-r--r--test/CodeGen/2010-03-5-LexicalScope.c4
-rw-r--r--test/CodeGen/PR4611-bitfield-layout.c5
-rw-r--r--test/CodeGen/a5.c5
-rw-r--r--test/CodeGen/aarch64-arguments.c194
-rw-r--r--test/CodeGen/aarch64-inline-asm.c56
-rw-r--r--test/CodeGen/aarch64-type-sizes.c90
-rw-r--r--test/CodeGen/aarch64-varargs.c238
-rw-r--r--test/CodeGen/address-safety-attr.cpp83
-rw-r--r--test/CodeGen/address-space-field1.c4
-rw-r--r--test/CodeGen/alias.c14
-rw-r--r--test/CodeGen/always-inline.c5
-rw-r--r--test/CodeGen/arm-asm-warn.c23
-rw-r--r--test/CodeGen/arm-neon-fma.c19
-rw-r--r--test/CodeGen/atomic_ops.c5
-rw-r--r--test/CodeGen/atomics-inlining.c49
-rw-r--r--test/CodeGen/attr-coldhot.c4
-rw-r--r--test/CodeGen/attr-minsize.cpp40
-rw-r--r--test/CodeGen/attr-naked.c6
-rw-r--r--test/CodeGen/attributes.c23
-rw-r--r--test/CodeGen/bitfield-2.c46
-rw-r--r--test/CodeGen/blocks-seq.c18
-rw-r--r--test/CodeGen/bool_test.c16
-rw-r--r--test/CodeGen/bounds-checking.c2
-rw-r--r--test/CodeGen/builtin-attributes.c4
-rw-r--r--test/CodeGen/builtins-arm.c7
-rw-r--r--test/CodeGen/builtins-mips.c7
-rw-r--r--test/CodeGen/builtins-multiprecision.c150
-rw-r--r--test/CodeGen/builtins-ppc-altivec.c28
-rw-r--r--test/CodeGen/builtins-ppc.c9
-rw-r--r--test/CodeGen/builtinshufflevector2.c8
-rw-r--r--test/CodeGen/c-strings.c33
-rw-r--r--test/CodeGen/c11atomics-ios.c214
-rw-r--r--test/CodeGen/c11atomics.c344
-rw-r--r--test/CodeGen/catch-undef-behavior.c253
-rw-r--r--test/CodeGen/code-coverage.c30
-rw-r--r--test/CodeGen/complex-convert.c717
-rw-r--r--test/CodeGen/compound-assign-overflow.c36
-rw-r--r--test/CodeGen/compound-literal.c34
-rw-r--r--test/CodeGen/debug-info-args.c4
-rw-r--r--test/CodeGen/debug-info-line.c6
-rw-r--r--test/CodeGen/debug-info-scope.c4
-rw-r--r--test/CodeGen/debug-info-static.c2
-rw-r--r--test/CodeGen/debug-info-vector.c7
-rw-r--r--test/CodeGen/exceptions.c9
-rw-r--r--test/CodeGen/fast-math.c11
-rw-r--r--test/CodeGen/finite-math.c11
-rw-r--r--test/CodeGen/frame-pointer-elim.c40
-rw-r--r--test/CodeGen/function-attributes.c51
-rw-r--r--test/CodeGen/functions.c2
-rw-r--r--test/CodeGen/global-blocks-lines.c45
-rw-r--r--test/CodeGen/incomplete-function-type-2.c19
-rw-r--r--test/CodeGen/init.c2
-rw-r--r--test/CodeGen/inline.c94
-rw-r--r--test/CodeGen/intel_ocl_bicc.c11
-rw-r--r--test/CodeGen/le32-regparm.c2
-rw-r--r--test/CodeGen/libcall-declarations.c208
-rw-r--r--test/CodeGen/libcalls-complex.c46
-rw-r--r--test/CodeGen/libcalls.c77
-rw-r--r--test/CodeGen/lifetime2.c17
-rw-r--r--test/CodeGen/linkage-redecl.c10
-rw-r--r--test/CodeGen/mips-constraint-regs.c12
-rw-r--r--test/CodeGen/mips-constraints-mem.c26
-rw-r--r--test/CodeGen/mips-target-data.c14
-rw-r--r--test/CodeGen/mips-vector-arg.c11
-rw-r--r--test/CodeGen/mips16-attr.c17
-rw-r--r--test/CodeGen/mips64-padding-arg.c32
-rw-r--r--test/CodeGen/mrtd.c4
-rw-r--r--test/CodeGen/ms-declspecs.c14
-rw-r--r--test/CodeGen/ms-inline-asm-64.c8
-rw-r--r--test/CodeGen/ms-inline-asm.c260
-rw-r--r--test/CodeGen/ms-inline-asm.cpp26
-rw-r--r--test/CodeGen/mult-alt-generic.c1
-rw-r--r--test/CodeGen/no-opt-volatile-memcpy.c40
-rw-r--r--test/CodeGen/nvptx-cpus.c11
-rw-r--r--test/CodeGen/packed-nest-unpacked.c2
-rw-r--r--test/CodeGen/packed-structure.c1
-rw-r--r--test/CodeGen/parameter-passing.c12
-rw-r--r--test/CodeGen/ppc-atomics.c35
-rw-r--r--test/CodeGen/ppc64-complex-parms.c184
-rw-r--r--test/CodeGen/ppc64-complex-return.c129
-rw-r--r--test/CodeGen/ppc64-extend.c9
-rw-r--r--test/CodeGen/ppc64-varargs-complex.c73
-rw-r--r--test/CodeGen/pr2394.c3
-rw-r--r--test/CodeGen/pragma-weak.c9
-rw-r--r--test/CodeGen/prefetchw-builtins.c12
-rw-r--r--test/CodeGen/r5.c5
-rw-r--r--test/CodeGen/rdrand-builtins.c25
-rw-r--r--test/CodeGen/regparm.c2
-rw-r--r--test/CodeGen/rtm-builtins.c5
-rw-r--r--test/CodeGen/sanitize-init-order.cpp24
-rw-r--r--test/CodeGen/sanitize-recover.c17
-rw-r--r--test/CodeGen/sanitize-thread-attr.cpp61
-rw-r--r--test/CodeGen/sanitize-use-after-scope.c22
-rw-r--r--test/CodeGen/split-debug-filename.c7
-rw-r--r--test/CodeGen/stack-protector.c16
-rw-r--r--test/CodeGen/string-literal.c75
-rw-r--r--test/CodeGen/struct-passing.c7
-rw-r--r--test/CodeGen/tbaa-struct.cpp29
-rw-r--r--test/CodeGen/tbaa.cpp217
-rw-r--r--test/CodeGen/ubsan-blacklist.c31
-rw-r--r--test/CodeGen/ucn-identifiers.c14
-rw-r--r--test/CodeGen/unreachable.c4
-rw-r--r--test/CodeGen/unsigned-overflow.c125
-rw-r--r--test/CodeGen/unsigned-promotion.c143
-rw-r--r--test/CodeGen/unsigned-trapv.c38
-rw-r--r--test/CodeGen/unwind-attr.c17
-rw-r--r--test/CodeGen/visibility.c7
-rw-r--r--test/CodeGen/vla.c6
-rw-r--r--test/CodeGen/volatile.c123
-rw-r--r--test/CodeGen/x86_32-arguments-darwin.c9
-rw-r--r--test/CodeGen/x86_32-arguments-linux.c4
-rw-r--r--test/CodeGen/x86_32-inline-asm.c24
-rw-r--r--test/CodeGen/x86_64-arguments.c38
121 files changed, 4973 insertions, 625 deletions
diff --git a/test/CodeGen/2006-01-13-StackSave.c b/test/CodeGen/2006-01-13-StackSave.c
index 7c506b3..82f4584 100644
--- a/test/CodeGen/2006-01-13-StackSave.c
+++ b/test/CodeGen/2006-01-13-StackSave.c
@@ -1,6 +1,6 @@
// PR691
-// RUN: %clang_cc1 %s -emit-llvm -o - | opt -std-compile-opts | \
-// RUN: llvm-dis | grep llvm.stacksave
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// CHECK: call i8* @llvm.stacksave()
void test(int N) {
int i;
diff --git a/test/CodeGen/2007-06-18-SextAttrAggregate.c b/test/CodeGen/2007-06-18-SextAttrAggregate.c
index 27ae6a9..f548951 100644
--- a/test/CodeGen/2007-06-18-SextAttrAggregate.c
+++ b/test/CodeGen/2007-06-18-SextAttrAggregate.c
@@ -1,6 +1,14 @@
// RUN: %clang_cc1 %s -o - -emit-llvm | FileCheck %s
+// XFAIL: aarch64
+
// PR1513
+// AArch64 ABI actually requires the reverse of what this is testing: the callee
+// does any extensions and remaining bits are unspecified.
+
+// Technically this test wasn't written to test that feature, but it's a
+// valuable check nevertheless.
+
struct s{
long a;
long b;
diff --git a/test/CodeGen/2008-01-07-UnusualIntSize.c b/test/CodeGen/2008-01-07-UnusualIntSize.c
index bf0ca55..c37c89e 100644
--- a/test/CodeGen/2008-01-07-UnusualIntSize.c
+++ b/test/CodeGen/2008-01-07-UnusualIntSize.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// FIXME: 32-bit target?
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
// PR1721
struct s {
@@ -8,8 +9,8 @@ struct s {
// This should have %0 and %1 truncated to 33 bits before any operation.
// This can be done using i33 or an explicit and.
_Bool test(void) {
- // CHECK: and i64 %[[TMP1:[0-9]+]], 8589934591
+ // CHECK: and i64 %[[TMP1:[^,]+]], 8589934591
// CHECK-NOT: and i64 [[TMP1]], 8589934591
- // CHECK: and i64 %{{[0-9]}}, 8589934591
+ // CHECK: and i64 %{{[^,]+}}, 8589934591
return a.u33 + b.u33 != 0;
}
diff --git a/test/CodeGen/2008-04-08-NoExceptions.c b/test/CodeGen/2008-04-08-NoExceptions.c
index ab2781b..1213492 100644
--- a/test/CodeGen/2008-04-08-NoExceptions.c
+++ b/test/CodeGen/2008-04-08-NoExceptions.c
@@ -2,9 +2,11 @@
void f(void);
void g(void) {
- // CHECK: define void @g() nounwind
+ // CHECK: define void @g() [[NUW:#[0-9]+]]
// CHECK-NOT: call void @f() nounwind
f();
}
-// CHECK-NOT: declare void @f() nounwind
+// CHECK-NOT: declare void @f() [[NUW]]
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/2008-07-30-implicit-initialization.c b/test/CodeGen/2008-07-30-implicit-initialization.c
index 8c719bb..e516259 100644
--- a/test/CodeGen/2008-07-30-implicit-initialization.c
+++ b/test/CodeGen/2008-07-30-implicit-initialization.c
@@ -1,6 +1,10 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt --std-compile-opts | llvm-dis > %t
-// RUN: grep "ret i32" %t | count 2
-// RUN: grep "ret i32 0" %t | count 2
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O1 -emit-llvm -o - %s | FileCheck %s
+// CHECK: define i32 @f0()
+// CHECK: ret i32 0
+// CHECK: define i32 @f1()
+// CHECK: ret i32 0
+// CHECK: define i32 @f2()
+// CHECK: ret i32 0
// <rdar://problem/6113085>
struct s0 {
@@ -12,14 +16,10 @@ int f0() {
return x.y;
}
-#if 0
-/* Optimizer isn't smart enough to reduce this since we use
- memset. Hrm. */
int f1() {
struct s0 x[2] = { {0} };
return x[1].x;
}
-#endif
int f2() {
int x[2] = { 0 };
diff --git a/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c b/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
index de06263..429fb1f 100644
--- a/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
+++ b/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis | grep "ret i32 1" | count 3
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O1 -emit-llvm -o - %s | FileCheck %s
+// CHECK: define i32 @f0
+// CHECK: ret i32 1
+// CHECK: define i32 @f1
+// CHECK: ret i32 1
+// CHECK: define i32 @f2
+// CHECK: ret i32 1
// <rdr://6115726>
int f0() {
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
index 8a9dfdd..c48ad28 100644
--- a/test/CodeGen/2009-10-20-GlobalDebug.c
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -6,5 +6,5 @@ int main() {
return 0;
}
-// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !5, metadata !"localstatic", metadata !"localstatic", metadata !"", metadata !6, i32 5, metadata !9, i32 1, i32 1, i32* @main.localstatic} ; [ DW_TAG_variable ]
-// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"global", metadata !"global", metadata !"", metadata !6, i32 3, metadata !9, i32 0, i32 1, i32* @global} ; [ DW_TAG_variable ]
+// CHECK: metadata !{i32 {{.*}}, i32 0, metadata !{{.*}}, metadata !"localstatic", metadata !"localstatic", metadata !"", metadata !{{.*}}, i32 5, metadata !{{.*}}, i32 1, i32 1, i32* @main.localstatic, null} ; [ DW_TAG_variable ]
+// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"global", metadata !"global", metadata !"", metadata !{{.*}}, i32 3, metadata !{{.*}}, i32 0, i32 1, i32* @global, null} ; [ DW_TAG_variable ]
diff --git a/test/CodeGen/2010-02-16-DbgScopes.c b/test/CodeGen/2010-02-16-DbgScopes.c
index b11f920..36484a4 100644
--- a/test/CodeGen/2010-02-16-DbgScopes.c
+++ b/test/CodeGen/2010-02-16-DbgScopes.c
@@ -1,5 +1,9 @@
-// RUN: %clang_cc1 -emit-llvm -g < %s | grep lexical | count 5
+// RUN: %clang_cc1 -emit-llvm -g < %s | FileCheck %s
// Test to check number of lexical scope identified in debug info.
+// CHECK: DW_TAG_lexical_block
+// CHECK: DW_TAG_lexical_block
+// CHECK: DW_TAG_lexical_block
+// CHECK: DW_TAG_lexical_block
extern int bar();
extern void foobar();
diff --git a/test/CodeGen/2010-03-5-LexicalScope.c b/test/CodeGen/2010-03-5-LexicalScope.c
index 0f63ff6..e0e41dd 100644
--- a/test/CodeGen/2010-03-5-LexicalScope.c
+++ b/test/CodeGen/2010-03-5-LexicalScope.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -emit-llvm -O0 -g %s -o - | grep DW_TAG_lexical_block | count 3
+// RUN: %clang_cc1 -emit-llvm -O0 -g %s -o - | FileCheck %s
+// CHECK: DW_TAG_lexical_block
+// CHECK: DW_TAG_lexical_block
int foo(int i) {
if (i) {
int j = 2;
diff --git a/test/CodeGen/PR4611-bitfield-layout.c b/test/CodeGen/PR4611-bitfield-layout.c
index 3975ed0..a383f34 100644
--- a/test/CodeGen/PR4611-bitfield-layout.c
+++ b/test/CodeGen/PR4611-bitfield-layout.c
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o %t
-// RUN: grep "struct.object_entry = type { i8, \[2 x i8\], i8 }" %t
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+//
+// CHECK: struct.object_entry = type { [4 x i8] }
struct object_entry {
unsigned int type:3, pack_id:16, depth:13;
diff --git a/test/CodeGen/a5.c b/test/CodeGen/a5.c
new file mode 100644
index 0000000..b342d35
--- /dev/null
+++ b/test/CodeGen/a5.c
@@ -0,0 +1,5 @@
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a5 -emit-llvm -S %s -o /dev/null
+
+int main() {
+ return 0;
+}
diff --git a/test/CodeGen/aarch64-arguments.c b/test/CodeGen/aarch64-arguments.c
new file mode 100644
index 0000000..901e734
--- /dev/null
+++ b/test/CodeGen/aarch64-arguments.c
@@ -0,0 +1,194 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=PCS %s
+
+// Sign extension is performed by the callee on AArch64, which means
+// that we *shouldn't* tag arguments and returns with their extension.
+
+// PCS: define i8 @f0(i16 %a)
+char f0(short a) {
+ return a;
+}
+
+// PCS: define [1 x i64] @f1()
+struct s1 { char f0; };
+struct s1 f1(void) {}
+
+// PCS: define [1 x i64] @f2()
+struct s2 { short f0; };
+struct s2 f2(void) {}
+
+// PCS: define [1 x i64] @f3()
+struct s3 { int f0; };
+struct s3 f3(void) {}
+
+// PCS: define [1 x i64] @f4()
+struct s4 { struct s4_0 { int f0; } f0; };
+struct s4 f4(void) {}
+
+// PCS: define [1 x i64] @f5()
+struct s5 { struct { } f0; int f1; };
+struct s5 f5(void) {}
+
+// PCS: define [1 x i64] @f6()
+struct s6 { int f0[1]; };
+struct s6 f6(void) {}
+
+// PCS: define void @f7()
+struct s7 { struct { int : 0; } f0; };
+struct s7 f7(void) {}
+
+// PCS: define void @f8()
+struct s8 { struct { int : 0; } f0[1]; };
+struct s8 f8(void) {}
+
+// PCS: define [1 x i64] @f9()
+struct s9 { long f0; int : 0; };
+struct s9 f9(void) {}
+
+// PCS: define [1 x i64] @f10()
+struct s10 { long f0; int : 0; int : 0; };
+struct s10 f10(void) {}
+
+// PCS: define [1 x i64] @f11()
+struct s11 { int : 0; long f0; };
+struct s11 f11(void) {}
+
+// PCS: define [1 x i64] @f12()
+union u12 { char f0; short f1; int f2; long f3; };
+union u12 f12(void) {}
+
+// PCS: define %struct.s13 @f13()
+struct s13 { float f0; };
+struct s13 f13(void) {}
+
+// PCS: define %union.u14 @f14()
+union u14 { float f0; };
+union u14 f14(void) {}
+
+// PCS: define void @f15()
+void f15(struct s7 a0) {}
+
+// PCS: define void @f16()
+void f16(struct s8 a0) {}
+
+// PCS: define [1 x i64] @f17()
+struct s17 { short f0 : 13; char f1 : 4; };
+struct s17 f17(void) {}
+
+// PCS: define [1 x i64] @f18()
+struct s18 { short f0; char f1 : 4; };
+struct s18 f18(void) {}
+
+// PCS: define [1 x i64] @f19()
+struct s19 { long f0; struct s8 f1; };
+struct s19 f19(void) {}
+
+// PCS: define [1 x i64] @f20()
+struct s20 { struct s8 f1; long f0; };
+struct s20 f20(void) {}
+
+// PCS: define [1 x i64] @f21()
+struct s21 { struct {} f1; long f0 : 4; };
+struct s21 f21(void) {}
+
+// PCS: define { float, float } @f22()
+// PCS: define { double, double } @f23(
+_Complex float f22(void) {}
+_Complex double f23(void) {}
+
+// PCS: define [1 x i64] @f24()
+struct s24 { _Complex char f0; };
+struct s24 f24() {}
+
+// PCS: define [1 x i64] @f25()
+struct s25 { _Complex short f0; };
+struct s25 f25() {}
+
+// PCS: define [1 x i64] @f26()
+struct s26 { _Complex int f0; };
+struct s26 f26() {}
+
+// PCS: define [2 x i64] @f27()
+struct s27 { _Complex long f0; };
+struct s27 f27() {}
+
+// PCS: define void @f28(i8 %a, i16 %b, i32 %c, i64 %d, float %e, double %f)
+void f28(char a, short b, int c, long d, float e, double f) {}
+
+// PCS: define void @f29([2 x i64] %a
+struct s29 { int arr[4]; };
+void f29(struct s29 a) {}
+
+// PCS: define void @f30(%struct.s30* %a)
+struct s30 { int arr[4]; char c;};
+void f30(struct s30 a) {}
+
+// PCS: define void @f31([4 x double] %a
+struct s31 { double arr[4]; };
+void f31(struct s31 a) {}
+
+// PCS: define void @f32(%struct.s32* %a)
+struct s32 { float arr[5]; };
+void f32(struct s32 a) {}
+
+// Not the only solution, but it *is* an HFA.
+// PCS: define void @f33([3 x float] %a.coerce0, float %a.coerce1)
+struct s33 { float arr[3]; float a; };
+void f33(struct s33 a) {}
+
+// PCS: define void @f34(%struct.s34* noalias sret
+struct s34 { int a[4]; char b };
+struct s34 f34(void) {}
+
+// PCS: define void @f35()
+struct s35 {};
+void f35(struct s35 a) {}
+
+// Check padding is added:
+// PCS: @f36(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s36* byval align 8 %stacked)
+struct s36 { long a, b; };
+void f36(int x0, int x1, int x2, int x3, int x4, int x5, int x6, struct s36 stacked) {}
+
+// But only once:
+// PCS: @f37(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s37* byval align 8 %stacked, %struct.s37* byval align 8 %stacked2)
+struct s37 { long a, b; };
+void f37(int x0, int x1, int x2, int x3, int x4, int x5, int x6, struct s37 stacked, struct s37 stacked2) {}
+
+// Check for HFA padding args. Also, they should not end up on the stack in a
+// way which will have holes in when lowered further by LLVM. In particular [3 x
+// float] would be unacceptable.
+
+// PCS: @f38(float %s0, double %d1, float %s2, float %s3, float %s4, float %s5, [2 x float], %struct.s38* byval align 4 %stacked)
+struct s38 { float a, b, c; };
+void f38(float s0, double d1, float s2, float s3, float s4, float s5, struct s38 stacked) {}
+
+// Check both VFP and integer arguments are padded (also that pointers and enums
+// get counted as integer types correctly).
+struct s39_int { long a, b; };
+struct s39_float { float a, b, c, d; };
+enum s39_enum { Val1, Val2 };
+// PCS: @f39(float %s0, i32 %x0, float %s1, i32* %x1, float %s2, i32 %x2, float %s3, float %s4, i32 %x3, [3 x float], %struct.s39_float* byval align 4 %stacked, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s39_int* byval align 8 %stacked2)
+void f39(float s0, int x0, float s1, int *x1, float s2, enum s39_enum x2, float s3, float s4,
+ int x3, struct s39_float stacked, int x4, int x5, int x6,
+ struct s39_int stacked2) {}
+
+struct s40 { __int128 a; };
+// PCS: @f40(i32 %x0, [1 x i128] %x2_3.coerce, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s40* byval align 16 %stacked)
+void f40(int x0, struct s40 x2_3, int x4, int x5, int x6, struct s40 stacked) {}
+
+// Checking: __int128 will get properly aligned type, with padding so big struct doesn't use x7.
+struct s41 { int arr[5]; };
+// PCS: @f41(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5, i32 %x6, [1 x i64], i128* byval align 16, %struct.s41* %stacked2)
+int f41(int x0, int x1, int x2, int x3, int x4, int x5, int x6, __int128 stacked, struct s41 stacked2) {}
+
+// Checking: __int128 needing to be aligned in registers will consume correct
+// number. Previously padding was inserted before "stacked" because x6_7 was
+// "allocated" to x5 and x6 by clang.
+// PCS: @f42(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i128 %x6_7, i128* byval align 16)
+void f42(int x0, int x1, int x2, int x3, int x4, __int128 x6_7, __int128 stacked) {}
+
+// Checking: __fp16 is extended to double when calling variadic functions
+void variadic(int a, ...);
+void f43(__fp16 *in) {
+ variadic(42, *in);
+// CHECK: call void @variadic(i32 42, double
+}
diff --git a/test/CodeGen/aarch64-inline-asm.c b/test/CodeGen/aarch64-inline-asm.c
new file mode 100644
index 0000000..ca39c6e
--- /dev/null
+++ b/test/CodeGen/aarch64-inline-asm.c
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// The only part clang really deals with is the lvalue/rvalue
+// distinction on constraints. It's sufficient to emit llvm and make
+// sure that's sane.
+
+long var;
+
+void test_generic_constraints(int var32, long var64) {
+ asm("add %0, %1, %1" : "=r"(var32) : "0"(var32));
+// CHECK: [[R32_ARG:%[a-zA-Z0-9]+]] = load i32*
+// CHECK: call i32 asm "add $0, $1, $1", "=r,0"(i32 [[R32_ARG]])
+
+ asm("add %0, %1, %1" : "=r"(var64) : "0"(var64));
+// CHECK: [[R32_ARG:%[a-zA-Z0-9]+]] = load i64*
+// CHECK: call i64 asm "add $0, $1, $1", "=r,0"(i64 [[R32_ARG]])
+
+ asm("ldr %0, %1" : "=r"(var32) : "m"(var));
+ asm("ldr %0, [%1]" : "=r"(var64) : "r"(&var));
+// CHECK: call i32 asm "ldr $0, $1", "=r,*m"(i64* @var)
+// CHECK: call i64 asm "ldr $0, [$1]", "=r,r"(i64* @var)
+}
+
+float f;
+double d;
+void test_constraint_w() {
+ asm("fadd %s0, %s1, %s1" : "=w"(f) : "w"(f));
+// CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load float* @f
+// CHECK: call float asm "fadd ${0:s}, ${1:s}, ${1:s}", "=w,w"(float [[FLT_ARG]])
+
+ asm("fadd %d0, %d1, %d1" : "=w"(d) : "w"(d));
+// CHECK: [[DBL_ARG:%[a-zA-Z_0-9]+]] = load double* @d
+// CHECK: call double asm "fadd ${0:d}, ${1:d}, ${1:d}", "=w,w"(double [[DBL_ARG]])
+}
+
+void test_constraints_immed(void) {
+ asm("add x0, x0, %0" : : "I"(4095) : "x0");
+ asm("and w0, w0, %0" : : "K"(0xaaaaaaaa) : "w0");
+ asm("and x0, x0, %0" : : "L"(0xaaaaaaaaaaaaaaaa) : "x0");
+// CHECK: call void asm sideeffect "add x0, x0, $0", "I,~{x0}"(i32 4095)
+// CHECK: call void asm sideeffect "and w0, w0, $0", "K,~{w0}"(i32 -1431655766)
+// CHECK: call void asm sideeffect "and x0, x0, $0", "L,~{x0}"(i64 -6148914691236517206)
+}
+
+void test_constraint_S(void) {
+ int *addr;
+ asm("adrp %0, %A1\n\t"
+ "add %0, %0, %L1" : "=r"(addr) : "S"(&var));
+// CHECK: call i32* asm "adrp $0, ${1:A}\0A\09add $0, $0, ${1:L}", "=r,S"(i64* @var)
+}
+
+void test_constraint_Q(void) {
+ int val;
+ asm("ldxr %0, %1" : "=r"(val) : "Q"(var));
+// CHECK: call i32 asm "ldxr $0, $1", "=r,*Q"(i64* @var)
+}
diff --git a/test/CodeGen/aarch64-type-sizes.c b/test/CodeGen/aarch64-type-sizes.c
new file mode 100644
index 0000000..3b9c9fc
--- /dev/null
+++ b/test/CodeGen/aarch64-type-sizes.c
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
+
+// char by definition has size 1
+
+int check_short() {
+ return sizeof(short);
+// CHECK: ret i32 2
+}
+
+int check_int() {
+ return sizeof(int);
+// CHECK: ret i32 4
+}
+
+int check_long() {
+// Both 4 and 8 are permitted under the PCS, Linux says 8!
+ return sizeof(long);
+// CHECK: ret i32 8
+}
+
+int check_longlong() {
+ return sizeof(long long);
+// CHECK: ret i32 8
+}
+
+int check_int128() {
+ return sizeof(__int128);
+// CHECK: ret i32 16
+}
+
+int check_fp16() {
+ return sizeof(__fp16);
+// CHECK: ret i32 2
+}
+
+int check_float() {
+ return sizeof(float);
+// CHECK: ret i32 4
+}
+
+int check_double() {
+ return sizeof(double);
+// CHECK: ret i32 8
+}
+
+int check_longdouble() {
+ return sizeof(long double);
+// CHECK: ret i32 16
+}
+
+int check_floatComplex() {
+ return sizeof(float _Complex);
+// CHECK: ret i32 8
+}
+
+int check_doubleComplex() {
+ return sizeof(double _Complex);
+// CHECK: ret i32 16
+}
+
+int check_longdoubleComplex() {
+ return sizeof(long double _Complex);
+// CHECK: ret i32 32
+}
+
+int check_bool() {
+ return sizeof(_Bool);
+// CHECK: ret i32 1
+}
+
+int check_wchar() {
+// PCS allows either unsigned short or unsigned int. Linux again says "bigger!"
+ return sizeof(__WCHAR_TYPE__);
+// CHECK: ret i32 4
+}
+
+int check_wchar_unsigned() {
+ return (__WCHAR_TYPE__)-1 > (__WCHAR_TYPE__)0;
+// CHECK: ret i32 1
+}
+
+enum Small {
+ Item
+};
+
+int foo() {
+ return sizeof(enum Small);
+// CHECK: ret i32 4
+}
+
diff --git a/test/CodeGen/aarch64-varargs.c b/test/CodeGen/aarch64-varargs.c
new file mode 100644
index 0000000..324a070
--- /dev/null
+++ b/test/CodeGen/aarch64-varargs.c
@@ -0,0 +1,238 @@
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -o - %s | FileCheck %s
+#include <stdarg.h>
+
+// Obviously there's more than one way to implement va_arg. This test should at
+// least prevent unintentional regressions caused by refactoring.
+
+va_list the_list;
+
+int simple_int(void) {
+// CHECK: define i32 @simple_int
+ return va_arg(the_list, int);
+// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
+
+// CHECK: [[VAARG_MAYBE_REG]]
+// CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 8
+// CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
+// CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
+
+// CHECK: [[VAARG_IN_REG]]
+// CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
+// CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
+// CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to i32*
+// CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
+
+// CHECK: [[VAARG_ON_STACK]]
+// CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
+// CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to i32*
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_END]]
+// CHECK: [[ADDR:%[a-z._0-9]+]] = phi i32* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
+// CHECK: [[RESULT:%[a-z_0-9]+]] = load i32* [[ADDR]]
+// CHECK: ret i32 [[RESULT]]
+}
+
+__int128 aligned_int(void) {
+// CHECK: define i128 @aligned_int
+ return va_arg(the_list, __int128);
+// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
+
+// CHECK: [[VAARG_MAYBE_REG]]
+// CHECK: [[ALIGN_REGOFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 15
+// CHECK: [[ALIGNED_REGOFFS:%[a-z_0-9]+]] = and i32 [[ALIGN_REGOFFS]], -16
+// CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[ALIGNED_REGOFFS]], 16
+// CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
+// CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
+
+// CHECK: [[VAARG_IN_REG]]
+// CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
+// CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[ALIGNED_REGOFFS]]
+// CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to i128*
+// CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
+
+// CHECK: [[VAARG_ON_STACK]]
+// CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[STACKINT:%[a-z_0-9]+]] = ptrtoint i8* [[STACK]] to i64
+// CHECK: [[ALIGN_STACK:%[a-z_0-9]+]] = add i64 [[STACKINT]], 15
+// CHECK: [[ALIGNED_STACK_INT:%[a-z_0-9]+]] = and i64 [[ALIGN_STACK]], -16
+// CHECK: [[ALIGNED_STACK_PTR:%[a-z_0-9]+]] = inttoptr i64 [[ALIGNED_STACK_INT]] to i8*
+// CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[ALIGNED_STACK_PTR]], i32 16
+// CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[ALIGNED_STACK_PTR]] to i128*
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_END]]
+// CHECK: [[ADDR:%[a-z._0-9]+]] = phi i128* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
+// CHECK: [[RESULT:%[a-z_0-9]+]] = load i128* [[ADDR]]
+// CHECK: ret i128 [[RESULT]]
+}
+
+struct bigstruct {
+ int a[10];
+};
+
+struct bigstruct simple_indirect(void) {
+// CHECK: define void @simple_indirect
+ return va_arg(the_list, struct bigstruct);
+// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
+
+// CHECK: [[VAARG_MAYBE_REG]]
+// CHECK-NOT: and i32
+// CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 8
+// CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
+// CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
+
+// CHECK: [[VAARG_IN_REG]]
+// CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
+// CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
+// CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to %struct.bigstruct**
+// CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
+
+// CHECK: [[VAARG_ON_STACK]]
+// CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK-NOT: and i64
+// CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
+// CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to %struct.bigstruct**
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_END]]
+// CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.bigstruct** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
+// CHECK: load %struct.bigstruct** [[ADDR]]
+}
+
+struct aligned_bigstruct {
+ float a;
+ long double b;
+};
+
+struct aligned_bigstruct simple_aligned_indirect(void) {
+// CHECK: define void @simple_aligned_indirect
+ return va_arg(the_list, struct aligned_bigstruct);
+// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
+
+// CHECK: [[VAARG_MAYBE_REG]]
+// CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 8
+// CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
+// CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
+// CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
+
+// CHECK: [[VAARG_IN_REG]]
+// CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
+// CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
+// CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to %struct.aligned_bigstruct**
+// CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
+
+// CHECK: [[VAARG_ON_STACK]]
+// CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
+// CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to %struct.aligned_bigstruct**
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_END]]
+// CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.aligned_bigstruct** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
+// CHECK: load %struct.aligned_bigstruct** [[ADDR]]
+}
+
+double simple_double(void) {
+// CHECK: define double @simple_double
+ return va_arg(the_list, double);
+// CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
+// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK]], label %[[VAARG_MAYBE_REG]]
+
+// CHECK: [[VAARG_MAYBE_REG]]
+// CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[VR_OFFS]], 16
+// CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
+// CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
+// CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
+
+// CHECK: [[VAARG_IN_REG]]
+// CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 2)
+// CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[VR_OFFS]]
+// CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to double*
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_ON_STACK]]
+// CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
+// CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to double*
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_END]]
+// CHECK: [[ADDR:%[a-z._0-9]+]] = phi double* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
+// CHECK: [[RESULT:%[a-z_0-9]+]] = load double* [[ADDR]]
+// CHECK: ret double [[RESULT]]
+}
+
+struct hfa {
+ float a, b;
+};
+
+struct hfa simple_hfa(void) {
+// CHECK: define %struct.hfa @simple_hfa
+ return va_arg(the_list, struct hfa);
+// CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
+// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
+
+// CHECK: [[VAARG_MAYBE_REG]]
+// CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[VR_OFFS]], 32
+// CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
+// CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
+// CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
+
+// CHECK: [[VAARG_IN_REG]]
+// CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 2)
+// CHECK: [[FIRST_REG:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[VR_OFFS]]
+// CHECK: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 0
+// CHECK: [[EL_TYPED:%[a-z_0-9]+]] = bitcast i8* [[EL_ADDR]] to float*
+// CHECK: [[EL_TMPADDR:%[a-z_0-9]+]] = getelementptr inbounds [2 x float]* %[[TMP_HFA:[a-z_.0-9]+]], i32 0, i32 0
+// CHECK: [[EL:%[a-z_0-9]+]] = load float* [[EL_TYPED]]
+// CHECK: store float [[EL]], float* [[EL_TMPADDR]]
+// CHECK: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 16
+// CHECK: [[EL_TYPED:%[a-z_0-9]+]] = bitcast i8* [[EL_ADDR]] to float*
+// CHECK: [[EL_TMPADDR:%[a-z_0-9]+]] = getelementptr inbounds [2 x float]* %[[TMP_HFA]], i32 0, i32 1
+// CHECK: [[EL:%[a-z_0-9]+]] = load float* [[EL_TYPED]]
+// CHECK: store float [[EL]], float* [[EL_TMPADDR]]
+// CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast [2 x float]* %[[TMP_HFA]] to %struct.hfa*
+// CHECK: br label %[[VAARG_END:[a-z_.0-9]+]]
+
+// CHECK: [[VAARG_ON_STACK]]
+// CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
+// CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to %struct.hfa*
+// CHECK: br label %[[VAARG_END]]
+
+// CHECK: [[VAARG_END]]
+// CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.hfa* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
+}
+
+void check_start(int n, ...) {
+// CHECK: define void @check_start(i32 %n, ...)
+
+ va_list the_list;
+ va_start(the_list, n);
+// CHECK: [[THE_LIST:%[a-z_0-9]+]] = alloca %struct.__va_list
+// CHECK: [[VOIDP_THE_LIST:%[a-z_0-9]+]] = bitcast %struct.__va_list* [[THE_LIST]] to i8*
+// CHECK: call void @llvm.va_start(i8* [[VOIDP_THE_LIST]])
+}
+
+
diff --git a/test/CodeGen/address-safety-attr.cpp b/test/CodeGen/address-safety-attr.cpp
index 5c9862d..f94efd6 100644
--- a/test/CodeGen/address-safety-attr.cpp
+++ b/test/CodeGen/address-safety-attr.cpp
@@ -1,41 +1,80 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=address | FileCheck -check-prefix ASAN %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=address | FileCheck -check-prefix=ASAN %s
+// RUN: echo "src:%s" > %t.file.blacklist
+// RUN: echo "fun:*BlacklistedFunction*" > %t.func.blacklist
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=address -fsanitize-blacklist=%t.file.blacklist | FileCheck -check-prefix=BLFILE %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=address -fsanitize-blacklist=%t.func.blacklist | FileCheck -check-prefix=BLFUNC %s
-// The address_safety attribute should be attached to functions
-// when AddressSanitizer is enabled, unless no_address_safety_analysis attribute
+// FIXME: %t.file.blacklist is like "src:x:\path\to\clang\test\CodeGen\address-safety-attr.cpp"
+// REQUIRES: shell
+
+// The sanitize_address attribute should be attached to functions
+// when AddressSanitizer is enabled, unless no_sanitize_address attribute
// is present.
-// CHECK-NOT: NoAddressSafety1{{.*}} address_safety
-// ASAN-NOT: NoAddressSafety1{{.*}} address_safety
-__attribute__((no_address_safety_analysis))
+// WITHOUT: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
+// BLFILE: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
+// BLFUNC: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
+// ASAN: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
+__attribute__((no_sanitize_address))
int NoAddressSafety1(int *a) { return *a; }
-// CHECK-NOT: NoAddressSafety2{{.*}} address_safety
-// ASAN-NOT: NoAddressSafety2{{.*}} address_safety
-__attribute__((no_address_safety_analysis))
+// WITHOUT: NoAddressSafety2{{.*}}) [[NOATTR]]
+// BLFILE: NoAddressSafety2{{.*}}) [[NOATTR]]
+// BLFUNC: NoAddressSafety2{{.*}}) [[NOATTR]]
+// ASAN: NoAddressSafety2{{.*}}) [[NOATTR]]
+__attribute__((no_sanitize_address))
int NoAddressSafety2(int *a);
int NoAddressSafety2(int *a) { return *a; }
-// CHECK-NOT: AddressSafetyOk{{.*}} address_safety
-// ASAN: AddressSafetyOk{{.*}} address_safety
+// WITHOUT: AddressSafetyOk{{.*}}) [[NOATTR]]
+// BLFILE: AddressSafetyOk{{.*}}) [[NOATTR]]
+// BLFUNC: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
+// ASAN: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
int AddressSafetyOk(int *a) { return *a; }
-// CHECK-NOT: TemplateNoAddressSafety{{.*}} address_safety
-// ASAN-NOT: TemplateNoAddressSafety{{.*}} address_safety
-template<int i>
-__attribute__((no_address_safety_analysis))
-int TemplateNoAddressSafety() { return i; }
+// WITHOUT: BlacklistedFunction{{.*}}) [[NOATTR]]
+// BLFILE: BlacklistedFunction{{.*}}) [[NOATTR]]
+// BLFUNC: BlacklistedFunction{{.*}}) [[NOATTR]]
+// ASAN: BlacklistedFunction{{.*}}) [[WITH]]
+int BlacklistedFunction(int *a) { return *a; }
-// CHECK-NOT: TemplateAddressSafetyOk{{.*}} address_safety
-// ASAN: TemplateAddressSafetyOk{{.*}} address_safety
+// WITHOUT: TemplateAddressSafetyOk{{.*}}) [[NOATTR]]
+// BLFILE: TemplateAddressSafetyOk{{.*}}) [[NOATTR]]
+// BLFUNC: TemplateAddressSafetyOk{{.*}}) [[WITH]]
+// ASAN: TemplateAddressSafetyOk{{.*}}) [[WITH]]
template<int i>
int TemplateAddressSafetyOk() { return i; }
+// WITHOUT: TemplateNoAddressSafety{{.*}}) [[NOATTR]]
+// BLFILE: TemplateNoAddressSafety{{.*}}) [[NOATTR]]
+// BLFUNC: TemplateNoAddressSafety{{.*}}) [[NOATTR]]
+// ASAN: TemplateNoAddressSafety{{.*}}) [[NOATTR]]
+template<int i>
+__attribute__((no_sanitize_address))
+int TemplateNoAddressSafety() { return i; }
+
int force_instance = TemplateAddressSafetyOk<42>()
+ TemplateNoAddressSafety<42>();
-// Check that __cxx_global_var_init* get the address_safety attribute.
+// Check that __cxx_global_var_init* get the sanitize_address attribute.
int global1 = 0;
int global2 = *(int*)((char*)&global1+1);
-// CHECK-NOT: @__cxx_global_var_init{{.*}}address_safety
-// ASAN: @__cxx_global_var_init{{.*}}address_safety
+// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR_NO_TF:#[0-9]+]]
+// BLFILE: @__cxx_global_var_init{{.*}}[[NOATTR_NO_TF:#[0-9]+]]
+// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH_NO_TF:#[0-9]+]]
+// ASAN: @__cxx_global_var_init{{.*}}[[WITH_NO_TF:#[0-9]+]]
+
+// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
+// WITHOUT: attributes [[NOATTR_NO_TF]] = { nounwind }
+
+// BLFILE: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BLFILE: attributes [[NOATTR_NO_TF]] = { nounwind }
+
+// BLFUNC: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BLFUNC: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
+// BLFUNC: attributes [[WITH_NO_TF]] = { nounwind sanitize_address }
+
+// ASAN: attributes [[NOATTR]] = { nounwind{{.*}} }
+// ASAN: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
+// ASAN: attributes [[WITH_NO_TF]] = { nounwind sanitize_address }
diff --git a/test/CodeGen/address-space-field1.c b/test/CodeGen/address-space-field1.c
index e9c1871..c6b3181 100644
--- a/test/CodeGen/address-space-field1.c
+++ b/test/CodeGen/address-space-field1.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 < %s -o - | FileCheck %s
// CHECK:%struct.S = type { i32, i32 }
-// CHECK:define void @test_addrspace(%struct.S addrspace(1)* %p1, %struct.S addrspace(2)* %p2) nounwind
+// CHECK:define void @test_addrspace(%struct.S addrspace(1)* %p1, %struct.S addrspace(2)* %p2) [[NUW:#[0-9]+]]
// CHECK: [[p1addr:%.*]] = alloca %struct.S addrspace(1)*
// CHECK: [[p2addr:%.*]] = alloca %struct.S addrspace(2)*
// CHECK: store %struct.S addrspace(1)* %p1, %struct.S addrspace(1)** [[p1addr]]
@@ -36,3 +36,5 @@ void test_addrspace(__addr1 S* p1, __addr2 S*p2) {
p1->a = p2->b;
p1->b = p2->a;
}
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c
index 0ccbca6..a8380a3 100644
--- a/test/CodeGen/alias.c
+++ b/test/CodeGen/alias.c
@@ -14,7 +14,7 @@ void f0(void) { }
extern void f1(void);
extern void f1(void) __attribute((alias("f0")));
// CHECKBASIC: @f1 = alias void ()* @f0
-// CHECKBASIC: define void @f0() nounwind {
+// CHECKBASIC: define void @f0() [[NUW:#[0-9]+]] {
// Make sure that aliases cause referenced values to be emitted.
// PR3200
@@ -34,13 +34,17 @@ static int inner_weak(int a) { return 0; }
extern __typeof(inner) inner_a __attribute__((alias("inner")));
static __typeof(inner_weak) inner_weak_a __attribute__((weakref, alias("inner_weak")));
// CHECKCC: @inner_a = alias i32 (i32)* @inner
-// CHECKCC: define internal arm_aapcs_vfpcc i32 @inner(i32 %a) nounwind {
+// CHECKCC: define internal arm_aapcs_vfpcc i32 @inner(i32 %a) [[NUW:#[0-9]+]] {
int outer(int a) { return inner(a); }
-// CHECKCC: define arm_aapcs_vfpcc i32 @outer(i32 %a) nounwind {
+// CHECKCC: define arm_aapcs_vfpcc i32 @outer(i32 %a) [[NUW]] {
// CHECKCC: call arm_aapcs_vfpcc i32 @inner(i32 %{{.*}})
int outer_weak(int a) { return inner_weak_a(a); }
-// CHECKCC: define arm_aapcs_vfpcc i32 @outer_weak(i32 %a) nounwind {
+// CHECKCC: define arm_aapcs_vfpcc i32 @outer_weak(i32 %a) [[NUW]] {
// CHECKCC: call arm_aapcs_vfpcc i32 @inner_weak(i32 %{{.*}})
-// CHECKCC: define internal arm_aapcs_vfpcc i32 @inner_weak(i32 %a) nounwind {
+// CHECKCC: define internal arm_aapcs_vfpcc i32 @inner_weak(i32 %a) [[NUW]] {
+
+// CHECKBASIC: attributes [[NUW]] = { nounwind{{.*}} }
+
+// CHECKCC: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/always-inline.c b/test/CodeGen/always-inline.c
index dc74be5..c9fd1ae 100644
--- a/test/CodeGen/always-inline.c
+++ b/test/CodeGen/always-inline.c
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | grep call | not grep foo
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fno-inline -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-NOT: foo
void bar() {
}
diff --git a/test/CodeGen/arm-asm-warn.c b/test/CodeGen/arm-asm-warn.c
index 0c4e97a..9b52dd6 100644
--- a/test/CodeGen/arm-asm-warn.c
+++ b/test/CodeGen/arm-asm-warn.c
@@ -1,7 +1,20 @@
// REQUIRES: arm-registered-target
// RUN: %clang_cc1 -triple armv7 %s -emit-llvm -o /dev/null
-// <rdar://problem/12284092>
+char bar();
+
+void t1(int x, char y) {
+ __asm__ volatile("mcr p15, 0, %1, c9, c12, 5;"
+ "mrc p15, 0, %0, c9, c13, 2;"
+ : "=r" (x)
+ : "r" (bar())); // no warning
+ __asm__ volatile("foo %0, %1"
+ : "+r" (x),
+ "+r" (y)
+ :);
+}
+
+// <rdar://problem/12284092>
typedef __attribute__((neon_vector_type(2))) long long int64x2_t;
typedef struct int64x2x4_t {
int64x2_t val[4];
@@ -9,10 +22,10 @@ typedef struct int64x2x4_t {
int64x2x4_t t2(const long long a[]) {
int64x2x4_t r;
__asm__("vldm %[a], { %q[r0], %q[r1], %q[r2], %q[r3] }"
- : [r0] "=r"(r.val[0]), // expected-warning {{the size being stored is truncated, use a modifier to specify the size}}
- [r1] "=r"(r.val[1]), // expected-warning {{the size being stored is truncated, use a modifier to specify the size}}
- [r2] "=r"(r.val[2]), // expected-warning {{the size being stored is truncated, use a modifier to specify the size}}
- [r3] "=r"(r.val[3]) // expected-warning {{the size being stored is truncated, use a modifier to specify the size}}
+ : [r0] "=r"(r.val[0]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r1] "=r"(r.val[1]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r2] "=r"(r.val[2]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r3] "=r"(r.val[3]) // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
: [a] "r"(a));
return r;
}
diff --git a/test/CodeGen/arm-neon-fma.c b/test/CodeGen/arm-neon-fma.c
new file mode 100644
index 0000000..994702d
--- /dev/null
+++ b/test/CodeGen/arm-neon-fma.c
@@ -0,0 +1,19 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple thumbv7-none-linux-gnueabihf \
+// RUN: -target-abi aapcs \
+// RUN: -target-cpu cortex-a8 \
+// RUN: -mfloat-abi hard \
+// RUN: -ffreestanding \
+// RUN: -O3 -S -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_neon.h>
+
+float32x2_t test_fma_order(float32x2_t accum, float32x2_t lhs, float32x2_t rhs) {
+ return vfma_f32(accum, lhs, rhs);
+// CHECK: call <2 x float> @llvm.fma.v2f32(<2 x float> %lhs, <2 x float> %rhs, <2 x float> %accum)
+}
+
+float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) {
+ return vfmaq_f32(accum, lhs, rhs);
+// CHECK: call <4 x float> @llvm.fma.v4f32(<4 x float> %lhs, <4 x float> %rhs, <4 x float> %accum)
+}
diff --git a/test/CodeGen/atomic_ops.c b/test/CodeGen/atomic_ops.c
index 481d1e0..910e9b9 100644
--- a/test/CodeGen/atomic_ops.c
+++ b/test/CodeGen/atomic_ops.c
@@ -15,9 +15,4 @@ void foo(int x)
// CHECK: sdiv i32
// CHECK: cmpxchg i16*
- // These should be emitting atomicrmw instructions, but they aren't yet
- i += 2; // CHECK: cmpxchg
- i -= 2; // CHECK: cmpxchg
- i++; // CHECK: cmpxchg
- i--; // CHECK: cmpxchg
}
diff --git a/test/CodeGen/atomics-inlining.c b/test/CodeGen/atomics-inlining.c
new file mode 100644
index 0000000..9b0d413
--- /dev/null
+++ b/test/CodeGen/atomics-inlining.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=PPC32
+// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=PPC64
+// RUN: %clang_cc1 -triple mipsel-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS32
+// RUN: %clang_cc1 -triple mips64el-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS64
+
+unsigned char c1, c2;
+unsigned short s1, s2;
+unsigned int i1, i2;
+unsigned long long ll1, ll2;
+
+enum memory_order {
+ memory_order_relaxed,
+ memory_order_consume,
+ memory_order_acquire,
+ memory_order_release,
+ memory_order_acq_rel,
+ memory_order_seq_cst
+};
+
+void test1(void) {
+ (void)__atomic_load(&c1, &c2, memory_order_seq_cst);
+ (void)__atomic_load(&s1, &s2, memory_order_seq_cst);
+ (void)__atomic_load(&i1, &i2, memory_order_seq_cst);
+ (void)__atomic_load(&ll1, &ll2, memory_order_seq_cst);
+
+// PPC32: define void @test1
+// PPC32: load atomic i8* @c1 seq_cst
+// PPC32: load atomic i16* @s1 seq_cst
+// PPC32: load atomic i32* @i1 seq_cst
+// PPC32: call void @__atomic_load(i32 8, i8* bitcast (i64* @ll1 to i8*)
+
+// PPC64: define void @test1
+// PPC64: load atomic i8* @c1 seq_cst
+// PPC64: load atomic i16* @s1 seq_cst
+// PPC64: load atomic i32* @i1 seq_cst
+// PPC64: load atomic i64* @ll1 seq_cst
+
+// MIPS32: define void @test1
+// MIPS32: load atomic i8* @c1 seq_cst
+// MIPS32: load atomic i16* @s1 seq_cst
+// MIPS32: load atomic i32* @i1 seq_cst
+// MIPS32: call void @__atomic_load(i32 8, i8* bitcast (i64* @ll1 to i8*)
+
+// MIPS64: define void @test1
+// MIPS64: load atomic i8* @c1 seq_cst
+// MIPS64: load atomic i16* @s1 seq_cst
+// MIPS64: load atomic i32* @i1 seq_cst
+// MIPS64: load atomic i64* @ll1 seq_cst
+}
diff --git a/test/CodeGen/attr-coldhot.c b/test/CodeGen/attr-coldhot.c
index b9bb299..a277119 100644
--- a/test/CodeGen/attr-coldhot.c
+++ b/test/CodeGen/attr-coldhot.c
@@ -4,6 +4,8 @@ int test1() __attribute__((__cold__)) {
return 42;
// Check that we set the optsize attribute on the function.
-// CHECK: @test1{{.*}}optsize
+// CHECK: @test1{{.*}}[[ATTR:#[0-9]+]]
// CHECK: ret
}
+
+// CHECK: attributes [[ATTR]] = { {{.*}}optsize{{.*}} }
diff --git a/test/CodeGen/attr-minsize.cpp b/test/CodeGen/attr-minsize.cpp
index a422a62..997194d 100644
--- a/test/CodeGen/attr-minsize.cpp
+++ b/test/CodeGen/attr-minsize.cpp
@@ -7,29 +7,29 @@
// Check that we set the minsize attribute on each function
// when Oz optimization level is set.
+__attribute__((minsize))
int test1() {
return 42;
-// Oz: @{{.*}}test1{{.*}}minsize
-// Oz: ret
-// OTHER: @{{.*}}test1
-// OTHER-NOT: minsize
-// OTHER: ret
+// Oz: @{{.*}}test1{{.*}}[[MINSIZE:#[0-9]+]]
+// OTHER: @{{.*}}test1{{.*}}[[MS:#[0-9]+]]
}
int test2() {
return 42;
-// Oz: @{{.*}}test2{{.*}}minsize
+// Oz: @{{.*}}test2{{.*}}[[MINSIZE]]
// Oz: ret
// OTHER: @{{.*}}test2
-// OTHER-NOT: minsize
+// OTHER-NOT: [[MS]]
// OTHER: ret
}
-__attribute__((minsize))
int test3() {
return 42;
-// Oz: @{{.*}}test3{{.*}}minsize
-// OTHER: @{{.*}}test3{{.*}}minsize
+// Oz: @{{.*}}test3{{.*}}[[MINSIZE]]
+// Oz: ret
+// OTHER: @{{.*}}test3
+// OTHER-NOT: [[MS]]
+// OTHER: ret
}
// Check that the minsize attribute is well propagated through
@@ -44,16 +44,16 @@ void test4(T arg) {
template
void test4<int>(int arg);
// Oz: define{{.*}}void @{{.*}}test4
-// Oz: minsize
+// Oz: [[MINSIZE]]
// OTHER: define{{.*}}void @{{.*}}test4
-// OTHER: minsize
+// OTHER: [[MS]]
template
void test4<float>(float arg);
// Oz: define{{.*}}void @{{.*}}test4
-// Oz: minsize
+// Oz: [[MINSIZE]]
// OTHER: define{{.*}}void @{{.*}}test4
-// OTHER: minsize
+// OTHER: [[MS]]
template<typename T>
void test5(T arg) {
@@ -63,13 +63,17 @@ void test5(T arg) {
template
void test5<int>(int arg);
// Oz: define{{.*}}void @{{.*}}test5
-// Oz: minsize
+// Oz: [[MINSIZE]]
// OTHER: define{{.*}}void @{{.*}}test5
-// OTHER-NOT: minsize
+// OTHER-NOT: define{{.*}}void @{{.*}}test5{{.*}}[[MS]]
template
void test5<float>(float arg);
// Oz: define{{.*}}void @{{.*}}test5
-// Oz: minsize
+// Oz: [[MINSIZE]]
// OTHER: define{{.*}}void @{{.*}}test5
-// OTHER-NOT: minsize
+// OTHER-NOT: define{{.*}}void @{{.*}}test5{{.*}}[[MS]]
+
+// Oz: attributes [[MINSIZE]] = { minsize{{.*}} }
+
+// OTHER: attributes [[MS]] = { minsize nounwind{{.*}} }
diff --git a/test/CodeGen/attr-naked.c b/test/CodeGen/attr-naked.c
index 2387d28..c07dd8d 100644
--- a/test/CodeGen/attr-naked.c
+++ b/test/CodeGen/attr-naked.c
@@ -4,13 +4,15 @@ void t1() __attribute__((naked));
// Basic functionality check
// (Note that naked needs to imply noinline to work properly.)
-// CHECK: define void @t1() nounwind noinline naked {
+// CHECK: define void @t1() [[NAKED:#[0-9]+]] {
void t1()
{
}
// Make sure this doesn't explode in the verifier.
// (It doesn't really make sense, but it isn't invalid.)
-// CHECK: define void @t2() nounwind noinline naked {
+// CHECK: define void @t2() [[NAKED]] {
__attribute((naked, always_inline)) void t2() {
}
+
+// CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} }
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
index 00688dc..356a179 100644
--- a/test/CodeGen/attributes.c
+++ b/test/CodeGen/attributes.c
@@ -36,39 +36,39 @@ int t17() {
return t15() + t16;
}
-// CHECK: define void @t1() noreturn nounwind {
+// CHECK: define void @t1() [[NR:#[0-9]+]] {
void t1() __attribute__((noreturn));
void t1() { while (1) {} }
-// CHECK: define void @t2() nounwind {
+// CHECK: define void @t2() [[NUW:#[0-9]+]] {
void t2() __attribute__((nothrow));
void t2() {}
-// CHECK: define weak void @t3() nounwind {
+// CHECK: define weak void @t3() [[NUW]] {
void t3() __attribute__((weak));
void t3() {}
-// CHECK: define hidden void @t4() nounwind {
+// CHECK: define hidden void @t4() [[NUW]] {
void t4() __attribute__((visibility("hidden")));
void t4() {}
-// CHECK: define void @t7() noreturn nounwind {
+// CHECK: define void @t7() [[NR]] {
void t7() __attribute__((noreturn, nothrow));
void t7() { while (1) {} }
-// CHECK: define void @t10() nounwind section "SECT" {
+// CHECK: define void @t10() [[NUW]] section "SECT" {
void t10(void) __attribute__((section("SECT")));
void t10(void) {}
-// CHECK: define void @t11() nounwind section "SECT" {
+// CHECK: define void @t11() [[NUW]] section "SECT" {
void __attribute__((section("SECT"))) t11(void) {}
-// CHECK: define i32 @t19() nounwind {
+// CHECK: define i32 @t19() [[NUW]] {
extern int t19(void) __attribute__((weak_import));
int t19(void) {
return 10;
}
-// CHECK:define void @t20() nounwind {
+// CHECK:define void @t20() [[NUW]] {
// CHECK: call void @abort()
// CHECK-NEXT: unreachable
void t20(void) {
@@ -88,4 +88,7 @@ void t21(void) {
void __attribute__((section(".foo"))) t22(void);
void __attribute__((section(".bar"))) t22(void) {}
-// CHECK: define void @t22() nounwind section ".bar"
+// CHECK: define void @t22() [[NUW]] section ".bar"
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} }
diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c
index 69ed5b1..bec55ff 100644
--- a/test/CodeGen/bitfield-2.c
+++ b/test/CodeGen/bitfield-2.c
@@ -9,17 +9,12 @@
// PR6176
// CHECK-RECORD: *** Dumping IRgen Record Layout
-// CHECK-RECORD: Record: struct s0
+// CHECK-RECORD: Record: RecordDecl{{.*}}s0
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s0 = type <{ [3 x i8] }>
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
-// CHECK-RECORD: <CGBitFieldInfo Size:24 IsSigned:1
-// CHECK-RECORD: NumComponents:2 Components: [
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
-// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:16>
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
-// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:16 TargetBitWidth:8>
+// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:24 IsSigned:1 StorageSize:24 StorageAlignment:1>
struct __attribute((packed)) s0 {
int f0 : 24;
};
@@ -54,22 +49,13 @@ unsigned long long test_0() {
// PR5591
// CHECK-RECORD: *** Dumping IRgen Record Layout
-// CHECK-RECORD: Record: struct s1
+// CHECK-RECORD: Record: RecordDecl{{.*}}s1
// CHECK-RECORD: Layout: <CGRecordLayout
-// CHECK-RECORD: LLVMType:%struct.s1 = type <{ [2 x i8], i8 }>
+// CHECK-RECORD: LLVMType:%struct.s1 = type <{ [3 x i8] }>
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
-// CHECK-RECORD: <CGBitFieldInfo Size:10 IsSigned:1
-// CHECK-RECORD: NumComponents:1 Components: [
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
-// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:10>
-// CHECK-RECORD: ]>
-// CHECK-RECORD: <CGBitFieldInfo Size:10 IsSigned:1
-// CHECK-RECORD: NumComponents:2 Components: [
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:10 AccessWidth:16
-// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:6>
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
-// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:6 TargetBitWidth:4>
+// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:10 IsSigned:1 StorageSize:24 StorageAlignment:1>
+// CHECK-RECORD: <CGBitFieldInfo Offset:10 Size:10 IsSigned:1 StorageSize:24 StorageAlignment:1>
#pragma pack(push)
#pragma pack(1)
@@ -111,15 +97,12 @@ unsigned long long test_1() {
// PR5567
// CHECK-RECORD: *** Dumping IRgen Record Layout
-// CHECK-RECORD: Record: union u2
+// CHECK-RECORD: Record: RecordDecl{{.*}}u2
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%union.u2 = type <{ i8 }>
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
-// CHECK-RECORD: <CGBitFieldInfo Size:3 IsSigned:0
-// CHECK-RECORD: NumComponents:1 Components: [
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:8
-// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:3>
+// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:3 IsSigned:0 StorageSize:8 StorageAlignment:1>
union __attribute__((packed)) u2 {
unsigned long long f0 : 3;
@@ -286,20 +269,13 @@ _Bool test_6() {
// Check that we compute the best alignment possible for each access.
//
// CHECK-RECORD: *** Dumping IRgen Record Layout
-// CHECK-RECORD: Record: struct s7
+// CHECK-RECORD: Record: RecordDecl{{.*}}s7
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s7 = type { i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] }
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
-// CHECK-RECORD: <CGBitFieldInfo Size:5 IsSigned:1
-// CHECK-RECORD: NumComponents:1 Components: [
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:12 FieldBitStart:0 AccessWidth:32
-// CHECK-RECORD: AccessAlignment:4 TargetBitOffset:0 TargetBitWidth:5>
-// CHECK-RECORD: ]>
-// CHECK-RECORD: <CGBitFieldInfo Size:29 IsSigned:1
-// CHECK-RECORD: NumComponents:1 Components: [
-// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:16 FieldBitStart:0 AccessWidth:32
-// CHECK-RECORD: AccessAlignment:16 TargetBitOffset:0 TargetBitWidth:29>
+// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:5 IsSigned:1 StorageSize:8 StorageAlignment:4>
+// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:29 IsSigned:1 StorageSize:32 StorageAlignment:16>
struct __attribute__((aligned(16))) s7 {
int a, b, c;
diff --git a/test/CodeGen/blocks-seq.c b/test/CodeGen/blocks-seq.c
index 3557b48..8db9e60 100644
--- a/test/CodeGen/blocks-seq.c
+++ b/test/CodeGen/blocks-seq.c
@@ -1,13 +1,11 @@
-// FIXME: We forcibly strip the names so that the test doesn't vary between
-// builds with and without asserts. We need a better solution for this.
-
-// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -emit-llvm-bc -o - %s | opt -strip | llvm-dis > %t
-// RUN: grep '%6 = call i32 (...)\* @rhs()' %t | count 1
-// RUN: grep '%7 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1
-// RUN: grep '%8 = load %0\*\* %7' %t | count 1
-// RUN: grep '%10 = call i32 (...)\* @rhs()' %t | count 1
-// RUN: grep '%11 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1
-// RUN: grep '%12 = load %0\*\* %11' %t | count 1
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// CHECK: [[Vi:%.+]] = alloca %struct.__block_byref_i, align 8
+// CHECK: call i32 (...)* @rhs()
+// CHECK: [[V7:%.+]] = getelementptr inbounds %struct.__block_byref_i* [[Vi]], i32 0, i32 1
+// CHECK: load %struct.__block_byref_i** [[V7]]
+// CHECK: call i32 (...)* @rhs()
+// CHECK: [[V11:%.+]] = getelementptr inbounds %struct.__block_byref_i* [[Vi]], i32 0, i32 1
+// CHECK: load %struct.__block_byref_i** [[V11]]
int rhs();
diff --git a/test/CodeGen/bool_test.c b/test/CodeGen/bool_test.c
index 715f846..83d8330 100644
--- a/test/CodeGen/bool_test.c
+++ b/test/CodeGen/bool_test.c
@@ -1,6 +1,18 @@
// REQUIRES: ppc32-registered-target
-// RUN: %clang_cc1 -triple powerpc-apple-darwin -emit-llvm -o - %s| FileCheck -check-prefix=DARWINPPC-CHECK %s
+// RUN: %clang_cc1 -triple powerpc-apple-macosx10.4.0 -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
int boolsize = sizeof(_Bool);
-//DARWINPPC-CHECK: boolsize = global i32 4, align 4
+// CHECK: boolsize = global i32 4, align 4
+void f(_Bool *x, _Bool *y) {
+ *x = *y;
+}
+
+// CHECK: define void @f(
+// CHECK: [[FROMMEM:%.*]] = load i32* %
+// CHECK: [[BOOLVAL:%.*]] = trunc i32 [[FROMMEM]] to i1
+// CHECK: [[TOMEM:%.*]] = zext i1 [[BOOLVAL]] to i32
+// CHECK: store i32 [[TOMEM]]
+// CHECK: ret void
+
+// CHECK: metadata !{i32 0, i32 2}
diff --git a/test/CodeGen/bounds-checking.c b/test/CodeGen/bounds-checking.c
index e278620..fa7541f 100644
--- a/test/CodeGen/bounds-checking.c
+++ b/test/CodeGen/bounds-checking.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fbounds-checking=4 -emit-llvm -triple x86_64-apple-darwin10 < %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=bounds -emit-llvm -triple x86_64-apple-darwin10 < %s | FileCheck %s
// CHECK: @f
double f(int b, int i) {
diff --git a/test/CodeGen/builtin-attributes.c b/test/CodeGen/builtin-attributes.c
index 1d3a943..c5c35c3 100644
--- a/test/CodeGen/builtin-attributes.c
+++ b/test/CodeGen/builtin-attributes.c
@@ -12,7 +12,7 @@ void f1() {
exit(1);
}
-// CHECK: call i8* @strstr{{.*}} nounwind
+// CHECK: call i8* @strstr{{.*}} [[NUW:#[0-9]+]]
char* f2(char* a, char* b) {
return __builtin_strstr(a, b);
}
@@ -57,3 +57,5 @@ int f3(double x) {
__builtin_remquol(x, x, &e);
return e;
}
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c
index 3611650..e6c7ced 100644
--- a/test/CodeGen/builtins-arm.c
+++ b/test/CodeGen/builtins-arm.c
@@ -11,3 +11,10 @@ void f1(char *a, char *b) {
}
// CHECK: call {{.*}} @__clear_cache
+
+void test_eh_return_data_regno()
+{
+ volatile int res;
+ res = __builtin_eh_return_data_regno(0); // CHECK: store volatile i32 0
+ res = __builtin_eh_return_data_regno(1); // CHECK: store volatile i32 1
+}
diff --git a/test/CodeGen/builtins-mips.c b/test/CodeGen/builtins-mips.c
index ef4662c..c6be896 100644
--- a/test/CodeGen/builtins-mips.c
+++ b/test/CodeGen/builtins-mips.c
@@ -532,3 +532,10 @@ void foo() {
v4i8_r = __builtin_mips_subuh_r_qb(v4i8_a, v4i8_b);
// CHECK: call <4 x i8> @llvm.mips.subuh.r.qb
}
+
+void test_eh_return_data_regno()
+{
+ volatile int res;
+ res = __builtin_eh_return_data_regno(0); // CHECK: store volatile i32 4
+ res = __builtin_eh_return_data_regno(1); // CHECK: store volatile i32 5
+}
diff --git a/test/CodeGen/builtins-multiprecision.c b/test/CodeGen/builtins-multiprecision.c
new file mode 100644
index 0000000..172f683
--- /dev/null
+++ b/test/CodeGen/builtins-multiprecision.c
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -triple "i686-unknown-unknown" -emit-llvm -x c %s -o - -O3 | FileCheck %s
+// RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - -O3 | FileCheck %s
+// RUN: %clang_cc1 -triple "x86_64-mingw32" -emit-llvm -x c %s -o - -O3 | FileCheck %s
+
+unsigned short test_addcs(unsigned short x, unsigned short y,
+ unsigned short carryin, unsigned short *z) {
+ // CHECK: @test_addcs
+ // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %x, i16 %y)
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %{{.+}}, i16 %carryin)
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to i16
+ // CHECK: store i16 %{{.+}}, i16* %z, align 2
+
+ unsigned short carryout;
+ *z = __builtin_addcs(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned test_addc(unsigned x, unsigned y, unsigned carryin, unsigned *z) {
+ // CHECK: @test_addc
+ // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %carryin)
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to i32
+ // CHECK: store i32 %{{.+}}, i32* %z, align 4
+ unsigned carryout;
+ *z = __builtin_addc(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned long test_addcl(unsigned long x, unsigned long y,
+ unsigned long carryin, unsigned long *z) {
+ // long is i32 on i686, i64 on x86_64.
+ // CHECK: @test_addcl([[UL:i32|i64]] %x
+ // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %x, [[UL]] %y)
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %carryin)
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to [[UL]]
+ // CHECK: store [[UL]] %{{.+}}, [[UL]]* %z
+ unsigned long carryout;
+ *z = __builtin_addcl(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned long long test_addcll(unsigned long long x, unsigned long long y,
+ unsigned long long carryin,
+ unsigned long long *z) {
+ // CHECK: @test_addcll
+ // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x, i64 %y)
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %carryin)
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to i64
+ // CHECK: store i64 %{{.+}}, i64* %z
+ unsigned long long carryout;
+ *z = __builtin_addcll(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned short test_subcs(unsigned short x, unsigned short y,
+ unsigned short carryin, unsigned short *z) {
+ // CHECK: @test_subcs
+ // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %x, i16 %y)
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %{{.+}}, i16 %carryin)
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to i16
+ // CHECK: store i16 %{{.+}}, i16* %z, align 2
+
+ unsigned short carryout;
+ *z = __builtin_subcs(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned test_subc(unsigned x, unsigned y, unsigned carryin, unsigned *z) {
+ // CHECK: @test_subc
+ // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %carryin)
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to i32
+ // CHECK: store i32 %{{.+}}, i32* %z, align 4
+ unsigned carryout;
+ *z = __builtin_subc(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned long test_subcl(unsigned long x, unsigned long y,
+ unsigned long carryin, unsigned long *z) {
+ // CHECK: @test_subcl([[UL:i32|i64]] %x
+ // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %x, [[UL]] %y)
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %carryin)
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to [[UL]]
+ // CHECK: store [[UL]] %{{.+}}, [[UL]]* %z
+ unsigned long carryout;
+ *z = __builtin_subcl(x, y, carryin, &carryout);
+
+ return carryout;
+}
+
+unsigned long long test_subcll(unsigned long long x, unsigned long long y,
+ unsigned long long carryin,
+ unsigned long long *z) {
+ // CHECK: @test_subcll
+ // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %x, i64 %y)
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %carryin)
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
+ // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
+ // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+ // CHECK: %{{.+}} = zext i1 %{{.+}} to i64
+ // CHECK: store i64 %{{.+}}, i64* %z
+ unsigned long long carryout;
+ *z = __builtin_subcll(x, y, carryin, &carryout);
+
+ return carryout;
+}
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
index e885cb0..9427a8a 100644
--- a/test/CodeGen/builtins-ppc-altivec.c
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -484,20 +484,20 @@ void test6() {
res_vf = vec_lvx(0, &param_f); // CHECK: @llvm.ppc.altivec.lvx
/* vec_lde */
- res_vsc = vec_lde(0, &vsc); // CHECK: @llvm.ppc.altivec.lvebx
- res_vuc = vec_lde(0, &vuc); // CHECK: @llvm.ppc.altivec.lvebx
- res_vs = vec_lde(0, &vs); // CHECK: @llvm.ppc.altivec.lvehx
- res_vus = vec_lde(0, &vus); // CHECK: @llvm.ppc.altivec.lvehx
- res_vi = vec_lde(0, &vi); // CHECK: @llvm.ppc.altivec.lvewx
- res_vui = vec_lde(0, &vui); // CHECK: @llvm.ppc.altivec.lvewx
- res_vf = vec_lde(0, &vf); // CHECK: @llvm.ppc.altivec.lvewx
- res_vsc = vec_lvebx(0, &vsc); // CHECK: @llvm.ppc.altivec.lvebx
- res_vuc = vec_lvebx(0, &vuc); // CHECK: @llvm.ppc.altivec.lvebx
- res_vs = vec_lvehx(0, &vs); // CHECK: @llvm.ppc.altivec.lvehx
- res_vus = vec_lvehx(0, &vus); // CHECK: @llvm.ppc.altivec.lvehx
- res_vi = vec_lvewx(0, &vi); // CHECK: @llvm.ppc.altivec.lvewx
- res_vui = vec_lvewx(0, &vui); // CHECK: @llvm.ppc.altivec.lvewx
- res_vf = vec_lvewx(0, &vf); // CHECK: @llvm.ppc.altivec.lvewx
+ res_vsc = vec_lde(0, &param_sc); // CHECK: @llvm.ppc.altivec.lvebx
+ res_vuc = vec_lde(0, &param_uc); // CHECK: @llvm.ppc.altivec.lvebx
+ res_vs = vec_lde(0, &param_s); // CHECK: @llvm.ppc.altivec.lvehx
+ res_vus = vec_lde(0, &param_us); // CHECK: @llvm.ppc.altivec.lvehx
+ res_vi = vec_lde(0, &param_i); // CHECK: @llvm.ppc.altivec.lvewx
+ res_vui = vec_lde(0, &param_ui); // CHECK: @llvm.ppc.altivec.lvewx
+ res_vf = vec_lde(0, &param_f); // CHECK: @llvm.ppc.altivec.lvewx
+ res_vsc = vec_lvebx(0, &param_sc); // CHECK: @llvm.ppc.altivec.lvebx
+ res_vuc = vec_lvebx(0, &param_uc); // CHECK: @llvm.ppc.altivec.lvebx
+ res_vs = vec_lvehx(0, &param_s); // CHECK: @llvm.ppc.altivec.lvehx
+ res_vus = vec_lvehx(0, &param_us); // CHECK: @llvm.ppc.altivec.lvehx
+ res_vi = vec_lvewx(0, &param_i); // CHECK: @llvm.ppc.altivec.lvewx
+ res_vui = vec_lvewx(0, &param_ui); // CHECK: @llvm.ppc.altivec.lvewx
+ res_vf = vec_lvewx(0, &param_f); // CHECK: @llvm.ppc.altivec.lvewx
/* vec_ldl */
res_vsc = vec_ldl(0, &vsc); // CHECK: @llvm.ppc.altivec.lvxl
diff --git a/test/CodeGen/builtins-ppc.c b/test/CodeGen/builtins-ppc.c
new file mode 100644
index 0000000..ee27a4c
--- /dev/null
+++ b/test/CodeGen/builtins-ppc.c
@@ -0,0 +1,9 @@
+// REQUIRES: ppc32-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+void test_eh_return_data_regno()
+{
+ volatile int res;
+ res = __builtin_eh_return_data_regno(0); // CHECK: store volatile i32 3
+ res = __builtin_eh_return_data_regno(1); // CHECK: store volatile i32 4
+}
diff --git a/test/CodeGen/builtinshufflevector2.c b/test/CodeGen/builtinshufflevector2.c
index faf7a3e..ac0e07a 100644
--- a/test/CodeGen/builtinshufflevector2.c
+++ b/test/CodeGen/builtinshufflevector2.c
@@ -16,14 +16,14 @@ void clang_shufflevector_v_v( float4* A, float4 x, uint4 mask ) {
// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 1
// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 1
+// CHECK: [[V2:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 1
// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 2
// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 2
+// CHECK: [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[E]], i32 2
// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 3
// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 3
-// CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}},
+// CHECK: [[V4:%.*]] = insertelement <4 x float> [[V3]], float [[E]], i32 3
+// CHECK: store <4 x float> [[V4]], <4 x float>* {{%.*}},
*A = __builtin_shufflevector( x, mask );
}
diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c
index 4fbeb7b..1021010 100644
--- a/test/CodeGen/c-strings.c
+++ b/test/CodeGen/c-strings.c
@@ -1,36 +1,55 @@
-// RUN: %clang_cc1 -emit-llvm -o %t %s
-// RUN: grep "hello" %t | count 3
-// RUN: grep 'c"hello\\00"' %t | count 2
-// RUN: grep 'c"hello\\00\\00\\00"' %t | count 1
-// RUN: grep 'c"ola"' %t | count 1
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-/* Should be 3 hello string, two global (of different sizes), the rest
- are shared. */
+// Should be 3 hello strings, two global (of different sizes), the rest are
+// shared.
+// CHECK: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
+// CHECK: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)
+// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align 1
+// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align 1
+// CHECK: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) }
+// CHECK: @x = global [3 x i8] c"ola", align 1
+
+void bar(const char *);
+
+// CHECK: define void @f0()
void f0() {
bar("hello");
+ // CHECK: call void @bar({{.*}} @.str
}
+// CHECK: define void @f1()
void f1() {
static char *x = "hello";
bar(x);
+ // CHECK: [[T1:%.*]] = load i8** @f1.x
+ // CHECK: call void @bar(i8* [[T1:%.*]])
}
+// CHECK: define void @f2()
void f2() {
static char x[] = "hello";
bar(x);
+ // CHECK: call void @bar({{.*}} @f2.x
}
+// CHECK: define void @f3()
void f3() {
static char x[8] = "hello";
bar(x);
+ // CHECK: call void @bar({{.*}} @f3.x
}
+void gaz(void *);
+
+// CHECK: define void @f4()
void f4() {
static struct s {
char *name;
} x = { "hello" };
gaz(&x);
+ // CHECK: call void @gaz({{.*}} @f4.x
}
char x[3] = "ola";
+
diff --git a/test/CodeGen/c11atomics-ios.c b/test/CodeGen/c11atomics-ios.c
new file mode 100644
index 0000000..d1c9b14
--- /dev/null
+++ b/test/CodeGen/c11atomics-ios.c
@@ -0,0 +1,214 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-apple-ios -std=c11 | FileCheck %s
+
+// There isn't really anything special about iOS; it just happens to
+// only deploy on processors with native atomics support, so it's a good
+// way to test those code-paths.
+
+// This work was done in pursuit of <rdar://13338582>.
+
+// CHECK: define arm_aapcscc void @testFloat(float*
+void testFloat(_Atomic(float) *fp) {
+// CHECK: [[FP:%.*]] = alloca float*
+// CHECK-NEXT: [[X:%.*]] = alloca float
+// CHECK-NEXT: [[F:%.*]] = alloca float
+// CHECK-NEXT: store float* {{%.*}}, float** [[FP]]
+
+// CHECK-NEXT: [[T0:%.*]] = load float** [[FP]]
+// CHECK-NEXT: store float 1.000000e+00, float* [[T0]], align 4
+ __c11_atomic_init(fp, 1.0f);
+
+// CHECK-NEXT: store float 2.000000e+00, float* [[X]], align 4
+ _Atomic(float) x = 2.0f;
+
+// CHECK-NEXT: [[T0:%.*]] = load float** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast float* [[T0]] to i32*
+// CHECK-NEXT: [[T2:%.*]] = load atomic i32* [[T1]] seq_cst, align 4
+// CHECK-NEXT: [[T3:%.*]] = bitcast i32 [[T2]] to float
+// CHECK-NEXT: store float [[T3]], float* [[F]]
+ float f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = load float* [[F]], align 4
+// CHECK-NEXT: [[T1:%.*]] = load float** [[FP]], align 4
+// CHECK-NEXT: [[T2:%.*]] = bitcast float [[T0]] to i32
+// CHECK-NEXT: [[T3:%.*]] = bitcast float* [[T1]] to i32*
+// CHECK-NEXT: store atomic i32 [[T2]], i32* [[T3]] seq_cst, align 4
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+// CHECK: define arm_aapcscc void @testComplexFloat([[CF:{ float, float }]]*
+void testComplexFloat(_Atomic(_Complex float) *fp) {
+// CHECK: [[FP:%.*]] = alloca [[CF]]*, align 4
+// CHECK-NEXT: [[X:%.*]] = alloca [[CF]], align 8
+// CHECK-NEXT: [[F:%.*]] = alloca [[CF]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = alloca [[CF]], align 8
+// CHECK-NEXT: [[TMP1:%.*]] = alloca [[CF]], align 8
+// CHECK-NEXT: store [[CF]]*
+
+// CHECK-NEXT: [[P:%.*]] = load [[CF]]** [[FP]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[P]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[P]], i32 0, i32 1
+// CHECK-NEXT: store float 1.000000e+00, float* [[T0]]
+// CHECK-NEXT: store float 0.000000e+00, float* [[T1]]
+ __c11_atomic_init(fp, 1.0f);
+
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[X]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[X]], i32 0, i32 1
+// CHECK-NEXT: store float 2.000000e+00, float* [[T0]]
+// CHECK-NEXT: store float 0.000000e+00, float* [[T1]]
+ _Atomic(_Complex float) x = 2.0f;
+
+// CHECK-NEXT: [[T0:%.*]] = load [[CF]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[CF]]* [[T0]] to i64*
+// CHECK-NEXT: [[T2:%.*]] = load atomic i64* [[T1]] seq_cst, align 8
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[CF]]* [[TMP0]] to i64*
+// CHECK-NEXT: store i64 [[T2]], i64* [[T3]], align 8
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[TMP0]], i32 0, i32 0
+// CHECK-NEXT: [[R:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[TMP0]], i32 0, i32 1
+// CHECK-NEXT: [[I:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 1
+// CHECK-NEXT: store float [[R]], float* [[T0]]
+// CHECK-NEXT: store float [[I]], float* [[T1]]
+ _Complex float f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 0
+// CHECK-NEXT: [[R:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 1
+// CHECK-NEXT: [[I:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[DEST:%.*]] = load [[CF]]** [[FP]], align 4
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[TMP1]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[TMP1]], i32 0, i32 1
+// CHECK-NEXT: store float [[R]], float* [[T0]]
+// CHECK-NEXT: store float [[I]], float* [[T1]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[CF]]* [[TMP1]] to i64*
+// CHECK-NEXT: [[T1:%.*]] = load i64* [[T0]], align 8
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[CF]]* [[DEST]] to i64*
+// CHECK-NEXT: store atomic i64 [[T1]], i64* [[T2]] seq_cst, align 8
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+typedef struct { short x, y, z, w; } S;
+// CHECK: define arm_aapcscc void @testStruct([[S:.*]]*
+void testStruct(_Atomic(S) *fp) {
+// CHECK: [[FP:%.*]] = alloca [[S]]*, align 4
+// CHECK-NEXT: [[X:%.*]] = alloca [[S]], align 8
+// CHECK-NEXT: [[F:%.*]] = alloca [[S:%.*]], align 2
+// CHECK-NEXT: [[TMP0:%.*]] = alloca [[S]], align 8
+// CHECK-NEXT: store [[S]]*
+
+// CHECK-NEXT: [[P:%.*]] = load [[S]]** [[FP]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[S]]* [[P]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 3
+// CHECK-NEXT: store i16 4, i16* [[T0]], align 2
+ __c11_atomic_init(fp, (S){1,2,3,4});
+
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[S]]* [[X]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 3
+// CHECK-NEXT: store i16 4, i16* [[T0]], align 2
+ _Atomic(S) x = (S){1,2,3,4};
+
+// CHECK-NEXT: [[T0:%.*]] = load [[S]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[S]]* [[T0]] to i64*
+// CHECK-NEXT: [[T2:%.*]] = load atomic i64* [[T1]] seq_cst, align 8
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[S]]* [[F]] to i64*
+// CHECK-NEXT: store i64 [[T2]], i64* [[T3]], align 2
+ S f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = load [[S]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[S]]* [[TMP0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[S]]* [[F]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[T1]], i8* [[T2]], i32 8, i32 2, i1 false)
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[S]]* [[TMP0]] to i64*
+// CHECK-NEXT: [[T4:%.*]] = load i64* [[T3]], align 8
+// CHECK-NEXT: [[T5:%.*]] = bitcast [[S]]* [[T0]] to i64*
+// CHECK-NEXT: store atomic i64 [[T4]], i64* [[T5]] seq_cst, align 8
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+typedef struct { short x, y, z; } PS;
+// CHECK: define arm_aapcscc void @testPromotedStruct([[APS:.*]]*
+void testPromotedStruct(_Atomic(PS) *fp) {
+// CHECK: [[FP:%.*]] = alloca [[APS]]*, align 4
+// CHECK-NEXT: [[X:%.*]] = alloca [[APS]], align 8
+// CHECK-NEXT: [[F:%.*]] = alloca [[PS:%.*]], align 2
+// CHECK-NEXT: [[TMP0:%.*]] = alloca [[APS]], align 8
+// CHECK-NEXT: [[TMP1:%.*]] = alloca [[APS]], align 8
+// CHECK-NEXT: store [[APS]]*
+
+// CHECK-NEXT: [[P:%.*]] = load [[APS]]** [[FP]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[APS]]* [[P]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[APS]]* [[P]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T1]], align 2
+ __c11_atomic_init(fp, (PS){1,2,3});
+
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[APS]]* [[X]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[APS]]* [[X]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T1]], align 2
+ _Atomic(PS) x = (PS){1,2,3};
+
+// CHECK-NEXT: [[T0:%.*]] = load [[APS]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[APS]]* [[T0]] to i64*
+// CHECK-NEXT: [[T2:%.*]] = load atomic i64* [[T1]] seq_cst, align 8
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[APS]]* [[TMP0]] to i64*
+// CHECK-NEXT: store i64 [[T2]], i64* [[T3]], align 8
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[APS]]* [[TMP0]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[PS]]* [[F]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[PS]]* [[T0]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[T1]], i8* [[T2]], i32 6, i32 2, i1 false)
+ PS f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = load [[APS]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[APS]]* [[TMP1]], i32 0, i32 0
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[PS]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[PS]]* [[F]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[T2]], i8* [[T3]], i32 6, i32 2, i1 false)
+// CHECK-NEXT: [[T4:%.*]] = bitcast [[APS]]* [[TMP1]] to i64*
+// CHECK-NEXT: [[T5:%.*]] = load i64* [[T4]], align 8
+// CHECK-NEXT: [[T6:%.*]] = bitcast [[APS]]* [[T0]] to i64*
+// CHECK-NEXT: store atomic i64 [[T5]], i64* [[T6]] seq_cst, align 8
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+void testPromotedStructOps(_Atomic(PS) *p) {
+ PS a = __c11_atomic_load(p, 5);
+ __c11_atomic_store(p, a, 5);
+ PS b = __c11_atomic_exchange(p, a, 5);
+
+ _Bool v = __c11_atomic_compare_exchange_strong(p, &b, a, 5, 5);
+ v = __c11_atomic_compare_exchange_weak(p, &b, a, 5, 5);
+}
diff --git a/test/CodeGen/c11atomics.c b/test/CodeGen/c11atomics.c
new file mode 100644
index 0000000..8d298af
--- /dev/null
+++ b/test/CodeGen/c11atomics.c
@@ -0,0 +1,344 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-freebsd -std=c11 | FileCheck %s
+
+// Test that we are generating atomicrmw instructions, rather than
+// compare-exchange loops for common atomic ops. This makes a big difference
+// on RISC platforms, where the compare-exchange loop becomes a ll/sc pair for
+// the load and then another ll/sc in the loop, expanding to about 30
+// instructions when it should be only 4. It has a smaller, but still
+// noticeable, impact on platforms like x86 and RISC-V, where there are atomic
+// RMW instructions.
+//
+// We currently emit cmpxchg loops for most operations on _Bools, because
+// they're sufficiently rare that it's not worth making sure that the semantics
+// are correct.
+
+typedef int __attribute__((vector_size(16))) vector;
+
+_Atomic(_Bool) b;
+_Atomic(int) i;
+_Atomic(long long) l;
+_Atomic(short) s;
+_Atomic(char*) p;
+_Atomic(float) f;
+_Atomic(vector) v;
+
+// CHECK: testinc
+void testinc(void)
+{
+ // Special case for suffix bool++, sets to true and returns the old value.
+ // CHECK: atomicrmw xchg i8* @b, i8 1 seq_cst
+ b++;
+ // CHECK: atomicrmw add i32* @i, i32 1 seq_cst
+ i++;
+ // CHECK: atomicrmw add i64* @l, i64 1 seq_cst
+ l++;
+ // CHECK: atomicrmw add i16* @s, i16 1 seq_cst
+ s++;
+ // Prefix increment
+ // Special case for bool: set to true and return true
+ // CHECK: store atomic i8 1, i8* @b seq_cst, align 1
+ ++b;
+ // Currently, we have no variant of atomicrmw that returns the new value, so
+ // we have to generate an atomic add, which returns the old value, and then a
+ // non-atomic add.
+ // CHECK: atomicrmw add i32* @i, i32 1 seq_cst
+ // CHECK: add i32
+ ++i;
+ // CHECK: atomicrmw add i64* @l, i64 1 seq_cst
+ // CHECK: add i64
+ ++l;
+ // CHECK: atomicrmw add i16* @s, i16 1 seq_cst
+ // CHECK: add i16
+ ++s;
+}
+// CHECK: testdec
+void testdec(void)
+{
+ // CHECK: cmpxchg i8* @b
+ b--;
+ // CHECK: atomicrmw sub i32* @i, i32 1 seq_cst
+ i--;
+ // CHECK: atomicrmw sub i64* @l, i64 1 seq_cst
+ l--;
+ // CHECK: atomicrmw sub i16* @s, i16 1 seq_cst
+ s--;
+ // CHECK: cmpxchg i8* @b
+ --b;
+ // CHECK: atomicrmw sub i32* @i, i32 1 seq_cst
+ // CHECK: sub i32
+ --i;
+ // CHECK: atomicrmw sub i64* @l, i64 1 seq_cst
+ // CHECK: sub i64
+ --l;
+ // CHECK: atomicrmw sub i16* @s, i16 1 seq_cst
+ // CHECK: sub i16
+ --s;
+}
+// CHECK: testaddeq
+void testaddeq(void)
+{
+ // CHECK: cmpxchg i8* @b
+ // CHECK: atomicrmw add i32* @i, i32 42 seq_cst
+ // CHECK: atomicrmw add i64* @l, i64 42 seq_cst
+ // CHECK: atomicrmw add i16* @s, i16 42 seq_cst
+ b += 42;
+ i += 42;
+ l += 42;
+ s += 42;
+}
+// CHECK: testsubeq
+void testsubeq(void)
+{
+ // CHECK: cmpxchg i8* @b
+ // CHECK: atomicrmw sub i32* @i, i32 42 seq_cst
+ // CHECK: atomicrmw sub i64* @l, i64 42 seq_cst
+ // CHECK: atomicrmw sub i16* @s, i16 42 seq_cst
+ b -= 42;
+ i -= 42;
+ l -= 42;
+ s -= 42;
+}
+// CHECK: testxoreq
+void testxoreq(void)
+{
+ // CHECK: cmpxchg i8* @b
+ // CHECK: atomicrmw xor i32* @i, i32 42 seq_cst
+ // CHECK: atomicrmw xor i64* @l, i64 42 seq_cst
+ // CHECK: atomicrmw xor i16* @s, i16 42 seq_cst
+ b ^= 42;
+ i ^= 42;
+ l ^= 42;
+ s ^= 42;
+}
+// CHECK: testoreq
+void testoreq(void)
+{
+ // CHECK: cmpxchg i8* @b
+ // CHECK: atomicrmw or i32* @i, i32 42 seq_cst
+ // CHECK: atomicrmw or i64* @l, i64 42 seq_cst
+ // CHECK: atomicrmw or i16* @s, i16 42 seq_cst
+ b |= 42;
+ i |= 42;
+ l |= 42;
+ s |= 42;
+}
+// CHECK: testandeq
+void testandeq(void)
+{
+ // CHECK: cmpxchg i8* @b
+ // CHECK: atomicrmw and i32* @i, i32 42 seq_cst
+ // CHECK: atomicrmw and i64* @l, i64 42 seq_cst
+ // CHECK: atomicrmw and i16* @s, i16 42 seq_cst
+ b &= 42;
+ i &= 42;
+ l &= 42;
+ s &= 42;
+}
+
+// CHECK: define arm_aapcscc void @testFloat(float*
+void testFloat(_Atomic(float) *fp) {
+// CHECK: [[FP:%.*]] = alloca float*
+// CHECK-NEXT: [[X:%.*]] = alloca float
+// CHECK-NEXT: [[F:%.*]] = alloca float
+// CHECK-NEXT: [[TMP0:%.*]] = alloca float
+// CHECK-NEXT: [[TMP1:%.*]] = alloca float
+// CHECK-NEXT: store float* {{%.*}}, float** [[FP]]
+
+// CHECK-NEXT: [[T0:%.*]] = load float** [[FP]]
+// CHECK-NEXT: store float 1.000000e+00, float* [[T0]], align 4
+ __c11_atomic_init(fp, 1.0f);
+
+// CHECK-NEXT: store float 2.000000e+00, float* [[X]], align 4
+ _Atomic(float) x = 2.0f;
+
+// CHECK-NEXT: [[T0:%.*]] = load float** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast float* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast float* [[TMP0]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_load(i32 4, i8* [[T1]], i8* [[T2]], i32 5)
+// CHECK-NEXT: [[T3:%.*]] = load float* [[TMP0]], align 4
+// CHECK-NEXT: store float [[T3]], float* [[F]]
+ float f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = load float* [[F]], align 4
+// CHECK-NEXT: [[T1:%.*]] = load float** [[FP]], align 4
+// CHECK-NEXT: store float [[T0]], float* [[TMP1]], align 4
+// CHECK-NEXT: [[T2:%.*]] = bitcast float* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = bitcast float* [[TMP1]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_store(i32 4, i8* [[T2]], i8* [[T3]], i32 5)
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+// CHECK: define arm_aapcscc void @testComplexFloat([[CF:{ float, float }]]*
+void testComplexFloat(_Atomic(_Complex float) *fp) {
+// CHECK: [[FP:%.*]] = alloca [[CF]]*, align 4
+// CHECK-NEXT: [[X:%.*]] = alloca [[CF]], align 8
+// CHECK-NEXT: [[F:%.*]] = alloca [[CF]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = alloca [[CF]], align 8
+// CHECK-NEXT: [[TMP1:%.*]] = alloca [[CF]], align 8
+// CHECK-NEXT: store [[CF]]*
+
+// CHECK-NEXT: [[P:%.*]] = load [[CF]]** [[FP]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[P]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[P]], i32 0, i32 1
+// CHECK-NEXT: store float 1.000000e+00, float* [[T0]]
+// CHECK-NEXT: store float 0.000000e+00, float* [[T1]]
+ __c11_atomic_init(fp, 1.0f);
+
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[X]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[X]], i32 0, i32 1
+// CHECK-NEXT: store float 2.000000e+00, float* [[T0]]
+// CHECK-NEXT: store float 0.000000e+00, float* [[T1]]
+ _Atomic(_Complex float) x = 2.0f;
+
+// CHECK-NEXT: [[T0:%.*]] = load [[CF]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[CF]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[CF]]* [[TMP0]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_load(i32 8, i8* [[T1]], i8* [[T2]], i32 5)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[TMP0]], i32 0, i32 0
+// CHECK-NEXT: [[R:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[TMP0]], i32 0, i32 1
+// CHECK-NEXT: [[I:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 1
+// CHECK-NEXT: store float [[R]], float* [[T0]]
+// CHECK-NEXT: store float [[I]], float* [[T1]]
+ _Complex float f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 0
+// CHECK-NEXT: [[R:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[F]], i32 0, i32 1
+// CHECK-NEXT: [[I:%.*]] = load float* [[T0]]
+// CHECK-NEXT: [[DEST:%.*]] = load [[CF]]** [[FP]], align 4
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[CF]]* [[TMP1]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[CF]]* [[TMP1]], i32 0, i32 1
+// CHECK-NEXT: store float [[R]], float* [[T0]]
+// CHECK-NEXT: store float [[I]], float* [[T1]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[CF]]* [[DEST]] to i8*
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[CF]]* [[TMP1]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_store(i32 8, i8* [[T0]], i8* [[T1]], i32 5)
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+typedef struct { short x, y, z, w; } S;
+// CHECK: define arm_aapcscc void @testStruct([[S:.*]]*
+void testStruct(_Atomic(S) *fp) {
+// CHECK: [[FP:%.*]] = alloca [[S]]*, align 4
+// CHECK-NEXT: [[X:%.*]] = alloca [[S]], align 8
+// CHECK-NEXT: [[F:%.*]] = alloca [[S:%.*]], align 2
+// CHECK-NEXT: [[TMP0:%.*]] = alloca [[S]], align 8
+// CHECK-NEXT: store [[S]]*
+
+// CHECK-NEXT: [[P:%.*]] = load [[S]]** [[FP]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[S]]* [[P]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[P]], i32 0, i32 3
+// CHECK-NEXT: store i16 4, i16* [[T0]], align 2
+ __c11_atomic_init(fp, (S){1,2,3,4});
+
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[S]]* [[X]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T0]], align 2
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[S]]* [[X]], i32 0, i32 3
+// CHECK-NEXT: store i16 4, i16* [[T0]], align 2
+ _Atomic(S) x = (S){1,2,3,4};
+
+// CHECK-NEXT: [[T0:%.*]] = load [[S]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[S]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[S]]* [[F]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_load(i32 8, i8* [[T1]], i8* [[T2]], i32 5)
+ S f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = load [[S]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[S]]* [[TMP0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[S]]* [[F]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[T1]], i8* [[T2]], i32 8, i32 2, i1 false)
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[S]]* [[T0]] to i8*
+// CHECK-NEXT: [[T4:%.*]] = bitcast [[S]]* [[TMP0]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_store(i32 8, i8* [[T3]], i8* [[T4]], i32 5)
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+typedef struct { short x, y, z; } PS;
+// CHECK: define arm_aapcscc void @testPromotedStruct([[APS:.*]]*
+void testPromotedStruct(_Atomic(PS) *fp) {
+// CHECK: [[FP:%.*]] = alloca [[APS]]*, align 4
+// CHECK-NEXT: [[X:%.*]] = alloca [[APS]], align 8
+// CHECK-NEXT: [[F:%.*]] = alloca [[PS:%.*]], align 2
+// CHECK-NEXT: [[TMP0:%.*]] = alloca [[APS]], align 8
+// CHECK-NEXT: [[TMP1:%.*]] = alloca [[APS]], align 8
+// CHECK-NEXT: store [[APS]]*
+
+// CHECK-NEXT: [[P:%.*]] = load [[APS]]** [[FP]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[APS]]* [[P]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[APS]]* [[P]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T1]], align 2
+ __c11_atomic_init(fp, (PS){1,2,3});
+
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[APS]]* [[X]] to i8*
+// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 8, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[APS]]* [[X]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: store i16 1, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 1
+// CHECK-NEXT: store i16 2, i16* [[T1]], align 2
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[PS]]* [[T0]], i32 0, i32 2
+// CHECK-NEXT: store i16 3, i16* [[T1]], align 2
+ _Atomic(PS) x = (PS){1,2,3};
+
+// CHECK-NEXT: [[T0:%.*]] = load [[APS]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[APS]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[APS]]* [[TMP0]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_load(i32 8, i8* [[T1]], i8* [[T2]], i32 5)
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[APS]]* [[TMP0]], i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[PS]]* [[F]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[PS]]* [[T0]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[T1]], i8* [[T2]], i32 6, i32 2, i1 false)
+ PS f = *fp;
+
+// CHECK-NEXT: [[T0:%.*]] = load [[APS]]** [[FP]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[APS]]* [[TMP1]], i32 0, i32 0
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[PS]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[PS]]* [[F]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[T2]], i8* [[T3]], i32 6, i32 2, i1 false)
+// CHECK-NEXT: [[T4:%.*]] = bitcast [[APS]]* [[T0]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast [[APS]]* [[TMP1]] to i8*
+// CHECK-NEXT: call arm_aapcscc void @__atomic_store(i32 8, i8* [[T4]], i8* [[T5]], i32 5)
+ *fp = f;
+
+// CHECK-NEXT: ret void
+}
+
+// CHECK: define arm_aapcscc void @testPromotedStructOps([[APS:.*]]*
+
+// FIXME: none of these look right, but we can leave the "test" here
+// to make sure they at least don't crash.
+void testPromotedStructOps(_Atomic(PS) *p) {
+ PS a = __c11_atomic_load(p, 5);
+ __c11_atomic_store(p, a, 5);
+ PS b = __c11_atomic_exchange(p, a, 5);
+ _Bool v = __c11_atomic_compare_exchange_strong(p, &b, a, 5, 5);
+ v = __c11_atomic_compare_exchange_weak(p, &b, a, 5, 5);
+}
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index 4198b62..ebe39fe 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -1,14 +1,14 @@
-// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,divide-by-zero -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -fsanitize-undefined-trap-on-error -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-TRAP
// RUN: %clang_cc1 -fsanitize=null -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-NULL
// RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW
// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
// FIXME: When we only emit each type once, use [[INT]] more below.
-// CHECK: @[[LINE_100:.*]] = private unnamed_addr constant {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i64 4, i8 1
+// CHECK: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i64 4, i8 1
// CHECK: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i64 4, i8 0
-// CHECK: @[[LINE_300_A:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
-// CHECK: @[[LINE_300_B:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
+// CHECK: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
// CHECK: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}}
// CHECK: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i64 4, i8 0 }
// CHECK: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i64 4, i8 1 }
@@ -19,49 +19,78 @@
// CHECK: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} }
// CHECK: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} }
-// CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr constant {{.*}}, i32 100, i32 5 {{.*}}
+// CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}}
// PR6805
// CHECK: @foo
// CHECK-NULL: @foo
+// CHECK-TRAP: @foo
void foo() {
union { int i; } u;
// CHECK: %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
+ // CHECK-TRAP: %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
// CHECK: %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8*
// CHECK-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64(i8* %[[I8PTR]], i1 false)
// CHECK-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
// CHECK-NEXT: %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
+ // CHECK-TRAP: %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8*
+ // CHECK-TRAP-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64(i8* %[[I8PTR]], i1 false)
+ // CHECK-TRAP-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
+ // CHECK-TRAP-NEXT: %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
+
// CHECK: %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64
// CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3
// CHECK-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
+ // CHECK-TRAP: %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64
+ // CHECK-TRAP-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3
+ // CHECK-TRAP-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
+
// CHECK: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
- // CHECK-NEXT: br i1 %[[OK]]
+ // CHECK-NEXT: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]]
+
+ // CHECK-TRAP: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
+ // CHECK-TRAP-NEXT: br i1 %[[OK]], {{.*}}
// CHECK: %[[ARG:.*]] = ptrtoint {{.*}} %[[PTR]] to i64
- // CHECK-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %[[ARG]]) noreturn nounwind
+ // CHECK-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %[[ARG]])
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW:#[0-9]+]]
+ // CHECK-TRAP-NEXT: unreachable
// With -fsanitize=null, only perform the null check.
// CHECK-NULL: %[[NULL:.*]] = icmp ne {{.*}}, null
// CHECK-NULL: br i1 %[[NULL]]
- // CHECK-NULL: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %{{.*}}) noreturn nounwind
+ // CHECK-NULL: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %{{.*}})
#line 100
u.i=1;
}
// CHECK: @bar
+// CHECK-TRAP: @bar
int bar(int *a) {
// CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
// CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
+ // CHECK-TRAP: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
+ // CHECK-TRAP-NEXT: icmp uge i64 %[[SIZE]], 4
+
// CHECK: %[[PTRINT:.*]] = ptrtoint
// CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
// CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
+ // CHECK-TRAP: %[[PTRINT:.*]] = ptrtoint
+ // CHECK-TRAP-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
+ // CHECK-TRAP-NEXT: icmp eq i64 %[[MISALIGN]], 0
+
// CHECK: %[[ARG:.*]] = ptrtoint
- // CHECK-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]]) noreturn nounwind
+ // CHECK-NEXT: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]])
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
+
#line 200
return *a;
}
@@ -73,55 +102,92 @@ int addr_space(int __attribute__((address_space(256))) *a) {
}
// CHECK: @lsh_overflow
+// CHECK-TRAP: @lsh_overflow
int lsh_overflow(int a, int b) {
// CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
- // CHECK-NEXT: br i1 %[[INBOUNDS]]
+ // CHECK-NEXT: br i1 %[[INBOUNDS]], label %[[CHECKBB:.*]], label %[[CONTBB:.*]]
- // FIXME: Only emit one trap block here.
- // CHECK: %[[ARG1:.*]] = zext
- // CHECK-NEXT: %[[ARG2:.*]] = zext
- // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300_A]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]], label %[[CHECKBB:.*]], label %[[CONTBB:.*]]
// CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]]
// CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]]
// CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT]], 0
- // CHECK-NEXT: br i1 %[[NO_OVERFLOW]]
+ // CHECK-NEXT: br label %[[CONTBB]]
+
+ // CHECK-TRAP: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]]
+ // CHECK-TRAP-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]]
+ // CHECK-TRAP-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT]], 0
+ // CHECK-TRAP-NEXT: br label %[[CONTBB]]
+
+ // CHECK: %[[VALID:.*]] = phi i1 [ %[[INBOUNDS]], {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECKBB]] ]
+ // CHECK-NEXT: br i1 %[[VALID]], {{.*}} !prof ![[WEIGHT_MD]]
+
+ // CHECK-TRAP: %[[VALID:.*]] = phi i1 [ %[[INBOUNDS]], {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECKBB]] ]
+ // CHECK-TRAP-NEXT: br i1 %[[VALID]]
+
// CHECK: %[[ARG1:.*]] = zext
// CHECK-NEXT: %[[ARG2:.*]] = zext
- // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300_B]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind
+ // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]])
+ // CHECK-NOT: call void @__ubsan_handle_shift_out_of_bounds
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP: unreachable
+ // CHECK-TRAP-NOT: call void @llvm.trap()
// CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]]
// CHECK-NEXT: ret i32 %[[RET]]
+
+ // CHECK-TRAP: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]]
+ // CHECK-TRAP-NEXT: ret i32 %[[RET]]
#line 300
return a << b;
}
// CHECK: @rsh_inbounds
+// CHECK-TRAP: @rsh_inbounds
int rsh_inbounds(int a, int b) {
- // CHECK: %[[INBOUNDS:.*]] = icmp ult i32 %[[RHS:.*]], 32
+ // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
// CHECK: br i1 %[[INBOUNDS]]
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
+ // CHECK-TRAP: br i1 %[[INBOUNDS]]
+
// CHECK: %[[ARG1:.*]] = zext
// CHECK-NEXT: %[[ARG2:.*]] = zext
- // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_400]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind
+ // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_400]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]])
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
// CHECK: %[[RET:.*]] = ashr i32 %[[LHS]], %[[RHS]]
// CHECK-NEXT: ret i32 %[[RET]]
+
+ // CHECK-TRAP: %[[RET:.*]] = ashr i32 %[[LHS]], %[[RHS]]
+ // CHECK-TRAP-NEXT: ret i32 %[[RET]]
#line 400
return a >> b;
}
// CHECK: @load
+// CHECK-TRAP: @load
int load(int *p) {
- // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}}) noreturn nounwind
+ // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}})
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
#line 500
return *p;
}
// CHECK: @store
+// CHECK-TRAP: @store
void store(int *p, int q) {
- // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}}) noreturn nounwind
+ // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}})
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
#line 600
*p = q;
}
@@ -129,22 +195,31 @@ void store(int *p, int q) {
struct S { int k; };
// CHECK: @member_access
+// CHECK-TRAP: @member_access
int *member_access(struct S *p) {
- // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}}) noreturn nounwind
+ // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}})
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
#line 700
return &p->k;
}
// CHECK: @signed_overflow
+// CHECK-TRAP: @signed_overflow
int signed_overflow(int a, int b) {
// CHECK: %[[ARG1:.*]] = zext
// CHECK-NEXT: %[[ARG2:.*]] = zext
- // CHECK-NEXT: call void @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_800]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) noreturn nounwind
+ // CHECK-NEXT: call void @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_800]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]])
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
#line 800
return a + b;
}
// CHECK: @no_return
+// CHECK-TRAP: @no_return
int no_return() {
// Reaching the end of a noreturn function is fine in C.
// FIXME: If the user explicitly requests -fsanitize=return, we should catch
@@ -152,6 +227,10 @@ int no_return() {
// CHECK-NOT: call
// CHECK-NOT: unreachable
// CHECK: ret i32
+
+ // CHECK-TRAP-NOT: call
+ // CHECK-TRAP-NOT: unreachable
+ // CHECK-TRAP: ret i32
}
// CHECK: @vla_bound
@@ -159,7 +238,7 @@ void vla_bound(int n) {
// CHECK: icmp sgt i32 %[[PARAM:.*]], 0
//
// CHECK: %[[ARG:.*]] = zext i32 %[[PARAM]] to i64
- // CHECK-NEXT: call void @__ubsan_handle_vla_bound_not_positive(i8* bitcast ({{.*}} @[[LINE_900]] to i8*), i64 %[[ARG]]) noreturn nounwind
+ // CHECK-NEXT: call void @__ubsan_handle_vla_bound_not_positive(i8* bitcast ({{.*}} @[[LINE_900]] to i8*), i64 %[[ARG]])
#line 900
int arr[n * 3];
}
@@ -171,55 +250,135 @@ float int_float_no_overflow(__int128 n) {
}
// CHECK: @int_float_overflow
+// CHECK-TRAP: @int_float_overflow
float int_float_overflow(unsigned __int128 n) {
// This is 2**104. FLT_MAX is 2**128 - 2**104.
// CHECK: icmp ule i128 %{{.*}}, -20282409603651670423947251286016
// CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = icmp ule i128 %{{.*}}, -20282409603651670423947251286016
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
return n;
}
// CHECK: @int_fp16_overflow
+// CHECK-TRAP: @int_fp16_overflow
void int_fp16_overflow(int n, __fp16 *p) {
// CHECK: %[[GE:.*]] = icmp sge i32 %{{.*}}, -65504
// CHECK: %[[LE:.*]] = icmp sle i32 %{{.*}}, 65504
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK-TRAP: %[[GE:.*]] = icmp sge i32 %{{.*}}, -65504
+ // CHECK-TRAP: %[[LE:.*]] = icmp sle i32 %{{.*}}, 65504
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
*p = n;
}
// CHECK: @float_int_overflow
+// CHECK-TRAP: @float_int_overflow
int float_int_overflow(float f) {
- // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0xC1E0000000000000
- // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41DFFFFFE0000000
+ // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
+ // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
- // CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK: %[[CAST:.*]] = bitcast float %[[F]] to i32
+ // CHECK: %[[ARG:.*]] = zext i32 %[[CAST]] to i64
+ // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
return f;
}
+// CHECK: @long_double_int_overflow
+// CHECK-TRAP: @long_double_int_overflow
+int long_double_int_overflow(long double ld) {
+ // CHECK: alloca x86_fp80
+ // CHECK: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E8000000100000000
+ // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000
+ // CHECK: and i1 %[[GE]], %[[LE]]
+
+ // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]]
+ // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64
+ // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E800000010000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E800000000000000
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
+ return ld;
+}
+
// CHECK: @float_uint_overflow
+// CHECK-TRAP: @float_uint_overflow
unsigned float_uint_overflow(float f) {
- // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], 0.{{0*}}e+00
- // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 0x41EFFFFFE0000000
+ // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00
+ // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
return f;
}
// CHECK: @fp16_char_overflow
+// CHECK-TRAP: @fp16_char_overflow
signed char fp16_char_overflow(__fp16 *p) {
- // CHECK: %[[GE:.*]] = fcmp oge float %[[F:.*]], -1.28{{0*}}e+02
- // CHECK: %[[LE:.*]] = fcmp ole float %[[F]], 1.27{{0*}}e+02
+ // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02
+ // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
return *p;
}
// CHECK: @float_float_overflow
+// CHECK-TRAP: @float_float_overflow
float float_float_overflow(double f) {
- // CHECK: %[[GE:.*]] = fcmp oge double %[[F:.*]], 0xC7EFFFFFE0000000
- // CHECK: %[[LE:.*]] = fcmp ole double %[[F]], 0x47EFFFFFE0000000
+ // CHECK: %[[F:.*]] = call double @llvm.fabs.f64(
+ // CHECK: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000
+ // CHECK: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
// CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK-TRAP: %[[F:.*]] = call double @llvm.fabs.f64(
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000
+ // CHECK-TRAP: %[[OUTOFBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = xor i1 %[[OUTOFBOUNDS]], true
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
return f;
}
@@ -228,6 +387,7 @@ float float_float_overflow(double f) {
int int_divide_overflow(int a, int b) {
// CHECK: %[[ZERO:.*]] = icmp ne i32 %[[B:.*]], 0
// CHECK-OVERFLOW-NOT: icmp ne i32 %{{.*}}, 0
+ // CHECK-TRAP: %[[ZERO:.*]] = icmp ne i32 %[[B:.*]], 0
// CHECK: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648
// CHECK-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B]], -1
@@ -237,12 +397,41 @@ int int_divide_overflow(int a, int b) {
// CHECK-OVERFLOW-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B:.*]], -1
// CHECK-OVERFLOW-NEXT: %[[OK:.*]] = or i1 %[[AOK]], %[[BOK]]
+ // CHECK-TRAP: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648
+ // CHECK-TRAP-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B]], -1
+ // CHECK-TRAP-NEXT: %[[OVER:.*]] = or i1 %[[AOK]], %[[BOK]]
+
// CHECK: %[[OK:.*]] = and i1 %[[ZERO]], %[[OVER]]
// CHECK: br i1 %[[OK]]
// CHECK-OVERFLOW: br i1 %[[OK]]
+
+ // CHECK-TRAP: %[[OK:.*]] = and i1 %[[ZERO]], %[[OVER]]
+ // CHECK-TRAP: br i1 %[[OK]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP: unreachable
return a / b;
// CHECK: }
// CHECK-OVERFLOW: }
+ // CHECK-TRAP: }
}
+
+// CHECK: @sour_bool
+_Bool sour_bool(_Bool *p) {
+ // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
+ // CHECK: br i1 %[[OK]]
+ // CHECK: call void @__ubsan_handle_load_invalid_value(i8* bitcast ({{.*}}), i64 {{.*}})
+
+ // CHECK-TRAP: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
+ // CHECK-TRAP: br i1 %[[OK]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP: unreachable
+ return *p;
+}
+
+// CHECK: ![[WEIGHT_MD]] = metadata !{metadata !"branch_weights", i32 1048575, i32 1}
+
+// CHECK-TRAP: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/test/CodeGen/code-coverage.c b/test/CodeGen/code-coverage.c
new file mode 100644
index 0000000..1b87d64
--- /dev/null
+++ b/test/CodeGen/code-coverage.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-no-function-names-in-data %s -o - | FileCheck %s --check-prefix WITHOUTNAMES
+
+// <rdar://problem/12843084>
+
+int test1(int a) {
+ switch (a % 2) {
+ case 0:
+ ++a;
+ case 1:
+ a /= 2;
+ }
+ return a;
+}
+
+// Check that the noredzone flag is set on the generated functions.
+
+// CHECK: void @__llvm_gcov_indirect_counter_increment(i32* %{{.*}}, i64** %{{.*}}) unnamed_addr [[NRZ:#[0-9]+]]
+
+// Inside llvm_gcov_writeout, check that -coverage-no-function-names-in-data
+// passes null as the function name.
+// CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ]]
+// CHECK: call void @llvm_gcda_emit_function({{.*}}, i8* getelementptr {{.*}}, {{.*}})
+// WITHOUTNAMES: void @__llvm_gcov_writeout() unnamed_addr
+// WITHOUTNAMES: call void @llvm_gcda_emit_function({{.*}}, i8* null, {{.*}})
+
+// CHECK: void @__llvm_gcov_flush() unnamed_addr [[NRZ]]
+// CHECK: void @__llvm_gcov_init() unnamed_addr [[NRZ]]
+
+// CHECK: attributes [[NRZ]] = { {{.*}}noredzone{{.*}} }
diff --git a/test/CodeGen/complex-convert.c b/test/CodeGen/complex-convert.c
new file mode 100644
index 0000000..aaa57a0
--- /dev/null
+++ b/test/CodeGen/complex-convert.c
@@ -0,0 +1,717 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// Test conversions between complex integer types and standard integer
+// types. Tests binary operator conversion and assignment conversion
+// with widening, narrowing, and equal-size operands. Signed and unsigned
+// variations. Attempts to work for all targets. Assumptions:
+//
+// * "char" and "long long" are of different lengths (CHSIZE and LLSIZE).
+// * Arithmetic is not performed directly on "char" type.
+
+void foo(signed char sc, unsigned char uc, signed long long sll,
+ unsigned long long ull, _Complex signed char csc,
+ _Complex unsigned char cuc, _Complex signed long long csll,
+ _Complex unsigned long long cull) {
+
+ signed char sc1;
+ unsigned char uc1;
+ signed long long sll1;
+ unsigned long long ull1;
+ _Complex signed char csc1;
+ _Complex unsigned char cuc1;
+ _Complex signed long long csll1;
+ _Complex unsigned long long cull1;
+ // CHECK: define void @foo(
+ // CHECK: alloca i[[CHSIZE:[0-9]+]], align [[CHALIGN:[0-9]+]]
+ // CHECK-NEXT: alloca i[[CHSIZE]], align [[CHALIGN]]
+ // CHECK-NEXT: alloca i[[LLSIZE:[0-9]+]], align [[LLALIGN:[0-9]+]]
+
+ sc1 = csc;
+ // CHECK: %[[VAR1:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR2:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR1]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR2]], i[[CHSIZE]]* %[[SC1:[A-Za-z0-9.]+]], align [[CHALIGN]]
+
+ sc1 = cuc;
+ // CHECK-NEXT: %[[VAR3:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR4:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR3]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR4]], i[[CHSIZE]]* %[[SC1]], align [[CHALIGN]]
+
+ sc1 = csll;
+ // CHECK-NEXT: %[[VAR5:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR6:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR5]]
+ // CHECK-NEXT: %[[VAR7:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR6]] to i[[CHSIZE]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR7]], i[[CHSIZE]]* %[[SC1]], align [[CHALIGN]]
+
+ sc1 = cull;
+ // CHECK-NEXT: %[[VAR8:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR9:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR8]]
+ // CHECK-NEXT: %[[VAR10:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR9]] to i[[CHSIZE]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR10]], i[[CHSIZE]]* %[[SC1]], align [[CHALIGN]]
+
+ uc1 = csc;
+ // CHECK-NEXT: %[[VAR11:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR12:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR11]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR12]], i[[CHSIZE]]* %[[UC1:[A-Za-z0-9.]+]], align [[CHALIGN]]
+
+ uc1 = cuc;
+ // CHECK-NEXT: %[[VAR13:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR14:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR13]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR14]], i[[CHSIZE]]* %[[UC1]], align [[CHALIGN]]
+
+ uc1 = csll;
+ // CHECK-NEXT: %[[VAR15:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR16:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR15]]
+ // CHECK-NEXT: %[[VAR17:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR16]] to i[[CHSIZE]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR17]], i[[CHSIZE]]* %[[UC1]], align [[CHALIGN]]
+
+ uc1 = cull;
+ // CHECK-NEXT: %[[VAR18:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR19:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR18]]
+ // CHECK-NEXT: %[[VAR20:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR19]] to i[[CHSIZE]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR20]], i[[CHSIZE]]* %[[UC1]], align [[CHALIGN]]
+
+ sll1 = csc;
+ // CHECK-NEXT: %[[VAR21:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR22:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR21]]
+ // CHECK-NEXT: %[[VAR23:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR22]] to i[[LLSIZE]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR23]], i[[LLSIZE]]* %[[SLL1:[A-Za-z0-9]+]], align [[LLALIGN]]
+
+ sll1 = cuc;
+ // CHECK-NEXT: %[[VAR24:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR25:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR24]]
+ // CHECK-NEXT: %[[VAR26:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR25]] to i[[LLSIZE]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR26]], i[[LLSIZE]]* %[[SLL1]], align [[LLALIGN]]
+
+ sll1 = csll;
+ // CHECK-NEXT: %[[VAR27:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR28:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR27]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR28]], i[[LLSIZE]]* %[[SLL1]], align [[LLALIGN]]
+
+ sll1 = cull;
+ // CHECK-NEXT: %[[VAR29:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR30:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR29]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR30]], i[[LLSIZE]]* %[[SLL1]], align [[LLALIGN]]
+
+ ull1 = csc;
+ // CHECK-NEXT: %[[VAR31:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR32:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR31]]
+ // CHECK-NEXT: %[[VAR33:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR32]] to i[[LLSIZE]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR33]], i[[LLSIZE]]* %[[ULL1:[A-Za-z0-9]+]], align [[LLALIGN]]
+
+ ull1 = cuc;
+ // CHECK-NEXT: %[[VAR34:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR35:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR34]]
+ // CHECK-NEXT: %[[VAR36:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR35]] to i[[LLSIZE]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR36]], i[[LLSIZE]]* %[[ULL1]], align [[LLALIGN]]
+
+ ull1 = csll;
+ // CHECK-NEXT: %[[VAR37:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR38:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR37]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR38]], i[[LLSIZE]]* %[[ULL1]], align [[LLALIGN]]
+
+ ull1 = cull;
+ // CHECK-NEXT: %[[VAR39:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR40:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR39]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR40]], i[[LLSIZE]]* %[[ULL1]], align [[LLALIGN]]
+
+ csc1 = sc;
+ // CHECK-NEXT: %[[VAR41:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR:[A-Za-z0-9.]+]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR42:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR43:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR41]], i[[CHSIZE]]* %[[VAR42]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR43]]
+
+ csc1 = uc;
+ // CHECK-NEXT: %[[VAR44:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR:[A-Za-z0-9.]+]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR45:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR46:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR44]], i[[CHSIZE]]* %[[VAR45]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR46]]
+
+ csc1 = sll;
+ // CHECK-NEXT: %[[VAR47:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR:[A-Za-z0-9.]+]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR48:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR47]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR49:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR50:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR48]], i[[CHSIZE]]* %[[VAR49]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR50]]
+
+ csc1 = ull;
+ // CHECK-NEXT: %[[VAR51:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR:[A-Za-z0-9.]+]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR52:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR51]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR53:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR54:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR52]], i[[CHSIZE]]* %[[VAR53]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR54]]
+
+ cuc1 = sc;
+ // CHECK-NEXT: %[[VAR55:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR56:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR57:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR55]], i[[CHSIZE]]* %[[VAR56]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR57]]
+
+ cuc1 = uc;
+ // CHECK-NEXT: %[[VAR58:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR59:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR60:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR58]], i[[CHSIZE]]* %[[VAR59]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR60]]
+
+ cuc1 = sll;
+ // CHECK-NEXT: %[[VAR61:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR62:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR61]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR63:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR64:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR62]], i[[CHSIZE]]* %[[VAR63]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR64]]
+
+ cuc1 = ull;
+ // CHECK-NEXT: %[[VAR65:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR66:[A-Za-z0-9.]+]] = trunc i[[LLSIZE]] %[[VAR65]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR67:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR68:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR66]], i[[CHSIZE]]* %[[VAR67]]
+ // CHECK-NEXT: store i[[CHSIZE]] 0, i[[CHSIZE]]* %[[VAR68]]
+
+ csll1 = sc;
+ // CHECK-NEXT: %[[VAR69:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR70:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR69]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR71:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR72:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR70]], i[[LLSIZE]]* %[[VAR71]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR72]]
+
+ csll1 = uc;
+ // CHECK-NEXT: %[[VAR73:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR74:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR73]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR75:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR76:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR74]], i[[LLSIZE]]* %[[VAR75]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR76]]
+
+ csll1 = sll;
+ // CHECK-NEXT: %[[VAR77:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR78:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR79:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR77]], i[[LLSIZE]]* %[[VAR78]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR79]]
+
+ csll1 = ull;
+ // CHECK-NEXT: %[[VAR77:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR78:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR79:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR77]], i[[LLSIZE]]* %[[VAR78]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR79]]
+
+ cull1 = sc;
+ // CHECK-NEXT: %[[VAR80:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR81:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR80]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR82:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR83:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR81]], i[[LLSIZE]]* %[[VAR82]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR83]]
+
+ cull1 = uc;
+ // CHECK-NEXT: %[[VAR84:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR85:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR84]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR86:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR87:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR85]], i[[LLSIZE]]* %[[VAR86]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR87]]
+
+ cull1 = sll;
+ // CHECK-NEXT: %[[VAR88:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR89:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR90:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR88]], i[[LLSIZE]]* %[[VAR89]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR90]]
+
+ cull1 = ull;
+ // CHECK-NEXT: %[[VAR91:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR92:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR93:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR91]], i[[LLSIZE]]* %[[VAR92]]
+ // CHECK-NEXT: store i[[LLSIZE]] 0, i[[LLSIZE]]* %[[VAR93]]
+
+ csc1 = sc + csc;
+ // CHECK-NEXT: %[[VAR94:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR95:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR94]] to i[[ARSIZE:[0-9]+]]
+ // CHECK-NEXT: %[[VAR96:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR97:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR96]]
+ // CHECK-NEXT: %[[VAR98:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR99:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR98]]
+ // CHECK-NEXT: %[[VAR100:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR97]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR101:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR99]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR102:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR95]], %[[VAR100]]
+ // CHECK-NEXT: %[[VAR103:[A-Za-z0-9.]+]] = add i[[ARSIZE]] 0, %[[VAR101]]
+ // CHECK-NEXT: %[[VAR104:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR102]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR105:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR103]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR106:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR107:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR104]], i[[CHSIZE]]* %[[VAR106]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR105]], i[[CHSIZE]]* %[[VAR107]]
+
+ cuc1 = sc + cuc;
+ // CHECK-NEXT: %[[VAR108:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR109:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR108]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR110:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR111:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR110]]
+ // CHECK-NEXT: %[[VAR112:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR113:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR112]]
+ // CHECK-NEXT: %[[VAR114:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR111]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR115:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR113]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR116:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR109]], %[[VAR114]]
+ // CHECK-NEXT: %[[VAR117:[A-Za-z0-9.]+]] = add i[[ARSIZE]] 0, %[[VAR115]]
+ // CHECK-NEXT: %[[VAR118:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR116]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR119:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR117]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR120:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR121:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR118]], i[[CHSIZE]]* %[[VAR120]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR119]], i[[CHSIZE]]* %[[VAR121]]
+
+ csll1 = sc + csll;
+ // CHECK-NEXT: %[[VAR122:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR123:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR122]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR124:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR125:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR124]]
+ // CHECK-NEXT: %[[VAR126:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR127:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR126]]
+ // CHECK-NEXT: %[[VAR128:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR123]], %[[VAR125]]
+ // CHECK-NEXT: %[[VAR129:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR127]]
+ // CHECK-NEXT: %[[VAR130:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR131:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR128]], i[[LLSIZE]]* %[[VAR130]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR129]], i[[LLSIZE]]* %[[VAR131]]
+
+ cull1 = sc + cull;
+ // CHECK-NEXT: %[[VAR132:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR133:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR132]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR134:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR135:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR134]]
+ // CHECK-NEXT: %[[VAR136:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR137:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR136]]
+ // CHECK-NEXT: %[[VAR138:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR133]], %[[VAR135]]
+ // CHECK-NEXT: %[[VAR139:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR137]]
+ // CHECK-NEXT: %[[VAR140:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR141:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR138]], i[[LLSIZE]]* %[[VAR140]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR139]], i[[LLSIZE]]* %[[VAR141]]
+
+ csc1 = uc + csc;
+ // CHECK-NEXT: %[[VAR142:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR143:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR142]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR144:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR145:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR144]]
+ // CHECK-NEXT: %[[VAR146:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR147:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR146]]
+ // CHECK-NEXT: %[[VAR148:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR145]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR149:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR147]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR150:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR143]], %[[VAR148]]
+ // CHECK-NEXT: %[[VAR151:[A-Za-z0-9.]+]] = add i[[ARSIZE]] 0, %[[VAR149]]
+ // CHECK-NEXT: %[[VAR152:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR150]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR153:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR151]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR154:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR155:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR152]], i[[CHSIZE]]* %[[VAR154]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR153]], i[[CHSIZE]]* %[[VAR155]]
+
+ cuc1 = uc + cuc;
+ // CHECK-NEXT: %[[VAR156:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR157:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR156]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR158:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR159:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR158]]
+ // CHECK-NEXT: %[[VAR160:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR161:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR160]]
+ // CHECK-NEXT: %[[VAR162:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR159]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR163:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR161]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR164:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR157]], %[[VAR162]]
+ // CHECK-NEXT: %[[VAR165:[A-Za-z0-9.]+]] = add i[[ARSIZE]] 0, %[[VAR163]]
+ // CHECK-NEXT: %[[VAR166:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR164]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR167:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR165]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR168:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR169:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR166]], i[[CHSIZE]]* %[[VAR168]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR167]], i[[CHSIZE]]* %[[VAR169]]
+
+ csll1 = uc + csll;
+ // CHECK-NEXT: %[[VAR170:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR171:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR170]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR172:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR173:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR172]]
+ // CHECK-NEXT: %[[VAR174:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR175:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR174]]
+ // CHECK-NEXT: %[[VAR176:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR171]], %[[VAR173]]
+ // CHECK-NEXT: %[[VAR177:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR175]]
+ // CHECK-NEXT: %[[VAR178:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR179:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR176]], i[[LLSIZE]]* %[[VAR178]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR177]], i[[LLSIZE]]* %[[VAR179]]
+
+ cull1 = uc + cull;
+ // CHECK-NEXT: %[[VAR180:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR181:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR180]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR182:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR183:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR182]]
+ // CHECK-NEXT: %[[VAR184:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR185:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR184]]
+ // CHECK-NEXT: %[[VAR186:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR181]], %[[VAR183]]
+ // CHECK-NEXT: %[[VAR187:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR185]]
+ // CHECK-NEXT: %[[VAR188:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR189:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR186]], i[[LLSIZE]]* %[[VAR188]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR187]], i[[LLSIZE]]* %[[VAR189]]
+
+ csll1 = sll + csc;
+ // CHECK-NEXT: %[[VAR190:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR191:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR192:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR191]]
+ // CHECK-NEXT: %[[VAR193:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR194:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR193]]
+ // CHECK-NEXT: %[[VAR195:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR192]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR196:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR194]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR197:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR190]], %[[VAR195]]
+ // CHECK-NEXT: %[[VAR198:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR196]]
+ // CHECK-NEXT: %[[VAR199:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR200:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR197]], i[[LLSIZE]]* %[[VAR199]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR198]], i[[LLSIZE]]* %[[VAR200]]
+
+ csll1 = sll + cuc;
+ // CHECK-NEXT: %[[VAR201:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR202:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR203:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR202]]
+ // CHECK-NEXT: %[[VAR204:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR205:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR204]]
+ // CHECK-NEXT: %[[VAR206:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR203]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR207:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR205]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR208:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR201]], %[[VAR206]]
+ // CHECK-NEXT: %[[VAR209:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR207]]
+ // CHECK-NEXT: %[[VAR210:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR211:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR208]], i[[LLSIZE]]* %[[VAR210]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR209]], i[[LLSIZE]]* %[[VAR211]]
+
+ csll1 = sll + csll;
+ // CHECK-NEXT: %[[VAR212:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR213:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR214:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR213]]
+ // CHECK-NEXT: %[[VAR215:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR216:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR215]]
+ // CHECK-NEXT: %[[VAR217:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR212]], %[[VAR214]]
+ // CHECK-NEXT: %[[VAR218:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR216]]
+ // CHECK-NEXT: %[[VAR219:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR220:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR217]], i[[LLSIZE]]* %[[VAR219]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR218]], i[[LLSIZE]]* %[[VAR220]]
+
+ csll1 = sll + cull;
+ // CHECK-NEXT: %[[VAR221:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR222:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR223:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR222]]
+ // CHECK-NEXT: %[[VAR224:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR225:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR224]]
+ // CHECK-NEXT: %[[VAR226:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR221]], %[[VAR223]]
+ // CHECK-NEXT: %[[VAR227:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR225]]
+ // CHECK-NEXT: %[[VAR228:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR229:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR226]], i[[LLSIZE]]* %[[VAR228]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR227]], i[[LLSIZE]]* %[[VAR229]]
+
+ csll1 = ull + csc;
+ // CHECK-NEXT: %[[VAR230:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR231:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR232:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR231]]
+ // CHECK-NEXT: %[[VAR233:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR234:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR233]]
+ // CHECK-NEXT: %[[VAR235:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR232]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR236:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR234]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR237:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR230]], %[[VAR235]]
+ // CHECK-NEXT: %[[VAR238:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR236]]
+ // CHECK-NEXT: %[[VAR239:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR240:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR237]], i[[LLSIZE]]* %[[VAR239]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR238]], i[[LLSIZE]]* %[[VAR240]]
+
+ cull1 = ull + cuc;
+ // CHECK-NEXT: %[[VAR241:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR242:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR243:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR242]]
+ // CHECK-NEXT: %[[VAR244:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR245:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR244]]
+ // CHECK-NEXT: %[[VAR246:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR243]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR247:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR245]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR248:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR241]], %[[VAR246]]
+ // CHECK-NEXT: %[[VAR249:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR247]]
+ // CHECK-NEXT: %[[VAR250:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR251:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR248]], i[[LLSIZE]]* %[[VAR250]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR249]], i[[LLSIZE]]* %[[VAR251]]
+
+ csll1 = ull + csll;
+ // CHECK-NEXT: %[[VAR252:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR253:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR254:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR253]]
+ // CHECK-NEXT: %[[VAR255:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR256:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR255]]
+ // CHECK-NEXT: %[[VAR257:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR252]], %[[VAR254]]
+ // CHECK-NEXT: %[[VAR258:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR256]]
+ // CHECK-NEXT: %[[VAR259:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR260:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR257]], i[[LLSIZE]]* %[[VAR259]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR258]], i[[LLSIZE]]* %[[VAR260]]
+
+ cull1 = ull + cull;
+ // CHECK-NEXT: %[[VAR261:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR262:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR263:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR262]]
+ // CHECK-NEXT: %[[VAR264:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR265:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR264]]
+ // CHECK-NEXT: %[[VAR266:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR261]], %[[VAR263]]
+ // CHECK-NEXT: %[[VAR267:[A-Za-z0-9.]+]] = add i[[LLSIZE]] 0, %[[VAR265]]
+ // CHECK-NEXT: %[[VAR268:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR269:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR266]], i[[LLSIZE]]* %[[VAR268]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR267]], i[[LLSIZE]]* %[[VAR269]]
+
+ csc1 = csc + sc;
+ // CHECK-NEXT: %[[VAR270:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR271:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR270]]
+ // CHECK-NEXT: %[[VAR272:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR273:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR272]]
+ // CHECK-NEXT: %[[VAR274:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR271]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR275:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR273]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR276:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR277:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR276]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR278:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR274]], %[[VAR277]]
+ // CHECK-NEXT: %[[VAR279:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR275]], 0
+ // CHECK-NEXT: %[[VAR280:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR278]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR281:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR279]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR282:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR283:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR280]], i[[CHSIZE]]* %[[VAR282]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR281]], i[[CHSIZE]]* %[[VAR283]]
+
+ csc1 = csc + uc;
+ // CHECK-NEXT: %[[VAR284:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR285:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR284]]
+ // CHECK-NEXT: %[[VAR286:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR287:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR286]]
+ // CHECK-NEXT: %[[VAR288:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR285]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR289:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR287]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR290:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR291:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR290]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR292:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR288]], %[[VAR291]]
+ // CHECK-NEXT: %[[VAR293:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR289]], 0
+ // CHECK-NEXT: %[[VAR294:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR292]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR295:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR293]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR296:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR297:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR294]], i[[CHSIZE]]* %[[VAR296]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR295]], i[[CHSIZE]]* %[[VAR297]]
+
+ csll1 = csc + sll;
+ // CHECK-NEXT: %[[VAR298:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR299:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR298]]
+ // CHECK-NEXT: %[[VAR300:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR301:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR300]]
+ // CHECK-NEXT: %[[VAR302:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR299]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR303:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR301]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR304:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR305:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR302]], %[[VAR304]]
+ // CHECK-NEXT: %[[VAR306:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR303]], 0
+ // CHECK-NEXT: %[[VAR307:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR308:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR305]], i[[LLSIZE]]* %[[VAR307]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR306]], i[[LLSIZE]]* %[[VAR308]]
+
+ csll1 = csc + ull;
+ // CHECK-NEXT: %[[VAR309:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR310:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR309]]
+ // CHECK-NEXT: %[[VAR311:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR312:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR311]]
+ // CHECK-NEXT: %[[VAR313:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR310]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR314:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR312]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR315:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR316:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR313]], %[[VAR315]]
+ // CHECK-NEXT: %[[VAR317:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR314]], 0
+ // CHECK-NEXT: %[[VAR318:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR319:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR316]], i[[LLSIZE]]* %[[VAR318]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR317]], i[[LLSIZE]]* %[[VAR319]]
+
+ csc1 = cuc + sc;
+ // CHECK-NEXT: %[[VAR320:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR321:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR320]]
+ // CHECK-NEXT: %[[VAR322:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR323:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR322]]
+ // CHECK-NEXT: %[[VAR324:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR321]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR325:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR323]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR326:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR327:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR326]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR328:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR324]], %[[VAR327]]
+ // CHECK-NEXT: %[[VAR329:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR325]], 0
+ // CHECK-NEXT: %[[VAR330:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR328]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR331:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR329]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR332:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR333:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CSC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR330]], i[[CHSIZE]]* %[[VAR332]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR331]], i[[CHSIZE]]* %[[VAR333]]
+
+ cuc1 = cuc + uc;
+ // CHECK-NEXT: %[[VAR334:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR335:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR334]]
+ // CHECK-NEXT: %[[VAR336:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR337:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR336]]
+ // CHECK-NEXT: %[[VAR338:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR335]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR339:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR337]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR340:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR341:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR340]] to i[[ARSIZE]]
+ // CHECK-NEXT: %[[VAR342:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR338]], %[[VAR341]]
+ // CHECK-NEXT: %[[VAR343:[A-Za-z0-9.]+]] = add i[[ARSIZE]] %[[VAR339]], 0
+ // CHECK-NEXT: %[[VAR344:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR342]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR345:[A-Za-z0-9.]+]] = trunc i[[ARSIZE]] %[[VAR343]] to i[[CHSIZE]]
+ // CHECK-NEXT: %[[VAR346:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR347:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR344]], i[[CHSIZE]]* %[[VAR346]]
+ // CHECK-NEXT: store i[[CHSIZE]] %[[VAR345]], i[[CHSIZE]]* %[[VAR347]]
+
+ csll1 = cuc + sll;
+ // CHECK-NEXT: %[[VAR348:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR349:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR348]]
+ // CHECK-NEXT: %[[VAR350:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR351:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR350]]
+ // CHECK-NEXT: %[[VAR352:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR349]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR353:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR351]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR354:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR355:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR352]], %[[VAR354]]
+ // CHECK-NEXT: %[[VAR356:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR353]], 0
+ // CHECK-NEXT: %[[VAR357:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR358:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR355]], i[[LLSIZE]]* %[[VAR357]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR356]], i[[LLSIZE]]* %[[VAR358]]
+
+ cull1 = cuc + ull;
+ // CHECK-NEXT: %[[VAR357:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR358:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR357]]
+ // CHECK-NEXT: %[[VAR359:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]] }* %[[CUC]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR360:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[VAR359]]
+ // CHECK-NEXT: %[[VAR361:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR358]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR362:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR360]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR363:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR364:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR361]], %[[VAR363]]
+ // CHECK-NEXT: %[[VAR365:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR362]], 0
+ // CHECK-NEXT: %[[VAR366:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR367:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR364]], i[[LLSIZE]]* %[[VAR366]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR365]], i[[LLSIZE]]* %[[VAR367]]
+
+ csll1 = csll + sc;
+ // CHECK-NEXT: %[[VAR368:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR369:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR368]]
+ // CHECK-NEXT: %[[VAR370:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR371:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR370]]
+ // CHECK-NEXT: %[[VAR372:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR373:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR372]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR374:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR369]], %[[VAR373]]
+ // CHECK-NEXT: %[[VAR375:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR371]], 0
+ // CHECK-NEXT: %[[VAR376:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR377:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR374]], i[[LLSIZE]]* %[[VAR376]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR375]], i[[LLSIZE]]* %[[VAR377]]
+
+ csll1 = csll + uc;
+ // CHECK-NEXT: %[[VAR378:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR379:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR378]]
+ // CHECK-NEXT: %[[VAR380:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR381:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR380]]
+ // CHECK-NEXT: %[[VAR382:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR383:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR382]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR384:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR379]], %[[VAR383]]
+ // CHECK-NEXT: %[[VAR385:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR381]], 0
+ // CHECK-NEXT: %[[VAR386:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR387:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR384]], i[[LLSIZE]]* %[[VAR386]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR385]], i[[LLSIZE]]* %[[VAR387]]
+
+ csll1 = csll + sll;
+ // CHECK-NEXT: %[[VAR388:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR389:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR388]]
+ // CHECK-NEXT: %[[VAR390:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR391:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR390]]
+ // CHECK-NEXT: %[[VAR392:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR393:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR389]], %[[VAR392]]
+ // CHECK-NEXT: %[[VAR394:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR391]], 0
+ // CHECK-NEXT: %[[VAR395:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR396:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR393]], i[[LLSIZE]]* %[[VAR395]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR394]], i[[LLSIZE]]* %[[VAR396]]
+
+ csll1 = csll + ull;
+ // CHECK-NEXT: %[[VAR397:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR398:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR397]]
+ // CHECK-NEXT: %[[VAR399:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR400:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR399]]
+ // CHECK-NEXT: %[[VAR401:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR402:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR398]], %[[VAR401]]
+ // CHECK-NEXT: %[[VAR403:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR400]], 0
+ // CHECK-NEXT: %[[VAR404:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR405:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR402]], i[[LLSIZE]]* %[[VAR404]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR403]], i[[LLSIZE]]* %[[VAR405]]
+
+ csll1 = cull + sc;
+ // CHECK-NEXT: %[[VAR406:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR407:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR406]]
+ // CHECK-NEXT: %[[VAR408:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR409:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR408]]
+ // CHECK-NEXT: %[[VAR410:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[SCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR411:[A-Za-z0-9.]+]] = sext i[[CHSIZE]] %[[VAR410]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR412:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR407]], %[[VAR411]]
+ // CHECK-NEXT: %[[VAR413:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR409]], 0
+ // CHECK-NEXT: %[[VAR414:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR415:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR412]], i[[LLSIZE]]* %[[VAR414]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR413]], i[[LLSIZE]]* %[[VAR415]]
+
+ cull1 = cull + uc;
+ // CHECK-NEXT: %[[VAR416:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR417:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR416]]
+ // CHECK-NEXT: %[[VAR418:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR419:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR418]]
+ // CHECK-NEXT: %[[VAR420:[A-Za-z0-9.]+]] = load i[[CHSIZE]]* %[[UCADDR]], align [[CHALIGN]]
+ // CHECK-NEXT: %[[VAR421:[A-Za-z0-9.]+]] = zext i[[CHSIZE]] %[[VAR420]] to i[[LLSIZE]]
+ // CHECK-NEXT: %[[VAR422:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR417]], %[[VAR421]]
+ // CHECK-NEXT: %[[VAR423:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR419]], 0
+ // CHECK-NEXT: %[[VAR424:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR425:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR422]], i[[LLSIZE]]* %[[VAR424]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR423]], i[[LLSIZE]]* %[[VAR425]]
+
+ csll1 = cull + sll;
+ // CHECK-NEXT: %[[VAR426:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR427:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR426]]
+ // CHECK-NEXT: %[[VAR428:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR429:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR428]]
+ // CHECK-NEXT: %[[VAR430:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[SLLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR431:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR427]], %[[VAR430]]
+ // CHECK-NEXT: %[[VAR432:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR429]], 0
+ // CHECK-NEXT: %[[VAR433:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR434:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CSLL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR431]], i[[LLSIZE]]* %[[VAR433]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR432]], i[[LLSIZE]]* %[[VAR434]]
+
+ cull1 = cull + ull;
+ // CHECK-NEXT: %[[VAR435:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR436:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR435]]
+ // CHECK-NEXT: %[[VAR437:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[VAR438:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[VAR437]]
+ // CHECK-NEXT: %[[VAR439:[A-Za-z0-9.]+]] = load i[[LLSIZE]]* %[[ULLADDR]], align [[LLALIGN]]
+ // CHECK-NEXT: %[[VAR440:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR436]], %[[VAR439]]
+ // CHECK-NEXT: %[[VAR441:[A-Za-z0-9.]+]] = add i[[LLSIZE]] %[[VAR438]], 0
+ // CHECK-NEXT: %[[VAR442:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[VAR443:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[LLSIZE]], i[[LLSIZE]] }* %[[CULL1]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR440]], i[[LLSIZE]]* %[[VAR442]]
+ // CHECK-NEXT: store i[[LLSIZE]] %[[VAR441]], i[[LLSIZE]]* %[[VAR443]]
+}
+
diff --git a/test/CodeGen/compound-assign-overflow.c b/test/CodeGen/compound-assign-overflow.c
new file mode 100644
index 0000000..e82061b
--- /dev/null
+++ b/test/CodeGen/compound-assign-overflow.c
@@ -0,0 +1,36 @@
+// Verify proper type emitted for compound assignments
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=signed-integer-overflow,unsigned-integer-overflow | FileCheck %s
+
+#include <stdint.h>
+
+// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
+// CHECK: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]]
+// CHECK: @[[UINT:.*]] = private unnamed_addr constant { i16, i16, [15 x i8] } { i16 0, i16 10, [15 x i8] c"'unsigned int'\00" }
+// CHECK: @[[LINE_200:.*]] = private unnamed_addr global {{.*}}, i32 200, i32 5 {{.*}} @[[UINT]]
+// CHECK: @[[DIVINT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
+// CHECK: @[[LINE_300:.*]] = private unnamed_addr global {{.*}}, i32 300, i32 5 {{.*}} @[[DIVINT]]
+
+int32_t x;
+
+// CHECK: @compaddsigned
+void compaddsigned() {
+#line 100
+ x += ((int32_t)1);
+ // CHECK: @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), {{.*}})
+}
+
+// CHECK: @compaddunsigned
+void compaddunsigned() {
+#line 200
+ x += ((uint32_t)1U);
+ // CHECK: @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), {{.*}})
+}
+
+int8_t a, b;
+
+// CHECK: @compdiv
+void compdiv() {
+#line 300
+ a /= b;
+ // CHECK: @__ubsan_handle_divrem_overflow(i8* bitcast ({{.*}} @[[LINE_300]] to i8*), {{.*}})
+}
diff --git a/test/CodeGen/compound-literal.c b/test/CodeGen/compound-literal.c
index a8eec61..e4bf962 100644
--- a/test/CodeGen/compound-literal.c
+++ b/test/CodeGen/compound-literal.c
@@ -32,3 +32,37 @@ void f() {
s = (S){s.y,s.x};
// CHECK-NEXT: ret void
}
+
+// CHECK: define i48 @g(
+struct G { short x, y, z; };
+struct G g(int x, int y, int z) {
+ // CHECK: [[RESULT:%.*]] = alloca [[G:%.*]], align 2
+ // CHECK-NEXT: [[X:%.*]] = alloca i32, align 4
+ // CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
+ // CHECK-NEXT: [[Z:%.*]] = alloca i32, align 4
+ // CHECK-NEXT: [[COERCE_TEMP:%.*]] = alloca i48
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: store i32
+
+ // Evaluate the compound literal directly in the result value slot.
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[G]]* [[RESULT]], i32 0, i32 0
+ // CHECK-NEXT: [[T1:%.*]] = load i32* [[X]], align 4
+ // CHECK-NEXT: [[T2:%.*]] = trunc i32 [[T1]] to i16
+ // CHECK-NEXT: store i16 [[T2]], i16* [[T0]], align 2
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[G]]* [[RESULT]], i32 0, i32 1
+ // CHECK-NEXT: [[T1:%.*]] = load i32* [[Y]], align 4
+ // CHECK-NEXT: [[T2:%.*]] = trunc i32 [[T1]] to i16
+ // CHECK-NEXT: store i16 [[T2]], i16* [[T0]], align 2
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[G]]* [[RESULT]], i32 0, i32 2
+ // CHECK-NEXT: [[T1:%.*]] = load i32* [[Z]], align 4
+ // CHECK-NEXT: [[T2:%.*]] = trunc i32 [[T1]] to i16
+ // CHECK-NEXT: store i16 [[T2]], i16* [[T0]], align 2
+ return (struct G) { x, y, z };
+
+ // CHECK-NEXT: [[T0:%.*]] = bitcast i48* [[COERCE_TEMP]] to i8*
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[G]]* [[RESULT]] to i8*
+ // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 6
+ // CHECK-NEXT: [[T0:%.*]] = load i48* [[COERCE_TEMP]]
+ // CHECK-NEXT: ret i48 [[T0]]
+}
diff --git a/test/CodeGen/debug-info-args.c b/test/CodeGen/debug-info-args.c
index 1d4ea10..3312952 100644
--- a/test/CodeGen/debug-info-args.c
+++ b/test/CodeGen/debug-info-args.c
@@ -2,8 +2,8 @@
int somefunc(char *x, int y, double z) {
- // CHECK: {{.*metadata !8, i32 0, i32 0}.*DW_TAG_subroutine_type}}
- // CHECK: {{!8 = .*metadata ![^,]*, metadata ![^,]*, metadata ![^,]*, metadata ![^,]*}}
+ // CHECK: metadata ![[NUM:[^,]*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type
+ // CHECK: ![[NUM]] = {{metadata !{metadata ![^,]*, metadata ![^,]*, metadata ![^,]*, metadata ![^,]*}}}
return y;
}
diff --git a/test/CodeGen/debug-info-line.c b/test/CodeGen/debug-info-line.c
index 9e6e971..8f869d0 100644
--- a/test/CodeGen/debug-info-line.c
+++ b/test/CodeGen/debug-info-line.c
@@ -1,9 +1,8 @@
// RUN: %clang -emit-llvm -S -g %s -o - | FileCheck %s
// Radar 8396182
-// There is only one lexical block, but we need a DILexicalBlock and two
-// DILexicalBlockFile to correctly represent file info. This means we have
-// two lexical blocks shown as the latter is also tagged as a lexical block.
+// There are no lexical blocks, but we need two DILexicalBlockFiles to
+// correctly represent file info.
int foo() {
int i = 1;
@@ -16,7 +15,6 @@ int foo() {
}
// CHECK: DW_TAG_lexical_block
-// CHECK: DW_TAG_lexical_block
// CHECK: !"m.h"
// CHECK: DW_TAG_lexical_block
// CHECK: !"m.c"
diff --git a/test/CodeGen/debug-info-scope.c b/test/CodeGen/debug-info-scope.c
index 6051e6e..9decaea 100644
--- a/test/CodeGen/debug-info-scope.c
+++ b/test/CodeGen/debug-info-scope.c
@@ -4,10 +4,12 @@
int main() {
int j = 0;
int k = 0;
-// CHECK: DW_TAG_auto_variable
+// CHECK: DW_TAG_auto_variable ] [i]
// CHECK-NEXT: DW_TAG_lexical_block
for (int i = 0; i < 10; i++)
j++;
+// CHECK: DW_TAG_auto_variable ] [i]
+// CHECK-NEXT: DW_TAG_lexical_block
for (int i = 0; i < 10; i++)
k++;
return 0;
diff --git a/test/CodeGen/debug-info-static.c b/test/CodeGen/debug-info-static.c
index e75d20f..931c9e2 100644
--- a/test/CodeGen/debug-info-static.c
+++ b/test/CodeGen/debug-info-static.c
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s
-// CHECK: xyzzy} ; [ DW_TAG_variable ]
+// CHECK: xyzzy, null} ; [ DW_TAG_variable ]
void f(void)
{
static int xyzzy;
diff --git a/test/CodeGen/debug-info-vector.c b/test/CodeGen/debug-info-vector.c
new file mode 100644
index 0000000..b7135af
--- /dev/null
+++ b/test/CodeGen/debug-info-vector.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
+typedef int v4si __attribute__((__vector_size__(16)));
+
+v4si a;
+
+// Test that we get an array type that's also a vector out of debug.
+// CHECK: [ DW_TAG_array_type ] [line 0, size 128, align 128, offset 0] [vector] [from int]
diff --git a/test/CodeGen/exceptions.c b/test/CodeGen/exceptions.c
index 20eb706..311bc84 100644
--- a/test/CodeGen/exceptions.c
+++ b/test/CodeGen/exceptions.c
@@ -19,3 +19,12 @@ void test1() {
// CHECK-ARM: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_sj0 to i8*)
// CHECK-ARM-NEXT: cleanup
}
+
+void test2_helper();
+void test2() {
+ __block int x = 10;
+ test2_helper(5, 6, 7);
+}
+void test2_helper(int x, int y) {
+}
+// CHECK: invoke void @test2_helper(i32 5, i32 6)
diff --git a/test/CodeGen/fast-math.c b/test/CodeGen/fast-math.c
new file mode 100644
index 0000000..76cfbbd
--- /dev/null
+++ b/test/CodeGen/fast-math.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s
+float f0, f1, f2;
+
+void foo(void) {
+ // CHECK: define void @foo()
+
+ // CHECK: fadd fast
+ f0 = f1 + f2;
+
+ // CHECK: ret
+}
diff --git a/test/CodeGen/finite-math.c b/test/CodeGen/finite-math.c
new file mode 100644
index 0000000..bf39cea
--- /dev/null
+++ b/test/CodeGen/finite-math.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -ffinite-math-only -emit-llvm -o - %s | FileCheck %s
+float f0, f1, f2;
+
+void foo(void) {
+ // CHECK: define void @foo()
+
+ // CHECK: fadd nnan ninf
+ f0 = f1 + f2;
+
+ // CHECK: ret
+}
diff --git a/test/CodeGen/frame-pointer-elim.c b/test/CodeGen/frame-pointer-elim.c
deleted file mode 100644
index b105a19..0000000
--- a/test/CodeGen/frame-pointer-elim.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// RUN: %clang -target 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 -target 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 -target i386-darwin -S -o - -fomit-frame-pointer %s | \
-// RUN: FileCheck --check-prefix=OMIT_ALL %s
-// OMIT_ALL: f0:
-// OMIT_ALL-NOT: pushl %ebp
-// OMIT_ALL: ret
-// OMIT_ALL: f1:
-// OMIT_ALL-NOT: pushl %ebp
-// OMIT_ALL: ret
-
-// RUN: %clang -target i386-darwin -S -o - -momit-leaf-frame-pointer %s | \
-// RUN: FileCheck --check-prefix=OMIT_LEAF %s
-// OMIT_LEAF: f0:
-// OMIT_LEAF-NOT: pushl %ebp
-// OMIT_LEAF: ret
-// OMIT_LEAF: f1:
-// OMIT_LEAF: pushl %ebp
-// OMIT_LEAF: ret
-
-void f0() {}
-void f1() { f0(); }
diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c
index 6cbf40b..25ca916 100644
--- a/test/CodeGen/function-attributes.c
+++ b/test/CodeGen/function-attributes.c
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -Os -o - %s | FileCheck %s
-// CHECK: define signext i8 @f0(i32 %x) nounwind
-// CHECK: define zeroext i8 @f1(i32 %x) nounwind
-// CHECK: define void @f2(i8 signext %x) nounwind
-// CHECK: define void @f3(i8 zeroext %x) nounwind
-// CHECK: define signext i16 @f4(i32 %x) nounwind
-// CHECK: define zeroext i16 @f5(i32 %x) nounwind
-// CHECK: define void @f6(i16 signext %x) nounwind
-// CHECK: define void @f7(i16 zeroext %x) nounwind
+// CHECK: define signext i8 @f0(i32 %x) [[NUW:#[0-9]+]]
+// CHECK: define zeroext i8 @f1(i32 %x) [[NUW]]
+// CHECK: define void @f2(i8 signext %x) [[NUW]]
+// CHECK: define void @f3(i8 zeroext %x) [[NUW]]
+// CHECK: define signext i16 @f4(i32 %x) [[NUW]]
+// CHECK: define zeroext i16 @f5(i32 %x) [[NUW]]
+// CHECK: define void @f6(i16 signext %x) [[NUW]]
+// CHECK: define void @f7(i16 zeroext %x) [[NUW]]
signed char f0(int x) { return x; }
@@ -25,20 +25,25 @@ void f6(signed short x) { }
void f7(unsigned short x) { }
// CHECK: define void @f8()
-// CHECK: nounwind
-// CHECK: alwaysinline
+// CHECK: [[AI:#[0-9]+]]
// CHECK: {
void __attribute__((always_inline)) f8(void) { }
// CHECK: call void @f9_t()
-// CHECK: noreturn
-// CHECK: {
+// CHECK: [[NR:#[0-9]+]]
+// CHECK: }
void __attribute__((noreturn)) f9_t(void);
void f9(void) { f9_t(); }
+// CHECK: call void @f9a()
+// CHECK: [[NR]]
+// CHECK: }
+_Noreturn void f9a(void);
+void f9b(void) { f9a(); }
+
// FIXME: We should be setting nounwind on calls.
// CHECK: call i32 @f10_t()
-// CHECK: readnone
+// CHECK: [[NUW_RN:#[0-9]+]]
// CHECK: {
int __attribute__((const)) f10_t(void);
int f10(void) { return f10_t(); }
@@ -50,7 +55,7 @@ int f12(int arg) {
return arg ? 0 : f10_t();
}
-// CHECK: define void @f13() nounwind readnone
+// CHECK: define void @f13() [[NUW]]
void f13(void) __attribute__((pure)) __attribute__((const));
void f13(void){}
@@ -77,24 +82,24 @@ void f14(int a) {
// <rdar://problem/7102668> [irgen] clang isn't setting the optsize bit on functions
// CHECK: define void @f15
-// CHECK: optsize
+// CHECK: [[NUW]]
// CHECK: {
void f15(void) {
}
// PR5254
// CHECK: define void @f16
-// CHECK: alignstack(16)
+// CHECK: [[ALIGN:#[0-9]+]]
// CHECK: {
void __attribute__((force_align_arg_pointer)) f16(void) {
}
// PR11038
// CHECK: define void @f18()
-// CHECK: returns_twice
+// CHECK: [[RT:#[0-9]+]]
// CHECK: {
// CHECK: call void @f17()
-// CHECK: returns_twice
+// CHECK: [[RT_CALL:#[0-9]+]]
// CHECK: ret void
__attribute__ ((returns_twice)) void f17(void);
__attribute__ ((returns_twice)) void f18(void) {
@@ -104,10 +109,18 @@ __attribute__ ((returns_twice)) void f18(void) {
// CHECK: define void @f19()
// CHECK: {
// CHECK: call i32 @setjmp(i32* null)
-// CHECK: returns_twice
+// CHECK: [[RT_CALL]]
// CHECK: ret void
typedef int jmp_buf[((9 * 2) + 3 + 16)];
int setjmp(jmp_buf);
void f19(void) {
setjmp(0);
}
+
+// CHECK: attributes [[NUW]] = { nounwind optsize readnone{{.*}} }
+// CHECK: attributes [[AI]] = { alwaysinline nounwind optsize readnone{{.*}} }
+// CHECK: attributes [[ALIGN]] = { nounwind optsize readnone alignstack=16{{.*}} }
+// CHECK: attributes [[RT]] = { nounwind optsize returns_twice{{.*}} }
+// CHECK: attributes [[NR]] = { noreturn nounwind optsize }
+// CHECK: attributes [[NUW_RN]] = { nounwind optsize readnone }
+// CHECK: attributes [[RT_CALL]] = { nounwind optsize returns_twice }
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
index 28e4bd0..8241a3d 100644
--- a/test/CodeGen/functions.c
+++ b/test/CodeGen/functions.c
@@ -24,7 +24,7 @@ void f0() {}
void f1();
void f2(void) {
-// CHECK: call void bitcast (void ()* @f1 to void (i32, i32, i32)*)(i32 1, i32 2, i32 3)
+// CHECK: call void @f1()
f1(1, 2, 3);
}
// CHECK: define void @f1()
diff --git a/test/CodeGen/global-blocks-lines.c b/test/CodeGen/global-blocks-lines.c
new file mode 100644
index 0000000..36e4618
--- /dev/null
+++ b/test/CodeGen/global-blocks-lines.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fblocks -g -emit-llvm %s -o - | FileCheck %s
+// Make sure we do not generate line info for debugging-related frame setup.
+// CHECK: define {{.*}}block_invoke
+// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg
+// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align
+// CHECK: ret
+// CHECK: define {{.*}}block_invoke
+// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg
+// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align
+// CHECK: ret
+// CHECK: define {{.*}}block_invoke
+// CHECK-NOT: store {{.*}}%struct.__block_descriptor*{{.*}}dbg
+// CHECK: store {{.*}}%struct.__block_descriptor*{{.*}}, align
+// CHECK: ret
+int printf(const char*, ...);
+
+static void* _NSConcreteGlobalBlock;
+
+
+typedef void (^ HelloBlock_t)(const char * name);
+
+ /* Breakpoint for first Block function. */
+HelloBlock_t helloBlock = ^(const char * name) {
+ printf("Hello there, %s!\n", name);
+};
+
+ /* Breakpoint for second Block function. */
+static HelloBlock_t s_helloBlock = ^(const char * name) {
+ printf("Hello there, %s!\n", name);
+};
+
+/* Breakpoint for third Block function. */
+int X = 1234;
+int (^CP)(void) = ^{ X = X+1; return X; };
+
+int
+main(int argc, char * argv[])
+{
+ helloBlock("world");
+ s_helloBlock("world");
+
+ CP();
+ printf ("X = %d\n", X);
+ return X - 1235;
+}
diff --git a/test/CodeGen/incomplete-function-type-2.c b/test/CodeGen/incomplete-function-type-2.c
new file mode 100644
index 0000000..41dd5fe
--- /dev/null
+++ b/test/CodeGen/incomplete-function-type-2.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+// PR14355: don't crash
+// Keep this test in its own file because CodeGenTypes has global state.
+// CHECK: define void @test10_foo({}* %p1.coerce) [[NUW:#[0-9]+]] {
+struct test10_B;
+typedef struct test10_B test10_F3(double);
+void test10_foo(test10_F3 p1);
+struct test10_B test10_b(double);
+void test10_bar() {
+ test10_foo(test10_b);
+}
+struct test10_B {};
+void test10_foo(test10_F3 p1)
+{
+ p1(0.0);
+}
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
index 259d34d..1b0beae 100644
--- a/test/CodeGen/init.c
+++ b/test/CodeGen/init.c
@@ -130,5 +130,5 @@ void test13(int x) {
struct X { int a; int b : 10; int c; };
struct X y = {.c = x};
// CHECK: @test13
- // CHECK: and i32 {{.*}}, -1024
+ // CHECK: and i16 {{.*}}, -1024
}
diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c
index addb30b..442b380 100644
--- a/test/CodeGen/inline.c
+++ b/test/CodeGen/inline.c
@@ -1,55 +1,55 @@
// RUN: echo "GNU89 tests:"
-// RUN: %clang %s -target i386-unknown-unknown -O1 -emit-llvm -S -o %t -std=gnu89
-// RUN: grep "define available_externally i32 @ei()" %t
-// RUN: grep "define i32 @foo()" %t
-// RUN: grep "define i32 @bar()" %t
-// RUN: grep "define void @unreferenced1()" %t
-// RUN: not grep unreferenced2 %t
-// RUN: grep "define void @gnu_inline()" %t
-// RUN: grep "define available_externally void @gnu_ei_inline()" %t
-// RUN: grep "define i32 @test1" %t
-// RUN: grep "define i32 @test2" %t
-// RUN: grep "define void @test3()" %t
-// RUN: grep "define available_externally i32 @test4" %t
-// RUN: grep "define available_externally i32 @test5" %t
-// RUN: grep "define i32 @test6" %t
-// RUN: grep "define void @test7" %t
-// RUN: grep "define i.. @strlcpy" %t
-// RUN: not grep test9 %t
-// RUN: grep "define void @testA" %t
-// RUN: grep "define void @testB" %t
-// RUN: grep "define void @testC" %t
+// RUN: %clang %s -target i386-unknown-unknown -O1 -emit-llvm -S -o - -std=gnu89 | FileCheck %s --check-prefix=CHECK1
+// CHECK1: define i32 @foo()
+// CHECK1: define i32 @bar()
+// CHECK1: define void @unreferenced1()
+// CHECK1-NOT: unreferenced2
+// CHECK1: define void @gnu_inline()
+// CHECK1: define i32 @test1
+// CHECK1: define i32 @test2
+// CHECK1: define void @test3()
+// CHECK1: define available_externally i32 @test4
+// CHECK1: define available_externally i32 @test5
+// CHECK1: define i32 @test6
+// CHECK1: define void @test7
+// CHECK1: define i{{..}} @strlcpy
+// CHECK1-NOT: test9
+// CHECK1: define void @testA
+// CHECK1: define void @testB
+// CHECK1: define void @testC
+// CHECK1: define available_externally void @gnu_ei_inline()
+// CHECK1: define available_externally i32 @ei()
// RUN: echo "C99 tests:"
-// RUN: %clang %s -target i386-unknown-unknown -O1 -emit-llvm -S -o %t -std=gnu99
-// RUN: grep "define i32 @ei()" %t
-// RUN: grep "define available_externally i32 @foo()" %t
-// RUN: grep "define i32 @bar()" %t
-// RUN: not grep unreferenced1 %t
-// RUN: grep "define void @unreferenced2()" %t
-// RUN: grep "define void @gnu_inline()" %t
-// RUN: grep "define available_externally void @gnu_ei_inline()" %t
-// RUN: grep "define i32 @test1" %t
-// RUN: grep "define i32 @test2" %t
-// RUN: grep "define void @test3" %t
-// RUN: grep "define available_externally i32 @test4" %t
-// RUN: grep "define available_externally i32 @test5" %t
-// RUN: grep "define i32 @test6" %t
-// RUN: grep "define void @test7" %t
-// RUN: grep "define available_externally i.. @strlcpy" %t
-// RUN: grep "define void @test9" %t
-// RUN: grep "define void @testA" %t
-// RUN: grep "define void @testB" %t
-// RUN: grep "define void @testC" %t
+// RUN: %clang %s -target i386-unknown-unknown -O1 -emit-llvm -S -o - -std=gnu99 | FileCheck %s --check-prefix=CHECK2
+// CHECK2: define i32 @ei()
+// CHECK2: define i32 @bar()
+// CHECK2-NOT: unreferenced1
+// CHECK2: define void @unreferenced2()
+// CHECK2: define void @gnu_inline()
+// CHECK2: define i32 @test1
+// CHECK2: define i32 @test2
+// CHECK2: define void @test3
+// CHECK2: define available_externally i32 @test4
+// CHECK2: define available_externally i32 @test5
+// CHECK2: define i32 @test6
+// CHECK2: define void @test7
+// CHECK2: define available_externally i{{..}} @strlcpy
+// CHECK2: define void @test9
+// CHECK2: define void @testA
+// CHECK2: define void @testB
+// CHECK2: define void @testC
+// CHECK2: define available_externally void @gnu_ei_inline()
+// CHECK2: define available_externally i32 @foo()
// RUN: echo "C++ tests:"
-// RUN: %clang -x c++ %s -target i386-unknown-unknown -O1 -emit-llvm -S -o %t -std=c++98
-// RUN: grep "define linkonce_odr i32 @_Z2eiv()" %t
-// RUN: grep "define linkonce_odr i32 @_Z3foov()" %t
-// RUN: grep "define i32 @_Z3barv()" %t
-// RUN: not grep unreferenced %t
-// RUN: grep "define void @_Z10gnu_inlinev()" %t
-// RUN: grep "define available_externally void @_Z13gnu_ei_inlinev()" %t
+// RUN: %clang -x c++ %s -target i386-unknown-unknown -O1 -emit-llvm -S -o - -std=c++98 | FileCheck %s --check-prefix=CHECK3
+// CHECK3: define i32 @_Z3barv()
+// CHECK3: define linkonce_odr i32 @_Z3foov()
+// CHECK3-NOT: unreferenced
+// CHECK3: define void @_Z10gnu_inlinev()
+// CHECK3: define available_externally void @_Z13gnu_ei_inlinev()
+// CHECK3: define linkonce_odr i32 @_Z2eiv()
extern __inline int ei() { return 123; }
diff --git a/test/CodeGen/intel_ocl_bicc.c b/test/CodeGen/intel_ocl_bicc.c
new file mode 100644
index 0000000..c5c5229
--- /dev/null
+++ b/test/CodeGen/intel_ocl_bicc.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((intel_ocl_bicc)) f1(void);
+
+void f2(void) {
+ f1();
+// CHECK: call intel_ocl_bicc void @f1()
+}
+
+// CHECK: declare intel_ocl_bicc void @f1()
diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c
index 6ab5a11..8c1ae5e 100644
--- a/test/CodeGen/le32-regparm.c
+++ b/test/CodeGen/le32-regparm.c
@@ -34,7 +34,7 @@ int
main(void) {
// The presence of double c means that foo* d is not passed inreg. This
// behavior is different from current x86-32 behavior
- // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.foo* null
+ // CHECK: call void @reduced(i8 inreg signext 0, {{.*}} %struct.foo* null
reduced(0, 0.0, 0, 0.0, 0);
// CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2)
bar(1,2);
diff --git a/test/CodeGen/libcall-declarations.c b/test/CodeGen/libcall-declarations.c
index 4517643..d07590f 100644
--- a/test/CodeGen/libcall-declarations.c
+++ b/test/CodeGen/libcall-declarations.c
@@ -86,106 +86,110 @@ void *use[] = {
sqrtf, tan, tanl, tanf, trunc, truncl, truncf
};
-// CHECK-NOERRNO: declare double @acos(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @acosl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @acosf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @asin(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @asinl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @asinf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @atan(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @atanl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @atanf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @atan2(double, double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @atan2f(float, float) nounwind readnone
-// CHECK-NOERRNO: declare double @ceil(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @ceill(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @ceilf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @copysign(double, double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @copysignf(float, float) nounwind readnone
-// CHECK-NOERRNO: declare double @cos(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @cosl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @cosf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @exp(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @expl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @expf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @exp2(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @exp2l(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @exp2f(float) nounwind readnone
-// CHECK-NOERRNO: declare double @fabs(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @fabsl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @fabsf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @floor(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @floorl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @floorf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @fma(double, double, double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @fmaf(float, float, float) nounwind readnone
-// CHECK-NOERRNO: declare double @fmax(double, double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @fmaxf(float, float) nounwind readnone
-// CHECK-NOERRNO: declare double @fmin(double, double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @fminf(float, float) nounwind readnone
-// CHECK-NOERRNO: declare double @log(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @logl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @logf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @log2(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @log2l(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @log2f(float) nounwind readnone
-// CHECK-NOERRNO: declare double @nearbyint(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @nearbyintl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @nearbyintf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @pow(double, double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @powf(float, float) nounwind readnone
-// CHECK-NOERRNO: declare double @rint(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @rintl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @rintf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @round(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @roundl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @roundf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @sin(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @sinl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @sinf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @sqrt(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @sqrtl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @sqrtf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @tan(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @tanl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @tanf(float) nounwind readnone
-// CHECK-NOERRNO: declare double @trunc(double) nounwind readnone
-// CHECK-NOERRNO: declare x86_fp80 @truncl(x86_fp80) nounwind readnone
-// CHECK-NOERRNO: declare float @truncf(float) nounwind readnone
+// CHECK-NOERRNO: declare double @acos(double) [[NUW:#[0-9]+]]
+// CHECK-NOERRNO: declare x86_fp80 @acosl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @acosf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @asin(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @asinl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @asinf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @atan(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @atanl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @atanf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @atan2(double, double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @atan2f(float, float) [[NUW]]
+// CHECK-NOERRNO: declare double @ceil(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @ceill(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @ceilf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @copysign(double, double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @copysignf(float, float) [[NUW]]
+// CHECK-NOERRNO: declare double @cos(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @cosl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @cosf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @exp(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @expl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @expf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @exp2(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @exp2f(float) [[NUW]]
+// CHECK-NOERRNO: declare double @fabs(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @fabsl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @fabsf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @floor(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @floorl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @floorf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @fma(double, double, double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @fmal(x86_fp80, x86_fp80, x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @fmaf(float, float, float) [[NUW]]
+// CHECK-NOERRNO: declare double @fmax(double, double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @fmaxf(float, float) [[NUW]]
+// CHECK-NOERRNO: declare double @fmin(double, double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @fminf(float, float) [[NUW]]
+// CHECK-NOERRNO: declare double @log(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @logl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @logf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @log2(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @log2l(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @log2f(float) [[NUW]]
+// CHECK-NOERRNO: declare double @nearbyint(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @nearbyintf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @pow(double, double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @powf(float, float) [[NUW]]
+// CHECK-NOERRNO: declare double @rint(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @rintl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @rintf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @round(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @roundl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @roundf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @sin(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @sinl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @sinf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @sqrt(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @sqrtf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @tan(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @tanl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @tanf(float) [[NUW]]
+// CHECK-NOERRNO: declare double @trunc(double) [[NUW]]
+// CHECK-NOERRNO: declare x86_fp80 @truncl(x86_fp80) [[NUW]]
+// CHECK-NOERRNO: declare float @truncf(float) [[NUW]]
-// CHECK-ERRNO: declare double @ceil(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @ceill(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @ceilf(float) nounwind readnone
-// CHECK-ERRNO: declare double @copysign(double, double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @copysignf(float, float) nounwind readnone
-// CHECK-ERRNO: declare double @fabs(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @fabsl(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @fabsf(float) nounwind readnone
-// CHECK-ERRNO: declare double @floor(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @floorl(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @floorf(float) nounwind readnone
-// CHECK-ERRNO: declare double @fmax(double, double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @fmaxf(float, float) nounwind readnone
-// CHECK-ERRNO: declare double @fmin(double, double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @fminf(float, float) nounwind readnone
-// CHECK-ERRNO: declare double @nearbyint(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @nearbyintf(float) nounwind readnone
-// CHECK-ERRNO: declare double @rint(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @rintl(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @rintf(float) nounwind readnone
-// CHECK-ERRNO: declare double @round(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @roundl(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @roundf(float) nounwind readnone
-// CHECK-ERRNO: declare double @trunc(double) nounwind readnone
-// CHECK-ERRNO: declare x86_fp80 @truncl(x86_fp80) nounwind readnone
-// CHECK-ERRNO: declare float @truncf(float) nounwind readnone
+// CHECK-ERRNO: declare double @ceil(double) [[NUW:#[0-9]+]]
+// CHECK-ERRNO: declare x86_fp80 @ceill(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @ceilf(float) [[NUW]]
+// CHECK-ERRNO: declare double @copysign(double, double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @copysignf(float, float) [[NUW]]
+// CHECK-ERRNO: declare double @fabs(double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @fabsl(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @fabsf(float) [[NUW]]
+// CHECK-ERRNO: declare double @floor(double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @floorl(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @floorf(float) [[NUW]]
+// CHECK-ERRNO: declare double @fmax(double, double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @fmaxf(float, float) [[NUW]]
+// CHECK-ERRNO: declare double @fmin(double, double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @fminf(float, float) [[NUW]]
+// CHECK-ERRNO: declare double @nearbyint(double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @nearbyintf(float) [[NUW]]
+// CHECK-ERRNO: declare double @rint(double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @rintl(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @rintf(float) [[NUW]]
+// CHECK-ERRNO: declare double @round(double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @roundl(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @roundf(float) [[NUW]]
+// CHECK-ERRNO: declare double @trunc(double) [[NUW]]
+// CHECK-ERRNO: declare x86_fp80 @truncl(x86_fp80) [[NUW]]
+// CHECK-ERRNO: declare float @truncf(float) [[NUW]]
+
+// CHECK-NOERRNO: attributes [[NUW]] = { nounwind readnone{{.*}} }
+
+// CHECK-ERRNO: attributes [[NUW]] = { nounwind readnone{{.*}} }
diff --git a/test/CodeGen/libcalls-complex.c b/test/CodeGen/libcalls-complex.c
new file mode 100644
index 0000000..7bcfa60
--- /dev/null
+++ b/test/CodeGen/libcalls-complex.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fno-builtin -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix YES %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix NO %s
+
+extern float crealf(float _Complex);
+extern double creal(double _Complex);
+extern long double creall(long double _Complex);
+
+extern float cimagf(float _Complex);
+extern double cimag(double _Complex);
+extern long double cimagl(long double _Complex);
+
+double test_creal(double _Complex z) {
+ return creal(z);
+ // CHECK-NO-NOT: call double @creal
+ // CHECK-YES: call double @creal
+}
+
+long double test_creall(double _Complex z) {
+ return creall(z);
+ // CHECK-NO-NOT: call x86_fp80 @creall
+ // CHECK-YES: call x86_fp80 @creall
+}
+
+float test_crealf(double _Complex z) {
+ return crealf(z);
+ // CHECK-NO-NOT: call float @crealf
+ // CHECK-YES: call float @crealf
+}
+
+double test_cimag(double _Complex z) {
+ return cimag(z);
+ // CHECK-NO-NOT: call double @cimag
+ // CHECK-YES: call double @cimag
+}
+
+long double test_cimagl(double _Complex z) {
+ return cimagl(z);
+ // CHECK-NO-NOT: call x86_fp80 @cimagl
+ // CHECK-YES: call x86_fp80 @cimagl
+}
+
+float test_cimagf(double _Complex z) {
+ return cimagf(z);
+ // CHECK-NO-NOT: call float @cimagf
+ // CHECK-YES: call float @cimagf
+}
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index ec895ac..8f8e182 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -24,9 +24,9 @@ void test_sqrt(float a0, double a1, long double a2) {
// CHECK-YES: declare float @sqrtf(float)
// CHECK-YES: declare double @sqrt(double)
// CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80)
-// CHECK-NO: declare float @sqrtf(float) nounwind readnone
-// CHECK-NO: declare double @sqrt(double) nounwind readnone
-// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) nounwind readnone
+// CHECK-NO: declare float @sqrtf(float) [[NUW_RN:#[0-9]+]]
+// CHECK-NO: declare double @sqrt(double) [[NUW_RN]]
+// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) [[NUW_RN]]
// CHECK-YES: define void @test_pow
// CHECK-NO: define void @test_pow
@@ -47,9 +47,9 @@ void test_pow(float a0, double a1, long double a2) {
// CHECK-YES: declare float @powf(float, float)
// CHECK-YES: declare double @pow(double, double)
// CHECK-YES: declare x86_fp80 @powl(x86_fp80, x86_fp80)
-// CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly
-// CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly
-// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly
+// CHECK-NO: declare float @llvm.pow.f32(float, float) [[NUW_RO:#[0-9]+]]
+// CHECK-NO: declare double @llvm.pow.f64(double, double) [[NUW_RO]]
+// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[NUW_RO]]
// CHECK-YES: define void @test_fma
// CHECK-NO: define void @test_fma
@@ -67,12 +67,12 @@ void test_fma(float a0, double a1, long double a2) {
long double l2 = fmal(a2, a2, a2);
}
-// CHECK-YES: declare float @llvm.fma.f32(float, float, float) nounwind readnone
-// CHECK-YES: declare double @llvm.fma.f64(double, double, double) nounwind readnone
-// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NO: declare float @llvm.fma.f32(float, float, float) nounwind readnone
-// CHECK-NO: declare double @llvm.fma.f64(double, double, double) nounwind readnone
-// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone
+// CHECK-YES: declare float @llvm.fma.f32(float, float, float) [[NUW_RN:#[0-9]+]]
+// CHECK-YES: declare double @llvm.fma.f64(double, double, double) [[NUW_RN]]
+// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[NUW_RN]]
+// CHECK-NO: declare float @llvm.fma.f32(float, float, float) [[NUW_RN2:#[0-9]+]]
+// CHECK-NO: declare double @llvm.fma.f64(double, double, double) [[NUW_RN2]]
+// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[NUW_RN2]]
// Just checking to make sure these library functions are marked readnone
void test_builtins(double d, float f, long double ld) {
@@ -81,40 +81,45 @@ void test_builtins(double d, float f, long double ld) {
double atan_ = atan(d);
long double atanl_ = atanl(ld);
float atanf_ = atanf(f);
-// CHECK-NO: declare double @atan(double) nounwind readnone
-// CHECK-NO: declare x86_fp80 @atanl(x86_fp80) nounwind readnone
-// CHECK-NO: declare float @atanf(float) nounwind readnone
-// CHECK-YES-NOT: declare double @atan(double) nounwind readnone
-// CHECK-YES-NOT: declare x86_fp80 @atanl(x86_fp80) nounwind readnone
-// CHECK-YES-NOT: declare float @atanf(float) nounwind readnone
+// CHECK-NO: declare double @atan(double) [[NUW_RN]]
+// CHECK-NO: declare x86_fp80 @atanl(x86_fp80) [[NUW_RN]]
+// CHECK-NO: declare float @atanf(float) [[NUW_RN]]
+// CHECK-YES-NOT: declare double @atan(double) [[NUW_RN]]
+// CHECK-YES-NOT: declare x86_fp80 @atanl(x86_fp80) [[NUW_RN]]
+// CHECK-YES-NOT: declare float @atanf(float) [[NUW_RN]]
double atan2_ = atan2(d, 2);
long double atan2l_ = atan2l(ld, ld);
float atan2f_ = atan2f(f, f);
-// CHECK-NO: declare double @atan2(double, double) nounwind readnone
-// CHECK-NO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-NO: declare float @atan2f(float, float) nounwind readnone
-// CHECK-YES-NOT: declare double @atan2(double, double) nounwind readnone
-// CHECK-YES-NOT: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) nounwind readnone
-// CHECK-YES-NOT: declare float @atan2f(float, float) nounwind readnone
+// CHECK-NO: declare double @atan2(double, double) [[NUW_RN]]
+// CHECK-NO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NUW_RN]]
+// CHECK-NO: declare float @atan2f(float, float) [[NUW_RN]]
+// CHECK-YES-NOT: declare double @atan2(double, double) [[NUW_RN]]
+// CHECK-YES-NOT: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NUW_RN]]
+// CHECK-YES-NOT: declare float @atan2f(float, float) [[NUW_RN]]
double exp_ = exp(d);
long double expl_ = expl(ld);
float expf_ = expf(f);
-// CHECK-NO: declare double @exp(double) nounwind readnone
-// CHECK-NO: declare x86_fp80 @expl(x86_fp80) nounwind readnone
-// CHECK-NO: declare float @expf(float) nounwind readnone
-// CHECK-YES-NOT: declare double @exp(double) nounwind readnone
-// CHECK-YES-NOT: declare x86_fp80 @expl(x86_fp80) nounwind readnone
-// CHECK-YES-NOT: declare float @expf(float) nounwind readnone
+// CHECK-NO: declare double @exp(double) [[NUW_RN]]
+// CHECK-NO: declare x86_fp80 @expl(x86_fp80) [[NUW_RN]]
+// CHECK-NO: declare float @expf(float) [[NUW_RN]]
+// CHECK-YES-NOT: declare double @exp(double) [[NUW_RN]]
+// CHECK-YES-NOT: declare x86_fp80 @expl(x86_fp80) [[NUW_RN]]
+// CHECK-YES-NOT: declare float @expf(float) [[NUW_RN]]
double log_ = log(d);
long double logl_ = logl(ld);
float logf_ = logf(f);
-// CHECK-NO: declare double @log(double) nounwind readnone
-// CHECK-NO: declare x86_fp80 @logl(x86_fp80) nounwind readnone
-// CHECK-NO: declare float @logf(float) nounwind readnone
-// CHECK-YES-NOT: declare double @log(double) nounwind readnone
-// CHECK-YES-NOT: declare x86_fp80 @logl(x86_fp80) nounwind readnone
-// CHECK-YES-NOT: declare float @logf(float) nounwind readnone
+// CHECK-NO: declare double @log(double) [[NUW_RN]]
+// CHECK-NO: declare x86_fp80 @logl(x86_fp80) [[NUW_RN]]
+// CHECK-NO: declare float @logf(float) [[NUW_RN]]
+// CHECK-YES-NOT: declare double @log(double) [[NUW_RN]]
+// CHECK-YES-NOT: declare x86_fp80 @logl(x86_fp80) [[NUW_RN]]
+// CHECK-YES-NOT: declare float @logf(float) [[NUW_RN]]
}
+
+// CHECK-YES: attributes [[NUW_RN]] = { nounwind readnone }
+
+// CHECK-NO: attributes [[NUW_RN]] = { nounwind readnone{{.*}} }
+// CHECK-NO: attributes [[NUW_RO]] = { nounwind readonly }
diff --git a/test/CodeGen/lifetime2.c b/test/CodeGen/lifetime2.c
new file mode 100644
index 0000000..ffff5cc
--- /dev/null
+++ b/test/CodeGen/lifetime2.c
@@ -0,0 +1,17 @@
+// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2
+// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0
+
+extern int bar(char *A, int n);
+
+// O0-NOT: @llvm.lifetime.start
+int foo (int n) {
+ if (n) {
+// O2: @llvm.lifetime.start
+ char A[100];
+ return bar(A, 1);
+ } else {
+// O2: @llvm.lifetime.start
+ char A[100];
+ return bar(A, 2);
+ }
+}
diff --git a/test/CodeGen/linkage-redecl.c b/test/CodeGen/linkage-redecl.c
index 09b51f0..14112fe 100644
--- a/test/CodeGen/linkage-redecl.c
+++ b/test/CodeGen/linkage-redecl.c
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - |grep internal
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @test2_i = internal global i32 99
+static int test2_i = 99;
+int test2_f() {
+ extern int test2_i;
+ return test2_i;
+}
// C99 6.2.2p3
// PR3425
@@ -9,3 +16,4 @@ void g0() {
}
extern void f(int x) { } // still has internal linkage
+// CHECK: define internal void @f
diff --git a/test/CodeGen/mips-constraint-regs.c b/test/CodeGen/mips-constraint-regs.c
index ea063b5..0d533f5 100644
--- a/test/CodeGen/mips-constraint-regs.c
+++ b/test/CodeGen/mips-constraint-regs.c
@@ -2,16 +2,14 @@
// RUN: | FileCheck %s
// This checks that the frontend will accept inline asm constraints
-// c', 'l' and 'x'. Semantic checking will happen in the
-// llvm backend. Any bad constraint letters will cause the frontend to
-// error out.
+// c', 'l' and 'x'.
int main()
{
// 'c': 16 bit address register for Mips16, GPR for all others
// I am using 'c' to constrain both the target and one of the source
// registers. We are looking for syntactical correctness.
- // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "addi $0,$1,$2 \0A\09\09", "=c,c,I"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}}
+ // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "addi $0,$1,$2 \0A\09\09", "=c,c,I"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) [[NUW:#[0-9]+]], !srcloc !{{[0-9]+}}
int __s, __v = 17;
int __t;
__asm__ __volatile__(
@@ -22,7 +20,7 @@ int main()
// 'l': lo register
// We are making it clear that destination register is lo with the
// use of the 'l' constraint ("=l").
- // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "mtlo $1 \0A\09\09", "=l,r,~{lo}"(i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}}
+ // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "mtlo $1 \0A\09\09", "=l,r,~{lo}"(i32 %{{[0-9]+}}) [[NUW]], !srcloc !{{[0-9]+}}
int i_temp = 44;
int i_result;
__asm__ __volatile__(
@@ -34,7 +32,7 @@ int main()
// 'x': Combined lo/hi registers
// We are specifying that destination registers are the hi/lo pair with the
// use of the 'x' constraint ("=x").
- // CHECK: %{{[0-9]+}} = call i64 asm sideeffect "mthi $1 \0A\09\09mtlo $2 \0A\09\09", "=x,r,r"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}}
+ // CHECK: %{{[0-9]+}} = call i64 asm sideeffect "mthi $1 \0A\09\09mtlo $2 \0A\09\09", "=x,r,r"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) [[NUW]], !srcloc !{{[0-9]+}}
int i_hi = 3;
int i_lo = 2;
long long ll_result = 0;
@@ -47,3 +45,5 @@ int main()
return 0;
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGen/mips-constraints-mem.c b/test/CodeGen/mips-constraints-mem.c
new file mode 100644
index 0000000..ea6bcaf
--- /dev/null
+++ b/test/CodeGen/mips-constraints-mem.c
@@ -0,0 +1,26 @@
+// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s \
+// RUN: | FileCheck %s
+
+// This checks that the frontend will accept inline asm memory constraints.
+
+int foo()
+{
+
+ // 'R': An address that can be used in a non-macro load or stor'
+ // This test will result in the higher and lower nibbles being
+ // switched due to the lwl/lwr instruction pairs.
+ // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "lwl $0, 1 + $1\0A\09lwr $0, 2 + $1\0A\09", "=r,*R"(i32* %{{[0-9,a-f]+}}) #1, !srcloc !0
+
+ int c = 0xffbbccdd;
+
+ int *p = &c;
+ int out = 0;
+
+ __asm volatile (
+ "lwl %0, 1 + %1\n\t"
+ "lwr %0, 2 + %1\n\t"
+ : "=r"(out)
+ : "R"(*p)
+ );
+ return 0;
+}
diff --git a/test/CodeGen/mips-target-data.c b/test/CodeGen/mips-target-data.c
new file mode 100644
index 0000000..88eadcb
--- /dev/null
+++ b/test/CodeGen/mips-target-data.c
@@ -0,0 +1,14 @@
+// RUN: %clang -target mipsel-linux-gnu -o - -emit-llvm -S %s |\
+// RUN: FileCheck %s -check-prefix=32EL
+// RUN: %clang -target mips-linux-gnu -o - -emit-llvm -S %s |\
+// RUN: FileCheck %s -check-prefix=32EB
+// RUN: %clang -target mips64el-linux-gnu -o - -emit-llvm -S %s |\
+// RUN: FileCheck %s -check-prefix=64EL
+// RUN: %clang -target mips64-linux-gnu -o - -emit-llvm -S %s |\
+// RUN: FileCheck %s -check-prefix=64EB
+
+// 32EL: e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
+// 32EB: E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
+// 64EL: e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32:64-S128
+// 64EB: E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32:64-S128
+
diff --git a/test/CodeGen/mips-vector-arg.c b/test/CodeGen/mips-vector-arg.c
index 584192f..6ffb043 100644
--- a/test/CodeGen/mips-vector-arg.c
+++ b/test/CodeGen/mips-vector-arg.c
@@ -8,21 +8,24 @@
typedef float v4sf __attribute__ ((__vector_size__ (16)));
typedef int v4i32 __attribute__ ((__vector_size__ (16)));
-// O32: define void @test_v4sf(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) nounwind
+// O32: define void @test_v4sf(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) [[NUW:#[0-9]+]]
// O32: declare i32 @test_v4sf_2(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)
-// N64: define void @test_v4sf(i64 %a1.coerce0, i64 %a1.coerce1, i32 %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) nounwind
+// N64: define void @test_v4sf(i64 %a1.coerce0, i64 %a1.coerce1, i32 %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) [[NUW:#[0-9]+]]
// N64: declare i32 @test_v4sf_2(i64, i64, i32, i64, i64, i64)
extern test_v4sf_2(v4sf, int, v4sf);
void test_v4sf(v4sf a1, int a2, v4sf a3) {
test_v4sf_2(a3, a2, a1);
}
-// O32: define void @test_v4i32(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) nounwind
+// O32: define void @test_v4i32(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) [[NUW]]
// O32: declare i32 @test_v4i32_2(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)
-// N64: define void @test_v4i32(i64 %a1.coerce0, i64 %a1.coerce1, i32 %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) nounwind
+// N64: define void @test_v4i32(i64 %a1.coerce0, i64 %a1.coerce1, i32 %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) [[NUW]]
// N64: declare i32 @test_v4i32_2(i64, i64, i32, i64, i64, i64)
extern test_v4i32_2(v4i32, int, v4i32);
void test_v4i32(v4i32 a1, int a2, v4i32 a3) {
test_v4i32_2(a3, a2, a1);
}
+// O32: attributes [[NUW]] = { nounwind{{.*}} }
+
+// N64: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/mips16-attr.c b/test/CodeGen/mips16-attr.c
new file mode 100644
index 0000000..18799be
--- /dev/null
+++ b/test/CodeGen/mips16-attr.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple mipsel-linux-gnu -emit-llvm -o - %s | FileCheck %s
+void __attribute__((mips16)) foo (void) {
+
+}
+
+// CHECK: define void @foo() [[MIPS16:#[0-9]+]]
+
+void __attribute__((nomips16)) nofoo (void) {
+
+}
+
+// CHECK: define void @nofoo() [[NOMIPS16:#[0-9]+]]
+
+// CHECK: attributes [[MIPS16]] = { nounwind {{.*}} "mips16" {{.*}} }
+
+// CHECK: attributes [[NOMIPS16]] = { nounwind {{.*}} "nomips16" {{.*}} }
+
diff --git a/test/CodeGen/mips64-padding-arg.c b/test/CodeGen/mips64-padding-arg.c
index 9d7f877..85dc00c 100644
--- a/test/CodeGen/mips64-padding-arg.c
+++ b/test/CodeGen/mips64-padding-arg.c
@@ -1,4 +1,5 @@
-// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang -target mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32
+// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64
typedef struct {
double d;
@@ -7,9 +8,9 @@ typedef struct {
// Insert padding to ensure arguments of type S0 are aligned to 16-byte boundaries.
-// CHECK: define void @foo1(i32 %a0, i64, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 %b, i64, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
-// CHECK: tail call void @foo2(i32 1, i32 2, i32 %a0, i64 undef, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 3, i64 undef, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
-// CHECK: declare void @foo2(i32, i32, i32, i64, double, i64, i64, i64, double, i64, i64, i64, i32, i64, double, i64, i64, i64)
+// N64: define void @foo1(i32 %a0, i64, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 %b, i64, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
+// N64: tail call void @foo2(i32 1, i32 2, i32 %a0, i64 undef, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 3, i64 undef, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
+// N64: declare void @foo2(i32, i32, i32, i64, double, i64, i64, i64, double, i64, i64, i64, i32, i64, double, i64, i64, i64)
extern void foo2(int, int, int, S0, S0, int, S0);
@@ -19,9 +20,9 @@ void foo1(int a0, S0 a1, S0 a2, int b, S0 a3) {
// Insert padding before long double argument.
//
-// CHECK: define void @foo3(i32 %a0, i64, fp128 %a1)
-// CHECK: tail call void @foo4(i32 1, i32 2, i32 %a0, i64 undef, fp128 %a1)
-// CHECK: declare void @foo4(i32, i32, i32, i64, fp128)
+// N64: define void @foo3(i32 %a0, i64, fp128 %a1)
+// N64: tail call void @foo4(i32 1, i32 2, i32 %a0, i64 undef, fp128 %a1)
+// N64: declare void @foo4(i32, i32, i32, i64, fp128)
extern void foo4(int, int, int, long double);
@@ -31,9 +32,9 @@ void foo3(int a0, long double a1) {
// Insert padding after hidden argument.
//
-// CHECK: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0)
-// CHECK: call void @foo6(%struct.S0* sret %agg.result, i32 1, i32 2, i64 undef, fp128 %a0)
-// CHECK: declare void @foo6(%struct.S0* sret, i32, i32, i64, fp128)
+// N64: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0)
+// N64: call void @foo6(%struct.S0* sret %agg.result, i32 1, i32 2, i64 undef, fp128 %a0)
+// N64: declare void @foo6(%struct.S0* sret, i32, i32, i64, fp128)
extern S0 foo6(int, int, long double);
@@ -41,3 +42,14 @@ S0 foo5(long double a0) {
return foo6(1, 2, a0);
}
+// Do not insert padding if ABI is O32.
+//
+// O32: define void @foo7(float %a0, double %a1)
+// O32: declare void @foo8(float, double)
+
+extern void foo8(float, double);
+
+void foo7(float a0, double a1) {
+ foo8(a0 + 1.0f, a1 + 2.0);
+}
+
diff --git a/test/CodeGen/mrtd.c b/test/CodeGen/mrtd.c
index d7729a5..a40a59a 100644
--- a/test/CodeGen/mrtd.c
+++ b/test/CodeGen/mrtd.c
@@ -2,7 +2,7 @@
void baz(int arg);
-// CHECK: define x86_stdcallcc void @foo(i32 %arg) nounwind
+// CHECK: define x86_stdcallcc void @foo(i32 %arg) [[NUW:#[0-9]+]]
void foo(int arg) {
// CHECK: call x86_stdcallcc i32 bitcast (i32 (...)* @bar to i32 (i32)*)(
bar(arg);
@@ -13,3 +13,5 @@ void foo(int arg) {
// CHECK: declare x86_stdcallcc i32 @bar(...)
// CHECK: declare x86_stdcallcc void @baz(i32)
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c
index 91862a7..26bdc58 100644
--- a/test/CodeGen/ms-declspecs.c
+++ b/test/CodeGen/ms-declspecs.c
@@ -8,17 +8,21 @@ union { struct S s; } u;
// CHECK: @u = {{.*}}zeroinitializer, align 16
-// CHECK: define void @t3() nounwind noinline naked {
+// CHECK: define void @t3() [[NAKED:#[0-9]+]] {
__declspec(naked) void t3() {}
-// CHECK: define void @t22() nounwind
+// CHECK: define void @t22() [[NUW:#[0-9]+]]
void __declspec(nothrow) t22();
void t22() {}
-// CHECK: define void @t2() nounwind noinline {
+// CHECK: define void @t2() [[NI:#[0-9]+]] {
__declspec(noinline) void t2() {}
-// CHECK: call void @f20_t()
-// CHECK: noreturn
+// CHECK: call void @f20_t() [[NR:#[0-9]+]]
__declspec(noreturn) void f20_t(void);
void f20(void) { f20_t(); }
+
+// CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c
index a74ede0..8d2940d 100644
--- a/test/CodeGen/ms-inline-asm-64.c
+++ b/test/CodeGen/ms-inline-asm-64.c
@@ -1,16 +1,18 @@
// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O0 -fms-extensions -fenable-experimental-ms-inline-asm -w -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s
void t1() {
int var = 10;
__asm mov rax, offset var ; rax = address of myvar
// CHECK: t1
-// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW:#[0-9]+]]
}
void t2() {
int var = 10;
__asm mov [eax], offset var
// CHECK: t2
-// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 7f43da8..d50ecfe 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -1,18 +1,18 @@
// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -O0 -fms-extensions -fenable-experimental-ms-inline-asm -w -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s
void t1() {
// CHECK: @t1
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm {}
}
void t2() {
// CHECK: @t2
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm nop
__asm nop
@@ -21,15 +21,15 @@ void t2() {
void t3() {
// CHECK: @t3
-// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm nop __asm nop __asm nop
}
void t4(void) {
// CHECK: @t4
-// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm mov ebx, eax
__asm mov ecx, ebx
@@ -37,7 +37,7 @@ void t4(void) {
void t5(void) {
// CHECK: @t5
-// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm mov ebx, eax __asm mov ecx, ebx
}
@@ -45,7 +45,7 @@ void t5(void) {
void t6(void) {
__asm int 0x2c
// CHECK: t6
-// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
}
void t7() {
@@ -54,8 +54,8 @@ void t7() {
}
__asm {}
// CHECK: t7
-// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
}
int t8() {
@@ -64,9 +64,9 @@ int t8() {
__asm int 4
return 10;
// CHECK: t8
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret i32 10
}
@@ -77,7 +77,7 @@ void t9() {
pop ebx
}
// CHECK: t9
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
}
unsigned t10(void) {
@@ -91,7 +91,7 @@ unsigned t10(void) {
// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
// CHECK: store i32 1, i32* [[I]], align 4
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}})
// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
// CHECK: ret i32 [[RET]]
}
@@ -99,7 +99,7 @@ unsigned t10(void) {
void t11(void) {
__asm mov eax, 1
// CHECK: t11
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
unsigned t12(void) {
@@ -112,7 +112,7 @@ unsigned t12(void) {
}
return j + m;
// CHECK: t12
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
}
void t13() {
@@ -121,8 +121,8 @@ void t13() {
__asm movzx eax, i
__asm movzx eax, j
// CHECK: t13
-// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}) nounwind
-// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}})
}
void t14() {
@@ -135,33 +135,38 @@ void t14() {
.endif
}
// CHECK: t14
-// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
+int gvar = 10;
void t15() {
- int var = 10;
- __asm mov eax, var ; eax = 10
- __asm mov eax, offset var ; eax = address of myvar
+ int lvar = 10;
+ __asm mov eax, lvar ; eax = 10
+ __asm mov eax, offset lvar ; eax = address of lvar
+ __asm mov eax, offset gvar ; eax = address of gvar
// CHECK: t15
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}})
}
void t16() {
int var = 10;
__asm mov [eax], offset var
// CHECK: t16
-// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) nounwind
+// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
void t17() {
__asm _emit 0x4A
__asm _emit 0x43
__asm _emit 0x4B
+ __asm _EMIT 0x4B
// CHECK: t17
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"() nounwind
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
}
struct t18_type { int a, b; };
@@ -177,7 +182,7 @@ int t18() {
}
return foo.b;
// CHECK: t18
-// CHECK: call void asm sideeffect inteldialect "lea ebx, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
int t19() {
@@ -191,12 +196,197 @@ int t19() {
}
return foo.b;
// CHECK: t19
-// CHECK: call void asm sideeffect inteldialect "lea ebx, foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t20() {
+ char bar;
int foo;
- __asm mov eax, TYPE foo
+ char _bar[2];
+ int _foo[4];
+
+ __asm mov eax, LENGTH foo
+ __asm mov eax, LENGTH bar
+ __asm mov eax, LENGTH _foo
+ __asm mov eax, LENGTH _bar
// CHECK: t20
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+ __asm mov eax, TYPE foo
+ __asm mov eax, TYPE bar
+ __asm mov eax, TYPE _foo
+ __asm mov eax, TYPE _bar
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+ __asm mov eax, SIZE foo
+ __asm mov eax, SIZE bar
+ __asm mov eax, SIZE _foo
+ __asm mov eax, SIZE _bar
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t21() {
+ __asm {
+ __asm push ebx
+ __asm mov ebx, 0x07
+ __asm pop ebx
+ }
+// CHECK: t21
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+}
+
+extern void t22_helper(int x);
+void t22() {
+ int x = 0;
+ __asm {
+ __asm push ebx
+ __asm mov ebx, esp
+ }
+ t22_helper(x);
+ __asm {
+ __asm mov esp, ebx
+ __asm pop ebx
+ }
+// CHECK: t22
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void @t22_helper
+// CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t23() {
+ __asm {
+ the_label:
+ }
+// CHECK: t23
+// CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t24_helper(void) {}
+void t24() {
+ __asm call t24_helper
+// CHECK: t24
+// CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper)
+}
+
+void t25() {
+ __asm mov eax, 0ffffffffh
+ __asm mov eax, 0fh
+ __asm mov eax, 0a2h
+ __asm mov eax, 0xa2h
+ __asm mov eax, 0xa2
+// CHECK: t25
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0ffffffffh", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0fh", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0a2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t26() {
+ __asm pushad
+ __asm mov eax, 0
+ __asm __emit 0fh
+ __asm __emit 0a2h
+ __asm __EMIT 0a2h
+ __asm popad
+// CHECK: t26
+// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t27() {
+ __asm mov eax, fs:[0h]
+// CHECK: t27
+// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t28() {
+ __asm align 8
+ __asm align 16;
+ __asm align 128;
+ __asm ALIGN 256;
+// CHECK: t28
+// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t29() {
+ int arr[2] = {0, 0};
+ int olen = 0, osize = 0, otype = 0;
+ __asm mov olen, LENGTH arr
+ __asm mov osize, SIZE arr
+ __asm mov otype, TYPE arr
+// CHECK: t29
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+}
+
+int results[2] = {13, 37};
+int *t30()
+{
+ int *res;
+ __asm lea edi, results
+ __asm mov res, edi
+ return res;
+// CHECK: t30
+// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}})
+}
+
+void t31() {
+ __asm pushad
+ __asm popad
+// CHECK: t31
+// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t32() {
+ int i;
+ __asm mov eax, i
+ __asm mov eax, dword ptr i
+ __asm mov ax, word ptr i
+ __asm mov al, byte ptr i
+// CHECK: t32
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+}
+
+void t33() {
+ int i;
+ __asm mov eax, [i]
+ __asm mov eax, dword ptr [i]
+ __asm mov ax, word ptr [i]
+ __asm mov al, byte ptr [i]
+// CHECK: t33
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+}
+
+void t34() {
+ __asm prefetchnta 64[eax]
+ __asm mov eax, dword ptr 4[eax]
+// CHECK: t34
+// CHECK: call void asm sideeffect inteldialect "prefetchnta $$64[eax]", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4[eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp
new file mode 100644
index 0000000..9c160be
--- /dev/null
+++ b/test/CodeGen/ms-inline-asm.cpp
@@ -0,0 +1,26 @@
+// REQUIRES: x86-64-registered-target
+// RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s
+
+struct Foo {
+ static int *ptr;
+ static int a, b;
+ struct Bar {
+ static int *ptr;
+ };
+};
+
+void t1() {
+ Foo::ptr = (int *)0xDEADBEEF;
+ Foo::Bar::ptr = (int *)0xDEADBEEF;
+ __asm mov eax, Foo::ptr
+ __asm mov eax, Foo::Bar::ptr
+ __asm mov eax, [Foo::ptr]
+ __asm mov eax, dword ptr [Foo::ptr]
+ __asm mov eax, dword ptr [Foo::ptr]
+// CHECK: @_Z2t1v
+// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::Bar::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c
index 1665f9c..6cf6f0a 100644
--- a/test/CodeGen/mult-alt-generic.c
+++ b/test/CodeGen/mult-alt-generic.c
@@ -1,7 +1,6 @@
// 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 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
diff --git a/test/CodeGen/no-opt-volatile-memcpy.c b/test/CodeGen/no-opt-volatile-memcpy.c
new file mode 100644
index 0000000..0fab363
--- /dev/null
+++ b/test/CodeGen/no-opt-volatile-memcpy.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -O0 -triple=x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+// rdar://11861085
+
+struct s {
+ char filler [128];
+ volatile int x;
+};
+
+struct s gs;
+
+void foo (void) {
+ struct s ls;
+ ls = ls;
+ gs = gs;
+ ls = gs;
+}
+// CHECK: define void @foo()
+// CHECK: %[[LS:.*]] = alloca %struct.s, align 4
+// CHECK-NEXT: %[[ZERO:.*]] = bitcast %struct.s* %[[LS]] to i8*
+// CHECK-NEXT: %[[ONE:.*]] = bitcast %struct.s* %[[LS]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* %[[ZERO]], i8* %[[ONE]], i64 132, i32 4, i1 true)
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true)
+// CHECK-NEXT: %[[TWO:.*]] = bitcast %struct.s* %[[LS]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* %[[TWO]], i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true)
+
+
+struct s1 {
+ struct s y;
+};
+
+struct s1 s;
+
+void fee (void) {
+ s = s;
+ s.y = gs;
+}
+// CHECK: define void @fee()
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true)
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true)
+
diff --git a/test/CodeGen/nvptx-cpus.c b/test/CodeGen/nvptx-cpus.c
new file mode 100644
index 0000000..c9c7680
--- /dev/null
+++ b/test/CodeGen/nvptx-cpus.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_20 -O3 -S -o %t %s -emit-llvm
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_21 -O3 -S -o %t %s -emit-llvm
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_30 -O3 -S -o %t %s -emit-llvm
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_35 -O3 -S -o %t %s -emit-llvm
+
+// Make sure clang accepts all supported architectures.
+
+void foo(float* a,
+ float* b) {
+ a[0] = b[0];
+}
diff --git a/test/CodeGen/packed-nest-unpacked.c b/test/CodeGen/packed-nest-unpacked.c
index 6097e3f..7f486c9 100644
--- a/test/CodeGen/packed-nest-unpacked.c
+++ b/test/CodeGen/packed-nest-unpacked.c
@@ -60,6 +60,6 @@ struct YBitfield gbitfield;
unsigned test7() {
// CHECK: @test7
- // CHECK: load i32* bitcast (%struct.XBitfield* getelementptr inbounds (%struct.YBitfield* @gbitfield, i32 0, i32 1) to i32*), align 1
+ // CHECK: load i32* bitcast (%struct.XBitfield* getelementptr inbounds (%struct.YBitfield* @gbitfield, i32 0, i32 1) to i32*), align 4
return gbitfield.y.b2;
}
diff --git a/test/CodeGen/packed-structure.c b/test/CodeGen/packed-structure.c
index 3aeaa23..ffd98db 100644
--- a/test/CodeGen/packed-structure.c
+++ b/test/CodeGen/packed-structure.c
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | opt -S -strip -o %t
-// RUX: llvm-gcc -flto -S -O3 -o %t %s
// RUN: FileCheck --check-prefix=CHECK-GLOBAL < %t %s
// RUN: FileCheck --check-prefix=CHECK-FUNCTIONS < %t %s
diff --git a/test/CodeGen/parameter-passing.c b/test/CodeGen/parameter-passing.c
index e48815b..40610af 100644
--- a/test/CodeGen/parameter-passing.c
+++ b/test/CodeGen/parameter-passing.c
@@ -5,14 +5,10 @@
// We also check _Bool and empty structures, as these can have annoying
// corner cases.
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O3 -emit-llvm -o %t
-// RUN: not grep '@g0' %t
-
-// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -O3 -emit-llvm -o %t
-// RUN: not grep '@g0' %t
-
-// RUN: %clang_cc1 %s -triple powerpc-unknown-unknown -O3 -emit-llvm -o %t
-// RUN: not grep '@g0' %t
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -O3 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -O3 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple powerpc-unknown-unknown -O3 -emit-llvm -o - | FileCheck %s
+// CHECK-NOT: @g0
typedef _Bool BoolTy;
typedef int ScalarTy;
diff --git a/test/CodeGen/ppc-atomics.c b/test/CodeGen/ppc-atomics.c
deleted file mode 100644
index 3fcb0fb..0000000
--- a/test/CodeGen/ppc-atomics.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: %clang_cc1 -triple powerpc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=32
-// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=64
-
-unsigned char c1, c2;
-unsigned short s1, s2;
-unsigned int i1, i2;
-unsigned long long ll1, ll2;
-
-enum memory_order {
- memory_order_relaxed,
- memory_order_consume,
- memory_order_acquire,
- memory_order_release,
- memory_order_acq_rel,
- memory_order_seq_cst
-};
-
-void test1(void) {
- (void)__atomic_load(&c1, &c2, memory_order_seq_cst);
- (void)__atomic_load(&s1, &s2, memory_order_seq_cst);
- (void)__atomic_load(&i1, &i2, memory_order_seq_cst);
- (void)__atomic_load(&ll1, &ll2, memory_order_seq_cst);
-
-// 32: define void @test1
-// 32: load atomic i8* @c1 seq_cst
-// 32: load atomic i16* @s1 seq_cst
-// 32: load atomic i32* @i1 seq_cst
-// 32: call void @__atomic_load(i32 8, i8* bitcast (i64* @ll1 to i8*)
-
-// 64: define void @test1
-// 64: load atomic i8* @c1 seq_cst
-// 64: load atomic i16* @s1 seq_cst
-// 64: load atomic i32* @i1 seq_cst
-// 64: load atomic i64* @ll1 seq_cst
-}
diff --git a/test/CodeGen/ppc64-complex-parms.c b/test/CodeGen/ppc64-complex-parms.c
new file mode 100644
index 0000000..92a6fa5
--- /dev/null
+++ b/test/CodeGen/ppc64-complex-parms.c
@@ -0,0 +1,184 @@
+// REQUIRES: ppc64-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+float crealf(_Complex float);
+double creal(_Complex double);
+long double creall(_Complex long double);
+
+float foo_float(_Complex float x) {
+ return crealf(x);
+}
+
+// CHECK: define float @foo_float(float {{[%A-Za-z0-9.]+}}, float {{[%A-Za-z0-9.]+}}) [[NUW:#[0-9]+]] {
+
+double foo_double(_Complex double x) {
+ return creal(x);
+}
+
+// CHECK: define double @foo_double(double {{[%A-Za-z0-9.]+}}, double {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+long double foo_long_double(_Complex long double x) {
+ return creall(x);
+}
+
+// CHECK: define ppc_fp128 @foo_long_double(ppc_fp128 {{[%A-Za-z0-9.]+}}, ppc_fp128 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+int foo_int(_Complex int x) {
+ return __real__ x;
+}
+
+// CHECK: define signext i32 @foo_int(i32 {{[%A-Za-z0-9.]+}}, i32 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+short foo_short(_Complex short x) {
+ return __real__ x;
+}
+
+// CHECK: define signext i16 @foo_short(i16 {{[%A-Za-z0-9.]+}}, i16 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+signed char foo_char(_Complex signed char x) {
+ return __real__ x;
+}
+
+// CHECK: define signext i8 @foo_char(i8 {{[%A-Za-z0-9.]+}}, i8 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+long foo_long(_Complex long x) {
+ return __real__ x;
+}
+
+// CHECK: define i64 @foo_long(i64 {{[%A-Za-z0-9.]+}}, i64 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+long long foo_long_long(_Complex long long x) {
+ return __real__ x;
+}
+
+// CHECK: define i64 @foo_long_long(i64 {{[%A-Za-z0-9.]+}}, i64 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+void bar_float(void) {
+ foo_float(2.0f - 2.5fi);
+}
+
+// CHECK: define void @bar_float() [[NUW]] {
+// CHECK: %[[VAR1:[A-Za-z0-9.]+]] = alloca { float, float }, align 4
+// CHECK: %[[VAR2:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR1]], i32 0, i32 0
+// CHECK: %[[VAR3:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR1]], i32 0, i32 1
+// CHECK: store float 2.000000e+00, float* %[[VAR2]]
+// CHECK: store float -2.500000e+00, float* %[[VAR3]]
+// CHECK: %[[VAR4:[A-Za-z0-9.]+]] = getelementptr { float, float }* %[[VAR1]], i32 0, i32 0
+// CHECK: %[[VAR5:[A-Za-z0-9.]+]] = load float* %[[VAR4]], align 1
+// CHECK: %[[VAR6:[A-Za-z0-9.]+]] = getelementptr { float, float }* %[[VAR1]], i32 0, i32 1
+// CHECK: %[[VAR7:[A-Za-z0-9.]+]] = load float* %[[VAR6]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call float @foo_float(float %[[VAR5]], float %[[VAR7]])
+
+void bar_double(void) {
+ foo_double(2.0 - 2.5i);
+}
+
+// CHECK: define void @bar_double() [[NUW]] {
+// CHECK: %[[VAR11:[A-Za-z0-9.]+]] = alloca { double, double }, align 8
+// CHECK: %[[VAR12:[A-Za-z0-9.]+]] = getelementptr inbounds { double, double }* %[[VAR11]], i32 0, i32 0
+// CHECK: %[[VAR13:[A-Za-z0-9.]+]] = getelementptr inbounds { double, double }* %[[VAR11]], i32 0, i32 1
+// CHECK: store double 2.000000e+00, double* %[[VAR12]]
+// CHECK: store double -2.500000e+00, double* %[[VAR13]]
+// CHECK: %[[VAR14:[A-Za-z0-9.]+]] = getelementptr { double, double }* %[[VAR11]], i32 0, i32 0
+// CHECK: %[[VAR15:[A-Za-z0-9.]+]] = load double* %[[VAR14]], align 1
+// CHECK: %[[VAR16:[A-Za-z0-9.]+]] = getelementptr { double, double }* %[[VAR11]], i32 0, i32 1
+// CHECK: %[[VAR17:[A-Za-z0-9.]+]] = load double* %[[VAR16]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call double @foo_double(double %[[VAR15]], double %[[VAR17]])
+
+void bar_long_double(void) {
+ foo_long_double(2.0L - 2.5Li);
+}
+
+// CHECK: define void @bar_long_double() [[NUW]] {
+// CHECK: %[[VAR21:[A-Za-z0-9.]+]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK: %[[VAR22:[A-Za-z0-9.]+]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 0
+// CHECK: %[[VAR23:[A-Za-z0-9.]+]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 1
+// CHECK: store ppc_fp128 0xM40000000000000000000000000000000, ppc_fp128* %[[VAR22]]
+// CHECK: store ppc_fp128 0xMC0040000000000000000000000000000, ppc_fp128* %[[VAR23]]
+// CHECK: %[[VAR24:[A-Za-z0-9.]+]] = getelementptr { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 0
+// CHECK: %[[VAR25:[A-Za-z0-9.]+]] = load ppc_fp128* %[[VAR24]], align 1
+// CHECK: %[[VAR26:[A-Za-z0-9.]+]] = getelementptr { ppc_fp128, ppc_fp128 }* %[[VAR21]], i32 0, i32 1
+// CHECK: %[[VAR27:[A-Za-z0-9.]+]] = load ppc_fp128* %[[VAR26]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call ppc_fp128 @foo_long_double(ppc_fp128 %[[VAR25]], ppc_fp128 %[[VAR27]])
+
+void bar_int(void) {
+ foo_int(2 - 3i);
+}
+
+// CHECK: define void @bar_int() [[NUW]] {
+// CHECK: %[[VAR31:[A-Za-z0-9.]+]] = alloca { i32, i32 }, align 4
+// CHECK: %[[VAR32:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR31]], i32 0, i32 0
+// CHECK: %[[VAR33:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR31]], i32 0, i32 1
+// CHECK: store i32 2, i32* %[[VAR32]]
+// CHECK: store i32 -3, i32* %[[VAR33]]
+// CHECK: %[[VAR34:[A-Za-z0-9.]+]] = getelementptr { i32, i32 }* %[[VAR31]], i32 0, i32 0
+// CHECK: %[[VAR35:[A-Za-z0-9.]+]] = load i32* %[[VAR34]], align 1
+// CHECK: %[[VAR36:[A-Za-z0-9.]+]] = getelementptr { i32, i32 }* %[[VAR31]], i32 0, i32 1
+// CHECK: %[[VAR37:[A-Za-z0-9.]+]] = load i32* %[[VAR36]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call signext i32 @foo_int(i32 %[[VAR35]], i32 %[[VAR37]])
+
+void bar_short(void) {
+ foo_short(2 - 3i);
+}
+
+// CHECK: define void @bar_short() [[NUW]] {
+// CHECK: %[[VAR41:[A-Za-z0-9.]+]] = alloca { i16, i16 }, align 2
+// CHECK: %[[VAR42:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR41]], i32 0, i32 0
+// CHECK: %[[VAR43:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR41]], i32 0, i32 1
+// CHECK: store i16 2, i16* %[[VAR42]]
+// CHECK: store i16 -3, i16* %[[VAR43]]
+// CHECK: %[[VAR44:[A-Za-z0-9.]+]] = getelementptr { i16, i16 }* %[[VAR41]], i32 0, i32 0
+// CHECK: %[[VAR45:[A-Za-z0-9.]+]] = load i16* %[[VAR44]], align 1
+// CHECK: %[[VAR46:[A-Za-z0-9.]+]] = getelementptr { i16, i16 }* %[[VAR41]], i32 0, i32 1
+// CHECK: %[[VAR47:[A-Za-z0-9.]+]] = load i16* %[[VAR46]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call signext i16 @foo_short(i16 %[[VAR45]], i16 %[[VAR47]])
+
+void bar_char(void) {
+ foo_char(2 - 3i);
+}
+
+// CHECK: define void @bar_char() [[NUW]] {
+// CHECK: %[[VAR51:[A-Za-z0-9.]+]] = alloca { i8, i8 }, align 1
+// CHECK: %[[VAR52:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR51]], i32 0, i32 0
+// CHECK: %[[VAR53:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR51]], i32 0, i32 1
+// CHECK: store i8 2, i8* %[[VAR52]]
+// CHECK: store i8 -3, i8* %[[VAR53]]
+// CHECK: %[[VAR54:[A-Za-z0-9.]+]] = getelementptr { i8, i8 }* %[[VAR51]], i32 0, i32 0
+// CHECK: %[[VAR55:[A-Za-z0-9.]+]] = load i8* %[[VAR54]], align 1
+// CHECK: %[[VAR56:[A-Za-z0-9.]+]] = getelementptr { i8, i8 }* %[[VAR51]], i32 0, i32 1
+// CHECK: %[[VAR57:[A-Za-z0-9.]+]] = load i8* %[[VAR56]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call signext i8 @foo_char(i8 %[[VAR55]], i8 %[[VAR57]])
+
+void bar_long(void) {
+ foo_long(2L - 3Li);
+}
+
+// CHECK: define void @bar_long() [[NUW]] {
+// CHECK: %[[VAR61:[A-Za-z0-9.]+]] = alloca { i64, i64 }, align 8
+// CHECK: %[[VAR62:[A-Za-z0-9.]+]] = getelementptr inbounds { i64, i64 }* %[[VAR61]], i32 0, i32 0
+// CHECK: %[[VAR63:[A-Za-z0-9.]+]] = getelementptr inbounds { i64, i64 }* %[[VAR61]], i32 0, i32 1
+// CHECK: store i64 2, i64* %[[VAR62]]
+// CHECK: store i64 -3, i64* %[[VAR63]]
+// CHECK: %[[VAR64:[A-Za-z0-9.]+]] = getelementptr { i64, i64 }* %[[VAR61]], i32 0, i32 0
+// CHECK: %[[VAR65:[A-Za-z0-9.]+]] = load i64* %[[VAR64]], align 1
+// CHECK: %[[VAR66:[A-Za-z0-9.]+]] = getelementptr { i64, i64 }* %[[VAR61]], i32 0, i32 1
+// CHECK: %[[VAR67:[A-Za-z0-9.]+]] = load i64* %[[VAR66]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call i64 @foo_long(i64 %[[VAR65]], i64 %[[VAR67]])
+
+void bar_long_long(void) {
+ foo_long_long(2LL - 3LLi);
+}
+
+// CHECK: define void @bar_long_long() [[NUW]] {
+// CHECK: %[[VAR71:[A-Za-z0-9.]+]] = alloca { i64, i64 }, align 8
+// CHECK: %[[VAR72:[A-Za-z0-9.]+]] = getelementptr inbounds { i64, i64 }* %[[VAR71]], i32 0, i32 0
+// CHECK: %[[VAR73:[A-Za-z0-9.]+]] = getelementptr inbounds { i64, i64 }* %[[VAR71]], i32 0, i32 1
+// CHECK: store i64 2, i64* %[[VAR72]]
+// CHECK: store i64 -3, i64* %[[VAR73]]
+// CHECK: %[[VAR74:[A-Za-z0-9.]+]] = getelementptr { i64, i64 }* %[[VAR71]], i32 0, i32 0
+// CHECK: %[[VAR75:[A-Za-z0-9.]+]] = load i64* %[[VAR74]], align 1
+// CHECK: %[[VAR76:[A-Za-z0-9.]+]] = getelementptr { i64, i64 }* %[[VAR71]], i32 0, i32 1
+// CHECK: %[[VAR77:[A-Za-z0-9.]+]] = load i64* %[[VAR76]], align 1
+// CHECK: %{{[A-Za-z0-9.]+}} = call i64 @foo_long_long(i64 %[[VAR75]], i64 %[[VAR77]])
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/ppc64-complex-return.c b/test/CodeGen/ppc64-complex-return.c
new file mode 100644
index 0000000..b3fd549
--- /dev/null
+++ b/test/CodeGen/ppc64-complex-return.c
@@ -0,0 +1,129 @@
+// REQUIRES: ppc64-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+float crealf(_Complex float);
+double creal(_Complex double);
+long double creall(_Complex long double);
+
+_Complex float foo_float(_Complex float x) {
+ return x;
+}
+
+// CHECK: define { float, float } @foo_float(float {{[%A-Za-z0-9.]+}}, float {{[%A-Za-z0-9.]+}}) [[NUW:#[0-9]+]] {
+
+_Complex double foo_double(_Complex double x) {
+ return x;
+}
+
+// CHECK: define { double, double } @foo_double(double {{[%A-Za-z0-9.]+}}, double {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+_Complex long double foo_long_double(_Complex long double x) {
+ return x;
+}
+
+// CHECK: define { ppc_fp128, ppc_fp128 } @foo_long_double(ppc_fp128 {{[%A-Za-z0-9.]+}}, ppc_fp128 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+_Complex int foo_int(_Complex int x) {
+ return x;
+}
+
+// CHECK: define { i32, i32 } @foo_int(i32 {{[%A-Za-z0-9.]+}}, i32 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+_Complex short foo_short(_Complex short x) {
+ return x;
+}
+
+// CHECK: define { i16, i16 } @foo_short(i16 {{[%A-Za-z0-9.]+}}, i16 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+_Complex signed char foo_char(_Complex signed char x) {
+ return x;
+}
+
+// CHECK: define { i8, i8 } @foo_char(i8 {{[%A-Za-z0-9.]+}}, i8 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+_Complex long foo_long(_Complex long x) {
+ return x;
+}
+
+// CHECK: define { i64, i64 } @foo_long(i64 {{[%A-Za-z0-9.]+}}, i64 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+_Complex long long foo_long_long(_Complex long long x) {
+ return x;
+}
+
+// CHECK: define { i64, i64 } @foo_long_long(i64 {{[%A-Za-z0-9.]+}}, i64 {{[%A-Za-z0-9.]+}}) [[NUW]] {
+
+float bar_float(void) {
+ return crealf(foo_float(2.0f - 2.5fi));
+}
+
+// CHECK: define float @bar_float() [[NUW]] {
+// CHECK: [[VAR1:[%A-Za-z0-9.]+]] = call { float, float } @foo_float
+// CHECK: extractvalue { float, float } [[VAR1]], 0
+// CHECK: extractvalue { float, float } [[VAR1]], 1
+
+double bar_double(void) {
+ return creal(foo_double(2.0 - 2.5i));
+}
+
+// CHECK: define double @bar_double() [[NUW]] {
+// CHECK: [[VAR2:[%A-Za-z0-9.]+]] = call { double, double } @foo_double
+// CHECK: extractvalue { double, double } [[VAR2]], 0
+// CHECK: extractvalue { double, double } [[VAR2]], 1
+
+long double bar_long_double(void) {
+ return creall(foo_long_double(2.0L - 2.5Li));
+}
+
+// CHECK: define ppc_fp128 @bar_long_double() [[NUW]] {
+// CHECK: [[VAR3:[%A-Za-z0-9.]+]] = call { ppc_fp128, ppc_fp128 } @foo_long_double
+// CHECK: extractvalue { ppc_fp128, ppc_fp128 } [[VAR3]], 0
+// CHECK: extractvalue { ppc_fp128, ppc_fp128 } [[VAR3]], 1
+
+int bar_int(void) {
+ return __real__(foo_int(2 - 3i));
+}
+
+// CHECK: define signext i32 @bar_int() [[NUW]] {
+// CHECK: [[VAR4:[%A-Za-z0-9.]+]] = call { i32, i32 } @foo_int
+// CHECK: extractvalue { i32, i32 } [[VAR4]], 0
+// CHECK: extractvalue { i32, i32 } [[VAR4]], 1
+
+short bar_short(void) {
+ return __real__(foo_short(2 - 3i));
+}
+
+// CHECK: define signext i16 @bar_short() [[NUW]] {
+// CHECK: [[VAR5:[%A-Za-z0-9.]+]] = call { i16, i16 } @foo_short
+// CHECK: extractvalue { i16, i16 } [[VAR5]], 0
+// CHECK: extractvalue { i16, i16 } [[VAR5]], 1
+
+signed char bar_char(void) {
+ return __real__(foo_char(2 - 3i));
+}
+
+// CHECK: define signext i8 @bar_char() [[NUW]] {
+// CHECK: [[VAR6:[%A-Za-z0-9.]+]] = call { i8, i8 } @foo_char
+// CHECK: extractvalue { i8, i8 } [[VAR6]], 0
+// CHECK: extractvalue { i8, i8 } [[VAR6]], 1
+
+long bar_long(void) {
+ return __real__(foo_long(2L - 3Li));
+}
+
+// CHECK: define i64 @bar_long() [[NUW]] {
+// CHECK: [[VAR7:[%A-Za-z0-9.]+]] = call { i64, i64 } @foo_long
+// CHECK: extractvalue { i64, i64 } [[VAR7]], 0
+// CHECK: extractvalue { i64, i64 } [[VAR7]], 1
+
+long long bar_long_long(void) {
+ return __real__(foo_long_long(2LL - 3LLi));
+}
+
+// CHECK: define i64 @bar_long_long() [[NUW]] {
+// CHECK: [[VAR8:[%A-Za-z0-9.]+]] = call { i64, i64 } @foo_long_long
+// CHECK: extractvalue { i64, i64 } [[VAR8]], 0
+// CHECK: extractvalue { i64, i64 } [[VAR8]], 1
+
+
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/ppc64-extend.c b/test/CodeGen/ppc64-extend.c
index f4d6bf9..68d28c7 100644
--- a/test/CodeGen/ppc64-extend.c
+++ b/test/CodeGen/ppc64-extend.c
@@ -2,14 +2,15 @@
// RUN: %clang_cc1 -O0 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
void f1(int x) { return; }
-// CHECK: define void @f1(i32 signext %x) nounwind
+// CHECK: define void @f1(i32 signext %x) [[NUW:#[0-9]+]]
void f2(unsigned int x) { return; }
-// CHECK: define void @f2(i32 zeroext %x) nounwind
+// CHECK: define void @f2(i32 zeroext %x) [[NUW]]
int f3(void) { return 0; }
-// CHECK: define signext i32 @f3() nounwind
+// CHECK: define signext i32 @f3() [[NUW]]
unsigned int f4(void) { return 0; }
-// CHECK: define zeroext i32 @f4() nounwind
+// CHECK: define zeroext i32 @f4() [[NUW]]
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/ppc64-varargs-complex.c b/test/CodeGen/ppc64-varargs-complex.c
new file mode 100644
index 0000000..b65a773
--- /dev/null
+++ b/test/CodeGen/ppc64-varargs-complex.c
@@ -0,0 +1,73 @@
+// REQUIRES: ppc64-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+void testva (int n, ...)
+{
+ va_list ap;
+
+ _Complex int i = va_arg(ap, _Complex int);
+ // CHECK: %[[VAR40:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+ // CHECK-NEXT: %[[VAR41:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR40]], i64 16
+ // CHECK-NEXT: store i8* %[[VAR41]], i8** %[[VAR100]]
+ // CHECK-NEXT: %[[VAR1:[A-Za-z0-9.]+]] = ptrtoint i8* %[[VAR40]] to i64
+ // CHECK-NEXT: %[[VAR2:[A-Za-z0-9.]+]] = add i64 %[[VAR1]], 4
+ // CHECK-NEXT: %[[VAR3:[A-Za-z0-9.]+]] = add i64 %[[VAR1]], 12
+ // CHECK-NEXT: %[[VAR4:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR2]] to i32*
+ // CHECK-NEXT: %[[VAR5:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR3]] to i32*
+ // CHECK-NEXT: %[[VAR6:[A-Za-z0-9.]+]] = load i32* %[[VAR4]]
+ // CHECK-NEXT: %[[VAR7:[A-Za-z0-9.]+]] = load i32* %[[VAR5]]
+ // CHECK-NEXT: %[[VAR8:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR0:[A-Za-z0-9.]+]], i32 0, i32 0
+ // CHECK-NEXT: %[[VAR9:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR0]], i32 0, i32 1
+ // CHECK-NEXT: store i32 %[[VAR6]], i32* %[[VAR8]]
+ // CHECK-NEXT: store i32 %[[VAR7]], i32* %[[VAR9]]
+
+ _Complex short s = va_arg(ap, _Complex short);
+ // CHECK: %[[VAR50:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+ // CHECK-NEXT: %[[VAR51:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR50]], i64 16
+ // CHECK-NEXT: store i8* %[[VAR51]], i8** %[[VAR100]]
+ // CHECK: %[[VAR11:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+ // CHECK-NEXT: %[[VAR12:[A-Za-z0-9.]+]] = add i64 %[[VAR11]], 6
+ // CHECK-NEXT: %[[VAR13:[A-Za-z0-9.]+]] = add i64 %[[VAR11]], 14
+ // CHECK-NEXT: %[[VAR14:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR12]] to i16*
+ // CHECK-NEXT: %[[VAR15:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR13]] to i16*
+ // CHECK-NEXT: %[[VAR16:[A-Za-z0-9.]+]] = load i16* %[[VAR14]]
+ // CHECK-NEXT: %[[VAR17:[A-Za-z0-9.]+]] = load i16* %[[VAR15]]
+ // CHECK-NEXT: %[[VAR18:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR10:[A-Za-z0-9.]+]], i32 0, i32 0
+ // CHECK-NEXT: %[[VAR19:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR10]], i32 0, i32 1
+ // CHECK-NEXT: store i16 %[[VAR16]], i16* %[[VAR18]]
+ // CHECK-NEXT: store i16 %[[VAR17]], i16* %[[VAR19]]
+
+ _Complex char c = va_arg(ap, _Complex char);
+ // CHECK: %[[VAR60:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+ // CHECK-NEXT: %[[VAR61:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR60]], i64 16
+ // CHECK-NEXT: store i8* %[[VAR61]], i8** %[[VAR100]]
+ // CHECK: %[[VAR21:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+ // CHECK-NEXT: %[[VAR22:[A-Za-z0-9.]+]] = add i64 %[[VAR21]], 7
+ // CHECK-NEXT: %[[VAR23:[A-Za-z0-9.]+]] = add i64 %[[VAR21]], 15
+ // CHECK-NEXT: %[[VAR24:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR22]] to i8*
+ // CHECK-NEXT: %[[VAR25:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR23]] to i8*
+ // CHECK-NEXT: %[[VAR26:[A-Za-z0-9.]+]] = load i8* %[[VAR24]]
+ // CHECK-NEXT: %[[VAR27:[A-Za-z0-9.]+]] = load i8* %[[VAR25]]
+ // CHECK-NEXT: %[[VAR28:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR20:[A-Za-z0-9.]+]], i32 0, i32 0
+ // CHECK-NEXT: %[[VAR29:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR20]], i32 0, i32 1
+ // CHECK-NEXT: store i8 %[[VAR26]], i8* %[[VAR28]]
+ // CHECK-NEXT: store i8 %[[VAR27]], i8* %[[VAR29]]
+
+ _Complex float f = va_arg(ap, _Complex float);
+ // CHECK: %[[VAR70:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+ // CHECK-NEXT: %[[VAR71:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR70]], i64 16
+ // CHECK-NEXT: store i8* %[[VAR71]], i8** %[[VAR100]]
+ // CHECK: %[[VAR31:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+ // CHECK-NEXT: %[[VAR32:[A-Za-z0-9.]+]] = add i64 %[[VAR31]], 4
+ // CHECK-NEXT: %[[VAR33:[A-Za-z0-9.]+]] = add i64 %[[VAR31]], 12
+ // CHECK-NEXT: %[[VAR34:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR32]] to float*
+ // CHECK-NEXT: %[[VAR35:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR33]] to float*
+ // CHECK-NEXT: %[[VAR36:[A-Za-z0-9.]+]] = load float* %[[VAR34]]
+ // CHECK-NEXT: %[[VAR37:[A-Za-z0-9.]+]] = load float* %[[VAR35]]
+ // CHECK-NEXT: %[[VAR38:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR30:[A-Za-z0-9.]+]], i32 0, i32 0
+ // CHECK-NEXT: %[[VAR39:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR30]], i32 0, i32 1
+ // CHECK-NEXT: store float %[[VAR36]], float* %[[VAR38]]
+ // CHECK-NEXT: store float %[[VAR37]], float* %[[VAR39]]
+}
diff --git a/test/CodeGen/pr2394.c b/test/CodeGen/pr2394.c
index e43281a..f1091ec 100644
--- a/test/CodeGen/pr2394.c
+++ b/test/CodeGen/pr2394.c
@@ -1,7 +1,6 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
struct __attribute((packed)) x {int a : 24;};
int a(struct x* g) {
- // CHECK: load i16
- // CHECK: load i8
+ // CHECK: load i24
return g->a;
}
diff --git a/test/CodeGen/pragma-weak.c b/test/CodeGen/pragma-weak.c
index 2efc2eb..d4b1b9f 100644
--- a/test/CodeGen/pragma-weak.c
+++ b/test/CodeGen/pragma-weak.c
@@ -136,7 +136,7 @@ void __both3(void) {}
void __a1(void) __attribute((noinline));
#pragma weak a1 = __a1
void __a1(void) {}
-// CHECK: define void @__a1() {{.*}} noinline
+// CHECK: define void @__a1() [[NI:#[0-9]+]]
// attributes introduced BEFORE a combination of #pragma weak and alias()
// hold...
@@ -144,11 +144,11 @@ void __a3(void) __attribute((noinline));
#pragma weak a3 = __a3
void a3(void) __attribute((alias("__a3")));
void __a3(void) {}
-// CHECK: define void @__a3() {{.*}} noinline
+// CHECK: define void @__a3() [[NI]]
#pragma weak xxx = __xxx
__attribute((pure,noinline,const,fastcall)) void __xxx(void) { }
-// CHECK: void @__xxx() {{.*}} noinline
+// CHECK: void @__xxx() [[RN:#[0-9]+]]
///////////// PR10878: Make sure we can call a weak alias
void SHA512Pad(void *context) {}
@@ -179,3 +179,6 @@ void zzz(void){}
// CHECK: define void @yyy()
int correct_linkage;
+
+// CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
+// CHECK: attributes [[RN]] = { noinline nounwind readnone{{.*}} }
diff --git a/test/CodeGen/prefetchw-builtins.c b/test/CodeGen/prefetchw-builtins.c
new file mode 100644
index 0000000..9c5fdc7
--- /dev/null
+++ b/test/CodeGen/prefetchw-builtins.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +prfchw -emit-llvm -o - %s | FileCheck %s
+
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
+
+#include <x86intrin.h>
+
+void prefetch_w(void *p) {
+ return _m_prefetchw(p);
+// CHECK: @prefetch_w
+// CHECK: call void @llvm.prefetch({{.*}}, i32 1, i32 3, i32 1)
+}
diff --git a/test/CodeGen/r5.c b/test/CodeGen/r5.c
new file mode 100644
index 0000000..30a0c0d
--- /dev/null
+++ b/test/CodeGen/r5.c
@@ -0,0 +1,5 @@
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-r5 -emit-llvm -S %s -o /dev/null
+
+int main() {
+ return 0;
+}
diff --git a/test/CodeGen/rdrand-builtins.c b/test/CodeGen/rdrand-builtins.c
index b7970f4..15414a3 100644
--- a/test/CodeGen/rdrand-builtins.c
+++ b/test/CodeGen/rdrand-builtins.c
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +rdrnd -emit-llvm -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +rdrnd -target-feature +rdseed -emit-llvm -o - %s | FileCheck %s
// Don't include mm_malloc.h, it's system specific.
#define __MM_MALLOC_H
-#include <immintrin.h>
+#include <x86intrin.h>
int rdrand16(unsigned short *p) {
return _rdrand16_step(p);
@@ -25,3 +25,24 @@ int rdrand64(unsigned long long *p) {
// CHECK: call { i64, i32 } @llvm.x86.rdrand.64
// CHECK: store i64
}
+
+int rdseed16(unsigned short *p) {
+ return _rdseed16_step(p);
+// CHECK: @rdseed16
+// CHECK: call { i16, i32 } @llvm.x86.rdseed.16
+// CHECK: store i16
+}
+
+int rdseed32(unsigned *p) {
+ return _rdseed32_step(p);
+// CHECK: @rdseed32
+// CHECK: call { i32, i32 } @llvm.x86.rdseed.32
+// CHECK: store i32
+}
+
+int rdseed64(unsigned long long *p) {
+ return _rdseed64_step(p);
+// CHECK: @rdseed64
+// CHECK: call { i64, i32 } @llvm.x86.rdseed.64
+// CHECK: store i64
+}
diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c
index d628b68..4c3752c 100644
--- a/test/CodeGen/regparm.c
+++ b/test/CodeGen/regparm.c
@@ -20,7 +20,7 @@ void f1(int i, int j, int k) { }
int
main(void) {
- // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.foo* inreg null
+ // CHECK: call void @reduced(i8 inreg signext 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/rtm-builtins.c b/test/CodeGen/rtm-builtins.c
index c4939a9..5660d8e 100644
--- a/test/CodeGen/rtm-builtins.c
+++ b/test/CodeGen/rtm-builtins.c
@@ -21,3 +21,8 @@ test_xabort(void) {
// CHECK: void @llvm.x86.xabort(i8 2)
_xabort(2);
}
+
+unsigned int test_xtest(void) {
+ // CHECK: i32 @llvm.x86.xtest()
+ return _xtest();
+}
diff --git a/test/CodeGen/sanitize-init-order.cpp b/test/CodeGen/sanitize-init-order.cpp
new file mode 100644
index 0000000..3e94620
--- /dev/null
+++ b/test/CodeGen/sanitize-init-order.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsanitize=address,init-order -emit-llvm -o - %s | FileCheck %s
+
+struct PODStruct {
+ int x;
+};
+PODStruct s1;
+
+struct PODWithDtor {
+ ~PODWithDtor() { }
+ int x;
+};
+PODWithDtor s2;
+
+struct PODWithCtorAndDtor {
+ PODWithCtorAndDtor() { }
+ ~PODWithCtorAndDtor() { }
+ int x;
+};
+PODWithCtorAndDtor s3;
+
+// Check that ASan init-order checking ignores structs with trivial default
+// constructor.
+// CHECK: !llvm.asan.dynamically_initialized_globals = !{[[GLOB:![0-9]+]]}
+// CHECK: [[GLOB]] = metadata !{%struct.PODWithCtorAndDtor
diff --git a/test/CodeGen/sanitize-recover.c b/test/CodeGen/sanitize-recover.c
new file mode 100644
index 0000000..3c9c895
--- /dev/null
+++ b/test/CodeGen/sanitize-recover.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s --check-prefix=RECOVER
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow -fno-sanitize-recover %s -emit-llvm -o - | FileCheck %s --check-prefix=ABORT
+
+
+// RECOVER: @test
+// ABORT: @test
+void test() {
+ extern volatile unsigned x, y, z;
+
+ // RECOVER: uadd.with.overflow.i32
+ // RECOVER: ubsan_handle_add_overflow(
+ // RECOVER-NOT: unreachable
+ // ABORT: uadd.with.overflow.i32
+ // ABORT: ubsan_handle_add_overflow_abort(
+ // ABORT: unreachable
+ x = y + z;
+}
diff --git a/test/CodeGen/sanitize-thread-attr.cpp b/test/CodeGen/sanitize-thread-attr.cpp
new file mode 100644
index 0000000..fe5d810
--- /dev/null
+++ b/test/CodeGen/sanitize-thread-attr.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+// RUN: echo "src:%s" > %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=thread -fsanitize-blacklist=%t | FileCheck -check-prefix=BL %s
+
+// REQUIRES: shell
+
+// The sanitize_thread attribute should be attached to functions
+// when ThreadSanitizer is enabled, unless no_sanitize_thread attribute
+// is present.
+
+// WITHOUT: NoTSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+// BL: NoTSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+// TSAN: NoTSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+__attribute__((no_sanitize_thread))
+int NoTSAN1(int *a) { return *a; }
+
+// WITHOUT: NoTSAN2{{.*}}) [[NOATTR]]
+// BL: NoTSAN2{{.*}}) [[NOATTR]]
+// TSAN: NoTSAN2{{.*}}) [[NOATTR]]
+__attribute__((no_sanitize_thread))
+int NoTSAN2(int *a);
+int NoTSAN2(int *a) { return *a; }
+
+// WITHOUT: TSANOk{{.*}}) [[NOATTR]]
+// BL: TSANOk{{.*}}) [[NOATTR]]
+// TSAN: TSANOk{{.*}}) [[WITH:#[0-9]+]]
+int TSANOk(int *a) { return *a; }
+
+// WITHOUT: TemplateTSANOk{{.*}}) [[NOATTR]]
+// BL: TemplateTSANOk{{.*}}) [[NOATTR]]
+// TSAN: TemplateTSANOk{{.*}}) [[WITH]]
+template<int i>
+int TemplateTSANOk() { return i; }
+
+// WITHOUT: TemplateNoTSAN{{.*}}) [[NOATTR]]
+// BL: TemplateNoTSAN{{.*}}) [[NOATTR]]
+// TSAN: TemplateNoTSAN{{.*}}) [[NOATTR]]
+template<int i>
+__attribute__((no_sanitize_thread))
+int TemplateNoTSAN() { return i; }
+
+int force_instance = TemplateTSANOk<42>()
+ + TemplateNoTSAN<42>();
+
+// Check that __cxx_global_var_init* get the sanitize_thread attribute.
+int global1 = 0;
+int global2 = *(int*)((char*)&global1+1);
+// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR_NO_TF:#[0-9]+]]
+// BL: @__cxx_global_var_init{{.*}}[[NOATTR_NO_TF:#[0-9]+]]
+// TSAN: @__cxx_global_var_init{{.*}}[[WITH_NO_TF:#[0-9]+]]
+
+// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
+// WITHOUT: attributes [[NOATTR_NO_TF]] = { nounwind }
+
+// BL: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BL: attributes [[NOATTR_NO_TF]] = { nounwind{{.*}} }
+
+// TSAN: attributes [[NOATTR]] = { nounwind{{.*}} }
+// TSAN: attributes [[WITH]] = { nounwind sanitize_thread{{.*}} }
+// TSAN: attributes [[WITH_NO_TF]] = { nounwind sanitize_thread }
diff --git a/test/CodeGen/sanitize-use-after-scope.c b/test/CodeGen/sanitize-use-after-scope.c
new file mode 100644
index 0000000..8f92038
--- /dev/null
+++ b/test/CodeGen/sanitize-use-after-scope.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address,use-after-scope %s \
+// RUN: | FileCheck %s -check-prefix=USE-AFTER-SCOPE
+// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address %s \
+// RUN: | FileCheck %s -check-prefix=ADDRESS-ONLY
+
+extern int bar(char *A, int n);
+
+// ADDRESS-ONLY-NOT: @llvm.lifetime.start
+int foo (int n) {
+ if (n) {
+ // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 10, i8* {{.*}})
+ char A[10];
+ return bar(A, 1);
+ // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 10, i8* {{.*}})
+ } else {
+ // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 20, i8* {{.*}})
+ char A[20];
+ return bar(A, 2);
+ // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 20, i8* {{.*}})
+ }
+}
+
diff --git a/test/CodeGen/split-debug-filename.c b/test/CodeGen/split-debug-filename.c
new file mode 100644
index 0000000..63970a8
--- /dev/null
+++ b/test/CodeGen/split-debug-filename.c
@@ -0,0 +1,7 @@
+// RUN: %clang -target x86_64-linux-gnu -gsplit-dwarf -S -emit-llvm -o - %s | FileCheck %s
+int main (void) {
+ return 0;
+}
+
+// Testing to ensure that the dwo name gets output into the compile unit.
+// CHECK: split-debug-filename.dwo
diff --git a/test/CodeGen/stack-protector.c b/test/CodeGen/stack-protector.c
index eb4cea2..e47e5b3 100644
--- a/test/CodeGen/stack-protector.c
+++ b/test/CodeGen/stack-protector.c
@@ -1,14 +1,24 @@
// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 0 | FileCheck -check-prefix=NOSSP %s
-// NOSSP: define void @test1(i8* %msg) nounwind {
+// NOSSP: define void @test1(i8* %msg) #0 {
// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 1 | FileCheck -check-prefix=WITHSSP %s
-// WITHSSP: define void @test1(i8* %msg) nounwind ssp {
+// WITHSSP: define void @test1(i8* %msg) #0 {
// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 2 | FileCheck -check-prefix=SSPREQ %s
-// SSPREQ: define void @test1(i8* %msg) nounwind sspreq {
+// SSPREQ: define void @test1(i8* %msg) #0 {
+
+typedef __SIZE_TYPE__ size_t;
int printf(const char * _Format, ...);
+size_t strlen(const char *s);
+char *strcpy(char *s1, const char *s2);
void test1(const char *msg) {
char a[strlen(msg) + 1];
strcpy(a, msg);
printf("%s\n", a);
}
+
+// NOSSP: attributes #{{.*}} = { nounwind{{.*}} }
+
+// WITHSSP: attributes #{{.*}} = { nounwind ssp{{.*}} }
+
+// SSPREQ: attributes #{{.*}} = { nounwind sspreq{{.*}} }
diff --git a/test/CodeGen/string-literal.c b/test/CodeGen/string-literal.c
index 12d431a..8bc97f1 100644
--- a/test/CodeGen/string-literal.c
+++ b/test/CodeGen/string-literal.c
@@ -1,80 +1,107 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s
-// RUN: %clang_cc1 -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s
-// RUN: %clang_cc1 -x c++ -std=c++11 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CPP0X %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-C %s
+// RUN: %clang_cc1 -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-C %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-CXX11 %s
+// RUN: %clang_cc1 -x c -std=c11 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-C11 %s
#include <stddef.h>
+#ifndef __cplusplus
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __CHAR16_TYPE__ char16_t;
+typedef __CHAR32_TYPE__ char32_t;
+#endif
+
int main() {
// CHECK-C: private unnamed_addr constant [10 x i8] c"abc\00\00\00\00\00\00\00", align 1
- // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c"abc\00\00\00\00\00\00\00", align 1
+ // CHECK-C11: private unnamed_addr constant [10 x i8] c"abc\00\00\00\00\00\00\00", align 1
+ // CHECK-CXX11: private unnamed_addr 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-C: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1
- // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1
+ // CHECK-C11: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1
+ // CHECK-CXX11: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1
char b[10] = "\u1120\u0220\U00102030";
// CHECK-C: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4
+ // CHECK-C11: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4
const wchar_t *foo = L"AB";
// CHECK-C: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4
+ // CHECK-C11: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4
const wchar_t *bar = L"\u1234\U0010F00B";
// CHECK-C: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4
+ // CHECK-C11: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4
const wchar_t *baz = L"\u1234" "\U0010F00C";
-#if __cplusplus >= 201103L
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 67, i32 68, i32 0], align 4
+#if __cplusplus >= 201103L || __STDC_VERSION__ >= 201112L
+ // CHECK-C11: private unnamed_addr constant [3 x i32] [i32 67, i32 68, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 67, i32 68, i32 0], align 4
const char32_t *c = U"CD";
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110028, i32 0], align 4
+ // CHECK-C11: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110028, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110028, i32 0], align 4
const char32_t *d = U"\u1235\U0010F00C";
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110027, i32 0], align 4
+ // CHECK-C11: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110027, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110027, i32 0], align 4
const char32_t *o = "\u1235" U"\U0010F00B";
- // CHECK-CPP0X: private unnamed_addr constant [3 x i16] [i16 69, i16 70, i16 0], align 2
+ // CHECK-C11: private unnamed_addr constant [3 x i16] [i16 69, i16 70, i16 0], align 2
+ // CHECK-CXX11: private unnamed_addr constant [3 x i16] [i16 69, i16 70, i16 0], align 2
const char16_t *e = u"EF";
// This should convert to utf16.
- // CHECK-CPP0X: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0], align 2
+ // CHECK-C11: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0], align 2
+ // CHECK-CXX11: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0], align 2
const char16_t *f = u"\u1120\u0220\U00102030";
// This should convert to utf16.
- // CHECK-CPP0X: private unnamed_addr constant [5 x i16] [i16 4384, i16 800, i16 -9272, i16 -9168, i16 0], align 2
+ // CHECK-C11: private unnamed_addr constant [5 x i16] [i16 4384, i16 800, i16 -9272, i16 -9168, i16 0], align 2
+ // CHECK-CXX11: private unnamed_addr constant [5 x i16] [i16 4384, i16 800, i16 -9272, i16 -9168, i16 0], align 2
const char16_t *p = u"\u1120\u0320" "\U00102030";
- // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"def\00", align 1
+ // CHECK-C11: private unnamed_addr constant [4 x i8] c"def\00", align 1
+ // CHECK-CXX11: private unnamed_addr constant [4 x i8] c"def\00", align 1
const char *g = u8"def";
- // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"ghi\00", align 1
+#ifdef __cplusplus
+ // CHECK-CXX11: private unnamed_addr constant [4 x i8] c"ghi\00", align 1
const char *h = R"foo(ghi)foo";
- // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"jkl\00", align 1
+ // CHECK-CXX11: private unnamed_addr constant [4 x i8] c"jkl\00", align 1
const char *i = u8R"bar(jkl)bar";
- // CHECK-CPP0X: private unnamed_addr constant [3 x i16] [i16 71, i16 72, i16 0], align 2
+ // CHECK-CXX11: private unnamed_addr constant [3 x i16] [i16 71, i16 72, i16 0], align 2
const char16_t *j = uR"foo(GH)foo";
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 73, i32 74, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 73, i32 74, i32 0], align 4
const char32_t *k = UR"bar(IJ)bar";
- // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 75, i32 76, i32 0], align 4
+ // CHECK-CXX11: private unnamed_addr constant [3 x i32] [i32 75, i32 76, i32 0], align 4
const wchar_t *l = LR"bar(KL)bar";
- // CHECK-CPP0X: private unnamed_addr constant [9 x i8] c"abc\5Cndef\00", align 1
+ // CHECK-CXX11: private unnamed_addr constant [9 x i8] c"abc\5Cndef\00", align 1
const char *m = R"(abc\ndef)";
- // CHECK-CPP0X: private unnamed_addr constant [8 x i8] c"abc\0Adef\00", align 1
+ // CHECK-CXX11: private unnamed_addr constant [8 x i8] c"abc\0Adef\00", align 1
const char *n = R"(abc
def)";
- // CHECK-CPP0X: private unnamed_addr constant [11 x i8] c"abc\0Adefghi\00", align 1
+ // CHECK-CXX11: private unnamed_addr constant [11 x i8] c"abc\0Adefghi\00", align 1
const char *q = R"(abc
def)" "ghi";
+ // CHECK-CXX11: private unnamed_addr constant [13 x i8] c"abc\5C\0A??=\0Adef\00", align 1
+ const char *r = R\
+"(abc\
+??=
+def)";
+
+#endif
#endif
}
diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c
index efb00ef..d28fee2 100644
--- a/test/CodeGen/struct-passing.c
+++ b/test/CodeGen/struct-passing.c
@@ -16,9 +16,12 @@ void __attribute__((pure)) f5(T1 a);
void *ps[] = { f0, f1, f2, f3, f4, f5 };
-// CHECK: declare i32 @f0() nounwind readnone
-// CHECK: declare i32 @f1() nounwind readonly
+// CHECK: declare i32 @f0() [[RN:#[0-9]+]]
+// CHECK: declare i32 @f1() [[RO:#[0-9]+]]
// CHECK: declare void @f2({{.*}} sret)
// CHECK: declare void @f3({{.*}} sret)
// CHECK: declare void @f4({{.*}} byval align 4)
// CHECK: declare void @f5({{.*}} byval align 4)
+
+// CHECK: attributes [[RN]] = { nounwind readnone{{.*}} }
+// CHECK: attributes [[RO]] = { nounwind readonly{{.*}} }
diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp
index 8b30aa0..12a6f4d 100644
--- a/test/CodeGen/tbaa-struct.cpp
+++ b/test/CodeGen/tbaa-struct.cpp
@@ -14,4 +14,33 @@ void copy(struct A *a, struct A *b) {
// CHECK: target datalayout = "{{.*}}p:[[P:64|32]]
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]]
+
+struct B {
+ char c1;
+ struct A a;
+ int ii;
+};
+
+void copy2(struct B *a, struct B *b) {
+ *a = *b;
+}
+
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 24, i32 4, i1 false), !tbaa.struct [[TS2:!.*]]
+
+typedef _Complex int T2;
+typedef _Complex char T5;
+typedef _Complex int T7;
+typedef struct T4 { T5 field0; T7 field1; } T4;
+typedef union T1 { T2 field0; T4 field1; } T1;
+
+void copy3 (T1 *a, T1 *b) {
+ *a = *b;
+}
+
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]]
+
// CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}}
+// (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int
+// CHECK: [[TS2]] = metadata !{i64 0, i64 1, metadata !{{.*}}, i64 4, i64 2, metadata !{{.*}}, i64 8, i64 4, metadata !{{.*}}, i64 12, i64 1, metadata !{{.*}}, i64 16, i64 4, metadata {{.*}}, i64 20, i64 4, metadata {{.*}}}
+// (offset, size) = (0,8) char; (0,2) char; (4,8) char
+// CHECK: [[TS3]] = metadata !{i64 0, i64 8, metadata !{{.*}}, i64 0, i64 2, metadata !{{.*}}, i64 4, i64 8, metadata !{{.*}}}
diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp
new file mode 100644
index 0000000..c30e4a3
--- /dev/null
+++ b/test/CodeGen/tbaa.cpp
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// Test TBAA metadata generated by front-end.
+
+#include <stdint.h>
+typedef struct
+{
+ uint16_t f16;
+ uint32_t f32;
+ uint16_t f16_2;
+ uint32_t f32_2;
+} StructA;
+typedef struct
+{
+ uint16_t f16;
+ StructA a;
+ uint32_t f32;
+} StructB;
+typedef struct
+{
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+} StructC;
+typedef struct
+{
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+ uint8_t f8;
+} StructD;
+
+typedef struct
+{
+ uint16_t f16;
+ uint32_t f32;
+} StructS;
+typedef struct
+{
+ uint16_t f16;
+ uint32_t f32;
+} StructS2;
+
+uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5
+ *s = 1;
+ A->f32 = 4;
+ return *s;
+}
+
+uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8
+ *s = 1;
+ A->f16 = 4;
+ return *s;
+}
+
+uint32_t g3(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
+ A->f32 = 1;
+ B->a.f32 = 4;
+ return A->f32;
+}
+
+uint32_t g4(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11
+ A->f32 = 1;
+ B->a.f16 = 4;
+ return A->f32;
+}
+
+uint32_t g5(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12
+ A->f32 = 1;
+ B->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g6(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13
+ A->f32 = 1;
+ B->a.f32_2 = 4;
+ return A->f32;
+}
+
+uint32_t g7(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14
+ A->f32 = 1;
+ S->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g8(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16
+ A->f32 = 1;
+ S->f16 = 4;
+ return A->f32;
+}
+
+uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17
+ S->f32 = 1;
+ S2->f32 = 4;
+ return S->f32;
+}
+
+uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19
+ S->f32 = 1;
+ S2->f16 = 4;
+ return S->f32;
+}
+
+uint32_t g11(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22
+ C->b.a.f32 = 1;
+ D->b.a.f32 = 4;
+ return C->b.a.f32;
+}
+
+uint32_t g12(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// TODO: differentiate the two accesses.
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
+ StructB *b1 = &(C->b);
+ StructB *b2 = &(D->b);
+ // b1, b2 have different context.
+ b1->a.f32 = 1;
+ b2->a.f32 = 4;
+ return b1->a.f32;
+}
+
+// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
+// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
+// CHECK: !4 = metadata !{metadata !"int", metadata !1}
+// CHECK: !5 = metadata !{metadata !"short", metadata !1}
+
+// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2}
+// PATH: !4 = metadata !{metadata !"int", metadata !1}
+// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4}
+// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4}
+// PATH: !7 = metadata !{metadata !"short", metadata !1}
+// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0}
+// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8}
+// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4}
+// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4}
+// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20}
+// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16}
+// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4}
+// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4}
+// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0}
+// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4}
+// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4}
+// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0}
+// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12}
+// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4}
+// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12}
+// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1}
diff --git a/test/CodeGen/ubsan-blacklist.c b/test/CodeGen/ubsan-blacklist.c
new file mode 100644
index 0000000..6c67f02
--- /dev/null
+++ b/test/CodeGen/ubsan-blacklist.c
@@ -0,0 +1,31 @@
+// Verify ubsan doesn't emit checks for blacklisted functions and files
+// RUN: echo "fun:hash" > %t-func.blacklist
+// RUN: echo "src:%s" > %t-file.blacklist
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow -fsanitize-blacklist=%t-func.blacklist -emit-llvm %s -o - | FileCheck %s --check-prefix=FUNC
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow -fsanitize-blacklist=%t-file.blacklist -emit-llvm %s -o - | FileCheck %s --check-prefix=FILE
+
+// FIXME: %t-file.blacklist contains DOSish paths.
+// REQUIRES: shell
+
+unsigned i;
+
+// DEFAULT: @hash
+// FUNC: @hash
+// FILE: @hash
+unsigned hash() {
+// DEFAULT: call void @__ubsan
+// FUNC-NOT: call void @__ubsan
+// FILE-NOT: call void @__ubsan
+ return i * 37;
+}
+
+// DEFAULT: @add
+// FUNC: @add
+// FILE: @add
+unsigned add() {
+// DEFAULT: call void @__ubsan
+// FUNC: call void @__ubsan
+// FILE-NOT: call void @__ubsan
+ return i + 1;
+}
diff --git a/test/CodeGen/ucn-identifiers.c b/test/CodeGen/ucn-identifiers.c
new file mode 100644
index 0000000..56e3aa5
--- /dev/null
+++ b/test/CodeGen/ucn-identifiers.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -emit-llvm -o /dev/null
+// RUN: %clang_cc1 %s -emit-llvm -o /dev/null -x c++
+// This file contains UTF-8; please do not fix!
+
+
+extern void \u00FCber(int);
+extern void \U000000FCber(int); // redeclaration, no warning
+
+void goodCalls() {
+ \u00FCber(0);
+ \u00fcber(1);
+ über(2);
+ \U000000FCber(3);
+}
diff --git a/test/CodeGen/unreachable.c b/test/CodeGen/unreachable.c
index 5e9fa6a..898f64e 100644
--- a/test/CodeGen/unreachable.c
+++ b/test/CodeGen/unreachable.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o %t %s
-// RUN: grep '@unreachable' %t | count 0
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// CHECK-NOT: @unreachable
extern void abort() __attribute__((noreturn));
extern int unreachable();
diff --git a/test/CodeGen/unsigned-overflow.c b/test/CodeGen/unsigned-overflow.c
new file mode 100644
index 0000000..341ea35
--- /dev/null
+++ b/test/CodeGen/unsigned-overflow.c
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s
+// Verify checked operations are emitted for integers and longs.
+// unsigned short/char's tested in unsigned-promotion.c
+
+unsigned long li, lj, lk;
+unsigned int ii, ij, ik;
+
+extern void opaquelong(unsigned long);
+extern void opaqueint(unsigned int);
+
+// CHECK: define void @testlongadd()
+void testlongadd() {
+
+ // CHECK: [[T1:%.*]] = load i64* @lj
+ // CHECK-NEXT: [[T2:%.*]] = load i64* @lk
+ // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]])
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
+ // CHECK: call void @__ubsan_handle_add_overflow
+ li = lj + lk;
+}
+
+// CHECK: define void @testlongsub()
+void testlongsub() {
+
+ // CHECK: [[T1:%.*]] = load i64* @lj
+ // CHECK-NEXT: [[T2:%.*]] = load i64* @lk
+ // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]])
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
+ // CHECK: call void @__ubsan_handle_sub_overflow
+ li = lj - lk;
+}
+
+// CHECK: define void @testlongmul()
+void testlongmul() {
+
+ // CHECK: [[T1:%.*]] = load i64* @lj
+ // CHECK-NEXT: [[T2:%.*]] = load i64* @lk
+ // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]])
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
+ // CHECK: call void @__ubsan_handle_mul_overflow
+ li = lj * lk;
+}
+
+// CHECK: define void @testlongpostinc()
+void testlongpostinc() {
+ opaquelong(li++);
+
+ // CHECK: [[T1:%.*]] = load i64* @li
+ // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
+ // CHECK: call void @__ubsan_handle_add_overflow
+}
+
+// CHECK: define void @testlongpreinc()
+void testlongpreinc() {
+ opaquelong(++li);
+
+ // CHECK: [[T1:%.*]] = load i64* @li
+ // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
+ // CHECK: call void @__ubsan_handle_add_overflow
+}
+
+// CHECK: define void @testintadd()
+void testintadd() {
+
+ // CHECK: [[T1:%.*]] = load i32* @ij
+ // CHECK-NEXT: [[T2:%.*]] = load i32* @ik
+ // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]])
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
+ // CHECK: call void @__ubsan_handle_add_overflow
+ ii = ij + ik;
+}
+
+// CHECK: define void @testintsub()
+void testintsub() {
+
+ // CHECK: [[T1:%.*]] = load i32* @ij
+ // CHECK-NEXT: [[T2:%.*]] = load i32* @ik
+ // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]])
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
+ // CHECK: call void @__ubsan_handle_sub_overflow
+ ii = ij - ik;
+}
+
+// CHECK: define void @testintmul()
+void testintmul() {
+
+ // CHECK: [[T1:%.*]] = load i32* @ij
+ // CHECK-NEXT: [[T2:%.*]] = load i32* @ik
+ // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]])
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
+ // CHECK: call void @__ubsan_handle_mul_overflow
+ ii = ij * ik;
+}
+
+// CHECK: define void @testintpostinc()
+void testintpostinc() {
+ opaqueint(ii++);
+
+ // CHECK: [[T1:%.*]] = load i32* @ii
+ // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+ // CHECK: call void @__ubsan_handle_add_overflow
+}
+
+// CHECK: define void @testintpreinc()
+void testintpreinc() {
+ opaqueint(++ii);
+
+ // CHECK: [[T1:%.*]] = load i32* @ii
+ // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+ // CHECK: call void @__ubsan_handle_add_overflow
+}
diff --git a/test/CodeGen/unsigned-promotion.c b/test/CodeGen/unsigned-promotion.c
new file mode 100644
index 0000000..c263c0c
--- /dev/null
+++ b/test/CodeGen/unsigned-promotion.c
@@ -0,0 +1,143 @@
+// Check -fsanitize=signed-integer-overflow and
+// -fsanitize=unsigned-integer-overflow with promoted unsigned types
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
+// RUN: -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CHECKS
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
+// RUN: -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=CHECKU
+
+unsigned short si, sj, sk;
+unsigned char ci, cj, ck;
+
+extern void opaqueshort(unsigned short);
+extern void opaquechar(unsigned char);
+
+// CHECKS: define void @testshortadd()
+// CHECKU: define void @testshortadd()
+void testshortadd() {
+ // CHECKS: load i16* @sj
+ // CHECKS: load i16* @sk
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_add_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i16* @sj
+ // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i16* @sk
+ // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
+ // CHECKU-NOT: llvm.sadd
+ // CHECKU-NOT: llvm.uadd
+ // CHECKU: [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
+
+ si = sj + sk;
+}
+
+// CHECKS: define void @testshortsub()
+// CHECKU: define void @testshortsub()
+void testshortsub() {
+
+ // CHECKS: load i16* @sj
+ // CHECKS: load i16* @sk
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_sub_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i16* @sj
+ // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i16* @sk
+ // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
+ // CHECKU-NOT: llvm.ssub
+ // CHECKU-NOT: llvm.usub
+ // CHECKU: [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
+
+ si = sj - sk;
+}
+
+// CHECKS: define void @testshortmul()
+// CHECKU: define void @testshortmul()
+void testshortmul() {
+
+ // CHECKS: load i16* @sj
+ // CHECKS: load i16* @sk
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_mul_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i16* @sj
+ // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i16* @sk
+ // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
+ // CHECKU-NOT: llvm.smul
+ // CHECKU-NOT: llvm.umul
+ // CHECKU: [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
+ si = sj * sk;
+}
+
+// CHECKS: define void @testcharadd()
+// CHECKU: define void @testcharadd()
+void testcharadd() {
+
+ // CHECKS: load i8* @cj
+ // CHECKS: load i8* @ck
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_add_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i8* @cj
+ // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i8* @ck
+ // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
+ // CHECKU-NOT: llvm.sadd
+ // CHECKU-NOT: llvm.uadd
+ // CHECKU: [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
+
+ ci = cj + ck;
+}
+
+// CHECKS: define void @testcharsub()
+// CHECKU: define void @testcharsub()
+void testcharsub() {
+
+ // CHECKS: load i8* @cj
+ // CHECKS: load i8* @ck
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_sub_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i8* @cj
+ // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i8* @ck
+ // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
+ // CHECKU-NOT: llvm.ssub
+ // CHECKU-NOT: llvm.usub
+ // CHECKU: [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
+
+ ci = cj - ck;
+}
+
+// CHECKS: define void @testcharmul()
+// CHECKU: define void @testcharmul()
+void testcharmul() {
+
+ // CHECKS: load i8* @cj
+ // CHECKS: load i8* @ck
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_mul_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i8* @cj
+ // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i8* @ck
+ // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
+ // CHECKU-NOT: llvm.smul
+ // CHECKU-NOT: llvm.umul
+ // CHECKU: [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
+
+ ci = cj * ck;
+}
diff --git a/test/CodeGen/unsigned-trapv.c b/test/CodeGen/unsigned-trapv.c
new file mode 100644
index 0000000..b7aed03
--- /dev/null
+++ b/test/CodeGen/unsigned-trapv.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=UNSIGNED
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=unsigned-integer-overflow -ftrapv | FileCheck %s --check-prefix=BOTH
+// Verify that -ftrapv and -fsanitize=unsigned-integer-overflow
+// work together as expected
+
+
+// UNSIGNED: @test_signed
+// TRAPV: @test_signed
+// BOTH: @test_signed
+void test_signed() {
+ extern volatile int a, b, c;
+ // UNSIGNED: add nsw i32
+ // UNSIGNED-NOT: overflow
+ // TRAPV: sadd.with.overflow.i32
+ // TRAPV-NOT: ubsan
+ // TRAPV: llvm.trap
+ // BOTH: sadd.with.overflow.i32
+ // BOTH-NOT: ubsan
+ // BOTH: llvm.trap
+ a = b + c;
+}
+
+// UNSIGNED: @test_unsigned
+// TRAPV: @test_unsigned
+// BOTH: @test_unsigned
+void test_unsigned() {
+ extern volatile unsigned x, y, z;
+ // UNSIGNED: uadd.with.overflow.i32
+ // UNSIGNED-NOT: llvm.trap
+ // UNSIGNED: ubsan
+ // TRAPV-NOT: overflow
+ // TRAPV-NOT: llvm.trap
+ // BOTH: uadd.with.overflow.i32
+ // BOTH: ubsan
+ // BOTH-NOT: llvm.trap
+ x = y + z;
+}
diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c
index 7a79cb6..e505a6e 100644
--- a/test/CodeGen/unwind-attr.c
+++ b/test/CodeGen/unwind-attr.c
@@ -3,22 +3,27 @@
int opaque();
-// CHECK: define [[INT:i.*]] @test0() {
-// CHECK-NOEXC: define [[INT:i.*]] @test0() nounwind {
+// CHECK: define [[INT:i.*]] @test0() [[TF:#[0-9]+]] {
+// CHECK-NOEXC: define [[INT:i.*]] @test0() [[NUW:#[0-9]+]] {
int test0(void) {
return opaque();
}
// <rdar://problem/8087431>: locally infer nounwind at -O0
-// CHECK: define [[INT:i.*]] @test1() nounwind {
-// CHECK-NOEXC: define [[INT:i.*]] @test1() nounwind {
+// CHECK: define [[INT:i.*]] @test1() [[NUW:#[0-9]+]] {
+// CHECK-NOEXC: define [[INT:i.*]] @test1() [[NUW]] {
int test1(void) {
return 0;
}
// <rdar://problem/8283071>: not for weak functions
-// CHECK: define weak [[INT:i.*]] @test2() {
-// CHECK-NOEXC: define weak [[INT:i.*]] @test2() nounwind {
+// CHECK: define weak [[INT:i.*]] @test2() [[TF]] {
+// CHECK-NOEXC: define weak [[INT:i.*]] @test2() [[NUW]] {
__attribute__((weak)) int test2(void) {
return 0;
}
+
+// CHECK: attributes [[TF]] = { "{{.*}} }
+// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+
+// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGen/visibility.c b/test/CodeGen/visibility.c
index fa4b599..3082b7b 100644
--- a/test/CodeGen/visibility.c
+++ b/test/CodeGen/visibility.c
@@ -67,3 +67,10 @@ __private_extern__ void test3(void) {}
// Top of file.
extern int test4;
__private_extern__ int test4 = 10;
+
+// rdar://12399248
+// CHECK-DEFAULT: define hidden void @test5()
+// CHECK-PROTECTED: define hidden void @test5()
+// CHECK-HIDDEN: define hidden void @test5()
+__attribute__((availability(macosx,introduced=10.5,deprecated=10.6)))
+__private_extern__ void test5(void) {}
diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c
index e151827..f63796b 100644
--- a/test/CodeGen/vla.c
+++ b/test/CodeGen/vla.c
@@ -190,4 +190,8 @@ void test6(void)
// CHECK-NEXT: store i32 0, i32* [[IX2]], align 4
}
-
+// Follow gcc's behavior for VLAs in parameter lists. PR9559.
+void test7(int a[b(0)]) {
+ // CHECK: define void @test7(
+ // CHECK: call i32 @b(i8* null)
+}
diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c
index 1a996de..0dcdc15 100644
--- a/test/CodeGen/volatile.c
+++ b/test/CodeGen/volatile.c
@@ -1,10 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm < %s -o %t
-// RUN: grep volatile %t | count 28
-// RUN: grep memcpy %t | count 7
-
-// The number 28 comes from the current codegen for volatile loads;
-// if this number changes, it's not necessarily something wrong, but
-// something has changed to affect volatile load/store codegen
+// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
int S;
volatile int vS;
@@ -43,58 +37,171 @@ volatile_int vtS;
int main() {
int i;
-
+// CHECK: [[I:%[a-zA-Z0-9_.]+]] = alloca i32
// load
i=S;
+// CHECK: load i32* @S
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vS;
+// CHECK: load volatile i32* @vS
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=*pS;
+// CHECK: [[PS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pS
+// CHECK: load i32* [[PS_VAL]]
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=*pvS;
+// CHECK: [[PVS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pvS
+// CHECK: load volatile i32* [[PVS_VAL]]
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=A[2];
+// CHECK: load i32* getelementptr {{.*}} @A
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vA[2];
+// CHECK: load volatile i32* getelementptr {{.*}} @vA
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=F.x;
+// CHECK: load i32* getelementptr {{.*}} @F
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vF.x;
+// CHECK: load volatile i32* getelementptr {{.*}} @vF
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=F2.x;
+// CHECK: load i32* getelementptr {{.*}} @F2
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vF2.x;
+// CHECK: load volatile i32* getelementptr {{.*}} @vF2
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vpF2->x;
+// CHECK: [[VPF2_VAL:%[a-zA-Z0-9_.]+]] = load {{%[a-zA-Z0-9_.]+}}** @vpF2
+// CHECK: [[ELT:%[a-zA-Z0-9_.]+]] = getelementptr {{.*}} [[VPF2_VAL]]
+// CHECK: load volatile i32* [[ELT]]
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=F3.x.y;
+// CHECK: load i32* getelementptr {{.*}} @F3
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vF3.x.y;
+// CHECK: load volatile i32* getelementptr {{.*}} @vF3
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=BF.x;
+// CHECK: load i8* getelementptr {{.*}} @BF
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vBF.x;
+// CHECK: load volatile i8* getelementptr {{.*}} @vBF
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=V[3];
+// CHECK: load <4 x i32>* @V
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vV[3];
+// CHECK: load volatile <4 x i32>* @vV
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=VE.yx[1];
+// CHECK: load <4 x i32>* @VE
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vVE.zy[1];
+// CHECK: load volatile <4 x i32>* @vVE
+// CHECK: store i32 {{.*}}, i32* [[I]]
i = aggFct().x; // Note: not volatile
+ // N.b. Aggregate return is extremely target specific, all we can
+ // really say here is that there probably shouldn't be a volatile
+ // load.
+// CHECK-NOT: load volatile
+// CHECK: store i32 {{.*}}, i32* [[I]]
i=vtS;
+// CHECK: load volatile i32* @vtS
+// CHECK: store i32 {{.*}}, i32* [[I]]
// store
S=i;
+// CHECK: load i32* [[I]]
+// CHECK: store i32 {{.*}}, i32* @S
vS=i;
+// CHECK: load i32* [[I]]
+// CHECK: store volatile i32 {{.*}}, i32* @vS
*pS=i;
+// CHECK: load i32* [[I]]
+// CHECK: [[PS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pS
+// CHECK: store i32 {{.*}}, i32* [[PS_VAL]]
*pvS=i;
+// CHECK: load i32* [[I]]
+// CHECK: [[PVS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pvS
+// CHECK: store volatile i32 {{.*}}, i32* [[PVS_VAL]]
A[2]=i;
+// CHECK: load i32* [[I]]
+// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @A
vA[2]=i;
+// CHECK: load i32* [[I]]
+// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vA
F.x=i;
+// CHECK: load i32* [[I]]
+// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @F
vF.x=i;
+// CHECK: load i32* [[I]]
+// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF
F2.x=i;
+// CHECK: load i32* [[I]]
+// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @F2
vF2.x=i;
+// CHECK: load i32* [[I]]
+// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF2
vpF2->x=i;
+// CHECK: load i32* [[I]]
+// CHECK: [[VPF2_VAL:%[a-zA-Z0-9_.]+]] = load {{%[a-zA-Z0-9._]+}}** @vpF2
+// CHECK: [[ELT:%[a-zA-Z0-9_.]+]] = getelementptr {{.*}} [[VPF2_VAL]]
+// CHECK: store volatile i32 {{.*}}, i32* [[ELT]]
vF3.x.y=i;
+// CHECK: load i32* [[I]]
+// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF3
BF.x=i;
+// CHECK: load i32* [[I]]
+// CHECK: load i8* getelementptr {{.*}} @BF
+// CHECK: store i8 {{.*}}, i8* getelementptr {{.*}} @BF
vBF.x=i;
+// CHECK: load i32* [[I]]
+// CHECK: load volatile i8* getelementptr {{.*}} @vBF
+// CHECK: store volatile i8 {{.*}}, i8* getelementptr {{.*}} @vBF
V[3]=i;
+// CHECK: load i32* [[I]]
+// CHECK: load <4 x i32>* @V
+// CHECK: store <4 x i32> {{.*}}, <4 x i32>* @V
vV[3]=i;
+// CHECK: load i32* [[I]]
+// CHECK: load volatile <4 x i32>* @vV
+// CHECK: store volatile <4 x i32> {{.*}}, <4 x i32>* @vV
vtS=i;
+// CHECK: load i32* [[I]]
+// CHECK: store volatile i32 {{.*}}, i32* @vtS
// other ops:
++S;
+// CHECK: load i32* @S
+// CHECK: store i32 {{.*}}, i32* @S
++vS;
+// CHECK: load volatile i32* @vS
+// CHECK: store volatile i32 {{.*}}, i32* @vS
i+=S;
+// CHECK: load i32* @S
+// CHECK: load i32* [[I]]
+// CHECK: store i32 {{.*}}, i32* [[I]]
i+=vS;
+// CHECK: load volatile i32* @vS
+// CHECK: load i32* [[I]]
+// CHECK: store i32 {{.*}}, i32* [[I]]
++vtS;
+// CHECK: load volatile i32* @vtS
+// CHECK: store volatile i32 {{.*}}, i32* @vtS
(void)vF2;
+ // From vF2 to a temporary
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* {{.*}} @vF2 {{.*}}, i1 true)
vF2 = vF2;
+ // vF2 to itself
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true)
vF2 = vF2 = vF2;
+ // vF2 to itself twice
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true)
vF2 = (vF2, vF2);
+ // vF2 to a temporary, then vF2 to itself
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* {{.*@vF2.*}}, i1 true)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true)
}
diff --git a/test/CodeGen/x86_32-arguments-darwin.c b/test/CodeGen/x86_32-arguments-darwin.c
index 5bbc80b..4aa4295 100644
--- a/test/CodeGen/x86_32-arguments-darwin.c
+++ b/test/CodeGen/x86_32-arguments-darwin.c
@@ -229,7 +229,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; }
// CHECK: define void @f56(
// CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1,
-// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4,
+// CHECK: i64 %a2.coerce, %struct.s56_1* byval align 4,
// CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4,
// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 16 %a7,
// CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9,
@@ -238,7 +238,7 @@ v4i32 f55(v4i32 arg) { return arg+arg; }
// CHECK: call void (i32, ...)* @f56_0(i32 1,
// CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}},
-// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
+// CHECK: i64 %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
// CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}},
// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 16 %{{[^ ]*}},
// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}},
@@ -337,3 +337,8 @@ T66 f66(int i, ...) {
__builtin_va_end(ap);
return v;
}
+
+// PR14453
+struct s67 { _Complex unsigned short int a; };
+void f67(struct s67 x) {}
+// CHECK: define void @f67(%struct.s67* byval align 4 %x)
diff --git a/test/CodeGen/x86_32-arguments-linux.c b/test/CodeGen/x86_32-arguments-linux.c
index 81dcaf6..e93f9dc 100644
--- a/test/CodeGen/x86_32-arguments-linux.c
+++ b/test/CodeGen/x86_32-arguments-linux.c
@@ -3,7 +3,7 @@
// CHECK: define void @f56(
// CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1,
-// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4,
+// CHECK: i64 %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,
@@ -12,7 +12,7 @@
// CHECK: call void (i32, ...)* @f56_0(i32 1,
// CHECK: i32 %{{.*}}, %struct.s56_0* byval align 4 %{{[^ ]*}},
-// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}},
+// CHECK: i64 %{{[^ ]*}}, %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 %{{[^ ]*}},
diff --git a/test/CodeGen/x86_32-inline-asm.c b/test/CodeGen/x86_32-inline-asm.c
new file mode 100644
index 0000000..473f78e
--- /dev/null
+++ b/test/CodeGen/x86_32-inline-asm.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -verify %s
+// <rdar://problem/12415959>
+
+typedef unsigned int u_int32_t;
+typedef u_int32_t uint32_t;
+
+typedef unsigned long long u_int64_t;
+typedef u_int64_t uint64_t;
+
+int func1() {
+ // Error out if size is > 32-bits.
+ uint32_t msr = 0x8b;
+ uint64_t val = 0;
+ __asm__ volatile("wrmsr"
+ :
+ : "c" (msr),
+ "a" ((val & 0xFFFFFFFFUL)), // expected-error {{invalid input size for constraint 'a'}}
+ "d" (((val >> 32) & 0xFFFFFFFFUL)));
+
+ // Don't error out if the size of the destination is <= 32 bits.
+ unsigned char data;
+ unsigned int port;
+ __asm__ volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); // No error expected.
+}
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index f73e1f0..518ee84 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -354,3 +354,41 @@ void test46() { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
struct s47 { unsigned a; };
void f47(int,int,int,int,int,int,struct s47);
void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); }
+
+// rdar://12723368
+// In the following example, there are holes in T4 at the 3rd byte and the 4th
+// byte, however, T2 does not have those holes. T4 is chosen to be the
+// representing type for union T1, but we can't use load or store of T4 since
+// it will skip the 3rd byte and the 4th byte.
+// In general, Since we don't accurately represent the data fields of a union,
+// do not use load or store of the representing llvm type for the union.
+typedef _Complex int T2;
+typedef _Complex char T5;
+typedef _Complex int T7;
+typedef struct T4 { T5 field0; T7 field1; } T4;
+typedef union T1 { T2 field0; T4 field1; } T1;
+extern T1 T1_retval;
+T1 test48(void) {
+// CHECK: @test48
+// CHECK: memcpy
+// CHECK: memcpy
+ return T1_retval;
+}
+
+void test49_helper(double, ...);
+void test49(double d, double e) {
+ test49_helper(d, e);
+}
+// CHECK: define void @test49(
+// CHECK: [[T0:%.*]] = load double*
+// CHECK-NEXT: [[T1:%.*]] = load double*
+// CHECK-NEXT: call void (double, ...)* @test49_helper(double [[T0]], double [[T1]])
+
+void test50_helper();
+void test50(double d, double e) {
+ test50_helper(d, e);
+}
+// CHECK: define void @test50(
+// CHECK: [[T0:%.*]] = load double*
+// CHECK-NEXT: [[T1:%.*]] = load double*
+// CHECK-NEXT: call void (double, double, ...)* bitcast (void (...)* @test50_helper to void (double, double, ...)*)(double [[T0]], double [[T1]])
OpenPOWER on IntegriCloud