[llvm] 3adcf96 - [JumpThreading] Let ProcessImpliedCondition look into freeze instructions
Juneyoung Lee via llvm-commits
llvm-commits at lists.llvm.org
Tue May 17 18:51:29 PDT 2022
Author: Juneyoung Lee
Date: 2022-05-18T10:41:31+09:00
New Revision: 3adcf96b4faa06ff6d82a8bdf92d2a3f4917c433
URL: https://github.com/llvm/llvm-project/commit/3adcf96b4faa06ff6d82a8bdf92d2a3f4917c433
DIFF: https://github.com/llvm/llvm-project/commit/3adcf96b4faa06ff6d82a8bdf92d2a3f4917c433.diff
LOG: [JumpThreading] Let ProcessImpliedCondition look into freeze instructions
This patch makes JumpThreading's ProcessImpliedCondition deal with frozen
conditions.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D84941
Added:
Modified:
llvm/lib/Transforms/Scalar/JumpThreading.cpp
llvm/test/Transforms/JumpThreading/freeze-impliescond.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 4a64ada1b538..fc7bcbae21a3 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1251,6 +1251,17 @@ bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
return false;
Value *Cond = BI->getCondition();
+ // Assuming that predecessor's branch was taken, if pred's branch condition
+ // (V) implies Cond, Cond can be either true, undef, or poison. In this case,
+ // freeze(Cond) is either true or a nondeterministic value.
+ // If freeze(Cond) has only one use, we can freely fold freeze(Cond) to true
+ // without affecting other instructions.
+ auto *FICond = dyn_cast<FreezeInst>(Cond);
+ if (FICond && FICond->hasOneUse())
+ Cond = FICond->getOperand(0);
+ else
+ FICond = nullptr;
+
BasicBlock *CurrentBB = BB;
BasicBlock *CurrentPred = BB->getSinglePredecessor();
unsigned Iter = 0;
@@ -1267,6 +1278,15 @@ bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
bool CondIsTrue = PBI->getSuccessor(0) == CurrentBB;
Optional<bool> Implication =
isImpliedCondition(PBI->getCondition(), Cond, DL, CondIsTrue);
+
+ // If the branch condition of BB (which is Cond) and CurrentPred are
+ // exactly the same freeze instruction, Cond can be folded into CondIsTrue.
+ if (!Implication && FICond && isa<FreezeInst>(PBI->getCondition())) {
+ if (cast<FreezeInst>(PBI->getCondition())->getOperand(0) ==
+ FICond->getOperand(0))
+ Implication = CondIsTrue;
+ }
+
if (Implication) {
BasicBlock *KeepSucc = BI->getSuccessor(*Implication ? 0 : 1);
BasicBlock *RemoveSucc = BI->getSuccessor(*Implication ? 1 : 0);
@@ -1275,6 +1295,9 @@ bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
UncondBI->setDebugLoc(BI->getDebugLoc());
++NumFolds;
BI->eraseFromParent();
+ if (FICond)
+ FICond->eraseFromParent();
+
DTU->applyUpdatesPermissive({{DominatorTree::Delete, BB, RemoveSucc}});
if (HasProfileData)
BPI->eraseBlock(BB);
diff --git a/llvm/test/Transforms/JumpThreading/freeze-impliescond.ll b/llvm/test/Transforms/JumpThreading/freeze-impliescond.ll
index 470782dab7c1..0962e0e88495 100644
--- a/llvm/test/Transforms/JumpThreading/freeze-impliescond.ll
+++ b/llvm/test/Transforms/JumpThreading/freeze-impliescond.ll
@@ -42,20 +42,12 @@ define void @test2(i1 %cond, i1 %dummycond) {
; CHECK-NEXT: [[COND_FR0:%.*]] = freeze i1 [[COND:%.*]]
; CHECK-NEXT: br i1 [[COND_FR0]], label [[A:%.*]], label [[B:%.*]]
; CHECK: A:
-; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[A2:%.*]], label [[DUMMY:%.*]]
-; CHECK: A2:
-; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]]
-; CHECK-NEXT: br i1 [[COND_FR]], label [[REACHABLE:%.*]], label [[UNREACHABLE:%.*]]
+; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[REACHABLE:%.*]], label [[DUMMY:%.*]]
; CHECK: B:
-; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[B2:%.*]], label [[DUMMY]]
-; CHECK: B2:
-; CHECK-NEXT: [[COND_FR2:%.*]] = freeze i1 [[COND]]
-; CHECK-NEXT: br i1 [[COND_FR2]], label [[UNREACHABLE]], label [[REACHABLE]]
+; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[REACHABLE]], label [[DUMMY]]
; CHECK: REACHABLE:
; CHECK-NEXT: call void @f()
; CHECK-NEXT: ret void
-; CHECK: UNREACHABLE:
-; CHECK-NEXT: ret void
; CHECK: DUMMY:
; CHECK-NEXT: ret void
;
@@ -81,6 +73,14 @@ DUMMY:
ret void
}
+; In this specific example, it is still correct to fold %cond.fr into true.
+; This case is unsupported because it is unclear what is the result of
+; isImpliedCondition if LHS is poison or undef.
+; If isImpliedCondition(poison, any value) is true,
+; isImpliedCondition(and true, poison, false) is also true because 'and' propagates poison.
+; However, freeze(and true, poison) does not imply false because the former can
+; be frozen to true. Therefore, we cannot look through the argument of freeze (%cond.fr0)
+; in general under this isImpliedCondition definition.
define void @and_noopt(i32 %x, i1 %cond2, i1 %dummycond) {
; CHECK-LABEL: @and_noopt(
; CHECK-NEXT: [[COND1:%.*]] = icmp slt i32 0, [[X:%.*]]
@@ -135,10 +135,7 @@ define void @and(i32 %x, i1 %cond2, i1 %dummycond) {
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND1]], [[COND2:%.*]]
; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
; CHECK: A:
-; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[A2:%.*]], label [[DUMMY:%.*]]
-; CHECK: A2:
-; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND1]]
-; CHECK-NEXT: br i1 [[COND_FR]], label [[REACHABLE:%.*]], label [[UNREACHABLE:%.*]]
+; CHECK-NEXT: br i1 [[DUMMYCOND:%.*]], label [[REACHABLE:%.*]], label [[DUMMY:%.*]]
; CHECK: B:
; CHECK-NEXT: br i1 [[DUMMYCOND]], label [[B2:%.*]], label [[DUMMY]]
; CHECK: B2:
@@ -150,8 +147,6 @@ define void @and(i32 %x, i1 %cond2, i1 %dummycond) {
; CHECK: REACHABLE2:
; CHECK-NEXT: call void @f()
; CHECK-NEXT: ret void
-; CHECK: UNREACHABLE:
-; CHECK-NEXT: ret void
; CHECK: DUMMY:
; CHECK-NEXT: ret void
;
More information about the llvm-commits
mailing list