Move mir const to valtree conversion to its own method.
This commit is contained in:
parent
168de14ac9
commit
acdfec6061
2 changed files with 25 additions and 23 deletions
|
@ -863,22 +863,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
// promotes any complex rvalues to constants.
|
// promotes any complex rvalues to constants.
|
||||||
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
|
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
|
||||||
if let mir::Operand::Constant(constant) = arg {
|
if let mir::Operand::Constant(constant) = arg {
|
||||||
let ct = self.monomorphize(constant.literal);
|
let (llval, ty) = self.simd_shuffle_indices(&bx, constant);
|
||||||
let uv = match ct {
|
|
||||||
mir::ConstantKind::Unevaluated(uv, _) => uv.shrink(),
|
|
||||||
other => span_bug!(constant.span, "{other:#?}"),
|
|
||||||
};
|
|
||||||
let c = self.cx.tcx().const_eval_resolve_for_typeck(
|
|
||||||
ty::ParamEnv::reveal_all(),
|
|
||||||
uv,
|
|
||||||
Some(constant.span),
|
|
||||||
);
|
|
||||||
let (llval, ty) = self.simd_shuffle_indices(
|
|
||||||
&bx,
|
|
||||||
constant.span,
|
|
||||||
self.monomorphize(constant.ty()),
|
|
||||||
c,
|
|
||||||
);
|
|
||||||
return OperandRef {
|
return OperandRef {
|
||||||
val: Immediate(llval),
|
val: Immediate(llval),
|
||||||
layout: bx.layout_of(ty),
|
layout: bx.layout_of(ty),
|
||||||
|
|
|
@ -5,7 +5,6 @@ use rustc_middle::mir;
|
||||||
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
|
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
|
||||||
use rustc_middle::ty::layout::HasTyCtxt;
|
use rustc_middle::ty::layout::HasTyCtxt;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::source_map::Span;
|
|
||||||
use rustc_target::abi::Abi;
|
use rustc_target::abi::Abi;
|
||||||
|
|
||||||
use super::FunctionCx;
|
use super::FunctionCx;
|
||||||
|
@ -59,15 +58,34 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
|
||||||
|
/// that the given `constant` is an `ConstantKind::Unevaluated` and must be convertible to
|
||||||
|
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
|
||||||
|
pub fn eval_unevaluated_mir_constant_to_valtree(
|
||||||
|
&self,
|
||||||
|
constant: &mir::Constant<'tcx>,
|
||||||
|
) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> {
|
||||||
|
let uv = match constant.literal {
|
||||||
|
mir::ConstantKind::Unevaluated(uv, _) => uv.shrink(),
|
||||||
|
other => span_bug!(constant.span, "{other:#?}"),
|
||||||
|
};
|
||||||
|
let uv = self.monomorphize(uv);
|
||||||
|
self.cx.tcx().const_eval_resolve_for_typeck(
|
||||||
|
ty::ParamEnv::reveal_all(),
|
||||||
|
uv,
|
||||||
|
Some(constant.span),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// process constant containing SIMD shuffle indices
|
/// process constant containing SIMD shuffle indices
|
||||||
pub fn simd_shuffle_indices(
|
pub fn simd_shuffle_indices(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Bx,
|
bx: &Bx,
|
||||||
span: Span,
|
constant: &mir::Constant<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
|
||||||
constant: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
|
|
||||||
) -> (Bx::Value, Ty<'tcx>) {
|
) -> (Bx::Value, Ty<'tcx>) {
|
||||||
let val = constant
|
let ty = self.monomorphize(constant.ty());
|
||||||
|
let val = self
|
||||||
|
.eval_unevaluated_mir_constant_to_valtree(constant)
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|val| {
|
.map(|val| {
|
||||||
|
@ -90,9 +108,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bx.const_struct(&values, false)
|
bx.const_struct(&values, false)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span });
|
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
|
||||||
// We've errored, so we don't have to produce working code.
|
// We've errored, so we don't have to produce working code.
|
||||||
let ty = self.monomorphize(ty);
|
|
||||||
let llty = bx.backend_type(bx.layout_of(ty));
|
let llty = bx.backend_type(bx.layout_of(ty));
|
||||||
bx.const_undef(llty)
|
bx.const_undef(llty)
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue