Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit e4d0a5e

Browse files
author
Jingyue Wu
committed
[ValueTracking] Extend range metadata to call/invoke
Summary: With this patch, range metadata can be added to call/invoke including IntrinsicInst. Previously, it could only be added to load. Rename computeKnownBitsLoad to computeKnownBitsFromRangeMetadata because range metadata is not only used by load. Update the language reference to reflect this change. Test Plan: Add several tests in range-2.ll to confirm the verifier is happy with having range metadata on call/invoke. Add two tests in AddOverFlow.ll to confirm annotating range metadata to call/invoke can benefit InstCombine. Reviewers: meheff, nlewycky, reames, hfinkel, eliben Reviewed By: eliben Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D4187 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211281 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent b7509c6 commit e4d0a5e

File tree

9 files changed

+138
-16
lines changed

9 files changed

+138
-16
lines changed

docs/LangRef.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2749,11 +2749,12 @@ number representing the maximum relative error, for example:
27492749
'``range``' Metadata
27502750
^^^^^^^^^^^^^^^^^^^^
27512751

2752-
``range`` metadata may be attached only to loads of integer types. It
2753-
expresses the possible ranges the loaded value is in. The ranges are
2754-
represented with a flattened list of integers. The loaded value is known
2755-
to be in the union of the ranges defined by each consecutive pair. Each
2756-
pair has the following properties:
2752+
``range`` metadata may be attached only to ``load``, ``call`` and ``invoke`` of
2753+
integer types. It expresses the possible ranges the loaded value or the value
2754+
returned by the called function at this call site is in. The ranges are
2755+
represented with a flattened list of integers. The loaded value or the value
2756+
returned is known to be in the union of the ranges defined by each consecutive
2757+
pair. Each pair has the following properties:
27572758

27582759
- The type must match the type loaded by the instruction.
27592760
- The pair ``a,b`` represents the range ``[a,b)``.
@@ -2771,8 +2772,9 @@ Examples:
27712772
27722773
%a = load i8* %x, align 1, !range !0 ; Can only be 0 or 1
27732774
%b = load i8* %y, align 1, !range !1 ; Can only be 255 (-1), 0 or 1
2774-
%c = load i8* %z, align 1, !range !2 ; Can only be 0, 1, 3, 4 or 5
2775-
%d = load i8* %z, align 1, !range !3 ; Can only be -2, -1, 3, 4 or 5
2775+
%c = call i8 @foo(), !range !2 ; Can only be 0, 1, 3, 4 or 5
2776+
%d = invoke i8 @bar() to label %cont
2777+
unwind label %lpad, !range !3 ; Can only be -2, -1, 3, 4 or 5
27762778
...
27772779
!0 = metadata !{ i8 0, i8 2 }
27782780
!1 = metadata !{ i8 255, i8 2 }

include/llvm/Analysis/ValueTracking.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ namespace llvm {
3737
/// for all of the elements in the vector.
3838
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
3939
const DataLayout *TD = nullptr, unsigned Depth = 0);
40-
void computeKnownBitsLoad(const MDNode &Ranges, APInt &KnownZero);
40+
/// Compute known bits from the range metadata.
41+
/// \p KnownZero the set of bits that are known to be zero
42+
void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
43+
APInt &KnownZero);
4144

4245
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
4346
/// one. Convenience wrapper around computeKnownBits.

lib/Analysis/ValueTracking.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ static void computeKnownBitsMul(Value *Op0, Value *Op1, bool NSW,
188188
KnownOne.setBit(BitWidth - 1);
189189
}
190190

191-
void llvm::computeKnownBitsLoad(const MDNode &Ranges, APInt &KnownZero) {
191+
void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
192+
APInt &KnownZero) {
192193
unsigned BitWidth = KnownZero.getBitWidth();
193194
unsigned NumRanges = Ranges.getNumOperands() / 2;
194195
assert(NumRanges >= 1);
@@ -338,7 +339,7 @@ void llvm::computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
338339
default: break;
339340
case Instruction::Load:
340341
if (MDNode *MD = cast<LoadInst>(I)->getMetadata(LLVMContext::MD_range))
341-
computeKnownBitsLoad(*MD, KnownZero);
342+
computeKnownBitsFromRangeMetadata(*MD, KnownZero);
342343
break;
343344
case Instruction::And: {
344345
// If either the LHS or the RHS are Zero, the result is zero.
@@ -733,6 +734,12 @@ void llvm::computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
733734
break;
734735
}
735736
case Instruction::Call:
737+
case Instruction::Invoke:
738+
if (MDNode *MD = cast<Instruction>(I)->getMetadata(LLVMContext::MD_range))
739+
computeKnownBitsFromRangeMetadata(*MD, KnownZero);
740+
// If a range metadata is attached to this IntrinsicInst, intersect the
741+
// explicit range specified by the metadata and the implicit range of
742+
// the intrinsic.
736743
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
737744
switch (II->getIntrinsicID()) {
738745
default: break;
@@ -742,16 +749,16 @@ void llvm::computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
742749
// If this call is undefined for 0, the result will be less than 2^n.
743750
if (II->getArgOperand(1) == ConstantInt::getTrue(II->getContext()))
744751
LowBits -= 1;
745-
KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
752+
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
746753
break;
747754
}
748755
case Intrinsic::ctpop: {
749756
unsigned LowBits = Log2_32(BitWidth)+1;
750-
KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
757+
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
751758
break;
752759
}
753760
case Intrinsic::x86_sse42_crc32_64_64:
754-
KnownZero = APInt::getHighBitsSet(64, 32);
761+
KnownZero |= APInt::getHighBitsSet(64, 32);
755762
break;
756763
}
757764
}

lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2084,7 +2084,7 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
20842084
unsigned MemBits = VT.getScalarType().getSizeInBits();
20852085
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
20862086
} else if (const MDNode *Ranges = LD->getRanges()) {
2087-
computeKnownBitsLoad(*Ranges, KnownZero);
2087+
computeKnownBitsFromRangeMetadata(*Ranges, KnownZero);
20882088
}
20892089
break;
20902090
}

lib/IR/Verifier.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2233,7 +2233,8 @@ void Verifier::visitInstruction(Instruction &I) {
22332233
}
22342234

22352235
MDNode *MD = I.getMetadata(LLVMContext::MD_range);
2236-
Assert1(!MD || isa<LoadInst>(I), "Ranges are only for loads!", &I);
2236+
Assert1(!MD || isa<LoadInst>(I) || isa<CallInst>(I) || isa<InvokeInst>(I),
2237+
"Ranges are only for loads, calls and invokes!", &I);
22372238

22382239
InstsInThisBlock.insert(&I);
22392240
}

test/Transforms/InstCombine/AddOverFlow.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,44 @@ define i16 @zero_sign_bit2(i16 %a, i16 %b) {
3434
ret i16 %3
3535
}
3636

37+
declare i16 @bounded(i16 %input);
38+
declare i32 @__gxx_personality_v0(...);
39+
!0 = metadata !{i16 0, i16 32768} ; [0, 32767]
40+
!1 = metadata !{i16 0, i16 32769} ; [0, 32768]
41+
42+
define i16 @add_bounded_values(i16 %a, i16 %b) {
43+
; CHECK-LABEL: @add_bounded_values(
44+
entry:
45+
%c = call i16 @bounded(i16 %a), !range !0
46+
%d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0
47+
cont:
48+
; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow.
49+
%e = add i16 %c, %d
50+
; CHECK: add nuw i16 %c, %d
51+
ret i16 %e
52+
lpad:
53+
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
54+
filter [0 x i8*] zeroinitializer
55+
ret i16 42
56+
}
57+
58+
define i16 @add_bounded_values_2(i16 %a, i16 %b) {
59+
; CHECK-LABEL: @add_bounded_values_2(
60+
entry:
61+
%c = call i16 @bounded(i16 %a), !range !1
62+
%d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1
63+
cont:
64+
; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore,
65+
; %c + %d may unsigned overflow and we cannot add NUW.
66+
%e = add i16 %c, %d
67+
; CHECK: add i16 %c, %d
68+
ret i16 %e
69+
lpad:
70+
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
71+
filter [0 x i8*] zeroinitializer
72+
ret i16 42
73+
}
74+
3775
; CHECK-LABEL: @ripple_nsw1
3876
; CHECK: add nsw i16 %a, %b
3977
define i16 @ripple_nsw1(i16 %x, i16 %y) {

test/Transforms/InstCombine/add2.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,44 @@ define i32 @mul_add_to_mul_6(i32 %x, i32 %y) {
217217
; CHECK-NEXT: %add = mul nsw i32 %mul1, 6
218218
; CHECK-NEXT: ret i32 %add
219219
}
220+
221+
; This test and the next test verify that when a range metadata is attached to
222+
; llvm.cttz, ValueTracking correctly intersects the range specified by the
223+
; metadata and the range implied by the intrinsic.
224+
;
225+
; In this test, the range specified by the metadata is more strict. Therefore,
226+
; ValueTracking uses that range.
227+
define i16 @add_cttz(i16 %a) {
228+
; CHECK-LABEL: @add_cttz(
229+
; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned
230+
; is in [0, 16). The range metadata indicates the value returned is in [0, 8).
231+
; Intersecting these ranges, we know the value returned is in [0, 8).
232+
; Therefore, InstCombine will transform
233+
; add %cttz, 1111 1111 1111 1000 ; decimal -8
234+
; to
235+
; or %cttz, 1111 1111 1111 1000
236+
%cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !0
237+
%b = add i16 %cttz, -8
238+
; CHECK: or i16 %cttz, -8
239+
ret i16 %b
240+
}
241+
declare i16 @llvm.cttz.i16(i16, i1)
242+
!0 = metadata !{i16 0, i16 8}
243+
244+
; Similar to @add_cttz, but in this test, the range implied by the
245+
; intrinsic is more strict. Therefore, ValueTracking uses that range.
246+
define i16 @add_cttz_2(i16 %a) {
247+
; CHECK-LABEL: @add_cttz_2(
248+
; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned
249+
; is in [0, 16). The range metadata indicates the value returned is in
250+
; [0, 32). Intersecting these ranges, we know the value returned is in
251+
; [0, 16). Therefore, InstCombine will transform
252+
; add %cttz, 1111 1111 1111 0000 ; decimal -16
253+
; to
254+
; or %cttz, 1111 1111 1111 0000
255+
%cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !1
256+
%b = add i16 %cttz, -16
257+
; CHECK: or i16 %cttz, -16
258+
ret i16 %b
259+
}
260+
!1 = metadata !{i16 0, i16 32}

test/Verifier/range-1.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ entry:
66
ret void
77
}
88
!0 = metadata !{i8 0, i8 1}
9-
; CHECK: Ranges are only for loads!
9+
; CHECK: Ranges are only for loads, calls and invokes!
1010
; CHECK-NEXT: store i8 0, i8* %x, align 1, !range !0
1111

1212
define i8 @f2(i8* %x) {

test/Verifier/range-2.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,33 @@ entry:
3434
ret i8 %y
3535
}
3636
!4 = metadata !{i8 -1, i8 0, i8 1, i8 -2}
37+
38+
; We can annotate the range of the return value of a CALL.
39+
define void @call_all(i8* %x) {
40+
entry:
41+
%v1 = call i8 @f1(i8* %x), !range !0
42+
%v2 = call i8 @f2(i8* %x), !range !1
43+
%v3 = call i8 @f3(i8* %x), !range !2
44+
%v4 = call i8 @f4(i8* %x), !range !3
45+
%v5 = call i8 @f5(i8* %x), !range !4
46+
ret void
47+
}
48+
49+
; We can annotate the range of the return value of an INVOKE.
50+
define void @invoke_all(i8* %x) {
51+
entry:
52+
%v1 = invoke i8 @f1(i8* %x) to label %cont unwind label %lpad, !range !0
53+
%v2 = invoke i8 @f2(i8* %x) to label %cont unwind label %lpad, !range !1
54+
%v3 = invoke i8 @f3(i8* %x) to label %cont unwind label %lpad, !range !2
55+
%v4 = invoke i8 @f4(i8* %x) to label %cont unwind label %lpad, !range !3
56+
%v5 = invoke i8 @f5(i8* %x) to label %cont unwind label %lpad, !range !4
57+
58+
cont:
59+
ret void
60+
61+
lpad:
62+
%4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
63+
filter [0 x i8*] zeroinitializer
64+
ret void
65+
}
66+
declare i32 @__gxx_personality_v0(...)

0 commit comments

Comments
 (0)