Skip to content

Commit 3027ab2

Browse files
committed
handle range attribute in computeKnownBits
1 parent a9bc886 commit 3027ab2

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,14 +1467,20 @@ static void computeKnownBitsFromOperator(const Operator *I,
14671467
break;
14681468
}
14691469
case Instruction::Call:
1470-
case Instruction::Invoke:
1470+
case Instruction::Invoke: {
14711471
// If range metadata is attached to this call, set known bits from that,
14721472
// and then intersect with known bits based on other properties of the
14731473
// function.
14741474
if (MDNode *MD =
14751475
Q.IIQ.getMetadata(cast<Instruction>(I), LLVMContext::MD_range))
14761476
computeKnownBitsFromRangeMetadata(*MD, Known);
1477-
if (const Value *RV = cast<CallBase>(I)->getReturnedArgOperand()) {
1477+
1478+
const CallBase *CB = cast<CallBase>(I);
1479+
1480+
if (std::optional<ConstantRange> Range = CB->getRange())
1481+
Known = Range->toKnownBits();
1482+
1483+
if (const Value *RV = CB->getReturnedArgOperand()) {
14781484
if (RV->getType() == I->getType()) {
14791485
computeKnownBits(RV, Known2, Depth + 1, Q);
14801486
Known = Known.unionWith(Known2);
@@ -1646,6 +1652,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
16461652
}
16471653
}
16481654
break;
1655+
}
16491656
case Instruction::ShuffleVector: {
16501657
auto *Shuf = dyn_cast<ShuffleVectorInst>(I);
16511658
// FIXME: Do we need to handle ConstantExpr involving shufflevectors?
@@ -1900,6 +1907,10 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
19001907
// assumptions. Confirm that we've handled them all.
19011908
assert(!isa<ConstantData>(V) && "Unhandled constant data!");
19021909

1910+
if (const Argument *A = dyn_cast<Argument>(V))
1911+
if (std::optional<ConstantRange> Range = A->getRange())
1912+
Known = Range->toKnownBits();
1913+
19031914
// All recursive calls that increase depth must come after this.
19041915
if (Depth == MaxAnalysisRecursionDepth)
19051916
return;

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

Lines changed: 6 additions & 12 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

0 commit comments

Comments
 (0)