diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 09d2eb6b08ca..c4fb8365cc18 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -134,6 +134,11 @@ public: return getOpcode() == AShr; } + /// Return true if this is and/or/xor. + inline bool isBitwiseLogicOp() const { + return getOpcode() == And || getOpcode() == Or || getOpcode() == Xor; + } + /// Determine if the OpCode is one of the CastInst instructions. static inline bool isCast(unsigned OpCode) { return OpCode >= CastOpsBegin && OpCode < CastOpsEnd; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index ecb406fabefb..9cb96fbed27a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -98,12 +98,11 @@ Value *InstCombiner::SimplifyBSwap(BinaryOperator &I) { IntegerType *ITy = dyn_cast(I.getType()); // Can't do vectors. - if (I.getType()->isVectorTy()) return nullptr; + if (I.getType()->isVectorTy()) + return nullptr; // Can only do bitwise ops. - unsigned Op = I.getOpcode(); - if (Op != Instruction::And && Op != Instruction::Or && - Op != Instruction::Xor) + if (!I.isBitwiseLogicOp()) return nullptr; Value *OldLHS = I.getOperand(0); @@ -132,14 +131,7 @@ Value *InstCombiner::SimplifyBSwap(BinaryOperator &I) { Value *NewRHS = IsBswapRHS ? IntrRHS->getOperand(0) : Builder->getInt(ConstRHS->getValue().byteSwap()); - Value *BinOp = nullptr; - if (Op == Instruction::And) - BinOp = Builder->CreateAnd(NewLHS, NewRHS); - else if (Op == Instruction::Or) - BinOp = Builder->CreateOr(NewLHS, NewRHS); - else //if (Op == Instruction::Xor) - BinOp = Builder->CreateXor(NewLHS, NewRHS); - + Value *BinOp = Builder->CreateBinOp(I.getOpcode(), NewLHS, NewRHS); Function *F = Intrinsic::getDeclaration(I.getModule(), Intrinsic::bswap, ITy); return Builder->CreateCall(F, BinOp); } @@ -1172,9 +1164,7 @@ static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, /// Fold {and,or,xor} (cast X), Y. Instruction *InstCombiner::foldCastedBitwiseLogic(BinaryOperator &I) { auto LogicOpc = I.getOpcode(); - assert((LogicOpc == Instruction::And || LogicOpc == Instruction::Or || - LogicOpc == Instruction::Xor) && - "Unexpected opcode for bitwise logic folding"); + assert(I.isBitwiseLogicOp() && "Unexpected opcode for bitwise logic folding"); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); CastInst *Cast0 = dyn_cast(Op0); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index c085a31b5cdf..491576e95dd7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -747,9 +747,7 @@ static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear, // If the operation is an AND/OR/XOR and the bits to clear are zero in the // other side, BitsToClear is ok. - if (Tmp == 0 && - (Opc == Instruction::And || Opc == Instruction::Or || - Opc == Instruction::Xor)) { + if (Tmp == 0 && I->isBitwiseLogicOp()) { // We use MaskedValueIsZero here for generality, but the case we care // about the most is constant RHS. unsigned VSize = V->getType()->getScalarSizeInBits(); @@ -1781,17 +1779,11 @@ static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast, /// Change the type of a bitwise logic operation if we can eliminate a bitcast. static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder) { - BinaryOperator *BO; - if (!match(BitCast.getOperand(0), m_OneUse(m_BinOp(BO)))) - return nullptr; - - auto Opcode = BO->getOpcode(); - if (Opcode != Instruction::And && Opcode != Instruction::Or && - Opcode != Instruction::Xor) - return nullptr; - Type *DestTy = BitCast.getType(); - if (!DestTy->getScalarType()->isIntegerTy()) + BinaryOperator *BO; + if (!DestTy->getScalarType()->isIntegerTy() || + !match(BitCast.getOperand(0), m_OneUse(m_BinOp(BO))) || + !BO->isBitwiseLogicOp()) return nullptr; // FIXME: This transform is restricted to vector types to avoid backend @@ -1805,14 +1797,14 @@ static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast, X->getType() == DestTy && !isa(X)) { // bitcast(logic(bitcast(X), Y)) --> logic'(X, bitcast(Y)) Value *CastedOp1 = Builder.CreateBitCast(BO->getOperand(1), DestTy); - return BinaryOperator::Create(Opcode, X, CastedOp1); + return BinaryOperator::Create(BO->getOpcode(), X, CastedOp1); } if (match(BO->getOperand(1), m_OneUse(m_BitCast(m_Value(X)))) && X->getType() == DestTy && !isa(X)) { // bitcast(logic(Y, bitcast(X))) --> logic'(bitcast(Y), X) Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy); - return BinaryOperator::Create(Opcode, CastedOp0, X); + return BinaryOperator::Create(BO->getOpcode(), CastedOp0, X); } return nullptr; diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index ad6e0c190e88..2529c4735544 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -177,11 +177,10 @@ static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1) { return false; // TODO: Enhance logic for other BinOps and remove this check. - auto AssocOpcode = BinOp1->getOpcode(); - if (AssocOpcode != Instruction::Xor && AssocOpcode != Instruction::And && - AssocOpcode != Instruction::Or) + if (!BinOp1->isBitwiseLogicOp()) return false; + auto AssocOpcode = BinOp1->getOpcode(); auto *BinOp2 = dyn_cast(Cast->getOperand(0)); if (!BinOp2 || !BinOp2->hasOneUse() || BinOp2->getOpcode() != AssocOpcode) return false;