[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:47:41 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