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:
@@ -779,11 +779,11 @@ impl OperandConstraint {
|
|||||||
if ctrl_type.is_int() {
|
if ctrl_type.is_int() {
|
||||||
// The upper bound in from_range is exclusive, and we want to exclude the
|
// The upper bound in from_range is exclusive, and we want to exclude the
|
||||||
// control type to construct the interval of [I8, ctrl_type).
|
// 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() {
|
} else if ctrl_type.is_float() {
|
||||||
// The upper bound in from_range is exclusive, and we want to exclude the
|
// The upper bound in from_range is exclusive, and we want to exclude the
|
||||||
// control type to construct the interval of [F32, ctrl_type).
|
// 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 {
|
} else {
|
||||||
panic!("The Narrower constraint only operates on floats or ints");
|
panic!("The Narrower constraint only operates on floats or ints");
|
||||||
}
|
}
|
||||||
@@ -797,15 +797,23 @@ impl OperandConstraint {
|
|||||||
tys.lanes = BitSet::from_range(0, 1);
|
tys.lanes = BitSet::from_range(0, 1);
|
||||||
|
|
||||||
if ctrl_type.is_int() {
|
if ctrl_type.is_int() {
|
||||||
// The interval should include all types wider than `ctrl_type`, so we use
|
let lower_bound = ctrl_type_bits as u8 + 1;
|
||||||
// `2^8` as the upper bound, and add one to the bits of `ctrl_type` to define
|
// The largest integer type we can represent in `BitSet8` is I128, which is
|
||||||
// the interval `(ctrl_type, I128]`.
|
// represented by bit 7 in the bit set. Adding one to exclude I128 from the
|
||||||
tys.ints = BitSet::from_range(ctrl_type_bits as u8 + 1, 8);
|
// 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() {
|
} else if ctrl_type.is_float() {
|
||||||
// The interval should include all float types wider than `ctrl_type`, so we
|
// 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
|
// use `2^7` as the upper bound, and add one to the bits of `ctrl_type` to
|
||||||
// define the interval `(ctrl_type, F64]`.
|
// 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 {
|
} else {
|
||||||
panic!("The Wider constraint only operates on floats or ints");
|
panic!("The Wider constraint only operates on floats or ints");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,11 +110,12 @@ block2(v3: f32, v4: i8):
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
function %bad_extend() {
|
function %bad_extend(i128) {
|
||||||
block0:
|
block0(v0: i128):
|
||||||
v0 = iconst.i32 10
|
v1 = iconst.i32 10
|
||||||
v1 = uextend.i16 v0 ; error: arg 0 (v0) with type i32 failed to satisfy type set
|
v2 = uextend.i16 v1 ; error: arg 0 (v1) with type i32 failed to satisfy type set
|
||||||
v2 = uextend.i32 v0 ; error: arg 0 (v0) 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +124,8 @@ block0:
|
|||||||
v0 = iconst.i32 10
|
v0 = iconst.i32 10
|
||||||
v1 = ireduce.i32 v0 ; error: arg 0 (v0) with type i32 failed to satisfy type set
|
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
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user