Skip to content

Commit 64ca38e

Browse files
committed
Make it possible it use value_field for SIMD values stored ByVal
1 parent 68eb232 commit 64ca38e

File tree

2 files changed

+31
-33
lines changed

2 files changed

+31
-33
lines changed

src/intrinsics/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ macro simd_int_binop {
272272
},
273273
($fx:expr, $op_u:ident|$op_s:ident($x:ident, $y:ident) -> $ret:ident) => {
274274
let (lane_layout, lane_count) = lane_type_and_count($fx.tcx, $x.layout());
275-
let x_val = $x.load_vector($fx);
276-
let y_val = $y.load_vector($fx);
275+
let x_val = $x.load_scalar($fx);
276+
let y_val = $y.load_scalar($fx);
277277

278278
let res = match lane_layout.ty.kind {
279279
ty::Uint(_) => $fx.bcx.ins().$op_u(x_val, y_val),
@@ -290,8 +290,8 @@ macro simd_int_flt_binop {
290290
},
291291
($fx:expr, $op_u:ident|$op_s:ident|$op_f:ident($x:ident, $y:ident) -> $ret:ident) => {
292292
let (lane_layout, lane_count) = lane_type_and_count($fx.tcx, $x.layout());
293-
let x_val = $x.load_vector($fx);
294-
let y_val = $y.load_vector($fx);
293+
let x_val = $x.load_scalar($fx);
294+
let y_val = $y.load_scalar($fx);
295295

296296
let res = match lane_layout.ty.kind {
297297
ty::Uint(_) => $fx.bcx.ins().$op_u(x_val, y_val),
@@ -305,8 +305,8 @@ macro simd_int_flt_binop {
305305

306306
macro simd_flt_binop($fx:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) {
307307
let (lane_layout, lane_count) = lane_type_and_count($fx.tcx, $x.layout());
308-
let x_val = $x.load_vector($fx);
309-
let y_val = $y.load_vector($fx);
308+
let x_val = $x.load_scalar($fx);
309+
let y_val = $y.load_scalar($fx);
310310

311311
let res = match lane_layout.ty.kind {
312312
ty::Float(_) => $fx.bcx.ins().$op(x_val, y_val),

src/value_and_place.rs

+25-27
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,14 @@ impl<'tcx> CValue<'tcx> {
122122
let layout = self.1;
123123
match self.0 {
124124
CValueInner::ByRef(ptr) => {
125-
let scalar = match layout.abi {
126-
layout::Abi::Scalar(ref scalar) => scalar.clone(),
125+
let clif_ty = match layout.abi {
126+
layout::Abi::Scalar(ref scalar) => scalar_to_clif_type(fx.tcx, scalar.clone()),
127+
layout::Abi::Vector { ref element, count } => {
128+
scalar_to_clif_type(fx.tcx, element.clone())
129+
.by(u16::try_from(count).unwrap()).unwrap()
130+
}
127131
_ => unreachable!(),
128132
};
129-
let clif_ty = scalar_to_clif_type(fx.tcx, scalar);
130133
ptr.load(fx, clif_ty, MemFlags::new())
131134
}
132135
CValueInner::ByVal(value) => value,
@@ -158,37 +161,32 @@ impl<'tcx> CValue<'tcx> {
158161
}
159162
}
160163

161-
/// Load a value with layout.abi of vector
162-
pub fn load_vector<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> Value {
163-
let layout = self.1;
164-
match self.0 {
165-
CValueInner::ByRef(ptr) => {
166-
let clif_ty = match layout.abi {
167-
layout::Abi::Vector { ref element, count } => {
168-
scalar_to_clif_type(fx.tcx, element.clone()).by(u16::try_from(count).unwrap()).unwrap()
169-
}
170-
_ => unreachable!(),
171-
};
172-
ptr.load(fx, clif_ty, MemFlags::new())
173-
}
174-
CValueInner::ByVal(value) => value,
175-
CValueInner::ByValPair(_, _) => bug!("Please use load_scalar_pair for ByValPair"),
176-
}
177-
}
178-
179164
pub fn value_field<'a>(
180165
self,
181166
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
182167
field: mir::Field,
183168
) -> CValue<'tcx> {
184169
let layout = self.1;
185-
let ptr = match self.0 {
186-
CValueInner::ByRef(ptr) => ptr,
170+
match self.0 {
171+
CValueInner::ByVal(val) => {
172+
match layout.abi {
173+
layout::Abi::Vector { element: _, count } => {
174+
let count = u8::try_from(count).expect("SIMD type with more than 255 lanes???");
175+
let field = u8::try_from(field.index()).unwrap();
176+
assert!(field < count);
177+
let lane = fx.bcx.ins().extractlane(val, field);
178+
let field_layout = layout.field(&*fx, usize::from(field));
179+
CValue::by_val(lane, field_layout)
180+
}
181+
_ => unreachable!("value_field for ByVal with abi {:?}", layout.abi),
182+
}
183+
}
184+
CValueInner::ByRef(ptr) => {
185+
let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
186+
CValue::by_ref(field_ptr, field_layout)
187+
}
187188
_ => bug!("place_field for {:?}", self),
188-
};
189-
190-
let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
191-
CValue::by_ref(field_ptr, field_layout)
189+
}
192190
}
193191

194192
pub fn unsize_value<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {

0 commit comments

Comments
 (0)