x64: improve generation of i128 icmp (#3946)

Previously, we used the flags of `AND` for `SETcc`. This change uses
`TEST` instead, which discards the AND result but sets the flags needed
for `SETcc`. This reduces register pressure slightly for this sequence.
This commit is contained in:
Andrew Brown
2022-03-18 16:36:31 -07:00
committed by GitHub
parent 41594dc5d9
commit 5fa104205d
4 changed files with 131 additions and 134 deletions

View File

@@ -1521,14 +1521,15 @@
(cmp_hi Reg (with_flags_reg (cmp (OperandSize.Size64) b_hi a_hi) (setcc (CC.Z))))
;; At this point, `cmp_lo` and `cmp_hi` contain either 0 or 1 in the
;; lowest 8 bits--`SETcc` guarantees this. The upper bits may be
;; unchanged so we must compare against 1; this instruction combines
;; `cmp_lo` and `cmp_hi` for that final comparison.
;; unchanged so we must compare against 1 below; this instruction
;; combines `cmp_lo` and `cmp_hi` for that final comparison.
(cmp Reg (x64_and $I64 cmp_lo cmp_hi)))
;; We can use the flag-setting behavior of `AND` to set the final
;; bits. If the result of `AND` is zero, then the `ZF` will be set;
;; if either of the halves `AND`s to 0, they were not equal,
;; therefore we `SETcc` with `NZ`.
(with_flags (x64_and_with_flags_paired $I64 cmp (RegMemImm.Imm 1)) (setcc (CC.NZ)))))
;; We must compare one more time against the immediate value 1 to
;; check if both `cmp_lo` and `cmp_hi` are true. If `cmp AND 1 == 0`
;; then the `ZF` will be set (see `TEST` definition); if either of
;; the halves `AND`s to 0, they were not equal, therefore we `SETcc`
;; with `NZ`.
(with_flags (test (OperandSize.Size64) (RegMemImm.Imm 1) cmp) (setcc (CC.NZ)))))
(rule (lower (icmp (IntCC.NotEqual) a @ (value_type $I128) b))
(let ((a_lo Gpr (value_regs_get_gpr a 0))
@@ -1539,7 +1540,7 @@
(cmp_hi Reg (with_flags_reg (cmp (OperandSize.Size64) b_hi a_hi) (setcc (CC.NZ))))
;; See comments for `IntCC.Equal`.
(cmp Reg (or $I64 cmp_lo cmp_hi)))
(with_flags (x64_and_with_flags_paired $I64 cmp (RegMemImm.Imm 1)) (setcc (CC.NZ)))))
(with_flags (test (OperandSize.Size64) (RegMemImm.Imm 1) cmp) (setcc (CC.NZ)))))
;;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;