[llvm] [LoopSimplifyCFG] Added the judgment whether the loop is in LoopSimplifyForm (PR #112845)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 21 20:49:52 PDT 2024
https://github.com/bwmaples updated https://github.com/llvm/llvm-project/pull/112845
>From ebe639f26a583394304113be192fc6d5396e4398 Mon Sep 17 00:00:00 2001
From: luanqingxin <luanqingxin at bytedance.com>
Date: Thu, 17 Oct 2024 21:42:33 +0800
Subject: [PATCH 1/2] [LoopSimplifyCFG] Added the judgment whether the loop is
in LoopSimplifyForm We can't add a single preheader for loop when any
preheader of loop ends with a indirectbranch inst. We will get nullptr in
function handleDeadExits when L.getLoopPreheader().
---
.../lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 9 +++
.../LoopSimplifyCFG/constant-fold-branch.ll | 66 +++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index ae9103d0608a11..2b0885f2686994 100644
--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -588,6 +588,15 @@ class ConstantTerminatorFoldingImpl {
return false;
}
+ // we can't handle the case when the loop isn't in LoopSimplifyForm.
+ // eg: indirectbranch
+ if (!DeadExitBlocks.empty() && !L.isLoopSimplifyForm()) {
+ LLVM_DEBUG(dbgs() << "Give up constant terminator folding in loop "
+ << Header->getName()
+ << ": loop isn't in SimplifyForm.\n");
+ return false;
+ }
+
SE.forgetTopmostLoop(&L);
// Dump analysis results.
LLVM_DEBUG(dump());
diff --git a/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll b/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
index 95667ebcc9fb24..aac12ee1c70e85 100644
--- a/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
+++ b/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
@@ -280,6 +280,72 @@ exit:
ret i32 %i.1
}
+; Check that we can handle indirectbranch.
+define i32 @dead_exit_test_indirectbranch_loop(i32 %end) {
+; CHECK-LABEL: @dead_exit_test_indirectbranch_loop(
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 10, [[END:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[PREBB1:%.*]], label [[PREBB2:%.*]]
+; CHECK: preBB1:
+; CHECK-NEXT: indirectbr ptr blockaddress(@dead_exit_test_indirectbranch_loop, [[HEADER:%.*]]), [label [[HEADER]], label %exit]
+; CHECK: preBB2:
+; CHECK-NEXT: indirectbr ptr blockaddress(@dead_exit_test_indirectbranch_loop, [[EXIT:%.*]]), [label [[HEADER]], label %exit]
+; CHECK: header:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREBB1]] ], [ 1, [[PREBB2]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
+; CHECK: dead:
+; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ]
+; CHECK-NEXT: br label [[DUMMY:%.*]]
+; CHECK: dummy:
+; CHECK-NEXT: br label [[LOOP_EXIT:%.*]]
+; CHECK: backedge:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
+; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[LOOP_EXIT_LOOPEXIT:%.*]]
+; CHECK: loop.exit.loopexit:
+; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
+; CHECK-NEXT: br label [[LOOP_EXIT]]
+; CHECK: loop.exit:
+; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[DUMMY]] ], [ [[I_INC_LCSSA]], [[LOOP_EXIT_LOOPEXIT]] ]
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[I_1]], [[LOOP_EXIT]] ], [ -1, [[PREBB1]] ], [ -1, [[PREBB2]] ]
+; CHECK-NEXT: ret i32 [[RET]]
+;
+start:
+ %cond = icmp slt i32 10, %end
+ br i1 %cond, label %preBB1, label %preBB2
+
+preBB1:
+ indirectbr ptr blockaddress(@dead_exit_test_indirectbranch_loop, %header), [label %header, label %exit]
+
+preBB2:
+ indirectbr ptr blockaddress(@dead_exit_test_indirectbranch_loop, %exit), [label %header, label %exit]
+
+header:
+ %i = phi i32 [0, %preBB1], [1, %preBB2], [%i.inc, %backedge]
+ br i1 true, label %backedge, label %dead
+
+dead:
+ br label %dummy
+
+dummy:
+ br label %loop.exit
+
+backedge:
+ %i.inc = add i32 %i, 1
+ %cmp = icmp slt i32 %i.inc, %end
+ br i1 %cmp, label %header, label %loop.exit
+
+loop.exit:
+ %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
+ br label %exit
+
+exit:
+ %ret = phi i32 [%i.1, %loop.exit], [-1, %preBB1], [-1, %preBB2]
+ ret i32 %ret
+}
+
; Check that we preserve static reachibility of a dead exit block while deleting
; a switch.
define i32 @dead_exit_test_switch_loop(i32 %end) {
>From 4e927627cfff8625f4ad577f290ca6c4ab2e1be9 Mon Sep 17 00:00:00 2001
From: luanqingxin <luanqingxin at bytedance.com>
Date: Tue, 22 Oct 2024 11:46:24 +0800
Subject: [PATCH 2/2] [LoopSimplifyCFG] Avoid preheader is nullptr in
handleDeadExits
---
llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 10 +---------
.../LoopSimplifyCFG/constant-fold-branch.ll | 14 ++++++--------
2 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index 2b0885f2686994..e1b5e3428d891d 100644
--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -349,6 +349,7 @@ class ConstantTerminatorFoldingImpl {
// Construct split preheader and the dummy switch to thread edges from it to
// dead exits.
BasicBlock *Preheader = L.getLoopPreheader();
+ if (Preheader == NULL) return;
BasicBlock *NewPreheader = llvm::SplitBlock(
Preheader, Preheader->getTerminator(), &DT, &LI, MSSAU);
@@ -588,15 +589,6 @@ class ConstantTerminatorFoldingImpl {
return false;
}
- // we can't handle the case when the loop isn't in LoopSimplifyForm.
- // eg: indirectbranch
- if (!DeadExitBlocks.empty() && !L.isLoopSimplifyForm()) {
- LLVM_DEBUG(dbgs() << "Give up constant terminator folding in loop "
- << Header->getName()
- << ": loop isn't in SimplifyForm.\n");
- return false;
- }
-
SE.forgetTopmostLoop(&L);
// Dump analysis results.
LLVM_DEBUG(dump());
diff --git a/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll b/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
index aac12ee1c70e85..f0eec63118e7be 100644
--- a/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
+++ b/llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll
@@ -291,19 +291,17 @@ define i32 @dead_exit_test_indirectbranch_loop(i32 %end) {
; CHECK: preBB2:
; CHECK-NEXT: indirectbr ptr blockaddress(@dead_exit_test_indirectbranch_loop, [[EXIT:%.*]]), [label [[HEADER]], label %exit]
; CHECK: header:
-; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREBB1]] ], [ 1, [[PREBB2]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[PREBB1]] ], [ 1, [[PREBB2]] ], [ [[I_INC:%.*]], [[HEADER]] ]
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
+; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[LOOP_EXIT_LOOPEXIT:%.*]]
; CHECK: dead:
-; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ]
+; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32
; CHECK-NEXT: br label [[DUMMY:%.*]]
; CHECK: dummy:
; CHECK-NEXT: br label [[LOOP_EXIT:%.*]]
-; CHECK: backedge:
-; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
-; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[LOOP_EXIT_LOOPEXIT:%.*]]
; CHECK: loop.exit.loopexit:
-; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
+; CHECK-NEXT: [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
; CHECK-NEXT: br label [[LOOP_EXIT]]
; CHECK: loop.exit:
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[DUMMY]] ], [ [[I_INC_LCSSA]], [[LOOP_EXIT_LOOPEXIT]] ]
More information about the llvm-commits
mailing list