Skip to content

Commit 3bc38fb

Browse files
authored
[InstCombine] Generalize and consolidate phi translation check (#106051)
The foldOpIntoPhi() transforms requires all operands to be phi-translatable. This can be the case either because they are phi nodes in the same block, or because the operand dominates the block. Currently, most callers of foldOpIntoPhi() satisfy this pre-condition by requiring a constant operand, which trivially dominates everything. Only selects had handling for variable operands. Move this logic into foldOpIntoPhi(), so things are handled correctly if other callers are generalized. Also make the implementation a bit more general by querying the dominator tree.
1 parent 8f77d37 commit 3bc38fb

File tree

3 files changed

+30
-47
lines changed

3 files changed

+30
-47
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,41 +1992,6 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
19921992
return Changed ? &SI : nullptr;
19931993
}
19941994

1995-
/// SI is a select whose condition is a PHI node (but the two may be in
1996-
/// different blocks). See if the true/false values (V) are live in all of the
1997-
/// predecessor blocks of the PHI. For example, cases like this can't be mapped:
1998-
///
1999-
/// X = phi [ C1, BB1], [C2, BB2]
2000-
/// Y = add
2001-
/// Z = select X, Y, 0
2002-
///
2003-
/// because Y is not live in BB1/BB2.
2004-
static bool canSelectOperandBeMappingIntoPredBlock(const Value *V,
2005-
const SelectInst &SI) {
2006-
// If the value is a non-instruction value like a constant or argument, it
2007-
// can always be mapped.
2008-
const Instruction *I = dyn_cast<Instruction>(V);
2009-
if (!I) return true;
2010-
2011-
// If V is a PHI node defined in the same block as the condition PHI, we can
2012-
// map the arguments.
2013-
const PHINode *CondPHI = cast<PHINode>(SI.getCondition());
2014-
2015-
if (const PHINode *VP = dyn_cast<PHINode>(I))
2016-
if (VP->getParent() == CondPHI->getParent())
2017-
return true;
2018-
2019-
// Otherwise, if the PHI and select are defined in the same block and if V is
2020-
// defined in a different block, then we can transform it.
2021-
if (SI.getParent() == CondPHI->getParent() &&
2022-
I->getParent() != CondPHI->getParent())
2023-
return true;
2024-
2025-
// Otherwise we have a 'hard' case and we can't tell without doing more
2026-
// detailed dominator based analysis, punt.
2027-
return false;
2028-
}
2029-
20301995
/// We have an SPF (e.g. a min or max) of an SPF of the form:
20311996
/// SPF2(SPF1(A, B), C)
20321997
Instruction *InstCombinerImpl::foldSPFofSPF(Instruction *Inner,
@@ -3929,11 +3894,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
39293894

39303895
// See if we can fold the select into a phi node if the condition is a select.
39313896
if (auto *PN = dyn_cast<PHINode>(SI.getCondition()))
3932-
// The true/false values have to be live in the PHI predecessor's blocks.
3933-
if (canSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
3934-
canSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
3935-
if (Instruction *NV = foldOpIntoPhi(SI, PN))
3936-
return NV;
3897+
if (Instruction *NV = foldOpIntoPhi(SI, PN))
3898+
return NV;
39373899

39383900
if (SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
39393901
if (TrueSI->getCondition()->getType() == CondVal->getType()) {

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,8 +1730,7 @@ static Value *simplifyInstructionWithPHI(Instruction &I, PHINode *PN,
17301730
const DataLayout &DL,
17311731
const SimplifyQuery SQ) {
17321732
// NB: It is a precondition of this transform that the operands be
1733-
// phi translatable! This is usually trivially satisfied by limiting it
1734-
// to constant ops, and for selects we do a more sophisticated check.
1733+
// phi translatable!
17351734
SmallVector<Value *> Ops;
17361735
for (Value *Op : I.operands()) {
17371736
if (Op == PN)
@@ -1784,9 +1783,31 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
17841783
// Otherwise, we can replace *all* users with the new PHI we form.
17851784
}
17861785

1786+
// Check that all operands are phi-translatable.
1787+
for (Value *Op : I.operands()) {
1788+
if (Op == PN)
1789+
continue;
1790+
1791+
// Non-instructions never require phi-translation.
1792+
auto *I = dyn_cast<Instruction>(Op);
1793+
if (!I)
1794+
continue;
1795+
1796+
// Phi-translate can handle phi nodes in the same block.
1797+
if (isa<PHINode>(I))
1798+
if (I->getParent() == PN->getParent())
1799+
continue;
1800+
1801+
// Operand dominates the block, no phi-translation necessary.
1802+
if (DT.dominates(I, PN->getParent()))
1803+
continue;
1804+
1805+
// Not phi-translatable, bail out.
1806+
return nullptr;
1807+
}
1808+
17871809
// Check to see whether the instruction can be folded into each phi operand.
17881810
// If there is one operand that does not fold, remember the BB it is in.
1789-
// If there is more than one or if *it* is a PHI, bail out.
17901811
SmallVector<Value *> NewPhiValues;
17911812
BasicBlock *NonSimplifiedBB = nullptr;
17921813
Value *NonSimplifiedInVal = nullptr;

llvm/test/Transforms/InstCombine/phi-select-constant.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,17 +226,17 @@ final:
226226
define i32 @dominating_values_select_not_same_block(i1 %c1, i1 %c2, ptr %p, ptr %p2) {
227227
; CHECK-LABEL: @dominating_values_select_not_same_block(
228228
; CHECK-NEXT: entry:
229-
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P:%.*]], align 4
230229
; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[P2:%.*]], align 4
231230
; CHECK-NEXT: br i1 [[C1:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
232231
; CHECK: delay:
232+
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P:%.*]], align 4
233+
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[C2:%.*]], i32 [[A]], i32 [[B]]
233234
; CHECK-NEXT: br label [[FINAL]]
234235
; CHECK: final:
235-
; CHECK-NEXT: [[USE2:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[C2:%.*]], [[DELAY]] ]
236+
; CHECK-NEXT: [[USE2:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[TMP0]], [[DELAY]] ]
236237
; CHECK-NEXT: br label [[SPLIT:%.*]]
237238
; CHECK: split:
238-
; CHECK-NEXT: [[VALUE:%.*]] = select i1 [[USE2]], i32 [[A]], i32 [[B]]
239-
; CHECK-NEXT: ret i32 [[VALUE]]
239+
; CHECK-NEXT: ret i32 [[USE2]]
240240
;
241241
entry:
242242
%a = load i32, ptr %p

0 commit comments

Comments
 (0)