@@ -278,7 +278,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
278278                { 
279279                    let  from_backend_ty = bx. backend_type ( operand. layout ) ; 
280280                    let  to_backend_ty = bx. backend_type ( cast) ; 
281-                     Some ( OperandValue :: Immediate ( self . transmute_immediate ( 
281+                     Some ( OperandValue :: Immediate ( transmute_immediate ( 
282282                        bx, 
283283                        imm, 
284284                        from_scalar, 
@@ -303,8 +303,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
303303                    let  out_a_ibty = bx. scalar_pair_element_backend_type ( cast,  0 ,  false ) ; 
304304                    let  out_b_ibty = bx. scalar_pair_element_backend_type ( cast,  1 ,  false ) ; 
305305                    Some ( OperandValue :: Pair ( 
306-                         self . transmute_immediate ( bx,  imm_a,  in_a,  in_a_ibty,  out_a,  out_a_ibty) , 
307-                         self . transmute_immediate ( bx,  imm_b,  in_b,  in_b_ibty,  out_b,  out_b_ibty) , 
306+                         transmute_immediate ( bx,  imm_a,  in_a,  in_a_ibty,  out_a,  out_a_ibty) , 
307+                         transmute_immediate ( bx,  imm_b,  in_b,  in_b_ibty,  out_b,  out_b_ibty) , 
308308                    ) ) 
309309                }  else  { 
310310                    None 
@@ -332,7 +332,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
332332        // valid ranges. For example, `char`s are passed as just `i32`, with no 
333333        // way for LLVM to know that they're 0x10FFFF at most. Thus we assume 
334334        // the range of the input value too, not just the output range. 
335-         self . assume_scalar_range ( bx,  imm,  from_scalar,  from_backend_ty) ; 
335+         assume_scalar_range ( bx,  imm,  from_scalar,  from_backend_ty) ; 
336336
337337        imm = match  ( from_scalar. primitive ( ) ,  to_scalar. primitive ( ) )  { 
338338            ( Int ( _,  is_signed) ,  Int ( ..) )  => bx. intcast ( imm,  to_backend_ty,  is_signed) , 
@@ -365,98 +365,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
365365        Some ( imm) 
366366    } 
367367
368-     /// Transmutes one of the immediates from an [`OperandValue::Immediate`] 
369-      /// or an [`OperandValue::Pair`] to an immediate of the target type. 
370-      /// 
371-      /// `to_backend_ty` must be the *non*-immediate backend type (so it will be 
372-      /// `i8`, not `i1`, for `bool`-like types.) 
373-      fn  transmute_immediate ( 
374-         & self , 
375-         bx :  & mut  Bx , 
376-         mut  imm :  Bx :: Value , 
377-         from_scalar :  abi:: Scalar , 
378-         from_backend_ty :  Bx :: Type , 
379-         to_scalar :  abi:: Scalar , 
380-         to_backend_ty :  Bx :: Type , 
381-     )  -> Bx :: Value  { 
382-         assert_eq ! ( from_scalar. size( self . cx) ,  to_scalar. size( self . cx) ) ; 
383- 
384-         // While optimizations will remove no-op transmutes, they might still be 
385-         // there in debug or things that aren't no-op in MIR because they change 
386-         // the Rust type but not the underlying layout/niche. 
387-         if  from_scalar == to_scalar && from_backend_ty == to_backend_ty { 
388-             return  imm; 
389-         } 
390- 
391-         use  abi:: Primitive :: * ; 
392-         imm = bx. from_immediate ( imm) ; 
393- 
394-         // If we have a scalar, we must already know its range. Either 
395-         // 
396-         // 1) It's a parameter with `range` parameter metadata, 
397-         // 2) It's something we `load`ed with `!range` metadata, or 
398-         // 3) After a transmute we `assume`d the range (see below). 
399-         // 
400-         // That said, last time we tried removing this, it didn't actually help 
401-         // the rustc-perf results, so might as well keep doing it 
402-         // <https://github.com/rust-lang/rust/pull/135610#issuecomment-2599275182> 
403-         self . assume_scalar_range ( bx,  imm,  from_scalar,  from_backend_ty) ; 
404- 
405-         imm = match  ( from_scalar. primitive ( ) ,  to_scalar. primitive ( ) )  { 
406-             ( Int ( ..)  | Float ( _) ,  Int ( ..)  | Float ( _) )  => bx. bitcast ( imm,  to_backend_ty) , 
407-             ( Pointer ( ..) ,  Pointer ( ..) )  => bx. pointercast ( imm,  to_backend_ty) , 
408-             ( Int ( ..) ,  Pointer ( ..) )  => bx. ptradd ( bx. const_null ( bx. type_ptr ( ) ) ,  imm) , 
409-             ( Pointer ( ..) ,  Int ( ..) )  => { 
410-                 // FIXME: this exposes the provenance, which shouldn't be necessary. 
411-                 bx. ptrtoint ( imm,  to_backend_ty) 
412-             } 
413-             ( Float ( _) ,  Pointer ( ..) )  => { 
414-                 let  int_imm = bx. bitcast ( imm,  bx. cx ( ) . type_isize ( ) ) ; 
415-                 bx. ptradd ( bx. const_null ( bx. type_ptr ( ) ) ,  int_imm) 
416-             } 
417-             ( Pointer ( ..) ,  Float ( _) )  => { 
418-                 // FIXME: this exposes the provenance, which shouldn't be necessary. 
419-                 let  int_imm = bx. ptrtoint ( imm,  bx. cx ( ) . type_isize ( ) ) ; 
420-                 bx. bitcast ( int_imm,  to_backend_ty) 
421-             } 
422-         } ; 
423- 
424-         // This `assume` remains important for cases like (a conceptual) 
425-         //    transmute::<u32, NonZeroU32>(x) == 0 
426-         // since it's never passed to something with parameter metadata (especially 
427-         // after MIR inlining) so the only way to tell the backend about the 
428-         // constraint that the `transmute` introduced is to `assume` it. 
429-         self . assume_scalar_range ( bx,  imm,  to_scalar,  to_backend_ty) ; 
430- 
431-         imm = bx. to_immediate_scalar ( imm,  to_scalar) ; 
432-         imm
433-     } 
434- 
435-     fn  assume_scalar_range ( 
436-         & self , 
437-         bx :  & mut  Bx , 
438-         imm :  Bx :: Value , 
439-         scalar :  abi:: Scalar , 
440-         backend_ty :  Bx :: Type , 
441-     )  { 
442-         if  matches ! ( self . cx. sess( ) . opts. optimize,  OptLevel :: No )  || scalar. is_always_valid ( self . cx )  { 
443-             return ; 
444-         } 
445- 
446-         match  scalar. primitive ( )  { 
447-             abi:: Primitive :: Int ( ..)  => { 
448-                 let  range = scalar. valid_range ( self . cx ) ; 
449-                 bx. assume_integer_range ( imm,  backend_ty,  range) ; 
450-             } 
451-             abi:: Primitive :: Pointer ( abi:: AddressSpace :: DATA ) 
452-                 if  !scalar. valid_range ( self . cx ) . contains ( 0 )  =>
453-             { 
454-                 bx. assume_nonnull ( imm) ; 
455-             } 
456-             abi:: Primitive :: Pointer ( ..)  | abi:: Primitive :: Float ( ..)  => { } 
457-         } 
458-     } 
459- 
460368    pub ( crate )  fn  codegen_rvalue_unsized ( 
461369        & mut  self , 
462370        bx :  & mut  Bx , 
@@ -1231,3 +1139,93 @@ impl OperandValueKind {
12311139        } ) 
12321140    } 
12331141} 
1142+ 
1143+ /// Transmutes one of the immediates from an [`OperandValue::Immediate`] 
1144+ /// or an [`OperandValue::Pair`] to an immediate of the target type. 
1145+ /// 
1146+ /// `to_backend_ty` must be the *non*-immediate backend type (so it will be 
1147+ /// `i8`, not `i1`, for `bool`-like types.) 
1148+ fn  transmute_immediate < ' a ,  ' tcx ,  Bx :  BuilderMethods < ' a ,  ' tcx > > ( 
1149+     bx :  & mut  Bx , 
1150+     mut  imm :  Bx :: Value , 
1151+     from_scalar :  abi:: Scalar , 
1152+     from_backend_ty :  Bx :: Type , 
1153+     to_scalar :  abi:: Scalar , 
1154+     to_backend_ty :  Bx :: Type , 
1155+ )  -> Bx :: Value  { 
1156+     assert_eq ! ( from_scalar. size( bx. cx( ) ) ,  to_scalar. size( bx. cx( ) ) ) ; 
1157+ 
1158+     // While optimizations will remove no-op transmutes, they might still be 
1159+     // there in debug or things that aren't no-op in MIR because they change 
1160+     // the Rust type but not the underlying layout/niche. 
1161+     if  from_scalar == to_scalar && from_backend_ty == to_backend_ty { 
1162+         return  imm; 
1163+     } 
1164+ 
1165+     use  abi:: Primitive :: * ; 
1166+     imm = bx. from_immediate ( imm) ; 
1167+ 
1168+     // If we have a scalar, we must already know its range. Either 
1169+     // 
1170+     // 1) It's a parameter with `range` parameter metadata, 
1171+     // 2) It's something we `load`ed with `!range` metadata, or 
1172+     // 3) After a transmute we `assume`d the range (see below). 
1173+     // 
1174+     // That said, last time we tried removing this, it didn't actually help 
1175+     // the rustc-perf results, so might as well keep doing it 
1176+     // <https://github.com/rust-lang/rust/pull/135610#issuecomment-2599275182> 
1177+     assume_scalar_range ( bx,  imm,  from_scalar,  from_backend_ty) ; 
1178+ 
1179+     imm = match  ( from_scalar. primitive ( ) ,  to_scalar. primitive ( ) )  { 
1180+         ( Int ( ..)  | Float ( _) ,  Int ( ..)  | Float ( _) )  => bx. bitcast ( imm,  to_backend_ty) , 
1181+         ( Pointer ( ..) ,  Pointer ( ..) )  => bx. pointercast ( imm,  to_backend_ty) , 
1182+         ( Int ( ..) ,  Pointer ( ..) )  => bx. ptradd ( bx. const_null ( bx. type_ptr ( ) ) ,  imm) , 
1183+         ( Pointer ( ..) ,  Int ( ..) )  => { 
1184+             // FIXME: this exposes the provenance, which shouldn't be necessary. 
1185+             bx. ptrtoint ( imm,  to_backend_ty) 
1186+         } 
1187+         ( Float ( _) ,  Pointer ( ..) )  => { 
1188+             let  int_imm = bx. bitcast ( imm,  bx. cx ( ) . type_isize ( ) ) ; 
1189+             bx. ptradd ( bx. const_null ( bx. type_ptr ( ) ) ,  int_imm) 
1190+         } 
1191+         ( Pointer ( ..) ,  Float ( _) )  => { 
1192+             // FIXME: this exposes the provenance, which shouldn't be necessary. 
1193+             let  int_imm = bx. ptrtoint ( imm,  bx. cx ( ) . type_isize ( ) ) ; 
1194+             bx. bitcast ( int_imm,  to_backend_ty) 
1195+         } 
1196+     } ; 
1197+ 
1198+     // This `assume` remains important for cases like (a conceptual) 
1199+     //    transmute::<u32, NonZeroU32>(x) == 0 
1200+     // since it's never passed to something with parameter metadata (especially 
1201+     // after MIR inlining) so the only way to tell the backend about the 
1202+     // constraint that the `transmute` introduced is to `assume` it. 
1203+     assume_scalar_range ( bx,  imm,  to_scalar,  to_backend_ty) ; 
1204+ 
1205+     imm = bx. to_immediate_scalar ( imm,  to_scalar) ; 
1206+     imm
1207+ } 
1208+ 
1209+ fn  assume_scalar_range < ' a ,  ' tcx ,  Bx :  BuilderMethods < ' a ,  ' tcx > > ( 
1210+     bx :  & mut  Bx , 
1211+     imm :  Bx :: Value , 
1212+     scalar :  abi:: Scalar , 
1213+     backend_ty :  Bx :: Type , 
1214+ )  { 
1215+     if  matches ! ( bx. cx( ) . sess( ) . opts. optimize,  OptLevel :: No )  || scalar. is_always_valid ( bx. cx ( ) )  { 
1216+         return ; 
1217+     } 
1218+ 
1219+     match  scalar. primitive ( )  { 
1220+         abi:: Primitive :: Int ( ..)  => { 
1221+             let  range = scalar. valid_range ( bx. cx ( ) ) ; 
1222+             bx. assume_integer_range ( imm,  backend_ty,  range) ; 
1223+         } 
1224+         abi:: Primitive :: Pointer ( abi:: AddressSpace :: DATA ) 
1225+             if  !scalar. valid_range ( bx. cx ( ) ) . contains ( 0 )  =>
1226+         { 
1227+             bx. assume_nonnull ( imm) ; 
1228+         } 
1229+         abi:: Primitive :: Pointer ( ..)  | abi:: Primitive :: Float ( ..)  => { } 
1230+     } 
1231+ } 
0 commit comments