diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index 3963a5c8ab8f9..2a37c06dd2c3c 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -834,6 +834,43 @@ class MinMaxIntrinsic : public IntrinsicInst { } }; +/// This class represents a ucmp/scmp intrinsic +class CmpIntrinsic : public IntrinsicInst { +public: + static bool classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { + case Intrinsic::scmp: + case Intrinsic::ucmp: + return true; + default: + return false; + } + } + static bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + + Value *getLHS() const { return const_cast(getArgOperand(0)); } + Value *getRHS() const { return const_cast(getArgOperand(1)); } + + static bool isSigned(Intrinsic::ID ID) { return ID == Intrinsic::scmp; } + bool isSigned() const { return isSigned(getIntrinsicID()); } + + static CmpInst::Predicate getGTPredicate(Intrinsic::ID ID) { + return isSigned(ID) ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; + } + CmpInst::Predicate getGTPredicate() const { + return getGTPredicate(getIntrinsicID()); + } + + static CmpInst::Predicate getLTPredicate(Intrinsic::ID ID) { + return isSigned(ID) ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; + } + CmpInst::Predicate getLTPredicate() const { + return getLTPredicate(getIntrinsicID()); + } +}; + /// This class represents an intrinsic that is based on a binary operation. /// This includes op.with.overflow and saturating add/sub intrinsics. class BinaryOpIntrinsic : public IntrinsicInst { diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 20f5dba413212..95de8eceb6be5 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -538,29 +538,28 @@ static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) { return false; } -static bool processCmpIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) { - bool IsSigned = II->getIntrinsicID() == Intrinsic::scmp; - ConstantRange LHS_CR = LVI->getConstantRangeAtUse(II->getOperandUse(0), - /*UndefAllowed*/ false); - ConstantRange RHS_CR = LVI->getConstantRangeAtUse(II->getOperandUse(1), - /*UndefAllowed*/ false); +static bool processCmpIntrinsic(CmpIntrinsic *CI, LazyValueInfo *LVI) { + ConstantRange LHS_CR = + LVI->getConstantRangeAtUse(CI->getOperandUse(0), /*UndefAllowed*/ false); + ConstantRange RHS_CR = + LVI->getConstantRangeAtUse(CI->getOperandUse(1), /*UndefAllowed*/ false); - if (LHS_CR.icmp(IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, RHS_CR)) { + if (LHS_CR.icmp(CI->getGTPredicate(), RHS_CR)) { ++NumCmpIntr; - II->replaceAllUsesWith(ConstantInt::get(II->getType(), 1)); - II->eraseFromParent(); + CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); + CI->eraseFromParent(); return true; } - if (LHS_CR.icmp(IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, RHS_CR)) { + if (LHS_CR.icmp(CI->getLTPredicate(), RHS_CR)) { ++NumCmpIntr; - II->replaceAllUsesWith(ConstantInt::getSigned(II->getType(), -1)); - II->eraseFromParent(); + CI->replaceAllUsesWith(ConstantInt::getSigned(CI->getType(), -1)); + CI->eraseFromParent(); return true; } if (LHS_CR.icmp(ICmpInst::ICMP_EQ, RHS_CR)) { ++NumCmpIntr; - II->replaceAllUsesWith(ConstantInt::get(II->getType(), 0)); - II->eraseFromParent(); + CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 0)); + CI->eraseFromParent(); return true; } @@ -658,9 +657,8 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) { return processAbsIntrinsic(&cast(CB), LVI); } - if (CB.getIntrinsicID() == Intrinsic::scmp || - CB.getIntrinsicID() == Intrinsic::ucmp) { - return processCmpIntrinsic(&cast(CB), LVI); + if (auto *CI = dyn_cast(&CB)) { + return processCmpIntrinsic(CI, LVI); } if (auto *MM = dyn_cast(&CB)) {