diff options
Diffstat (limited to 'test/CodeGenCXX')
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]] [] |