[clang] [Clang] Add `noalias` to `this` pointer in C++ constructors (PR #136792)
via cfe-commits
cfe-commits at lists.llvm.org
Sun May 4 06:58:54 PDT 2025
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
More information about the cfe-commits
mailing list