diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e186431934d22..9b29d64c97f79 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8553,7 +8553,20 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower, Lower = *C; Upper = C->shl(ShiftAmount) + 1; } + } else { + // If lowbit is set, value can never be zero. + if ((*C)[0]) + Lower = APInt::getOneBitSet(Width, 0); + // If we are shifting a constant the largest it can be is if the longest + // sequence of consecutive ones is shifted to the highbits (breaking + // ties for which sequence is higher). At the moment we take a liberal + // upper bound on this by just popcounting the constant. + // TODO: There may be a bitwise trick for it longest/highest + // consecutative sequence of ones (naive method is O(Width) loop). + Upper = APInt::getHighBitsSet(Width, C->popcount()) + 1; } + } else if (match(BO.getOperand(1), m_APInt(C)) && C->ult(Width)) { + Upper = APInt::getBitsSetFrom(Width, C->getZExtValue()) + 1; } break; diff --git a/llvm/test/Analysis/ValueTracking/constant-ranges.ll b/llvm/test/Analysis/ValueTracking/constant-ranges.ll index e425c1547bc3a..14331c251ff52 100644 --- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll +++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll @@ -3,9 +3,7 @@ define i1 @shl_C_X_ugt(i8 %x) { ; CHECK-LABEL: @shl_C_X_ugt( -; CHECK-NEXT: [[SHL:%.*]] = shl i8 7, [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[SHL]], -32 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %shl = shl i8 7, %x %r = icmp ugt i8 %shl, 224 @@ -14,9 +12,7 @@ define i1 @shl_C_X_ugt(i8 %x) { define i1 @shl_C_X_ugt2(i8 %x) { ; CHECK-LABEL: @shl_C_X_ugt2( -; CHECK-NEXT: [[SHL:%.*]] = shl i8 5, [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[SHL]], -64 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %shl = shl i8 5, %x %r = icmp ugt i8 %shl, 192 @@ -69,9 +65,7 @@ define i1 @shl_C_X_ugt_todo(i8 %x) { define i1 @shl_X_C_ugt(i8 %x) { ; CHECK-LABEL: @shl_X_C_ugt( -; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 6 -; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[SHL]], -64 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %shl = shl i8 %x, 6 %r = icmp ugt i8 %shl, 192