Skip to content

Commit

Permalink
cranelift-interpreter: Fix panic when bitcasting SIMD values
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-justin committed May 15, 2023
1 parent a3a491c commit 8b9307b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
16 changes: 16 additions & 0 deletions cranelift/filetests/filetests/runtests/simd-bitcast.clif
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,19 @@ block0(v0: f64x2):
}
; run: %bitcast_fi64x2([0x0.0 -NaN:0x7ffffffffffff]) == [0 18446744073709551615]
; run: %bitcast_fi64x2([-NaN:0x7ffffffffffff 0x0.000000000007fp-1022]) == [-1 127]

function %bitcast_more_lanes(i64x2) -> i32x4 {
block0(v0: i64x2):
v1 = bitcast.i32x4 little v0
return v1
}
; run: %bitcast_more_lanes(0x00000000000000000000000000000000) == 0x00000000000000000000000000000000
; run: %bitcast_more_lanes(0x00000000000000ff00000000000000ff) == 0x00000000000000ff00000000000000ff

function %bitcast_fewer_lanes(i16x8) -> i64x2 {
block0(v0: i16x8):
v1 = bitcast.i64x2 little v0
return v1
}
; run: %bitcast_fewer_lanes(0x00000000000000000000000000000000) == 0x00000000000000000000000000000000
; run: %bitcast_fewer_lanes(0x00ff0000000000000000000000000000) == 0x00ff0000000000000000000000000000
20 changes: 15 additions & 5 deletions cranelift/interpreter/src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -904,11 +904,21 @@ where
Opcode::IsInvalid => unimplemented!("IsInvalid"),
Opcode::Bitcast | Opcode::ScalarToVector => {
let input_ty = inst_context.type_of(inst_context.args()[0]).unwrap();
let arg0 = extractlanes(&arg(0), input_ty)?;
let lanes = &arg0
.into_iter()
.map(|x| DataValue::convert(x, ValueConversionKind::Exact(ctrl_ty.lane_type())))
.collect::<ValueResult<SimdVec<DataValue>>>()?;
let out_lane_ty = ctrl_ty.lane_type();
let nr_in_lane_bytes = input_ty.lane_type().bytes() as usize;
let nr_out_lane_bytes = out_lane_ty.bytes() as usize;
let lanes = &if nr_in_lane_bytes == nr_out_lane_bytes {
extractlanes(&arg(0), input_ty)?
.into_iter()
.map(|lane| DataValue::convert(lane, ValueConversionKind::Exact(out_lane_ty)))
.collect::<ValueResult<SimdVec<DataValue>>>()?
} else {
arg(0)
.into_array()?
.chunks(nr_out_lane_bytes)
.map(|bytes| DataValue::read_from_slice_ne(&bytes, out_lane_ty))
.collect::<SimdVec<DataValue>>()
};
assign(match inst.opcode() {
Opcode::Bitcast => vectorizelanes(lanes, ctrl_ty)?,
Opcode::ScalarToVector => vectorizelanes_all(lanes, ctrl_ty)?,
Expand Down

0 comments on commit 8b9307b

Please sign in to comment.