@@ -23,7 +23,7 @@ use std::fmt;
23
23
use std:: i128;
24
24
use std:: iter;
25
25
use std:: mem;
26
- use std:: ops:: { Add , Sub , Mul , AddAssign , Deref , RangeInclusive } ;
26
+ use std:: ops:: { Add , Sub , Mul , AddAssign , Deref , Range , RangeInclusive } ;
27
27
28
28
use ich:: StableHashingContext ;
29
29
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher ,
@@ -648,6 +648,25 @@ impl Scalar {
648
648
false
649
649
}
650
650
}
651
+
652
+ /// Returns a range suitable to be passed to LLVM for range metadata.
653
+ pub fn range_metadata < C : HasDataLayout > ( & self , cx : C ) -> Option < 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 ;
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)
669
+ }
651
670
}
652
671
653
672
/// The first half of a fat pointer.
0 commit comments