-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
[Sink] Fix bugs of sinking unreachable BB from phi #68576
Conversation
@llvm/pr-subscribers-llvm-transforms ChangesResolve #68529. Full diff: https://github.com/llvm/llvm-project/pull/68576.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index ed69f1938ec7921..fc10243cff19964 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -368,6 +368,13 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_,
continue;
}
+ auto PredsAreReachable = [&Unreachable](BasicBlock *BB) -> bool {
+ for (auto *Pred : predecessors(BB))
+ if (Unreachable.count(Pred))
+ return false;
+ return true;
+ };
+
// processBlock doesn't thread BBs with unconditional TIs. However, if BB
// is "almost empty", we attempt to merge BB with its sole successor.
auto *BI = dyn_cast<BranchInst>(BB.getTerminator());
@@ -379,6 +386,7 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_,
// Don't alter Loop headers and latches to ensure another pass can
// detect and transform nested loops later.
!LoopHeaders.count(&BB) && !LoopHeaders.count(Succ) &&
+ PredsAreReachable(&BB) &&
TryToSimplifyUncondBranchFromEmptyBlock(&BB, DTU.get())) {
RemoveRedundantDbgInstrs(Succ);
// BB is valid for cleanup here because we passed in DTU. F remains
diff --git a/llvm/test/Transforms/JumpThreading/bb-unreachable-from-entry.ll b/llvm/test/Transforms/JumpThreading/bb-unreachable-from-entry.ll
index 2a9765233ec1043..e8fa399ff8a6d99 100644
--- a/llvm/test/Transforms/JumpThreading/bb-unreachable-from-entry.ll
+++ b/llvm/test/Transforms/JumpThreading/bb-unreachable-from-entry.ll
@@ -27,3 +27,38 @@ exit1:
exit2:
ret void
}
+
+define i32 @bar(i32 noundef %a) {
+; CHECK-LABEL: @bar(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[A:%.*]], 0
+; CHECK-NEXT: br i1 [[DOTNOT]], label [[END:%.*]], label [[ELSE:%.*]]
+; CHECK: else:
+; CHECK-NEXT: [[B:%.*]] = and i32 undef, 65535
+; CHECK-NEXT: br label [[B2:%.*]]
+; CHECK: dead:
+; CHECK-NEXT: br label [[B2]]
+; CHECK: B2:
+; CHECK-NEXT: br label [[END]]
+; CHECK: end:
+; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[B2]] ]
+; CHECK-NEXT: ret i32 [[DOT0]]
+;
+entry:
+ %.not = icmp eq i32 %a, 0
+ br i1 %.not, label %end, label %else
+
+ else: ; preds = %1
+ %b = and i32 undef, 65535
+ br label %B2
+
+dead: ; No predecessors!
+ br label %B2
+
+B2: ; preds = %2, %4
+ br label %end
+
+end: ; preds = %5, %1
+ %.0 = phi i32 [ %a, %entry ], [ %b, %B2 ]
+ ret i32 %.0
+}
diff --git a/llvm/test/Transforms/JumpThreading/unreachable-loops.ll b/llvm/test/Transforms/JumpThreading/unreachable-loops.ll
index 8d649761700a90c..7e1dcfb3e4c78a9 100644
--- a/llvm/test/Transforms/JumpThreading/unreachable-loops.ll
+++ b/llvm/test/Transforms/JumpThreading/unreachable-loops.ll
@@ -15,9 +15,11 @@ define void @unreachable_single_bb_loop() {
; CHECK: bb2:
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP]], 1
; CHECK-NEXT: switch i1 [[TMP4]], label [[BB2:%.*]] [
-; CHECK-NEXT: i1 false, label [[BB8]]
+; CHECK-NEXT: i1 false, label [[BB7:%.*]]
; CHECK-NEXT: i1 true, label [[BB8]]
; CHECK-NEXT: ]
+; CHECK: bb7:
+; CHECK-NEXT: br label [[BB8]]
; CHECK: bb8:
; CHECK-NEXT: ret void
;
@@ -57,9 +59,11 @@ define void @unreachable_multi_bbs_loop() {
; CHECK: bb2:
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP]], 1
; CHECK-NEXT: switch i1 [[TMP4]], label [[BB3:%.*]] [
-; CHECK-NEXT: i1 false, label [[BB8]]
+; CHECK-NEXT: i1 false, label [[BB7:%.*]]
; CHECK-NEXT: i1 true, label [[BB8]]
; CHECK-NEXT: ]
+; CHECK: bb7:
+; CHECK-NEXT: br label [[BB8]]
; CHECK: bb8:
; CHECK-NEXT: ret void
;
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unreachable blocks are dominated by all blocks, so this is well-defined IR. If a pass fails to handle it correctly, that pass needs to be fixed.
Does it mean |
Yes, that's right. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Resolve #68529.
Sink pass doesn't consider whether Basicblock from phi is unreachable.
This patch moves unreachability check after checking phi.