diff --git a/cranelift/codegen/src/ir/instructions.rs b/cranelift/codegen/src/ir/instructions.rs index 36e343db57..014828170b 100644 --- a/cranelift/codegen/src/ir/instructions.rs +++ b/cranelift/codegen/src/ir/instructions.rs @@ -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"); } diff --git a/cranelift/filetests/filetests/verifier/type_check.clif b/cranelift/filetests/filetests/verifier/type_check.clif index 41ded268c3..bbd737ca34 100644 --- a/cranelift/filetests/filetests/verifier/type_check.clif +++ b/cranelift/filetests/filetests/verifier/type_check.clif @@ -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 }