[llvm] [SimplifyCFG] Simplify conditional branches on const icmp eq's (PR #73334)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 24 06:44:47 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: None (yonillasky)
<details>
<summary>Changes</summary>
The issue that is being addressed here is shown in the `@ intersection_block_with_dead_predecessor` test.
Before this fix, what happens there is that:
- SimplifyCFG converts the switch instruction into a conditional branch (on the PHI value)
- SimplifyCFG identifies the block `%a` is dead, and deletes it
- PHI decays into a constant
- The condition of the conditional branch is now a compile-time constant, so one of the outgoing edges is dead, but no further simplification is performed (though here, for instance, `%c` is a dead block)
I am fixing that, by explicitly doing the necessary constant-folding for this specific case.
---
Full diff: https://github.com/llvm/llvm-project/pull/73334.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+18)
- (added) llvm/test/Transforms/SimplifyCFG/constant-valued-cond-br.ll (+47)
``````````diff
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 3bcd896639a8ec2..2fe0c281662aa36 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3578,6 +3578,13 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
return true;
}
+static BranchInst *decayCondBranchToUncondBranch(IRBuilderBase &Builder, BranchInst *BI, bool Eval) {
+ unsigned SuccessorIdx = (Eval) ? 0 : 1;
+ auto *NewBI = Builder.CreateBr(BI->getSuccessor(SuccessorIdx));
+ BI->eraseFromParent();
+ return NewBI;
+}
+
static Value *createLogicalOp(IRBuilderBase &Builder,
Instruction::BinaryOps Opc, Value *LHS,
Value *RHS, const Twine &Name = "") {
@@ -7325,6 +7332,17 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (mergeConditionalStores(PBI, BI, DTU, DL, TTI))
return requestResimplify();
+ // Check if the condition is an equality between two constants. This can form due to other
+ // CFGSimplify steps, and may prevent further simplification if we don't deal with it here.
+ if (auto ICmp = dyn_cast<ICmpInst>(BI->getCondition()))
+ if (ICmp->getPredicate() == CmpInst::ICMP_EQ)
+ if (auto *LHS = dyn_cast<ConstantInt>(ICmp->getOperand(0)))
+ if (auto *RHS = dyn_cast<ConstantInt>(ICmp->getOperand(1))) {
+ bool CondEval = LHS->getZExtValue() == RHS->getZExtValue();
+ decayCondBranchToUncondBranch(Builder, BI, CondEval);
+ return requestResimplify();
+ }
+
return false;
}
diff --git a/llvm/test/Transforms/SimplifyCFG/constant-valued-cond-br.ll b/llvm/test/Transforms/SimplifyCFG/constant-valued-cond-br.ll
new file mode 100644
index 000000000000000..51262dab3ab0436
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/constant-valued-cond-br.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
+
+define void @const_valued_cond_br(ptr %P) {
+; CHECK-LABEL: define void @const_valued_cond_br(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 42, 42
+; CHECK-NEXT: store i32 123, ptr [[P]], align 4
+; CHECK-NEXT: ret void
+;
+entry:
+ %cond = icmp eq i32 42, 42
+ br i1 %cond, label %a, label %b
+a:
+ store i32 123, ptr %P
+ br label %b
+b:
+ ret void
+}
+
+
+
+define void @intersection_block_with_dead_predecessor(ptr %P) {
+; CHECK-LABEL: define void @intersection_block_with_dead_predecessor(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 1, 1
+; CHECK-NEXT: store i32 321, ptr [[P]], align 4
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %b
+b:
+ %x = phi i32 [1, %entry], [2, %a]
+ switch i32 %x, label %c [
+ i32 1, label %d
+ ]
+c:
+ store i32 123, ptr %P
+ ret void
+d:
+ store i32 321, ptr %P
+ ret void
+a: ; unreachable
+ br label %b
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/73334
More information about the llvm-commits
mailing list