1
1
//! Handling of `static`s, `const`s and promoted allocations
2
2
3
+ use std:: cmp:: Ordering ;
4
+
3
5
use cranelift_module:: * ;
4
6
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
5
7
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
6
8
use rustc_middle:: mir:: interpret:: { read_target_uint, AllocId , GlobalAlloc , Scalar } ;
7
9
use rustc_middle:: mir:: ConstValue ;
10
+ use rustc_middle:: ty:: ScalarInt ;
8
11
9
12
use crate :: prelude:: * ;
10
13
@@ -430,17 +433,17 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
430
433
pub ( crate ) fn mir_operand_get_const_val < ' tcx > (
431
434
fx : & FunctionCx < ' _ , ' _ , ' tcx > ,
432
435
operand : & Operand < ' tcx > ,
433
- ) -> Option < ConstValue < ' tcx > > {
436
+ ) -> Option < ScalarInt > {
434
437
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 ( ) ,
436
439
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
437
440
// inside a temporary before being passed to the intrinsic requiring the const argument.
438
441
// This code tries to find a single constant defining definition of the referenced local.
439
442
Operand :: Copy ( place) | Operand :: Move ( place) => {
440
443
if !place. projection . is_empty ( ) {
441
444
return None ;
442
445
}
443
- let mut computed_const_val = None ;
446
+ let mut computed_scalar_int = None ;
444
447
for bb_data in fx. mir . basic_blocks . iter ( ) {
445
448
for stmt in & bb_data. statements {
446
449
match & stmt. kind {
@@ -456,22 +459,38 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
456
459
operand,
457
460
ty,
458
461
) => {
459
- if computed_const_val . is_some ( ) {
462
+ if computed_scalar_int . is_some ( ) {
460
463
return None ; // local assigned twice
461
464
}
462
465
if !matches ! ( ty. kind( ) , ty:: Uint ( _) | ty:: Int ( _) ) {
463
466
return None ;
464
467
}
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 ( ) )
468
473
{
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) ;
472
491
}
473
492
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)
475
494
}
476
495
_ => return None ,
477
496
}
@@ -522,7 +541,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
522
541
TerminatorKind :: Call { .. } => { }
523
542
}
524
543
}
525
- computed_const_val
544
+ computed_scalar_int
526
545
}
527
546
}
528
547
}
0 commit comments