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:
@@ -318,3 +318,25 @@ block0(v0: i32, v1: i8):
|
||||
; run: %sshr_i32_i8(0x40000000, 32) == 0x40000000
|
||||
; run: %sshr_i32_i8(0x40000000, 33) == 0x20000000
|
||||
; run: %sshr_i32_i8(0x40000000, 34) == 0x10000000
|
||||
|
||||
function %rotl_i8_const_37(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = iconst.i8 37
|
||||
v2 = rotl.i8 v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; run: %rotl_i8_const_37(0x00) == 0x00
|
||||
; run: %rotl_i8_const_37(0x01) == 0x20
|
||||
; run: %rotl_i8_const_37(0x12) == 0x42
|
||||
|
||||
function %rotr_i8_const_37(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = iconst.i8 37
|
||||
v2 = rotr.i8 v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; run: %rotr_i8_const_37(0x00) == 0x00
|
||||
; run: %rotr_i8_const_37(0x01) == 0x08
|
||||
; run: %rotr_i8_const_37(0x12) == 0x90
|
||||
|
||||
Reference in New Issue
Block a user