diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-08-10 16:12:19 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-08-10 16:12:19 +0000 |
commit | c9cc86a5b31a0cb4600ca7ef31a266b6b4420afe (patch) | |
tree | 2449205eb640b8952f8ee3e51dbcfebcc601ef1e /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | |
parent | 5099835541374f9b59e3e7b600b88a97a02b02b5 (diff) | |
download | bcm5719-llvm-c9cc86a5b31a0cb4600ca7ef31a266b6b4420afe.tar.gz bcm5719-llvm-c9cc86a5b31a0cb4600ca7ef31a266b6b4420afe.zip |
[InstCombine] revert r339439 - rearrange code for foldSelectBinOpIdentity
That was supposed to be NFC, but it exposed a logic hole somewhere that
caused bots to fail.
llvm-svn: 339446
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 188c045a0de..796b4021d27 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -54,38 +54,34 @@ static Value *createMinMax(InstCombiner::BuilderTy &Builder, return Builder.CreateSelect(Builder.CreateICmp(Pred, A, B), A, B); } -/// Replace a select operand based on an equality comparison with the identity -/// constant of a binop. +/// Fold +/// %A = icmp eq/ne i8 %x, 0 +/// %B = op i8 %x, %z +/// %C = select i1 %A, i8 %B, i8 %y +/// To +/// %C = select i1 %A, i8 %z, i8 %y +/// OP: binop with an identity constant +/// TODO: support for non-commutative and FP opcodes static Instruction *foldSelectBinOpIdentity(SelectInst &Sel) { - // The select condition must be an equality compare with a constant operand. - // TODO: Support FP compares. - Value *X; + + Value *Cond = Sel.getCondition(); + Value *X, *Z; Constant *C; CmpInst::Predicate Pred; - if (!match(Sel.getCondition(), m_ICmp(Pred, m_Value(X), m_Constant(C))) || + if (!match(Cond, m_ICmp(Pred, m_Value(X), m_Constant(C))) || !ICmpInst::isEquality(Pred)) return nullptr; - // A select operand must be a binop, and the compare constant must be the - // identity constant for that binop. - // TODO: Support non-commutative binops. bool IsEq = Pred == ICmpInst::ICMP_EQ; - BinaryOperator *BO; - if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)) || - ConstantExpr::getBinOpIdentity(BO->getOpcode(), X->getType(), false) != C) - return nullptr; - - // Last, match the compare variable operand with a binop operand. - Value *Y; - if (!match(BO, m_c_BinOp(m_Value(Y), m_Specific(X)))) - return nullptr; - - // BO = binop Y, X - // S = { select (cmp eq X, C), BO, ? } or { select (cmp ne X, C), ?, BO } - // => - // S = { select (cmp eq X, C), Y, ? } or { select (cmp ne X, C), ?, Y } - Sel.setOperand(IsEq ? 1 : 2, Y); - return &Sel; + auto *BO = + dyn_cast<BinaryOperator>(IsEq ? Sel.getTrueValue() : Sel.getFalseValue()); + // TODO: support for undefs + if (BO && match(BO, m_c_BinOp(m_Specific(X), m_Value(Z))) && + ConstantExpr::getBinOpIdentity(BO->getOpcode(), X->getType()) == C) { + Sel.setOperand(IsEq ? 1 : 2, Z); + return &Sel; + } + return nullptr; } /// This folds: |