Skip to content

Commit

Permalink
riscv64: Improve scalar_to_vector for constants (#7284)
Browse files Browse the repository at this point in the history
* riscv: Add rule for vmerge.vim

Additionally add an imm5_from_value extractor. Closes #7189

* riscv: Add tests for vmerge.vim

Closes #7189

* riscv: format tests

* riscv: format scalar_to_vector rule

* riscv: add runtests and rm duplicate definition
  • Loading branch information
BieVic authored Oct 19, 2023
1 parent dd42290 commit 70039d8
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 5 deletions.
6 changes: 5 additions & 1 deletion cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1888,9 +1888,13 @@
(decl pure partial i8_to_imm5 (i8) Imm5)
(extern constructor i8_to_imm5 i8_to_imm5)

;; Helper to go directly from a `Value` to an `Imm5`.
(decl imm5_from_value (Imm5) Value)
(extractor (imm5_from_value n) (i64_from_iconst (imm5_from_i64 n)))

;; Constructor that matches a `Value` equivalent to a replicated Imm5 on all lanes.
(decl pure partial replicated_imm5 (Value) Imm5)
(rule (replicated_imm5 (splat (i64_from_iconst (imm5_from_i64 n)))) n)
(rule (replicated_imm5 (splat (imm5_from_value n))) n)
(rule (replicated_imm5 (vconst (u128_from_constant n128)))
(if-let (u128_replicated_u64 n64) n128)
(if-let (u64_replicated_u32 n32) n64)
Expand Down
13 changes: 9 additions & 4 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -2700,18 +2700,23 @@

;;;; Rules for `scalar_to_vector` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule 0 (lower (has_type (ty_vec_fits_in_register ty) (scalar_to_vector x)))
(if (ty_vector_float ty))
(let ((zero VReg (rv_vmv_vx (zero_reg) ty))
(elem VReg (rv_vfmv_sf x ty))
(mask VReg (gen_vec_mask 1)))
(rv_vmerge_vvm zero elem mask ty)))

(rule 1 (lower (has_type (ty_vec_fits_in_register ty) (scalar_to_vector x)))
(if (ty_vector_not_float ty))
(let ((zero VReg (rv_vmv_vx (zero_reg) ty))
(mask VReg (gen_vec_mask 1)))
(rv_vmerge_vxm zero x mask ty)))

(rule 0 (lower (has_type (ty_vec_fits_in_register ty) (scalar_to_vector x)))
(if (ty_vector_float ty))
(rule 2 (lower (has_type (ty_vec_fits_in_register ty) (scalar_to_vector (imm5_from_value x))))
(let ((zero VReg (rv_vmv_vx (zero_reg) ty))
(elem VReg (rv_vfmv_sf x ty))
(mask VReg (gen_vec_mask 1)))
(rv_vmerge_vvm zero elem mask ty)))
(rv_vmerge_vim zero x mask ty)))

;;;; Rules for `sqmul_round_sat` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
105 changes: 105 additions & 0 deletions cranelift/filetests/filetests/isa/riscv64/simd-scalartovector.clif
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,108 @@ block0(v0: f64):
; .byte 0xa7, 0x04, 0x05, 0x02
; ret

function %scalartovector_i8_imm(i8) -> i8x16 {
block0(v0: i8):
v1 = iconst.i8 7
v2 = scalar_to_vector.i8x16 v1
return v2
}

; VCode:
; block0:
; vmv.v.x v11,zero #avl=16, #vtype=(e8, m1, ta, ma)
; vmv.v.i v0,1 #avl=2, #vtype=(e64, m1, ta, ma)
; vmerge.vim v15,v11,7,v0.t #avl=16, #vtype=(e8, m1, ta, ma)
; vse8.v v15,0(a1) #avl=16, #vtype=(e8, m1, ta, ma)
; ret
;
; Disassembled:
; block0: ; offset 0x0
; .byte 0x57, 0x70, 0x08, 0xcc
; .byte 0xd7, 0x45, 0x00, 0x5e
; .byte 0x57, 0x70, 0x81, 0xcd
; .byte 0x57, 0xb0, 0x00, 0x5e
; .byte 0x57, 0x70, 0x08, 0xcc
; .byte 0xd7, 0xb7, 0xb3, 0x5c
; .byte 0xa7, 0x87, 0x05, 0x02
; ret

function %scalartovector_i16_imm(i16) -> i16x8 {
block0(v0: i16):
v1 = iconst.i16 7
v2 = scalar_to_vector.i16x8 v1
return v2
}

; VCode:
; block0:
; vmv.v.x v11,zero #avl=8, #vtype=(e16, m1, ta, ma)
; vmv.v.i v0,1 #avl=2, #vtype=(e64, m1, ta, ma)
; vmerge.vim v15,v11,7,v0.t #avl=8, #vtype=(e16, m1, ta, ma)
; vse8.v v15,0(a1) #avl=16, #vtype=(e8, m1, ta, ma)
; ret
;
; Disassembled:
; block0: ; offset 0x0
; .byte 0x57, 0x70, 0x84, 0xcc
; .byte 0xd7, 0x45, 0x00, 0x5e
; .byte 0x57, 0x70, 0x81, 0xcd
; .byte 0x57, 0xb0, 0x00, 0x5e
; .byte 0x57, 0x70, 0x84, 0xcc
; .byte 0xd7, 0xb7, 0xb3, 0x5c
; .byte 0x57, 0x70, 0x08, 0xcc
; .byte 0xa7, 0x87, 0x05, 0x02
; ret

function %scalartovector_i32_imm(i32) -> i32x4 {
block0(v0: i32):
v1 = iconst.i32 7
v2 = scalar_to_vector.i32x4 v1
return v2
}

; VCode:
; block0:
; vmv.v.x v11,zero #avl=4, #vtype=(e32, m1, ta, ma)
; vmv.v.i v0,1 #avl=2, #vtype=(e64, m1, ta, ma)
; vmerge.vim v15,v11,7,v0.t #avl=4, #vtype=(e32, m1, ta, ma)
; vse8.v v15,0(a1) #avl=16, #vtype=(e8, m1, ta, ma)
; ret
;
; Disassembled:
; block0: ; offset 0x0
; .byte 0x57, 0x70, 0x02, 0xcd
; .byte 0xd7, 0x45, 0x00, 0x5e
; .byte 0x57, 0x70, 0x81, 0xcd
; .byte 0x57, 0xb0, 0x00, 0x5e
; .byte 0x57, 0x70, 0x02, 0xcd
; .byte 0xd7, 0xb7, 0xb3, 0x5c
; .byte 0x57, 0x70, 0x08, 0xcc
; .byte 0xa7, 0x87, 0x05, 0x02
; ret

function %scalartovector_i64_imm(i64) -> i64x2 {
block0(v0: i64):
v1 = iconst.i64 7
v2 = scalar_to_vector.i64x2 v1
return v2
}

; VCode:
; block0:
; vmv.v.x v11,zero #avl=2, #vtype=(e64, m1, ta, ma)
; vmv.v.i v0,1 #avl=2, #vtype=(e64, m1, ta, ma)
; vmerge.vim v15,v11,7,v0.t #avl=2, #vtype=(e64, m1, ta, ma)
; vse8.v v15,0(a1) #avl=16, #vtype=(e8, m1, ta, ma)
; ret
;
; Disassembled:
; block0: ; offset 0x0
; .byte 0x57, 0x70, 0x81, 0xcd
; .byte 0xd7, 0x45, 0x00, 0x5e
; .byte 0x57, 0xb0, 0x00, 0x5e
; .byte 0xd7, 0xb7, 0xb3, 0x5c
; .byte 0x57, 0x70, 0x08, 0xcc
; .byte 0xa7, 0x87, 0x05, 0x02
; ret

16 changes: 16 additions & 0 deletions cranelift/filetests/filetests/runtests/simd-scalartovector.clif
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ block0(v0: i32):
; run: %scalartovector_i32(1) == [1 0 0 0]
; run: %scalartovector_i32(4294967295) == [4294967295 0 0 0]

function %scalartovector_i32_imm(i32) -> i32x4 {
block0(v0: i32):
v1 = iconst.i32 7
v2 = scalar_to_vector.i32x4 v1
return v2
}
; run: %scalartovector_i32_imm(1) == [7 0 0 0]

function %scalartovector_i64(i64) -> i64x2 {
block0(v0: i64):
v1 = scalar_to_vector.i64x2 v0
Expand All @@ -24,6 +32,14 @@ block0(v0: i64):
; run: %scalartovector_i64(1) == [1 0]
; run: %scalartovector_i64(18446744073709551615) == [18446744073709551615 0]

function %scalartovector_i64_imm(i64) -> i64x2 {
block0(v0: i64):
v1 = iconst.i64 7
v2 = scalar_to_vector.i64x2 v1
return v2
}
; run: %scalartovector_i64_imm(1) == [7 0]

function %scalartovector_f32(f32) -> f32x4 {
block0(v0: f32):
v1 = scalar_to_vector.f32x4 v0
Expand Down

0 comments on commit 70039d8

Please sign in to comment.