Skip to content

Commit 50ece4c

Browse files
committed
[ValueTracking] Add better support for ConstantRange(And)
The fairly common power of two pattern `X & -X` can be capped at the highest power of 2 (signbit set).
1 parent 0f8b40a commit 50ece4c

File tree

2 files changed

+7
-10
lines changed

2 files changed

+7
-10
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8492,6 +8492,11 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
84928492
if (match(BO.getOperand(1), m_APInt(C)))
84938493
// 'and x, C' produces [0, C].
84948494
Upper = *C + 1;
8495+
// X & -X is a power of two or zero. So we can cap the value at max power of
8496+
// two.
8497+
if (match(BO.getOperand(0), m_Neg(m_Specific(BO.getOperand(1)))) ||
8498+
match(BO.getOperand(1), m_Neg(m_Specific(BO.getOperand(0)))))
8499+
Upper = APInt::getSignedMinValue(Width) + 1;
84958500
break;
84968501

84978502
case Instruction::Or:

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,7 @@ define i1 @shl_X_C_ugt_fail2(i8 %x) {
9696

9797
define i1 @and_ugt(i8 %xx) {
9898
; CHECK-LABEL: @and_ugt(
99-
; CHECK-NEXT: [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]]
100-
; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X]]
101-
; CHECK-NEXT: [[X_P2:%.*]] = and i8 [[NEGX]], [[X]]
102-
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X_P2]], -128
103-
; CHECK-NEXT: ret i1 [[R]]
99+
; CHECK-NEXT: ret i1 false
104100
;
105101
%x = mul i8 %xx, %xx ; thwart complexity-based canonicalization
106102
%negx = sub i8 0, %x
@@ -111,11 +107,7 @@ define i1 @and_ugt(i8 %xx) {
111107

112108
define i1 @and_ugt2(i8 %xx) {
113109
; CHECK-LABEL: @and_ugt2(
114-
; CHECK-NEXT: [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]]
115-
; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X]]
116-
; CHECK-NEXT: [[X_P2:%.*]] = and i8 [[X]], [[NEGX]]
117-
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X_P2]], -128
118-
; CHECK-NEXT: ret i1 [[R]]
110+
; CHECK-NEXT: ret i1 false
119111
;
120112
%x = mul i8 %xx, %xx ; thwart complexity-based canonicalization
121113
%negx = sub i8 0, %x

0 commit comments

Comments
 (0)