File tree Expand file tree Collapse file tree 3 files changed +28
-30
lines changed
Expand file tree Collapse file tree 3 files changed +28
-30
lines changed Original file line number Diff line number Diff line change @@ -650,16 +650,22 @@ impl Scalar {
650650 }
651651
652652 /// 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 > > {
654654 // For a (max) value of -1, max will be `-1 as usize`, which overflows.
655655 // However, that is fine here (it would still represent the full range),
656656 // i.e., if the range is everything.
657657 let bits = self . value . size ( cx) . bits ( ) ;
658658 assert ! ( bits <= 128 ) ;
659659 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)
663669 }
664670}
665671
Original file line number Diff line number Diff line change @@ -1056,20 +1056,16 @@ impl<'a, 'tcx> FnType<'tcx> {
10561056 _ => { }
10571057 }
10581058 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+ _ => { }
10711068 }
1072- _ => { }
10731069 }
10741070 }
10751071 for arg in & self . args {
Original file line number Diff line number Diff line change @@ -91,20 +91,16 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
9191 }
9292
9393 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+ _ => { }
106103 }
107- _ => { }
108104 }
109105 } ;
110106
You can’t perform that action at this time.
0 commit comments