diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3021,57 +3021,7 @@ return nullptr; if (auto *BO = dyn_cast(Cmp.getOperand(0))) { - switch (BO->getOpcode()) { - case Instruction::Xor: - if (Instruction *I = foldICmpXorConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::And: - if (Instruction *I = foldICmpAndConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::Or: - if (Instruction *I = foldICmpOrConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::Mul: - if (Instruction *I = foldICmpMulConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::Shl: - if (Instruction *I = foldICmpShlConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::LShr: - case Instruction::AShr: - if (Instruction *I = foldICmpShrConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::SRem: - if (Instruction *I = foldICmpSRemConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::UDiv: - if (Instruction *I = foldICmpUDivConstant(Cmp, BO, *C)) - return I; - LLVM_FALLTHROUGH; - case Instruction::SDiv: - if (Instruction *I = foldICmpDivConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::Sub: - if (Instruction *I = foldICmpSubConstant(Cmp, BO, *C)) - return I; - break; - case Instruction::Add: - if (Instruction *I = foldICmpAddConstant(Cmp, BO, *C)) - return I; - break; - default: - break; - } - // TODO: These folds could be refactored to be part of the above calls. - if (Instruction *I = foldICmpBinOpEqualityWithConstant(Cmp, BO, *C)) + if (Instruction *I = foldICmpBinOpWithConstant(Cmp, BO, *C)) return I; } @@ -3328,6 +3278,64 @@ return nullptr; } +/// Fold an icmp with BinaryOp and constant operand: icmp Pred BO, C. +Instruction *InstCombinerImpl::foldICmpBinOpWithConstant(ICmpInst &Cmp, + BinaryOperator *BO, + const APInt &C) { + switch (BO->getOpcode()) { + case Instruction::Xor: + if (Instruction *I = foldICmpXorConstant(Cmp, BO, C)) + return I; + break; + case Instruction::And: + if (Instruction *I = foldICmpAndConstant(Cmp, BO, C)) + return I; + break; + case Instruction::Or: + if (Instruction *I = foldICmpOrConstant(Cmp, BO, C)) + return I; + break; + case Instruction::Mul: + if (Instruction *I = foldICmpMulConstant(Cmp, BO, C)) + return I; + break; + case Instruction::Shl: + if (Instruction *I = foldICmpShlConstant(Cmp, BO, C)) + return I; + break; + case Instruction::LShr: + case Instruction::AShr: + if (Instruction *I = foldICmpShrConstant(Cmp, BO, C)) + return I; + break; + case Instruction::SRem: + if (Instruction *I = foldICmpSRemConstant(Cmp, BO, C)) + return I; + break; + case Instruction::UDiv: + if (Instruction *I = foldICmpUDivConstant(Cmp, BO, C)) + return I; + LLVM_FALLTHROUGH; + case Instruction::SDiv: + if (Instruction *I = foldICmpDivConstant(Cmp, BO, C)) + return I; + break; + case Instruction::Sub: + if (Instruction *I = foldICmpSubConstant(Cmp, BO, C)) + return I; + break; + case Instruction::Add: + if (Instruction *I = foldICmpAddConstant(Cmp, BO, C)) + return I; + break; + default: + break; + } + + // TODO: These folds could be refactored to be part of the above calls. + return foldICmpBinOpEqualityWithConstant(Cmp, BO, C); +} + /// Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C. Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp, IntrinsicInst *II, 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 @@ -682,6 +682,8 @@ Value *foldMultiplicationOverflowCheck(ICmpInst &Cmp); + Instruction *foldICmpBinOpWithConstant(ICmpInst &Cmp, BinaryOperator *BO, + const APInt &C); Instruction *foldICmpSelectConstant(ICmpInst &Cmp, SelectInst *Select, ConstantInt *C); Instruction *foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc,