[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