cranelift: Optimize select+icmp into {s,u}{min,max} (#5546)
* cranelift: Optimize `select+icmp` into `{s,u}{min,max}`
* cranelift: Add generic egraph icmp reverse rule
* cranelift: Optimize `vselect+icmp` into `{s,u}{min,max}`
* cranelift: Optimize some `vselect+fcmp` into `f{min,max}_pseudo`
* cranelift: Add inverted forms of min/max rules
This commit is contained in:
@@ -345,3 +345,131 @@
|
||||
(uextend $I64 x @ (value_type $I32))
|
||||
(iconst _ (u64_from_imm64 0))))
|
||||
(iconst ty (imm64 1)))
|
||||
|
||||
|
||||
;; Transform select-of-icmp into {u,s}{min,max} instructions where possible.
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedGreaterThan) x y) x y))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) x y))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedGreaterThan) x y) x y))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) x y))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedLessThan) x y) x y))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) x y))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedLessThan) x y) x y))
|
||||
(umin ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) x y))
|
||||
(umin ty x y))
|
||||
|
||||
|
||||
;; These are the same rules as above, but when the operands for select are swapped
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedLessThan) x y) y x))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) y x))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedLessThan) x y) y x))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) y x))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedGreaterThan) x y) y x))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) y x))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedGreaterThan) x y) y x))
|
||||
(umin ty x y))
|
||||
(rule (simplify
|
||||
(select ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) y x))
|
||||
(umin ty x y))
|
||||
|
||||
;; Transform vselect-of-icmp into {u,s}{min,max} instructions where possible.
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedGreaterThan) x y) x y))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) x y))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedGreaterThan) x y) x y))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) x y))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedLessThan) x y) x y))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) x y))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedLessThan) x y) x y))
|
||||
(umin ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) x y))
|
||||
(umin ty x y))
|
||||
|
||||
;; These are the same rules as above, but when the operands for select are swapped
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedLessThan) x y) y x))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) y x))
|
||||
(smax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedLessThan) x y) y x))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) y x))
|
||||
(umax ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedGreaterThan) x y) y x))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) y x))
|
||||
(smin ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedGreaterThan) x y) y x))
|
||||
(umin ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) y x))
|
||||
(umin ty x y))
|
||||
|
||||
;; For floats convert fcmp lt into pseudo_min and gt into pseudo_max
|
||||
;;
|
||||
;; fmax_pseudo docs state:
|
||||
;; The behaviour for this operations is defined as fmax_pseudo(a, b) = (a < b) ? b : a, and the behaviour for zero
|
||||
;; or NaN inputs follows from the behaviour of < with such inputs.
|
||||
;;
|
||||
;; That is exactly the operation that we match here!
|
||||
(rule (simplify
|
||||
(select ty (fcmp _ (FloatCC.LessThan) x y) x y))
|
||||
(fmin_pseudo ty x y))
|
||||
(rule (simplify
|
||||
(select ty (fcmp _ (FloatCC.GreaterThan) x y) x y))
|
||||
(fmax_pseudo ty x y))
|
||||
|
||||
;; Do the same for vectors
|
||||
(rule (simplify
|
||||
(vselect ty (fcmp _ (FloatCC.LessThan) x y) x y))
|
||||
(fmin_pseudo ty x y))
|
||||
(rule (simplify
|
||||
(vselect ty (fcmp _ (FloatCC.GreaterThan) x y) x y))
|
||||
(fmax_pseudo ty x y))
|
||||
|
||||
Reference in New Issue
Block a user