Cranelift(Aarch64): Optimize lowering of icmps with immediates (#5252)
We can encode more constants into 12-bit immediates if we do the following
rewrite for comparisons with odd constants:
A >= B + 1
==> A - 1 >= B
==> A > B
This commit is contained in:
@@ -1695,14 +1695,22 @@
|
||||
;;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select _flags @ (icmp cc x @ (value_type in_ty) y) rn rm)))
|
||||
(let ((cond Cond (cond_code cc)))
|
||||
(lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
cond ty rn rm)))
|
||||
(select (icmp cc
|
||||
x @ (value_type in_ty)
|
||||
y)
|
||||
rn
|
||||
rm)))
|
||||
(let ((comparison FlagsAndCC (lower_icmp_into_flags cc x y in_ty)))
|
||||
(lower_select (flags_and_cc_flags comparison)
|
||||
(cond_code (flags_and_cc_cc comparison))
|
||||
ty
|
||||
rn
|
||||
rm)))
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select _flags @ (fcmp cc x @ (value_type in_ty) y) rn rm)))
|
||||
(select (fcmp cc x @ (value_type in_ty) y)
|
||||
rn
|
||||
rm)))
|
||||
(let ((cond Cond (fp_cond_code cc)))
|
||||
(lower_select
|
||||
(fpu_cmp (scalar_size in_ty) x y)
|
||||
@@ -1729,12 +1737,16 @@
|
||||
;;;; Rules for `select_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select_spectre_guard
|
||||
(icmp cc x @ (value_type in_ty) y) if_true if_false)))
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(select_spectre_guard (icmp cc x @ (value_type in_ty) y)
|
||||
if_true
|
||||
if_false)))
|
||||
(let ((comparison FlagsAndCC (lower_icmp_into_flags cc x y in_ty))
|
||||
(dst ValueRegs (lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
cond ty if_true if_false))
|
||||
(flags_and_cc_flags comparison)
|
||||
(cond_code (flags_and_cc_cc comparison))
|
||||
ty
|
||||
if_true
|
||||
if_false))
|
||||
(_ InstOutput (side_effect (csdb))))
|
||||
dst))
|
||||
|
||||
@@ -2381,23 +2393,27 @@
|
||||
|
||||
;; `brz` following `icmp`
|
||||
(rule (lower_branch (brz (icmp cc x @ (value_type ty) y) _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(cond Cond (invert_cond cond)) ;; negate for `brz`
|
||||
(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)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (lower_icmp_into_flags cc x y ty)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
(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 (icmp cc x @ (value_type ty) y) _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(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)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (lower_icmp_into_flags cc x y ty)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
(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 (fcmp cc x @ (value_type (ty_scalar_float ty)) y) _ _) targets)
|
||||
(let ((cond Cond (fp_cond_code cc))
|
||||
|
||||
Reference in New Issue
Block a user