11//! Handling of `static`s, `const`s and promoted allocations
22
3+ use std:: cmp:: Ordering ;
4+
35use cranelift_module:: * ;
46use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
57use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
68use rustc_middle:: mir:: interpret:: { read_target_uint, AllocId , GlobalAlloc , Scalar } ;
79use rustc_middle:: mir:: ConstValue ;
10+ use rustc_middle:: ty:: ScalarInt ;
811
912use crate :: prelude:: * ;
1013
@@ -430,17 +433,17 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
430433pub ( crate ) fn mir_operand_get_const_val < ' tcx > (
431434 fx : & FunctionCx < ' _ , ' _ , ' tcx > ,
432435 operand : & Operand < ' tcx > ,
433- ) -> Option < ConstValue < ' tcx > > {
436+ ) -> Option < ScalarInt > {
434437 match operand {
435- Operand :: Constant ( const_) => Some ( eval_mir_constant ( fx, const_) . 0 ) ,
438+ Operand :: Constant ( const_) => eval_mir_constant ( fx, const_) . 0 . try_to_scalar_int ( ) ,
436439 // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
437440 // inside a temporary before being passed to the intrinsic requiring the const argument.
438441 // This code tries to find a single constant defining definition of the referenced local.
439442 Operand :: Copy ( place) | Operand :: Move ( place) => {
440443 if !place. projection . is_empty ( ) {
441444 return None ;
442445 }
443- let mut computed_const_val = None ;
446+ let mut computed_scalar_int = None ;
444447 for bb_data in fx. mir . basic_blocks . iter ( ) {
445448 for stmt in & bb_data. statements {
446449 match & stmt. kind {
@@ -456,22 +459,38 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
456459 operand,
457460 ty,
458461 ) => {
459- if computed_const_val . is_some ( ) {
462+ if computed_scalar_int . is_some ( ) {
460463 return None ; // local assigned twice
461464 }
462465 if !matches ! ( ty. kind( ) , ty:: Uint ( _) | ty:: Int ( _) ) {
463466 return None ;
464467 }
465- let const_val = mir_operand_get_const_val ( fx, operand) ?;
466- if fx. layout_of ( * ty) . size
467- != const_val. try_to_scalar_int ( ) ?. size ( )
468+ let scalar_int = mir_operand_get_const_val ( fx, operand) ?;
469+ let scalar_int = match fx
470+ . layout_of ( * ty)
471+ . size
472+ . cmp ( & scalar_int. size ( ) )
468473 {
469- return None ;
470- }
471- computed_const_val = Some ( const_val) ;
474+ Ordering :: Equal => scalar_int,
475+ Ordering :: Less => match ty. kind ( ) {
476+ ty:: Uint ( _) => ScalarInt :: try_from_uint (
477+ scalar_int. try_to_uint ( scalar_int. size ( ) ) . unwrap ( ) ,
478+ fx. layout_of ( * ty) . size ,
479+ )
480+ . unwrap ( ) ,
481+ ty:: Int ( _) => ScalarInt :: try_from_int (
482+ scalar_int. try_to_int ( scalar_int. size ( ) ) . unwrap ( ) ,
483+ fx. layout_of ( * ty) . size ,
484+ )
485+ . unwrap ( ) ,
486+ _ => unreachable ! ( ) ,
487+ } ,
488+ Ordering :: Greater => return None ,
489+ } ;
490+ computed_scalar_int = Some ( scalar_int) ;
472491 }
473492 Rvalue :: Use ( operand) => {
474- computed_const_val = mir_operand_get_const_val ( fx, operand)
493+ computed_scalar_int = mir_operand_get_const_val ( fx, operand)
475494 }
476495 _ => return None ,
477496 }
@@ -522,7 +541,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
522541 TerminatorKind :: Call { .. } => { }
523542 }
524543 }
525- computed_const_val
544+ computed_scalar_int
526545 }
527546 }
528547}
0 commit comments