1;; `select`/`bitselect`-related rewrites
2
3;; remove select when both choices are the same
4(rule (simplify (select    ty _ x x)) x)
5(rule (simplify (bitselect ty _ x x)) x)
6
7;; if icmp(x, y) { 1 } else { 0 } => uextend(icmp(x, y))
8(rule (simplify (select ty cmp@(icmp _ cc x y)
9                        (iconst_u _ 1)
10                        (iconst_u _ 0)))
11    (uextend_from_i8 ty cmp))
12;; if icmp(x, y) { 0 } else { 1 } => uextend(!icmp(x, y))
13(rule (simplify (select sty (icmp cty cc x y)
14                        (iconst_u _ 0)
15                        (iconst_u _ 1)))
16    (uextend_from_i8 sty (icmp cty (intcc_complement cc) x y)))
17
18;; Transform select-of-icmp into {u,s}{min,max} instructions where possible.
19(rule (simplify (select ty (sgt _ x y) x y)) (smax ty x y))
20(rule (simplify (select ty (sge _ x y) x y)) (smax ty x y))
21(rule (simplify (select ty (ugt _ x y) x y)) (umax ty x y))
22(rule (simplify (select ty (uge _ x y) x y)) (umax ty x y))
23(rule (simplify (select ty (slt _ x y) x y)) (smin ty x y))
24(rule (simplify (select ty (sle _ x y) x y)) (smin ty x y))
25(rule (simplify (select ty (ult _ x y) x y)) (umin ty x y))
26(rule (simplify (select ty (ule _ x y) x y)) (umin ty x y))
27
28;; These are the same rules as above, but when the operands for select are swapped
29(rule (simplify (select ty (slt _ x y) y x)) (smax ty x y))
30(rule (simplify (select ty (sle _ x y) y x)) (smax ty x y))
31(rule (simplify (select ty (ult _ x y) y x)) (umax ty x y))
32(rule (simplify (select ty (ule _ x y) y x)) (umax ty x y))
33(rule (simplify (select ty (sgt _ x y) y x)) (smin ty x y))
34(rule (simplify (select ty (sge _ x y) y x)) (smin ty x y))
35(rule (simplify (select ty (ugt _ x y) y x)) (umin ty x y))
36(rule (simplify (select ty (uge _ x y) y x)) (umin ty x y))
37
38;; Transform bitselect-of-icmp into {u,s}{min,max} instructions where possible.
39(rule (simplify (bitselect ty @ (multi_lane _ _) (sgt _ x y) x y)) (smax ty x y))
40(rule (simplify (bitselect ty @ (multi_lane _ _) (sge _ x y) x y)) (smax ty x y))
41(rule (simplify (bitselect ty @ (multi_lane _ _) (ugt _ x y) x y)) (umax ty x y))
42(rule (simplify (bitselect ty @ (multi_lane _ _) (uge _ x y) x y)) (umax ty x y))
43(rule (simplify (bitselect ty @ (multi_lane _ _) (slt _ x y) x y)) (smin ty x y))
44(rule (simplify (bitselect ty @ (multi_lane _ _) (sle _ x y) x y)) (smin ty x y))
45(rule (simplify (bitselect ty @ (multi_lane _ _) (ult _ x y) x y)) (umin ty x y))
46(rule (simplify (bitselect ty @ (multi_lane _ _) (ule _ x y) x y)) (umin ty x y))
47
48;; These are the same rules as above, but when the operands for select are swapped
49(rule (simplify (bitselect ty @ (multi_lane _ _) (slt _ x y) y x)) (smax ty x y))
50(rule (simplify (bitselect ty @ (multi_lane _ _) (sle _ x y) y x)) (smax ty x y))
51(rule (simplify (bitselect ty @ (multi_lane _ _) (ult _ x y) y x)) (umax ty x y))
52(rule (simplify (bitselect ty @ (multi_lane _ _) (ule _ x y) y x)) (umax ty x y))
53(rule (simplify (bitselect ty @ (multi_lane _ _) (sgt _ x y) y x)) (smin ty x y))
54(rule (simplify (bitselect ty @ (multi_lane _ _) (sge _ x y) y x)) (smin ty x y))
55(rule (simplify (bitselect ty @ (multi_lane _ _) (ugt _ x y) y x)) (umin ty x y))
56(rule (simplify (bitselect ty @ (multi_lane _ _) (uge _ x y) y x)) (umin ty x y))
57
58;; (c & x) | (~c & y) -> (bitselect c x y)
59;; These are all the same rule, just with different permutations of the operands
60;;
61;; We currently only match vectors since scalar floats and i128's are not supported
62;; in some backends.
63(rule (simplify (bor (ty_vec128 ty) (band ty c x) (band ty (bnot ty c) y))) (bitselect ty c x y))
64(rule (simplify (bor (ty_vec128 ty) (band ty c x) (band ty y (bnot ty c) ))) (bitselect ty c x y))
65(rule (simplify (bor (ty_vec128 ty) (band ty x c) (band ty (bnot ty c) y))) (bitselect ty c x y))
66(rule (simplify (bor (ty_vec128 ty) (band ty x c) (band ty y (bnot ty c) ))) (bitselect ty c x y))
67(rule (simplify (bor (ty_vec128 ty) (band ty (bnot ty c) y) (band ty c x))) (bitselect ty c x y))
68(rule (simplify (bor (ty_vec128 ty) (band ty (bnot ty c) y) (band ty x c))) (bitselect ty c x y))
69(rule (simplify (bor (ty_vec128 ty) (band ty y (bnot ty c)) (band ty c x))) (bitselect ty c x y))
70(rule (simplify (bor (ty_vec128 ty) (band ty y (bnot ty c)) (band ty x c))) (bitselect ty c x y))
71
72;; extend from i8 to i8 is invalid CLIF, so this allows fixing that in the output
73;; rather than needing to duplicate rules for the different width categories
74(decl uextend_from_i8 (Type Value) Value)
75(rule 0 (uextend_from_i8 ty val) (uextend ty val))
76(rule 1 (uextend_from_i8 $I8 val) val)
77