diff options
Diffstat (limited to 'clang/test/CodeGenCXX')
27 files changed, 513 insertions, 146 deletions
diff --git a/clang/test/CodeGenCXX/aarch64-arguments.cpp b/clang/test/CodeGenCXX/aarch64-arguments.cpp index ffb0caf..3206e38 100644 --- a/clang/test/CodeGenCXX/aarch64-arguments.cpp +++ b/clang/test/CodeGenCXX/aarch64-arguments.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple arm64-none-linux -emit-llvm -w -o - %s | FileCheck -check-prefix=PCS %s -// PCS: define{{.*}} void @{{.*}}(i8 %a +// PCS: define{{.*}} void @{{.*}}(i64 %a.coerce) struct s0 {}; void f0(s0 a) {} diff --git a/clang/test/CodeGenCXX/alloc-token-builtin.cpp b/clang/test/CodeGenCXX/alloc-token-builtin.cpp new file mode 100644 index 0000000..adadf7b --- /dev/null +++ b/clang/test/CodeGenCXX/alloc-token-builtin.cpp @@ -0,0 +1,97 @@ +// To test IR generation of the builtin without evaluating the LLVM intrinsic, +// we set the mode to a stateful mode, which prohibits constant evaluation. +// RUN: %clang_cc1 -triple x86_64-linux-gnu -Werror -std=c++20 -emit-llvm -falloc-token-mode=random -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-CODEGEN +// RUN: %clang_cc1 -triple x86_64-linux-gnu -Werror -std=c++20 -emit-llvm -falloc-token-max=2 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LOWER + +extern "C" void *my_malloc(unsigned long, unsigned long); + +struct NoPtr { + int x; + long y; +}; + +struct WithPtr { + int a; + char *buf; +}; + +int unevaluated_fn(); + +// CHECK-LABEL: @_Z16test_builtin_intv( +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT:[0-9]+]]) +// CHECK-LOWER: ret i64 0 +unsigned long test_builtin_int() { + return __builtin_infer_alloc_token(sizeof(1)); +} + +// CHECK-LABEL: @_Z16test_builtin_ptrv( +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_PTR:[0-9]+]]) +// CHECK-LOWER: ret i64 1 +unsigned long test_builtin_ptr() { + return __builtin_infer_alloc_token(sizeof(int *)); +} + +// CHECK-LABEL: @_Z25test_builtin_struct_noptrv( +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_NOPTR:[0-9]+]]) +// CHECK-LOWER: ret i64 0 +unsigned long test_builtin_struct_noptr() { + return __builtin_infer_alloc_token(sizeof(NoPtr)); +} + +// CHECK-LABEL: @_Z25test_builtin_struct_w_ptrv( +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_WITHPTR:[0-9]+]]) +// CHECK-LOWER: ret i64 1 +unsigned long test_builtin_struct_w_ptr() { + return __builtin_infer_alloc_token(sizeof(WithPtr), 123); +} + +// CHECK-LABEL: @_Z24test_builtin_unevaluatedv( +// CHECK-NOT: call{{.*}}unevaluated_fn +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT:[0-9]+]]) +// CHECK-LOWER: ret i64 0 +unsigned long test_builtin_unevaluated() { + return __builtin_infer_alloc_token(sizeof(int) * unevaluated_fn()); +} + +// CHECK-LABEL: @_Z36test_builtin_unsequenced_unevaluatedi( +// CHECK: add nsw +// CHECK-NOT: add nsw +// CHECK-CODEGEN: %[[REG:[0-9]+]] = call i64 @llvm.alloc.token.id.i64(metadata ![[META_UNKNOWN:[0-9]+]]) +// CHECK-CODEGEN: call{{.*}}@my_malloc({{.*}}, i64 noundef %[[REG]]) +// CHECK-LOWER: call{{.*}}@my_malloc({{.*}}, i64 noundef 0) +void test_builtin_unsequenced_unevaluated(int x) { + my_malloc(++x, __builtin_infer_alloc_token(++x)); +} + +// CHECK-LABEL: @_Z20test_builtin_unknownv( +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_UNKNOWN:[0-9]+]]) +// CHECK-LOWER: ret i64 0 +unsigned long test_builtin_unknown() { + return __builtin_infer_alloc_token(4096); +} + +// Test template instantiation. +template <typename T> +constexpr unsigned long get_token() { + return __builtin_infer_alloc_token(sizeof(T)); +} + +// CHECK-LABEL: @_Z13get_token_intv() +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT]]) +// CHECK-LOWER: ret i64 0 +unsigned long get_token_int() { + return get_token<int>(); +} + +// CHECK-LABEL: @_Z13get_token_ptrv() +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_PTR]]) +// CHECK-LOWER: ret i64 1 +unsigned long get_token_ptr() { + return get_token<int *>(); +} + +// CHECK-CODEGEN: ![[META_INT]] = !{!"int", i1 false} +// CHECK-CODEGEN: ![[META_PTR]] = !{!"int *", i1 true} +// CHECK-CODEGEN: ![[META_NOPTR]] = !{!"NoPtr", i1 false} +// CHECK-CODEGEN: ![[META_WITHPTR]] = !{!"WithPtr", i1 true} +// CHECK-CODEGEN: ![[META_UNKNOWN]] = !{} diff --git a/clang/test/CodeGenCXX/alloc-token.cpp b/clang/test/CodeGenCXX/alloc-token.cpp index feed808..9884220 100644 --- a/clang/test/CodeGenCXX/alloc-token.cpp +++ b/clang/test/CodeGenCXX/alloc-token.cpp @@ -17,10 +17,10 @@ struct __sized_ptr_t { size_t n; }; enum class __hot_cold_t : uint8_t; -__sized_ptr_t __size_returning_new(size_t size); -__sized_ptr_t __size_returning_new_hot_cold(size_t, __hot_cold_t); -__sized_ptr_t __size_returning_new_aligned(size_t, std::align_val_t); -__sized_ptr_t __size_returning_new_aligned_hot_cold(size_t, std::align_val_t, __hot_cold_t); +__sized_ptr_t __size_returning_new(size_t size) __attribute__((malloc_span)); +__sized_ptr_t __size_returning_new_hot_cold(size_t, __hot_cold_t) __attribute__((malloc_span)); +__sized_ptr_t __size_returning_new_aligned(size_t, std::align_val_t) __attribute__((malloc_span)); +__sized_ptr_t __size_returning_new_aligned_hot_cold(size_t, std::align_val_t, __hot_cold_t) __attribute__((malloc_span)); } void *sink; // prevent optimizations from removing the calls @@ -101,12 +101,11 @@ int *test_new_array_nothrow() { } // CHECK-LABEL: define dso_local void @_Z23test_size_returning_newv( -// CHECK: call { ptr, i64 } @__size_returning_new(i64 noundef 8) -// CHECK: call { ptr, i64 } @__size_returning_new_hot_cold(i64 noundef 8, i8 noundef zeroext 1) -// CHECK: call { ptr, i64 } @__size_returning_new_aligned(i64 noundef 8, i64 noundef 32) -// CHECK: call { ptr, i64 } @__size_returning_new_aligned_hot_cold(i64 noundef 8, i64 noundef 32, i8 noundef zeroext 1) +// CHECK: call { ptr, i64 } @__size_returning_new(i64 noundef 8){{.*}} !alloc_token [[META_LONG]] +// CHECK: call { ptr, i64 } @__size_returning_new_hot_cold(i64 noundef 8, i8 noundef zeroext 1){{.*}} !alloc_token [[META_LONG]] +// CHECK: call { ptr, i64 } @__size_returning_new_aligned(i64 noundef 8, i64 noundef 32){{.*}} !alloc_token [[META_LONG]] +// CHECK: call { ptr, i64 } @__size_returning_new_aligned_hot_cold(i64 noundef 8, i64 noundef 32, i8 noundef zeroext 1){{.*}}_token [[META_LONG]] void test_size_returning_new() { - // FIXME: Support __size_returning_new variants. sink = __size_returning_new(sizeof(long)).p; sink = __size_returning_new_hot_cold(sizeof(long), __hot_cold_t{1}).p; sink = __size_returning_new_aligned(sizeof(long), std::align_val_t{32}).p; diff --git a/clang/test/CodeGenCXX/arm64-darwinpcs.cpp b/clang/test/CodeGenCXX/arm64-darwinpcs.cpp index a0b0d9e..ef0e2da 100644 --- a/clang/test/CodeGenCXX/arm64-darwinpcs.cpp +++ b/clang/test/CodeGenCXX/arm64-darwinpcs.cpp @@ -7,7 +7,7 @@ void test_extensions(bool a, char b, short c) {} struct Empty {}; void test_empty(Empty e) {} -// CHECK: define{{.*}} void @_Z10test_empty5Empty(i8 +// CHECK: define{{.*}} void @_Z10test_empty5Empty(i64 %e.coerce) // CHECK-DARWIN: define{{.*}} void @_Z10test_empty5Empty() struct HFA { diff --git a/clang/test/CodeGenCXX/attr-callback.cpp b/clang/test/CodeGenCXX/attr-callback.cpp index c3456d6c..efa705b 100644 --- a/clang/test/CodeGenCXX/attr-callback.cpp +++ b/clang/test/CodeGenCXX/attr-callback.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++23 %s -emit-llvm -o - | FileCheck %s struct Base { @@ -47,9 +47,30 @@ struct Derived_2 : public Base { // CHECK-NOT: !callback void Derived_2::virtual_1(void (*callback)(void)) {} +class ExplicitParameterObject { + __attribute__((callback(1, 0))) void implicit_this_idx(void (*callback)(ExplicitParameterObject*)); + __attribute__((callback(1, this))) void implicit_this_identifier(void (*callback)(ExplicitParameterObject*)); + __attribute__((callback(2, 1))) void explicit_this_idx(this ExplicitParameterObject* self, void (*callback)(ExplicitParameterObject*)); + __attribute__((callback(2, self))) void explicit_this_identifier(this ExplicitParameterObject* self, void (*callback)(ExplicitParameterObject*)); +}; + +// CHECK-DAG: define{{.*}} void @_ZN23ExplicitParameterObject17implicit_this_idxEPFvPS_E({{[^!]*!callback}} ![[cid3:[0-9]+]] +void ExplicitParameterObject::implicit_this_idx(void (*callback)(ExplicitParameterObject*)) {} + +// CHECK-DAG: define{{.*}} void @_ZN23ExplicitParameterObject24implicit_this_identifierEPFvPS_E({{[^!]*!callback}} ![[cid3]] +void ExplicitParameterObject::implicit_this_identifier(void (*callback)(ExplicitParameterObject*)) {} + +// CHECK-DAG: define{{.*}} void @_ZNH23ExplicitParameterObject17explicit_this_idxEPS_PFvS0_E({{[^!]*!callback}} ![[cid3]] +void ExplicitParameterObject::explicit_this_idx(this ExplicitParameterObject* self, void (*callback)(ExplicitParameterObject*)) {} + +// CHECK-DAG: define{{.*}} void @_ZNH23ExplicitParameterObject24explicit_this_identifierEPS_PFvS0_E({{[^!]*!callback}} ![[cid3]] +void ExplicitParameterObject::explicit_this_identifier(this ExplicitParameterObject* self, void (*callback)(ExplicitParameterObject*)) {} + // 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} +// CHECK-DAG: ![[cid3]] = !{![[cid3b:[0-9]+]]} +// CHECK-DAG: ![[cid3b]] = !{i64 1, i64 0, i1 false} diff --git a/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/clang/test/CodeGenCXX/attr-cpuspecific.cpp index 225c6a5..fc0e1da 100644 --- a/clang/test/CodeGenCXX/attr-cpuspecific.cpp +++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX -// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX -// RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefix=WINDOWS +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX +// RUN: %clang_cc1 -triple x86_64-apple-macos -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX +// RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WINDOWS struct S { __attribute__((cpu_specific(atom))) @@ -16,14 +16,16 @@ void foo() { // LINUX: @_ZN1S4FuncEv = weak_odr alias void (ptr), ptr @_ZN1S4FuncEv.ifunc // LINUX: @_ZN1S4FuncEv.ifunc = weak_odr ifunc void (ptr), ptr @_ZN1S4FuncEv.resolver -// LINUX: define weak_odr ptr @_ZN1S4FuncEv.resolver +// LINUX: define weak_odr ptr @_ZN1S4FuncEv.resolver() #[[ATTR_RESOLVER:[0-9]+]] // LINUX: ret ptr @_ZN1S4FuncEv.S // LINUX: ret ptr @_ZN1S4FuncEv.O // LINUX: declare void @_ZN1S4FuncEv.S // LINUX: define linkonce_odr void @_ZN1S4FuncEv.O -// WINDOWS: define weak_odr dso_local void @"?Func@S@@QEAAXXZ"(ptr %0) comdat +// WINDOWS: define weak_odr dso_local void @"?Func@S@@QEAAXXZ"(ptr %0) #[[ATTR_RESOLVER:[0-9]+]] comdat // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(ptr %0) // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(ptr %0) // WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S" // WINDOWS: define linkonce_odr dso_local void @"?Func@S@@QEAAXXZ.O" + +// CHECK: attributes #[[ATTR_RESOLVER]] = { disable_sanitizer_instrumentation } diff --git a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp index a502d24..1992f08 100644 --- a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp @@ -106,7 +106,8 @@ void run_foo_tml() { // CHECK-NEXT: ret i32 4 // // -// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovli.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovli.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER:[0-9]+]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -147,7 +148,8 @@ void run_foo_tml() { // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIssE7foo_tmlEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIssE7foo_tmlEv.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 diff --git a/clang/test/CodeGenCXX/attr-target-clones-riscv.cpp b/clang/test/CodeGenCXX/attr-target-clones-riscv.cpp index 7e57b14..693fec0 100644 --- a/clang/test/CodeGenCXX/attr-target-clones-riscv.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones-riscv.cpp @@ -52,7 +52,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo1v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo1v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER:[0-9]+]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -83,7 +84,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo2v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo2v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -115,7 +117,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo3v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo3v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -140,7 +143,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 4 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo4v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo4v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -159,7 +163,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 5 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo5v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo5v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: ret ptr @_Z4foo5v.default @@ -177,7 +182,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo6v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo6v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -214,7 +220,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo7v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo7v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -265,7 +272,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo8v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo8v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -316,7 +324,8 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo9v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo9v.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -367,6 +376,7 @@ int bar() { return foo1() + foo2() + foo3() + foo4() + foo5()+ foo6() + foo7() + // //. // CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+i,+m,+zmmul" } +// CHECK: attributes #[[ATTR_RESOLVER]] = { disable_sanitizer_instrumentation } // CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+i,+m,+zbb,+zmmul" } // CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+c,+i,+m,+zbb,+zca,+zmmul" } // CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+d,+f,+i,+m,+v,+zbb,+zicsr,+zmmul,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" } diff --git a/clang/test/CodeGenCXX/attr-target-clones.cpp b/clang/test/CodeGenCXX/attr-target-clones.cpp index 0814df3..5cc9c61 100644 --- a/clang/test/CodeGenCXX/attr-target-clones.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones.cpp @@ -1,59 +1,39 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS -// DARWIN-NOT: comdat // Aliases for ifuncs -// ITANIUM: @_Z10overloadedi.ifunc = weak_odr alias i32 (i32), ptr @_Z10overloadedi -// ITANIUM: @_Z10overloadedPKc.ifunc = weak_odr alias i32 (ptr), ptr @_Z10overloadedPKc -// ITANIUM: @_ZN1CIssE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIssE3fooEv -// ITANIUM: @_ZN1CIisE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIisE3fooEv -// ITANIUM: @_ZN1CIdfE3fooEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN1CIdfE3fooEv // Overloaded ifuncs -// ITANIUM: @_Z10overloadedi = weak_odr ifunc i32 (i32), ptr @_Z10overloadedi.resolver -// ITANIUM: @_Z10overloadedPKc = weak_odr ifunc i32 (ptr), ptr @_Z10overloadedPKc.resolver // struct 'C' ifuncs, note the 'float, U' one doesn't get one. -// ITANIUM: @_ZN1CIssE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIssE3fooEv.resolver -// ITANIUM: @_ZN1CIisE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIisE3fooEv.resolver -// ITANIUM: @_ZN1CIdfE3fooEv = weak_odr ifunc i32 (ptr), ptr @_ZN1CIdfE3fooEv.resolver +// int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return 1; } -// ITANIUM: define {{.*}}i32 @_Z10overloadedi.sse4.2.0(i32{{.+}}) -// ITANIUM: define {{.*}}i32 @_Z10overloadedi.default.1(i32{{.+}}) -// ITANIUM: define weak_odr ptr @_Z10overloadedi.resolver() -// LINUX-SAME: comdat -// ITANIUM: ret ptr @_Z10overloadedi.sse4.2.0 -// ITANIUM: ret ptr @_Z10overloadedi.default.1 - -// WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.sse4.2.0"(i32{{.+}}) -// WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.default.1"(i32{{.+}}) -// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHH@Z"(i32{{.+}}) comdat -// WINDOWS: call i32 @"?overloaded@@YAHH@Z.sse4.2.0" -// WINDOWS: call i32 @"?overloaded@@YAHH@Z.default.1" + +// int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const char *) { return 2; } -// ITANIUM: define {{.*}}i32 @_Z10overloadedPKc.arch_ivybridge.0(ptr{{.+}}) -// ITANIUM: define {{.*}}i32 @_Z10overloadedPKc.default.1(ptr{{.+}}) -// ITANIUM: define weak_odr ptr @_Z10overloadedPKc.resolver() -// LINUX-SAME: comdat -// ITANIUM: ret ptr @_Z10overloadedPKc.arch_ivybridge.0 -// ITANIUM: ret ptr @_Z10overloadedPKc.default.1 - -// WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0"(ptr{{.+}}) -// WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.default.1"(ptr{{.+}}) -// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHPEBD@Z"(ptr{{.+}}) comdat -// WINDOWS: call i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0" -// WINDOWS: call i32 @"?overloaded@@YAHPEBD@Z.default.1" + +// LINUX-LABEL: define dso_local void @_Z14use_overloadedv( +// LINUX-SAME: ) #[[ATTR1:[0-9]+]] { +// LINUX-NEXT: [[ENTRY:.*:]] +// LINUX-NEXT: [[CALL:%.*]] = call noundef i32 @_Z10overloadedi(i32 noundef 1) +// LINUX-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z10overloadedPKc(ptr noundef null) +// LINUX-NEXT: ret void +// +// DARWIN-LABEL: define void @_Z14use_overloadedv( +// DARWIN-SAME: ) #[[ATTR1:[0-9]+]] { +// DARWIN-NEXT: [[ENTRY:.*:]] +// DARWIN-NEXT: [[CALL:%.*]] = call noundef i32 @_Z10overloadedi(i32 noundef 1) +// DARWIN-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z10overloadedPKc(ptr noundef null) +// DARWIN-NEXT: ret void +// void use_overloaded() { overloaded(1); - // ITANIUM: call noundef i32 @_Z10overloadedi - // WINDOWS: call noundef i32 @"?overloaded@@YAHH@Z" overloaded(nullptr); - // ITANIUM: call noundef i32 @_Z10overloadedPKc - // WINDOWS: call noundef i32 @"?overloaded@@YAHPEBD@Z" } template<typename T, typename U> @@ -69,67 +49,56 @@ struct C<float, U> { int foo(){ return 2;} }; template<> +// struct C<double, float> { int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 3;} }; +// LINUX-LABEL: define dso_local void @_Z16uses_specializedv( +// LINUX-SAME: ) #[[ATTR1]] { +// LINUX-NEXT: [[ENTRY:.*:]] +// LINUX-NEXT: [[C:%.*]] = alloca [[STRUCT_C:%.*]], align 1 +// LINUX-NEXT: [[C2:%.*]] = alloca [[STRUCT_C_0:%.*]], align 1 +// LINUX-NEXT: [[C3:%.*]] = alloca [[STRUCT_C_1:%.*]], align 1 +// LINUX-NEXT: [[C4:%.*]] = alloca [[STRUCT_C_2:%.*]], align 1 +// LINUX-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN1CIssE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C]]) +// LINUX-NEXT: [[CALL1:%.*]] = call noundef i32 @_ZN1CIisE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C2]]) +// LINUX-NEXT: [[CALL2:%.*]] = call noundef i32 @_ZN1CIfsE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C3]]) +// LINUX-NEXT: [[CALL3:%.*]] = call noundef i32 @_ZN1CIdfE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C4]]) +// LINUX-NEXT: ret void +// +// DARWIN-LABEL: define void @_Z16uses_specializedv( +// DARWIN-SAME: ) #[[ATTR1]] { +// DARWIN-NEXT: [[ENTRY:.*:]] +// DARWIN-NEXT: [[C:%.*]] = alloca [[STRUCT_C:%.*]], align 1 +// DARWIN-NEXT: [[C2:%.*]] = alloca [[STRUCT_C_0:%.*]], align 1 +// DARWIN-NEXT: [[C3:%.*]] = alloca [[STRUCT_C_1:%.*]], align 1 +// DARWIN-NEXT: [[C4:%.*]] = alloca [[STRUCT_C_2:%.*]], align 1 +// DARWIN-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN1CIssE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C]]) +// DARWIN-NEXT: [[CALL1:%.*]] = call noundef i32 @_ZN1CIisE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C2]]) +// DARWIN-NEXT: [[CALL2:%.*]] = call noundef i32 @_ZN1CIfsE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C3]]) +// DARWIN-NEXT: [[CALL3:%.*]] = call noundef i32 @_ZN1CIdfE3fooEv(ptr noundef nonnull align 1 dereferenceable(1) [[C4]]) +// DARWIN-NEXT: ret void +// void uses_specialized() { C<short, short> c; c.foo(); - // ITANIUM: call noundef i32 @_ZN1CIssE3fooEv(ptr - // WINDOWS: call noundef i32 @"?foo@?$C@FF@@QEAAHXZ"(ptr C<int, short> c2; c2.foo(); - // ITANIUM: call noundef i32 @_ZN1CIisE3fooEv(ptr - // WINDOWS: call noundef i32 @"?foo@?$C@HF@@QEAAHXZ"(ptr C<float, short> c3; c3.foo(); // Note this is not an ifunc/mv - // ITANIUM: call noundef i32 @_ZN1CIfsE3fooEv(ptr - // WINDOWS: call noundef i32 @"?foo@?$C@MF@@QEAAHXZ"(ptr C<double, float> c4; c4.foo(); - // ITANIUM: call noundef i32 @_ZN1CIdfE3fooEv(ptr - // WINDOWS: call noundef i32 @"?foo@?$C@NM@@QEAAHXZ"(ptr } -// ITANIUM: define weak_odr ptr @_ZN1CIssE3fooEv.resolver() -// LINUX-SAME: comdat -// ITANIUM: ret ptr @_ZN1CIssE3fooEv.sse4.2.0 -// ITANIUM: ret ptr @_ZN1CIssE3fooEv.default.1 - -// WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ"(ptr -// WINDOWS: call i32 @"?foo@?$C@FF@@QEAAHXZ.sse4.2.0" -// WINDOWS: call i32 @"?foo@?$C@FF@@QEAAHXZ.default.1" - -// ITANIUM: define weak_odr ptr @_ZN1CIisE3fooEv.resolver() -// LINUX-SAME: comdat -// ITANIUM: ret ptr @_ZN1CIisE3fooEv.sse4.2.0 -// ITANIUM: ret ptr @_ZN1CIisE3fooEv.default.1 - -// WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ"(ptr -// WINDOWS: call i32 @"?foo@?$C@HF@@QEAAHXZ.sse4.2.0" -// WINDOWS: call i32 @"?foo@?$C@HF@@QEAAHXZ.default.1" - -// ITANIUM: define weak_odr ptr @_ZN1CIdfE3fooEv.resolver() -// LINUX-SAME: comdat -// ITANIUM: ret ptr @_ZN1CIdfE3fooEv.sse4.2.0 -// ITANIUM: ret ptr @_ZN1CIdfE3fooEv.default.1 - -// WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ"(ptr -// WINDOWS: call i32 @"?foo@?$C@NM@@QEAAHXZ.sse4.2.0" -// WINDOWS: call i32 @"?foo@?$C@NM@@QEAAHXZ.default.1" - -// ITANIUM: define {{.*}}i32 @_ZN1CIssE3fooEv.sse4.2.0(ptr -// ITANIUM: define {{.*}}i32 @_ZN1CIssE3fooEv.default.1(ptr -// ITANIUM: define {{.*}}i32 @_ZN1CIisE3fooEv.sse4.2.0(ptr -// ITANIUM: define {{.*}}i32 @_ZN1CIisE3fooEv.default.1(ptr -// ITANIUM: define {{.*}}i32 @_ZN1CIdfE3fooEv.sse4.2.0(ptr -// ITANIUM: define {{.*}}i32 @_ZN1CIdfE3fooEv.default.1(ptr - -// WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ.sse4.2.0"(ptr -// WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ.default.1"(ptr -// WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ.sse4.2.0"(ptr -// WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ.default.1"(ptr -// WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ.sse4.2.0"(ptr -// WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ.default.1"(ptr + + + + + + + +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// ITANIUM: {{.*}} +// WINDOWS: {{.*}} diff --git a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp index 8f2fb5e..a7681e5 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp @@ -60,27 +60,27 @@ int bar() { // WINDOWS: call noundef i32 @"?foo@@YAHH@Z.resolver"(i32 noundef 1) // WINDOWS: call noundef i32 @"?foo@ns@@YAHH@Z.resolver"(i32 noundef 2) -// ITANIUM: define weak_odr ptr @_Z3fooi.resolver() +// ITANIUM: define weak_odr ptr @_Z3fooi.resolver() #[[ATTR_RESOLVER:[0-9]+]] // LINUX-SAME: comdat // ITANIUM: ret ptr @_Z3fooi.arch_sandybridge // ITANIUM: ret ptr @_Z3fooi.arch_ivybridge // ITANIUM: ret ptr @_Z3fooi.sse4.2 // ITANIUM: ret ptr @_Z3fooi -// WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) #[[ATTR_RESOLVER:[0-9]+]] comdat // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z"(i32 %0) -// ITANIUM: define weak_odr ptr @_ZN2ns3fooEi.resolver() +// ITANIUM: define weak_odr ptr @_ZN2ns3fooEi.resolver() #[[ATTR_RESOLVER]] // LINUX-SAME: comdat // ITANIUM: ret ptr @_ZN2ns3fooEi.arch_sandybridge // ITANIUM: ret ptr @_ZN2ns3fooEi.arch_ivybridge // ITANIUM: ret ptr @_ZN2ns3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN2ns3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) #[[ATTR_RESOLVER]] comdat // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0) diff --git a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp index f956890..59581b4 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp @@ -180,7 +180,8 @@ int templ_use() { // ITANIUM: ret ptr @_ZN5templIdE3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN5templIdE3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) +// WINDOWS-SAME: comdat // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2" diff --git a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp index 3c56cad..8d6b178 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp @@ -54,7 +54,8 @@ int bar() { // ITANIUM: ret ptr @_ZN1S3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN1S3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) +// WINDOWS-SAME: comdat // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr %0, i32 %1) diff --git a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp index e30fbf4e..5f00083 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp @@ -61,7 +61,8 @@ int bar2() { // ITANIUM: ret ptr @_Z12foo_overloadv.sse4.2 // ITANIUM: ret ptr @_Z12foo_overloadv -// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() +// WINDOWS-SAME comdat // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge" // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_ivybridge" // WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2" @@ -74,7 +75,8 @@ int bar2() { // ITANIUM: ret ptr @_Z12foo_overloadi.sse4.2 // ITANIUM: ret ptr @_Z12foo_overloadi -// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) +// WINDOWS-SAME: comdat // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_sandybridge" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_ivybridge" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.sse4.2" diff --git a/clang/test/CodeGenCXX/attr-target-version-riscv.cpp b/clang/test/CodeGenCXX/attr-target-version-riscv.cpp index ffb4576..dd0e682 100644 --- a/clang/test/CodeGenCXX/attr-target-version-riscv.cpp +++ b/clang/test/CodeGenCXX/attr-target-version-riscv.cpp @@ -49,7 +49,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo1v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo1v.resolver() +// CHECK-SAME: comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -74,7 +75,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo2v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo2v.resolver() +// CHECK-SAME: comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -112,7 +114,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo3v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo3v.resolver() +// CHECK-SAME comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -150,7 +153,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo4v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo4v.resolver() +// CHECK-SAME: comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -201,7 +205,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo5v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo5v.resolver() +// CHECK-SAME: comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -252,7 +257,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo6v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo6v.resolver() +// CHECK-SAME: comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 @@ -303,7 +309,8 @@ int bar() { return foo1() + foo2() + foo3(); } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z4foo7v.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z4foo7v.resolver() +// CHECK-SAME: comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_riscv_feature_bits(ptr null) // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [2 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8 diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index b6ba07e..c62b026 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -231,7 +231,8 @@ int bar() { // CHECK-NEXT: ret i32 [[ADD3]] // // -// CHECK-LABEL: define weak_odr ptr @_Z3fooi.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z3fooi.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER:[0-9]+]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -245,7 +246,8 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3fooi.default // // -// CHECK-LABEL: define weak_odr ptr @_Z3foov.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z3foov.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -259,7 +261,8 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3foov.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass3gooEi.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass3gooEi.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -281,7 +284,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass23unused_with_default_defEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass23unused_with_default_defEv.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -295,7 +299,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass32unused_with_imp +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -309,7 +314,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -322,6 +328,7 @@ int bar() { // CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default // +// CHECK: attributes #[[ATTR_RESOLVER]] = { disable_sanitizer_instrumentation } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp b/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp index d30631f..ca27193 100644 --- a/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp +++ b/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp @@ -22,3 +22,35 @@ void test_ldrex() { void tset_strex() { __builtin_arm_strex(true, &b); } + +#ifdef __arm__ +// ARM exclusive atomic builtins + +long long c; + +// CHECK-LABEL: @_Z11test_ldrexdv() +// CHECK: [[STRUCTRES:%.*]] = call { i32, i32 } @llvm.arm.ldrexd(ptr @c) +// CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1 +// CHECK: [[RESLO:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 0 +// CHECK: [[RESHI64:%.*]] = zext i32 [[RESHI]] to i64 +// CHECK: [[RESLO64:%.*]] = zext i32 [[RESLO]] to i64 +// CHECK: [[RESHIHI:%.*]] = shl nuw i64 [[RESHI64]], 32 +// CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]] +// CHECK: store i64 [[INTRES]], ptr @c, align 8 + +void test_ldrexd() { + c = __builtin_arm_ldrexd(&c); +} + +// CHECK-LABEL: @_Z11tset_strexdv() +// CHECK: store i64 42, ptr [[TMP:%.*]], align 8 +// CHECK: [[LOHI:%.*]] = load { i32, i32 }, ptr [[TMP]] +// CHECK: [[LO:%.*]] = extractvalue { i32, i32 } [[LOHI]], 0 +// CHECK: [[HI:%.*]] = extractvalue { i32, i32 } [[LOHI]], 1 +// CHECK: %{{.*}} = call i32 @llvm.arm.strexd(i32 [[LO]], i32 [[HI]], ptr @c) + +void tset_strexd() { + __builtin_arm_strexd(42, &c); +} + +#endif diff --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp index 9169f3a..ef30a25 100644 --- a/clang/test/CodeGenCXX/builtins.cpp +++ b/clang/test/CodeGenCXX/builtins.cpp @@ -83,3 +83,59 @@ int structured_binding_size() { return __builtin_structured_binding_size(S2); // CHECK: ret i32 2 } + +void test_int_reference(int& a) { + __builtin_bswapg(a); +} +// CHECK-LABEL: @_Z18test_int_referenceRi +// CHECK: store ptr %a, ptr +// CHECK: load ptr, ptr +// CHECK: load i32, ptr +// CHECK: call i32 @llvm.bswap.i32 + +void test_long_reference(long& a) { + __builtin_bswapg(a); +} +// CHECK-LABEL: @_Z19test_long_referenceRl +// CHECK: store ptr %a, ptr +// CHECK: load ptr, ptr +// CHECK: load i64, ptr +// CHECK: call i64 @llvm.bswap.i64 + +void test_short_reference(short& a) { + __builtin_bswapg(a); +} +// CHECK-LABEL: @_Z20test_short_referenceRs +// CHECK: store ptr %a, ptr +// CHECK: load ptr, ptr +// CHECK: load i16, ptr +// CHECK: call i16 @llvm.bswap.i16 + +void test_char_reference(char& a) { + __builtin_bswapg(a); +} +// CHECK-LABEL: @_Z19test_char_referenceRc +// CHECK: store ptr %a, ptr +// CHECK: load ptr, ptr +// CHECK-NOT: call i8 @llvm.bswap.i8 +// CHECK: ret void + +void test_bitint() { + _BitInt(8) a = 0x12; + __builtin_bswapg(a); + _BitInt(16) b = 0x1234; + __builtin_bswapg(b); + _BitInt(32) c = 0x00001234; + __builtin_bswapg(c); + _BitInt(64) d = 0x0000000000001234; + __builtin_bswapg(d); + _BitInt(128) e = ~(_BitInt(128))0; + __builtin_bswapg(e); +} +// CHECK-LABEL: @_Z11test_bitintv +// CHECK-NOT: call i8 @llvm.bswap.i8 +// CHECK: call i16 @llvm.bswap.i16 +// CHECK: call i32 @llvm.bswap.i32 +// CHECK: call i64 @llvm.bswap.i64 +// CHECK: call i128 @llvm.bswap.i128 +// CHECK: ret void diff --git a/clang/test/CodeGenCXX/cfi-vcall-trap-recover-runtime.cpp b/clang/test/CodeGenCXX/cfi-vcall-trap-recover-runtime.cpp index 3e9328a..2451d31 100644 --- a/clang/test/CodeGenCXX/cfi-vcall-trap-recover-runtime.cpp +++ b/clang/test/CodeGenCXX/cfi-vcall-trap-recover-runtime.cpp @@ -9,6 +9,11 @@ // RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -fsanitize-recover=cfi-vcall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=RECOVER_MIN %s +// RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -fsanitize-recover=cfi-vcall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -fsanitize-handler-preserve-all-regs -emit-llvm -o - %s | FileCheck --check-prefix=PRESERVE_MIN %s + +// RUN: %clang_cc1 -fsanitize=cfi-vcall -fno-sanitize-trap=cfi-vcall -fsanitize-minimal-runtime -flto -fvisibility=hidden -triple x86_64-unknown-linux -fwhole-program-vtables -fsanitize-handler-preserve-all-regs -emit-llvm -o - %s | FileCheck --check-prefix=ABORT_MIN %s + + struct S1 { virtual void f(); }; @@ -111,6 +116,25 @@ struct S1 { // RECOVER_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]]) // RECOVER_MIN-NEXT: ret void // +// PRESERVE_MIN-LABEL: define hidden void @_Z3s1fP2S1( +// PRESERVE_MIN-SAME: ptr noundef [[S1:%.*]]) #[[ATTR0:[0-9]+]] { +// PRESERVE_MIN-NEXT: [[ENTRY:.*:]] +// PRESERVE_MIN-NEXT: [[S1_ADDR:%.*]] = alloca ptr, align 8 +// PRESERVE_MIN-NEXT: store ptr [[S1]], ptr [[S1_ADDR]], align 8 +// PRESERVE_MIN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S1_ADDR]], align 8 +// PRESERVE_MIN-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8 +// PRESERVE_MIN-NEXT: [[TMP1:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS2S1"), !nosanitize [[META5:![0-9]+]] +// PRESERVE_MIN-NEXT: [[TMP2:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"all-vtables"), !nosanitize [[META5]] +// PRESERVE_MIN-NEXT: br i1 [[TMP1]], label %[[CONT:.*]], label %[[HANDLER_CFI_CHECK_FAIL:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]] +// PRESERVE_MIN: [[HANDLER_CFI_CHECK_FAIL]]: +// PRESERVE_MIN-NEXT: call preserve_allcc void @__ubsan_handle_cfi_check_fail_minimal_preserve() #[[ATTR3:[0-9]+]], !nosanitize [[META5]] +// PRESERVE_MIN-NEXT: br label %[[CONT]], !nosanitize [[META5]] +// PRESERVE_MIN: [[CONT]]: +// PRESERVE_MIN-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 0 +// PRESERVE_MIN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VFN]], align 8 +// PRESERVE_MIN-NEXT: call void [[TMP3]](ptr noundef nonnull align 8 dereferenceable(8) [[TMP0]]) +// PRESERVE_MIN-NEXT: ret void +// void s1f(S1 *s1) { s1->f(); } @@ -130,3 +154,6 @@ void s1f(S1 *s1) { // RECOVER_MIN: [[META5]] = !{} // RECOVER_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1} //. +// PRESERVE_MIN: [[META5]] = !{} +// PRESERVE_MIN: [[PROF6]] = !{!"branch_weights", i32 1048575, i32 1} +//. diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index dfbb276..2c9e7d3 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -1130,5 +1130,6 @@ public: class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {}; // Implicit move constructor declaration. // MSVC2015-DAG: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q +// PS-DAG: define weak_odr dllexport void @_ZN18ACE_Service_ObjectC1EOS_ // The declarations should not be exported. // MSVC2013-NOT: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp index 363f97a..ed1c72c 100644 --- a/clang/test/CodeGenCXX/dllimport.cpp +++ b/clang/test/CodeGenCXX/dllimport.cpp @@ -35,7 +35,7 @@ struct ExplicitSpec_NotImported {}; #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; } #define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; } #define USECLASS(class) void UNIQ(USE)() { class x; } -#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; } +#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(const class&) { return &class::operator=; } #define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; } //===----------------------------------------------------------------------===// @@ -649,13 +649,15 @@ struct __declspec(dllimport) T { static int b; // MO1-DAG: @"?b@T@@2HA" = external dllimport global i32 - T& operator=(T&) = default; - // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@AAU0@@Z" + T& operator=(const T&) = default; + // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@ABU0@@Z" + // PS-DAG: declare dllimport nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN1TaSERKS_ T& operator=(T&&) = default; - // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them. + // Note: Don't mark inline move operators dllimport because MSVC versions before 2015 don't export them. // M18-DAG: define linkonce_odr dso_local x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@$$QAU0@@Z" // M19-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@$$QAU0@@Z" + // PS-DAG: declare dllimport nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN1TaSEOS_ }; USEMEMFUNC(T, a) USESTATICMEMFUNC(T, StaticMethod) diff --git a/clang/test/CodeGenCXX/fmv-namespace.cpp b/clang/test/CodeGenCXX/fmv-namespace.cpp index 75f29e1..4680b39 100644 --- a/clang/test/CodeGenCXX/fmv-namespace.cpp +++ b/clang/test/CodeGenCXX/fmv-namespace.cpp @@ -72,7 +72,8 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER:[0-9]+]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -86,7 +87,8 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret ptr @_ZN4Name3fooEv.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN3Foo3barEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN3Foo3barEv.resolver( +// CHECK-SAME: ) #[[ATTR_RESOLVER]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -99,6 +101,7 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: ret ptr @_ZN3Foo3barEv.default // +// CHECK: attributes #[[ATTR_RESOLVER]] = { disable_sanitizer_instrumentation } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp b/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp index 2e7531b..4be1cb3 100644 --- a/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp +++ b/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp @@ -19,7 +19,7 @@ using i4x3x3 = _BitInt(4) __attribute__((matrix_type(3, 3))); // CHECK-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 4 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i8>, ptr [[A]], align 4 // CHECK-NEXT: [[A1:%.*]] = shufflevector <4 x i8> [[LOADVECN]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 2> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[A1]], <3 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[A1]], <3 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i8> [[EXTRACTVEC]], ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[LOADVECN2:%.*]] = load <4 x i8>, ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[EXTRACTVEC3:%.*]] = shufflevector <4 x i8> [[LOADVECN2]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 2> @@ -38,7 +38,7 @@ i8x3 v1(i8x3 a) { // CHECK-SAME: <3 x i32> noundef [[A:%.*]]) #[[ATTR1:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[A_ADDR:%.*]] = alloca <3 x i32>, align 16 -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i32> [[A]], <3 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i32> [[A]], <3 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i32> [[EXTRACTVEC]], ptr [[A_ADDR]], align 16 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i32>, ptr [[A_ADDR]], align 16 // CHECK-NEXT: [[EXTRACTVEC1:%.*]] = shufflevector <4 x i32> [[LOADVECN]], <4 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2> @@ -57,7 +57,7 @@ i32x3 v2(i32x3 a) { // CHECK-NEXT: [[A_ADDR:%.*]] = alloca <3 x i512>, align 256 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i512>, ptr [[TMP0]], align 256 // CHECK-NEXT: [[A:%.*]] = shufflevector <4 x i512> [[LOADVECN]], <4 x i512> poison, <3 x i32> <i32 0, i32 1, i32 2> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i512> [[A]], <3 x i512> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i512> [[A]], <3 x i512> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i512> [[EXTRACTVEC]], ptr [[A_ADDR]], align 256 // CHECK-NEXT: [[LOADVECN1:%.*]] = load <4 x i512>, ptr [[A_ADDR]], align 256 // CHECK-NEXT: [[EXTRACTVEC2:%.*]] = shufflevector <4 x i512> [[LOADVECN1]], <4 x i512> poison, <3 x i32> <i32 0, i32 1, i32 2> @@ -80,7 +80,7 @@ i512x3 v3(i512x3 a) { // CHECK-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 4 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i4>, ptr [[A]], align 4 // CHECK-NEXT: [[A1:%.*]] = shufflevector <4 x i4> [[LOADVECN]], <4 x i4> poison, <3 x i32> <i32 0, i32 1, i32 2> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i4> [[A1]], <3 x i4> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i4> [[A1]], <3 x i4> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i4> [[EXTRACTVEC]], ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[LOADVECN2:%.*]] = load <4 x i4>, ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[EXTRACTVEC3:%.*]] = shufflevector <4 x i4> [[LOADVECN2]], <4 x i4> poison, <3 x i32> <i32 0, i32 1, i32 2> diff --git a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp index de112d6..9f116c4 100644 --- a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp +++ b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp @@ -10,11 +10,16 @@ template <class T> class c { +public: + c(const c &) {} + c(c &&) noexcept {} void f() {} }; template class __declspec(dllexport) c<int>; +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEC1ERKS0_ +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEC1EOS0_ // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv extern template class __declspec(dllexport) c<char>; @@ -27,6 +32,18 @@ template class __declspec(dllexport) c<double>; // CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv +extern template class __declspec(dllimport) c<short>; + +// CHECK: declare dllimport {{.*}} @_ZN1cIsEC1ERKS0_ +// CHECK: declare dllimport {{.*}} @_ZN1cIsEC1EOS0_ +// CHECK: declare dllimport {{.*}} @_ZN1cIsE1fEv + +void use_ctors(c<short> &&x) { + c<short> y{x}; + c<short> z{static_cast<c<short> &&>(x)}; + z.f(); +} + template <class T> struct outer { void f(); diff --git a/clang/test/CodeGenCXX/speculative-devirt-metadata.cpp b/clang/test/CodeGenCXX/speculative-devirt-metadata.cpp new file mode 100644 index 0000000..20d2ab9 --- /dev/null +++ b/clang/test/CodeGenCXX/speculative-devirt-metadata.cpp @@ -0,0 +1,78 @@ +// Test that Clang emits vtable metadata when speculative devirtualization is enabled. +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fdevirtualize-speculatively -emit-llvm -o - %s | FileCheck --check-prefix=CHECK %s + +struct A { + A(); + virtual void f(); +}; + +struct B : virtual A { + B(); + virtual void g(); + virtual void h(); +}; + +namespace { + +struct D : B { + D(); + virtual void f(); + virtual void h(); +}; + +} + +A::A() {} +B::B() {} +D::D() {} + +void A::f() { +} + +void B::g() { +} + +void D::f() { +} + +void D::h() { +} + +void af(A *a) { + // CHECK: [[P:%[^ ]*]] = call i1 @llvm.public.type.test(ptr [[VT:%[^ ]*]], metadata !"_ZTS1A") + // CHECK-NEXT: call void @llvm.assume(i1 [[P]]) + a->f(); +} + +void dg1(D *d) { + // CHECK: [[P:%[^ ]*]] = call i1 @llvm.public.type.test(ptr [[VT:%[^ ]*]], metadata !"_ZTS1B") + // CHECK-NEXT: call void @llvm.assume(i1 [[P]]) + d->g(); +} + +void df1(D *d) { + // CHECK: [[P:%[^ ]*]] = call i1 @llvm.type.test(ptr [[VT:%[^ ]*]], metadata !11) + // CHECK-NEXT: call void @llvm.assume(i1 [[P]]) + d->f(); +} + +void dh1(D *d) { + // CHECK: [[P:%[^ ]*]] = call i1 @llvm.type.test(ptr [[VT:%[^ ]*]], metadata !11) + // CHECK-NEXT: call void @llvm.assume(i1 [[P]]) + d->h(); +} + + +D d; + +void foo() { + dg1(&d); + df1(&d); + dh1(&d); + + + struct FA : A { + void f() {} + } fa; + af(&fa); +} diff --git a/clang/test/CodeGenCXX/tmp-md-nodes1.cpp b/clang/test/CodeGenCXX/tmp-md-nodes1.cpp index 524b2c0..f39dca3e 100644 --- a/clang/test/CodeGenCXX/tmp-md-nodes1.cpp +++ b/clang/test/CodeGenCXX/tmp-md-nodes1.cpp @@ -2,6 +2,14 @@ // RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -emit-llvm %s -o - | \ // RUN: FileCheck %s +// Trigger GenerateVarArgsThunk. +// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \ +// RUN: FileCheck %s + +// Check that retainedNodes are properly maintained at function cloning. +// RUN: %clang_cc1 -O1 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DI + // This test simply checks that the varargs thunk is created. The failing test // case asserts. @@ -16,3 +24,11 @@ struct CharlieImpl : Charlie, Alpha { } delta; // CHECK: define {{.*}} void @_ZThn{{[48]}}_N11CharlieImpl5bravoEz( + +// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN11CharlieImpl5bravoEz", {{.*}}, retainedNodes: [[RN1:![0-9]+]] +// A non-empty retainedNodes list of original DISubprogram. +// CHECK-DI: [[RN1]] = !{!{{.*}}} + +// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN11CharlieImpl5bravoEz", {{.*}}, retainedNodes: [[EMPTY:![0-9]+]] +// An empty retainedNodes list of cloned DISubprogram. +// CHECK-DI: [[EMPTY]] = !{} diff --git a/clang/test/CodeGenCXX/tmp-md-nodes2.cpp b/clang/test/CodeGenCXX/tmp-md-nodes2.cpp index 8500cf3..0c323ae 100644 --- a/clang/test/CodeGenCXX/tmp-md-nodes2.cpp +++ b/clang/test/CodeGenCXX/tmp-md-nodes2.cpp @@ -2,6 +2,14 @@ // RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -emit-llvm %s -o - | \ // RUN: FileCheck %s +// Trigger GenerateVarArgsThunk. +// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \ +// RUN: FileCheck %s + +// Check that retainedNodes are properly maintained at function cloning. +// RUN: %clang_cc1 -O1 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DI + // This test simply checks that the varargs thunk is created. The failing test // case asserts. @@ -31,3 +39,11 @@ BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) { } // CHECK: define {{.*}} @_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz( + +// An empty retainedNodes list of cloned DISubprogram. +// CHECK-DI: [[EMPTY:![0-9]+]] = !{} +// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz", {{.*}}, retainedNodes: [[RN1:![0-9]+]] +// A non-empty retainedNodes list of original DISubprogram. +// CHECK-DI: [[RN1]] = !{!{{.*}}} + +// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz", {{.*}}, retainedNodes: [[EMPTY]] diff --git a/clang/test/CodeGenCXX/ubsan-coroutines.cpp b/clang/test/CodeGenCXX/ubsan-coroutines.cpp index 04ab050..60c89a4 100644 --- a/clang/test/CodeGenCXX/ubsan-coroutines.cpp +++ b/clang/test/CodeGenCXX/ubsan-coroutines.cpp @@ -1,6 +1,7 @@ // This test merely verifies that emitting the object file does not cause a // crash when the LLVM coroutines passes are run. // RUN: %clang_cc1 -emit-obj -std=c++2a -fsanitize=null %s -o %t.o +// UNSUPPORTED: target={{.*}}-zos{{.*}} namespace std { template <typename R, typename... T> struct coroutine_traits { |
