Skip to content

Commit 7ad5c32

Browse files
committed
Support narrowing casts in mir_operand_get_const_val
1 parent f1784d2 commit 7ad5c32

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

src/constant.rs

+31-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
//! Handling of `static`s, `const`s and promoted allocations
22
3+
use std::cmp::Ordering;
4+
35
use cranelift_module::*;
46
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
57
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
68
use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar};
79
use rustc_middle::mir::ConstValue;
10+
use rustc_middle::ty::ScalarInt;
811

912
use crate::prelude::*;
1013

@@ -430,17 +433,17 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
430433
pub(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
}

src/intrinsics/simd.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,11 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
282282
fx.tcx.sess.span_fatal(span, "Index argument for `simd_insert` is not a constant");
283283
};
284284

285-
let idx = idx_const
286-
.try_to_bits(Size::from_bytes(4 /* u32*/))
287-
.unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
285+
let idx: u32 = idx_const
286+
.try_to_u32()
287+
.unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const));
288288
let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx);
289-
if idx >= lane_count.into() {
289+
if u64::from(idx) >= lane_count {
290290
fx.tcx.sess.span_fatal(
291291
fx.mir.span,
292292
format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count),
@@ -331,10 +331,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
331331
};
332332

333333
let idx = idx_const
334-
.try_to_bits(Size::from_bytes(4 /* u32*/))
335-
.unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
334+
.try_to_u32()
335+
.unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const));
336336
let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx);
337-
if idx >= lane_count.into() {
337+
if u64::from(idx) >= lane_count {
338338
fx.tcx.sess.span_fatal(
339339
fx.mir.span,
340340
format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count),

0 commit comments

Comments
 (0)