@@ -9,6 +9,7 @@ use rustc_middle::mir::{self, ConstValue};
9
9
use rustc_middle:: ty:: Ty ;
10
10
use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
11
11
use rustc_middle:: { bug, span_bug} ;
12
+ use rustc_session:: config:: OptLevel ;
12
13
use tracing:: { debug, instrument} ;
13
14
14
15
use super :: place:: { PlaceRef , PlaceValue } ;
@@ -496,6 +497,18 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
496
497
_ => ( tag_imm, bx. cx ( ) . immediate_backend_type ( tag_op. layout ) ) ,
497
498
} ;
498
499
500
+ // Layout ensures that we only get here for cases where the discriminant
501
+ // value and the variant index match, since that's all `Niche` can encode.
502
+ // But for emphasis and debugging, let's double-check one anyway.
503
+ debug_assert_eq ! (
504
+ self . layout
505
+ . ty
506
+ . discriminant_for_variant( bx. tcx( ) , untagged_variant)
507
+ . unwrap( )
508
+ . val,
509
+ u128 :: from( untagged_variant. as_u32( ) ) ,
510
+ ) ;
511
+
499
512
let relative_max = niche_variants. end ( ) . as_u32 ( ) - niche_variants. start ( ) . as_u32 ( ) ;
500
513
501
514
// We have a subrange `niche_start..=niche_end` inside `range`.
@@ -537,6 +550,21 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
537
550
relative_discr,
538
551
bx. cx ( ) . const_uint ( tag_llty, relative_max as u64 ) ,
539
552
) ;
553
+
554
+ // Thanks to parameter attributes and load metadata, LLVM already knows
555
+ // the general valid range of the tag. It's possible, though, for there
556
+ // to be an impossible value *in the middle*, which those ranges don't
557
+ // communicate, so it's worth an `assume` to let the optimizer know.
558
+ if niche_variants. contains ( & untagged_variant)
559
+ && bx. cx ( ) . sess ( ) . opts . optimize != OptLevel :: No
560
+ {
561
+ let impossible =
562
+ u64:: from ( untagged_variant. as_u32 ( ) - niche_variants. start ( ) . as_u32 ( ) ) ;
563
+ let impossible = bx. cx ( ) . const_uint ( tag_llty, impossible) ;
564
+ let ne = bx. icmp ( IntPredicate :: IntNE , relative_discr, impossible) ;
565
+ bx. assume ( ne) ;
566
+ }
567
+
540
568
( is_niche, cast_tag, niche_variants. start ( ) . as_u32 ( ) as u128 )
541
569
} ;
542
570
0 commit comments