diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1990,45 +1990,11 @@ return nullptr; } -Instruction *InstCombinerImpl::matchBSwapOrBitReverse(BinaryOperator &Or, +Instruction *InstCombinerImpl::matchBSwapOrBitReverse(Instruction &I, bool MatchBSwaps, bool MatchBitReversals) { - assert(Or.getOpcode() == Instruction::Or && "bswap requires an 'or'"); - Value *Op0 = Or.getOperand(0), *Op1 = Or.getOperand(1); - - // Look through zero extends. - if (Instruction *Ext = dyn_cast(Op0)) - Op0 = Ext->getOperand(0); - - if (Instruction *Ext = dyn_cast(Op1)) - Op1 = Ext->getOperand(0); - - // (A | B) | C and A | (B | C) -> bswap if possible. - bool OrWithOrs = match(Op0, m_Or(m_Value(), m_Value())) || - match(Op1, m_Or(m_Value(), m_Value())); - - // (A >> B) | C and (A << B) | C -> bswap if possible. - bool OrWithShifts = match(Op0, m_LogicalShift(m_Value(), m_Value())) || - match(Op1, m_LogicalShift(m_Value(), m_Value())); - - // (A & B) | C and A | (B & C) -> bswap if possible. - bool OrWithAnds = match(Op0, m_And(m_Value(), m_Value())) || - match(Op1, m_And(m_Value(), m_Value())); - - // fshl(A,B,C) | D and A | fshl(B,C,D) -> bswap if possible. - // fshr(A,B,C) | D and A | fshr(B,C,D) -> bswap if possible. - bool OrWithFunnels = match(Op0, m_FShl(m_Value(), m_Value(), m_Value())) || - match(Op0, m_FShr(m_Value(), m_Value(), m_Value())) || - match(Op0, m_FShl(m_Value(), m_Value(), m_Value())) || - match(Op0, m_FShr(m_Value(), m_Value(), m_Value())); - - // TODO: Do we need all these filtering checks or should we just rely on - // recognizeBSwapOrBitReverseIdiom + collectBitParts to reject them quickly? - if (!OrWithOrs && !OrWithShifts && !OrWithAnds && !OrWithFunnels) - return nullptr; - SmallVector Insts; - if (!recognizeBSwapOrBitReverseIdiom(&Or, MatchBSwaps, MatchBitReversals, + if (!recognizeBSwapOrBitReverseIdiom(&I, MatchBSwaps, MatchBitReversals, Insts)) return nullptr; Instruction *LastInst = Insts.pop_back_val(); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -715,10 +715,10 @@ Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocaInst &AI); bool mergeStoreIntoSuccessor(StoreInst &SI); - /// Given an 'or' instruction, check to see if it is part of a + /// Given an initial instruction, check to see if it is root of a /// bswap/bitreverse idiom. If so, return the equivalent bswap/bitreverse /// intrinsic. - Instruction *matchBSwapOrBitReverse(BinaryOperator &Or, bool MatchBSwaps, + Instruction *matchBSwapOrBitReverse(Instruction &I, bool MatchBSwaps, bool MatchBitReversals); Instruction *SimplifyAnyMemTransfer(AnyMemTransferInst *MI);