Skip to content

Commit e2d269b

Browse files
committed
handle range attribute in computeKnownBits
1 parent 7d0668a commit e2d269b

File tree

2 files changed

+21
-15
lines changed

2 files changed

+21
-15
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,14 +1500,20 @@ static void computeKnownBitsFromOperator(const Operator *I,
15001500
break;
15011501
}
15021502
case Instruction::Call:
1503-
case Instruction::Invoke:
1503+
case Instruction::Invoke: {
15041504
// If range metadata is attached to this call, set known bits from that,
15051505
// and then intersect with known bits based on other properties of the
15061506
// function.
15071507
if (MDNode *MD =
15081508
Q.IIQ.getMetadata(cast<Instruction>(I), LLVMContext::MD_range))
15091509
computeKnownBitsFromRangeMetadata(*MD, Known);
1510-
if (const Value *RV = cast<CallBase>(I)->getReturnedArgOperand()) {
1510+
1511+
const auto *CB = cast<CallBase>(I);
1512+
1513+
if (std::optional<ConstantRange> Range = CB->getRange())
1514+
Known = Known.unionWith(Range->toKnownBits());
1515+
1516+
if (const Value *RV = CB->getReturnedArgOperand()) {
15111517
if (RV->getType() == I->getType()) {
15121518
computeKnownBits(RV, Known2, Depth + 1, Q);
15131519
Known = Known.unionWith(Known2);
@@ -1679,6 +1685,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
16791685
}
16801686
}
16811687
break;
1688+
}
16821689
case Instruction::ShuffleVector: {
16831690
auto *Shuf = dyn_cast<ShuffleVectorInst>(I);
16841691
// FIXME: Do we need to handle ConstantExpr involving shufflevectors?
@@ -1933,6 +1940,10 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
19331940
// assumptions. Confirm that we've handled them all.
19341941
assert(!isa<ConstantData>(V) && "Unhandled constant data!");
19351942

1943+
if (const auto *A = dyn_cast<Argument>(V))
1944+
if (std::optional<ConstantRange> Range = A->getRange())
1945+
Known = Range->toKnownBits();
1946+
19361947
// All recursive calls that increase depth must come after this.
19371948
if (Depth == MaxAnalysisRecursionDepth)
19381949
return;

llvm/test/Transforms/InstSimplify/shift-knownbits.ll

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ define i32 @shl_amount_is_known_bogus(i32 %a, i32 %b) {
1616

1717
define i32 @shl_amount_is_known_bogus_range_attr(i32 %a, i32 range(i32 32, 64) %b) {
1818
; CHECK-LABEL: @shl_amount_is_known_bogus_range_attr(
19-
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
20-
; CHECK-NEXT: ret i32 [[SHL]]
19+
; CHECK-NEXT: ret i32 poison
2120
;
2221
%shl = shl i32 %a, %b
2322
ret i32 %shl
@@ -38,8 +37,7 @@ declare range(i32 0, 32) i32 @returns_in_range_helper()
3837
define i32 @shl_amount_is_known_bogus_range_return(i32 %a) {
3938
; CHECK-LABEL: @shl_amount_is_known_bogus_range_return(
4039
; CHECK-NEXT: [[B:%.*]] = call i32 @returns_out_of_range_helper()
41-
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B]]
42-
; CHECK-NEXT: ret i32 [[SHL]]
40+
; CHECK-NEXT: ret i32 poison
4341
;
4442
%b = call i32 @returns_out_of_range_helper()
4543
%shl = shl i32 %a, %b
@@ -62,8 +60,7 @@ declare i32 @returns_i32_helper()
6260
define i32 @shl_amount_is_known_bogus_range_call(i32 %a) {
6361
; CHECK-LABEL: @shl_amount_is_known_bogus_range_call(
6462
; CHECK-NEXT: [[B:%.*]] = call range(i32 32, 64) i32 @returns_i32_helper()
65-
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B]]
66-
; CHECK-NEXT: ret i32 [[SHL]]
63+
; CHECK-NEXT: ret i32 poison
6764
;
6865
%b = call range(i32 32, 64) i32 @returns_i32_helper()
6966
%shl = shl i32 %a, %b
@@ -83,8 +80,7 @@ define i32 @neg_shl_amount_is_known_bogus_range_call(i32 %a) {
8380

8481
define <2 x i32> @shl_amount_is_known_bogus_range_attr_vec(<2 x i32> %a, <2 x i32> range(i32 32, 64) %b) {
8582
; CHECK-LABEL: @shl_amount_is_known_bogus_range_attr_vec(
86-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], [[B:%.*]]
87-
; CHECK-NEXT: ret <2 x i32> [[SHL]]
83+
; CHECK-NEXT: ret <2 x i32> poison
8884
;
8985
%shl = shl <2 x i32> %a, %b
9086
ret <2 x i32> %shl
@@ -105,8 +101,7 @@ declare range(i32 0, 32) <2 x i32> @returns_in_range_helper_vec()
105101
define <2 x i32> @shl_amount_is_known_bogus_range_return_vec(<2 x i32> %a) {
106102
; CHECK-LABEL: @shl_amount_is_known_bogus_range_return_vec(
107103
; CHECK-NEXT: [[B:%.*]] = call <2 x i32> @returns_out_of_range_helper_vec()
108-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], [[B]]
109-
; CHECK-NEXT: ret <2 x i32> [[SHL]]
104+
; CHECK-NEXT: ret <2 x i32> poison
110105
;
111106
%b = call <2 x i32> @returns_out_of_range_helper_vec()
112107
%shl = shl <2 x i32> %a, %b
@@ -129,8 +124,7 @@ declare <2 x i32> @returns_i32_helper_vec()
129124
define <2 x i32> @shl_amount_is_known_bogus_range_call_vec(<2 x i32> %a) {
130125
; CHECK-LABEL: @shl_amount_is_known_bogus_range_call_vec(
131126
; CHECK-NEXT: [[B:%.*]] = call range(i32 32, 64) <2 x i32> @returns_i32_helper_vec()
132-
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], [[B]]
133-
; CHECK-NEXT: ret <2 x i32> [[SHL]]
127+
; CHECK-NEXT: ret <2 x i32> poison
134128
;
135129
%b = call range(i32 32, 64) <2 x i32> @returns_i32_helper_vec()
136130
%shl = shl <2 x i32> %a, %b
@@ -151,7 +145,8 @@ define <2 x i32> @neg_shl_amount_is_known_bogus_range_call_vec(<2 x i32> %a) {
151145
define i32 @shl_amount_is_not_known_bogus_range_call_and_range_metadata(i32 %a) {
152146
; CHECK-LABEL: @shl_amount_is_not_known_bogus_range_call_and_range_metadata(
153147
; CHECK-NEXT: [[B:%.*]] = call range(i32 0, 32) i32 @returns_i32_helper(), !range [[RNG0:![0-9]+]]
154-
; CHECK-NEXT: ret i32 poison
148+
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B]]
149+
; CHECK-NEXT: ret i32 [[SHL]]
155150
;
156151
%b = call range(i32 0, 32) i32 @returns_i32_helper(), !range !{ i32 32, i32 64 }
157152
%shl = shl i32 %a, %b

0 commit comments

Comments
 (0)