diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 92338d33b27a438..53da8d2776a220a 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9897,13 +9897,20 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower, } } -static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II) { +static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II, + bool UseInstrInfo) { unsigned Width = II.getType()->getScalarSizeInBits(); const APInt *C; switch (II.getIntrinsicID()) { - case Intrinsic::ctpop: case Intrinsic::ctlz: - case Intrinsic::cttz: + case Intrinsic::cttz: { + APInt Upper(Width, Width); + if (!UseInstrInfo || !match(II.getArgOperand(1), m_One())) + Upper += 1; + // Maximum of set/clear bits is the bit width. + return ConstantRange::getNonEmpty(APInt::getZero(Width), Upper); + } + case Intrinsic::ctpop: // Maximum of set/clear bits is the bit width. return ConstantRange::getNonEmpty(APInt::getZero(Width), APInt(Width, Width) + 1); @@ -10094,7 +10101,7 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, setLimitsForBinOp(*BO, Lower, Upper, IIQ, ForSigned); CR = ConstantRange::getNonEmpty(Lower, Upper); } else if (auto *II = dyn_cast(V)) - CR = getRangeForIntrinsic(*II); + CR = getRangeForIntrinsic(*II, UseInstrInfo); else if (auto *SI = dyn_cast(V)) { ConstantRange CRTrue = computeConstantRange( SI->getTrueValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1); diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index 67d5c4dbfb2e7d8..910750adf9d427a 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -1582,9 +1582,7 @@ define i1 @ctlz_i1_non_poison_eq_false(i1 %x) { define i1 @ctlz_i1_poison_eq_false(i1 %x) { ; CHECK-LABEL: @ctlz_i1_poison_eq_false( -; CHECK-NEXT: [[CT:%.*]] = call i1 @llvm.ctlz.i1(i1 [[X:%.*]], i1 true) -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[CT]], false -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %ct = call i1 @llvm.ctlz.i1(i1 %x, i1 true) %cmp = icmp eq i1 %ct, false @@ -1604,9 +1602,7 @@ define i1 @cttz_i1_non_poison_eq_false(i1 %x) { define i1 @cttz_i1_poison_eq_false(i1 %x) { ; CHECK-LABEL: @cttz_i1_poison_eq_false( -; CHECK-NEXT: [[CT:%.*]] = call i1 @llvm.cttz.i1(i1 [[X:%.*]], i1 true) -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[CT]], false -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %ct = call i1 @llvm.cttz.i1(i1 %x, i1 true) %cmp = icmp eq i1 %ct, false