Skip to content

Commit c12d2f0

Browse files
committed
Introduce Scalar::range_metadata
1 parent f078a38 commit c12d2f0

File tree

3 files changed

+30
-28
lines changed

3 files changed

+30
-28
lines changed

src/librustc/ty/layout.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::fmt;
2323
use std::i128;
2424
use std::iter;
2525
use std::mem;
26-
use std::ops::{Add, Sub, Mul, AddAssign, Deref, RangeInclusive};
26+
use std::ops::{Add, Sub, Mul, AddAssign, Deref, Range, RangeInclusive};
2727

2828
use ich::StableHashingContext;
2929
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
@@ -648,6 +648,19 @@ impl Scalar {
648648
false
649649
}
650650
}
651+
652+
/// Returns a range suitable to be passed to LLVM for range metadata.
653+
pub fn range_metadata<C: HasDataLayout>(&self, cx: C) -> Range<u128> {
654+
// For a (max) value of -1, max will be `-1 as usize`, which overflows.
655+
// However, that is fine here (it would still represent the full range),
656+
// i.e., if the range is everything.
657+
let bits = self.value.size(cx).bits();
658+
assert!(bits <= 128);
659+
let mask = !0u128 >> (128 - bits);
660+
let start = self.valid_range.start & mask;
661+
let end = self.valid_range.end.wrapping_add(1) & mask;
662+
start..end
663+
}
651664
}
652665

653666
/// The first half of a fat pointer.

src/librustc_trans/abi.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,22 +1056,18 @@ impl<'a, 'tcx> FnType<'tcx> {
10561056
_ => {}
10571057
}
10581058
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
1059-
let (min, max) = (scalar.valid_range.start, scalar.valid_range.end);
1060-
let max_next = max.wrapping_add(1);
1061-
let bits = scalar.value.size(bx.cx).bits();
1062-
assert!(bits <= 128);
1063-
let mask = !0u128 >> (128 - bits);
1064-
// For a (max) value of -1, max will be `-1 as usize`, which overflows.
1065-
// However, that is fine here (it would still represent the full range),
1066-
// i.e., if the range is everything. The lo==hi case would be
1067-
// rejected by the LLVM verifier (it would mean either an
1068-
// empty set, which is impossible, or the entire range of the
1069-
// type, which is pointless).
1059+
let range = scalar.range_metadata(bx.cx);
1060+
// The lo==hi case would be rejected by the LLVM verifier
1061+
// (it would mean either an empty set, which is impossible, or the
1062+
// entire range of the type, which is pointless).
1063+
//
1064+
// If the value is a boolean, the range is 0..2 and that ultimately
1065+
// become 0..0 when the type becomes i1.
10701066
match scalar.value {
1071-
layout::Int(..) if !scalar.is_bool() && max_next & mask != min & mask => {
1067+
layout::Int(..) if !scalar.is_bool() && range.start != range.end => {
10721068
// llvm::ConstantRange can deal with ranges that wrap around,
10731069
// so an overflow on (max + 1) is fine.
1074-
bx.range_metadata(callsite, min..max_next);
1070+
bx.range_metadata(callsite, range);
10751071
}
10761072
_ => {}
10771073
}

src/librustc_trans/mir/place.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,24 +91,17 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
9191
}
9292

9393
let scalar_load_metadata = |load, scalar: &layout::Scalar| {
94-
let (min, max) = (scalar.valid_range.start, scalar.valid_range.end);
95-
let max_next = max.wrapping_add(1);
96-
let bits = scalar.value.size(bx.cx).bits();
97-
assert!(bits <= 128);
98-
let mask = !0u128 >> (128 - bits);
99-
// For a (max) value of -1, max will be `-1 as usize`, which overflows.
100-
// However, that is fine here (it would still represent the full range),
101-
// i.e., if the range is everything. The lo==hi case would be
102-
// rejected by the LLVM verifier (it would mean either an
103-
// empty set, which is impossible, or the entire range of the
104-
// type, which is pointless).
94+
let range = scalar.range_metadata(bx.cx);
95+
// The lo==hi case would be rejected by the LLVM verifier
96+
// (it would mean either an empty set, which is impossible, or the
97+
// entire range of the type, which is pointless).
10598
match scalar.value {
106-
layout::Int(..) if max_next & mask != min & mask => {
99+
layout::Int(..) if range.start != range.end => {
107100
// llvm::ConstantRange can deal with ranges that wrap around,
108101
// so an overflow on (max + 1) is fine.
109-
bx.range_metadata(load, min..max_next);
102+
bx.range_metadata(load, range);
110103
}
111-
layout::Pointer if 0 < min && min < max => {
104+
layout::Pointer if 0 < range.start && range.start < range.end => {
112105
bx.nonnull_metadata(load);
113106
}
114107
_ => {}

0 commit comments

Comments
 (0)