[PATCH] D85029: [JumpThreading] Allow duplicating a basic block into preds when its branch condition is freeze(phi)

Juneyoung Lee via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 4 01:56:59 PDT 2020


aqjune updated this revision to Diff 282831.
aqjune added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85029/new/

https://reviews.llvm.org/D85029

Files:
  llvm/lib/Transforms/Scalar/JumpThreading.cpp
  llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll


Index: llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll
===================================================================
--- llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll
+++ llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll
@@ -37,17 +37,15 @@
 
 define i32 @test2(i1 %cond, i1 %a, i1 %b) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[C:%.*]]
 ; CHECK:       A:
 ; CHECK-NEXT:    call void @f()
-; CHECK-NEXT:    br label [[C:%.*]]
-; CHECK:       B:
-; CHECK-NEXT:    call void @g()
-; CHECK-NEXT:    br label [[C]]
+; CHECK-NEXT:    [[P_FR1:%.*]] = freeze i1 [[A:%.*]]
+; CHECK-NEXT:    br i1 [[P_FR1]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
 ; CHECK:       C:
-; CHECK-NEXT:    [[P:%.*]] = phi i1 [ [[A:%.*]], [[A]] ], [ [[B:%.*]], [[B]] ]
-; CHECK-NEXT:    [[P_FR:%.*]] = freeze i1 [[P]]
-; CHECK-NEXT:    br i1 [[P_FR]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
+; CHECK-NEXT:    call void @g()
+; CHECK-NEXT:    [[P_FR:%.*]] = freeze i1 [[B:%.*]]
+; CHECK-NEXT:    br i1 [[P_FR]], label [[EXIT1]], label [[EXIT2]]
 ; CHECK:       EXIT1:
 ; CHECK-NEXT:    ret i32 0
 ; CHECK:       EXIT2:
Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1197,11 +1197,14 @@
   if (ProcessThreadableEdges(CondInst, BB, Preference, Terminator))
     return true;
 
-  // If this is an otherwise-unfoldable branch on a phi node in the current
-  // block, see if we can simplify.
-  if (PHINode *PN = dyn_cast<PHINode>(CondInst))
-    if (PN->getParent() == BB && isa<BranchInst>(BB->getTerminator()))
-      return ProcessBranchOnPHI(PN);
+  // If this is an otherwise-unfoldable branch on a phi node or freeze(phi) in
+  // the current block, see if we can simplify.
+  PHINode *PN = dyn_cast<PHINode>(
+      isa<FreezeInst>(CondInst) ? cast<FreezeInst>(CondInst)->getOperand(0)
+                                : CondInst);
+
+  if (PN && PN->getParent() == BB && isa<BranchInst>(BB->getTerminator()))
+    return ProcessBranchOnPHI(PN);
 
   // If this is an otherwise-unfoldable branch on a XOR, see if we can simplify.
   if (CondInst->getOpcode() == Instruction::Xor &&
@@ -1757,8 +1760,8 @@
 }
 
 /// ProcessBranchOnPHI - We have an otherwise unthreadable conditional branch on
-/// a PHI node in the current block.  See if there are any simplifications we
-/// can do based on inputs to the phi node.
+/// a PHI node (or freeze PHI) in the current block.  See if there are any
+/// simplifications we can do based on inputs to the phi node.
 bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) {
   BasicBlock *BB = PN->getParent();
 
@@ -1771,6 +1774,22 @@
   // *duplicate* the conditional branch into that block in order to further
   // encourage jump threading and to eliminate cases where we have branch on a
   // phi of an icmp (branch on icmp is much better).
+  // This transformation is correct when a frozen PN is used as a branch
+  // condition as well, because it does not remove the freeze instruction.
+  //
+  //   p = phi [a, pred1] [b, pred2]
+  //   p.fr = freeze p
+  //   br p.fr, ...
+  // =>
+  // pred1:
+  //   p.fr = freeze a
+  //   br p.fr, ...
+  // pred2:
+  //   p.fr2 = freeze b
+  //   br p.fr2, ...
+  //
+  // This is beneficial because when a and b are icmps CodeGenPrepare can
+  // canonicalize them to br(freeze(icmp)).
   for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
     BasicBlock *PredBB = PN->getIncomingBlock(i);
     if (BranchInst *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator()))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85029.282831.patch
Type: text/x-patch
Size: 3774 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200804/b6ebaf2e/attachment.bin>


More information about the llvm-commits mailing list