Skip to content

Commit 85e17bb

Browse files
committedAug 10, 2018
[InstCombine] rearrange code for foldSelectBinOpIdentity; NFCI
This is a retry of rL339439 with a fix for the problem that caused the original commit to be reverted at rL339446. That problem was that the compare can be integer while the binop is FP or vice-versa, so we need to use the binop type when we ask for the identity constant. A test to guard against the problem was added at rL339453. llvm-svn: 339469
1 parent 99a1ce9 commit 85e17bb

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed
 

‎llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

+25-21
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,38 @@ static Value *createMinMax(InstCombiner::BuilderTy &Builder,
5454
return Builder.CreateSelect(Builder.CreateICmp(Pred, A, B), A, B);
5555
}
5656

57-
/// Fold
58-
/// %A = icmp eq/ne i8 %x, 0
59-
/// %B = op i8 %x, %z
60-
/// %C = select i1 %A, i8 %B, i8 %y
61-
/// To
62-
/// %C = select i1 %A, i8 %z, i8 %y
63-
/// OP: binop with an identity constant
64-
/// TODO: support for non-commutative and FP opcodes
57+
/// Replace a select operand based on an equality comparison with the identity
58+
/// constant of a binop.
6559
static Instruction *foldSelectBinOpIdentity(SelectInst &Sel) {
66-
67-
Value *Cond = Sel.getCondition();
68-
Value *X, *Z;
60+
// The select condition must be an equality compare with a constant operand.
61+
// TODO: Support FP compares.
62+
Value *X;
6963
Constant *C;
7064
CmpInst::Predicate Pred;
71-
if (!match(Cond, m_ICmp(Pred, m_Value(X), m_Constant(C))) ||
65+
if (!match(Sel.getCondition(), m_ICmp(Pred, m_Value(X), m_Constant(C))) ||
7266
!ICmpInst::isEquality(Pred))
7367
return nullptr;
7468

69+
// A select operand must be a binop, and the compare constant must be the
70+
// identity constant for that binop.
71+
// TODO: Support non-commutative binops.
7572
bool IsEq = Pred == ICmpInst::ICMP_EQ;
76-
auto *BO =
77-
dyn_cast<BinaryOperator>(IsEq ? Sel.getTrueValue() : Sel.getFalseValue());
78-
// TODO: support for undefs
79-
if (BO && match(BO, m_c_BinOp(m_Specific(X), m_Value(Z))) &&
80-
ConstantExpr::getBinOpIdentity(BO->getOpcode(), X->getType()) == C) {
81-
Sel.setOperand(IsEq ? 1 : 2, Z);
82-
return &Sel;
83-
}
84-
return nullptr;
73+
BinaryOperator *BO;
74+
if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)) ||
75+
ConstantExpr::getBinOpIdentity(BO->getOpcode(), BO->getType(), false) != C)
76+
return nullptr;
77+
78+
// Last, match the compare variable operand with a binop operand.
79+
Value *Y;
80+
if (!match(BO, m_c_BinOp(m_Value(Y), m_Specific(X))))
81+
return nullptr;
82+
83+
// BO = binop Y, X
84+
// S = { select (cmp eq X, C), BO, ? } or { select (cmp ne X, C), ?, BO }
85+
// =>
86+
// S = { select (cmp eq X, C), Y, ? } or { select (cmp ne X, C), ?, Y }
87+
Sel.setOperand(IsEq ? 1 : 2, Y);
88+
return &Sel;
8589
}
8690

8791
/// This folds:

0 commit comments

Comments
 (0)
Please sign in to comment.