Skip to content

Commit

Permalink
x64: Add {u,s}mulhi.i8 instruction support (#7866)
Browse files Browse the repository at this point in the history
  • Loading branch information
afonso360 committed Feb 3, 2024
1 parent c2fc362 commit c7a7b8c
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 22 deletions.
38 changes: 18 additions & 20 deletions cranelift/codegen/src/isa/x64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -4159,35 +4159,33 @@

;; Rules for `umulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (umulhi a @ (value_type $I16) b))
(let ((res ValueRegs (mul_hi $I16 $false a b))
(hi Gpr (value_regs_get_gpr res 1)))
hi))

(rule (lower (umulhi a @ (value_type $I32) b))
(let ((res ValueRegs (mul_hi $I32 $false a b))
(hi Gpr (value_regs_get_gpr res 1)))
;; The umulhi instruction is not available for 8-bit types, so we can extend
;; the inputs, use the 16-bit multiply and shift the result down.
(rule 1 (lower (umulhi a @ (value_type $I8) b))
(let ((a_ext Gpr (extend_to_gpr a $I16 (ExtendKind.Zero)))
(b_ext Gpr (extend_to_gpr b $I16 (ExtendKind.Zero)))
(mul Gpr (x64_mul $I16 a_ext b_ext))
(hi Gpr (x64_shr $I64 mul (imm8_to_imm8_gpr 8))))
hi))

(rule (lower (umulhi a @ (value_type $I64) b))
(let ((res ValueRegs (mul_hi $I64 $false a b))
(rule 0 (lower (umulhi a @ (value_type ty) b))
(let ((res ValueRegs (mul_hi ty $false a b))
(hi Gpr (value_regs_get_gpr res 1)))
hi))

;; Rules for `smulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (smulhi a @ (value_type $I16) b))
(let ((res ValueRegs (mul_hi $I16 $true a b))
(hi Gpr (value_regs_get_gpr res 1)))
hi))

(rule (lower (smulhi a @ (value_type $I32) b))
(let ((res ValueRegs (mul_hi $I32 $true a b))
(hi Gpr (value_regs_get_gpr res 1)))
;; The smulhi instruction is not available for 8-bit types, so we can extend
;; the inputs, use the 16-bit multiply and shift the result down.
(rule 1 (lower (smulhi a @ (value_type $I8) b))
(let ((a_ext Gpr (extend_to_gpr a $I16 (ExtendKind.Sign)))
(b_ext Gpr (extend_to_gpr b $I16 (ExtendKind.Sign)))
(mul Gpr (x64_mul $I16 a_ext b_ext))
(hi Gpr (x64_sar $I64 mul (imm8_to_imm8_gpr 8))))
hi))

(rule (lower (smulhi a @ (value_type $I64) b))
(let ((res ValueRegs (mul_hi $I64 $true a b))
(rule 0 (lower (smulhi a @ (value_type ty) b))
(let ((res ValueRegs (mul_hi ty $true a b))
(hi Gpr (value_regs_get_gpr res 1)))
hi))

Expand Down
31 changes: 31 additions & 0 deletions cranelift/filetests/filetests/isa/x64/smulhi.clif
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
test compile precise-output
target x86_64

function %smulhi_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = smulhi v0, v1
return v2
}

; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; movsbl %dil, %eax
; movsbl %sil, %r8d
; imull %eax, %r8d, %eax
; sarq $8, %rax, %rax
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; movsbl %dil, %eax
; movsbl %sil, %r8d
; imull %r8d, %eax
; sarq $8, %rax
; movq %rbp, %rsp
; popq %rbp
; retq

function %f1(i16, i16) -> i16 {
block0(v0: i16, v1: i16):
v2 = smulhi v0, v1
Expand Down
31 changes: 31 additions & 0 deletions cranelift/filetests/filetests/isa/x64/umulhi.clif
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
test compile precise-output
target x86_64

function %umulhi_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = umulhi v0, v1
return v2
}

; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; movzbl %dil, %eax
; movzbl %sil, %r8d
; imull %eax, %r8d, %eax
; shrq $8, %rax, %rax
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; movzbl %dil, %eax
; movzbl %sil, %r8d
; imull %r8d, %eax
; shrq $8, %rax
; movq %rbp, %rsp
; popq %rbp
; retq

function %f1(i16, i16) -> i16 {
block0(v0: i16, v1: i16):
v2 = umulhi v0, v1
Expand Down
9 changes: 9 additions & 0 deletions cranelift/filetests/filetests/runtests/smulhi.clif
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ target riscv64
target riscv64 has_c has_zcb


function %smulhi_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = smulhi v0, v1
return v2
}
; run: %smulhi_i8(-2, -4) == 0
; run: %smulhi_i8(2, -4) == -1
; run: %smulhi_i8(255, 255) == 0

function %smulhi_i16(i16, i16) -> i16 {
block0(v0: i16, v1: i16):
v2 = smulhi v0, v1
Expand Down
8 changes: 8 additions & 0 deletions cranelift/filetests/filetests/runtests/umulhi.clif
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ target s390x
target riscv64
target riscv64 has_c has_zcb

function %umulhi_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = umulhi v0, v1
return v2
}
; run: %umulhi_i8(2, 4) == 0
; run: %umulhi_i8(255, 255) == 254

function %umulhi_i16(i16, i16) -> i16 {
block0(v0: i16, v1: i16):
v2 = umulhi v0, v1
Expand Down
2 changes: 0 additions & 2 deletions cranelift/fuzzgen/src/function_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,6 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
rets,
(Opcode::UmulOverflow | Opcode::SmulOverflow, &[I128, I128]),
(Opcode::Imul, &[I8X16, I8X16]),
// https://github.com/bytecodealliance/wasmtime/issues/5468
(Opcode::Smulhi | Opcode::Umulhi, &[I8, I8]),
// https://github.com/bytecodealliance/wasmtime/issues/4756
(Opcode::Udiv | Opcode::Sdiv, &[I128, I128]),
// https://github.com/bytecodealliance/wasmtime/issues/5474
Expand Down

0 comments on commit c7a7b8c

Please sign in to comment.