@@ -270,6 +270,28 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
270
270
TagEncoding :: Niche { untagged_variant, ref niche_variants, niche_start }
271
271
if is_niche_after_nonniche ( tag_scalar, niche_start, niche_variants, bx. cx ( ) ) =>
272
272
{
273
+ if untagged_variant >= * niche_variants. start ( ) {
274
+ // This assumption helps LLVM to compile `get_discr() == untagged_variant`
275
+ // to a single cmp.
276
+ if untagged_variant <= * niche_variants. end ( ) {
277
+ let unused_tag = bx. cx ( ) . const_uint_big (
278
+ niche_llty,
279
+ niche_start + untagged_variant. as_u32 ( ) as u128 ,
280
+ ) ;
281
+ let assumption = bx. icmp ( IntPredicate :: IntNE , tag, unused_tag) ;
282
+ bx. assume ( assumption) ;
283
+ } else {
284
+ // This assumption is in theory implied by tag range, but doing it
285
+ // explicitly helps.
286
+ let last_tag = bx. cx ( ) . const_uint_big (
287
+ niche_llty,
288
+ niche_start + niche_variants. end ( ) . as_u32 ( ) as u128 ,
289
+ ) ;
290
+ let assumption = bx. icmp ( IntPredicate :: IntULE , tag, last_tag) ;
291
+ bx. assume ( assumption) ;
292
+ }
293
+ }
294
+
273
295
let ( niche_llty, tag) = match tag_scalar. primitive ( ) {
274
296
// Operations on u8/u16 directly result in some additional movzxs, pretend the tag
275
297
// is cast_to type (usize) instead.
@@ -302,11 +324,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
302
324
} ;
303
325
let untagged_discr =
304
326
bx. cx ( ) . const_uint ( niche_llty, untagged_variant. as_u32 ( ) as u64 ) ;
305
- if untagged_variant >= * niche_variants. start ( ) {
306
- let tagged_never_untagged =
307
- bx. icmp ( IntPredicate :: IntNE , untagged_discr, niche_discr) ;
308
- bx. assume ( tagged_never_untagged) ;
309
- }
310
327
let discr = bx. select ( is_untagged, untagged_discr, niche_discr) ;
311
328
312
329
bx. intcast ( discr, cast_to, false )
0 commit comments