cranelift-interpreter: Fix incorrect scalar_to_vector result (#6133)
* The `vectorizelanes` function performs a check to see whether there is a single value provided in an array, and if so returns it as a scalar. While elsewhere in the interpreter this behaviour is relied upon, it yields an incorrect result when attempting to convert a scalar to a vector. The original `vectorizelanes` remains untouched, however, an unconditional variant `vectorizelanes_all` was added. * A test was added under `filetests/runtests/issue5911.clif`. Fixes #5911
This commit is contained in:
committed by
GitHub
parent
c85bf27ff8
commit
c475735f5e
@@ -1,4 +1,5 @@
|
|||||||
test run
|
test run
|
||||||
|
test interpret
|
||||||
target aarch64
|
target aarch64
|
||||||
target s390x
|
target s390x
|
||||||
; i8 and i16 are invalid source sizes for x86_64
|
; i8 and i16 are invalid source sizes for x86_64
|
||||||
@@ -16,5 +17,6 @@ block0(v0: i16):
|
|||||||
v1 = scalar_to_vector.i16x8 v0
|
v1 = scalar_to_vector.i16x8 v0
|
||||||
return v1
|
return v1
|
||||||
}
|
}
|
||||||
|
; run: %scalartovector_i16(0) == [0 0 0 0 0 0 0 0]
|
||||||
; run: %scalartovector_i16(1) == [1 0 0 0 0 0 0 0]
|
; run: %scalartovector_i16(1) == [1 0 0 0 0 0 0 0]
|
||||||
; run: %scalartovector_i16(65535) == [65535 0 0 0 0 0 0 0]
|
; run: %scalartovector_i16(65535) == [65535 0 0 0 0 0 0 0]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
test run
|
test run
|
||||||
|
test interpret
|
||||||
target aarch64
|
target aarch64
|
||||||
target s390x
|
target s390x
|
||||||
set enable_simd
|
set enable_simd
|
||||||
@@ -18,6 +19,7 @@ block0(v0: i64):
|
|||||||
v1 = scalar_to_vector.i64x2 v0
|
v1 = scalar_to_vector.i64x2 v0
|
||||||
return v1
|
return v1
|
||||||
}
|
}
|
||||||
|
; run: %scalartovector_i64(0) == [0 0]
|
||||||
; run: %scalartovector_i64(1) == [1 0]
|
; run: %scalartovector_i64(1) == [1 0]
|
||||||
; run: %scalartovector_i64(18446744073709551615) == [18446744073709551615 0]
|
; run: %scalartovector_i64(18446744073709551615) == [18446744073709551615 0]
|
||||||
|
|
||||||
|
|||||||
@@ -934,14 +934,15 @@ where
|
|||||||
Opcode::Bitcast | Opcode::ScalarToVector => {
|
Opcode::Bitcast | Opcode::ScalarToVector => {
|
||||||
let input_ty = inst_context.type_of(inst_context.args()[0]).unwrap();
|
let input_ty = inst_context.type_of(inst_context.args()[0]).unwrap();
|
||||||
let arg0 = extractlanes(&arg(0)?, input_ty)?;
|
let arg0 = extractlanes(&arg(0)?, input_ty)?;
|
||||||
|
let lanes = &arg0
|
||||||
assign(vectorizelanes(
|
|
||||||
&arg0
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| V::convert(x, ValueConversionKind::Exact(ctrl_ty.lane_type())))
|
.map(|x| V::convert(x, ValueConversionKind::Exact(ctrl_ty.lane_type())))
|
||||||
.collect::<ValueResult<SimdVec<V>>>()?,
|
.collect::<ValueResult<SimdVec<V>>>()?;
|
||||||
ctrl_ty,
|
assign(match inst.opcode() {
|
||||||
)?)
|
Opcode::Bitcast => vectorizelanes(lanes, ctrl_ty)?,
|
||||||
|
Opcode::ScalarToVector => vectorizelanes_all(lanes, ctrl_ty)?,
|
||||||
|
_ => unreachable!(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Opcode::Ireduce => assign(Value::convert(
|
Opcode::Ireduce => assign(Value::convert(
|
||||||
arg(0)?,
|
arg(0)?,
|
||||||
@@ -1552,9 +1553,17 @@ where
|
|||||||
{
|
{
|
||||||
// If the array is only one element, return it as a scalar.
|
// If the array is only one element, return it as a scalar.
|
||||||
if x.len() == 1 {
|
if x.len() == 1 {
|
||||||
return Ok(x[0].clone());
|
Ok(x[0].clone())
|
||||||
|
} else {
|
||||||
|
vectorizelanes_all(x, vector_type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a Rust array of [Value] back into a `Value::vector`.
|
||||||
|
fn vectorizelanes_all<V>(x: &[V], vector_type: types::Type) -> ValueResult<V>
|
||||||
|
where
|
||||||
|
V: Value,
|
||||||
|
{
|
||||||
let lane_type = vector_type.lane_type();
|
let lane_type = vector_type.lane_type();
|
||||||
let iterations = match lane_type {
|
let iterations = match lane_type {
|
||||||
types::I8 => 1,
|
types::I8 => 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user