[llvm] [LoopSimplifyCFG] Added the judgment whether the loop is in LoopSimplifyForm (PR #112845)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 23:10:25 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: bwmaples (bwmaples)

<details>
<summary>Changes</summary>

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().

---
Full diff: https://github.com/llvm/llvm-project/pull/112845.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp (+9) 
- (modified) llvm/test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll (+66) 


``````````diff
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) {

``````````

</details>


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


More information about the llvm-commits mailing list