Fix some 16- and 8-bit behavior in x64 backend related to rotates.
Uncovered by @bjorn3 (thanks!): 8- and 16-bit rotates were not working properly in recent versions of Cranelift with part of the lowering migrated to ISLE. This PR fixes a few issues: - 8- and 16-bit rotate-left needs to mask a constant amount, if any, because we use a 32-bit rotate instruction and so don't get the appropriate shift-amount masking for free from x86 semantics. - `operand_size_from_type` was incorrect: it only handled 32- and 64-bit types and silently returned `OperandSize::Size32` for everything else. Now uses the `OperandSize::from_ty(ty)` helper as the pre-ISLE code did. Our test coverage for narrow value types is not great; this PR adds some runtests for rotl/rotr but more would always be better!
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
src/clif.isle be1359b4b6b153f378517c1dd95cd80f4a6bed0c7b86eaba11c088fd71b7bfe80a3c868ace245b2da0bfbbd6ded262ea9576c8e0eeacbf89d03c34a17a709602
|
||||
src/prelude.isle d3d2a6a42fb778231a4cdca30995324e1293a9ca8073c5a27a501535759eb51f84a6718322a93dfba4b66ee4f0c9afce7dcec0428516ef0c5bc96e8c8b76925d
|
||||
src/prelude.isle 75a46b97817ad6a4c34e618b81e60876eec6fd1c83ac3ee174851e42045c951644663b2cbc31f1749ce2bc3ad9eb94fb0b877eb2c3bc4885cab7d7e87e9df1d6
|
||||
src/isa/aarch64/inst.isle 8e4b8e452cf06a368c2e1d930042027a5d3bd690ab46d498d959257e9b4461d17abf244838395cd80da1fe5e2e86fc43855fb5753ca4f1643538c2ae4b3b4a1e
|
||||
src/isa/aarch64/lower.isle bc3db9c1e6ac186b918cc04f4d26af398f99ec36c8cdc20ec4d02d18dd57dba12e3184fea031b4ac97051c5e194a69666afb5e204807c818e6688c177f9c1b91
|
||||
|
||||
@@ -34,6 +34,8 @@ pub trait Context {
|
||||
fn ty_bits_u16(&mut self, arg0: Type) -> u16;
|
||||
fn fits_in_32(&mut self, arg0: Type) -> Option<Type>;
|
||||
fn fits_in_64(&mut self, arg0: Type) -> Option<Type>;
|
||||
fn ty_32_or_64(&mut self, arg0: Type) -> Option<Type>;
|
||||
fn ty_8_or_16(&mut self, arg0: Type) -> Option<Type>;
|
||||
fn vec128(&mut self, arg0: Type) -> Option<Type>;
|
||||
fn not_i64x2(&mut self, arg0: Type) -> Option<()>;
|
||||
fn value_list_slice(&mut self, arg0: ValueList) -> ValueSlice;
|
||||
@@ -49,6 +51,7 @@ pub trait Context {
|
||||
fn first_result(&mut self, arg0: Inst) -> Option<Value>;
|
||||
fn inst_data(&mut self, arg0: Inst) -> InstructionData;
|
||||
fn value_type(&mut self, arg0: Value) -> Type;
|
||||
fn ty_bits_mask(&mut self, arg0: Type) -> u64;
|
||||
fn multi_lane(&mut self, arg0: Type) -> Option<(u8, u16)>;
|
||||
fn def_inst(&mut self, arg0: Value) -> Option<Inst>;
|
||||
fn trap_code_division_by_zero(&mut self) -> TrapCode;
|
||||
@@ -79,13 +82,13 @@ pub trait Context {
|
||||
fn safe_divisor_from_imm64(&mut self, arg0: Imm64) -> Option<u64>;
|
||||
}
|
||||
|
||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 246.
|
||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 259.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ProducesFlags {
|
||||
ProducesFlags { inst: MInst, result: Reg },
|
||||
}
|
||||
|
||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 249.
|
||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 262.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ConsumesFlags {
|
||||
ConsumesFlags { inst: MInst, result: Reg },
|
||||
@@ -999,7 +1002,7 @@ pub fn constructor_with_flags<C: Context>(
|
||||
result: pattern3_1,
|
||||
} = pattern2_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 259.
|
||||
// Rule at src/prelude.isle line 272.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
||||
@@ -1027,7 +1030,7 @@ pub fn constructor_with_flags_1<C: Context>(
|
||||
result: pattern3_1,
|
||||
} = pattern2_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 267.
|
||||
// Rule at src/prelude.isle line 280.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
return Some(pattern3_1);
|
||||
@@ -1061,7 +1064,7 @@ pub fn constructor_with_flags_2<C: Context>(
|
||||
result: pattern5_1,
|
||||
} = pattern4_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 277.
|
||||
// Rule at src/prelude.isle line 290.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
let expr2_0 = C::emit(ctx, &pattern5_0);
|
||||
|
||||
Reference in New Issue
Block a user