cranelift: Remove redundant branch and select instructions (#5097)
As discussed in the 2022/10/19 meeting, this PR removes many of the branch and select instructions that used iflags, in favor if using brz/brnz and select in their place. Additionally, it reworks selectif_spectre_guard to take an i8 input instead of an iflags input. For reference, the removed instructions are: br_icmp, brif, brff, trueif, trueff, and selectif.
This commit is contained in:
@@ -1706,21 +1706,6 @@
|
||||
(rule (lower (resumable_trap trap_code))
|
||||
(side_effect (udf trap_code)))
|
||||
|
||||
;;;; Rules for `trueif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures the input is always a single-def ifcmp.
|
||||
(rule (lower (has_type out_ty
|
||||
(trueif cc insn @ (ifcmp x @ (value_type in_ty) y))))
|
||||
(lower_icmp_into_reg cc x y in_ty out_ty))
|
||||
|
||||
;;;; Rules for `trueff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures the input is always a single-def ffcmp.
|
||||
(rule (lower (trueff cc insn @ (ffcmp x @ (value_type in_ty) y)))
|
||||
(with_flags_reg
|
||||
(fpu_cmp (scalar_size in_ty) x y)
|
||||
(materialize_bool_result (fp_cond_code cc))))
|
||||
|
||||
;;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
@@ -1755,22 +1740,11 @@
|
||||
(cmp (OperandSize.Size64) rcond (zero_reg))
|
||||
(Cond.Ne) ty rn rm)))
|
||||
|
||||
;;;; Rules for `selectif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures that the input is always a single-def ifcmp.
|
||||
(rule (lower (has_type ty
|
||||
(selectif cc flags @ (ifcmp x @ (value_type in_ty) y)
|
||||
if_true if_false)))
|
||||
(let ((cond Cond (cond_code cc)))
|
||||
(lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
cond ty if_true if_false)))
|
||||
|
||||
;;;; Rules for `selectif_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; Rules for `select_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(selectif_spectre_guard cc
|
||||
flags @ (ifcmp x @ (value_type in_ty) y) if_true if_false)))
|
||||
(select_spectre_guard
|
||||
(icmp cc x @ (value_type in_ty) y) if_true if_false)))
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(dst ValueRegs (lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
@@ -2422,7 +2396,7 @@
|
||||
(rule (lower (fvpromote_low val))
|
||||
(vec_rr_long (VecRRLongOp.Fcvtl32) val $false))
|
||||
|
||||
;;; Rules for `brz`/`brnz`/`brif`/`brff`/`bricmp` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Rules for `brz`/`brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; `brz` following `icmp`
|
||||
(rule (lower_branch (brz (icmp cc x @ (value_type ty) y) _ _) targets)
|
||||
@@ -2505,58 +2479,6 @@
|
||||
(with_flags_side_effect flags
|
||||
(cond_br taken not_taken (cond_br_not_zero rt))))))
|
||||
|
||||
;; `br_icmp`
|
||||
(rule (lower_branch (br_icmp cc x @ (value_type ty) y _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (lower_icmp_into_flags cc x y ty)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
|
||||
;; `brif`
|
||||
(rule (lower_branch (brif cc (ifcmp x @ (value_type ty) y) _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (lower_icmp_into_flags cc x y ty)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
;; If the `ifcmp` result is actually placed in a register, we need to move it
|
||||
;; back into the flags.
|
||||
(rule -1 (lower_branch (brif cc f _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(rn Reg (put_in_reg f))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (mov_to_nzcv rn)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
|
||||
;; `brff`
|
||||
(rule (lower_branch (brff cc (ffcmp x @ (value_type ty) y) _ _) targets)
|
||||
(let ((cond Cond (fp_cond_code cc))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (fpu_cmp (scalar_size ty) x y)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
;; If the `ffcmp` result is actually placed in a register, we need to move it
|
||||
;; back into the flags.
|
||||
(rule -1 (lower_branch (brff cc f _ _) targets)
|
||||
(let ((cond Cond (fp_cond_code cc))
|
||||
(rn Reg (put_in_reg f))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (mov_to_nzcv rn)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
|
||||
;;; Rules for `jump` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower_branch (jump _ _) targets)
|
||||
|
||||
@@ -151,14 +151,10 @@ pub(crate) fn lower_insn_to_regs(
|
||||
|
||||
Opcode::Select => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Selectif | Opcode::SelectifSpectreGuard => implemented_in_isle(ctx),
|
||||
Opcode::SelectSpectreGuard => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Bitselect | Opcode::Vselect => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trueif => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trueff => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::IsNull | Opcode::IsInvalid => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Copy => implemented_in_isle(ctx),
|
||||
@@ -205,13 +201,7 @@ pub(crate) fn lower_insn_to_regs(
|
||||
|
||||
Opcode::GetPinnedReg | Opcode::SetPinnedReg => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Jump
|
||||
| Opcode::Brz
|
||||
| Opcode::Brnz
|
||||
| Opcode::BrIcmp
|
||||
| Opcode::Brif
|
||||
| Opcode::Brff
|
||||
| Opcode::BrTable => {
|
||||
Opcode::Jump | Opcode::Brz | Opcode::Brnz | Opcode::BrTable => {
|
||||
panic!("Branch opcode reached non-branch lowering logic!");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user