@@ -505,7 +505,47 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
505505
506506 match scalar. primitive ( ) {
507507 abi:: Primitive :: Int ( ..) => {
508- if !scalar. is_always_valid ( bx) {
508+ if let Some ( adt) = layout. ty . ty_adt_def ( )
509+ && adt. is_enum ( )
510+ {
511+ let mut discr_vals: Vec < _ > =
512+ adt. discriminants ( bx. tcx ) . map ( |( _, d) | d. val ) . collect ( ) ;
513+ discr_vals. sort ( ) ;
514+ let mut ranges =
515+ vec ! [ WrappingRange { start: discr_vals[ 0 ] , end: discr_vals[ 0 ] } ] ;
516+ for & discr in & discr_vals[ 1 ..] {
517+ let last = ranges. last_mut ( ) . unwrap ( ) ;
518+ if discr == last. end + 1 {
519+ last. end = discr;
520+ } else if !last. contains ( discr) {
521+ ranges. push ( WrappingRange { start : discr, end : discr } ) ;
522+ }
523+ }
524+
525+ if bx. cx . sess ( ) . opts . optimize != OptLevel :: No {
526+ unsafe {
527+ let llty = bx. cx . val_ty ( load) ;
528+ let md =
529+ ranges
530+ . iter ( )
531+ . flat_map ( |range| {
532+ [
533+ llvm:: LLVMValueAsMetadata (
534+ bx. cx . const_uint_big ( llty, range. start ) ,
535+ ) ,
536+ llvm:: LLVMValueAsMetadata ( bx. cx . const_uint_big (
537+ llty,
538+ range. end . wrapping_add ( 1 ) ,
539+ ) ) ,
540+ ]
541+ } )
542+ . collect :: < Vec < _ > > ( ) ;
543+ let md =
544+ llvm:: LLVMMDNodeInContext2 ( bx. cx . llcx , md. as_ptr ( ) , md. len ( ) ) ;
545+ bx. set_metadata ( load, llvm:: MD_range , md) ;
546+ }
547+ }
548+ } else if !scalar. is_always_valid ( bx) {
509549 bx. range_metadata ( load, scalar. valid_range ( bx) ) ;
510550 }
511551 }
0 commit comments