summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/2011-12-19-init-list-ctor.cpp6
-rw-r--r--test/CodeGenCXX/Inputs/override-bit-field-layout.layout8
-rw-r--r--test/CodeGenCXX/Inputs/override-layout-virtual-base.layout8
-rw-r--r--test/CodeGenCXX/address-space-of-this.cpp9
-rw-r--r--test/CodeGenCXX/amdgcn-automatic-variable.cpp2
-rw-r--r--test/CodeGenCXX/amdgcn-string-literal.cpp8
-rw-r--r--test/CodeGenCXX/amdgpu-float16.cpp20
-rw-r--r--test/CodeGenCXX/arm-pcs.cpp51
-rw-r--r--test/CodeGenCXX/arm-swiftcall.cpp2
-rw-r--r--test/CodeGenCXX/attr-callback.cpp55
-rw-r--r--test/CodeGenCXX/attr-speculative-load-hardening.cpp62
-rw-r--r--test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp19
-rw-r--r--test/CodeGenCXX/auto-var-init.cpp569
-rw-r--r--test/CodeGenCXX/builtin-calling-conv.cpp42
-rw-r--r--test/CodeGenCXX/builtin-is-constant-evaluated.cpp133
-rw-r--r--test/CodeGenCXX/builtins.cpp2
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp43
-rw-r--r--test/CodeGenCXX/char8_t.cpp12
-rw-r--r--test/CodeGenCXX/const-init-cxx11.cpp2
-rw-r--r--test/CodeGenCXX/constructor-direct-call.cpp27
-rw-r--r--test/CodeGenCXX/cxx11-special-members.cpp2
-rw-r--r--test/CodeGenCXX/cxx11-thread-local-visibility.cpp17
-rw-r--r--test/CodeGenCXX/cxx11-thread-local.cpp2
-rw-r--r--test/CodeGenCXX/cxx11-user-defined-literal.cpp14
-rw-r--r--test/CodeGenCXX/cxx1y-init-captures-eh.cpp104
-rw-r--r--test/CodeGenCXX/cxx1y-variable-template-linkage.cpp54
-rw-r--r--test/CodeGenCXX/cxx1z-init-statement.cpp2
-rw-r--r--test/CodeGenCXX/cxx2a-compare.cpp2
-rw-r--r--test/CodeGenCXX/cxx2a-three-way-comparison.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-class.cpp45
-rw-r--r--test/CodeGenCXX/debug-info-composite-triviality.cpp96
-rw-r--r--test/CodeGenCXX/debug-info-global-ctor-dtor.cpp44
-rw-r--r--test/CodeGenCXX/debug-info-inheriting-constructor.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-var-template-partial.cpp17
-rw-r--r--test/CodeGenCXX/discard-name-values.cpp4
-rw-r--r--test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp4
-rw-r--r--test/CodeGenCXX/dllimport-runtime-fns.cpp63
-rw-r--r--test/CodeGenCXX/float16-declarations.cpp6
-rw-r--r--test/CodeGenCXX/for-range.cpp2
-rw-r--r--test/CodeGenCXX/inheriting-constructor.cpp14
-rw-r--r--test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp34
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp7
-rw-r--r--test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp13
-rw-r--r--test/CodeGenCXX/microsoft-abi-template-static-init.cpp92
-rw-r--r--test/CodeGenCXX/microsoft-abi-typeid.cpp2
-rw-r--r--test/CodeGenCXX/mingw-template-dllexport.cpp48
-rw-r--r--test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp82
-rw-r--r--test/CodeGenCXX/new-array-init.cpp22
-rw-r--r--test/CodeGenCXX/new-overflow.cpp2
-rw-r--r--test/CodeGenCXX/new.cpp2
-rw-r--r--test/CodeGenCXX/override-bit-field-layout.cpp18
-rw-r--r--test/CodeGenCXX/override-layout-virtual-base.cpp21
-rw-r--r--test/CodeGenCXX/override-layout.cpp21
-rw-r--r--test/CodeGenCXX/pod-member-memcpys.cpp14
-rw-r--r--test/CodeGenCXX/pragma-followup_inner.cpp42
-rw-r--r--test/CodeGenCXX/pragma-followup_outer.cpp41
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp4
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-nested.cpp4
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-outer.cpp2
-rw-r--r--test/CodeGenCXX/pragma-loop-safety.cpp12
-rw-r--r--test/CodeGenCXX/pragma-loop.cpp59
-rw-r--r--test/CodeGenCXX/pragma-unroll-and-jam.cpp2
-rw-r--r--test/CodeGenCXX/predefined-expr-cxx14.cpp7
-rw-r--r--test/CodeGenCXX/runtime-dllstorage.cpp4
-rw-r--r--test/CodeGenCXX/stmtexpr.cpp76
-rw-r--r--test/CodeGenCXX/trivial-auto-var-init.cpp75
-rw-r--r--test/CodeGenCXX/trivial_abi.cpp19
-rw-r--r--test/CodeGenCXX/ubsan-unreachable.cpp40
-rw-r--r--test/CodeGenCXX/volatile.cpp18
-rw-r--r--test/CodeGenCXX/vtable-key-function-ios.cpp10
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp2
-rw-r--r--test/CodeGenCXX/wasm-eh.cpp10
75 files changed, 2057 insertions, 342 deletions
diff --git a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
index 84c4619593..4113137348 100644
--- a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
+++ b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
@@ -19,8 +19,8 @@ struct S {
};
// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 0)
-// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 0)
-// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0))
// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 0)
-// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i32 0, i32 0))
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0))
diff --git a/test/CodeGenCXX/Inputs/override-bit-field-layout.layout b/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
index 8e67dce650..b57c6efbc1 100644
--- a/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
+++ b/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
@@ -14,3 +14,11 @@ Layout: <ASTRecordLayout
Size:128
Alignment:64
FieldOffsets: [64]>
+
+*** Dumping AST Record Layout
+Type: struct S3
+
+Layout: <ASTRecordLayout
+ Size:32
+ Alignment:32
+ FieldOffsets: [0, 1]>
diff --git a/test/CodeGenCXX/Inputs/override-layout-virtual-base.layout b/test/CodeGenCXX/Inputs/override-layout-virtual-base.layout
new file mode 100644
index 0000000000..71d88c1e60
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/override-layout-virtual-base.layout
@@ -0,0 +1,8 @@
+
+*** Dumping AST Record Layout
+Type: struct S2
+
+Layout: <ASTRecordLayout
+ Size:64
+ Alignment:64
+ FieldOffsets: []>
diff --git a/test/CodeGenCXX/address-space-of-this.cpp b/test/CodeGenCXX/address-space-of-this.cpp
new file mode 100644
index 0000000000..3a1e53ced0
--- /dev/null
+++ b/test/CodeGenCXX/address-space-of-this.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -std=c++14 -triple=spir -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++17 -triple=spir -emit-llvm -o - | FileCheck %s
+
+struct MyType {
+ MyType(int i) : i(i) {}
+ int i;
+};
+//CHECK: call void @_ZN6MyTypeC1Ei(%struct.MyType* addrspacecast (%struct.MyType addrspace(10)* @m to %struct.MyType*), i32 123)
+MyType __attribute__((address_space(10))) m = 123;
diff --git a/test/CodeGenCXX/amdgcn-automatic-variable.cpp b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
index 9830a7845e..f96e288a97 100644
--- a/test/CodeGenCXX/amdgcn-automatic-variable.cpp
+++ b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
@@ -39,7 +39,7 @@ void func2(void) {
// CHECK: store i32* %[[r0]], i32** %[[r3]], align 8
int *lp1 = &lv1;
- // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i32 0, i32 0
+ // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i64 0, i64 0
// CHECK: store i32* %[[arraydecay]], i32** %[[r4]], align 8
int *lp2 = la;
diff --git a/test/CodeGenCXX/amdgcn-string-literal.cpp b/test/CodeGenCXX/amdgcn-string-literal.cpp
index 70be249433..3148077165 100644
--- a/test/CodeGenCXX/amdgcn-string-literal.cpp
+++ b/test/CodeGenCXX/amdgcn-string-literal.cpp
@@ -14,7 +14,7 @@ void g(const char* p);
// CHECK-LABEL: define void @_Z1fv()
void f() {
const char* l_str = "l_str";
-
+
// CHECK: call void @llvm.memcpy.p0i8.p4i8.i64
char l_array[] = "l_array";
@@ -26,3 +26,9 @@ void f() {
const char* p = g_str;
g(p);
}
+
+// CHECK-LABEL: define void @_Z1ev
+void e() {
+ g("string literal");
+ g("string literal");
+}
diff --git a/test/CodeGenCXX/amdgpu-float16.cpp b/test/CodeGenCXX/amdgpu-float16.cpp
new file mode 100644
index 0000000000..cbd1e1dee6
--- /dev/null
+++ b/test/CodeGenCXX/amdgpu-float16.cpp
@@ -0,0 +1,20 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx701 -S -o - %s | FileCheck %s -check-prefix=NOF16
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx803 -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx900 -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx906 -S -o - %s | FileCheck %s
+void f() {
+ _Float16 x, y, z;
+ // CHECK: v_add_f16_e64
+ // NOF16: v_add_f32_e64
+ z = x + y;
+ // CHECK: v_sub_f16_e64
+ // NOF16: v_sub_f32_e64
+ z = x - y;
+ // CHECK: v_mul_f16_e64
+ // NOF16: v_mul_f32_e64
+ z = x * y;
+ // CHECK: v_div_fixup_f16
+ // NOF16: v_div_fixup_f32
+ z = x / y;
+}
diff --git a/test/CodeGenCXX/arm-pcs.cpp b/test/CodeGenCXX/arm-pcs.cpp
new file mode 100644
index 0000000000..1d327d794b
--- /dev/null
+++ b/test/CodeGenCXX/arm-pcs.cpp
@@ -0,0 +1,51 @@
+// Covers a bug fix for ABI selection with homogenous aggregates:
+// See: https://bugs.llvm.org/show_bug.cgi?id=39982
+
+// REQUIRES: arm-registered-target
+// RUN: %clang -mfloat-abi=hard --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=HARD,CHECK
+// RUN: %clang -mfloat-abi=softfp --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=SOFTFP,CHECK
+// RUN: %clang -mfloat-abi=soft --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=SOFT,CHECK
+
+struct S {
+ float f;
+ float d;
+ float c;
+ float t;
+};
+
+// Variadic functions should always marshal for the base standard.
+// See section 5.5 (Parameter Passing) of the AAPCS.
+float __attribute__((pcs("aapcs-vfp"))) variadic(S s, ...) {
+ // CHECK-NOT: vmov s{{[0-9]+}}, s{{[0-9]+}}
+ // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
+ return s.d;
+}
+
+float no_attribute(S s) {
+ // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // SOFTFP: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ return s.d;
+}
+
+float __attribute__((pcs("aapcs-vfp"))) baz(float x, float y) {
+ // CHECK-NOT: mov s{{[0-9]+}}, r{{[0-9]+}}
+ // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // SOFTFP: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ return y;
+}
+
+float __attribute__((pcs("aapcs-vfp"))) foo(S s) {
+ // CHECK-NOT: mov s{{[0-9]+}}, r{{[0-9]+}}
+ // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // SOFTFP: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ return s.d;
+}
+
+float __attribute__((pcs("aapcs"))) bar(S s) {
+ // CHECK-NOT: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
+ return s.d;
+}
diff --git a/test/CodeGenCXX/arm-swiftcall.cpp b/test/CodeGenCXX/arm-swiftcall.cpp
index 36a5afad4c..62a92fc20f 100644
--- a/test/CodeGenCXX/arm-swiftcall.cpp
+++ b/test/CodeGenCXX/arm-swiftcall.cpp
@@ -120,6 +120,6 @@ TEST(struct_indirect_1)
class struct_trivial {
int x;
};
-// CHECK-LABEL define void @test_struct_trivial(i32{{( %.*)?}})
+// CHECK-LABEL: define swiftcc void @test_struct_trivial(i32{{( %.*)?}})
extern "C" SWIFTCALL
void test_struct_trivial(struct_trivial triv) {}
diff --git a/test/CodeGenCXX/attr-callback.cpp b/test/CodeGenCXX/attr-callback.cpp
new file mode 100644
index 0000000000..a05b640b60
--- /dev/null
+++ b/test/CodeGenCXX/attr-callback.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+struct Base {
+
+ void no_args_1(void (*callback)(void));
+ __attribute__((callback(1))) void no_args_2(void (*callback1)(void), void (*callback2)(void));
+ __attribute__((callback(callback1))) void no_args_3(void (*callback1)(void), void (*callback2)(void));
+
+ // TODO: There should probably be a warning or even an error for different
+ // callbacks on the same method.
+ __attribute__((callback(1))) virtual void
+ virtual_1(void (*callback)(void));
+
+ __attribute__((callback(callback, this, __, this))) virtual void
+ this_unknown_this(void (*callback)(Base *, Base *, Base *));
+};
+
+// CHECK-DAG: define void @_ZN4Base9no_args_1EPFvvE({{[^!]*!callback}} ![[cid0:[0-9]+]]
+__attribute__((callback(1))) void
+Base::no_args_1(void (*callback)(void)) {
+}
+
+// CHECK-DAG: define void @_ZN4Base9no_args_2EPFvvES1_({{[^!]*!callback}} ![[cid1:[0-9]+]]
+__attribute__((callback(2))) void Base::no_args_2(void (*callback1)(void), void (*callback2)(void)) {
+}
+// CHECK-DAG: define void @_ZN4Base9no_args_3EPFvvES1_({{[^!]*!callback}} ![[cid1]]
+__attribute__((callback(callback2))) void Base::no_args_3(void (*callback1)(void), void (*callback2)(void)) {
+}
+
+// CHECK-DAG: define void @_ZN4Base17this_unknown_thisEPFvPS_S0_S0_E({{[^!]*!callback}} ![[cid2:[0-9]+]]
+void Base::this_unknown_this(void (*callback)(Base *, Base *, Base *)) {
+}
+
+struct Derived_1 : public Base {
+ __attribute__((callback(1))) virtual void
+ virtual_1(void (*callback)(void)) override;
+};
+
+// CHECK-DAG: define void @_ZN9Derived_19virtual_1EPFvvE({{[^!]*!callback}} ![[cid0]]
+void Derived_1::virtual_1(void (*callback)(void)) {}
+
+struct Derived_2 : public Base {
+ void virtual_1(void (*callback)(void)) override;
+};
+
+// CHECK-DAG: define void @_ZN9Derived_29virtual_1EPFvvE
+// CHECK-NOT: !callback
+void Derived_2::virtual_1(void (*callback)(void)) {}
+
+// CHECK-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]}
+// CHECK-DAG: ![[cid0b]] = !{i64 1, i1 false}
+// CHECK-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]}
+// CHECK-DAG: ![[cid1b]] = !{i64 2, i1 false}
+// CHECK-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]}
+// CHECK-DAG: ![[cid2b]] = !{i64 1, i64 0, i64 -1, i64 0, i1 false}
diff --git a/test/CodeGenCXX/attr-speculative-load-hardening.cpp b/test/CodeGenCXX/attr-speculative-load-hardening.cpp
new file mode 100644
index 0000000000..22c5dd52e6
--- /dev/null
+++ b/test/CodeGenCXX/attr-speculative-load-hardening.cpp
@@ -0,0 +1,62 @@
+// Check that we correctly set or did not set the attribute for each function.
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
+
+// Check that we correctly set or did not set the attribute on each function despite the
+// -mspeculative-load-hardening flag.
+// RUN: %clang_cc1 -mspeculative-load-hardening -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
+// RUN: %clang_cc1 -mspeculative-load-hardening -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK4
+
+
+// Check that we correctly set or did not set the attribute on each function despite the
+// -mno-speculative-load-hardening flag.
+// RUN: %clang -mno-speculative-load-hardening -S -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5
+// RUN: %clang -mno-speculative-load-hardening -S -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK6
+
+
+[[clang::speculative_load_hardening]]
+int test1() {
+ return 42;
+}
+
+int __attribute__((speculative_load_hardening)) test2() {
+ return 42;
+}
+
+[[clang::no_speculative_load_hardening]]
+int test3() {
+ return 42;
+}
+
+int __attribute__((no_speculative_load_hardening)) test4() {
+ return 42;
+}
+// CHECK1: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK1: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK1: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK1-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK2: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK2: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK2: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK2-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK3: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK3: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK3: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK3-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK4: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK4: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK4: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK4-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK5: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK5: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK5: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK5-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK6: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK6: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK6: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK6-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp b/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
new file mode 100644
index 0000000000..7d2062f989
--- /dev/null
+++ b/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// Check that PR17480 is fixed: __attribute__((used)) ignored in templated
+// classes
+namespace InstantiateUsedMemberDefinition {
+template <typename T>
+struct S {
+ int __attribute__((used)) f() {
+ return 0;
+ }
+};
+
+void test() {
+ // Check that InstantiateUsedMemberDefinition::S<int>::f() is defined
+ // as a result of the S class template implicit instantiation
+ // CHECK: define linkonce_odr i32 @_ZN31InstantiateUsedMemberDefinition1SIiE1fEv
+ S<int> inst;
+}
+} // namespace InstantiateUsedMemberDefinition
diff --git a/test/CodeGenCXX/auto-var-init.cpp b/test/CodeGenCXX/auto-var-init.cpp
index 0d13c0af4e..390161cf7f 100644
--- a/test/CodeGenCXX/auto-var-init.cpp
+++ b/test/CodeGenCXX/auto-var-init.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,CHECK-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O0,PATTERN,PATTERN-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -O1 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O1,PATTERN,PATTERN-O1
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O0,ZERO,ZERO-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -O1 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O1,ZERO,ZERO-O1
template<typename T> void used(T &) noexcept;
@@ -30,104 +32,193 @@ template<typename T> void used(T &) noexcept;
// PATTERN-NOT: undef
// ZERO-NOT: undef
-// PATTERN: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
+// PATTERN-O1-NOT: @__const.test_empty_uninit.uninit
struct empty {};
-// PATTERN: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
-// PATTERN: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
-// ZERO: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// PATTERN-O0: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// ZERO-O0: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// PATTERN-O1-NOT: @__const.test_small_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_small_custom.custom
+// ZERO-O1-NOT: @__const.test_small_custom.custom
struct small { char c; };
-// PATTERN: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
-// PATTERN: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
-// PATTERN: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O1-NOT: @__const.test_smallinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_smallinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_smallinit_custom.custom
struct smallinit { char c = 42; };
-// PATTERN: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
-// PATTERN: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
-// PATTERN: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O1-NOT: @__const.test_smallpartinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_smallpartinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_smallpartinit_custom.custom
struct smallpartinit { char c = 42, d; };
-// PATTERN: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
-// PATTERN: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
-// PATTERN: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O0: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O0: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O0: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O1-NOT: @__const.test_nullinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_nullinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_nullinit_custom.custom
struct nullinit { char* null = nullptr; };
-// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
-// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+// PATTERN-O0: @__const.test_padded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
+// ZERO-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
+// PATTERN-O1-NOT: @__const.test_padded_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_padded_custom.custom
+// ZERO-O1-NOT: @__const.test_padded_custom.custom
struct padded { char c; int i; };
-// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_paddednullinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_paddednullinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_paddednullinit_custom.custom
struct paddednullinit { char c = 0; int i = 0; };
-// PATTERN: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
-// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_paddedpacked_uninit.uninit = private unnamed_addr constant %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, align 1
+// PATTERN: @__const.test_paddedpacked_custom.custom = private unnamed_addr constant %struct.paddedpacked <{ i8 42, i32 13371337 }>, align 1
+// ZERO: @__const.test_paddedpacked_custom.custom = private unnamed_addr constant %struct.paddedpacked <{ i8 42, i32 13371337 }>, align 1
+struct paddedpacked { char c; int i; } __attribute__((packed));
+// PATTERN-O0: @__const.test_paddedpackedarray_uninit.uninit = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>] }, align 1
+// PATTERN: @__const.test_paddedpackedarray_custom.custom = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }>] }, align 1
+// ZERO: @__const.test_paddedpackedarray_custom.custom = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }>] }, align 1
+struct paddedpackedarray { struct paddedpacked p[2]; };
+// PATTERN-O0: @__const.test_unpackedinpacked_uninit.uninit = private unnamed_addr constant <{ { i8, [3 x i8], i32 }, i8 }> <{ { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, i8 -86 }>, align 1
+struct unpackedinpacked { padded a; char b; } __attribute__((packed));
+// PATTERN-O0: @__const.test_paddednested_uninit.uninit = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 } }, align 4
+// PATTERN: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
+// ZERO: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
+struct paddednested { struct padded p1, p2; };
+// PATTERN-O0: @__const.test_paddedpackednested_uninit.uninit = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }> }, align 1
+// PATTERN: @__const.test_paddedpackednested_custom.custom = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }> }, align 1
+// ZERO: @__const.test_paddedpackednested_custom.custom = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }> }, align 1
+struct paddedpackednested { struct paddedpacked p1, p2; };
+// PATTERN-O0: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN-O0: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] c"\AA\AA\AA" }, align 4
+// ZERO-O0: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O1-NOT: @__const.test_bitfield_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_bitfield_custom.custom
+// ZERO-O1-NOT: @__const.test_bitfield_custom.custom
struct bitfield { int i : 4; int j : 2; };
-// PATTERN: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
-// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN-O0: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] c"\AA\AA\AA", i8 1, [3 x i8] c"\AA\AA\AA" }, align 4
+// ZERO-O0: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O1-NOT: @__const.test_bitfieldaligned_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_bitfieldaligned_custom.custom
+// ZERO-O1-NOT: @__const.test_bitfieldaligned_custom.custom
struct bitfieldaligned { int i : 4; int : 0; int j : 2; };
struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; };
-// PATTERN: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
-// PATTERN: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
-// ZERO: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// ZERO-O0: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// PATTERN-O1-NOT: @__const.test_arraytail_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_arraytail_custom.custom
+// ZERO-O1-NOT: @__const.test_arraytail_custom.custom
struct arraytail { int i; int arr[]; };
-// PATTERN: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
-// PATTERN: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
-// ZERO: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
-// PATTERN: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
-// PATTERN: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
-// ZERO: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
-// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
+// PATTERN-O0: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
+// PATTERN-O0: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// ZERO-O0: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// PATTERN-O1-NOT: @__const.test_int1_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_int1_custom.custom
+// ZERO-O1-NOT: @__const.test_int1_custom.custom
+
+// PATTERN-O0: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
+// PATTERN-O0: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// ZERO-O0: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// PATTERN-O1-NOT: @__const.test_bool4_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_bool4_custom.custom
+// ZERO-O1-NOT: @__const.test_bool4_custom.custom
+
// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
-// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }], align 16
-// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
-// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+// PATTERN-O0: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }], align 16
+// PATTERN-O1-NOT: @__const.test_tailpad4_uninit.uninit
+// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
+// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
struct tailpad { short s; char c; };
-// PATTERN: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
+// PATTERN-O0: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
+// PATTERN-O1-NOT: @__const.test_atomicnotlockfree_uninit.uninit
struct notlockfree { long long a[4]; };
-// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 8
-// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant %struct.tailpad { i16 -21846, i8 -86 }, align 4
-// PATTERN: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// PATTERN-O0: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 8
+// PATTERN-O1-NOT: @__const.test_atomicpadded_uninit.uninit
+// PATTERN-O0: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, align 4
+// PATTERN-O1-NOT: @__const.test_atomictailpad_uninit.uninit
+// PATTERN-O0: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_complexfloat_uninit.uninit
+// PATTERN-O0: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_complexfloat_braces.braces
+// PATTERN-O0: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_complexfloat_custom.custom
+// PATTERN-O0: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_complexdouble_uninit.uninit
+// PATTERN-O0: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_complexdouble_braces.braces
+// PATTERN-O0: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_complexdouble_custom.custom
+// PATTERN-O0: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatile_custom.custom
struct semivolatile { int i; volatile int vi; };
-// PATTERN: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
-// ZERO: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// PATTERN-O0: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatileinit_uninit.uninit
+// PATTERN-O0: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatileinit_braces.braces
+// PATTERN-O0: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// ZERO-O0: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// ZERO-O1-NOT: @__const.test_semivolatile_custom.custom
struct semivolatileinit { int i = 0x11111111; volatile int vi = 0x11111111; };
-// PATTERN: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
-// PATTERN: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN-O0: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN-O1-NOT: @__const.test_base_uninit.uninit
+// PATTERN-O0: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN-O1-NOT: @__const.test_base_braces.braces
struct base { virtual ~base(); };
-// PATTERN: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
-// PATTERN: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN-O0: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN-O1-NOT: @__const.test_derived_uninit.uninit
+// PATTERN-O0: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN-O1-NOT: @__const.test_derived_braces.braces
struct derived : public base {};
-// PATTERN: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
-// PATTERN: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN-O0: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN-O1-NOT: @__const.test_virtualderived_uninit.uninit
+// PATTERN-O0: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN-O1-NOT: @__const.test_virtualderived_braces.braces
struct virtualderived : public virtual base, public virtual derived {};
-// PATTERN: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// PATTERN-O0: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_matching_uninit.uninit
+// PATTERN-O0: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// PATTERN-O1-NOT: @__const.test_matching_custom.custom
+// ZERO-O0: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// ZERO-O1-NOT: @__const.test_matching_custom.custom
union matching { int i; float f; };
-// PATTERN: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
-// ZERO: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// PATTERN-O0: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_matchingreverse_uninit.uninit
+// PATTERN-O0: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// PATTERN-O1-NOT: @__const.test_matchingreverse_custom.custom
+// ZERO-O0: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// ZERO-O1-NOT: @__const.test_matchingreverse_custom.custom
union matchingreverse { float f; int i; };
-// PATTERN: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
-// ZERO: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// PATTERN-O0: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatched_uninit.uninit
+// PATTERN-O0: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatched_custom.custom
+// ZERO-O0: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// ZERO-O1-NOT: @__const.test_unmatched_custom.custom
union unmatched { char c; int i; };
-// PATTERN: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// PATTERN-O0: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatchedreverse_uninit.uninit
+// PATTERN-O0: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatchedreverse_custom.custom
+// ZERO-O0: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO-O1-NOT: @__const.test_unmatchedreverse_custom.custom
union unmatchedreverse { int i; char c; };
-// PATTERN: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
-// ZERO: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// PATTERN-O0: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_unmatchedfp_uninit.uninit
+// PATTERN-O0: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// PATTERN-O1-NOT: @__const.test_unmatchedfp_custom.custom
+// ZERO-O0: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// ZERO-O1-NOT: @__const.test_unmatchedfp_custom.custom
union unmatchedfp { float f; double d; };
enum emptyenum {};
enum smallenum { VALUE };
@@ -472,9 +563,11 @@ TEST_UNINIT(empty, empty);
// CHECK: %uninit = alloca %struct.empty, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_empty_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// PATTERN-O1: store i8 -86, {{.*}} align 1
// ZERO-LABEL: @test_empty_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i8 0, {{.*}} align 1
TEST_BRACES(empty, empty);
// CHECK-LABEL: @test_empty_braces()
@@ -488,9 +581,11 @@ TEST_UNINIT(small, small);
// CHECK: %uninit = alloca %struct.small, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_small_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// PATTERN-O1: store i8 -86, {{.*}} align 1
// ZERO-LABEL: @test_small_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i8 0, {{.*}} align 1
TEST_BRACES(small, small);
// CHECK-LABEL: @test_small_braces()
@@ -532,9 +627,12 @@ TEST_UNINIT(smallpartinit, smallpartinit);
// CHECK-NEXT: call void @{{.*}}smallpartinit{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_smallpartinit_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// PATTERN-O1: store i8 -86, {{.*}} align 1
+// PATTERN-O1: store i8 42, {{.*}} align 1
// ZERO-LABEL: @test_smallpartinit_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i16 0, i16* %uninit, align 2
TEST_BRACES(smallpartinit, smallpartinit);
// CHECK-LABEL: @test_smallpartinit_braces()
@@ -579,9 +677,11 @@ TEST_UNINIT(padded, padded);
// CHECK: %uninit = alloca %struct.padded, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_padded_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_padded_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(padded, padded);
// CHECK-LABEL: @test_padded_braces()
@@ -603,9 +703,11 @@ TEST_UNINIT(paddednullinit, paddednullinit);
// CHECK-NEXT: call void @{{.*}}paddednullinit{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_paddednullinit_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_paddednullinit_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(paddednullinit, paddednullinit);
// CHECK-LABEL: @test_paddednullinit_braces()
@@ -625,14 +727,123 @@ TEST_CUSTOM(paddednullinit, paddednullinit, { 42, 13371337 });
// CHECK-NEXT: store i32 13371337, i32* %[[I]], align [[ALIGN]]
// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+TEST_UNINIT(paddedpacked, paddedpacked);
+// CHECK-LABEL: @test_paddedpacked_uninit()
+// CHECK: %uninit = alloca %struct.paddedpacked, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpacked_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddedpacked_uninit.uninit
+// PATTERN-O1: %[[C:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 0
+// PATTERN-O1 store i8 -86, i8* %[[C]], align
+// PATTERN-O1: %[[I:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 1
+// PATTERN-O1: store i32 -1431655766, i32* %[[I]], align
+
+// ZERO-LABEL: @test_paddedpacked_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpacked, paddedpacked);
+// CHECK-LABEL: @test_paddedpacked_braces()
+// CHECK: %braces = alloca %struct.paddedpacked, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 5, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpacked, paddedpacked, { 42, 13371337 });
+// CHECK-LABEL: @test_paddedpacked_custom()
+// CHECK: %custom = alloca %struct.paddedpacked, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddedpacked_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddedpackedarray, paddedpackedarray);
+// CHECK-LABEL: @test_paddedpackedarray_uninit()
+// CHECK: %uninit = alloca %struct.paddedpackedarray, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpackedarray_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddedpackedarray_uninit.uninit
+// PATTERN-O1: getelementptr
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}i8 -86, i64 10
+// ZERO-LABEL: @test_paddedpackedarray_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpackedarray, paddedpackedarray);
+// CHECK-LABEL: @test_paddedpackedarray_braces()
+// CHECK: %braces = alloca %struct.paddedpackedarray, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 10, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpackedarray, paddedpackedarray, { {{ 42, 13371337 }, { 43, 13371338 }} });
+// CHECK-LABEL: @test_paddedpackedarray_custom()
+// CHECK: %custom = alloca %struct.paddedpackedarray, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddedpackedarray_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unpackedinpacked, unpackedinpacked);
+// CHECK-LABEL: @test_unpackedinpacked_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}}, i64 9, i1 false)
+
+TEST_UNINIT(paddednested, paddednested);
+// CHECK-LABEL: @test_paddednested_uninit()
+// CHECK: %uninit = alloca %struct.paddednested, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddednested_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddednested_uninit.uninit
+// PATTERN-O1: getelementptr
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}, i8 -86, i64 16
+// ZERO-LABEL: @test_paddednested_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddednested, paddednested);
+// CHECK-LABEL: @test_paddednested_braces()
+// CHECK: %braces = alloca %struct.paddednested, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddednested, paddednested, { { 42, 13371337 }, { 43, 13371338 } });
+// CHECK-LABEL: @test_paddednested_custom()
+// CHECK: %custom = alloca %struct.paddednested, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddednested_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddedpackednested, paddedpackednested);
+// CHECK-LABEL: @test_paddedpackednested_uninit()
+// CHECK: %uninit = alloca %struct.paddedpackednested, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpackednested_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddedpackednested_uninit.uninit
+// PATTERN-O1: getelementptr
+// PATTERN-O1: call void @llvm.memset.p0i8.i64(i8* nonnull align 1 %0, i8 -86, i64 10, i1 false
+// ZERO-LABEL: @test_paddedpackednested_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpackednested, paddedpackednested);
+// CHECK-LABEL: @test_paddedpackednested_braces()
+// CHECK: %braces = alloca %struct.paddedpackednested, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 10, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpackednested, paddedpackednested, { { 42, 13371337 }, { 43, 13371338 } });
+// CHECK-LABEL: @test_paddedpackednested_custom()
+// CHECK: %custom = alloca %struct.paddedpackednested, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddedpackednested_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
TEST_UNINIT(bitfield, bitfield);
// CHECK-LABEL: @test_bitfield_uninit()
// CHECK: %uninit = alloca %struct.bitfield, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_bitfield_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_bitfield_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, i32* %uninit, align 4
TEST_BRACES(bitfield, bitfield);
// CHECK-LABEL: @test_bitfield_braces()
@@ -653,9 +864,11 @@ TEST_UNINIT(bitfieldaligned, bitfieldaligned);
// CHECK: %uninit = alloca %struct.bitfieldaligned, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_bitfieldaligned_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_bitfieldaligned_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(bitfieldaligned, bitfieldaligned);
// CHECK-LABEL: @test_bitfieldaligned_braces()
@@ -699,9 +912,11 @@ TEST_UNINIT(arraytail, arraytail);
// CHECK: %uninit = alloca %struct.arraytail, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_arraytail_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, {{.*}} align 4
// ZERO-LABEL: @test_arraytail_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(arraytail, arraytail);
// CHECK-LABEL: @test_arraytail_braces()
@@ -724,16 +939,15 @@ TEST_UNINIT(int0, int[0]);
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_int0_uninit()
// PATTERN: %uninit = alloca [0 x i32], align
-// PATTERN-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-O0-NEXT: call void @{{.*}}used{{.*}}%uninit)
// ZERO-LABEL: @test_int0_uninit()
// ZERO: %uninit = alloca [0 x i32], align
-// ZERO-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// ZERO-O0-NEXT: call void @{{.*}}used{{.*}}%uninit)
TEST_BRACES(int0, int[0]);
// CHECK-LABEL: @test_int0_braces()
// CHECK: %braces = alloca [0 x i32], align [[ALIGN:[0-9]*]]
// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 0, i1 false)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
TEST_UNINIT(int1, int[1]);
@@ -741,9 +955,11 @@ TEST_UNINIT(int1, int[1]);
// CHECK: %uninit = alloca [1 x i32], align [[ALIGN:[0-9]*]]
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_int1_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, {{.*}} align 4
// ZERO-LABEL: @test_int1_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(int1, int[1]);
// CHECK-LABEL: @test_int1_braces()
@@ -787,9 +1003,11 @@ TEST_UNINIT(bool4, bool[4]);
// CHECK: %uninit = alloca [4 x i8], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_bool4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_bool4_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, i32* %uninit, align 4
TEST_BRACES(bool4, bool[4]);
// CHECK-LABEL: @test_bool4_braces()
@@ -806,13 +1024,20 @@ TEST_CUSTOM(bool4, bool[4], { true, true, true, true });
// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
TEST_UNINIT(intptr4, int*[4]);
-// CHECK-LABEL: @test_intptr4_uninit()
-// CHECK: %uninit = alloca [4 x i32*], align
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
-// PATTERN-LABEL: @test_intptr4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_intptr4_uninit.uninit
-// ZERO-LABEL: @test_intptr4_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// CHECK-LABEL: @test_intptr4_uninit()
+// CHECK: %uninit = alloca [4 x i32*], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-O1-LABEL: @test_intptr4_uninit()
+// PATTERN-O1: %1 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 0
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %1, align 16
+// PATTERN-O1-NEXT: %2 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 1
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %2, align 8
+// PATTERN-O1-NEXT: %3 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 2
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %3, align 16
+// PATTERN-O1-NEXT: %4 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 3
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %4, align 8
+// ZERO-LABEL: @test_intptr4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
TEST_BRACES(intptr4, int*[4]);
// CHECK-LABEL: @test_intptr4_braces()
@@ -833,7 +1058,9 @@ TEST_UNINIT(tailpad4, tailpad[4]);
// CHECK: %uninit = alloca [4 x %struct.tailpad], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_tailpad4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// PATTERN-O1: bitcast
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}0, i8 -86, i64 16
// ZERO-LABEL: @test_tailpad4_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -856,7 +1083,7 @@ TEST_UNINIT(tailpad9, tailpad[9]);
// CHECK: %uninit = alloca [9 x %struct.tailpad], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_tailpad9_uninit()
-// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// PATTERN-O0: call void @llvm.memset{{.*}}, i8 -86,
// ZERO-LABEL: @test_tailpad9_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -907,7 +1134,9 @@ TEST_UNINIT(atomicnotlockfree, _Atomic(notlockfree));
// CHECK: %uninit = alloca %struct.notlockfree, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_atomicnotlockfree_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// PATTERN-O1: bitcast
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}, i8 -86, i64 32
// ZERO-LABEL: @test_atomicnotlockfree_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -916,28 +1145,36 @@ TEST_UNINIT(atomicpadded, _Atomic(padded));
// CHECK: %uninit = alloca %struct.padded, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_atomicpadded_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_atomicpadded_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_UNINIT(atomictailpad, _Atomic(tailpad));
// CHECK-LABEL: @test_atomictailpad_uninit()
// CHECK: %uninit = alloca %struct.tailpad, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_atomictailpad_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
// ZERO-LABEL: @test_atomictailpad_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
-
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, i32* %uninit, align 4
TEST_UNINIT(complexfloat, _Complex float);
// CHECK-LABEL: @test_complexfloat_uninit()
// CHECK: %uninit = alloca { float, float }, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_complexfloat_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// PATTERN-O1: %[[F1:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 0
+// PATTERN-O1 store float 0xFFFFFFFFE0000000, float* %[[F1]], align
+// PATTERN-O1: %[[F2:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 1
+// PATTERN-O1: store float 0xFFFFFFFFE0000000, float* %[[F2]], align
+
// ZERO-LABEL: @test_complexfloat_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(complexfloat, _Complex float);
// CHECK-LABEL: @test_complexfloat_braces()
@@ -962,7 +1199,7 @@ TEST_UNINIT(complexdouble, _Complex double);
// CHECK: %uninit = alloca { double, double }, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_complexdouble_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
// ZERO-LABEL: @test_complexdouble_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -1005,9 +1242,10 @@ TEST_UNINIT(semivolatile, semivolatile);
// CHECK: %uninit = alloca %struct.semivolatile, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_semivolatile_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
// ZERO-LABEL: @test_semivolatile_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(semivolatile, semivolatile);
// CHECK-LABEL: @test_semivolatile_braces()
@@ -1019,9 +1257,10 @@ TEST_BRACES(semivolatile, semivolatile);
TEST_CUSTOM(semivolatile, semivolatile, { 0x44444444, 0x44444444 });
// CHECK-LABEL: @test_semivolatile_custom()
// CHECK: %custom = alloca %struct.semivolatile, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i64 4919131752989213764, i64* %custom, align 8
TEST_UNINIT(semivolatileinit, semivolatileinit);
// CHECK-LABEL: @test_semivolatileinit_uninit()
@@ -1054,9 +1293,10 @@ TEST_UNINIT(base, base);
// CHECK-NEXT: call void @{{.*}}base{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_base_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
// ZERO-LABEL: @test_base_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, {{.*}} align 8
TEST_BRACES(base, base);
// CHECK-LABEL: @test_base_braces()
@@ -1072,9 +1312,10 @@ TEST_UNINIT(derived, derived);
// CHECK-NEXT: call void @{{.*}}derived{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_derived_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
// ZERO-LABEL: @test_derived_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, {{.*}} align 8
TEST_BRACES(derived, derived);
// CHECK-LABEL: @test_derived_braces()
@@ -1090,7 +1331,7 @@ TEST_UNINIT(virtualderived, virtualderived);
// CHECK-NEXT: call void @{{.*}}virtualderived{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_virtualderived_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
// ZERO-LABEL: @test_virtualderived_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -1108,9 +1349,10 @@ TEST_UNINIT(matching, matching);
// CHECK: %uninit = alloca %union.matching, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_matching_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
// ZERO-LABEL: @test_matching_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(matching, matching);
// CHECK-LABEL: @test_matching_braces()
@@ -1122,18 +1364,22 @@ TEST_BRACES(matching, matching);
TEST_CUSTOM(matching, matching, { .f = 0xf00f });
// CHECK-LABEL: @test_matching_custom()
// CHECK: %custom = alloca %union.matching, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: getelementptr
+// CHECK-O1: store i32 1198526208, i32* {{.*}}, align 4
TEST_UNINIT(matchingreverse, matchingreverse);
// CHECK-LABEL: @test_matchingreverse_uninit()
// CHECK: %uninit = alloca %union.matchingreverse, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_matchingreverse_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// PATTERN-O1: store float 0xFFFFFFFFE0000000
// ZERO-LABEL: @test_matchingreverse_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(matchingreverse, matchingreverse);
// CHECK-LABEL: @test_matchingreverse_braces()
@@ -1145,18 +1391,20 @@ TEST_BRACES(matchingreverse, matchingreverse);
TEST_CUSTOM(matchingreverse, matchingreverse, { .i = 0xf00f });
// CHECK-LABEL: @test_matchingreverse_custom()
// CHECK: %custom = alloca %union.matchingreverse, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i32 61455, i32* %1, align 4
TEST_UNINIT(unmatched, unmatched);
// CHECK-LABEL: @test_unmatched_uninit()
// CHECK: %uninit = alloca %union.unmatched, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_unmatched_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
// ZERO-LABEL: @test_unmatched_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(unmatched, unmatched);
// CHECK-LABEL: @test_unmatched_braces()
@@ -1168,18 +1416,20 @@ TEST_BRACES(unmatched, unmatched);
TEST_CUSTOM(unmatched, unmatched, { .i = 0x3badbeef });
// CHECK-LABEL: @test_unmatched_custom()
// CHECK: %custom = alloca %union.unmatched, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i32 1001242351, i32* {{.*}}, align 4
TEST_UNINIT(unmatchedreverse, unmatchedreverse);
// CHECK-LABEL: @test_unmatchedreverse_uninit()
// CHECK: %uninit = alloca %union.unmatchedreverse, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_unmatchedreverse_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
// ZERO-LABEL: @test_unmatchedreverse_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(unmatchedreverse, unmatchedreverse);
// CHECK-LABEL: @test_unmatchedreverse_braces()
@@ -1191,18 +1441,21 @@ TEST_BRACES(unmatchedreverse, unmatchedreverse);
TEST_CUSTOM(unmatchedreverse, unmatchedreverse, { .c = 42 });
// CHECK-LABEL: @test_unmatchedreverse_custom()
// CHECK: %custom = alloca %union.unmatchedreverse, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// PATTERN-O1: store i32 -1431655894, i32* {{.*}}, align 4
+// ZERO-O1: store i32 42, i32* {{.*}}, align 4
TEST_UNINIT(unmatchedfp, unmatchedfp);
// CHECK-LABEL: @test_unmatchedfp_uninit()
// CHECK: %uninit = alloca %union.unmatchedfp, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_unmatchedfp_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
// ZERO-LABEL: @test_unmatchedfp_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, {{.*}} align 8
TEST_BRACES(unmatchedfp, unmatchedfp);
// CHECK-LABEL: @test_unmatchedfp_braces()
@@ -1214,19 +1467,19 @@ TEST_BRACES(unmatchedfp, unmatchedfp);
TEST_CUSTOM(unmatchedfp, unmatchedfp, { .d = 3.1415926535897932384626433 });
// CHECK-LABEL: @test_unmatchedfp_custom()
// CHECK: %custom = alloca %union.unmatchedfp, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
-
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i64 4614256656552045848, i64* %1, align 8
TEST_UNINIT(emptyenum, emptyenum);
// CHECK-LABEL: @test_emptyenum_uninit()
// CHECK: %uninit = alloca i32, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_emptyenum_uninit()
-// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_emptyenum_uninit()
-// ZERO: store i32 0, i32* %braces, align 4
+// ZERO: store i32 0, i32* %uninit, align 4
TEST_BRACES(emptyenum, emptyenum);
// CHECK-LABEL: @test_emptyenum_braces()
@@ -1245,9 +1498,9 @@ TEST_UNINIT(smallenum, smallenum);
// CHECK: %uninit = alloca i32, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_smallenum_uninit()
-// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_smallenum_uninit()
-// ZERO: store i32 0, i32* %braces, align 4
+// ZERO: store i32 0, i32* %uninit, align 4
TEST_BRACES(smallenum, smallenum);
// CHECK-LABEL: @test_smallenum_braces()
diff --git a/test/CodeGenCXX/builtin-calling-conv.cpp b/test/CodeGenCXX/builtin-calling-conv.cpp
new file mode 100644
index 0000000000..6fdeca0d2c
--- /dev/null
+++ b/test/CodeGenCXX/builtin-calling-conv.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-linux-pc -DREDECL -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX
+// RUN: %clang_cc1 -triple spir-unknown-unknown -DREDECL -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR
+// RUN: %clang_cc1 -triple x86_64-linux-pc -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX
+// RUN: %clang_cc1 -triple spir-unknown-unknown -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR
+
+#ifdef REDECL
+namespace std {
+#ifdef SPIR
+using size_t = unsigned int;
+#else
+using size_t = unsigned long;
+#endif // SPIR
+} // namespace std
+
+float __builtin_atan2f(float, float);
+void *operator new(std::size_t);
+#endif // REDECL
+
+void foo();
+
+void user() {
+ int i;
+ ::operator new(5);
+ (void)__builtin_atan2f(1.1, 2.2);
+ foo();
+}
+
+// LINUX: define void @_Z4userv()
+// LINUX: call i8* @_Znwm
+// LINUX: call float @atan2f
+// LINUX: call void @_Z3foov
+// LINUX: declare noalias i8* @_Znwm(i64)
+// LINUX: declare float @atan2f(float, float)
+// LINUX: declare void @_Z3foov()
+
+// SPIR: define spir_func void @_Z4userv()
+// SPIR: call spir_func i8* @_Znwj
+// SPIR: call spir_func float @atan2f
+// SPIR: call spir_func void @_Z3foov
+// SPIR: declare spir_func noalias i8* @_Znwj(i32)
+// SPIR: declare spir_func float @atan2f(float, float)
+// SPIR: declare spir_func void @_Z3foov()
diff --git a/test/CodeGenCXX/builtin-is-constant-evaluated.cpp b/test/CodeGenCXX/builtin-is-constant-evaluated.cpp
new file mode 100644
index 0000000000..74f414d237
--- /dev/null
+++ b/test/CodeGenCXX/builtin-is-constant-evaluated.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -std=c++2a -o %t.ll
+// RUN: FileCheck -check-prefix=CHECK-FN-CG -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-STATIC -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-DYN -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-ARR -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-FOLD -input-file=%t.ll %s
+
+using size_t = decltype(sizeof(int));
+
+#define CONSTINIT __attribute__((require_constant_initialization))
+
+extern "C" [[noreturn]] void BOOM();
+extern "C" void OK();
+extern "C" size_t RANDU();
+
+namespace std {
+inline constexpr bool is_constant_evaluated() noexcept {
+ return __builtin_is_constant_evaluated();
+}
+} // namespace std
+
+// CHECK-FN-CG-LABEL: define zeroext i1 @_Z3foov()
+// CHECK-FN-CG: ret i1 false
+bool foo() {
+ return __builtin_is_constant_evaluated();
+}
+
+// CHECK-FN-CG-LABEL: define linkonce_odr i32 @_Z1fv()
+constexpr int f() {
+ // CHECK-FN-CG: store i32 13, i32* %n, align 4
+ // CHECK-FN-CG: store i32 17, i32* %m, align 4
+ // CHECK-FN-CG: %1 = load i32, i32* %m, align 4
+ // CHECK-FN-CG: %add = add nsw i32 %1, 13
+ // CHECK-FN-CG: ret i32 %add
+ const int n = __builtin_is_constant_evaluated() && std::is_constant_evaluated() ? 13 : 17; // n == 13
+ int m = __builtin_is_constant_evaluated() ? 13 : 17; // m might be 13 or 17 (see below)
+ char arr[n] = {}; // char[13]
+ return m + int(sizeof(arr));
+}
+
+// CHECK-STATIC-DAG: @p = global i32 26,
+CONSTINIT int p = f(); // f().m == 13; initialized to 26
+// CHECK-STATIC-DAG: @p2 = global i32 26,
+int p2 = f(); // same result without CONSTINIT
+
+// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init()
+// CHECK-DYN: %0 = load i32, i32* @p, align 4
+// CHECK-DYN-NEXT: %call = call i32 @_Z1fv()
+// CHECK-DYN-NEXT: %add = add nsw i32 %0, %call
+// CHECK-DYN-NEXT: store i32 %add, i32* @q, align 4
+// CHECK-DYN-NEXT: ret void
+int q = p + f(); // m == 17 for this call; initialized to 56
+
+int y;
+
+// CHECK-STATIC-DAG: @b = global i32 2,
+CONSTINIT int b = __builtin_is_constant_evaluated() ? 2 : y; // static initialization to 2
+
+// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init.1()
+// CHECK-DYN: %0 = load i32, i32* @y, align 4
+// CHECK-DYN: %1 = load i32, i32* @y, align 4
+// CHECK-DYN-NEXT: %add = add
+// CHECK-DYN-NEXT: store i32 %add, i32* @c,
+int c = y + (__builtin_is_constant_evaluated() ? 2 : y); // dynamic initialization to y+y
+
+// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init.2()
+// CHECK-DYN: store i32 1, i32* @_ZL1a, align 4
+// CHECK-DYN-NEXT: ret void
+const int a = __builtin_is_constant_evaluated() ? y : 1; // dynamic initialization to 1
+const int *a_sink = &a;
+
+// CHECK-ARR-LABEL: define void @_Z13test_arr_exprv
+void test_arr_expr() {
+ // CHECK-ARR: %x1 = alloca [101 x i8],
+ char x1[std::is_constant_evaluated() && __builtin_is_constant_evaluated() ? 101 : 1];
+
+ // CHECK-ARR: %x2 = alloca [42 x i8],
+ char x2[std::is_constant_evaluated() && __builtin_is_constant_evaluated() ? 42 : RANDU()];
+
+ // CHECK-ARR: call i8* @llvm.stacksave()
+ // CHECK-ARR: %vla = alloca i8, i64 13,
+ char x3[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? RANDU() : 13];
+}
+
+// CHECK-ARR-LABEL: define void @_Z17test_new_arr_exprv
+void test_new_arr_expr() {
+ // CHECK-ARR: call i8* @_Znam(i64 17)
+ new char[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? 1 : 17];
+}
+
+// CHECK-FOLD-LABEL: @_Z31test_constant_initialized_locali(
+bool test_constant_initialized_local(int k) {
+ // CHECK-FOLD: store i8 1, i8* %n,
+ // CHECK-FOLD: store volatile i8* %n, i8** %p,
+ const bool n = __builtin_is_constant_evaluated() && std::is_constant_evaluated();
+ const bool *volatile p = &n;
+ return *p;
+}
+
+// CHECK-FOLD-LABEL: define void @_Z21test_ir_constant_foldv()
+void test_ir_constant_fold() {
+ // CHECK-FOLD-NEXT: entry:
+ // CHECK-FOLD-NEXT: call void @OK()
+ // CHECK-FOLD-NEXT: call void @OK()
+ // CHECK-FOLD-NEXT: ret void
+ if (std::is_constant_evaluated()) {
+ BOOM();
+ } else {
+ OK();
+ }
+ std::is_constant_evaluated() ? BOOM() : OK();
+}
+
+// CHECK-STATIC-DAG: @ir = constant i32* @i_constant,
+int i_constant;
+int i_not_constant;
+int &ir = __builtin_is_constant_evaluated() ? i_constant : i_not_constant;
+
+// CHECK-FOLD-LABEL: @_Z35test_ref_initialization_local_scopev()
+void test_ref_initialization_local_scope() {
+ const int i_constant = 42;
+ const int i_non_constant = 101;
+ // CHECK-FOLD: store i32* %i_non_constant, i32** %r,
+ const int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant;
+}
+
+// CHECK-FOLD-LABEL: @_Z22test_ref_to_static_varv()
+void test_ref_to_static_var() {
+ static int i_constant = 42;
+ static int i_non_constant = 101;
+ // CHECK-FOLD: store i32* @_ZZ22test_ref_to_static_varvE10i_constant, i32** %r,
+ int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant;
+} \ No newline at end of file
diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp
index 33c714e9e1..242cba7bc1 100644
--- a/test/CodeGenCXX/builtins.cpp
+++ b/test/CodeGenCXX/builtins.cpp
@@ -29,7 +29,7 @@ long y = __builtin_abs(-2l);
extern const char char_memchr_arg[32];
char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32);
-// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i32 0, i32 0), i32 123, i64 32)
+// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i64 0, i64 0), i32 123, i64 32)
int constexpr_overflow_result() {
constexpr int x = 1;
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 0e8d4fa51a..ba72af038a 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -533,6 +533,7 @@ namespace NothrowNew {
// CHECK: [[nonnull]]:
// CHECK: llvm.objectsize
+ // CHECK: icmp uge i64 {{.*}}, 123456,
// CHECK: br i1
//
// CHECK: call {{.*}}__ubsan_handle_type_mismatch
@@ -550,6 +551,7 @@ namespace NothrowNew {
// CHECK: [[nonnull]]:
// CHECK: llvm.objectsize
+ // CHECK: icmp uge i64 {{.*}}, 123456,
// CHECK: br i1
//
// CHECK: call {{.*}}__ubsan_handle_type_mismatch
@@ -561,6 +563,47 @@ namespace NothrowNew {
// CHECK: ret
return new (nothrow{}) X[123456];
}
+
+ // CHECK-LABEL: define{{.*}}throwing_new
+ void *throwing_new(int size) {
+ // CHECK: icmp ne i8*{{.*}}, null
+ // CHECK: %[[size:.*]] = mul
+ // CHECK: llvm.objectsize
+ // CHECK: icmp uge i64 {{.*}}, %[[size]],
+ // CHECK: %[[ok:.*]] = and
+ // CHECK: br i1 %[[ok]], label %[[good:.*]], label %[[bad:[^,]*]]
+ //
+ // CHECK: [[bad]]:
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: [[good]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new char[size];
+ }
+
+ // CHECK-LABEL: define{{.*}}nothrow_new_zero_size
+ void *nothrow_new_zero_size() {
+ // CHECK: %[[nonnull:.*]] = icmp ne i8*{{.*}}, null
+ // CHECK-NOT: llvm.objectsize
+ // CHECK: br i1 %[[nonnull]], label %[[good:.*]], label %[[bad:[^,]*]]
+ //
+ // CHECK: [[bad]]:
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: [[good]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new char[0];
+ }
+
+ // CHECK-LABEL: define{{.*}}throwing_new_zero_size
+ void *throwing_new_zero_size() {
+ // Nothing to check here.
+ // CHECK-NOT: __ubsan_handle_type_mismatch
+ return new (nothrow{}) char[0];
+ // CHECK: ret
+ }
}
struct ThisAlign {
diff --git a/test/CodeGenCXX/char8_t.cpp b/test/CodeGenCXX/char8_t.cpp
index f24f12d6df..1016d6346b 100644
--- a/test/CodeGenCXX/char8_t.cpp
+++ b/test/CodeGenCXX/char8_t.cpp
@@ -1,9 +1,11 @@
-// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s
-// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - -verify
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - | FileCheck %s --check-prefix=MSABI
-// CHECK: define void @_Z1fDu(
-void f(char8_t c) {} // expected-error {{cannot mangle this built-in char8_t type yet}}
+// ITANIUM: define void @_Z1fDu(
+// MSABI: define {{.*}}void @"?f@@YAX_Q@Z"(
+void f(char8_t c) {}
-// CHECK: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE
+// ITANIUM: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE(
+// MSABI: define weak_odr {{.*}}void @"??$g@H@@YAXPEB_Q@Z"(
template<typename T> void g(decltype(T() + u8"foo" + u8'r')) {}
template void g<int>(const char8_t*);
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 9fb4ba5fe1..0873486093 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -554,7 +554,7 @@ namespace InitFromConst {
// CHECK: call void @_ZN13InitFromConst7consumeIMNS_1SEiEEvT_(i64 0)
consume(mp);
- // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0))
+ // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZN13InitFromConstL1aE, i64 0, i64 0))
consume(a);
}
}
diff --git a/test/CodeGenCXX/constructor-direct-call.cpp b/test/CodeGenCXX/constructor-direct-call.cpp
index bcddc0fa7a..0ed9cd9027 100644
--- a/test/CodeGenCXX/constructor-direct-call.cpp
+++ b/test/CodeGenCXX/constructor-direct-call.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc19.11.0 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK
class Test1 {
public:
@@ -9,7 +10,8 @@ void f1() {
Test1 var;
var.Test1::Test1();
- // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 4, i1 false)
+ // CHECK32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 4, i1 false)
+ // CHECK64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i64 4, i1 false)
var.Test1::Test1(var);
}
@@ -22,13 +24,16 @@ public:
void f2() {
// CHECK: %var = alloca %class.Test2, align 4
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK64-NEXT: %call = call %class.Test2* @"??0Test2@@QEAA@XZ"(%class.Test2* %var)
Test2 var;
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK64-NEXT: %call1 = call %class.Test2* @"??0Test2@@QEAA@XZ"(%class.Test2* %var)
var.Test2::Test2();
- // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 8, i1 false)
+ // CHECK32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 8, i1 false)
+ // CHECK64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i64 8, i1 false)
var.Test2::Test2(var);
}
@@ -45,15 +50,19 @@ public:
};
void f3() {
- // CHECK: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK32: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK64: %call = call %class.Test3* @"??0Test3@@QEAA@XZ"(%class.Test3* %var)
Test3 var;
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var2)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var2)
+ // CHECK64-NEXT: %call1 = call %class.Test3* @"??0Test3@@QEAA@XZ"(%class.Test3* %var2)
Test3 var2;
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK64-NEXT: %call2 = call %class.Test3* @"??0Test3@@QEAA@XZ"(%class.Test3* %var)
var.Test3::Test3();
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
+ // CHECK64-NEXT: %call3 = call %class.Test3* @"??0Test3@@QEAA@AEBV0@@Z"(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
var.Test3::Test3(var2);
}
diff --git a/test/CodeGenCXX/cxx11-special-members.cpp b/test/CodeGenCXX/cxx11-special-members.cpp
index 96109ba5ba..b1cadaf3d4 100644
--- a/test/CodeGenCXX/cxx11-special-members.cpp
+++ b/test/CodeGenCXX/cxx11-special-members.cpp
@@ -40,7 +40,7 @@ void f3() {
D b;
}
// Trivial default ctor, might or might not be defined, but we must not expect
-// someone else ot define it.
+// someone else to define it.
// CHECK-NOT: declare {{.*}} @_ZN1CILi0EEC1Ev
// CHECK: define {{.*}} @_ZN1DC1Ev
diff --git a/test/CodeGenCXX/cxx11-thread-local-visibility.cpp b/test/CodeGenCXX/cxx11-thread-local-visibility.cpp
new file mode 100644
index 0000000000..b46d41d7c9
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-thread-local-visibility.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=DARWIN %s
+
+// Regression test for PR40327
+
+// LINUX: @default_tls = thread_local global i32
+// LINUX: @hidden_tls = hidden thread_local global i32
+// LINUX: define weak_odr hidden i32* @_ZTW11default_tls()
+// LINUX: define weak_odr hidden i32* @_ZTW10hidden_tls()
+//
+// DARWIN: @default_tls = internal thread_local global i32
+// DARWIN: @hidden_tls = internal thread_local global i32
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW11default_tls()
+// DARWIN: define hidden cxx_fast_tlscc i32* @_ZTW10hidden_tls()
+
+__attribute__((visibility("default"))) thread_local int default_tls;
+__attribute__((visibility("hidden"))) thread_local int hidden_tls;
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
index 156c4f5919..de941af1af 100644
--- a/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -318,7 +318,7 @@ void set_anon_i() {
// CHECK-NOT: call void @[[V_M_INIT]]()
-// LIUNX: define weak_odr hidden i32* @_ZTW1a() {
+// LINUX: define weak_odr hidden i32* @_ZTW1a()
// DARWIN: define cxx_fast_tlscc i32* @_ZTW1a()
// LINUX: call void @_ZTH1a()
// DARWIN: call cxx_fast_tlscc void @_ZTH1a()
diff --git a/test/CodeGenCXX/cxx11-user-defined-literal.cpp b/test/CodeGenCXX/cxx11-user-defined-literal.cpp
index 05c04b1b41..c1eab634b1 100644
--- a/test/CodeGenCXX/cxx11-user-defined-literal.cpp
+++ b/test/CodeGenCXX/cxx11-user-defined-literal.cpp
@@ -16,8 +16,8 @@ template<char...Cs> S operator"" _t() { return S(); }
// CHECK: @[[s_0xffffeeee:.*]] = {{.*}} constant [11 x i8] c"0xffffeeee\00"
void f() {
- // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_foo]], i32 0, i32 0), i64 3)
- // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_bar]], i32 0, i32 0), i64 3)
+ // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_foo]], i64 0, i64 0), i64 3)
+ // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_bar]], i64 0, i64 0), i64 3)
// CHECK: call void @_Zli2_yw({{.*}} 97)
// CHECK: call void @_Zli2_zy({{.*}} 42)
// CHECK: call void @_Zli2_fe({{.*}} x86_fp80 0xK3FFF8000000000000000)
@@ -28,9 +28,9 @@ void f() {
// CHECK: call void @_ZN1SD1Ev({{.*}})
"foo"_x, "bar"_x, L'a'_y, 42_z, 1.0_f;
- // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_123]], i32 0, i32 0))
- // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_4_9]], i32 0, i32 0))
- // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[s_0xffffeeee]], i32 0, i32 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_123]], i64 0, i64 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_4_9]], i64 0, i64 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[s_0xffffeeee]], i64 0, i64 0))
// CHECK: call void @_ZN1SD1Ev({{.*}})
// CHECK: call void @_ZN1SD1Ev({{.*}})
// CHECK: call void @_ZN1SD1Ev({{.*}})
@@ -59,11 +59,11 @@ void h() {
// CHECK: call void @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 42)
// CHECK: define {{.*}} @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32
-// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3)
+// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i64 0, i64 0), i64 3)
// CHECK: call void @_ZN1SclEi
// CHECK: call void @_ZN1SD1Ev
// CHECK: define {{.*}} @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32
-// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3)
+// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i64 0, i64 0), i64 3)
// CHECK: call void @_ZN1SclEi
// CHECK: call void @_ZN1SD1Ev
diff --git a/test/CodeGenCXX/cxx1y-init-captures-eh.cpp b/test/CodeGenCXX/cxx1y-init-captures-eh.cpp
new file mode 100644
index 0000000000..70103dccb1
--- /dev/null
+++ b/test/CodeGenCXX/cxx1y-init-captures-eh.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -fexceptions -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
+
+struct S {
+ S();
+ ~S();
+};
+
+struct T {
+ T() noexcept;
+ ~T();
+ int n;
+};
+
+// CHECK-LABEL: define void @_Z1fv(
+void f() {
+ // CHECK: call void @_ZN1SC1Ev(
+ // CHECK: invoke void @__cxa_throw
+ //
+ // Ensure we call the lambda destructor here, and do not call the destructor
+ // for the capture.
+ // CHECK: landingpad
+ // CHECK-NOT: _ZN1SD
+ // CHECK: call void @"_ZZ1fvEN3$_0D1Ev"(
+ // CHECK-NOT: _ZN1SD
+ // CHECK: resume
+ [s = S()] {}, throw 0;
+
+ // CHECK: }
+}
+
+// CHECK-LABEL: define void @_Z1gv(
+void g() {
+ // CHECK: call void @_ZN1SC1Ev(
+ // CHECK: invoke void @__cxa_throw
+ //
+ // Ensure we call the lambda destructor here, and do not call the destructor
+ // for the capture.
+ // CHECK: landingpad
+ // CHECK-NOT: @"_ZZ1gvEN3$_0D1Ev"(
+ // CHECK: call void @_ZN1SD1Ev(
+ // CHECK-NOT: @"_ZZ1gvEN3$_0D1Ev"(
+ // CHECK: resume
+ [s = S(), t = (throw 0, 1)] {};
+
+ // CHECK: }
+}
+
+void x() noexcept;
+void y() noexcept;
+
+// CHECK-LABEL: define void @_Z1hbb(
+void h(bool b1, bool b2) {
+ // CHECK: {{.*}} = alloca i1,
+ // CHECK: %[[S_ISACTIVE:.*]] = alloca i1,
+ // CHECK: {{.*}} = alloca i1,
+
+ // lambda init: s and t, branch on b1
+ // CHECK: call void @_ZN1SC1Ev(
+ // CHECK: store i1 true, i1* %[[S_ISACTIVE]], align 1
+ // CHECK: call void @_ZN1TC1Ev(
+ // CHECK: br i1
+
+ // throw 1
+ // CHECK: invoke void @__cxa_throw
+
+ // completion of lambda init, branch on b2
+ // CHECK: store i32 42,
+ // CHECK: store i1 false, i1* %[[S_ISACTIVE]], align 1
+ // CHECK: br i1
+
+ // throw 2
+ // CHECK: invoke void @__cxa_throw
+
+ // end of full-expression
+ // CHECK: call void @_Z1xv(
+ // CHECK: call void @"_ZZ1hbbEN3$_2D1Ev"(
+ // CHECK: call void @_ZN1TD1Ev(
+ // CHECK: call void @_Z1yv(
+ // CHECK: ret void
+
+ // cleanups for throw 1
+ // CHECK: landingpad
+ // CHECK-NOT: @"_ZZ1hbbEN3$_2D1Ev"(
+ // CHECK: br
+
+ // cleanups for throw 2
+ // CHECK: landingpad
+ // CHECK: call void @"_ZZ1hbbEN3$_2D1Ev"(
+ // CHECK: br
+
+ // common cleanup code
+ // CHECK: call void @_ZN1TD1Ev(
+ // CHECK: load i1, i1* %[[S_ISACTIVE]],
+ // CHECK: br i1
+
+ // CHECK: call void @_ZN1SD1Ev(
+ // CHECK: br
+
+ // CHECK: resume
+ [s = S(), t = T().n, u = (b1 ? throw 1 : 42)] {}, (b2 ? throw 2 : 0), x();
+ y();
+
+ // CHECK: }
+}
diff --git a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
index bc775568aa..c77841cabc 100644
--- a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
@@ -6,21 +6,61 @@
// should be 'internal global' and not 'linkonce_odr global'.
template <typename T> int x = 42;
-
+// CHECK-DAG: @_Z1xIiE = linkonce_odr global
// CHECK-DAG: @_Z1xIZL3foovE3FooE = internal global
+// 'static' affects the linkage of the global
+template <typename T> static int y = 42;
+// CHECK-DAG: @_ZL1yIiE = internal global
+// CHECK-DAG: @_ZL1yIZL3foovE3FooE = internal global
+
+// 'const' does not
+template <typename T> const int z = 42;
+// CHECK-DAG: @_Z1zIiE = linkonce_odr constant
+// CHECK-DAG: @_Z1zIZL3foovE3FooE = internal constant
+
+template <typename T> T t = 42;
+// CHECK-DAG: @_Z1tIiE = linkonce_odr global
+// CHECK-DAG: @_Z1tIKiE = linkonce_odr constant
+
+int mode;
+
// CHECK-DAG: define internal dereferenceable(4) i32* @_ZL3foov(
-static int &foo() {
+static const int &foo() {
struct Foo { };
-
- // CHECK-DAG: ret i32* @_Z1xIZL3foovE3FooE
- return x<Foo>;
+
+ switch (mode) {
+ case 0:
+ // CHECK-DAG: @_Z1xIiE
+ return x<int>;
+ case 1:
+ // CHECK-DAG: @_Z1xIZL3foovE3FooE
+ return x<Foo>;
+ case 2:
+ // CHECK-DAG: @_ZL1yIiE
+ return y<int>;
+ case 3:
+ // CHECK-DAG: @_ZL1yIZL3foovE3FooE
+ return y<Foo>;
+ case 4:
+ // CHECK-DAG: @_Z1zIiE
+ return z<int>;
+ case 5:
+ // CHECK-DAG: @_Z1zIZL3foovE3FooE
+ return z<Foo>;
+ case 6:
+ // CHECK-DAG: @_Z1tIiE
+ return t<int>;
+ case 7:
+ // CHECK-DAG: @_Z1tIKiE
+ return t<const int>;
+ }
}
#if !__has_feature(cxx_exceptions) // File A
// CHECKA-DAG: define dereferenceable(4) i32* @_Z3barv(
-int &bar() {
+const int &bar() {
// CHECKA-DAG: call dereferenceable(4) i32* @_ZL3foov()
return foo();
}
@@ -28,7 +68,7 @@ int &bar() {
#else // File B
// CHECKB-DAG: declare dereferenceable(4) i32* @_Z3barv(
-int &bar();
+const int &bar();
int main() {
// CHECKB-DAG: call dereferenceable(4) i32* @_Z3barv()
diff --git a/test/CodeGenCXX/cxx1z-init-statement.cpp b/test/CodeGenCXX/cxx1z-init-statement.cpp
index 5c05212c72..522ae56d50 100644
--- a/test/CodeGenCXX/cxx1z-init-statement.cpp
+++ b/test/CodeGenCXX/cxx1z-init-statement.cpp
@@ -5,7 +5,7 @@ void f() {
// CHECK: %[[A:.*]] = alloca i32, align 4
// CHECK-NEXT: store i32 5, i32* %[[A]], align 4
// CHECK-NEXT: %[[B:.*]] = load i32, i32* %[[A]], align 4
- // CHECK-NEXT %[[C:.*]] = icmp slt i32 %[[B]], 8
+ // CHECK-NEXT: %[[C:.*]] = icmp slt i32 %[[B]], 8
if (int a = 5; a < 8)
;
}
diff --git a/test/CodeGenCXX/cxx2a-compare.cpp b/test/CodeGenCXX/cxx2a-compare.cpp
index ef6bb5556e..31ae85bcdd 100644
--- a/test/CodeGenCXX/cxx2a-compare.cpp
+++ b/test/CodeGenCXX/cxx2a-compare.cpp
@@ -80,7 +80,7 @@ auto mem_ptr_test(MemPtrT x, MemPtrT y) {
// CHECK: %cmp.ptr.null = icmp eq [[TY]] %lhs.memptr.ptr, 0
// CHECK: %cmp.adj = icmp eq [[TY]] %lhs.memptr.adj, %rhs.memptr.adj
// CHECK: %[[OR:.*]] = or i1
- // CHECK-SAME %cmp.adj
+ // CHECK-SAME: %cmp.adj
// CHECK: %memptr.eq = and i1 %cmp.ptr, %[[OR]]
// CHECK: %sel.eq = select i1 %memptr.eq, i8 [[EQ]], i8 [[NE]]
// CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
diff --git a/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
index fd72d4a39c..e3c1535815 100644
--- a/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
+++ b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -1,24 +1,28 @@
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
-// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %ms_abi_triple 2>&1 | FileCheck %s --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple x86_64-pc-win32 2>&1 | FileCheck %s --check-prefix=MSABI
// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple -DBUILTIN 2>&1 | FileCheck %s --check-prefix=BUILTIN
-// MSABI: cannot mangle this three-way comparison operator yet
struct A {
void operator<=>(int);
};
// ITANIUM: define {{.*}}@_ZN1AssEi(
+// MSABI: define {{.*}}@"??__MA@@QEAAXH@Z"(
void A::operator<=>(int) {}
// ITANIUM: define {{.*}}@_Zssi1A(
+// MSABI: define {{.*}}@"??__M@YAXHUA@@@Z"(
void operator<=>(int, A) {}
int operator<=>(A, A);
// ITANIUM: define {{.*}}_Z1f1A(
+// MSABI: define {{.*}}@"?f@@YAHUA@@@Z"(
int f(A a) {
// ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_(
// ITANIUM: ret i32 %[[RET]]
+ // MSABI: %[[RET:.*]] = call {{.*}}"??__M@YAHUA@@0@Z"(
+ // MSABI: ret i32 %[[RET]]
return a <=> a;
}
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
index e06ef8dfda..b3e79c3792 100644
--- a/test/CodeGenCXX/debug-info-class.cpp
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -57,6 +57,11 @@ struct I : virtual H {};
struct J : I {};
J j;
+struct K {
+ virtual void func() {
+ }
+};
+
struct A {
int one;
static const int HdrSize = 52;
@@ -72,6 +77,8 @@ void f1() {
E y;
int i = F::i;
F::inner z;
+ K k;
+ k.func();
}
int main(int argc, char **argv) {
@@ -83,12 +90,12 @@ int main(int argc, char **argv) {
return 0;
}
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s
// CHECK98: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
// CHECK98-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
@@ -98,7 +105,8 @@ int main(int argc, char **argv) {
// CHECK: [[F:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "F"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1F"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "I"
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: ){{$}}
@@ -117,7 +125,8 @@ int main(int argc, char **argv) {
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
// CHECK-SAME: vtableHolder: [[C]]
-// CHECK-SAME: identifier: "_ZTS1C"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_S:![0-9]*]], [[C_DTOR:![0-9]*]]}
// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C"
// CHECK-SAME: DIFlagArtificial
@@ -129,16 +138,21 @@ int main(int argc, char **argv) {
// CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D"
// CHECK-NOT: size:
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1D"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1E"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "K"
+// CHECK-SAME: identifier: "_ZTS1K"
+// CHECK-SAME: ){{$}}
// CHECK: !DISubprogram(name: "func",{{.*}} scope: [[D]]
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
// CHECK-SAME: declaration: [[D_FUNC_DECL:![0-9]*]]
// CHECK: [[D_FUNC_DECL]] = !DISubprogram(name: "func",{{.*}} scope: [[D]]
-// CHECK-SAME: isDefinition: false
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "inner",{{.*}} line: 50
// CHECK-NOT: DIFlagFwdDecl
@@ -147,7 +161,8 @@ int main(int argc, char **argv) {
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "G"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1G"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: [[G_INNER_MEM]] = !{[[G_INNER_I:![0-9]*]]}
// CHECK: [[G_INNER_I]] = !DIDerivedType(tag: DW_TAG_member, name: "j"
// CHECK-SAME: baseType: ![[INT]]
@@ -155,5 +170,5 @@ int main(int argc, char **argv) {
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A"
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "HdrSize"
//
-// CHECK: ![[EXCEPTLOC]] = !DILocation(line: 84,
-// CHECK: ![[RETLOC]] = !DILocation(line: 83,
+// CHECK: ![[EXCEPTLOC]] = !DILocation(line: 91,
+// CHECK: ![[RETLOC]] = !DILocation(line: 90,
diff --git a/test/CodeGenCXX/debug-info-composite-triviality.cpp b/test/CodeGenCXX/debug-info-composite-triviality.cpp
new file mode 100644
index 0000000000..962b82743a
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-composite-triviality.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Cases to show some non-trivial types with flags combined with DIFlagNonTrivial and DIFlagTypePassByValue.
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Explicit",{{.*}}flags: DIFlagTypePassByValue | DIFlagNonTrivial
+struct Explicit {
+ explicit Explicit();
+ int a;
+} Explicit;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Struct",{{.*}}flags: DIFlagTypePassByValue | DIFlagNonTrivial
+struct Struct {
+ Struct() {}
+} Struct;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Annotated",{{.*}}flags: DIFlagTypePassByValue | DIFlagNonTrivial
+struct __attribute__((trivial_abi)) Annotated {
+ Annotated() {};
+} Annotated;
+
+
+// Check a non-composite type
+// CHECK-DAG: !DIGlobalVariable(name: "GlobalVar", {{.*}}type: {{.*}}, isLocal: false, isDefinition: true)
+int GlobalVar = 0;
+
+// Cases to test composite type's triviality
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "Union",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+union Union {
+ int a;
+} Union;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "Trivial",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct Trivial {
+ int i;
+} Trivial;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialA",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct TrivialA {
+ TrivialA() = default;
+} TrivialA;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialB",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct TrivialB {
+ int m;
+ TrivialB(int x) { m = x; }
+ TrivialB() = default;
+} TrivialB;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialC",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct TrivialC {
+ struct Trivial x;
+} TrivialC;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialD",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct NT {
+ NT() {};
+};
+struct TrivialD {
+ static struct NT x; // Member is non-trivial but is static.
+} TrivialD;
+
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivial",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivial {
+ NonTrivial() {}
+} NonTrivial;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialA",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialA {
+ ~NonTrivialA();
+} NonTrivialA;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialB",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialB {
+ struct NonTrivial x;
+} NonTrivialB;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialC",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialC {
+ virtual void f() {}
+} NonTrivialC;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialD",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialD : NonTrivial {
+} NonTrivialD;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialE",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialE : Trivial, NonTrivial {
+} NonTrivialE;
diff --git a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
index 0ede3c6e48..e3df9ca9ae 100644
--- a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
+++ b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
@@ -2,11 +2,14 @@
// RUN: | FileCheck %s --check-prefix=CHECK-NOKEXT
// RUN: %clang_cc1 %s -debug-info-kind=limited -triple %itanium_abi_triple -fno-use-cxa-atexit -fapple-kext -S -disable-O0-optnone -emit-llvm -o - \
// RUN: | FileCheck %s --check-prefix=CHECK-KEXT
+// RUN: %clang_cc1 %s -gcodeview -debug-info-kind=limited -triple x86_64-windows-msvc -fno-use-cxa-atexit -S -disable-O0-optnone -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK-MSVC
class A {
- public:
- A() {}
- virtual ~A() {}
+public:
+ A();
+ A(int x);
+ virtual ~A();
};
A glob;
@@ -16,12 +19,35 @@ void foo() {
static A stat;
}
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+template <typename T>
+struct FooTpl {
+ template <typename U>
+ static A sdm_tpl;
+};
+template <typename T>
+template <typename U>
+A FooTpl<T>::sdm_tpl(sizeof(U) + sizeof(T));
+template A FooTpl<int>::sdm_tpl<int>;
+
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 15,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 15,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 19,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-KEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+
+// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'glob'",{{.*}} line: 15,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'glob'",{{.*}} line: 15,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'array'",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'array'",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'stat'",{{.*}} line: 19,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+
+// MSVC does weird stuff when templates are involved, so we don't match exactly,
+// but these names are reasonable.
+// FIXME: These should not be marked DISPFlagLocalToUnit.
+// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic initializer for 'sdm_tpl<int>'",{{.*}} line: 29,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic atexit destructor for 'sdm_tpl<int>'",{{.*}} line: 29,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
index 8e47a0da6d..3a26050782 100644
--- a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -9,9 +9,9 @@ struct B : A {
A::A(int i, ...) {}
// CHECK: define void @{{.*}}foo
-// CHECK-NOT ret void
+// CHECK-NOT: ret void
// CHECK: call void @llvm.dbg.declare
-// CHECK-NOT ret void
+// CHECK-NOT: ret void
// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC:[0-9]+]]
// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index db6006cab8..3d5b04d164 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -30,7 +30,7 @@ inline int add3(int x) {
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
// CHECK-SAME: name: "var"
// CHECK-SAME: templateParams: {{![0-9]+}}
-// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}})
+// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}})
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
// CHECK-SAME: name: "varray"
// CHECK-SAME: templateParams: {{![0-9]+}}
diff --git a/test/CodeGenCXX/debug-info-var-template-partial.cpp b/test/CodeGenCXX/debug-info-var-template-partial.cpp
new file mode 100644
index 0000000000..21ea03b8ee
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-var-template-partial.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - -debug-info-kind=limited | FileCheck %s
+
+template <typename LHS, typename RHS> constexpr bool is_same_v = false;
+template <typename T> constexpr bool is_same_v<T, T> = true;
+
+template constexpr bool is_same_v<int, int>;
+static_assert(is_same_v<int, int>, "should get partial spec");
+
+// Note that the template arguments for the instantiated variable use the
+// parameter names from the primary template. The partial specialization might
+// not have enough parameters.
+
+// CHECK: distinct !DIGlobalVariable(name: "is_same_v", linkageName: "_Z9is_same_vIiiE", {{.*}} templateParams: ![[PARAMS:[0-9]+]])
+// CHECK: ![[PARAMS]] = !{![[LHS:[0-9]+]], ![[RHS:[0-9]+]]}
+// CHECK: ![[LHS]] = !DITemplateTypeParameter(name: "LHS", type: ![[INT:[0-9]+]])
+// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK: ![[RHS]] = !DITemplateTypeParameter(name: "RHS", type: ![[INT]])
diff --git a/test/CodeGenCXX/discard-name-values.cpp b/test/CodeGenCXX/discard-name-values.cpp
index d4d7527c28..aa30dae750 100644
--- a/test/CodeGenCXX/discard-name-values.cpp
+++ b/test/CodeGenCXX/discard-name-values.cpp
@@ -10,7 +10,7 @@ bool test(bool pred) {
// CHECK: br i1 %pred, label %if.then, label %if.end
if (pred) {
- // DISCARDVALUE: ; <label>:2:
+ // DISCARDVALUE: 2:
// DISCARDVALUE-NEXT: tail call void @branch()
// DISCARDVALUE-NEXT: br label %3
@@ -20,7 +20,7 @@ bool test(bool pred) {
branch();
}
- // DISCARDVALUE: ; <label>:3:
+ // DISCARDVALUE: 3:
// DISCARDVALUE-NEXT: ret i1 %0
// CHECK: if.end:
diff --git a/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp b/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
index 3866731a3c..02cab5e2b4 100644
--- a/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
+++ b/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
-// RUN: -disable-llvm-passes \
+// RUN: -disable-llvm-passes -std=c++14 \
// RUN: -fno-dllexport-inlines -emit-llvm -O1 -o - | \
// RUN: FileCheck --check-prefix=CHECK --check-prefix=NOEXPORTINLINE %s
// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
-// RUN: -disable-llvm-passes \
+// RUN: -disable-llvm-passes -std=c++14 \
// RUN: -emit-llvm -O1 -o - | \
// RUN: FileCheck --check-prefix=CHECK --check-prefix=EXPORTINLINE %s
diff --git a/test/CodeGenCXX/dllimport-runtime-fns.cpp b/test/CodeGenCXX/dllimport-runtime-fns.cpp
new file mode 100644
index 0000000000..a42fcce8bb
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-runtime-fns.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility-version=19.20 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility-version=19.20 -triple aarch64-windows-msvc -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-windows-itanium -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -triple aarch64-windows-gnu -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=GNU
+
+void foo1() { throw 1; }
+// _CxxThrowException should not be marked dllimport.
+// MSVC-LABEL: define dso_local void @"?foo1@@YAXXZ"
+// MSVC: call void @_CxxThrowException
+// MSVC: declare dso_local void @_CxxThrowException(i8*, %eh.ThrowInfo*)
+
+// __cxa_throw should be marked dllimport for *-windows-itanium.
+// ITANIUM-LABEL: define dso_local void @_Z4foo1v()
+// ITANIUM: call void @__cxa_throw({{.*}})
+// ITANIUM: declare dllimport void @__cxa_throw({{.*}})
+
+// ... but not for *-windows-gnu.
+// GNU-LABEL: define dso_local void @_Z4foo1v()
+// GNU: call void @__cxa_throw({{.*}})
+// GNU: declare dso_local void @__cxa_throw({{.*}})
+
+
+void bar();
+void foo2() noexcept(true) { bar(); }
+// __std_terminate should not be marked dllimport.
+// MSVC-LABEL: define dso_local void @"?foo2@@YAXXZ"
+// MSVC: call void @__std_terminate()
+// MSVC: declare dso_local void @__std_terminate()
+
+// _ZSt9terminatev and __cxa_begin_catch should be marked dllimport.
+// ITANIUM-LABEL: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+// ITANIUM: call i8* @__cxa_begin_catch({{.*}})
+// ITANIUM: call void @_ZSt9terminatev()
+// ITANIUM: declare dllimport i8* @__cxa_begin_catch(i8*)
+// ITANIUM: declare dllimport void @_ZSt9terminatev()
+
+// .. not for mingw.
+// GNU-LABEL: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+// GNU: call i8* @__cxa_begin_catch({{.*}})
+// GNU: call void @_ZSt9terminatev()
+// GNU: declare dso_local i8* @__cxa_begin_catch(i8*)
+// GNU: declare dso_local void @_ZSt9terminatev()
+
+
+struct A {};
+struct B { virtual void f(); };
+struct C : A, virtual B {};
+struct T {};
+T *foo3() { return dynamic_cast<T *>((C *)0); }
+// __RTDynamicCast should not be marked dllimport.
+// MSVC-LABEL: define dso_local %struct.T* @"?foo3@@YAPEAUT@@XZ"
+// MSVC: call i8* @__RTDynamicCast({{.*}})
+// MSVC: declare dso_local i8* @__RTDynamicCast(i8*, i32, i8*, i8*, i32)
+
+// Again, imported
+// ITANIUM-LABEL: define dso_local %struct.T* @_Z4foo3v()
+// ITANIUM: call i8* @__dynamic_cast({{.*}})
+// ITANIUM: declare dllimport i8* @__dynamic_cast({{.*}})
+
+// Not imported
+// GNU-LABEL: define dso_local %struct.T* @_Z4foo3v()
+// GNU: call i8* @__dynamic_cast({{.*}})
+// GNU: declare dso_local i8* @__dynamic_cast({{.*}})
diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp
index 7e1c1e8db9..7d07eac481 100644
--- a/test/CodeGenCXX/float16-declarations.cpp
+++ b/test/CodeGenCXX/float16-declarations.cpp
@@ -1,5 +1,4 @@
// RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64
-// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86
/* Various contexts where type _Float16 can appear. */
@@ -15,7 +14,6 @@ namespace {
_Float16 arr1n[10];
// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
-// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16
_Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
@@ -30,14 +28,12 @@ namespace {
_Float16 f1f;
// CHECK-AARCH64-DAG: @f1f = dso_local global half 0xH0000, align 2
-// CHECK-X86-DAG: @f1f = dso_local global half 0xH0000, align 2
_Float16 f2f = 32.4;
// CHECK-DAG: @f2f = dso_local global half 0xH500D, align 2
_Float16 arr1f[10];
// CHECK-AARCH64-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 2
-// CHECK-X86-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 16
_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
// CHECK-DAG: @arr2f = dso_local global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
@@ -137,8 +133,6 @@ int main(void) {
long double cvtld = f2n;
//CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
//CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
-//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80
-//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16
_Float16 f2h = 42.0f;
//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp
index 8124129713..4104380447 100644
--- a/test/CodeGenCXX/for-range.cpp
+++ b/test/CodeGenCXX/for-range.cpp
@@ -39,7 +39,7 @@ void for_array() {
for (B b : array) {
// CHECK-NOT: 5begin
// CHECK-NOT: 3end
- // CHECK: getelementptr {{.*}}, i32 0
+ // CHECK: getelementptr {{.*}}, i64 0
// CHECK: getelementptr {{.*}}, i64 5
// CHECK: br label %[[COND:.*]]
diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp
index fa3e5ab8aa..2614a80759 100644
--- a/test/CodeGenCXX/inheriting-constructor.cpp
+++ b/test/CodeGenCXX/inheriting-constructor.cpp
@@ -270,15 +270,6 @@ namespace inalloca_virt {
// WIN32: call void @llvm.stackrestore(
// WIN32: br
//
- // WIN32: store i32 0, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
- // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
- // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
- // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
- //
- // Note: this block is unreachable.
- // WIN32: store {{.*}} @"??_8B@inalloca_virt@@7B@"
- // WIN32: br
- //
// WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
// WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
// WIN32: call {{.*}} @"??1Q@@QAE@XZ"(
@@ -294,11 +285,6 @@ namespace inalloca_virt {
// WIN64: br i1
// WIN64: store {{.*}} @"??_8C@inalloca_virt@@7B@"
// WIN64: call {{.*}} @"??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
- // WIN64: br
- // WIN64: br i1
- // (Unreachable block)
- // WIN64: store {{.*}} @"??_8B@inalloca_virt@@7B@"
- // WIN64: br
// WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
// WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
// WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]])
diff --git a/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp b/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp
new file mode 100644
index 0000000000..3bec64156a
--- /dev/null
+++ b/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++2a -triple %itanium_abi_triple -emit-llvm -o - %s -w | FileCheck %s
+
+template<class, int, class>
+struct DummyType { };
+
+inline void inline_func() {
+ // CHECK: UlvE
+ []{}();
+
+ // CHECK: UlTyvE
+ []<class>{}.operator()<int>();
+
+ // CHECK: UlTyT_E
+ []<class T>(T){}(1);
+
+ // CHECK: UlTyTyT_T0_E
+ []<class T1, class T2>(T1, T2){}(1, 2);
+
+ // CHECK: UlTyTyT0_T_E
+ []<class T1, class T2>(T2, T1){}(2, 1);
+
+ // CHECK: UlTniTyTnjT0_E
+ []<int I, class T, unsigned U>(T){}.operator()<1, int, 2>(3);
+
+ // CHECK: UlTyTtTyTniTyETniTyvE
+ []<class,
+ template<class, int, class> class,
+ int,
+ class>{}.operator()<unsigned, DummyType, 5, int>();
+}
+
+void call_inline_func() {
+ inline_func();
+}
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index e128c94431..75ca3af825 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s
// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=aarch64-pc-win32 -std=c++98 -DARM | FileCheck -check-prefixes=X64,ARM %s
int a;
// CHECK-DAG: @"?a@@3HA"
@@ -456,6 +457,8 @@ int bar(int *const i __attribute__((pass_object_size(1)))) { return 0; }
int qux(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(0)))) { return 0; }
// CHECK-DAG: define dso_local i32 @"?zot@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z"
int zot(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(1)))) { return 0; }
+// CHECK-DAG: define dso_local i32 @"?silly_word@PassObjectSize@@YAHQAHW4__pass_dynamic_object_size1@__clang@@@Z"
+int silly_word(int *const i __attribute__((pass_dynamic_object_size(1)))) { return 0; }
}
namespace Atomic {
@@ -466,10 +469,12 @@ namespace Complex {
// CHECK-DAG: define dso_local void @"?f@Complex@@YAXU?$_Complex@H@__clang@@@Z"(
void f(_Complex int) {}
}
+#ifdef ARM
namespace Float16 {
-// CHECK-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"(
+// ARM-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"(
void f(_Float16) {}
}
+#endif // ARM
namespace PR26029 {
template <class>
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
index e45d37273c..9567245d98 100644
--- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -60,7 +60,7 @@ T* test5(A* x) { return dynamic_cast<T*>(x); }
// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi %struct.T*
@@ -100,7 +100,7 @@ void* test8(A* x) { return dynamic_cast<void*>(x); }
// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi i8*
// CHECK-NEXT: ret i8* [[RET]]
diff --git a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
index 6682fafc91..7e8619b8b0 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -293,7 +293,7 @@ struct class_0 : class_1 {
};
class_0::class_0() {
- // WIN32: define dso_local x86_thiscallcc %struct.class_0* @"??0class_0@@QAE@XZ"(%struct.class_0* returned %this, i32 %is_most_derived)
+ // WIN32: define dso_local x86_thiscallcc %struct.class_0* @"??0class_0@@QAE@XZ"(%struct.class_0* returned %this, i32 %is_most_derived)
// WIN32: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
// WIN32: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
// WIN32: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
@@ -304,7 +304,7 @@ class_0::class_0() {
// ehcleanup:
// WIN32: %[[CLEANUPPAD:.*]] = cleanuppad within none []
// WIN32-NEXT: bitcast %{{.*}}* %{{.*}} to i8*
- // WIN32-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i{{.*}} {{.}}
+ // WIN32-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i{{.*}} {{.}}
// WIN32-NEXT: bitcast i8* %{{.*}} to %{{.*}}*
// WIN32-NEXT: %[[SHOULD_CALL_VBASE_DTOR:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
// WIN32-NEXT: br i1 %[[SHOULD_CALL_VBASE_DTOR]], label %[[DTOR_VBASE:.*]], label %[[SKIP_VBASE:.*]]
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index a910a2d7f7..ad4073099c 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -69,6 +69,11 @@ struct BaseNoByval : Small {
int bb;
};
+struct SmallWithPrivate {
+private:
+ int i;
+};
+
// WIN32: declare dso_local void @"{{.*take_bools_and_chars.*}}"
// WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor,
// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca)
@@ -165,7 +170,7 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WIN64: call void @"??1SmallWithDtor@@QEAA@XZ"
// WIN64: }
// WOA64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i64 %s.coerce) {{.*}} {
-// WOA64: call void @"??1SmallWithDtor@@QEAA@XZ"
+// WOA64: call void @"??1SmallWithDtor@@QEAA@XZ"(%struct.SmallWithDtor* %s)
// WOA64: }
// FIXME: MSVC incompatible!
@@ -173,6 +178,12 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WOA: call arm_aapcs_vfpcc void @"??1SmallWithDtor@@QAA@XZ"(%struct.SmallWithDtor* %s)
// WOA: }
+
+// Test that the eligible non-aggregate is passed directly, but returned
+// indirectly on ARM64 Windows.
+// WOA64: define dso_local void @"?small_arg_with_private_member@@YA?AUSmallWithPrivate@@U1@@Z"(%struct.SmallWithPrivate* inreg noalias sret %agg.result, i64 %s.coerce) {{.*}} {
+SmallWithPrivate small_arg_with_private_member(SmallWithPrivate s) { return s; }
+
void call_small_arg_with_dtor() {
small_arg_with_dtor(SmallWithDtor());
}
diff --git a/test/CodeGenCXX/microsoft-abi-template-static-init.cpp b/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
new file mode 100644
index 0000000000..3b419c18c0
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+
+struct S {
+ S();
+ ~S();
+};
+
+template <typename T> struct __declspec(dllexport) ExportedTemplate {
+ static S s;
+};
+template <typename T> S ExportedTemplate<T>::s;
+void useExportedTemplate(ExportedTemplate<int> x) {
+ (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+inline int __declspec(selectany) x1 = f();
+}
+
+namespace explicit_template_instantiation {
+template <typename T> struct A { static int x; };
+template <typename T> int A<T>::x = f();
+template struct A<int>;
+}
+
+namespace implicit_template_instantiation {
+template <typename T> struct A { static int x; };
+template <typename T> int A<T>::x = f();
+int g() { return A<int>::x; }
+}
+
+
+template <class T>
+struct X_ {
+ static T ioo;
+ static T init();
+};
+template <class T> T X_<T>::ioo = X_<T>::init();
+template struct X_<int>;
+
+template <class T>
+struct X {
+ static T ioo;
+ static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X<int>::ioo = X<int>::init();
+template struct X<int>;
+class a {
+public:
+ a();
+};
+// For the static var inside unnamed namespace, the object is local to TU.
+// No need to put static var in the linker directive.
+// The static init routine is called before main.
+namespace {
+template <int> class aj {
+public:
+ static a al;
+};
+template <int am> a aj<am>::al;
+class b : aj<3> {
+ void c();
+};
+void b::c() { al; }
+}
+
+// C++17, inline static data member also need to use
+struct A
+{
+ A();
+ ~A();
+};
+
+struct S1
+{
+ inline static A aoo; // C++17 inline variable, thus also a definition
+};
+
+int foo();
+inline int zoo = foo();
+inline static int boo = foo();
+
+
+// CHECK: @llvm.used = appending global [7 x i8*] [i8* bitcast (i32* @"?x1@selectany_init@@3HA" to i8*), i8* bitcast (i32* @"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* @"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.A, %struct.A* @"?aoo@S1@@2UA@@A", i32 0, i32 0), i8* bitcast (i32* @"?zoo@@3HA" to i8*), i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section "llvm.metadata"
diff --git a/test/CodeGenCXX/microsoft-abi-typeid.cpp b/test/CodeGenCXX/microsoft-abi-typeid.cpp
index a571654ef0..128f2710df 100644
--- a/test/CodeGenCXX/microsoft-abi-typeid.cpp
+++ b/test/CodeGenCXX/microsoft-abi-typeid.cpp
@@ -36,7 +36,7 @@ const std::type_info* test3_typeid() { return &typeid(*fn()); }
// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
// CHECK-NEXT: [[VBASE_OFFS:%.*]] = load i32, i32* [[VBSLOT]], align 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[THIS]], i32 [[VBASE_OFFS]]
-// CHECK-NEXT: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]])
+// CHECK-NEXT: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* nonnull [[ADJ]])
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
// CHECK-NEXT: ret %struct.type_info* [[RET]]
diff --git a/test/CodeGenCXX/mingw-template-dllexport.cpp b/test/CodeGenCXX/mingw-template-dllexport.cpp
new file mode 100644
index 0000000000..408a3fd0a7
--- /dev/null
+++ b/test/CodeGenCXX/mingw-template-dllexport.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-mingw32 %s -o - | FileCheck %s
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+
+template <class T>
+class c {
+ void f() {}
+};
+
+template class __declspec(dllexport) c<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv
+
+extern template class __declspec(dllexport) c<char>;
+template class c<char>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv
+
+extern template class c<double>;
+template class __declspec(dllexport) c<double>;
+
+// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
+
+template <class T>
+struct outer {
+ void f();
+ struct inner {
+ void f();
+ };
+};
+
+template <class T> void outer<T>::f() {}
+template <class T> void outer<T>::inner::f() {}
+
+template class __declspec(dllexport) outer<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv
+// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv
+
+extern template class __declspec(dllimport) outer<char>;
+USEMEMFUNC(outer<char>, f)
+USEMEMFUNC(outer<char>::inner, f)
+
+// CHECK: declare dllimport {{.*}} @_ZN5outerIcE1fEv
+// CHECK: define {{.*}} @_ZN5outerIcE5inner1fEv
diff --git a/test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp b/test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp
new file mode 100644
index 0000000000..c1a7e6b66b
--- /dev/null
+++ b/test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -fexceptions -o - | FileCheck %s
+
+// PR41065: As background, when constructing a complete object, virtual bases
+// are constructed first. If an exception is thrown while constructing a
+// subobject later, those virtual bases are destroyed, so sema references the
+// relevant constructors and destructors of every base class in case they are
+// needed.
+//
+// However, an abstract class can never be used to construct a complete object.
+// In the Itanium C++ ABI, this works out nicely, because we never end up
+// emitting the "complete" constructor variant, only the "base" constructor
+// variant, which can be called by constructors of derived classes. For various
+// reasons, Sema does not mark ctors and dtors of virtual bases referenced when
+// the constructor of an abstract class is emitted.
+//
+// In the Microsoft ABI, there are no complete/base variants, so before PR41065
+// was fixed, the constructor of an abstract class could reference special
+// members of a virtual base without marking them referenced. This could lead to
+// unresolved symbol errors at link time.
+//
+// The fix is to implement the same optimization as Sema: If the class is
+// abstract, don't bother initializing its virtual bases. The "is this class the
+// most derived class" check in the constructor will never pass, and the virtual
+// base constructor calls are always dead. Skip them.
+
+struct A {
+ A();
+ virtual void f() = 0;
+ virtual ~A();
+};
+
+// B has an implicit inline dtor, but is still abstract.
+struct B : A {
+ B(int n);
+ int n;
+};
+
+// Still abstract
+struct C : virtual B {
+ C(int n);
+ //void f() override;
+};
+
+// Not abstract, D::D calls C::C and B::B.
+struct D : C {
+ D(int n);
+ void f() override;
+};
+
+void may_throw();
+C::C(int n) : B(n) { may_throw(); }
+
+// No branches, no constructor calls before may_throw();
+//
+// CHECK-LABEL: define dso_local %struct.C* @"??0C@@QEAA@H@Z"(%struct.C* returned %this, i32 %n, i32 %is_most_derived)
+// CHECK-NOT: br i1
+// CHECK-NOT: {{call.*@"\?0}}
+// CHECK: call void @"?may_throw@@YAXXZ"()
+// no cleanups
+
+
+D::D(int n) : C(n), B(n) { may_throw(); }
+
+// Conditionally construct (and destroy) vbase B, unconditionally C.
+//
+// CHECK-LABEL: define dso_local %struct.D* @"??0D@@QEAA@H@Z"(%struct.D* returned %this, i32 %n, i32 %is_most_derived)
+// CHECK: icmp ne i32 {{.*}}, 0
+// CHECK: br i1
+// CHECK: call %struct.B* @"??0B@@QEAA@H@Z"
+// CHECK: br label
+// CHECK: invoke %struct.C* @"??0C@@QEAA@H@Z"
+// CHECK: invoke void @"?may_throw@@YAXXZ"()
+// CHECK: cleanuppad
+// CHECK: call void @"??1C@@UEAA@XZ"
+// CHECK: cleanupret
+//
+// CHECK: cleanuppad
+// CHECK: icmp ne i32 {{.*}}, 0
+// CHECK: br i1
+// CHECK: call void @"??1B@@UEAA@XZ"
+// CHECK: br label
+// CHECK: cleanupret
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 90cd600229..b504d5e780 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -123,3 +123,25 @@ void constexpr_test() {
// SIO: call i8* @_Zna{{.}}(i32 4)
new int[0+1]{0};
}
+
+// CHECK-LABEL: define void @_Z13unknown_boundv
+void unknown_bound() {
+ struct Aggr { int x, y, z; };
+ new Aggr[]{1, 2, 3, 4};
+ // CHECK: call {{.*}}_Znaj(i32 24)
+ // CHECK: store i32 1
+ // CHECK: store i32 2
+ // CHECK: store i32 3
+ // CHECK: store i32 4
+ // CHECK: store i32 0
+ // CHECK: store i32 0
+ // CHECK-NOT: store
+ // CHECK: }
+}
+
+// CHECK-LABEL: define void @_Z20unknown_bound_stringv
+void unknown_bound_string() {
+ new char[]{"hello"};
+ // CHECK: call {{.*}}_Znaj(i32 6)
+ // CHECK: memcpy{{.*}} i32 6,
+}
diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp
index b27984f66a..a2269bfc59 100644
--- a/test/CodeGenCXX/new-overflow.cpp
+++ b/test/CodeGenCXX/new-overflow.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
// rdar://problem/9246208
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 3bebc2ab8a..1f5288d1d1 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
typedef __typeof__(sizeof(0)) size_t;
diff --git a/test/CodeGenCXX/override-bit-field-layout.cpp b/test/CodeGenCXX/override-bit-field-layout.cpp
index e84fcb0f45..dee7944f6a 100644
--- a/test/CodeGenCXX/override-bit-field-layout.cpp
+++ b/test/CodeGenCXX/override-bit-field-layout.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-bit-field-layout.layout %s | FileCheck %s
+// RUN: %clang_cc1 -w -triple=x86_64-pc-win32 -fms-compatibility -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-bit-field-layout.layout %s | FileCheck %s
// CHECK: Type: struct S1
// CHECK: FieldOffsets: [0, 11]
@@ -14,7 +14,23 @@ struct S2 {
short a : 3;
};
+// CHECK: Type: struct S3
+// CHECK: Size:32
+// CHECK: FieldOffsets: [0, 1]
+struct S3 {
+ int a : 1;
+ int b : 2;
+};
+
+// CHECK: Type: struct S4
+// CHECK: FieldOffsets: [32]
+struct S4 : S3 {
+ char c;
+};
+
void use_structs() {
S1 s1s[sizeof(S1)];
S2 s2s[sizeof(S2)];
+ S3 s3s[sizeof(S3)];
+ S4 s4s[sizeof(S4)];
}
diff --git a/test/CodeGenCXX/override-layout-virtual-base.cpp b/test/CodeGenCXX/override-layout-virtual-base.cpp
new file mode 100644
index 0000000000..d9e7346737
--- /dev/null
+++ b/test/CodeGenCXX/override-layout-virtual-base.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -w -triple=x86_64-pc-win32 -fms-compatibility -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-virtual-base.layout %s | FileCheck %s
+
+struct S1 {
+ int a;
+};
+
+struct S2 : virtual S1 {
+ virtual void foo() {}
+};
+
+// CHECK: Type: struct S3
+// CHECK: FieldOffsets: [128]
+struct S3 : S2 {
+ char b;
+};
+
+void use_structs() {
+ S1 s1s[sizeof(S1)];
+ S2 s2s[sizeof(S2)];
+ S3 s3s[sizeof(S3)];
+}
diff --git a/test/CodeGenCXX/override-layout.cpp b/test/CodeGenCXX/override-layout.cpp
index a3c4bb446c..fea2a45c62 100644
--- a/test/CodeGenCXX/override-layout.cpp
+++ b/test/CodeGenCXX/override-layout.cpp
@@ -64,6 +64,23 @@ struct PACKED X5 {
short r;
};
+// CHECK: Type: struct X6
+struct __attribute__((aligned(16))) X6 {
+ int x;
+ int y;
+ virtual ~X6();
+};
+
+// CHECK: Type: struct X7
+struct X7 {
+ int z;
+};
+
+// CHECK: Type: struct X8
+struct X8 : X6, virtual X7 {
+ char c;
+};
+
void use_structs() {
X0 x0s[sizeof(X0)];
X1 x1s[sizeof(X1)];
@@ -71,7 +88,9 @@ void use_structs() {
X3 x3s[sizeof(X3)];
X4 x4s[sizeof(X4)];
X5 x5s[sizeof(X5)];
+ X6 x6s[sizeof(X6)];
+ X7 x7s[sizeof(X7)];
+ X8 x8s[sizeof(X8)];
x4s[1].a = 1;
x5s[1].a = 17;
}
-
diff --git a/test/CodeGenCXX/pod-member-memcpys.cpp b/test/CodeGenCXX/pod-member-memcpys.cpp
index 9facb8ad50..a43706cb37 100644
--- a/test/CodeGenCXX/pod-member-memcpys.cpp
+++ b/test/CodeGenCXX/pod-member-memcpys.cpp
@@ -45,6 +45,13 @@ struct ArrayMember {
int w, x, y, z;
};
+struct ZeroLengthArrayMember {
+ NonPOD np;
+ int a;
+ int b[0];
+ int c;
+};
+
struct VolatileMember {
int a, b, c, d;
volatile int v;
@@ -109,6 +116,7 @@ CALL_AO(Basic)
CALL_AO(PODMember)
CALL_AO(PODLikeMember)
CALL_AO(ArrayMember)
+CALL_AO(ZeroLengthArrayMember)
CALL_AO(VolatileMember)
CALL_AO(BitfieldMember)
CALL_AO(InnerClassMember)
@@ -142,6 +150,12 @@ CALL_AO(PackedMembers)
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}})
// CHECK: ret %struct.ArrayMember*
+// ZeroLengthArrayMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ZeroLengthArrayMember* @_ZN21ZeroLengthArrayMemberaSERKS_(%struct.ZeroLengthArrayMember* %this, %struct.ZeroLengthArrayMember* dereferenceable({{[0-9]+}}))
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 8, i1 {{.*}})
+// CHECK: ret %struct.ZeroLengthArrayMember*
+
// VolatileMember copy-assignment:
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
diff --git a/test/CodeGenCXX/pragma-followup_inner.cpp b/test/CodeGenCXX/pragma-followup_inner.cpp
new file mode 100644
index 0000000000..62e9f07f01
--- /dev/null
+++ b/test/CodeGenCXX/pragma-followup_inner.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+extern "C" void followup_inner(int n, int *x) {
+#pragma unroll_and_jam(4)
+ for(int j = 0; j < n; j++) {
+#pragma clang loop pipeline_initiation_interval(10)
+#pragma clang loop unroll_count(4)
+#pragma clang loop vectorize(assume_safety)
+#pragma clang loop distribute(enable)
+ for(int i = 0; i < n; i++)
+ x[j+i*n] = 10;
+
+ }
+}
+
+
+// CHECK-LABEL: define void @followup_inner
+// CHECK: br label %for.cond1, !llvm.loop ![[INNERLOOP_3:[0-9]+]]
+// CHECK: br label %for.cond, !llvm.loop ![[OUTERLOOP_9:[0-9]+]]
+
+// CHECK-DAG: ![[ACCESSGROUP_2:[0-9]+]] = distinct !{}
+
+// CHECK-DAG: ![[INNERLOOP_3:[0-9]+]] = distinct !{![[INNERLOOP_3:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
+// CHECK-DAG: ![[PARALLEL_ACCESSES_4:[0-9]+]] = !{!"llvm.loop.parallel_accesses", !2}
+// CHECK-DAG: ![[DISTRIBUTE_5:[0-9]+]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK-DAG: ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]] = !{!"llvm.loop.distribute.followup_all", ![[LOOP_7:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]]}
+// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
+
+// CHECK-DAG: ![[OUTERLOOP_9:[0-9]+]] = distinct !{![[OUTERLOOP_9:[0-9]+]], ![[UNROLLANDJAM_COUNT_10:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]]}
+// CHECK-DAG: ![[UNROLLANDJAM_COUNT_10:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
+// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_inner", !12}
+
+// CHECK-DAG: ![[LOOP_12:[0-9]+]] = distinct !{![[LOOP_12:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_13:[0-9]+]], ![[UNROLL_COUNT_13:[0-9]+]], ![[UNROLL_FOLLOWUP_14:[0-9]+]]}
+// CHECK-DAG: ![[ISVECTORIZED_13:[0-9]+]] = !{!"llvm.loop.isvectorized"}
+// CHECK-DAG: ![[UNROLL_COUNT_13:[0-9]+]] = !{!"llvm.loop.unroll.count", i32 4}
+// CHECK-DAG: ![[UNROLL_FOLLOWUP_14:[0-9]+]] = !{!"llvm.loop.unroll.followup_all", ![[LOOP_15:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_15:[0-9]+]] = distinct !{![[LOOP_15:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_13:[0-9]+]], ![[UNROLL_DISABLE_16:[0-9]+]], ![[PIPELINE_17:[0-9]+]]}
+// CHECK-DAG: ![[UNROLL_DISABLE_16:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
+// CHECK-DAG: ![[PIPELINE_17:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
diff --git a/test/CodeGenCXX/pragma-followup_outer.cpp b/test/CodeGenCXX/pragma-followup_outer.cpp
new file mode 100644
index 0000000000..a71056eb3a
--- /dev/null
+++ b/test/CodeGenCXX/pragma-followup_outer.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+extern "C" void followup_outer(int n, int *x) {
+#pragma clang loop pipeline_initiation_interval(10)
+#pragma clang loop unroll_count(4)
+#pragma unroll_and_jam
+#pragma clang loop vectorize(assume_safety)
+#pragma clang loop distribute(enable)
+ for(int j = 0; j < n; j++) {
+ x[j] = 10;
+ }
+}
+
+
+// CHECK-LABEL: define void @followup_outer
+// CHECK: br label %for.cond, !llvm.loop ![[LOOP_3:[0-9]+]]
+
+// CHECK-DAG: ![[ACCESSGROUP_2:[0-9]+]] = distinct !{}
+
+// CHECK-DAG: ![[LOOP_3:[0-9]+]] = distinct !{![[LOOP_3:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
+// CHECK-DAG: ![[PARALLEL_ACCESSES_4:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[ACCESSGROUP_2]]}
+// CHECK-DAG: ![[DISTRIBUTE_5:[0-9]+]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK-DAG: ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]] = !{!"llvm.loop.distribute.followup_all", ![[LOOP_7:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]], ![[VECTORIZE_FOLLOWUP_9:[0-9]+]]}
+// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK-DAG: ![[VECTORIZE_FOLLOWUP_9:[0-9]+]] = !{!"llvm.loop.vectorize.followup_all", ![[LOOP_10:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_10:[0-9]+]] = distinct !{![[LOOP_10:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_12:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]]}
+// CHECK-DAG: ![[ISVECTORIZED_11:[0-9]+]] = !{!"llvm.loop.isvectorized"}
+// CHECK-DAG: ![[UNROLLANDJAM_12:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.enable"}
+// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[LOOP_14:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_14:[0-9]+]] = distinct !{![[LOOP_14:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_COUNT_16:[0-9]+]], ![[UNROLL_FOLLOWUP_17:[0-9]+]]}
+// CHECK-DAG: ![[UNROLLANDJAM_DISABLE_15:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.disable"}
+// CHECK-DAG: ![[UNROLL_COUNT_16:[0-9]+]] = !{!"llvm.loop.unroll.count", i32 4}
+// CHECK-DAG: ![[UNROLL_FOLLOWUP_17:[0-9]+]] = !{!"llvm.loop.unroll.followup_all", ![[LOOP_18:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_18:[0-9]+]] = distinct !{![[LOOP_18:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_DISABLE_19:[0-9]+]], ![[INITIATIONINTERVAL_20:[0-9]+]]}
+// CHECK-DAG: ![[UNROLL_DISABLE_19:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
+// CHECK-DAG: ![[INITIATIONINTERVAL_20:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
diff --git a/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
index da060f7902..1aed1e6df8 100644
--- a/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
@@ -26,7 +26,7 @@ void vectorize_imperfectly_nested_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-nested.cpp b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
index deec06bbc8..d3bdb880e1 100644
--- a/test/CodeGenCXX/pragma-loop-safety-nested.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
@@ -21,7 +21,7 @@ void vectorize_nested_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-outer.cpp b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
index d99b86ffe2..670cb29edd 100644
--- a/test/CodeGenCXX/pragma-loop-safety-outer.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
@@ -18,5 +18,5 @@ void vectorize_outer_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_9:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety.cpp b/test/CodeGenCXX/pragma-loop-safety.cpp
index c0b10b0a6b..86e7632a44 100644
--- a/test/CodeGenCXX/pragma-loop-safety.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -47,12 +47,12 @@ void interleave_test(int *List, int Length) {
}
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
-// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]]}
-// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
-// CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
-// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[PARALLEL_ACCESSES_7:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]]}
// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
+// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
+// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
-// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]], ![[PARALLEL_ACCESSES_11:[0-9]+]]}
-// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
+// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
diff --git a/test/CodeGenCXX/pragma-loop.cpp b/test/CodeGenCXX/pragma-loop.cpp
index e337913646..32075f965c 100644
--- a/test/CodeGenCXX/pragma-loop.cpp
+++ b/test/CodeGenCXX/pragma-loop.cpp
@@ -158,37 +158,60 @@ void template_test(double *List, int Length) {
for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[WIDTH_4:.*]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[UNROLL_FULL:.*]], ![[DISTRIBUTE_ENABLE:.*]]}
-// CHECK: ![[WIDTH_4]] = !{!"llvm.loop.vectorize.width", i32 4}
-// CHECK: ![[INTERLEAVE_4]] = !{!"llvm.loop.interleave.count", i32 4}
-// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_FULL:.*]]}
// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
-// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
-// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
-// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
+
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]]}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
// CHECK: ![[DISTRIBUTE_DISABLE]] = !{!"llvm.loop.distribute.enable", i1 false}
-// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]], ![[INTENABLE_1:.*]]}
+// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
+// CHECK: ![[INTERLEAVE_4]] = !{!"llvm.loop.interleave.count", i32 4}
+
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[FOLLOWUP_VECTOR_3:.*]]}
+// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[FOLLOWUP_VECTOR_3]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_3:.*]]}
+// CHECK: ![[AFTER_VECTOR_3]] = distinct !{![[AFTER_VECTOR_3]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[ISVECTORIZED]] = !{!"llvm.loop.isvectorized"}
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
+
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]]}
// CHECK: ![[WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
// CHECK: ![[INTERLEAVE_2]] = !{!"llvm.loop.interleave.count", i32 2}
-// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[WIDTH_1:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
+
+// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_1:.*]]}
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
-// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[FOLLOWUP_VECTOR_6:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_6]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_6:.*]]}
+// CHECK: ![[AFTER_VECTOR_6]] = distinct !{![[AFTER_VECTOR_6]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[WIDTH_5:.*]]}
// CHECK: ![[WIDTH_5]] = !{!"llvm.loop.vectorize.width", i32 5}
+
// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], ![[WIDTH_5:.*]]}
-// CHECK: ![[LOOP_9]] = distinct !{![[LOOP_9]], ![[WIDTH_8:.*]], ![[INTERLEAVE_8:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[INTERLEAVE_8]] = !{!"llvm.loop.interleave.count", i32 8}
-// CHECK: ![[LOOP_10]] = distinct !{![[LOOP_10]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[LOOP_11]] = distinct !{![[LOOP_11]], ![[WIDTH_2:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[LOOP_12]] = distinct !{![[LOOP_12]], ![[WIDTH_6:.*]], ![[INTERLEAVE_10:.*]], ![[UNROLL_24:.*]]}
-// CHECK: ![[WIDTH_6]] = !{!"llvm.loop.vectorize.width", i32 6}
-// CHECK: ![[INTERLEAVE_10]] = !{!"llvm.loop.interleave.count", i32 10}
+
+// CHECK: ![[LOOP_9]] = distinct !{![[LOOP_9]], ![[WIDTH_8:.*]], ![[INTERLEAVE_8:.*]], ![[FOLLOWUP_VECTOR_9:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_9]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_9:.*]]}
+// CHECK: ![[AFTER_VECTOR_9]] = distinct !{![[AFTER_VECTOR_9]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_10]] = distinct !{![[LOOP_10]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[FOLLOWUP_VECTOR_10:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_10]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_10:.*]]}
+// CHECK: ![[AFTER_VECTOR_10]] = distinct !{![[AFTER_VECTOR_10]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_11]] = distinct !{![[LOOP_11]], ![[WIDTH_2:.*]], ![[INTERLEAVE_4:.*]], ![[FOLLOWUP_VECTOR_11:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_11]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_11:.*]]}
+// CHECK: ![[AFTER_VECTOR_11]] = distinct !{![[AFTER_VECTOR_11]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_12]] = distinct !{![[LOOP_12]], ![[WIDTH_6:.*]], ![[INTERLEAVE_10:.*]], ![[FOLLOWUP_VECTOR_12:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_12]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_12:.*]]}
+// CHECK: ![[AFTER_VECTOR_12]] = distinct !{![[AFTER_VECTOR_12]], ![[ISVECTORIZED:.*]], ![[UNROLL_24:.*]]}
// CHECK: ![[UNROLL_24]] = !{!"llvm.loop.unroll.count", i32 24}
-// CHECK: ![[LOOP_13]] = distinct !{![[LOOP_13]], ![[WIDTH_8:.*]], ![[INTERLEAVE_16:.*]], ![[UNROLL_32:.*]]}
+
+// CHECK: ![[LOOP_13]] = distinct !{![[LOOP_13]], ![[WIDTH_8:.*]], ![[INTERLEAVE_16:.*]], ![[FOLLOWUP_VECTOR_13:.*]]}
// CHECK: ![[INTERLEAVE_16]] = !{!"llvm.loop.interleave.count", i32 16}
+// CHECK: ![[FOLLOWUP_VECTOR_13]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_13:.*]]}
+// CHECK: ![[AFTER_VECTOR_13]] = distinct !{![[AFTER_VECTOR_13]], ![[ISVECTORIZED:.*]], ![[UNROLL_32:.*]]}
// CHECK: ![[UNROLL_32]] = !{!"llvm.loop.unroll.count", i32 32}
+
// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], ![[WIDTH_10:.*]]}
// CHECK: ![[WIDTH_10]] = !{!"llvm.loop.vectorize.width", i32 10}
diff --git a/test/CodeGenCXX/pragma-unroll-and-jam.cpp b/test/CodeGenCXX/pragma-unroll-and-jam.cpp
index 9842126034..524b60ab69 100644
--- a/test/CodeGenCXX/pragma-unroll-and-jam.cpp
+++ b/test/CodeGenCXX/pragma-unroll-and-jam.cpp
@@ -51,5 +51,5 @@ void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
-// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_4:.*]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNJ_DISABLE:.*]], ![[UNROLL_4:.*]]}
// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/test/CodeGenCXX/predefined-expr-cxx14.cpp b/test/CodeGenCXX/predefined-expr-cxx14.cpp
index dd531e3112..ec7c3db7bd 100644
--- a/test/CodeGenCXX/predefined-expr-cxx14.cpp
+++ b/test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -20,6 +20,8 @@
// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [31 x i8] c"~ClassBlockConstr_block_invoke\00"
// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [30 x i8] c"ClassBlockConstr_block_invoke\00"
+// CHECK-DAG: private unnamed_addr constant [32 x i8] c"const char *ConstexprPrettyFn()\00"
+
int printf(const char * _Format, ...);
class ClassInTopLevelNamespace {
@@ -83,6 +85,11 @@ public:
const char *getFunc() const { return Func; }
};
+constexpr const char* ConstexprPrettyFn() {
+ return __PRETTY_FUNCTION__;
+}
+const char* ConstexprPrettyVar = ConstexprPrettyFn();
+
int
main() {
int a;
diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp
index 7220fa50b0..d89b5089dd 100644
--- a/test/CodeGenCXX/runtime-dllstorage.cpp
+++ b/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -14,7 +14,7 @@
// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
-// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
#if defined(IMPORT_DECLARATIONS)
@@ -108,7 +108,7 @@ void l() {
// CHECK-MS-DAG: @_Init_thread_epoch = external thread_local global i32
// CHECK-MS-DAG: declare dso_local i32 @__tlregdtor(void ()*)
// CHECK-MS-DAG: declare dso_local i32 @atexit(void ()*)
-// CHECK-MS-DYNAMIC-DAG: declare dllimport {{.*}} void @_CxxThrowException
+// CHECK-MS-DYNAMIC-DAG: declare {{.*}} void @_CxxThrowException
// CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException
// CHECK-MS-DAG: declare dso_local noalias i8* @"??2@YAPAXI@Z"
// CHECK-MS-DAG: declare dso_local void @_Init_thread_header(i32*)
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 4586a3c38f..fe5ff2c7de 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -190,3 +190,79 @@ extern "C" int cleanup_exit_complex(bool b) {
// CHECK: %[[v2:[^ ]*]] = load float, float* %[[tmp2]]
// CHECK: store float %[[v1]], float* %v.realp
// CHECK: store float %[[v2]], float* %v.imagp
+
+extern "C" void then(int);
+
+// CHECK-LABEL: @{{.*}}volatile_load
+void volatile_load() {
+ volatile int n;
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({n;});
+
+ // CHECK-LABEL: @then(i32 1)
+ then(1);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({goto lab; lab: n;});
+
+ // CHECK-LABEL: @then(i32 2)
+ then(2);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({[[gsl::suppress("foo")]] n;});
+
+ // CHECK-LABEL: @then(i32 3)
+ then(3);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({if (true) n;});
+
+ // CHECK: }
+}
+
+// CHECK-LABEL: @{{.*}}volatile_load_template
+template<typename T>
+void volatile_load_template() {
+ volatile T n;
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({n;});
+
+ // CHECK-LABEL: @then(i32 1)
+ then(1);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({goto lab; lab: n;});
+
+ // CHECK-LABEL: @then(i32 2)
+ then(2);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({[[gsl::suppress("foo")]] n;});
+
+ // CHECK-LABEL: @then(i32 3)
+ then(3);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({if (true) n;});
+
+ // CHECK: }
+}
+template void volatile_load_template<int>();
diff --git a/test/CodeGenCXX/trivial-auto-var-init.cpp b/test/CodeGenCXX/trivial-auto-var-init.cpp
index b795c0755b..2cc63a47dd 100644
--- a/test/CodeGenCXX/trivial-auto-var-init.cpp
+++ b/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -30,6 +30,53 @@ void test_block() {
used(block);
}
+// Using the variable being initialized is typically UB in C, but for blocks we
+// can be nice: they imply extra book-keeping and we can do the auto-init before
+// any of said book-keeping.
+//
+// UNINIT-LABEL: test_block_self_init(
+// ZERO-LABEL: test_block_self_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_self_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+using Block = void (^)();
+typedef struct XYZ {
+ Block block;
+} * xyz_t;
+void test_block_self_init() {
+ extern xyz_t create(Block block);
+ __block xyz_t captured = create(^() {
+ used(captured);
+ });
+}
+
+// Capturing with escape after initialization is also an edge case.
+//
+// UNINIT-LABEL: test_block_captures_self_after_init(
+// ZERO-LABEL: test_block_captures_self_after_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_captures_self_after_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+void test_block_captures_self_after_init() {
+ extern xyz_t create(Block block);
+ __block xyz_t captured;
+ captured = create(^() {
+ used(captured);
+ });
+}
+
// This type of code is currently not handled by zero / pattern initialization.
// The test will break when that is fixed.
// UNINIT-LABEL: test_goto_unreachable_value(
@@ -126,6 +173,34 @@ void test_vla(int size) {
used(ptr);
}
+// UNINIT-LABEL: test_alloca(
+// ZERO-LABEL: test_alloca(
+// ZERO: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// ZERO-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]]
+// ZERO-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %[[ALLOCA]], i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_alloca(
+// PATTERN: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// PATTERN-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]]
+// PATTERN-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %[[ALLOCA]], i8 -86, i64 %[[SIZE]], i1 false)
+void test_alloca(int size) {
+ void *ptr = __builtin_alloca(size);
+ used(ptr);
+}
+
+// UNINIT-LABEL: test_alloca_with_align(
+// ZERO-LABEL: test_alloca_with_align(
+// ZERO: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// ZERO-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align 128
+// ZERO-NEXT: call void @llvm.memset{{.*}}(i8* align 128 %[[ALLOCA]], i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_alloca_with_align(
+// PATTERN: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// PATTERN-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align 128
+// PATTERN-NEXT: call void @llvm.memset{{.*}}(i8* align 128 %[[ALLOCA]], i8 -86, i64 %[[SIZE]], i1 false)
+void test_alloca_with_align(int size) {
+ void *ptr = __builtin_alloca_with_align(size, 1024);
+ used(ptr);
+}
+
// UNINIT-LABEL: test_struct_vla(
// ZERO-LABEL: test_struct_vla(
// ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
diff --git a/test/CodeGenCXX/trivial_abi.cpp b/test/CodeGenCXX/trivial_abi.cpp
index e37c8ff615..2cf07b2258 100644
--- a/test/CodeGenCXX/trivial_abi.cpp
+++ b/test/CodeGenCXX/trivial_abi.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
// CHECK: %[[STRUCT_SMALL:.*]] = type { i32* }
// CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] }
@@ -43,13 +43,6 @@ struct HasNonTrivial {
NonTrivial m;
};
-struct __attribute__((trivial_abi)) CopyMoveDeleted {
- CopyMoveDeleted(int);
- CopyMoveDeleted(const CopyMoveDeleted &) = delete;
- CopyMoveDeleted(CopyMoveDeleted &&) = delete;
- int a;
-};
-
// CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
// CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0
@@ -244,11 +237,3 @@ void calleeExceptionLarge(Large, Large);
void testExceptionLarge() {
calleeExceptionLarge(Large(), Large());
}
-
-// A class with deleted copy and move constructors can still be passed or
-// returned in registers if the class is annotated with trivial_abi.
-
-// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 %
-CopyMoveDeleted testCopyMoveDeleted(int a) {
- return a;
-}
diff --git a/test/CodeGenCXX/ubsan-unreachable.cpp b/test/CodeGenCXX/ubsan-unreachable.cpp
index 32a78048cf..70a487a177 100644
--- a/test/CodeGenCXX/ubsan-unreachable.cpp
+++ b/test/CodeGenCXX/ubsan-unreachable.cpp
@@ -1,39 +1,37 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=unreachable | FileCheck %s
-extern void __attribute__((noreturn)) abort();
+void abort() __attribute__((noreturn));
-// CHECK-LABEL: define void @_Z14calls_noreturnv
+// CHECK-LABEL: define void @_Z14calls_noreturnv()
void calls_noreturn() {
+ // Check absence ([^#]*) of call site attributes (including noreturn)
+ // CHECK: call void @_Z5abortv(){{[^#]*}}
abort();
- // Check that there are no attributes on the call site.
- // CHECK-NOT: call void @_Z5abortv{{.*}}#
-
// CHECK: __ubsan_handle_builtin_unreachable
// CHECK: unreachable
}
struct A {
- // CHECK: declare void @_Z5abortv{{.*}} [[ABORT_ATTR:#[0-9]+]]
+ // CHECK: declare void @_Z5abortv() [[EXTERN_FN_ATTR:#[0-9]+]]
// CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev
void call1() {
- // CHECK-NOT: call void @_ZN1A16does_not_return2Ev{{.*}}#
+ // CHECK: call void @_ZN1A16does_not_return2Ev({{.*}}){{[^#]*}}
does_not_return2();
// CHECK: __ubsan_handle_builtin_unreachable
// CHECK: unreachable
}
- // Test static members.
- static void __attribute__((noreturn)) does_not_return1() {
- // CHECK-NOT: call void @_Z5abortv{{.*}}#
+ // Test static members. Checks are below after `struct A` scope ends.
+ static void does_not_return1() __attribute__((noreturn)) {
abort();
}
// CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev
void call2() {
- // CHECK-NOT: call void @_ZN1A16does_not_return1Ev{{.*}}#
+ // CHECK: call void @_ZN1A16does_not_return1Ev(){{[^#]*}}
does_not_return1();
// CHECK: __ubsan_handle_builtin_unreachable
@@ -41,23 +39,23 @@ struct A {
}
// Test calls through pointers to non-static member functions.
- typedef void __attribute__((noreturn)) (A::*MemFn)();
+ typedef void (A::*MemFn)() __attribute__((noreturn));
// CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev
void call3() {
MemFn MF = &A::does_not_return2;
+ // CHECK: call void %{{[0-9]+\(.*}}){{[^#]*}}
(this->*MF)();
- // CHECK-NOT: call void %{{.*}}#
// CHECK: __ubsan_handle_builtin_unreachable
// CHECK: unreachable
}
// Test regular members.
// CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return2Ev({{.*}})
- // CHECK-SAME: [[DOES_NOT_RETURN_ATTR:#[0-9]+]]
- void __attribute__((noreturn)) does_not_return2() {
- // CHECK-NOT: call void @_Z5abortv(){{.*}}#
+ // CHECK-SAME: [[USER_FN_ATTR:#[0-9]+]]
+ void does_not_return2() __attribute__((noreturn)) {
+ // CHECK: call void @_Z5abortv(){{[^#]*}}
abort();
// CHECK: call void @__ubsan_handle_builtin_unreachable
@@ -68,7 +66,9 @@ struct A {
}
};
-// CHECK: define linkonce_odr void @_ZN1A16does_not_return1Ev() [[DOES_NOT_RETURN_ATTR]]
+// CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return1Ev()
+// CHECK-SAME: [[USER_FN_ATTR]]
+// CHECK: call void @_Z5abortv(){{[^#]*}}
void force_irgen() {
A a;
@@ -77,5 +77,7 @@ void force_irgen() {
a.call3();
}
-// CHECK-NOT: [[ABORT_ATTR]] = {{[^}]+}}noreturn
-// CHECK-NOT: [[DOES_NOT_RETURN_ATTR]] = {{[^}]+}}noreturn
+// `noreturn` should be removed from functions and call sites
+// CHECK-LABEL: attributes
+// CHECK-NOT: [[USER_FN_ATTR]] = { {{.*noreturn.*}} }
+// CHECK-NOT: [[EXTERN_FN_ATTR]] = { {{.*noreturn.*}} }
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
index 9c0271b21d..cf49aed4de 100644
--- a/test/CodeGenCXX/volatile.cpp
+++ b/test/CodeGenCXX/volatile.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++98 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++98 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
// Check that IR gen doesn't try to do an lvalue-to-rvalue conversion
@@ -33,3 +33,19 @@ namespace test1 {
*x;
}
}
+
+namespace PR40642 {
+ template <class T> struct S {
+ // CHECK-LABEL: define {{.*}} @_ZN7PR406421SIiE3fooEv(
+ void foo() {
+ // CHECK98-NOT: load volatile
+ // CHECK11: load volatile
+ if (true)
+ reinterpret_cast<const volatile unsigned char *>(m_ptr)[0];
+ // CHECK: }
+ }
+ int *m_ptr;
+ };
+
+ void f(S<int> *x) { x->foo(); }
+}
diff --git a/test/CodeGenCXX/vtable-key-function-ios.cpp b/test/CodeGenCXX/vtable-key-function-ios.cpp
index a119c780bb..ff2793ad51 100644
--- a/test/CodeGenCXX/vtable-key-function-ios.cpp
+++ b/test/CodeGenCXX/vtable-key-function-ios.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefixes=CHECK,CHECK-UNIX %s
// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
-// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck -check-prefixes=CHECK,CHECK-MINGW %s
// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
// The 'a' variants ask for the vtable first.
@@ -29,7 +29,8 @@ struct Test0a {
// V-table should be defined externally.
Test0a::Test0a() { use(typeid(Test0a)); }
// CHECK: @_ZTV6Test0a = external {{(dso_local )?}}unnamed_addr constant
-// CHECK: @_ZTI6Test0a = external {{(dso_local )?}}constant
+// CHECK-UNIX: @_ZTI6Test0a = external {{(dso_local )?}}constant
+// CHECK-MINGW: @_ZTI6Test0a = linkonce_odr {{(dso_local )?}}constant
// This is not a key function.
void Test0a::foo() {}
@@ -48,7 +49,8 @@ void Test0b::foo() {}
// V-table should be defined externally.
Test0b::Test0b() { use(typeid(Test0b)); }
// CHECK: @_ZTV6Test0b = external {{(dso_local )?}}unnamed_addr constant
-// CHECK: @_ZTI6Test0b = external {{(dso_local )?}}constant
+// CHECK-UNIX: @_ZTI6Test0b = external {{(dso_local )?}}constant
+// CHECK-MINGW: @_ZTI6Test0b = linkonce_odr {{(dso_local )?}}constant
/*** Test1a ******************************************************************/
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index 4a47e3c9d2..115303f62b 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -1412,7 +1412,7 @@ struct D : virtual C {
// CHECK-35-NEXT: 13 | void Test28::B::b()
//
// CHECK-35: VTable indices for 'Test28::E' (1 entries).
-// CHECK-35-NEXT : 0 | void Test28::E::e()
+// CHECK-35-NEXT: 0 | void Test28::E::e()
// CHECK-35: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
// CHECK-35-NEXT: 0 | vbase_offset (8)
diff --git a/test/CodeGenCXX/wasm-eh.cpp b/test/CodeGenCXX/wasm-eh.cpp
index ea77fec820..fbbf4dd3fd 100644
--- a/test/CodeGenCXX/wasm-eh.cpp
+++ b/test/CodeGenCXX/wasm-eh.cpp
@@ -62,7 +62,7 @@ void test0() {
// CHECK-NEXT: br label %[[TRY_CONT_BB]]
// CHECK: [[RETHROW_BB]]:
-// CHECK-NEXT: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: call void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
// CHECK-NEXT: unreachable
// Single catch-all
@@ -232,7 +232,7 @@ void test6() {
// CHECK: catchret from %[[CATCHPAD]] to label %{{.*}}
// CHECK: [[RETHROW_BB]]:
-// CHECK-NEXT: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
// CHECK-NEXT: to label %[[UNREACHABLE_BB:.*]] unwind label %[[EHCLEANUP_BB1:.*]]
// CHECK: [[EHCLEANUP_BB2]]:
@@ -296,7 +296,7 @@ void test7() {
// CHECK: catchret from %[[CATCHPAD0]] to label
-// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
+// CHECK: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
// CHECK: %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CATCHPAD0]] []
// CHECK: cleanupret from %[[CLEANUPPAD1]] unwind label
@@ -368,11 +368,11 @@ void test8() {
// CHECK: catchret from %[[CATCHPAD1]] to label
-// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ]
+// CHECK: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ]
// CHECK: catchret from %[[CATCHPAD0]] to label
-// CHECK: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
+// CHECK: call void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
// CHECK: unreachable
// CHECK: %[[CLEANUPPAD0:.*]] = cleanuppad within %[[CATCHPAD1]] []