do the variant idx computations on the host (non-overflowing)
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 94fbd4a..9e7ae32 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -687,24 +687,22 @@
                         (dataful_variant.as_u32() as u128, dataful_variant)
                     },
                     Ok(raw_discr) => {
+                        // We need to use machine arithmetic to get the relative variant idx.
                         let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                         let discr_val = ImmTy::from_uint(raw_discr, discr_layout);
-                        // We need to use machine arithmetic.
                         let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
-                        let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
                         let variant_index_relative_val = self.binary_op(
                             mir::BinOp::Sub,
                             discr_val,
                             niche_start_val,
                         )?;
-                        let variant_index_val = self.binary_op(
-                            mir::BinOp::Add,
-                            variant_index_relative_val,
-                            variants_start_val,
-                        )?;
-                        let variant_index = variant_index_val
+                        let variant_index_relative = variant_index_relative_val
                             .to_scalar()?
                             .assert_bits(discr_val.layout.size);
+                        // Then computing the absolute variant idx should not overflow any more.
+                        let variant_index = variants_start
+                            .checked_add(variant_index_relative)
+                            .expect("oveflow computing absolute variant idx");
                         // Check if this is in the range that indicates an actual discriminant.
                         if variants_start <= variant_index && variant_index <= variants_end {
                             let index = variant_index as usize;
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 9a3d701..5f4903d 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -1060,17 +1060,15 @@
                     variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(),
                 );
                 if variant_index != dataful_variant {
-                    let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
-                    // We need to use machine arithmetic.
                     let variants_start = niche_variants.start().as_u32();
-                    let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
+                    let variant_index_relative = variant_index.as_u32()
+                        .checked_sub(variants_start)
+                        .expect("overflow computing relative variant idx");
+                    // We need to use machine arithmetic when taking into account `niche_start`.
+                    let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                     let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
-                    let variant_index_val = ImmTy::from_uint(variant_index.as_u32(), discr_layout);
-                    let variant_index_relative_val = self.binary_op(
-                        mir::BinOp::Sub,
-                        variant_index_val,
-                        variants_start_val,
-                    )?;
+                    let variant_index_relative_val =
+                        ImmTy::from_uint(variant_index_relative, discr_layout);
                     let discr_val = self.binary_op(
                         mir::BinOp::Add,
                         variant_index_relative_val,