File tree 3 files changed +28
-30
lines changed
3 files changed +28
-30
lines changed Original file line number Diff line number Diff line change @@ -650,16 +650,22 @@ impl Scalar {
650
650
}
651
651
652
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 > {
653
+ pub fn range_metadata < C : HasDataLayout > ( & self , cx : C ) -> Option < Range < u128 > > {
654
654
// For a (max) value of -1, max will be `-1 as usize`, which overflows.
655
655
// However, that is fine here (it would still represent the full range),
656
656
// i.e., if the range is everything.
657
657
let bits = self . value . size ( cx) . bits ( ) ;
658
658
assert ! ( bits <= 128 ) ;
659
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
660
+ let start = self . valid_range . start ;
661
+ let end = self . valid_range . end . wrapping_add ( 1 ) ;
662
+ if start & mask == end & mask {
663
+ // The lo==hi case would be rejected by the LLVM verifier
664
+ // (it would mean either an empty set, which is impossible, or the
665
+ // entire range of the type, which is pointless).
666
+ return None ;
667
+ }
668
+ Some ( start..end)
663
669
}
664
670
}
665
671
Original file line number Diff line number Diff line change @@ -1056,20 +1056,16 @@ impl<'a, 'tcx> FnType<'tcx> {
1056
1056
_ => { }
1057
1057
}
1058
1058
if let layout:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
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.
1066
- match scalar. value {
1067
- layout:: Int ( ..) if !scalar. is_bool ( ) && range. start != range. end => {
1068
- // llvm::ConstantRange can deal with ranges that wrap around,
1069
- // so an overflow on (max + 1) is fine.
1070
- bx. range_metadata ( callsite, range) ;
1059
+ if let Some ( range) = scalar. range_metadata ( bx. cx ) {
1060
+ // If the value is a boolean, the range is 0..2 and that ultimately
1061
+ // become 0..0 when the type becomes i1, which would be rejected
1062
+ // by the LLVM verifier.
1063
+ match scalar. value {
1064
+ layout:: Int ( ..) if !scalar. is_bool ( ) => {
1065
+ bx. range_metadata ( callsite, range) ;
1066
+ }
1067
+ _ => { }
1071
1068
}
1072
- _ => { }
1073
1069
}
1074
1070
}
1075
1071
for arg in & self . args {
Original file line number Diff line number Diff line change @@ -91,20 +91,16 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
91
91
}
92
92
93
93
let scalar_load_metadata = |load, scalar : & layout:: Scalar | {
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).
98
- match scalar. value {
99
- layout:: Int ( ..) if range. start != range. end => {
100
- // llvm::ConstantRange can deal with ranges that wrap around,
101
- // so an overflow on (max + 1) is fine.
102
- bx. range_metadata ( load, range) ;
103
- }
104
- layout:: Pointer if 0 < range. start && range. start < range. end => {
105
- bx. nonnull_metadata ( load) ;
94
+ if let Some ( range) = scalar. range_metadata ( bx. cx ) {
95
+ match scalar. value {
96
+ layout:: Int ( ..) => {
97
+ bx. range_metadata ( load, range) ;
98
+ }
99
+ layout:: Pointer if 0 < range. start && range. start < range. end => {
100
+ bx. nonnull_metadata ( load) ;
101
+ }
102
+ _ => { }
106
103
}
107
- _ => { }
108
104
}
109
105
} ;
110
106
You can’t perform that action at this time.
0 commit comments