-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[Attributor][FIX] Fix NonNull deduction bug. #85810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
In commit b3fec10, NonNull deduction is improved but it introduces bug found by compiling Spec2006, and New codes will use the function isAssumeDead(const BasicBlock *BB) to check whether BB is dead, but AssumedLiveBlocks may not contain all the live blocks when used. And I revert codes partially to fix this bug.
@llvm/pr-subscribers-llvm-transforms Author: laichunfeng (lcvon007) ChangesIn commit b3fec10, NonNull deduction is improved but it introduces And I revert codes partially to fix this bug. Patch is 47.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85810.diff 4 Files Affected:
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index f98833bd119891..65e6e3a5bb43bf 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2425,6 +2425,8 @@ bool AANonNull::isImpliedByIR(Attributor &A, const IRPosition &IRP,
AttrKinds.push_back(Attribute::Dereferenceable);
if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
return true;
+ if (IRP.getPositionKind() == IRP_RETURNED)
+ return false;
DominatorTree *DT = nullptr;
AssumptionCache *AC = nullptr;
@@ -2436,25 +2438,8 @@ bool AANonNull::isImpliedByIR(Attributor &A, const IRPosition &IRP,
}
}
- SmallVector<AA::ValueAndContext> Worklist;
- if (IRP.getPositionKind() != IRP_RETURNED) {
- Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
- } else {
- bool UsedAssumedInformation = false;
- if (!A.checkForAllInstructions(
- [&](Instruction &I) {
- Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
- return true;
- },
- IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
- UsedAssumedInformation))
- return false;
- }
-
- if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
- return !isKnownNonZero(VAC.getValue(), A.getDataLayout(), 0, AC,
- VAC.getCtxI(), DT);
- }))
+ if (!isKnownNonZero(&IRP.getAssociatedValue(), A.getDataLayout(), 0, AC,
+ IRP.getCtxI(), DT))
return false;
A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 42d81792c2f4e4..4b0114299bb596 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -9,6 +9,9 @@ declare nonnull ptr @ret_nonnull()
declare void @llvm.assume(i1)
; Return a pointer trivially nonnull (call return attribute)
+;.
+; CHECK: @G = internal global i64 1, align 8
+;.
define ptr @test1() {
; CHECK-LABEL: define {{[^@]+}}@test1() {
; CHECK-NEXT: [[RET:%.*]] = call nonnull ptr @ret_nonnull()
@@ -34,10 +37,10 @@ define ptr @test2A(i1 %c, ptr %ret) {
; CHECK-SAME: (i1 noundef [[C:%.*]], ptr nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; CHECK: A:
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15:[0-9]+]] [ "nonnull"(ptr [[RET]]) ]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16:[0-9]+]] [ "nonnull"(ptr [[RET]]) ]
; CHECK-NEXT: ret ptr [[RET]]
; CHECK: B:
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15]] [ "nonnull"(ptr [[RET]]) ]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "nonnull"(ptr [[RET]]) ]
; CHECK-NEXT: ret ptr [[RET]]
;
br i1 %c, label %A, label %B
@@ -55,10 +58,10 @@ define ptr @test2B(i1 %c, ptr %ret) {
; CHECK-SAME: (i1 noundef [[C:%.*]], ptr nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; CHECK: A:
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15]] [ "dereferenceable"(ptr [[RET]], i32 4) ]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "dereferenceable"(ptr [[RET]], i32 4) ]
; CHECK-NEXT: ret ptr [[RET]]
; CHECK: B:
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15]] [ "dereferenceable"(ptr [[RET]], i32 4) ]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "dereferenceable"(ptr [[RET]], i32 4) ]
; CHECK-NEXT: ret ptr [[RET]]
;
br i1 %c, label %A, label %B
@@ -274,7 +277,7 @@ define ptr @test10(ptr %a, i64 %n) {
; CHECK-LABEL: define {{[^@]+}}@test10
; CHECK-SAME: (ptr nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[N]], 0
-; CHECK-NEXT: call void @llvm.assume(i1 noundef [[CMP]]) #[[ATTR15]]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef [[CMP]]) #[[ATTR16]]
; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[N]]
; CHECK-NEXT: ret ptr [[B]]
;
@@ -397,20 +400,20 @@ define internal ptr @f1(ptr %arg) {
; TUNIT-NEXT: [[TMP:%.*]] = icmp eq ptr [[ARG]], null
; TUNIT-NEXT: br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
; TUNIT: bb1:
-; TUNIT-NEXT: [[TRUETMP2:%.*]] = load i32, ptr [[ARG]], align 4
-; TUNIT-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[TRUETMP2]], 0
-; TUNIT-NEXT: br i1 [[TRUETMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
+; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARG]], align 4
+; TUNIT-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; TUNIT-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
; TUNIT: bb4:
-; TUNIT-NEXT: [[TRUETMP5:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 1
-; TUNIT-NEXT: [[TMP5B:%.*]] = tail call ptr @f3(ptr nofree nonnull readonly [[TRUETMP5]]) #[[ATTR16:[0-9]+]]
+; TUNIT-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 1
+; TUNIT-NEXT: [[TMP5B:%.*]] = tail call ptr @f3(ptr nofree nonnull readonly [[TMP5]]) #[[ATTR17:[0-9]+]]
; TUNIT-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, ptr [[TMP5B]], i64 -1
; TUNIT-NEXT: br label [[BB9]]
; TUNIT: bb6:
-; TUNIT-NEXT: [[TRUETMP7:%.*]] = tail call ptr @f2(ptr nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR16]]
-; TUNIT-NEXT: ret ptr [[TRUETMP7]]
+; TUNIT-NEXT: [[TMP7:%.*]] = tail call ptr @f2(ptr nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR17]]
+; TUNIT-NEXT: ret ptr [[TMP7]]
; TUNIT: bb9:
-; TUNIT-NEXT: [[TRUETMP10:%.*]] = phi ptr [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to ptr), [[BB:%.*]] ]
-; TUNIT-NEXT: ret ptr [[TRUETMP10]]
+; TUNIT-NEXT: [[TMP10:%.*]] = phi ptr [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to ptr), [[BB:%.*]] ]
+; TUNIT-NEXT: ret ptr [[TMP10]]
;
; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@f1
@@ -419,20 +422,20 @@ define internal ptr @f1(ptr %arg) {
; CGSCC-NEXT: [[TMP:%.*]] = icmp eq ptr [[ARG]], null
; CGSCC-NEXT: br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
; CGSCC: bb1:
-; CGSCC-NEXT: [[TRUETMP2:%.*]] = load i32, ptr [[ARG]], align 4
-; CGSCC-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[TRUETMP2]], 0
-; CGSCC-NEXT: br i1 [[TRUETMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
+; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARG]], align 4
+; CGSCC-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CGSCC-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
; CGSCC: bb4:
-; CGSCC-NEXT: [[TRUETMP5:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 1
-; CGSCC-NEXT: [[TMP5B:%.*]] = tail call ptr @f3(ptr nofree nonnull readonly [[TRUETMP5]]) #[[ATTR16:[0-9]+]]
+; CGSCC-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 1
+; CGSCC-NEXT: [[TMP5B:%.*]] = tail call ptr @f3(ptr nofree nonnull readonly [[TMP5]]) #[[ATTR17:[0-9]+]]
; CGSCC-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, ptr [[TMP5B]], i64 -1
; CGSCC-NEXT: br label [[BB9]]
; CGSCC: bb6:
-; CGSCC-NEXT: [[TRUETMP7:%.*]] = tail call ptr @f2(ptr nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR16]]
-; CGSCC-NEXT: ret ptr [[TRUETMP7]]
+; CGSCC-NEXT: [[TMP7:%.*]] = tail call ptr @f2(ptr nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR17]]
+; CGSCC-NEXT: ret ptr [[TMP7]]
; CGSCC: bb9:
-; CGSCC-NEXT: [[TRUETMP10:%.*]] = phi ptr [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to ptr), [[BB:%.*]] ]
-; CGSCC-NEXT: ret ptr [[TRUETMP10]]
+; CGSCC-NEXT: [[TMP10:%.*]] = phi ptr [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to ptr), [[BB:%.*]] ]
+; CGSCC-NEXT: ret ptr [[TMP10]]
;
bb:
@@ -464,14 +467,14 @@ define internal ptr @f2(ptr %arg) {
; TUNIT-LABEL: define {{[^@]+}}@f2
; TUNIT-SAME: (ptr nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = tail call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR16]]
+; TUNIT-NEXT: [[TMP:%.*]] = tail call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR17]]
; TUNIT-NEXT: ret ptr [[TMP]]
;
; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@f2
; CGSCC-SAME: (ptr nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = tail call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR16]]
+; CGSCC-NEXT: [[TMP:%.*]] = tail call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR17]]
; CGSCC-NEXT: ret ptr [[TMP]]
;
bb:
@@ -485,14 +488,14 @@ define dso_local noalias ptr @f3(ptr %arg) {
; TUNIT-LABEL: define {{[^@]+}}@f3
; TUNIT-SAME: (ptr nofree readonly [[ARG:%.*]]) #[[ATTR6]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR16]]
+; TUNIT-NEXT: [[TMP:%.*]] = call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR17]]
; TUNIT-NEXT: ret ptr [[TMP]]
;
; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@f3
; CGSCC-SAME: (ptr nofree readonly [[ARG:%.*]]) #[[ATTR5]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR16]]
+; CGSCC-NEXT: [[TMP:%.*]] = call ptr @f1(ptr nofree readonly [[ARG]]) #[[ATTR17]]
; CGSCC-NEXT: ret ptr [[TMP]]
;
bb:
@@ -856,7 +859,7 @@ define i8 @parent6(ptr %a, ptr %b) {
define i8 @parent7(ptr %a) {
; CHECK-LABEL: define {{[^@]+}}@parent7
; CHECK-SAME: (ptr nonnull [[A:%.*]]) {
-; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(ptr nonnull readonly [[A]]) #[[ATTR17:[0-9]+]]
+; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(ptr nonnull readonly [[A]]) #[[ATTR18:[0-9]+]]
; CHECK-NEXT: call void @use1nonnull(ptr nonnull [[A]])
; CHECK-NEXT: ret i8 [[RET]]
;
@@ -877,12 +880,12 @@ define i1 @parent8(ptr %a, ptr %bogus1, ptr %b) personality ptr @esfp{
; TUNIT-SAME: (ptr nonnull [[A:%.*]], ptr nocapture nofree readnone [[BOGUS1:%.*]], ptr nonnull [[B:%.*]]) #[[ATTR5]] personality ptr @esfp {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: invoke void @use2nonnull(ptr nonnull [[A]], ptr nonnull [[B]])
-; TUNIT-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
+; TUNIT-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; TUNIT: cont:
; TUNIT-NEXT: ret i1 false
; TUNIT: exc:
; TUNIT-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
-; TUNIT-NEXT: filter [0 x ptr] zeroinitializer
+; TUNIT-NEXT: filter [0 x ptr] zeroinitializer
; TUNIT-NEXT: unreachable
;
; CGSCC: Function Attrs: nounwind
@@ -890,12 +893,12 @@ define i1 @parent8(ptr %a, ptr %bogus1, ptr %b) personality ptr @esfp{
; CGSCC-SAME: (ptr nonnull [[A:%.*]], ptr nocapture nofree readnone [[BOGUS1:%.*]], ptr nonnull [[B:%.*]]) #[[ATTR4]] personality ptr @esfp {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: invoke void @use2nonnull(ptr nonnull [[A]], ptr nonnull [[B]])
-; CGSCC-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
+; CGSCC-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; CGSCC: cont:
; CGSCC-NEXT: ret i1 false
; CGSCC: exc:
; CGSCC-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
-; CGSCC-NEXT: filter [0 x ptr] zeroinitializer
+; CGSCC-NEXT: filter [0 x ptr] zeroinitializer
; CGSCC-NEXT: unreachable
;
@@ -963,7 +966,6 @@ define ptr addrspace(3) @as(ptr addrspace(3) dereferenceable(4) %p) {
ret ptr addrspace(3) %p
}
-; CHECK-NOT: @g2()
define internal ptr @g2() {
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@g2
@@ -982,7 +984,7 @@ define ptr @g1() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@g1
; CGSCC-SAME: () #[[ATTR10:[0-9]+]] {
-; CGSCC-NEXT: [[C:%.*]] = call noundef nonnull align 4 ptr @g2() #[[ATTR18:[0-9]+]]
+; CGSCC-NEXT: [[C:%.*]] = call noundef nonnull align 4 ptr @g2() #[[ATTR19:[0-9]+]]
; CGSCC-NEXT: ret ptr [[C]]
;
%c = call ptr @g2()
@@ -1100,33 +1102,33 @@ define i32 @nonnull_exec_ctx_1(ptr %a, i32 %b) {
; TUNIT-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
; TUNIT-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR8]] {
; TUNIT-NEXT: en:
-; TUNIT-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[B]], 0
-; TUNIT-NEXT: br i1 [[TRUETMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; TUNIT-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; TUNIT-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
; TUNIT: ex:
-; TUNIT-NEXT: [[TRUETMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR7]]
-; TUNIT-NEXT: ret i32 [[TRUETMP5]]
+; TUNIT-NEXT: [[TMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR7]]
+; TUNIT-NEXT: ret i32 [[TMP5]]
; TUNIT: hd:
-; TUNIT-NEXT: [[TRUETMP7:%.*]] = phi i32 [ [[TRUETMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
+; TUNIT-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
; TUNIT-NEXT: tail call void @h(ptr [[A]]) #[[ATTR7]]
-; TUNIT-NEXT: [[TRUETMP8]] = add nuw i32 [[TRUETMP7]], 1
-; TUNIT-NEXT: [[TRUETMP9:%.*]] = icmp eq i32 [[TRUETMP8]], [[B]]
-; TUNIT-NEXT: br i1 [[TRUETMP9]], label [[EX]], label [[HD]]
+; TUNIT-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; TUNIT-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; TUNIT-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
; CGSCC: Function Attrs: mustprogress nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
; CGSCC-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
; CGSCC-NEXT: en:
-; CGSCC-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[B]], 0
-; CGSCC-NEXT: br i1 [[TRUETMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; CGSCC-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; CGSCC-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
; CGSCC: ex:
-; CGSCC-NEXT: [[TRUETMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR6]]
-; CGSCC-NEXT: ret i32 [[TRUETMP5]]
+; CGSCC-NEXT: [[TMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR6]]
+; CGSCC-NEXT: ret i32 [[TMP5]]
; CGSCC: hd:
-; CGSCC-NEXT: [[TRUETMP7:%.*]] = phi i32 [ [[TRUETMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
+; CGSCC-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
; CGSCC-NEXT: tail call void @h(ptr [[A]]) #[[ATTR6]]
-; CGSCC-NEXT: [[TRUETMP8]] = add nuw i32 [[TRUETMP7]], 1
-; CGSCC-NEXT: [[TRUETMP9:%.*]] = icmp eq i32 [[TRUETMP8]], [[B]]
-; CGSCC-NEXT: br i1 [[TRUETMP9]], label [[EX]], label [[HD]]
+; CGSCC-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; CGSCC-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; CGSCC-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -1150,37 +1152,37 @@ define i32 @nonnull_exec_ctx_1b(ptr %a, i32 %b) {
; TUNIT-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
; TUNIT-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR8]] {
; TUNIT-NEXT: en:
-; TUNIT-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[B]], 0
-; TUNIT-NEXT: br i1 [[TRUETMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; TUNIT-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; TUNIT-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
; TUNIT: ex:
-; TUNIT-NEXT: [[TRUETMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR7]]
-; TUNIT-NEXT: ret i32 [[TRUETMP5]]
+; TUNIT-NEXT: [[TMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR7]]
+; TUNIT-NEXT: ret i32 [[TMP5]]
; TUNIT: hd:
-; TUNIT-NEXT: [[TRUETMP7:%.*]] = phi i32 [ [[TRUETMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
+; TUNIT-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
; TUNIT-NEXT: tail call void @h(ptr [[A]]) #[[ATTR7]]
; TUNIT-NEXT: br label [[HD2]]
; TUNIT: hd2:
-; TUNIT-NEXT: [[TRUETMP8]] = add nuw i32 [[TRUETMP7]], 1
-; TUNIT-NEXT: [[TRUETMP9:%.*]] = icmp eq i32 [[TRUETMP8]], [[B]]
-; TUNIT-NEXT: br i1 [[TRUETMP9]], label [[EX]], label [[HD]]
+; TUNIT-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; TUNIT-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; TUNIT-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
; CGSCC: Function Attrs: mustprogress nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
; CGSCC-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
; CGSCC-NEXT: en:
-; CGSCC-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[B]], 0
-; CGSCC-NEXT: br i1 [[TRUETMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; CGSCC-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; CGSCC-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
; CGSCC: ex:
-; CGSCC-NEXT: [[TRUETMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR6]]
-; CGSCC-NEXT: ret i32 [[TRUETMP5]]
+; CGSCC-NEXT: [[TMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR6]]
+; CGSCC-NEXT: ret i32 [[TMP5]]
; CGSCC: hd:
-; CGSCC-NEXT: [[TRUETMP7:%.*]] = phi i32 [ [[TRUETMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
+; CGSCC-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
; CGSCC-NEXT: tail call void @h(ptr [[A]]) #[[ATTR6]]
; CGSCC-NEXT: br label [[HD2]]
; CGSCC: hd2:
-; CGSCC-NEXT: [[TRUETMP8]] = add nuw i32 [[TRUETMP7]], 1
-; CGSCC-NEXT: [[TRUETMP9:%.*]] = icmp eq i32 [[TRUETMP8]], [[B]]
-; CGSCC-NEXT: br i1 [[TRUETMP9]], label [[EX]], label [[HD]]
+; CGSCC-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; CGSCC-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; CGSCC-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -1207,33 +1209,33 @@ define i32 @nonnull_exec_ctx_2(ptr %a, i32 %b) willreturn nounwind {
; TUNIT-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
; TUNIT-SAME: (ptr nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR8]] {
; TUNIT-NEXT: en:
-; TUNIT-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[B]], 0
-; TUNIT-NEXT: br i1 [[TRUETMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; TUNIT-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; TUNIT-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
; TUNIT: ex:
-; TUNIT-NEXT: [[TRUETMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR5]]
-; TUNIT-NEXT: ret i32 [[TRUETMP5]]
+; TUNIT-NEXT: [[TMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR5]]
+; TUNIT-NEXT: ret i32 [[TMP5]]
; TUNIT: hd:
-; TUNIT-NEXT: [[TRUETMP7:%.*]] = phi i32 [ [[TRUETMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
+; TUNIT-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
; TUNIT-NEXT: tail call void @h(ptr nonnull [[A]]) #[[ATTR5]]
-; TUNIT-NEXT: [[TRUETMP8]] = add nuw i32 [[TRUETMP7]], 1
-; TUNIT-NEXT: [[TRUETMP9:%.*]] = icmp eq i32 [[TRUETMP8]], [[B]]
-; TUNIT-NEXT: br i1 [[TRUETMP9]], label [[EX]], label [[HD]]
+; TUNIT-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; TUNIT-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; TUNIT-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
; CGSCC: Function Attrs: mustprogress nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
; CGSCC-SAME: (ptr nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
; CGSCC-NEXT: en:
-; CGSCC-NEXT: [[TRUETMP3:%.*]] = icmp eq i32 [[B]], 0
-; CGSCC-NEXT: br i1 [[TRUETMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; CGSCC-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; CGSCC-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
; CGSCC: ex:
-; CGSCC-NEXT: [[TRUETMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR4]]
-; CGSCC-NEXT: ret i32 [[TRUETMP5]]
+; CGSCC-NEXT: [[TMP5:%.*]] = tail call i32 @g(ptr nonnull [[A]]) #[[ATTR4]]
+; CGSCC-NEXT: ret i32 [[TMP5]]
; CGSCC: hd:
-; CGSCC-NEXT: [[TRUETMP7:%.*]] = phi i32 [ [[TRUETMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
+; CGSCC-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
; CGSCC-NEXT: tail call void @h(ptr nonnull [[A...
[truncated]
|
@G = internal global i64 1, align 8
define dso_local ptr @update_global_in_alive_bb() {
entry:
%0 = load i64, ptr @G, align 8
%cmp = icmp ne i64 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then:
store i64 0, ptr @G, align 8
ret ptr inttoptr (i64 5 to ptr)
if.else:
ret ptr null
} It can not defer nonull attribute for this function(Call this function twice will get different result.), but the compiler consider it's nonnull return @jdoerfert . |
Sorry, I missed this. Let me look into the issue. Bug is for sure confirmed. |
We cannot use assumed dead information for nonnull IR-implied deduction as we will never go back and re-check. This was reported in llvm#85810
Can you check if #93322 fixes your issue? |
I have a comment about the testcase in your PR, please help review it @jdoerfert |
We cannot use assumed dead information for nonnull IR-implied deduction as we will never go back and re-check. This was reported in #85810
In commit b3fec10, NonNull deduction is improved but it introduces
bug found by compiling Spec2006, and New codes will use the function
isAssumeDead(const BasicBlock *BB) to check whether BB is dead, but
AssumedLiveBlocks may not contain all the live blocks when used.
And I revert codes partially to fix this bug.