mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-08 01:28:18 +03:00
Handle SIMD vectors in CPlace::place_field
This commit is contained in:
@@ -82,6 +82,7 @@ pub(super) fn add_local_place_comments<'tcx>(
|
||||
assert_eq!(local, place_local);
|
||||
("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())))
|
||||
}
|
||||
CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
|
||||
CPlaceInner::Addr(ptr, meta) => {
|
||||
let meta = if let Some(meta) = meta {
|
||||
Cow::Owned(format!(",meta={}", meta))
|
||||
|
||||
@@ -411,6 +411,11 @@ fn place_location<'tcx>(
|
||||
|
||||
AttributeValue::Exprloc(Expression::new())
|
||||
}
|
||||
CPlaceInner::VarLane(_, _, _) => {
|
||||
// FIXME implement this
|
||||
|
||||
AttributeValue::Exprloc(Expression::new())
|
||||
}
|
||||
CPlaceInner::Addr(_, _) => {
|
||||
// FIXME implement this (used by arguments and returns)
|
||||
|
||||
|
||||
+49
-15
@@ -272,6 +272,7 @@ pub(crate) struct CPlace<'tcx> {
|
||||
pub(crate) enum CPlaceInner {
|
||||
Var(Local, Variable),
|
||||
VarPair(Local, Variable, Variable),
|
||||
VarLane(Local, Variable, u8),
|
||||
Addr(Pointer, Option<Value>),
|
||||
}
|
||||
|
||||
@@ -374,6 +375,12 @@ pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> CV
|
||||
fx.bcx.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index()));
|
||||
CValue::by_val_pair(val1, val2, layout)
|
||||
}
|
||||
CPlaceInner::VarLane(_local, var, lane) => {
|
||||
let val = fx.bcx.use_var(var);
|
||||
fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||
let val = fx.bcx.ins().extractlane(val, lane);
|
||||
CValue::by_val(val, layout)
|
||||
}
|
||||
CPlaceInner::Addr(ptr, extra) => {
|
||||
if let Some(extra) = extra {
|
||||
CValue::by_ref_unsized(ptr, extra, layout)
|
||||
@@ -395,7 +402,8 @@ pub(crate) fn to_ptr_maybe_unsized(self) -> (Pointer, Option<Value>) {
|
||||
match self.inner {
|
||||
CPlaceInner::Addr(ptr, extra) => (ptr, extra),
|
||||
CPlaceInner::Var(_, _)
|
||||
| CPlaceInner::VarPair(_, _, _) => bug!("Expected CPlace::Addr, found {:?}", self),
|
||||
| CPlaceInner::VarPair(_, _, _)
|
||||
| CPlaceInner::VarLane(_, _, _) => bug!("Expected CPlace::Addr, found {:?}", self),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,6 +535,22 @@ fn transmute_value<'tcx>(
|
||||
transmute_value(fx, var2, data2, dst_ty2);
|
||||
return;
|
||||
}
|
||||
CPlaceInner::VarLane(_local, var, lane) => {
|
||||
let data = from.load_scalar(fx);
|
||||
|
||||
// First get the old vector
|
||||
let vector = fx.bcx.use_var(var);
|
||||
fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||
|
||||
// Next insert the written lane into the vector
|
||||
let vector = fx.bcx.ins().insertlane(vector, data, lane);
|
||||
|
||||
// Finally write the new vector
|
||||
fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||
fx.bcx.def_var(var, vector);
|
||||
|
||||
return;
|
||||
}
|
||||
CPlaceInner::Addr(ptr, None) => {
|
||||
if dst_layout.size == Size::ZERO || dst_layout.abi == Abi::Uninhabited {
|
||||
return;
|
||||
@@ -589,23 +613,33 @@ pub(crate) fn place_field(
|
||||
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
|
||||
field: mir::Field,
|
||||
) -> CPlace<'tcx> {
|
||||
// FIXME handle simd values
|
||||
|
||||
let layout = self.layout();
|
||||
if let CPlaceInner::VarPair(local, var1, var2) = self.inner {
|
||||
let layout = layout.field(&*fx, field.index());
|
||||
|
||||
match field.as_u32() {
|
||||
0 => return CPlace {
|
||||
inner: CPlaceInner::Var(local, var1),
|
||||
layout,
|
||||
},
|
||||
1 => return CPlace {
|
||||
inner: CPlaceInner::Var(local, var2),
|
||||
layout,
|
||||
},
|
||||
_ => unreachable!("field should be 0 or 1"),
|
||||
match self.inner {
|
||||
CPlaceInner::Var(local, var) => {
|
||||
if let Abi::Vector { .. } = layout.abi {
|
||||
return CPlace {
|
||||
inner: CPlaceInner::VarLane(local, var, field.as_u32().try_into().unwrap()),
|
||||
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
|
||||
};
|
||||
}
|
||||
}
|
||||
CPlaceInner::VarPair(local, var1, var2) => {
|
||||
let layout = layout.field(&*fx, field.index());
|
||||
|
||||
match field.as_u32() {
|
||||
0 => return CPlace {
|
||||
inner: CPlaceInner::Var(local, var1),
|
||||
layout,
|
||||
},
|
||||
1 => return CPlace {
|
||||
inner: CPlaceInner::Var(local, var2),
|
||||
layout,
|
||||
},
|
||||
_ => unreachable!("field should be 0 or 1"),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let (base, extra) = self.to_ptr_maybe_unsized();
|
||||
|
||||
Reference in New Issue
Block a user