diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 4295c76..b1c7039 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -7034,7 +7034,7 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) { return Res; { - Value *X, *Y, *Z; + Value *X, *Y; // Transform (X & ~Y) == 0 --> (X & Y) != 0 // and (X & ~Y) != 0 --> (X & Y) == 0 // if A is a power of 2. @@ -7044,32 +7044,18 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) { return new ICmpInst(I.getInversePredicate(), Builder.CreateAnd(X, Y), Op1); - // Transform (~X ^ Y) s< ~Z --> (X ^ Y) s> Z, - // (~X ^ Y) s> ~Z --> (X ^ Y) s< Z, - // (~X ^ Y) s<= ~Z --> (X ^ Y) s>= Z, - // (~X ^ Y) s>= ~Z --> (X ^ Y) s<= Z, - // (~X ^ Y) u< ~Z --> (X ^ Y) u< Z, - // (~X ^ Y) u> ~Z --> (X ^ Y) u< Z, - // (~X ^ Y) u<= ~Z --> (X ^ Y) u>= Z, - // (~X ^ Y) u>= ~Z --> (X ^ Y) u<= Z, - // (~X ^ Y) == ~Z --> (X ^ Y) == Z, - // and (~X ^ Y) != ~Z --> (X ^ Y) != Z, - if (match(&I, m_c_ICmp(Pred, m_c_Xor(m_Not(m_Value(X)), m_Value(Y)), - m_Not(m_Value(Z)))) && - (I.getOperand(0)->hasOneUse() || I.getOperand(1)->hasOneUse())) - return new ICmpInst(I.getSwappedPredicate(Pred), Builder.CreateXor(X, Y), - Z); - - // ~X < ~Y --> Y < X - // ~X < C --> X > ~C - if (match(Op0, m_Not(m_Value(X)))) { - if (match(Op1, m_Not(m_Value(Y)))) - return new ICmpInst(I.getPredicate(), Y, X); - - const APInt *C; - if (match(Op1, m_APInt(C))) - return new ICmpInst(I.getSwappedPredicate(), X, - ConstantInt::get(Op1->getType(), ~(*C))); + // Op0 pred Op1 -> ~Op1 pred ~Op0, if this allows us to drop an instruction. + if (Op0->getType()->isIntOrIntVectorTy()) { + bool ConsumesOp0, ConsumesOp1; + if (isFreeToInvert(Op0, Op0->hasOneUse(), ConsumesOp0) && + isFreeToInvert(Op1, Op1->hasOneUse(), ConsumesOp1) && + (ConsumesOp0 || ConsumesOp1)) { + Value *InvOp0 = getFreelyInverted(Op0, Op0->hasOneUse(), &Builder); + Value *InvOp1 = getFreelyInverted(Op1, Op1->hasOneUse(), &Builder); + assert(InvOp0 && InvOp1 && + "Mismatch between isFreeToInvert and getFreelyInverted"); + return new ICmpInst(I.getSwappedPredicate(), InvOp0, InvOp1); + } } Instruction *AddI = nullptr; |
