Skip to content

Commit 0f8b40a

Browse files
committed
[ValueTracking] Add better support for ConstantRange(Shl)
1) If LHS is constant: - The low bits of the LHS is set, the lower bound is non-zero - The upper bound can be capped at popcount(LHS) high bits 2) If RHS is constant: - The upper bound can be capped at (Width - RHS) high bits
1 parent 457308a commit 0f8b40a

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8553,7 +8553,20 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
85538553
Lower = *C;
85548554
Upper = C->shl(ShiftAmount) + 1;
85558555
}
8556+
} else {
8557+
// If lowbit is set, value can never be zero.
8558+
if ((*C)[0])
8559+
Lower = APInt::getOneBitSet(Width, 0);
8560+
// If we are shifting a constant the largest it can be is if the longest
8561+
// sequence of consecutive ones is shifted to the highbits (breaking
8562+
// ties for which sequence is higher). At the moment we take a liberal
8563+
// upper bound on this by just popcounting the constant.
8564+
// TODO: There may be a bitwise trick for it longest/highest
8565+
// consecutative sequence of ones (naive method is O(Width) loop).
8566+
Upper = APInt::getHighBitsSet(Width, C->popcount()) + 1;
85568567
}
8568+
} else if (match(BO.getOperand(1), m_APInt(C)) && C->ult(Width)) {
8569+
Upper = APInt::getBitsSetFrom(Width, C->getZExtValue()) + 1;
85578570
}
85588571
break;
85598572

llvm/test/Analysis/ValueTracking/constant-ranges.ll

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
define i1 @shl_C_X_ugt(i8 %x) {
55
; CHECK-LABEL: @shl_C_X_ugt(
6-
; CHECK-NEXT: [[SHL:%.*]] = shl i8 7, [[X:%.*]]
7-
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[SHL]], -32
8-
; CHECK-NEXT: ret i1 [[R]]
6+
; CHECK-NEXT: ret i1 false
97
;
108
%shl = shl i8 7, %x
119
%r = icmp ugt i8 %shl, 224
@@ -14,9 +12,7 @@ define i1 @shl_C_X_ugt(i8 %x) {
1412

1513
define i1 @shl_C_X_ugt2(i8 %x) {
1614
; CHECK-LABEL: @shl_C_X_ugt2(
17-
; CHECK-NEXT: [[SHL:%.*]] = shl i8 5, [[X:%.*]]
18-
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[SHL]], -64
19-
; CHECK-NEXT: ret i1 [[R]]
15+
; CHECK-NEXT: ret i1 false
2016
;
2117
%shl = shl i8 5, %x
2218
%r = icmp ugt i8 %shl, 192
@@ -69,9 +65,7 @@ define i1 @shl_C_X_ugt_todo(i8 %x) {
6965

7066
define i1 @shl_X_C_ugt(i8 %x) {
7167
; CHECK-LABEL: @shl_X_C_ugt(
72-
; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 6
73-
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[SHL]], -64
74-
; CHECK-NEXT: ret i1 [[R]]
68+
; CHECK-NEXT: ret i1 false
7569
;
7670
%shl = shl i8 %x, 6
7771
%r = icmp ugt i8 %shl, 192

0 commit comments

Comments
 (0)