Skip to content

Commit

Permalink
riscv64: Add generic select lowering using zicond
Browse files Browse the repository at this point in the history
  • Loading branch information
afonso360 committed May 27, 2024
1 parent fb76898 commit e33745c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 8 deletions.
28 changes: 20 additions & 8 deletions cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -2590,41 +2590,53 @@
;; Rotate Zero Reg to the right. This allows us to write fewer rules
;; below when matching the zero register

(rule 4 (gen_select_xreg (int_compare_decompose cc a @ (zero_reg) b) x y)
(rule 5 (gen_select_xreg (int_compare_decompose cc a @ (zero_reg) b) x y)
(gen_select_xreg (int_compare (intcc_swap_args cc) b a) x y))

(rule 3 (gen_select_xreg c @ (int_compare_decompose cc a b) x @ (zero_reg) y)
(rule 4 (gen_select_xreg c @ (int_compare_decompose cc a b) x @ (zero_reg) y)
(gen_select_xreg (int_compare (intcc_complement cc) b a) y x))


(rule 2 (gen_select_xreg (int_compare_decompose cc x y) x y)
(rule 3 (gen_select_xreg (int_compare_decompose cc x y) x y)
(if-let (IntCC.UnsignedLessThan) (intcc_without_eq cc))
(if-let $true (has_zbb))
(rv_minu x y))

(rule 2 (gen_select_xreg (int_compare_decompose cc x y) x y)
(rule 3 (gen_select_xreg (int_compare_decompose cc x y) x y)
(if-let (IntCC.SignedLessThan) (intcc_without_eq cc))
(if-let $true (has_zbb))
(rv_min x y))

(rule 2 (gen_select_xreg (int_compare_decompose cc x y) x y)
(rule 3 (gen_select_xreg (int_compare_decompose cc x y) x y)
(if-let (IntCC.UnsignedGreaterThan) (intcc_without_eq cc))
(if-let $true (has_zbb))
(rv_maxu x y))

(rule 2 (gen_select_xreg (int_compare_decompose cc x y) x y)
(rule 3 (gen_select_xreg (int_compare_decompose cc x y) x y)
(if-let (IntCC.SignedGreaterThan) (intcc_without_eq cc))
(if-let $true (has_zbb))
(rv_max x y))

(rule 1 (gen_select_xreg (int_compare_decompose (IntCC.Equal) c (zero_reg)) x (zero_reg))
(rule 2 (gen_select_xreg (int_compare_decompose (IntCC.Equal) c (zero_reg)) x (zero_reg))
(if-let $true (has_zicond))
(rv_czero_nez x c))

(rule 1 (gen_select_xreg (int_compare_decompose (IntCC.NotEqual) c (zero_reg)) x (zero_reg))
(rule 2 (gen_select_xreg (int_compare_decompose (IntCC.NotEqual) c (zero_reg)) x (zero_reg))
(if-let $true (has_zicond))
(rv_czero_eqz x c))

(rule 1 (gen_select_xreg (int_compare_decompose (IntCC.Equal) c (zero_reg)) x y)
(if-let $true (has_zicond))
(rv_or
(rv_czero_nez x c)
(rv_czero_eqz y c)))

(rule 1 (gen_select_xreg (int_compare_decompose (IntCC.NotEqual) c (zero_reg)) x y)
(if-let $true (has_zicond))
(rv_or
(rv_czero_eqz x c)
(rv_czero_nez y c)))

(rule 0 (gen_select_xreg c x y)
(let
((dst WritableReg (temp_writable_xreg))
Expand Down
45 changes: 45 additions & 0 deletions cranelift/filetests/filetests/isa/riscv64/zicond.clif
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,48 @@ block0(v0: i64, v1: i64):
; .byte 0x33, 0xd5, 0xa5, 0x0e
; ret


function %select_icmp_eq_zero(i64, i64, i64) -> i64 {
block0(v0: i64, v1: i64, v2: i64):
v3 = iconst.i64 0
v4 = icmp.i64 eq v0, v3
v5 = select.i64 v4, v1, v2
return v5
}

; VCode:
; block0:
; czero.eqz a4,a1,a0
; czero.nez a0,a2,a0
; or a0,a4,a0
; ret
;
; Disassembled:
; block0: ; offset 0x0
; .byte 0x33, 0xd7, 0xa5, 0x0e
; .byte 0x33, 0x75, 0xa6, 0x0e
; or a0, a4, a0
; ret

function %select_icmp_ne_zero(i64, i64, i64) -> i64 {
block0(v0: i64, v1: i64, v2: i64):
v3 = iconst.i64 0
v4 = icmp.i64 ne v0, v3
v5 = select.i64 v4, v1, v2
return v5
}

; VCode:
; block0:
; czero.nez a4,a1,a0
; czero.eqz a0,a2,a0
; or a0,a4,a0
; ret
;
; Disassembled:
; block0: ; offset 0x0
; .byte 0x33, 0xf7, 0xa5, 0x0e
; .byte 0x33, 0x55, 0xa6, 0x0e
; or a0, a4, a0
; ret

40 changes: 40 additions & 0 deletions cranelift/filetests/filetests/runtests/select.clif
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,43 @@ block0(v0: i32):
; run: %select_overflow_i32(2) == 1
; run: %select_overflow_i32(1) == 0
; run: %select_overflow_i32(98) == 1

function %select_zero(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
v2 = iconst.i64 0
v3 = select.i64 v0, v1, v2
return v3
}
; run: %select_zero(0, 42) == 0
; run: %select_zero(42, 42) == 42

function %select_zero_icmp_neq_zero(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
v2 = iconst.i64 0
v3 = icmp.i64 ne v0, v2
v4 = select.i64 v3, v1, v2
return v4
}
; run: %select_zero_icmp_neq_zero(0, 42) == 0
; run: %select_zero_icmp_neq_zero(42, 42) == 42

function %select_icmp_eq_zero(i64, i64, i64) -> i64 {
block0(v0: i64, v1: i64, v2: i64):
v3 = iconst.i64 0
v4 = icmp.i64 eq v0, v3
v5 = select.i64 v4, v1, v2
return v5
}
; run: %select_icmp_eq_zero(0, 42, 35) == 42
; run: %select_icmp_eq_zero(42, 42, 35) == 35

function %select_icmp_ne_zero(i64, i64, i64) -> i64 {
block0(v0: i64, v1: i64, v2: i64):
v3 = iconst.i64 0
v4 = icmp.i64 ne v0, v3
v5 = select.i64 v4, v1, v2
return v5
}
; run: %select_icmp_ne_zero(0, 42, 35) == 35
; run: %select_icmp_ne_zero(42, 42, 35) == 42

0 comments on commit e33745c

Please sign in to comment.