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:
@@ -95,6 +95,11 @@ macro_rules! isle_prelude_methods {
|
||||
ty.bits().try_into().unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ty_bits_mask(&mut self, ty: Type) -> u64 {
|
||||
(1 << (self.ty_bits(ty) as u64)) - 1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ty_bits_u16(&mut self, ty: Type) -> u16 {
|
||||
ty.bits()
|
||||
@@ -118,6 +123,24 @@ macro_rules! isle_prelude_methods {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ty_32_or_64(&mut self, ty: Type) -> Option<Type> {
|
||||
if ty.bits() == 32 || ty.bits() == 64 {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ty_8_or_16(&mut self, ty: Type) -> Option<Type> {
|
||||
if ty.bits() == 8 || ty.bits() == 16 {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn vec128(&mut self, ty: Type) -> Option<Type> {
|
||||
if ty.is_vector() && ty.bits() == 128 {
|
||||
Some(ty)
|
||||
|
||||
Reference in New Issue
Block a user