cranelift: Remove brz and brnz (#5630)

Remove the brz and brnz instructions, as their behavior is now redundant with brif.
This commit is contained in:
Trevor Elliott
2023-01-30 12:34:56 -08:00
committed by GitHub
parent 77cf547f41
commit a5698cedf8
247 changed files with 2947 additions and 3754 deletions

View File

@@ -160,8 +160,7 @@ mod tests {
let mut pos = FuncCursor::new(&mut func);
pos.insert_block(block0);
pos.ins().brnz(v0, block2, &[]);
pos.ins().jump(block1, &[]);
pos.ins().brif(v0, block2, &[], block1, &[]);
pos.insert_block(block1);
pos.ins().return_(&[]);

View File

@@ -2507,93 +2507,6 @@
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_not_zero rt))))))
;;; Rules for `brz`/`brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; `brz` following `icmp`
(rule (lower_branch (brz (maybe_uextend (icmp cc x @ (value_type ty) y)) _) targets)
(let ((comparison FlagsAndCC (lower_icmp_into_flags cc x y ty))
;; Negate the condition for `brz`.
(cond Cond (invert_cond (cond_code (flags_and_cc_cc comparison))))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect (flags_and_cc_flags comparison)
(cond_br taken
not_taken
(cond_br_cond cond))))))
;; `brnz` following `icmp`
(rule (lower_branch (brnz (maybe_uextend (icmp cc x @ (value_type ty) y)) _) targets)
(let ((comparison FlagsAndCC (lower_icmp_into_flags cc x y ty))
(cond Cond (cond_code (flags_and_cc_cc comparison)))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect (flags_and_cc_flags comparison)
(cond_br taken
not_taken
(cond_br_cond cond))))))
;; `brz` following `fcmp`
(rule (lower_branch (brz (maybe_uextend (fcmp cc x @ (value_type (ty_scalar_float ty)) y)) _) targets)
(let ((cond Cond (fp_cond_code cc))
(cond Cond (invert_cond cond)) ;; negate for `brz`
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect (fpu_cmp (scalar_size ty) x y)
(cond_br taken not_taken
(cond_br_cond cond))))))
;; `brnz` following `fcmp`
(rule (lower_branch (brnz (maybe_uextend (fcmp cc x @ (value_type (ty_scalar_float ty)) y)) _) targets)
(let ((cond Cond (fp_cond_code cc))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect (fpu_cmp (scalar_size ty) x y)
(cond_br taken not_taken
(cond_br_cond cond))))))
;; standard `brz`
(rule -1 (lower_branch (brz c @ (value_type $I128) _) targets)
(let ((flags ProducesFlags (flags_to_producesflags c))
(c ValueRegs (put_in_regs c))
(c_lo Reg (value_regs_get c 0))
(c_hi Reg (value_regs_get c 1))
(rt Reg (orr $I64 c_lo c_hi))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_zero rt))))))
(rule -2 (lower_branch (brz c @ (value_type ty) _) targets)
(if (ty_int_ref_scalar_64 ty))
(let ((flags ProducesFlags (flags_to_producesflags c))
(rt Reg (put_in_reg_zext64 c))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_zero rt))))))
;; standard `brnz`
(rule -1 (lower_branch (brnz c @ (value_type $I128) _) targets)
(let ((flags ProducesFlags (flags_to_producesflags c))
(c ValueRegs (put_in_regs c))
(c_lo Reg (value_regs_get c 0))
(c_hi Reg (value_regs_get c 1))
(rt Reg (orr $I64 c_lo c_hi))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_not_zero rt))))))
(rule -2 (lower_branch (brnz c @ (value_type ty) _) targets)
(if (ty_int_ref_scalar_64 ty))
(let ((flags ProducesFlags (flags_to_producesflags c))
(rt Reg (put_in_reg_zext64 c))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
(emit_side_effect
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_not_zero rt))))))
;;; Rules for `jump` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower_branch (jump _) targets)

View File

@@ -293,15 +293,12 @@ mod test {
pos.insert_block(bb0);
let v0 = pos.ins().iconst(I32, 0x1234);
let v1 = pos.ins().iadd(arg0, v0);
pos.ins().brnz(v1, bb1, &[]);
pos.ins().jump(bb2, &[]);
pos.ins().brif(v1, bb1, &[], bb2, &[]);
pos.insert_block(bb1);
pos.ins().brnz(v1, bb2, &[]);
pos.ins().jump(bb3, &[]);
pos.ins().brif(v1, bb2, &[], bb3, &[]);
pos.insert_block(bb2);
let v2 = pos.ins().iadd(v1, v0);
pos.ins().brnz(v2, bb2, &[]);
pos.ins().jump(bb1, &[]);
pos.ins().brif(v2, bb2, &[], bb1, &[]);
pos.insert_block(bb3);
let v3 = pos.ins().isub(v1, v0);
pos.ins().return_(&[v3]);

View File

@@ -1868,8 +1868,8 @@
(decl int_zero_reg (Type) ValueRegs)
(extern constructor int_zero_reg int_zero_reg)
(decl lower_brz_or_nz (IntCC ValueRegs VecMachLabel Type) Unit)
(extern constructor lower_brz_or_nz lower_brz_or_nz)
(decl lower_cond_br (IntCC ValueRegs VecMachLabel Type) Unit)
(extern constructor lower_cond_br lower_cond_br)
;; Normalize a value for comparision.
;;
@@ -1901,14 +1901,14 @@
;; Default behavior for branching based on an input value.
(rule
(lower_branch (brif v @ (value_type ty) _ _) targets)
(lower_brz_or_nz (IntCC.NotEqual) (normalize_cmp_value ty v) targets ty))
(lower_cond_br (IntCC.NotEqual) (normalize_cmp_value ty v) targets ty))
;; Special case for SI128 to reify the comparison value and branch on it.
(rule 2
(lower_branch (brif v @ (value_type $I128) _ _) targets)
(let ((zero ValueRegs (value_regs (zero_reg) (zero_reg)))
(cmp Reg (gen_icmp (IntCC.NotEqual) v zero $I128)))
(lower_brz_or_nz (IntCC.NotEqual) cmp targets $I64)))
(lower_cond_br (IntCC.NotEqual) cmp targets $I64)))
;; Branching on the result of an icmp
(rule 1
@@ -1930,66 +1930,6 @@
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp cc ty a b) then else))))
;;;;;
(rule
(lower_branch (brz v @ (value_type ty) _) targets)
(lower_brz_or_nz (IntCC.Equal) (normalize_cmp_value ty v) targets ty))
;; Special case for SI128 to reify the comparison value and branch on it.
(rule 2
(lower_branch (brz v @ (value_type $I128) _) targets)
(let ((zero ValueRegs (value_regs (zero_reg) (zero_reg)))
(cmp Reg (gen_icmp (IntCC.Equal) v zero $I128)))
(lower_brz_or_nz (IntCC.NotEqual) cmp targets $I64)))
(rule 1
(lower_branch (brz (maybe_uextend (icmp cc a @ (value_type ty) b)) _) targets)
(lower_br_icmp (intcc_inverse cc) a b targets ty))
(rule 1
(lower_branch (brz (maybe_uextend (fcmp cc a @ (value_type ty) b)) _) targets)
(if-let $true (floatcc_unordered cc))
(let ((then BranchTarget (label_to_br_target (vec_label_get targets 0)))
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp (floatcc_inverse cc) ty a b) then else))))
(rule 1
(lower_branch (brz (maybe_uextend (fcmp cc a @ (value_type ty) b)) _) targets)
(if-let $false (floatcc_unordered cc))
(let ((then BranchTarget (label_to_br_target (vec_label_get targets 0)))
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp cc ty a b) else then))))
;;;;
(rule
(lower_branch (brnz v @ (value_type ty) _) targets)
(lower_brz_or_nz (IntCC.NotEqual) (normalize_cmp_value ty v) targets ty))
;; Special case for SI128 to reify the comparison value and branch on it.
(rule 2
(lower_branch (brnz v @ (value_type $I128) _) targets)
(let ((zero ValueRegs (value_regs (zero_reg) (zero_reg)))
(cmp Reg (gen_icmp (IntCC.NotEqual) v zero $I128)))
(lower_brz_or_nz (IntCC.NotEqual) cmp targets $I64)))
(rule 1
(lower_branch (brnz (maybe_uextend (icmp cc a @ (value_type ty) b)) _) targets)
(lower_br_icmp cc a b targets ty))
(rule 1
(lower_branch (brnz (maybe_uextend (fcmp cc a @ (value_type ty) b)) _) targets)
(if-let $true (floatcc_unordered cc))
(let ((then BranchTarget (label_to_br_target (vec_label_get targets 0)))
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp (floatcc_inverse cc) ty a b) else then))))
(rule 1
(lower_branch (brnz (maybe_uextend (fcmp cc a @ (value_type ty) b)) _) targets)
(if-let $false (floatcc_unordered cc))
(let ((then BranchTarget (label_to_br_target (vec_label_get targets 0)))
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp cc ty a b) then else))))
;;;
(decl lower_br_table (Reg VecMachLabel) Unit)
(extern constructor lower_br_table lower_br_table)

View File

@@ -118,7 +118,6 @@ impl Into<AMode> for StackAMode {
}
/// risc-v always take two register to compare
/// brz can be compare with zero register which has the value 0
#[derive(Clone, Copy, Debug)]
pub struct IntegerCompare {
pub(crate) kind: IntCC,

View File

@@ -159,8 +159,7 @@ mod tests {
let mut pos = FuncCursor::new(&mut func);
pos.insert_block(block0);
pos.ins().brnz(v0, block2, &[]);
pos.ins().jump(block1, &[]);
pos.ins().brif(v0, block2, &[], block1, &[]);
pos.insert_block(block1);
pos.ins().return_(&[]);

View File

@@ -61,7 +61,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
}
}
fn lower_brz_or_nz(
fn lower_cond_br(
&mut self,
cc: &IntCC,
a: ValueRegs,

View File

@@ -194,8 +194,7 @@ mod tests {
let mut pos = FuncCursor::new(&mut func);
pos.insert_block(block0);
pos.ins().brnz(v0, block2, &[]);
pos.ins().jump(block1, &[]);
pos.ins().brif(v0, block2, &[], block1, &[]);
pos.insert_block(block1);
pos.ins().return_(&[]);

View File

@@ -3761,28 +3761,6 @@
(vec_element targets 1))))
;;;; Rules for `brz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Two-way conditional branch on zero. `targets` contains:
;; - element 0: target if the condition is true (i.e. value is zero)
;; - element 1: target if the condition is false (i.e. value is nonzero)
(rule (lower_branch (brz val_cond _) targets)
(emit_side_effect (cond_br_bool (invert_bool (value_nonzero val_cond))
(vec_element targets 0)
(vec_element targets 1))))
;;;; Rules for `brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Two-way conditional branch on nonzero. `targets` contains:
;; - element 0: target if the condition is true (i.e. value is nonzero)
;; - element 1: target if the condition is false (i.e. value is zero)
(rule (lower_branch (brnz val_cond _) targets)
(emit_side_effect (cond_br_bool (value_nonzero val_cond)
(vec_element targets 0)
(vec_element targets 1))))
;;;; Rules for `trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (trap trap_code))

View File

@@ -265,15 +265,12 @@ mod test {
pos.insert_block(bb0);
let v0 = pos.ins().iconst(I32, 0x1234);
let v1 = pos.ins().iadd(arg0, v0);
pos.ins().brnz(v1, bb1, &[]);
pos.ins().jump(bb2, &[]);
pos.ins().brif(v1, bb1, &[], bb2, &[]);
pos.insert_block(bb1);
pos.ins().brnz(v1, bb2, &[]);
pos.ins().jump(bb3, &[]);
pos.ins().brif(v1, bb2, &[], bb3, &[]);
pos.insert_block(bb2);
let v2 = pos.ins().iadd(v1, v0);
pos.ins().brnz(v2, bb2, &[]);
pos.ins().jump(bb1, &[]);
pos.ins().brif(v2, bb2, &[], bb1, &[]);
pos.insert_block(bb3);
let v3 = pos.ins().isub(v1, v0);
pos.ins().return_(&[v3]);

View File

@@ -362,7 +362,7 @@
;; One-way conditional branch: jcond cond target.
;;
;; This instruction is useful when we have conditional jumps depending on
;; more than two conditions, see for instance the lowering of Brz/brnz
;; more than two conditions, see for instance the lowering of Brif
;; with Fcmp inputs.
;;
;; A note of caution: in contexts where the branch target is another

View File

@@ -184,8 +184,7 @@ mod tests {
let mut pos = FuncCursor::new(&mut func);
pos.insert_block(block0);
pos.ins().brnz(v0, block2, &[]);
pos.ins().jump(block1, &[]);
pos.ins().brif(v0, block2, &[], block1, &[]);
pos.insert_block(block1);
pos.ins().return_(&[]);

View File

@@ -2904,41 +2904,6 @@
(jmp_cond (CC.NZ) then else))))
;; Rules for `brz` and `brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule 2 (lower_branch (brz (maybe_uextend (icmp cc a b)) _) (two_targets taken not_taken))
(let ((cmp IcmpCondResult (invert_icmp_cond_result (emit_cmp cc a b))))
(emit_side_effect (jmp_cond_icmp cmp taken not_taken))))
(rule 2 (lower_branch (brz (maybe_uextend (fcmp cc a b)) _) (two_targets taken not_taken))
(let ((cmp FcmpCondResult (emit_fcmp (floatcc_inverse cc) a b)))
(emit_side_effect (jmp_cond_fcmp cmp taken not_taken))))
(rule 1 (lower_branch (brz val @ (value_type $I128) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (cmp_zero_i128 (CC.NZ) val) taken not_taken)))
(rule 0 (lower_branch (brz val @ (value_type (ty_int_bool_or_ref)) _) (two_targets taken not_taken))
(emit_side_effect
(with_flags_side_effect (cmp_zero_int_bool_ref val)
(jmp_cond (CC.Z) taken not_taken))))
(rule 2 (lower_branch (brnz (maybe_uextend (icmp cc a b)) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (emit_cmp cc a b) taken not_taken)))
(rule 2 (lower_branch (brnz (maybe_uextend (fcmp cc a b)) _) (two_targets taken not_taken))
(let ((cmp FcmpCondResult (emit_fcmp cc a b)))
(emit_side_effect (jmp_cond_fcmp cmp taken not_taken))))
(rule 1 (lower_branch (brnz val @ (value_type $I128) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (cmp_zero_i128 (CC.Z) val) taken not_taken)))
(rule 0 (lower_branch (brnz val @ (value_type (ty_int_bool_or_ref)) _) (two_targets taken not_taken))
(emit_side_effect
(with_flags_side_effect (cmp_zero_int_bool_ref val)
(jmp_cond (CC.NZ) taken not_taken))))
;; Compare an I128 value to zero, returning a flags result suitable for making a
;; jump decision. The comparison is implemented as `(hi == 0) && (low == 0)`,
;; and the result can be interpreted as follows

View File

@@ -261,23 +261,20 @@ mod test {
let v0 = pos.ins().iconst(I32, 0x1234);
pos.set_srcloc(SourceLoc::new(2));
let v1 = pos.ins().iadd(arg0, v0);
pos.ins().brnz(v1, bb1, &[v1]);
pos.ins().jump(bb2, &[]);
pos.ins().brif(v1, bb1, &[v1], bb2, &[]);
pos.insert_block(bb1);
pos.set_srcloc(SourceLoc::new(3));
let v2 = pos.ins().isub(v1, v0);
pos.set_srcloc(SourceLoc::new(4));
let v3 = pos.ins().iadd(v2, bb1_param);
pos.ins().brnz(v1, bb2, &[]);
pos.ins().jump(bb3, &[v3]);
pos.ins().brif(v1, bb2, &[], bb3, &[v3]);
pos.func.layout.set_cold(bb2);
pos.insert_block(bb2);
pos.set_srcloc(SourceLoc::new(5));
let v4 = pos.ins().iadd(v1, v0);
pos.ins().brnz(v4, bb2, &[]);
pos.ins().jump(bb1, &[v4]);
pos.ins().brif(v4, bb2, &[], bb1, &[v4]);
pos.insert_block(bb3);
pos.set_srcloc(SourceLoc::new(6));