1
Fork 0

Make simd_shuffle_indices use valtrees

This commit is contained in:
Oli Scherer 2023-06-16 16:02:11 +00:00
parent 06c58cb966
commit 168de14ac9
6 changed files with 92 additions and 45 deletions

View file

@ -863,7 +863,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// promotes any complex rvalues to constants.
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
if let mir::Operand::Constant(constant) = arg {
let c = self.eval_mir_constant(constant);
let ct = self.monomorphize(constant.literal);
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,

View file

@ -65,16 +65,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx: &Bx,
span: Span,
ty: Ty<'tcx>,
constant: Result<ConstValue<'tcx>, ErrorHandled>,
constant: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
) -> (Bx::Value, Ty<'tcx>) {
constant
let val = constant
.ok()
.flatten()
.map(|val| {
let field_ty = ty.builtin_index().unwrap();
let c = mir::ConstantKind::from_value(val, ty);
let values: Vec<_> = bx
.tcx()
.destructure_mir_constant(ty::ParamEnv::reveal_all(), c)
.fields
let values: Vec<_> = val
.unwrap_branch()
.iter()
.map(|field| {
if let Some(prim) = field.try_to_scalar() {
@ -88,15 +87,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
})
.collect();
let llval = bx.const_struct(&values, false);
(llval, c.ty())
bx.const_struct(&values, false)
})
.unwrap_or_else(|_| {
.unwrap_or_else(|| {
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span });
// 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));
(bx.const_undef(llty), ty)
})
bx.const_undef(llty)
});
(val, ty)
}
}

View file

@ -92,7 +92,6 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
param_env: ty::ParamEnv<'tcx>,
val: mir::ConstantKind<'tcx>,
) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> {
trace!("destructure_mir_constant: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
let op = ecx.eval_mir_constant(&val, None, None)?;

View file

@ -95,11 +95,15 @@ impl<'tcx> TyCtxt<'tcx> {
// used generic parameters is a bug of evaluation, so checking for it
// here does feel somewhat sensible.
if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
assert!(matches!(
self.def_kind(ct.def),
DefKind::InlineConst | DefKind::AnonConst
));
let mir_body = self.mir_for_ctfe(ct.def);
let def_kind = self.def_kind(instance.def_id());
assert!(
matches!(
def_kind,
DefKind::InlineConst | DefKind::AnonConst | DefKind::AssocConst
),
"{cid:?} is {def_kind:?}",
);
let mir_body = self.mir_for_ctfe(instance.def_id());
if mir_body.is_polymorphic {
let Some(local_def_id) = ct.def.as_local() else { return };
self.struct_span_lint_hir(
@ -239,15 +243,3 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
self.eval_to_allocation_raw(param_env.and(gid))
}
}
impl<'tcx> TyCtxt<'tcx> {
/// Destructure a mir constant ADT or array into its variant index and its field values.
/// Panics if the destructuring fails, use `try_destructure_mir_constant` for fallible version.
pub fn destructure_mir_constant(
self,
param_env: ty::ParamEnv<'tcx>,
constant: mir::ConstantKind<'tcx>,
) -> mir::DestructuredConstant<'tcx> {
self.try_destructure_mir_constant(param_env.and(constant)).unwrap()
}
}