cranelift: Fix shift overflow when constructing BitSet (#6020)

* Fix shift overflow when constructing the Wider constraint for integers

* Clarify comment
This commit is contained in:
Trevor Elliott
2023-03-14 15:25:51 -07:00
committed by GitHub
parent 48ecb6f119
commit 68b937d965
2 changed files with 23 additions and 12 deletions

View File

@@ -779,11 +779,11 @@ impl OperandConstraint {
if ctrl_type.is_int() {
// The upper bound in from_range is exclusive, and we want to exclude the
// control type to construct the interval of [I8, ctrl_type).
tys.ints = BitSet::from_range(3, ctrl_type_bits as u8);
tys.ints = BitSet8::from_range(3, ctrl_type_bits as u8);
} else if ctrl_type.is_float() {
// The upper bound in from_range is exclusive, and we want to exclude the
// control type to construct the interval of [F32, ctrl_type).
tys.floats = BitSet::from_range(5, ctrl_type_bits as u8);
tys.floats = BitSet8::from_range(5, ctrl_type_bits as u8);
} else {
panic!("The Narrower constraint only operates on floats or ints");
}
@@ -797,15 +797,23 @@ impl OperandConstraint {
tys.lanes = BitSet::from_range(0, 1);
if ctrl_type.is_int() {
// The interval should include all types wider than `ctrl_type`, so we use
// `2^8` as the upper bound, and add one to the bits of `ctrl_type` to define
// the interval `(ctrl_type, I128]`.
tys.ints = BitSet::from_range(ctrl_type_bits as u8 + 1, 8);
let lower_bound = ctrl_type_bits as u8 + 1;
// The largest integer type we can represent in `BitSet8` is I128, which is
// represented by bit 7 in the bit set. Adding one to exclude I128 from the
// lower bound would overflow as 2^8 doesn't fit in a u8, but this would
// already describe the empty set so instead we leave `ints` in its default
// empty state.
if lower_bound < BitSet8::bits() as u8 {
// The interval should include all types wider than `ctrl_type`, so we use
// `2^8` as the upper bound, and add one to the bits of `ctrl_type` to define
// the interval `(ctrl_type, I128]`.
tys.ints = BitSet8::from_range(lower_bound, 8);
}
} else if ctrl_type.is_float() {
// The interval should include all float types wider than `ctrl_type`, so we
// use `2^7` as the upper bound, and add one to the bits of `ctrl_type` to
// define the interval `(ctrl_type, F64]`.
tys.floats = BitSet::from_range(ctrl_type_bits as u8 + 1, 7);
tys.floats = BitSet8::from_range(ctrl_type_bits as u8 + 1, 7);
} else {
panic!("The Wider constraint only operates on floats or ints");
}

View File

@@ -110,11 +110,12 @@ block2(v3: f32, v4: i8):
return
}
function %bad_extend() {
block0:
v0 = iconst.i32 10
v1 = uextend.i16 v0 ; error: arg 0 (v0) with type i32 failed to satisfy type set
v2 = uextend.i32 v0 ; error: arg 0 (v0) with type i32 failed to satisfy type set
function %bad_extend(i128) {
block0(v0: i128):
v1 = iconst.i32 10
v2 = uextend.i16 v1 ; error: arg 0 (v1) with type i32 failed to satisfy type set
v3 = uextend.i32 v1 ; error: arg 0 (v1) with type i32 failed to satisfy type set
v4 = uextend.i128 v0 ; error: arg 0 (v0) with type i128 failed to satisfy type set
return
}
@@ -123,6 +124,8 @@ block0:
v0 = iconst.i32 10
v1 = ireduce.i32 v0 ; error: arg 0 (v0) with type i32 failed to satisfy type set
v2 = ireduce.i64 v0 ; error: arg 0 (v0) with type i32 failed to satisfy type set
v4 = iconst.i8 10
v5 = ireduce.i64 v4 ; error: arg 0 (v4) with type i8 failed to satisfy type set
return
}