diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2020-03-28 15:21:58 +0100 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2020-07-25 12:28:24 +0200 |
| commit | 08fc673190ef43b111a6fea2fadf7de25bf7f282 (patch) | |
| tree | 884379f06ea492bbc2b43f7df30be4e3422a73ba /src | |
| parent | abc99c62595831127e8ac4dfd6ccacd7ccbf9942 (diff) | |
| download | rust-08fc673190ef43b111a6fea2fadf7de25bf7f282.tar.gz rust-08fc673190ef43b111a6fea2fadf7de25bf7f282.zip | |
Handle SIMD vectors in CPlace::place_field
Diffstat (limited to 'src')
| -rw-r--r-- | src/abi/comments.rs | 1 | ||||
| -rw-r--r-- | src/debuginfo/mod.rs | 5 | ||||
| -rw-r--r-- | src/value_and_place.rs | 66 |
3 files changed, 56 insertions, 16 deletions
diff --git a/src/abi/comments.rs b/src/abi/comments.rs index 7c4d7b12f6e..357c28c832a 100644 --- a/src/abi/comments.rs +++ b/src/abi/comments.rs @@ -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)) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 37dc9f4e3c5..2c92fd0e47c 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -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) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 477a417639e..d0e8a4b0c9f 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -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 @@ impl<'tcx> CPlace<'tcx> { 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 @@ impl<'tcx> CPlace<'tcx> { 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 @@ impl<'tcx> CPlace<'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 @@ impl<'tcx> CPlace<'tcx> { 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(); |
