[InstCombine] Combine select & Phi by same condition
authorMax Kazantsev <mkazantsev@azul.com>
Thu, 25 Jun 2020 03:42:16 +0000 (10:42 +0700)
committerMax Kazantsev <mkazantsev@azul.com>
Thu, 25 Jun 2020 03:44:10 +0000 (10:44 +0700)
This patch transforms
```
p = phi [x, y]
s = select cond, z, p
```
with
```
s = phi[x, z]
```
if we can prove that the Phi node takes values basing on select's condition.

Differential Revision: https://reviews.llvm.org/D82072
Reviewed By: nikic

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/select.ll

index 346b4b2..cef991a 100644 (file)
@@ -2469,6 +2469,11 @@ static Instruction *foldSelectToPhi(SelectInst &Sel, const DominatorTree &DT,
   } else
     return nullptr;
 
+  // We want to replace select %cond, %a, %b with a phi that takes value %a
+  // for all incoming edges that are dominated by condition `%cond == true`,
+  // and value %b for edges dominated by condition `%cond == false`. If %a
+  // or %b are also phis from the same basic block, we can go further and take
+  // their incoming values from the corresponding blocks.
   BasicBlockEdge TrueEdge(IDom, TrueSucc);
   BasicBlockEdge FalseEdge(IDom, FalseSucc);
   DenseMap<BasicBlock *, Value *> Inputs;
@@ -2476,9 +2481,9 @@ static Instruction *foldSelectToPhi(SelectInst &Sel, const DominatorTree &DT,
     // Check implication.
     BasicBlockEdge Incoming(Pred, BB);
     if (DT.dominates(TrueEdge, Incoming))
-      Inputs[Pred] = IfTrue;
+      Inputs[Pred] = IfTrue->DoPHITranslation(BB, Pred);
     else if (DT.dominates(FalseEdge, Incoming))
-      Inputs[Pred] = IfFalse;
+      Inputs[Pred] = IfFalse->DoPHITranslation(BB, Pred);
     else
       return nullptr;
     // Check availability.
index 680bac5..0fcbe03 100644 (file)
@@ -2000,7 +2000,6 @@ merge:
   ret i32 %s
 }
 
-; TODO: Replace with phi[x, z].
 define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) {
 ; CHECK-LABEL: @select_phi_same_condition(
 ; CHECK-NEXT:  entry:
@@ -2010,8 +2009,7 @@ define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) {
 ; CHECK:       if.false:
 ; CHECK-NEXT:    br label [[MERGE]]
 ; CHECK:       merge:
-; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[Z:%.*]], [[IF_FALSE]] ]
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[PHI]]
+; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[Z:%.*]], [[IF_FALSE]] ], [ [[X:%.*]], [[IF_TRUE]] ]
 ; CHECK-NEXT:    ret i32 [[S]]
 ;
 entry: