[llvm] [Attributor] Avoid inferring align and nonnull from poison-producing calls (PR #224932)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 20 07:15:57 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: hehuan (xxxxbc)

<details>
<summary>Changes</summary>

[Attributor] Avoid inferring align and nonnull from poison-producing calls

The align and nonnull parameter attributes produce poison when their constraints are violated. Attributor treated these attributes as facts about the original caller value even when the call boundary allowed poison. This could incorrectly strengthen caller parameters and the alignment of memory accesses.

Only use align or nonnull attributes from a call site or callee declaration to reason about the original argument when CallBase::isPassingUndefUB() indicates that the call rejects poison. Preserve the existing positive propagation tests by adding noundef, and add regression coverage for both attributes with and without noundef in module and CGSCC modes.

Fixes #<!-- -->224817

---

Patch is 46.67 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/224932.diff


6 Files Affected:

- (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+19-6) 
- (modified) llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll (+8-8) 
- (modified) llvm/test/Transforms/Attributor/align.ll (+8-8) 
- (added) llvm/test/Transforms/Attributor/call-site-argument-poison.ll (+51) 
- (modified) llvm/test/Transforms/Attributor/callbacks.ll (+25-25) 
- (modified) llvm/test/Transforms/Attributor/nonnull.ll (+61-61) 


``````````diff
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 04b7d34b02fb2d..5d8e27e5701d66 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2542,12 +2542,18 @@ static int64_t getKnownNonNullAndDerefBytesForUse(
 
     unsigned ArgNo = CB->getArgOperandNo(U);
     IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
-    // As long as we only use known information there is no need to track
-    // dependences here.
-    bool IsKnownNonNull;
-    AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP,
-                                             DepClassTy::NONE, IsKnownNonNull);
-    IsNonNull |= IsKnownNonNull;
+    // The nonnull attribute produces poison if its constraint is violated. It
+    // therefore only proves that the original value is nonnull if poison is
+    // not accepted at this call boundary.
+    if (!CB->paramHasAttr(ArgNo, Attribute::NonNull) ||
+        CB->isPassingUndefUB(ArgNo)) {
+      // As long as we only use known information there is no need to track
+      // dependences here.
+      bool IsKnownNonNull;
+      AA::hasAssumedIRAttr<Attribute::NonNull>(
+          A, &QueryingAA, IRP, DepClassTy::NONE, IsKnownNonNull);
+      IsNonNull |= IsKnownNonNull;
+    }
     auto *DerefAA =
         A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
     return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
@@ -5295,6 +5301,13 @@ static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
       return 0;
 
     unsigned ArgNo = CB->getArgOperandNo(U);
+    // The align attribute produces poison if its constraint is violated. It
+    // therefore only proves that the original value is aligned if poison is
+    // not accepted at this call boundary.
+    if (CB->paramHasAttr(ArgNo, Attribute::Alignment) &&
+        !CB->isPassingUndefUB(ArgNo))
+      return 0;
+
     IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
     // As long as we only use known information there is no need to track
     // dependences here.
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
index d7a9c6748d905c..d38338a010f726 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
@@ -66,7 +66,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg)
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -133,7 +133,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg)
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -200,7 +200,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg)
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -267,7 +267,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg)
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -328,7 +328,7 @@ define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %arg)
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -389,7 +389,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %arg)
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -456,7 +456,7 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg) #4 {
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
@@ -523,7 +523,7 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg) #3 {
 bb:
   %tmp = alloca <8 x i64>, align 32
   %tmp2 = alloca <8 x i64>, align 32
-  call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+  call void @llvm.memset.p0.i64(ptr noundef align 32 %tmp, i8 0, i64 32, i1 false)
   call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %tmp2, ptr %tmp)
   %tmp4 = load <8 x i64>, ptr %tmp2, align 32
   store <8 x i64> %tmp4, ptr %arg, align 2
diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll
index 904233408c144b..6de922da0cf48f 100644
--- a/llvm/test/Transforms/Attributor/align.ll
+++ b/llvm/test/Transforms/Attributor/align.ll
@@ -649,7 +649,7 @@ define void @test12-5(ptr align 4 %p) {
 ; TUNIT-SAME: (ptr align 16 [[P:%.*]]) #[[ATTR7:[0-9]+]] {
 ; TUNIT-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
 ; TUNIT-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3
-; TUNIT-NEXT:    tail call void @use(ptr align 16 [[ARRAYIDX1]]) #[[ATTR6:[0-9]+]]
+; TUNIT-NEXT:    tail call void @use(ptr noundef align 16 [[ARRAYIDX1]]) #[[ATTR6:[0-9]+]]
 ; TUNIT-NEXT:    ret void
 ;
 ; CGSCC: Function Attrs: mustprogress nounwind willreturn
@@ -657,13 +657,13 @@ define void @test12-5(ptr align 4 %p) {
 ; CGSCC-SAME: (ptr align 16 [[P:%.*]]) #[[ATTR8:[0-9]+]] {
 ; CGSCC-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
 ; CGSCC-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3
-; CGSCC-NEXT:    tail call void @use(ptr align 16 [[ARRAYIDX1]]) #[[ATTR7:[0-9]+]]
+; CGSCC-NEXT:    tail call void @use(ptr noundef align 16 [[ARRAYIDX1]]) #[[ATTR7:[0-9]+]]
 ; CGSCC-NEXT:    ret void
 ;
   %p-cast = bitcast ptr %p to ptr
   %arrayidx0 = getelementptr i64, ptr %p-cast, i64 1
   %arrayidx1 = getelementptr i64, ptr %arrayidx0, i64 3
-  tail call void @use(ptr align 16 %arrayidx1)
+  tail call void @use(ptr noundef align 16 %arrayidx1)
   ret void
 }
 
@@ -671,17 +671,17 @@ define void @test12-6(ptr align 4 %p) {
 ; TUNIT: Function Attrs: mustprogress nounwind willreturn
 ; TUNIT-LABEL: define {{[^@]+}}@test12-6
 ; TUNIT-SAME: (ptr align 16 [[P:%.*]]) #[[ATTR7]] {
-; TUNIT-NEXT:    tail call void @use(ptr align 16 [[P]]) #[[ATTR6]]
+; TUNIT-NEXT:    tail call void @use(ptr noundef align 16 [[P]]) #[[ATTR6]]
 ; TUNIT-NEXT:    ret void
 ;
 ; CGSCC: Function Attrs: mustprogress nounwind willreturn
 ; CGSCC-LABEL: define {{[^@]+}}@test12-6
 ; CGSCC-SAME: (ptr align 16 [[P:%.*]]) #[[ATTR8]] {
-; CGSCC-NEXT:    tail call void @use(ptr align 16 [[P]]) #[[ATTR7]]
+; CGSCC-NEXT:    tail call void @use(ptr noundef align 16 [[P]]) #[[ATTR7]]
 ; CGSCC-NEXT:    ret void
 ;
   %p-cast = bitcast ptr %p to ptr
-  tail call void @use(ptr align 16 %p-cast)
+  tail call void @use(ptr noundef align 16 %p-cast)
   ret void
 }
 
@@ -1020,10 +1020,10 @@ return:                                           ; preds = %entry, %if.then
   ret ptr %retval.0
 }
 
-; FIXME: align 4 should not be propagated to the caller's p unless there is noundef
+; The align attribute does not describe the caller's value without noundef.
 define void @align4_caller(ptr %p) {
 ; CHECK-LABEL: define {{[^@]+}}@align4_caller
-; CHECK-SAME: (ptr align 4 [[P:%.*]]) {
+; CHECK-SAME: (ptr [[P:%.*]]) {
 ; CHECK-NEXT:    call void @align4_callee(ptr align 4 [[P]])
 ; CHECK-NEXT:    ret void
 ;
diff --git a/llvm/test/Transforms/Attributor/call-site-argument-poison.ll b/llvm/test/Transforms/Attributor/call-site-argument-poison.ll
new file mode 100644
index 00000000000000..d79389114dbf2b
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/call-site-argument-poison.ll
@@ -0,0 +1,51 @@
+; RUN: opt -passes=attributor -S < %s | FileCheck %s
+; RUN: opt -passes=attributor-cgscc -S < %s | FileCheck %s
+
+declare void @use(ptr)
+
+; Parameter attributes such as align and nonnull produce poison when their
+; constraints are violated. Unless the argument is also noundef (or otherwise
+; rejects poison), these attributes do not describe the original value.
+
+define void @align_without_noundef(ptr %p) {
+; CHECK-LABEL: define void @align_without_noundef(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT:    call void @use(ptr align 4 [[P]])
+; CHECK-NEXT:    store i8 1, ptr [[P]], align 1
+; CHECK-NEXT:    ret void
+  call void @use(ptr align 4 %p)
+  store i8 1, ptr %p, align 1
+  ret void
+}
+
+define void @align_with_noundef(ptr %p) {
+; CHECK-LABEL: define void @align_with_noundef(
+; CHECK-SAME: ptr noundef align 4 [[P:%.*]]) {
+; CHECK-NEXT:    call void @use(ptr noundef align 4 [[P]])
+; CHECK-NEXT:    store i8 1, ptr [[P]], align 4
+; CHECK-NEXT:    ret void
+  call void @use(ptr noundef align 4 %p)
+  store i8 1, ptr %p, align 1
+  ret void
+}
+
+define i1 @nonnull_without_noundef(ptr %p) {
+; CHECK-LABEL: define i1 @nonnull_without_noundef(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT:    call void @use(ptr nonnull [[P]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr [[P]], null
+; CHECK-NEXT:    ret i1 [[CMP]]
+  call void @use(ptr nonnull %p)
+  %cmp = icmp ne ptr %p, null
+  ret i1 %cmp
+}
+
+define i1 @nonnull_with_noundef(ptr %p) {
+; CHECK-LABEL: define noundef i1 @nonnull_with_noundef(
+; CHECK-SAME: ptr noundef nonnull [[P:%.*]]) {
+; CHECK-NEXT:    call void @use(ptr noundef nonnull [[P]])
+; CHECK-NEXT:    ret i1 true
+  call void @use(ptr noundef nonnull %p)
+  %cmp = icmp ne ptr %p, null
+  ret i1 %cmp
+}
diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll
index 80a0b2befbbeec..601dadc281f881 100644
--- a/llvm/test/Transforms/Attributor/callbacks.ll
+++ b/llvm/test/Transforms/Attributor/callbacks.ll
@@ -33,7 +33,7 @@ define void @t0_caller(ptr %a) {
 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
-; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr noundef null, ptr noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr noundef nonnull @t0_callback_callee, ptr align 256 [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])
+; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr noundef null, ptr noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr noundef nonnull @t0_callback_callee, ptr noundef align 256 [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])
 ; CGSCC-NEXT:    ret void
 ;
 entry:
@@ -51,21 +51,21 @@ entry:
 define internal void @t0_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {
 ;
 ; TUNIT-LABEL: define {{[^@]+}}@t0_callback_callee
-; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {
+; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr noundef align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {
 ; TUNIT-NEXT:  entry:
 ; TUNIT-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
 ; TUNIT-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
 ; TUNIT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
-; TUNIT-NEXT:    tail call void @t0_check(ptr align 256 [[A]], i64 noundef 99, ptr align 32 [[TMP0]])
+; TUNIT-NEXT:    tail call void @t0_check(ptr noundef align 256 [[A]], i64 noundef 99, ptr align 32 [[TMP0]])
 ; TUNIT-NEXT:    ret void
 ;
 ; CGSCC-LABEL: define {{[^@]+}}@t0_callback_callee
-; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {
+; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr noundef align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {
 ; CGSCC-NEXT:  entry:
 ; CGSCC-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
 ; CGSCC-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
 ; CGSCC-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
-; CGSCC-NEXT:    tail call void @t0_check(ptr align 256 [[A]], i64 noundef 99, ptr [[TMP0]])
+; CGSCC-NEXT:    tail call void @t0_check(ptr noundef align 256 [[A]], i64 noundef 99, ptr [[TMP0]])
 ; CGSCC-NEXT:    ret void
 ;
 entry:
@@ -76,7 +76,7 @@ entry:
   ret void
 }
 
-declare void @t0_check(ptr align 256, i64, ptr)
+declare void @t0_check(ptr noundef align 256, i64, ptr)
 
 declare !callback !0 void @t0_callback_broker(ptr, ptr, ptr, ...)
 
@@ -106,7 +106,7 @@ define void @t1_caller(ptr noalias %a) {
 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
-; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t1_callback_callee, ptr align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])
+; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t1_callback_callee, ptr noundef align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])
 ; CGSCC-NEXT:    ret void
 ;
 entry:
@@ -125,22 +125,22 @@ define internal void @t1_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64
 ;
 ; TUNIT: Function Attrs: nosync
 ; TUNIT-LABEL: define {{[^@]+}}@t1_callback_callee
-; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
+; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr noundef align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
 ; TUNIT-NEXT:  entry:
 ; TUNIT-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
 ; TUNIT-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
 ; TUNIT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
-; TUNIT-NEXT:    tail call void @t1_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr align 32 captures(none) [[TMP0]])
+; TUNIT-NEXT:    tail call void @t1_check(ptr noundef align 256 captures(none) [[A]], i64 noundef 99, ptr align 32 captures(none) [[TMP0]])
 ; TUNIT-NEXT:    ret void
 ;
 ; CGSCC: Function Attrs: nosync
 ; CGSCC-LABEL: define {{[^@]+}}@t1_callback_callee
-; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
+; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr noundef align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CGSCC-NEXT:  entry:
 ; CGSCC-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
 ; CGSCC-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
 ; CGSCC-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
-; CGSCC-NEXT:    tail call void @t1_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr captures(none) [[TMP0]])
+; CGSCC-NEXT:    tail call void @t1_check(ptr noundef align 256 captures(none) [[A]], i64 noundef 99, ptr captures(none) [[TMP0]])
 ; CGSCC-NEXT:    ret void
 ;
 entry:
@@ -151,7 +151,7 @@ entry:
   ret void
 }
 
-declare void @t1_check(ptr nocapture align 256, i64, ptr nocapture) nosync
+declare void @t1_check(ptr nocapture noundef align 256, i64, ptr nocapture) nosync
 
 declare !callback !0 void @t1_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)
 
@@ -179,7 +179,7 @@ define void @t2_caller(ptr noalias %a) {
 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
-; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t2_callback_callee, ptr align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 capt...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/224932


More information about the llvm-commits mailing list