[InstCombine] Combine select & Phi by same condition

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
This commit is contained in:
Max Kazantsev 2020-06-25 10:42:16 +07:00
parent a5041987ed
commit 1eeb714787
2 changed files with 8 additions and 5 deletions

View 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.

View 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: