llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-hlsl Author: Guy David (guy-david) <details> <summary>Changes</summary> Note: the patch is probably amending the wrong piece of code, I've tried to add it to `buildThisParam` but hit an assertion because of a missing translation unit context. Clang does not transform the following example into a 128-bit load and store: ```c++ class vector4f { private: float _elements[4]; public: explicit __attribute__((noinline)) vector4f(float const *src) { _elements[0] = src[0]; _elements[1] = src[1]; _elements[2] = src[2]; _elements[3] = src[3]; } }; ``` And instead generates 8 memory operations. That's because `src` might overlap with `_elements`. However, GCC is able to optimize it for constructors only. According to the standard in 11.10.4.2 under [class.cdtor]: > "During the construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor’s this pointer, the value of the object or subobject thus obtained is unspecified." which sounds like `restrict`. Relevant GCC chain-mail: https://gcc.gnu.org/pipermail/gcc-patches/2018-May/498812.html. --- Patch is 4.14 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136792.diff 132 Files Affected: - (modified) clang/lib/CodeGen/CGCall.cpp (+7-2) - (modified) clang/test/CodeGen/attr-counted-by-pr88931.cpp (+1-1) - (modified) clang/test/CodeGen/attr-noundef.cpp (+152-151) - (modified) clang/test/CodeGen/paren-list-agg-init.cpp (+4-4) - (modified) clang/test/CodeGen/temporary-lifetime.cpp (+8-8) - (modified) clang/test/CodeGenCUDA/offload_via_llvm.cu (+5-5) - (modified) clang/test/CodeGenCUDA/record-layout.cu (+10-10) - (modified) clang/test/CodeGenCUDA/vtbl.cu (+1-1) - (modified) clang/test/CodeGenCXX/LoongArch/abi-lp64d-struct-inherit.cpp (+1-1) - (modified) clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp (+4-4) - (modified) clang/test/CodeGenCXX/amdgcn-automatic-variable.cpp (+1-1) - (modified) clang/test/CodeGenCXX/amdgcn-func-arg.cpp (+1-1) - (modified) clang/test/CodeGenCXX/atomicinit.cpp (+3-3) - (modified) clang/test/CodeGenCXX/bug135668.cpp (+1-1) - (modified) clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp (+2-2) - (modified) clang/test/CodeGenCXX/cxx2a-consteval.cpp (+1-1) - (modified) clang/test/CodeGenCXX/cxx2b-deducing-this.cpp (+1-1) - (modified) clang/test/CodeGenCXX/fcheck-new.cpp (+1-1) - (modified) clang/test/CodeGenCXX/for-range.cpp (+8-8) - (modified) clang/test/CodeGenCXX/gh62818.cpp (+1-1) - (modified) clang/test/CodeGenCXX/ibm128-declarations.cpp (+4-4) - (modified) clang/test/CodeGenCXX/init-invariant.cpp (+5-5) - (modified) clang/test/CodeGenCXX/matrix-casts.cpp (+2-2) - (modified) clang/test/CodeGenCXX/no-elide-constructors.cpp (+1-1) - (modified) clang/test/CodeGenCXX/nrvo.cpp (+137-137) - (modified) clang/test/CodeGenCXX/pr13396.cpp (+4-4) - (modified) clang/test/CodeGenCXX/ptrauth-qualifier-struct.cpp (+2-2) - (modified) clang/test/CodeGenCXX/trivial_abi_debuginfo.cpp (+1-1) - (modified) clang/test/CodeGenCXX/vtt-address-space.cpp (+12-12) - (modified) clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp (+1-1) - (modified) clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl (+9-9) - (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl (+9-9) - (modified) clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl (+9-9) - (modified) clang/test/Headers/__clang_hip_cmath.hip (+4-4) - (modified) clang/test/OpenMP/amdgcn_sret_ctor.cpp (+3-5) - (modified) clang/test/OpenMP/amdgcn_target_global_constructor.cpp (+4-4) - (modified) clang/test/OpenMP/distribute_firstprivate_codegen.cpp (+36-36) - (modified) clang/test/OpenMP/distribute_lastprivate_codegen.cpp (+44-44) - (modified) clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp (+36-36) - (modified) clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp (+52-52) - (modified) clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp (+20-20) - (modified) clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp (+52-52) - (modified) clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp (+259-259) - (modified) clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp (+244-244) - (modified) clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp (+504-504) - (modified) clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp (+238-238) - (modified) clang/test/OpenMP/distribute_private_codegen.cpp (+44-44) - (modified) clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp (+168-168) - (modified) clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp (+176-176) - (modified) clang/test/OpenMP/distribute_simd_private_codegen.cpp (+190-190) - (modified) clang/test/OpenMP/for_firstprivate_codegen.cpp (+56-56) - (modified) clang/test/OpenMP/for_lastprivate_codegen.cpp (+70-70) - (modified) clang/test/OpenMP/for_linear_codegen.cpp (+24-24) - (modified) clang/test/OpenMP/for_private_codegen.cpp (+22-22) - (modified) clang/test/OpenMP/for_reduction_codegen.cpp (+50-50) - (modified) clang/test/OpenMP/for_reduction_codegen_UDR.cpp (+54-54) - (modified) clang/test/OpenMP/irbuilder_for_iterator.cpp (+4-4) - (modified) clang/test/OpenMP/irbuilder_for_rangefor.cpp (+4-4) - (modified) clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp (+9-9) - (modified) clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp (+13-13) - (modified) clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp (+236-236) - (modified) clang/test/OpenMP/parallel_copyin_codegen.cpp (+59-59) - (modified) clang/test/OpenMP/parallel_firstprivate_codegen.cpp (+106-106) - (modified) clang/test/OpenMP/parallel_for_linear_codegen.cpp (+8-8) - (modified) clang/test/OpenMP/parallel_master_codegen.cpp (+4-4) - (modified) clang/test/OpenMP/parallel_master_taskloop_codegen.cpp (+4-4) - (modified) clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp (+111-111) - (modified) clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp (+47-47) - (modified) clang/test/OpenMP/parallel_master_taskloop_simd_codegen.cpp (+28-28) - (modified) clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp (+111-111) - (modified) clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp (+73-73) - (modified) clang/test/OpenMP/parallel_private_codegen.cpp (+40-40) - (modified) clang/test/OpenMP/parallel_reduction_codegen.cpp (+50-50) - (modified) clang/test/OpenMP/reduction_compound_op.cpp (+28-28) - (modified) clang/test/OpenMP/reduction_implicit_map.cpp (+8-8) - (modified) clang/test/OpenMP/reverse_codegen.cpp (+8-8) - (modified) clang/test/OpenMP/scope_codegen.cpp (+60-60) - (modified) clang/test/OpenMP/sections_firstprivate_codegen.cpp (+57-57) - (modified) clang/test/OpenMP/sections_lastprivate_codegen.cpp (+48-48) - (modified) clang/test/OpenMP/sections_private_codegen.cpp (+24-24) - (modified) clang/test/OpenMP/sections_reduction_codegen.cpp (+32-32) - (modified) clang/test/OpenMP/simd_private_taskloop_codegen.cpp (+128-128) - (modified) clang/test/OpenMP/single_codegen.cpp (+60-60) - (modified) clang/test/OpenMP/single_firstprivate_codegen.cpp (+57-57) - (modified) clang/test/OpenMP/single_private_codegen.cpp (+24-24) - (modified) clang/test/OpenMP/stripe_codegen.cpp (+8-8) - (modified) clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp (+12-12) - (modified) clang/test/OpenMP/target_has_device_addr_codegen.cpp (+25-25) - (modified) clang/test/OpenMP/target_has_device_addr_codegen_01.cpp (+8-8) - (modified) clang/test/OpenMP/target_in_reduction_codegen.cpp (+9-9) - (modified) clang/test/OpenMP/target_is_device_ptr_codegen.cpp (+32-32) - (modified) clang/test/OpenMP/target_map_member_expr_codegen.cpp (+8-8) - (modified) clang/test/OpenMP/target_parallel_generic_loop_codegen-1.cpp (+156-156) - (modified) clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp (+82-82) - (modified) clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp (+44-44) - (modified) clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp (+148-148) - (modified) clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp (+52-52) - (modified) clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp (+92-92) - (modified) clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp (+490-490) - (modified) clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp (+278-278) - (modified) clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp (+382-382) - (modified) clang/test/OpenMP/target_teams_distribute_private_codegen.cpp (+56-56) - (modified) clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp (+202-202) - (modified) clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp (+176-176) - (modified) clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp (+184-184) - (modified) clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp (+76-76) - (modified) clang/test/OpenMP/task_codegen.cpp (+266-266) - (modified) clang/test/OpenMP/task_in_reduction_codegen.cpp (+9-9) - (modified) clang/test/OpenMP/taskloop_in_reduction_codegen.cpp (+9-9) - (modified) clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp (+13-13) - (modified) clang/test/OpenMP/taskloop_strictmodifier_codegen.cpp (+211-5) - (modified) clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp (+82-82) - (modified) clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp (+44-44) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp (+98-98) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp (+52-52) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp (+12-12) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp (+64-64) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp (+293-293) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp (+244-244) - (modified) clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp () - (modified) clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp (+237-237) - (modified) clang/test/OpenMP/teams_distribute_private_codegen.cpp (+56-56) - (modified) clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp (+202-202) - (modified) clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp (+176-176) - (modified) clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp (+184-184) - (modified) clang/test/OpenMP/teams_firstprivate_codegen.cpp (+74-74) - (modified) clang/test/OpenMP/teams_generic_loop_private_codegen.cpp (+56-56) - (modified) clang/test/OpenMP/teams_private_codegen.cpp (+72-72) - (modified) clang/test/OpenMP/threadprivate_codegen.cpp (+300-300) - (modified) clang/test/OpenMP/tile_codegen.cpp (+8-8) - (modified) clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected (+13-13) - (modified) clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp.expected (+4-4) ``````````diff diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 82a24f7c295a2..c2f5fc261955d 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2731,8 +2731,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, llvm::AttributeSet::get(getLLVMContext(), Attrs); } - // Apply `nonnull`, `dereferenceable(N)` and `align N` to the `this` argument, - // unless this is a thunk function. + // Apply `nonnull`, `dereferenceable(N)`, `align N` (and `noalias` for + // constructors) to the `this` argument, unless this is a thunk function. // FIXME: fix this properly, https://reviews.llvm.org/D100388 if (FI.isInstanceMethod() && !IRFunctionArgs.hasInallocaArg() && !FI.arg_begin()->type->isVoidPointerType() && !IsThunk) { @@ -2744,6 +2744,11 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, QualType ThisTy = FI.arg_begin()->type.getTypePtr()->getPointeeType(); + // According to [class.cdtor]/2, the value of the object is unspecified if + // its elements are accessed not through `this`. + if (isa_and_nonnull<CXXConstructorDecl>(TargetDecl)) + Attrs.addAttribute(llvm::Attribute::NoAlias); + if (!CodeGenOpts.NullPointerIsValid && getTypes().getTargetAddressSpace(FI.arg_begin()->type) == 0) { Attrs.addAttribute(llvm::Attribute::NonNull); diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.cpp b/clang/test/CodeGen/attr-counted-by-pr88931.cpp index 6d0c46bbbe8f9..8297cdf0f120c 100644 --- a/clang/test/CodeGen/attr-counted-by-pr88931.cpp +++ b/clang/test/CodeGen/attr-counted-by-pr88931.cpp @@ -11,7 +11,7 @@ struct foo { void init(void * __attribute__((pass_dynamic_object_size(0)))); // CHECK-LABEL: define dso_local void @_ZN3foo3barC1Ev( -// CHECK-SAME: ptr noundef nonnull align 4 dereferenceable(1) [[THIS:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] align 2 { +// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(1) [[THIS:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] align 2 { // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @_Z4initPvU25pass_dynamic_object_size0(ptr noundef nonnull align 4 dereferenceable(1) [[THIS]], i64 noundef -1) #[[ATTR2:[0-9]+]] // CHECK-NEXT: ret void diff --git a/clang/test/CodeGen/attr-noundef.cpp b/clang/test/CodeGen/attr-noundef.cpp index abdf9496bd396..30c4282759144 100644 --- a/clang/test/CodeGen/attr-noundef.cpp +++ b/clang/test/CodeGen/attr-noundef.cpp @@ -10,157 +10,158 @@ // TODO: No structs may currently be marked noundef namespace check_structs { -struct Trivial { - int a; -}; -Trivial ret_trivial() { return {}; } -void pass_trivial(Trivial e) {} -// CHECK-INTEL: [[DEF:define( dso_local)?]] i32 @{{.*}}ret_trivial -// CHECK-AARCH: [[DEF:define( dso_local)?]] i32 @{{.*}}ret_trivial -// CHECK-INTEL: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i32 % -// CHECK-AARCH: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i64 % - -struct NoCopy { - int a; - NoCopy(NoCopy &) = delete; -}; -NoCopy ret_nocopy() { return {}; } -void pass_nocopy(NoCopy e) {} -// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % -// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef % - -struct Huge { - int a[1024]; -}; -Huge ret_huge() { return {}; } -void pass_huge(Huge h) {} -// CHECK: [[DEF]] void @{{.*}}ret_huge{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % -// CHECK: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr noundef -} // namespace check_structs - -//************ Passing unions by value -// No unions may be marked noundef - -namespace check_unions { -union Trivial { - int a; -}; -Trivial ret_trivial() { return {}; } -void pass_trivial(Trivial e) {} -// CHECK-INTEL: [[DEF]] i32 @{{.*}}ret_trivial -// CHECK-AARCH: [[DEF]] i32 @{{.*}}ret_trivial -// CHECK-INTEL: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i32 % -// CHECK-AARCH: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i64 % - -union NoCopy { - int a; - NoCopy(NoCopy &) = delete; -}; -NoCopy ret_nocopy() { return {}; } -void pass_nocopy(NoCopy e) {} -// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % -// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef % -} // namespace check_unions - -//************ Passing `this` pointers -// `this` pointer must always be defined - -namespace check_this { -struct Object { - int data[]; - - Object() { - this->data[0] = 0; + struct Trivial { + int a; + }; + Trivial ret_trivial() { return {}; } + void pass_trivial(Trivial e) {} + // CHECK-INTEL: [[DEF:define( dso_local)?]] i32 @{{.*}}ret_trivial + // CHECK-AARCH: [[DEF:define( dso_local)?]] i32 @{{.*}}ret_trivial + // CHECK-INTEL: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i32 % + // CHECK-AARCH: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i64 % + + struct NoCopy { + int a; + NoCopy(NoCopy &) = delete; + }; + NoCopy ret_nocopy() { return {}; } + void pass_nocopy(NoCopy e) {} + // CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % + // CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef % + + struct Huge { + int a[1024]; + }; + Huge ret_huge() { return {}; } + void pass_huge(Huge h) {} + // CHECK: [[DEF]] void @{{.*}}ret_huge{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % + // CHECK: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr noundef + } // namespace check_structs + + //************ Passing unions by value + // No unions may be marked noundef + + namespace check_unions { + union Trivial { + int a; + }; + Trivial ret_trivial() { return {}; } + void pass_trivial(Trivial e) {} + // CHECK-INTEL: [[DEF]] i32 @{{.*}}ret_trivial + // CHECK-AARCH: [[DEF]] i32 @{{.*}}ret_trivial + // CHECK-INTEL: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i32 % + // CHECK-AARCH: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i64 % + + union NoCopy { + int a; + NoCopy(NoCopy &) = delete; + }; + NoCopy ret_nocopy() { return {}; } + void pass_nocopy(NoCopy e) {} + // CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % + // CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef % + } // namespace check_unions + + //************ Passing `this` pointers + // `this` pointer must always be defined + + namespace check_this { + struct Object { + int data[]; + + Object() { + this->data[0] = 0; + } + int getData() { + return this->data[0]; + } + Object *getThis() { + return this; + } + }; + + void use_object() { + Object obj; + obj.getData(); + obj.getThis(); } - int getData() { - return this->data[0]; + // CHECK: define linkonce_odr void @{{.*}}Object{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(1) % + // CHECK: define linkonce_odr noundef i32 @{{.*}}Object{{.*}}getData{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) % + // CHECK: define linkonce_odr noundef ptr @{{.*}}Object{{.*}}getThis{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) % + } // namespace check_this + + //************ Passing vector types + + namespace check_vecs { + typedef int __attribute__((vector_size(12))) i32x3; + i32x3 ret_vec() { + return {}; } - Object *getThis() { - return this; + void pass_vec(i32x3 v) { } -}; - -void use_object() { - Object obj; - obj.getData(); - obj.getThis(); -} -// CHECK: define linkonce_odr void @{{.*}}Object{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) % -// CHECK: define linkonce_odr noundef i32 @{{.*}}Object{{.*}}getData{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) % -// CHECK: define linkonce_odr noundef ptr @{{.*}}Object{{.*}}getThis{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) % -} // namespace check_this - -//************ Passing vector types - -namespace check_vecs { -typedef int __attribute__((vector_size(12))) i32x3; -i32x3 ret_vec() { - return {}; -} -void pass_vec(i32x3 v) { -} - -// CHECK: [[DEF]] noundef <3 x i32> @{{.*}}ret_vec{{.*}}() -// CHECK-INTEL: [[DEF]] void @{{.*}}pass_vec{{.*}}(<3 x i32> noundef % -// CHECK-AARCH: [[DEF]] void @{{.*}}pass_vec{{.*}}(<4 x i32> % -} // namespace check_vecs - -//************ Passing exotic types -// Function/Array pointers, Function member / Data member pointers, nullptr_t, ExtInt types - -namespace check_exotic { -struct Object { - int mfunc(); - int mdata; -}; -typedef int Object::*mdptr; -typedef int (Object::*mfptr)(); -typedef decltype(nullptr) nullptr_t; -typedef int (*arrptr)[32]; -typedef int (*fnptr)(int); - -arrptr ret_arrptr() { - return nullptr; -} -fnptr ret_fnptr() { - return nullptr; -} -mdptr ret_mdptr() { - return nullptr; -} -mfptr ret_mfptr() { - return nullptr; -} -nullptr_t ret_npt() { - return nullptr; -} -void pass_npt(nullptr_t t) { -} -_BitInt(3) ret_BitInt() { - return 0; -} -void pass_BitInt(_BitInt(3) e) { -} -void pass_large_BitInt(_BitInt(127) e) { -} - -// Pointers to arrays/functions are always noundef -// CHECK: [[DEF]] noundef ptr @{{.*}}ret_arrptr{{.*}}() -// CHECK: [[DEF]] noundef ptr @{{.*}}ret_fnptr{{.*}}() - -// Pointers to members are never noundef -// CHECK: [[DEF]] i64 @{{.*}}ret_mdptr{{.*}}() -// CHECK-INTEL: [[DEF]] { i64, i64 } @{{.*}}ret_mfptr{{.*}}() -// CHECK-AARCH: [[DEF]] [2 x i64] @{{.*}}ret_mfptr{{.*}}() - -// nullptr_t is never noundef -// CHECK: [[DEF]] ptr @{{.*}}ret_npt{{.*}}() -// CHECK: [[DEF]] void @{{.*}}pass_npt{{.*}}(ptr % - -// CHECK-INTEL: [[DEF]] noundef signext i3 @{{.*}}ret_BitInt{{.*}}() -// CHECK-AARCH: [[DEF]] noundef i3 @{{.*}}ret_BitInt{{.*}}() -// CHECK-INTEL: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef signext % -// CHECK-AARCH: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef % -// CHECK-INTEL: [[DEF]] void @{{.*}}pass_large_BitInt{{.*}}(i64 noundef %{{.*}}, i64 noundef % -// CHECK-AARCH: [[DEF]] void @{{.*}}pass_large_BitInt{{.*}}(i127 noundef % -} // namespace check_exotic + + // CHECK: [[DEF]] noundef <3 x i32> @{{.*}}ret_vec{{.*}}() + // CHECK-INTEL: [[DEF]] void @{{.*}}pass_vec{{.*}}(<3 x i32> noundef % + // CHECK-AARCH: [[DEF]] void @{{.*}}pass_vec{{.*}}(<4 x i32> % + } // namespace check_vecs + + //************ Passing exotic types + // Function/Array pointers, Function member / Data member pointers, nullptr_t, ExtInt types + + namespace check_exotic { + struct Object { + int mfunc(); + int mdata; + }; + typedef int Object::*mdptr; + typedef int (Object::*mfptr)(); + typedef decltype(nullptr) nullptr_t; + typedef int (*arrptr)[32]; + typedef int (*fnptr)(int); + + arrptr ret_arrptr() { + return nullptr; + } + fnptr ret_fnptr() { + return nullptr; + } + mdptr ret_mdptr() { + return nullptr; + } + mfptr ret_mfptr() { + return nullptr; + } + nullptr_t ret_npt() { + return nullptr; + } + void pass_npt(nullptr_t t) { + } + _BitInt(3) ret_BitInt() { + return 0; + } + void pass_BitInt(_BitInt(3) e) { + } + void pass_large_BitInt(_BitInt(127) e) { + } + + // Pointers to arrays/functions are always noundef + // CHECK: [[DEF]] noundef ptr @{{.*}}ret_arrptr{{.*}}() + // CHECK: [[DEF]] noundef ptr @{{.*}}ret_fnptr{{.*}}() + + // Pointers to members are never noundef + // CHECK: [[DEF]] i64 @{{.*}}ret_mdptr{{.*}}() + // CHECK-INTEL: [[DEF]] { i64, i64 } @{{.*}}ret_mfptr{{.*}}() + // CHECK-AARCH: [[DEF]] [2 x i64] @{{.*}}ret_mfptr{{.*}}() + + // nullptr_t is never noundef + // CHECK: [[DEF]] ptr @{{.*}}ret_npt{{.*}}() + // CHECK: [[DEF]] void @{{.*}}pass_npt{{.*}}(ptr % + + // CHECK-INTEL: [[DEF]] noundef signext i3 @{{.*}}ret_BitInt{{.*}}() + // CHECK-AARCH: [[DEF]] noundef i3 @{{.*}}ret_BitInt{{.*}}() + // CHECK-INTEL: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef signext % + // CHECK-AARCH: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef % + // CHECK-INTEL: [[DEF]] void @{{.*}}pass_large_BitInt{{.*}}(i64 noundef %{{.*}}, i64 noundef % + // CHECK-AARCH: [[DEF]] void @{{.*}}pass_large_BitInt{{.*}}(i127 noundef % + } // namespace check_exotic + \ No newline at end of file diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp index 235352382332a..e674a3492612e 100644 --- a/clang/test/CodeGen/paren-list-agg-init.cpp +++ b/clang/test/CodeGen/paren-list-agg-init.cpp @@ -390,9 +390,9 @@ namespace gh61145 { // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S1]], align 1 // a.k.a. Vec::Vec() - // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noalias noundef nonnull align 1 dereferenceable(1) [[V]]) // a.k.a. Vec::Vec(Vec&&) - // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noalias noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) // a.k.a. S1::~S1() // CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) // a.k.a.Vec::~Vec() @@ -410,9 +410,9 @@ namespace gh61145 { // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S2]], align 1 // a.k.a. Vec::Vec() - // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noalias noundef nonnull align 1 dereferenceable(1) [[V]]) // a.k.a. Vec::Vec(Vec&&) - // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noalias noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) // CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds nuw [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 // CHECK-NEXT: store i8 0, ptr [[C]], align 1 // a.k.a. S2::~S2() diff --git a/clang/test/CodeGen/temporary-lifetime.cpp b/clang/test/CodeGen/temporary-lifetime.cpp index 9f085d41d1464..3c2715c5a3dfe 100644 --- a/clang/test/CodeGen/temporary-lifetime.cpp +++ b/clang/test/CodeGen/temporary-lifetime.cpp @@ -22,12 +22,12 @@ T Baz(); void Test1() { // CHECK-DTOR-LABEL: Test1 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]]) - // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]]) + // CHECK-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR:[^ ]+]]) // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR]]) // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]]) // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]]) - // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]]) + // CHECK-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR:[^ ]+]]) // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR]]) // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]]) @@ -35,11 +35,11 @@ void Test1() { // CHECK-NO-DTOR-LABEL: Test1 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]]) - // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]]) + // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR:[^ ]+]]) // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]]) // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]]) - // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]]) + // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR:[^ ]+]]) // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]]) // CHECK-NO-DTOR: } @@ -56,10 +56,10 @@ void Test1() { void Test2() { // CHECK-DTOR-LABEL: Test2 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR1:.+]]) - // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR1:[^ ]+]]) + // CHECK-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR1:[^ ]+]]) // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR2:.+]]) - // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR2:[^ ]+]]) + // CHECK-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR2:[^ ]+]]) // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR2]]) // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR2]]) @@ -69,10 +69,10 @@ void Test2() { // CHECK-NO-DTOR-LABEL: Test2 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR1:.+]]) - // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR1:[^ ]+]]) + // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR1:[^ ]+]]) // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR2:.+]]) - // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR2:[^ ]+]]) + // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr noalias nonnull {{[^,]*}} %[[VAR2:[^ ]+]]) // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR2]]) // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR1]]) diff --git a/clang/test/CodeGenCUDA/offload_via_llvm.cu b/clang/test/CodeGenCUDA/offload_via_llvm.cu index 62942d8dc0755..860b036ec1b9c 100644 --- a/clang/test/CodeGenCUDA/offload_via_llvm.cu +++ b/clang/test/CodeGenCUDA/offload_via_llvm.cu @@ -45,7 +45,7 @@ // HST-NEXT: [[TMP15:%.*]] = call i32 @__llvmPopCallConfiguration(ptr [[GRID_DIM]], ptr [[BLOCK_DIM]], ptr [[SHMEM_SIZE]], ptr [[STREAM]]) // HST-NEXT: [[TMP16:%.*]] = load i32, ptr [[SHMEM_SIZE]], align 4 // HST-NEXT: [[TMP17:%.*]] = load ptr, ptr [[STREAM]], align 4 -// HST-NEXT: [[CALL:%.*]] = call noundef i32 @llvmLaunchKernel(ptr noundef @_Z18__device_stub__fooisPvS_, ptr noundef byval([[STRUCT_DIM3]]) align 4 [[GRID_DIM]], ptr noundef byval([[STRUCT_DIM3]]) align 4 [[BLOCK_DIM]], ptr noundef [[KERNEL_LAUNCH_PARAMS]], i32 noundef [[TMP16]], ptr noundef [[TMP17]]) +// HST-NEXT: [[CALL:%.*]] = call noundef i32 @llvmLaunchKernel(ptr noundef @_Z18__device_stub__fooisPvS_, ptr noundef byval([[STRUCT_DIM3]]) align 4 [[GRID_DIM]], ptr noundef byval([[STRUCT_DIM3]]) align 4 [[BLOCK_DIM]], ptr noundef [[KERNEL_LAUNCH_PARAMS]], i32 noundef [[TMP16]], ptr noundef [[TMP17]]) #[[ATTR3:[0-9]+]] // HST-NEXT: br label %[[SETUP_END:.*]] // HST: [[SETUP_END]]: // HST-NEXT: ret void @@ -72,15 +72,15 @@ __global__ void foo(int, short, void *, void *) {} // HST-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_DIM3:%.*]], align 4 // HST-NEXT: [[AGG_TMP1:%.*]] = alloca [[STRUCT_DIM3]], align 4 // HST-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 4 -// HST-NEXT: call void @_ZN4dim3C1Ejjj(ptr noundef nonnull align 4 dereferenceable(12) [[AGG_TMP]], i32 noundef 3, i32 noundef 1, i32 noundef 1) -// HST-NEXT: call void @_ZN4dim3C1Ejjj(ptr noundef nonnull align 4 dereferenceable(12) [[AGG_TMP1]], i32 noundef 7, i32 noundef 1, i32 noundef 1) -// HST-NEXT: [[CALL:%.*]] = call i32 @__llvmPushCallConfiguration(ptr noundef byval([[STRUCT_DIM3]]) align 4 [[AGG_TMP]], ptr noundef byval([[STRUCT_DIM3]]) align 4 [[AGG_TMP1]], i32 noundef 0, ptr noundef null) +// HST-NEXT: call void @_ZN4dim3C1Ejjj(ptr noalias noundef nonnull align 4 dereferenceable(12) [[AGG_TMP]], i32 noundef 3, i32 noundef 1, i32 noundef 1) #[[ATTR3]] +// HST-NEXT: call void @_ZN4dim3C1Ejjj(ptr noalias noundef nonnull align 4 dereferenceable(12) [[AGG_TMP... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/136792 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits