ISLE: Resolve overlap in the riscv64 backend (#4982)

Resolve overlap in the RiscV64 backend by adding priorities to rules. Additionally, one test updated as a result of this work, as a peephole optimization for addition with immediates fires now.
This commit is contained in:
Trevor Elliott
2022-09-29 17:22:25 -07:00
committed by GitHub
parent 77ab99d3b0
commit c1d6ca48a7
3 changed files with 254 additions and 253 deletions

View File

@@ -832,7 +832,7 @@
;; extend int if need. ;; extend int if need.
(decl ext_int_if_need (bool ValueRegs Type) ValueRegs) (decl ext_int_if_need (bool ValueRegs Type) ValueRegs)
;;; for I8 and I16 ... ;;; for I8 and I16 ...
(rule (rule -1
(ext_int_if_need signed val (fits_in_32 ty)) (ext_int_if_need signed val (fits_in_32 ty))
(gen_extend val signed (ty_bits ty) 64)) (gen_extend val signed (ty_bits ty) 64))
;;; otherwise this is a I64 or I128 ;;; otherwise this is a I64 or I128
@@ -857,7 +857,7 @@
(def_inst (iconst (u64_from_imm64 (imm12_from_u64 n))))) (def_inst (iconst (u64_from_imm64 (imm12_from_u64 n)))))
(decl select_addi (Type) AluOPRRI) (decl select_addi (Type) AluOPRRI)
(rule (select_addi (fits_in_32 ty)) (AluOPRRI.Addiw)) (rule 1 (select_addi (fits_in_32 ty)) (AluOPRRI.Addiw))
(rule (select_addi (fits_in_64 ty)) (AluOPRRI.Addi)) (rule (select_addi (fits_in_64 ty)) (AluOPRRI.Addi))
@@ -911,17 +911,17 @@
(if-let $false (has_b)) (if-let $false (has_b))
(gen_cltz $false x ty)) (gen_cltz $false x ty))
(rule (rule 2
(lower_ctz $I64 x) (lower_ctz $I64 x)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Ctz) x)) (alu_rr_funct12 (AluOPRRI.Ctz) x))
(rule (rule 2
(lower_ctz $I32 x) (lower_ctz $I32 x)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Ctzw) x)) (alu_rr_funct12 (AluOPRRI.Ctzw) x))
;;;; for I8 and I16 ;;;; for I8 and I16
(rule (rule 1
(lower_ctz ty x) (lower_ctz ty x)
(if-let $true (has_b)) (if-let $true (has_b))
(let (let
@@ -956,17 +956,17 @@
(lower_clz ty rs) (lower_clz ty rs)
(if-let $false (has_b)) (if-let $false (has_b))
(gen_cltz $true rs ty)) (gen_cltz $true rs ty))
(rule (rule 2
(lower_clz $I64 r) (lower_clz $I64 r)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Clz) r)) (alu_rr_funct12 (AluOPRRI.Clz) r))
(rule (rule 2
(lower_clz $I32 r) (lower_clz $I32 r)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Clzw) r)) (alu_rr_funct12 (AluOPRRI.Clzw) r))
;;; for I8 and I16 ;;; for I8 and I16
(rule (rule 1
(lower_clz ty r) (lower_clz ty r)
(if-let $true (has_b)) (if-let $true (has_b))
(let (let
@@ -1011,12 +1011,12 @@
;; val is_signed from_bits to_bits ;; val is_signed from_bits to_bits
(decl lower_extend (Reg bool u8 u8) ValueRegs) (decl lower_extend (Reg bool u8 u8) ValueRegs)
(rule (rule -1
(lower_extend r is_signed from_bits to_bits) (lower_extend r is_signed from_bits to_bits)
(gen_extend r is_signed from_bits to_bits)) (gen_extend r is_signed from_bits to_bits))
;;;; for I128 signed extend. ;;;; for I128 signed extend.
(rule (rule 1
(lower_extend r $true 64 128) (lower_extend r $true 64 128)
(let (let
((tmp Reg (alu_rrr (AluOPRRR.Slt) r (zero_reg))) ((tmp Reg (alu_rrr (AluOPRRR.Slt) r (zero_reg)))
@@ -1033,7 +1033,7 @@
;;;; for I128 unsigned extend. ;;;; for I128 unsigned extend.
(rule (rule 1
(lower_extend r $false 64 128) (lower_extend r $false 64 128)
(value_regs (gen_move2 r $I64 $I64) (zero_reg))) (value_regs (gen_move2 r $I64 $I64) (zero_reg)))
@@ -1056,7 +1056,7 @@
(value_regs low high))) (value_regs low high)))
(decl lower_umlhi (Type Reg Reg) Reg) (decl lower_umlhi (Type Reg Reg) Reg)
(rule (rule 1
(lower_umlhi $I64 rs1 rs2) (lower_umlhi $I64 rs1 rs2)
(alu_rrr (AluOPRRR.Mulhu) rs1 rs2)) (alu_rrr (AluOPRRR.Mulhu) rs1 rs2))
@@ -1067,7 +1067,7 @@
(alu_rr_imm12 (AluOPRRI.Srli) tmp (imm12_const (ty_bits ty))))) (alu_rr_imm12 (AluOPRRI.Srli) tmp (imm12_const (ty_bits ty)))))
(decl lower_smlhi (Type Reg Reg) Reg) (decl lower_smlhi (Type Reg Reg) Reg)
(rule (rule 1
(lower_smlhi $I64 rs1 rs2) (lower_smlhi $I64 rs1 rs2)
(alu_rrr (AluOPRRR.Mulh) rs1 rs2)) (alu_rrr (AluOPRRR.Mulh) rs1 rs2))
@@ -1084,7 +1084,7 @@
(decl lower_rotl (Type Reg Reg) Reg) (decl lower_rotl (Type Reg Reg) Reg)
(rule (rule 1
(lower_rotl $I64 rs amount) (lower_rotl $I64 rs amount)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rrr (AluOPRRR.Rol) rs amount)) (alu_rrr (AluOPRRR.Rol) rs amount))
@@ -1094,7 +1094,7 @@
(if-let $false (has_b)) (if-let $false (has_b))
(lower_rotl_shift $I64 rs amount)) (lower_rotl_shift $I64 rs amount))
(rule (rule 1
(lower_rotl $I32 rs amount) (lower_rotl $I32 rs amount)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rrr (AluOPRRR.Rolw) rs amount)) (alu_rrr (AluOPRRR.Rolw) rs amount))
@@ -1104,7 +1104,7 @@
(if-let $false (has_b)) (if-let $false (has_b))
(lower_rotl_shift $I32 rs amount)) (lower_rotl_shift $I32 rs amount))
(rule (rule -1
(lower_rotl ty rs amount) (lower_rotl ty rs amount)
(lower_rotl_shift ty rs amount)) (lower_rotl_shift ty rs amount))
@@ -1133,7 +1133,7 @@
(decl lower_rotr (Type Reg Reg) Reg) (decl lower_rotr (Type Reg Reg) Reg)
(rule (rule 1
(lower_rotr $I64 rs amount) (lower_rotr $I64 rs amount)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rrr (AluOPRRR.Ror) rs amount)) (alu_rrr (AluOPRRR.Ror) rs amount))
@@ -1142,7 +1142,7 @@
(if-let $false (has_b)) (if-let $false (has_b))
(lower_rotr_shift $I64 rs amount)) (lower_rotr_shift $I64 rs amount))
(rule (rule 1
(lower_rotr $I32 rs amount) (lower_rotr $I32 rs amount)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rrr (AluOPRRR.Rorw) rs amount)) (alu_rrr (AluOPRRR.Rorw) rs amount))
@@ -1152,7 +1152,7 @@
(if-let $false (has_b)) (if-let $false (has_b))
(lower_rotr_shift $I32 rs amount)) (lower_rotr_shift $I32 rs amount))
(rule (rule -1
(lower_rotr ty rs amount) (lower_rotr ty rs amount)
(lower_rotr_shift ty rs amount)) (lower_rotr_shift ty rs amount))
@@ -1206,7 +1206,7 @@
(writable_reg_to_reg sum))) (writable_reg_to_reg sum)))
(decl lower_popcnt (Reg Type) Reg) (decl lower_popcnt (Reg Type) Reg)
(rule (lower_popcnt rs ty ) (rule 1 (lower_popcnt rs ty )
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Cpop) (ext_int_if_need $false rs ty))) (alu_rr_funct12 (AluOPRRI.Cpop) (ext_int_if_need $false rs ty)))
(rule (lower_popcnt rs ty) (rule (lower_popcnt rs ty)
@@ -1781,7 +1781,7 @@
;;; lower icmp ;;; lower icmp
(decl lower_icmp (IntCC ValueRegs ValueRegs Type) Reg) (decl lower_icmp (IntCC ValueRegs ValueRegs Type) Reg)
;;; eq or ne. ;;; eq or ne.
(rule (rule -1
(lower_icmp (intcc_is_eq_or_ne cc) x y ty) (lower_icmp (intcc_is_eq_or_ne cc) x y ty)
(gen_icmp cc (ext_int_if_need $false x ty) (ext_int_if_need $false y ty) ty)) (gen_icmp cc (ext_int_if_need $false x ty) (ext_int_if_need $false y ty) ty))
;;;; singed >= ... ;;;; singed >= ...
@@ -1861,7 +1861,7 @@
;;; right now only return if overflow. ;;; right now only return if overflow.
(decl lower_uadd_overflow (Reg Reg Type) Reg) (decl lower_uadd_overflow (Reg Reg Type) Reg)
(rule (rule 1
(lower_uadd_overflow x y $I64) (lower_uadd_overflow x y $I64)
(let (let
((tmp Reg (alu_add x y))) ((tmp Reg (alu_add x y)))
@@ -1944,7 +1944,7 @@
;;; ;;;
(decl gen_andn (Reg Reg) Reg) (decl gen_andn (Reg Reg) Reg)
(rule (rule 1
(gen_andn rs1 rs2) (gen_andn rs1 rs2)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rrr (AluOPRRR.Andn) rs1 rs2)) (alu_rrr (AluOPRRR.Andn) rs1 rs2))
@@ -1958,7 +1958,7 @@
;;; ;;;
(decl gen_orn (Reg Reg) Reg) (decl gen_orn (Reg Reg) Reg)
(rule (rule 1
(gen_orn rs1 rs2 ) (gen_orn rs1 rs2 )
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rrr (AluOPRRR.Orn) rs1 rs2)) (alu_rrr (AluOPRRR.Orn) rs1 rs2))
@@ -1971,7 +1971,7 @@
(alu_rrr (AluOPRRR.Or) rs1 tmp))) (alu_rrr (AluOPRRR.Or) rs1 tmp)))
(decl gen_rev8 (Reg) Reg) (decl gen_rev8 (Reg) Reg)
(rule (rule 1
(gen_rev8 rs) (gen_rev8 rs)
(if-let $true (has_b)) (if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Rev8) rs)) (alu_rr_funct12 (AluOPRRI.Rev8) rs))
@@ -1989,7 +1989,7 @@
(extern constructor has_zbkb has_zbkb) (extern constructor has_zbkb has_zbkb)
(decl gen_brev8 (Reg Type) Reg) (decl gen_brev8 (Reg Type) Reg)
(rule (rule 1
(gen_brev8 rs _) (gen_brev8 rs _)
(if-let $true (has_zbkb)) (if-let $true (has_zbkb))
(alu_rr_funct12 (AluOPRRI.Brev8) rs)) (alu_rr_funct12 (AluOPRRI.Brev8) rs))

View File

@@ -1,5 +1,7 @@
;; riscv64 instruction selection and CLIF-to-MachInst lowering. ;; riscv64 instruction selection and CLIF-to-MachInst lowering.
(pragma overlap_errors)
;; The main lowering constructor term: takes a clif `Inst` and returns the ;; The main lowering constructor term: takes a clif `Inst` and returns the
;; register(s) within which the lowered instruction's result values live. ;; register(s) within which the lowered instruction's result values live.
(decl lower (Inst) InstOutput) (decl lower (Inst) InstOutput)
@@ -25,18 +27,18 @@
;;;; Rules for `iadd` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `iadd` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_32 ty) (iadd x y))) (rule -1 (lower (has_type (fits_in_32 ty) (iadd x y)))
(alu_rrr (AluOPRRR.Addw) x y)) (alu_rrr (AluOPRRR.Addw) x y))
;; Base case, simply adding things in registers. ;; Base case, simply adding things in registers.
(rule (lower (has_type (fits_in_64 ty) (iadd x y))) (rule -2 (lower (has_type (fits_in_64 ty) (iadd x y)))
(alu_add x y)) (alu_add x y))
;; Special cases for when one operand is an immediate that fits in 12 bits. ;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_value y)))) (rule 1 (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_value y))))
(alu_rr_imm12 (select_addi ty) x y)) (alu_rr_imm12 (select_addi ty) x y))
(rule (lower (has_type (fits_in_64 ty) (iadd (imm12_from_value x) y))) (rule 2 (lower (has_type (fits_in_64 ty) (iadd (imm12_from_value x) y)))
(alu_rr_imm12 (select_addi ty) y x)) (alu_rr_imm12 (select_addi ty) y x))
(rule (rule
@@ -61,10 +63,10 @@
;;;; Rules for `isub` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `isub` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Base case, simply subtracting things in registers. ;; Base case, simply subtracting things in registers.
(rule (lower (has_type (fits_in_64 ty) (isub x y))) (rule -2 (lower (has_type (fits_in_64 ty) (isub x y)))
(alu_rrr (AluOPRRR.Sub) x y)) (alu_rrr (AluOPRRR.Sub) x y))
(rule (lower (has_type (fits_in_32 ty) (isub x y))) (rule -1 (lower (has_type (fits_in_32 ty) (isub x y)))
(alu_rrr (AluOPRRR.Subw) x y)) (alu_rrr (AluOPRRR.Subw) x y))
(rule (lower (has_type $I128 (isub x y))) (rule (lower (has_type $I128 (isub x y)))
@@ -79,9 +81,9 @@
;;;; Rules for `imul` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `imul` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (imul x y))) (rule -2 (lower (has_type (fits_in_64 ty) (imul x y)))
(alu_rrr (AluOPRRR.Mul) x y)) (alu_rrr (AluOPRRR.Mul) x y))
(rule (lower (has_type (fits_in_32 ty) (imul x y))) (rule -1 (lower (has_type (fits_in_32 ty) (imul x y)))
(alu_rrr (AluOPRRR.Mulw) x y)) (alu_rrr (AluOPRRR.Mulw) x y))
;;;; Rules for `smulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `smulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -122,13 +124,13 @@
;;;; Rules for `div` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `div` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_32 ty) (udiv x y))) (rule -1 (lower (has_type (fits_in_32 ty) (udiv x y)))
(let (let
((y2 Reg (ext_int_if_need $false y ty)) ((y2 Reg (ext_int_if_need $false y ty))
(_ InstOutput (gen_div_by_zero y2))) (_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Divuw) (ext_int_if_need $false x ty) y2))) (alu_rrr (AluOPRRR.Divuw) (ext_int_if_need $false x ty) y2)))
(rule (lower (has_type (fits_in_32 ty) (sdiv x y))) (rule -1 (lower (has_type (fits_in_32 ty) (sdiv x y)))
(let (let
((a Reg (ext_int_if_need $true x ty)) ((a Reg (ext_int_if_need $true x ty))
(b Reg (ext_int_if_need $true y ty)) (b Reg (ext_int_if_need $true y ty))
@@ -149,13 +151,13 @@
;;;; Rules for `rem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `rem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_16 ty) (urem x y))) (rule -1 (lower (has_type (fits_in_16 ty) (urem x y)))
(let (let
((y2 Reg (ext_int_if_need $false y ty)) ((y2 Reg (ext_int_if_need $false y ty))
(_ InstOutput (gen_div_by_zero y2))) (_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Remuw) (ext_int_if_need $false x ty) y2))) (alu_rrr (AluOPRRR.Remuw) (ext_int_if_need $false x ty) y2)))
(rule (lower (has_type (fits_in_16 ty) (srem x y))) (rule -1 (lower (has_type (fits_in_16 ty) (srem x y)))
(let (let
((y2 Reg (ext_int_if_need $true y ty)) ((y2 Reg (ext_int_if_need $true y ty))
(_ InstOutput (gen_div_by_zero y2))) (_ InstOutput (gen_div_by_zero y2)))
@@ -184,14 +186,14 @@
(alu_rrr (AluOPRRR.RemU) x y))) (alu_rrr (AluOPRRR.RemU) x y)))
;;;; Rules for `and` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `and` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (band x y))) (rule -1 (lower (has_type (fits_in_64 ty) (band x y)))
(alu_rrr (AluOPRRR.And) x y)) (alu_rrr (AluOPRRR.And) x y))
;; Special cases for when one operand is an immediate that fits in 12 bits. ;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule (lower (has_type (fits_in_64 ty) (band x (imm12_from_value y)))) (rule 2 (lower (has_type (fits_in_64 ty) (band x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Andi) x y)) (alu_rr_imm12 (AluOPRRI.Andi) x y))
(rule (lower (has_type (fits_in_64 ty) (band (imm12_from_value x) y))) (rule 1 (lower (has_type (fits_in_64 ty) (band (imm12_from_value x) y)))
(alu_rr_imm12 (AluOPRRI.Andi) y x)) (alu_rr_imm12 (AluOPRRI.Andi) y x))
(rule (lower (has_type $B128 (band x y))) (rule (lower (has_type $B128 (band x y)))
@@ -206,14 +208,14 @@
;;;; Rules for `or` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `or` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (bor x y))) (rule -1 (lower (has_type (fits_in_64 ty) (bor x y)))
(alu_rrr (AluOPRRR.Or) x y)) (alu_rrr (AluOPRRR.Or) x y))
;; Special cases for when one operand is an immediate that fits in 12 bits. ;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule (lower (has_type (fits_in_64 ty) (bor x (imm12_from_value y)))) (rule 2 (lower (has_type (fits_in_64 ty) (bor x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Ori) x y)) (alu_rr_imm12 (AluOPRRI.Ori) x y))
(rule (lower (has_type (fits_in_64 ty) (bor (imm12_from_value x) y))) (rule 1 (lower (has_type (fits_in_64 ty) (bor (imm12_from_value x) y)))
(alu_rr_imm12 (AluOPRRI.Ori) y x)) (alu_rr_imm12 (AluOPRRI.Ori) y x))
(rule (lower (has_type $B128 (bor x y))) (rule (lower (has_type $B128 (bor x y)))
(lower_b128_binary (AluOPRRR.Or) x y)) (lower_b128_binary (AluOPRRR.Or) x y))
@@ -226,14 +228,14 @@
;;;; Rules for `xor` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `xor` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (bxor x y))) (rule -1 (lower (has_type (fits_in_64 ty) (bxor x y)))
(alu_rrr (AluOPRRR.Xor) x y)) (alu_rrr (AluOPRRR.Xor) x y))
;; Special cases for when one operand is an immediate that fits in 12 bits. ;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule (lower (has_type (fits_in_64 ty) (bxor x (imm12_from_value y)))) (rule 2 (lower (has_type (fits_in_64 ty) (bxor x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Xori) x y)) (alu_rr_imm12 (AluOPRRI.Xori) x y))
(rule (lower (has_type (fits_in_64 ty) (bxor (imm12_from_value x) y))) (rule 1 (lower (has_type (fits_in_64 ty) (bxor (imm12_from_value x) y)))
(alu_rr_imm12 (AluOPRRI.Xori) y x)) (alu_rr_imm12 (AluOPRRI.Xori) y x))
(rule (lower (has_type $B128 (bxor x y))) (rule (lower (has_type $B128 (bxor x y)))
(lower_b128_binary (AluOPRRR.Xor) x y)) (lower_b128_binary (AluOPRRR.Xor) x y))
@@ -246,7 +248,7 @@
;;;; Rules for `bnot` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `bnot` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type fits_in_64 (bnot x))) (rule -1 (lower (has_type fits_in_64 (bnot x)))
(alu_rr_imm12 (AluOPRRI.Xori) x (imm_from_neg_bits -1))) (alu_rr_imm12 (AluOPRRI.Xori) x (imm_from_neg_bits -1)))
(rule (lower (has_type $I128 (bnot x))) (rule (lower (has_type $I128 (bnot x)))
@@ -266,7 +268,7 @@
(rule (lower (has_type ty (bitrev x))) (rule (lower (has_type ty (bitrev x)))
(lower_bit_reverse x ty)) (lower_bit_reverse x ty))
(rule (lower (has_type $I128 (bitrev x))) (rule 1 (lower (has_type $I128 (bitrev x)))
(let ((val ValueRegs x) (let ((val ValueRegs x)
(lo_rev Reg (lower_bit_reverse (value_regs_get val 0) $I64)) (lo_rev Reg (lower_bit_reverse (value_regs_get val 0) $I64))
(hi_rev Reg (lower_bit_reverse (value_regs_get val 1) $I64))) (hi_rev Reg (lower_bit_reverse (value_regs_get val 1) $I64)))
@@ -277,13 +279,13 @@
(rule (lower (has_type ty (ctz x))) (rule (lower (has_type ty (ctz x)))
(lower_ctz ty x)) (lower_ctz ty x))
(rule (lower (has_type $I128 (ctz x))) (rule 1 (lower (has_type $I128 (ctz x)))
(lower_ctz_128 x)) (lower_ctz_128 x))
;;;; Rules for `clz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `clz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type ty (clz x))) (rule (lower (has_type ty (clz x)))
(lower_clz ty x)) (lower_clz ty x))
(rule (lower (has_type $I128 (clz x))) (rule 1 (lower (has_type $I128 (clz x)))
(lower_clz_i128 x)) (lower_clz_i128 x))
;;;; Rules for `uextend` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `uextend` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -298,7 +300,7 @@
;;;; Rules for `band_not` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `band_not` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (band_not x y))) (rule (lower (has_type (fits_in_64 ty) (band_not x y)))
(gen_andn x y)) (gen_andn x y))
(rule (lower (has_type $I128 (band_not x y))) (rule 1 (lower (has_type $I128 (band_not x y)))
(let (let
((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1))))
@@ -307,84 +309,84 @@
;;;; Rules for `popcnt` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `popcnt` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (popcnt x))) (rule (lower (has_type (fits_in_64 ty) (popcnt x)))
(lower_popcnt x ty)) (lower_popcnt x ty))
(rule (lower (has_type $I128 (popcnt x))) (rule 1 (lower (has_type $I128 (popcnt x)))
(lower_popcnt_i128 x)) (lower_popcnt_i128 x))
;;;; Rules for `ishl` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `ishl` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type $I8 (ishl x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I8 (ishl x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sllw) x (alu_andi y 7)) (alu_rrr (AluOPRRR.Sllw) x (alu_andi y 7))
) )
(rule (lower (has_type $I8(ishl x (imm12_from_value y)))) (rule 2 (lower (has_type $I8 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slliw) x (imm12_and y 7))) (alu_rr_imm12 (AluOPRRI.Slliw) x (imm12_and y 7)))
(rule (lower (has_type $I16 (ishl x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I16 (ishl x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sllw) x (alu_andi y 15)) (alu_rrr (AluOPRRR.Sllw) x (alu_andi y 15))
) )
(rule (lower (has_type $I16(ishl x (imm12_from_value y)))) (rule 2 (lower (has_type $I16 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slliw) x (imm12_and y 15))) (alu_rr_imm12 (AluOPRRI.Slliw) x (imm12_and y 15)))
(rule (lower (has_type $I32(ishl x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I32 (ishl x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sllw) x y)) (alu_rrr (AluOPRRR.Sllw) x y))
(rule (lower (has_type $I32 (ishl x (imm12_from_value y)))) (rule 2 (lower (has_type $I32 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slliw) x y)) (alu_rr_imm12 (AluOPRRI.Slliw) x y))
(rule (lower (has_type $I64 (ishl x (imm12_from_value y)))) (rule 2 (lower (has_type $I64 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slli) x y)) (alu_rr_imm12 (AluOPRRI.Slli) x y))
(rule (lower (has_type $I64(ishl x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I64 (ishl x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sll) x y)) (alu_rrr (AluOPRRR.Sll) x y))
(rule (lower (has_type $I128 (ishl x y))) (rule 0 (lower (has_type $I128 (ishl x y)))
(lower_i128_ishl x y)) (lower_i128_ishl x y))
;;;; Rules for `ushr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `ushr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type $I8 (ushr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I8 (ushr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Srlw) (ext_int_if_need $false x $I8) (alu_andi y 7)) (alu_rrr (AluOPRRR.Srlw) (ext_int_if_need $false x $I8) (alu_andi y 7))
) )
(rule (lower (has_type $I8(ushr x (imm12_from_value y)))) (rule 2 (lower (has_type $I8 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.SrliW) (ext_int_if_need $false x $I8) (imm12_and y 7))) (alu_rr_imm12 (AluOPRRI.SrliW) (ext_int_if_need $false x $I8) (imm12_and y 7)))
(rule (lower (has_type $I16 (ushr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I16 (ushr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Srlw) (ext_int_if_need $false x $I16) (alu_andi y 15)) (alu_rrr (AluOPRRR.Srlw) (ext_int_if_need $false x $I16) (alu_andi y 15))
) )
(rule (lower (has_type $I16(ushr x (imm12_from_value y)))) (rule 2 (lower (has_type $I16 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.SrliW) (ext_int_if_need $false x $I16) (imm12_and y 15))) (alu_rr_imm12 (AluOPRRI.SrliW) (ext_int_if_need $false x $I16) (imm12_and y 15)))
(rule (lower (has_type $I32(ushr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I32 (ushr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Srlw) x y)) (alu_rrr (AluOPRRR.Srlw) x y))
(rule (lower (has_type $I32 (ushr x (imm12_from_value y)))) (rule 2 (lower (has_type $I32 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.SrliW) x y)) (alu_rr_imm12 (AluOPRRI.SrliW) x y))
(rule (lower (has_type $I64 (ushr x (imm12_from_value y)))) (rule 2 (lower (has_type $I64 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srli) x y)) (alu_rr_imm12 (AluOPRRI.Srli) x y))
(rule (lower (has_type $I64(ushr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I64 (ushr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Srl) x y)) (alu_rrr (AluOPRRR.Srl) x y))
(rule (lower (has_type $I128 (ushr x y))) (rule 0 (lower (has_type $I128 (ushr x y)))
(lower_i128_ushr x y)) (lower_i128_ushr x y))
;;;; Rules for `sshr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `sshr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type $I8 (sshr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I8 (sshr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sra) (ext_int_if_need $true x $I8) (alu_andi y 7)) (alu_rrr (AluOPRRR.Sra) (ext_int_if_need $true x $I8) (alu_andi y 7))
) )
(rule (lower (has_type $I8(sshr x (imm12_from_value y)))) (rule 2 (lower (has_type $I8 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srai) (ext_int_if_need $true x $I8) (imm12_and y 7))) (alu_rr_imm12 (AluOPRRI.Srai) (ext_int_if_need $true x $I8) (imm12_and y 7)))
(rule (lower (has_type $I16 (sshr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I16 (sshr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sra) (ext_int_if_need $true x $I16) (alu_andi y 15)) (alu_rrr (AluOPRRR.Sra) (ext_int_if_need $true x $I16) (alu_andi y 15))
) )
(rule (lower (has_type $I16(sshr x (imm12_from_value y)))) (rule 2 (lower (has_type $I16 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srai) (ext_int_if_need $true x $I16) (imm12_and y 15))) (alu_rr_imm12 (AluOPRRI.Srai) (ext_int_if_need $true x $I16) (imm12_and y 15)))
(rule (lower (has_type $I32 (sshr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I32 (sshr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sraw) x y)) (alu_rrr (AluOPRRR.Sraw) x y))
(rule (lower (has_type $I32 (sshr x (imm12_from_value y)))) (rule 2 (lower (has_type $I32 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Sraiw) x y)) (alu_rr_imm12 (AluOPRRI.Sraiw) x y))
(rule (lower (has_type $I64 (sshr x (valueregs_2_reg y)))) (rule 1 (lower (has_type $I64 (sshr x (valueregs_2_reg y))))
(alu_rrr (AluOPRRR.Sra) x y)) (alu_rrr (AluOPRRR.Sra) x y))
(rule (lower (has_type $I64(sshr x (imm12_from_value y)))) (rule 2 (lower (has_type $I64 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srai) x y)) (alu_rr_imm12 (AluOPRRI.Srai) x y))
(rule (lower (has_type $I128 (sshr x y))) (rule 0 (lower (has_type $I128 (sshr x y)))
(lower_i128_sshr x y)) (lower_i128_sshr x y))
@@ -392,14 +394,14 @@
(rule (lower (has_type (fits_in_64 ty) (rotl x (valueregs_2_reg y)))) (rule (lower (has_type (fits_in_64 ty) (rotl x (valueregs_2_reg y))))
(lower_rotl ty (ext_int_if_need $false x ty) y)) (lower_rotl ty (ext_int_if_need $false x ty) y))
(rule (lower (has_type $I128 (rotl x y))) (rule 1 (lower (has_type $I128 (rotl x y)))
(lower_i128_rotl x y)) (lower_i128_rotl x y))
;;;; Rules for `rotr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `rotr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (rotr x (valueregs_2_reg y)))) (rule (lower (has_type (fits_in_64 ty) (rotr x (valueregs_2_reg y))))
(lower_rotr ty (ext_int_if_need $false x ty) y)) (lower_rotr ty (ext_int_if_need $false x ty) y))
(rule (lower (has_type $I128 (rotr x y))) (rule 1 (lower (has_type $I128 (rotr x y)))
(lower_i128_rotr x y)) (lower_i128_rotr x y))
@@ -407,7 +409,7 @@
;; notice x y order!!! ;; notice x y order!!!
(rule (lower (has_type (fits_in_64 ty) (bxor_not x y))) (rule (lower (has_type (fits_in_64 ty) (bxor_not x y)))
(gen_xor_not x y)) (gen_xor_not x y))
(rule (lower (has_type $I128 (bxor_not x y))) (rule 1 (lower (has_type $I128 (bxor_not x y)))
(let (let
((low Reg (gen_xor_not (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_xor_not (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_xor_not (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_xor_not (value_regs_get x 1) (value_regs_get y 1))))
@@ -419,7 +421,7 @@
(rule (lower (has_type (fits_in_64 ty) (bor_not x y))) (rule (lower (has_type (fits_in_64 ty) (bor_not x y)))
(gen_orn x y)) (gen_orn x y))
(rule (lower (has_type $I128 (bor_not x y))) (rule 1 (lower (has_type $I128 (bor_not x y)))
(let (let
((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1))))
@@ -429,7 +431,7 @@
;;;; Rules for `cls` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `cls` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (cls x))) (rule (lower (has_type (fits_in_64 ty) (cls x)))
(lower_cls x ty)) (lower_cls x ty))
(rule (lower (has_type $I128 (cls x))) (rule 1 (lower (has_type $I128 (cls x)))
(lower_cls_i128 x)) (lower_cls_i128 x))
@@ -463,27 +465,27 @@
;;;; Rules for `AtomicRMW` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `AtomicRMW` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (rule -1
;; ;;
(lower (lower
(has_type (valid_atomic_transaction ty) (atomic_rmw flags op addr x))) (has_type (valid_atomic_transaction ty) (atomic_rmw flags op addr x)))
(gen_atomic (get_atomic_rmw_op ty op) addr x (atomic_amo))) (gen_atomic (get_atomic_rmw_op ty op) addr x (atomic_amo)))
;;; for I8 and I16 ;;; for I8 and I16
(rule (rule 1
(lower (lower
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags op addr x))) (has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags op addr x)))
(gen_atomic_rmw_loop op ty addr x)) (gen_atomic_rmw_loop op ty addr x))
;;;special for I8 and I16 max min etc. ;;;special for I8 and I16 max min etc.
;;;because I need uextend or sextend the value. ;;;because I need uextend or sextend the value.
(rule (rule 2
(lower (lower
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags (is_atomic_rmw_max_etc op $true) addr x))) (has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags (is_atomic_rmw_max_etc op $true) addr x)))
(gen_atomic_rmw_loop op ty addr (ext_int_if_need $true x ty))) (gen_atomic_rmw_loop op ty addr (ext_int_if_need $true x ty)))
(rule (rule 2
;; ;;
(lower (lower
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags (is_atomic_rmw_max_etc op $false) addr x))) (has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags (is_atomic_rmw_max_etc op $false) addr x)))
@@ -529,14 +531,14 @@
(gen_atomic_store p ty src)) (gen_atomic_store p ty src))
(decl gen_atomic_offset (Reg Type) Reg) (decl gen_atomic_offset (Reg Type) Reg)
(rule (gen_atomic_offset p (fits_in_16 ty)) (rule 1 (gen_atomic_offset p (fits_in_16 ty))
(alu_slli (alu_andi p 3) 3)) (alu_slli (alu_andi p 3) 3))
(rule (gen_atomic_offset p _) (rule (gen_atomic_offset p _)
(zero_reg)) (zero_reg))
(decl gen_atomic_p (Reg Type) Reg) (decl gen_atomic_p (Reg Type) Reg)
(rule (gen_atomic_p p (fits_in_16 ty)) (rule 1 (gen_atomic_p p (fits_in_16 ty))
(alu_andi p -4)) (alu_andi p -4))
(rule (gen_atomic_p p _) (rule (gen_atomic_p p _)
@@ -637,7 +639,7 @@
(rule (rule
(lower (has_type (fits_in_64 ty) (bint (valueregs_2_reg x)))) (lower (has_type (fits_in_64 ty) (bint (valueregs_2_reg x))))
(gen_bint x)) (gen_bint x))
(rule (rule 1
(lower (has_type $I128 (bint (valueregs_2_reg x)))) (lower (has_type $I128 (bint (valueregs_2_reg x))))
(let ((tmp Reg (gen_bint x))) (let ((tmp Reg (gen_bint x)))
(value_regs tmp (zero_reg))) (value_regs tmp (zero_reg)))
@@ -731,11 +733,11 @@
(gen_load p offset (load_op ty) flags ty) (gen_load p offset (load_op ty) flags ty)
) )
;;;; for I128 ;;;; for I128
(rule (rule 1
(lower (has_type $I128 (load flags p offset))) (lower (has_type $I128 (load flags p offset)))
(gen_load_128 p offset flags)) (gen_load_128 p offset flags))
;;;; for B128 ;;;; for B128
(rule (rule 1
(lower (has_type $B128 (load flags p offset))) (lower (has_type $B128 (load flags p offset)))
(gen_load_128 p offset flags)) (gen_load_128 p offset flags))
@@ -759,12 +761,12 @@
(gen_store p offset (store_op ty) flags x)) (gen_store p offset (store_op ty) flags x))
;;; special for I128 ;;; special for I128
(rule (rule 1
(lower (store flags x @ (value_type $I128 ) p offset)) (lower (store flags x @ (value_type $I128 ) p offset))
(gen_store_128 p offset flags x)) (gen_store_128 p offset flags x))
;;; special for B128 ;;; special for B128
(rule (rule 1
(lower (store flags x @ (value_type $B128 ) p offset)) (lower (store flags x @ (value_type $B128 ) p offset))
(gen_store_128 p offset flags x)) (gen_store_128 p offset flags x))
@@ -781,11 +783,11 @@
(lower (icmp cc x @ (value_type ty) y)) (lower (icmp cc x @ (value_type ty) y))
(lower_icmp cc x y ty)) (lower_icmp cc x y ty))
;; special for `iadd_ifcout` first out. ;; special for `iadd_ifcout` first out.
(rule (rule 2
(lower (icmp cc (iadd_ifcout a @ (value_type ty) b) y)) (lower (icmp cc (iadd_ifcout a @ (value_type ty) b) y))
(lower_icmp cc (alu_add a b) y ty)) (lower_icmp cc (alu_add a b) y ty))
(rule (rule 1
(lower (icmp cc x (iadd_ifcout a @ (value_type ty) b))) (lower (icmp cc x (iadd_ifcout a @ (value_type ty) b)))
(lower_icmp cc x (alu_add a b) ty)) (lower_icmp cc x (alu_add a b) ty))
@@ -929,7 +931,7 @@
(lower (has_type (fits_in_64 ty) (bmask x @ (value_type ity)))) (lower (has_type (fits_in_64 ty) (bmask x @ (value_type ity))))
(gen_move2 (value_regs_get x 0) ity ty)) (gen_move2 (value_regs_get x 0) ity ty))
;;; for i128 ;;; for i128
(rule (rule 1
;; because we encode bool all 1s. ;; because we encode bool all 1s.
;; move is just ok. ;; move is just ok.
(lower (has_type $I128 (bmask x @ (value_type ity)))) (lower (has_type $I128 (bmask x @ (value_type ity))))
@@ -945,7 +947,7 @@
(gen_moves x ity ty)) (gen_moves x ity ty))
;;; for B128 ;;; for B128
(rule (rule 1
;; because we encode bool all 1s. ;; because we encode bool all 1s.
;; move is just ok. ;; move is just ok.
(lower (has_type ty (bextend x @ (value_type ity)))) (lower (has_type ty (bextend x @ (value_type ity))))

View File

@@ -329,8 +329,7 @@ block0(v0: i32):
} }
; block0: ; block0:
; li a1,-1 ; addiw a0,a0,-1
; addw a0,a0,a1
; ret ; ret
function %f27(i32) -> i32 { function %f27(i32) -> i32 {