1;; `select`/`bitselect`-related rewrites
2
3;; remove select when both choices are the same
4(rule (simplify (select    ty _ x x)) (subsume x))
5(rule (simplify (bitselect ty _ x x)) (subsume x))
6
7;; Push zeroes to the right -- this makes the select `truthy`, as used elsewhere
8;; if icmp { 0 } else { nonzero } => if !icmp { nonzero } else { 0 }
9(rule (simplify (select sty (icmp cty cc x y)
10                        zero @ (iconst_u _ 0)
11                        nonzero @ (iconst_u _ (u64_when_non_zero))))
12    (select sty (icmp cty (intcc_complement cc) x y) nonzero zero))
13
14;; if icmp(x, y) { 1 } else { 0 } => uextend(icmp(x, y))
15(rule (simplify (select ty cmp @ (icmp _ cc x y)
16                        (iconst_u _ 1)
17                        (iconst_u _ 0)))
18    (uextend_maybe ty cmp))
19;; if icmp(x, y) { -1 } else { 0 } => uextend(icmp(x, y))
20(rule (simplify (select ty cmp@(icmp _ cc x y)
21                        (iconst_s _ -1)
22                        (iconst_s _ 0)))
23    (bmask ty cmp))
24
25;; Transform select-of-icmp into {u,s}{min,max} instructions where possible.
26(rule (simplify (select ty (sgt _ x y) x y)) (smax ty x y))
27(rule (simplify (select ty (sge _ x y) x y)) (smax ty x y))
28(rule (simplify (select ty (ugt _ x y) x y)) (umax ty x y))
29(rule (simplify (select ty (uge _ x y) x y)) (umax ty x y))
30(rule (simplify (select ty (slt _ x y) x y)) (smin ty x y))
31(rule (simplify (select ty (sle _ x y) x y)) (smin ty x y))
32(rule (simplify (select ty (ult _ x y) x y)) (umin ty x y))
33(rule (simplify (select ty (ule _ x y) x y)) (umin ty x y))
34
35;; These are the same rules as above, but when the operands for select are swapped
36(rule (simplify (select ty (slt _ x y) y x)) (smax ty x y))
37(rule (simplify (select ty (sle _ x y) y x)) (smax ty x y))
38(rule (simplify (select ty (ult _ x y) y x)) (umax ty x y))
39(rule (simplify (select ty (ule _ x y) y x)) (umax ty x y))
40(rule (simplify (select ty (sgt _ x y) y x)) (smin ty x y))
41(rule (simplify (select ty (sge _ x y) y x)) (smin ty x y))
42(rule (simplify (select ty (ugt _ x y) y x)) (umin ty x y))
43(rule (simplify (select ty (uge _ x y) y x)) (umin ty x y))
44
45;; Transform bitselect-of-icmp into {u,s}{min,max} instructions where possible.
46(rule (simplify (bitselect ty @ (multi_lane _ _) (sgt _ x y) x y)) (smax ty x y))
47(rule (simplify (bitselect ty @ (multi_lane _ _) (sge _ x y) x y)) (smax ty x y))
48(rule (simplify (bitselect ty @ (multi_lane _ _) (ugt _ x y) x y)) (umax ty x y))
49(rule (simplify (bitselect ty @ (multi_lane _ _) (uge _ x y) x y)) (umax ty x y))
50(rule (simplify (bitselect ty @ (multi_lane _ _) (slt _ x y) x y)) (smin ty x y))
51(rule (simplify (bitselect ty @ (multi_lane _ _) (sle _ x y) x y)) (smin ty x y))
52(rule (simplify (bitselect ty @ (multi_lane _ _) (ult _ x y) x y)) (umin ty x y))
53(rule (simplify (bitselect ty @ (multi_lane _ _) (ule _ x y) x y)) (umin ty x y))
54
55;; These are the same rules as above, but when the operands for select are swapped
56(rule (simplify (bitselect ty @ (multi_lane _ _) (slt _ x y) y x)) (smax ty x y))
57(rule (simplify (bitselect ty @ (multi_lane _ _) (sle _ x y) y x)) (smax ty x y))
58(rule (simplify (bitselect ty @ (multi_lane _ _) (ult _ x y) y x)) (umax ty x y))
59(rule (simplify (bitselect ty @ (multi_lane _ _) (ule _ x y) y x)) (umax ty x y))
60(rule (simplify (bitselect ty @ (multi_lane _ _) (sgt _ x y) y x)) (smin ty x y))
61(rule (simplify (bitselect ty @ (multi_lane _ _) (sge _ x y) y x)) (smin ty x y))
62(rule (simplify (bitselect ty @ (multi_lane _ _) (ugt _ x y) y x)) (umin ty x y))
63(rule (simplify (bitselect ty @ (multi_lane _ _) (uge _ x y) y x)) (umin ty x y))
64
65;; (c & x) | (~c & y) -> (bitselect c x y)
66;; These are all the same rule, just with different permutations of the operands
67;;
68;; We currently only match vectors since scalar floats and i128's are not supported
69;; in some backends.
70(rule (simplify (bor (ty_vec128 ty) (band ty c x) (band ty (bnot ty c) y))) (bitselect ty c x y))
71(rule (simplify (bor (ty_vec128 ty) (band ty c x) (band ty y (bnot ty c) ))) (bitselect ty c x y))
72(rule (simplify (bor (ty_vec128 ty) (band ty x c) (band ty (bnot ty c) y))) (bitselect ty c x y))
73(rule (simplify (bor (ty_vec128 ty) (band ty x c) (band ty y (bnot ty c) ))) (bitselect ty c x y))
74(rule (simplify (bor (ty_vec128 ty) (band ty (bnot ty c) y) (band ty c x))) (bitselect ty c x y))
75(rule (simplify (bor (ty_vec128 ty) (band ty (bnot ty c) y) (band ty x c))) (bitselect ty c x y))
76(rule (simplify (bor (ty_vec128 ty) (band ty y (bnot ty c)) (band ty c x))) (bitselect ty c x y))
77(rule (simplify (bor (ty_vec128 ty) (band ty y (bnot ty c)) (band ty x c))) (bitselect ty c x y))
78
79;; Lift an extend operation outside of a `select` if the extend is happening
80;; on both the consequent and the alternative.
81(rule (simplify (select ty cond
82                           (uextend ty a @ (value_type small))
83                           (uextend ty b @ (value_type small))))
84      (uextend ty (select small cond a b)))
85(rule (simplify (select ty cond
86                           (sextend ty a @ (value_type small))
87                           (sextend ty b @ (value_type small))))
88      (sextend ty (select small cond a b)))
89
90(rule (simplify (select ty (sgt _ x (iconst_u ty 0)) x (ineg ty x))) (subsume (iabs ty x)))
91(rule (simplify (select ty (sge _ x (iconst_u ty 0)) x (ineg ty x))) (subsume (iabs ty x)))
92(rule (simplify (select ty (sle _ x (iconst_u ty 0)) (ineg ty x) x)) (subsume (iabs ty x)))
93(rule (simplify (select ty (slt _ x (iconst_u ty 0)) (ineg ty x) x)) (subsume (iabs ty x)))
94
95;; fold add-select to select-add
96(rule (simplify
97        (iadd ty (select ty c (iconst_u ty x) (iconst_u ty y)) (iconst_u ty z)))
98        (select ty c
99            (iconst ty (imm64_masked ty (u64_wrapping_add x z)))
100            (iconst ty (imm64_masked ty (u64_wrapping_add y z)))))
101
102(rule (simplify (select ty d a (select ty d _ y))) (select ty d a y))
103(rule (simplify (select ty d (select ty d x _) a)) (select ty d x a))
104
105;; min x y < x => false and its commutative versions
106(rule (simplify (sgt (fits_in_64 ty) (smin _ x y) x)) (iconst_u ty 0))
107(rule (simplify (sgt (fits_in_64 ty) (smin _ x y) y)) (iconst_u ty 0))
108(rule (simplify (slt (fits_in_64 ty) x (smin _ x z))) (iconst_u ty 0))
109(rule (simplify (slt (fits_in_64 ty) x (smin _ y x))) (iconst_u ty 0))
110(rule (simplify (ugt (fits_in_64 ty) (umin _ x y) x)) (iconst_u ty 0))
111(rule (simplify (ugt (fits_in_64 ty) (umin _ x y) y)) (iconst_u ty 0))
112(rule (simplify (ult (fits_in_64 ty) x (umin _ x z))) (iconst_u ty 0))
113(rule (simplify (ult (fits_in_64 ty) x (umin _ y x))) (iconst_u ty 0))
114
115;; (x == y) ? x : y => y
116;; select(eq/ne) patterns that always collapse to y.
117(rule (simplify (select ty (eq cty x y) x y)) (subsume y))
118(rule (simplify (select ty (ne cty x y) y x)) (subsume y))
119(rule (simplify (select ty (eq cty y x) x y)) (subsume y))
120(rule (simplify (select ty (ne cty y x) y x)) (subsume y))
121
122;; (x | (y != z)) ? y : z  ==> y
123(rule (simplify (select ty (bor cty x (ne cty y z)) y z)) (subsume y))
124(rule (simplify (select ty (bor cty (ne cty y z) x) y z)) (subsume y))
125(rule (simplify (select ty (bor cty x (ne cty z y)) y z)) (subsume y))
126(rule (simplify (select ty (bor cty (ne cty z y) x) y z)) (subsume y))
127
128;; (x == y) ? x : (x | y)  ==> (x | y)
129;; and equivalent operand-order variants.
130(rule (simplify (select ty (eq cty x y) x (bor ty x y))) (bor ty x y))
131(rule (simplify (select ty (ne cty x y) (bor ty x y) x)) (bor ty x y))
132(rule (simplify (select ty (eq cty x y) x (bor ty y x))) (bor ty x y))
133(rule (simplify (select ty (ne cty x y) (bor ty y x) x)) (bor ty x y))
134(rule (simplify (select ty (eq cty y x) x (bor ty x y))) (bor ty x y))
135(rule (simplify (select ty (ne cty y x) (bor ty x y) x)) (bor ty x y))
136(rule (simplify (select ty (eq cty y x) x (bor ty y x))) (bor ty x y))
137(rule (simplify (select ty (ne cty y x) (bor ty y x) x)) (bor ty x y))
138
139;; (x != y) ? (x & y) : y  ==> (x & y)
140;; and equivalent operand-order variants.
141(rule (simplify (select ty (ne cty x y) (band ty x y) y)) (band ty x y))
142(rule (simplify (select ty (eq cty x y) y (band ty x y))) (band ty x y))
143(rule (simplify (select ty (ne cty x y) (band ty y x) y)) (band ty x y))
144(rule (simplify (select ty (eq cty x y) y (band ty y x))) (band ty x y))
145(rule (simplify (select ty (ne cty y x) (band ty x y) y)) (band ty x y))
146(rule (simplify (select ty (eq cty y x) y (band ty x y))) (band ty x y))
147(rule (simplify (select ty (ne cty y x) (band ty y x) y)) (band ty x y))
148(rule (simplify (select ty (eq cty y x) y (band ty y x))) (band ty x y))
149
150;; (x <_u y) ? 1 : (x == y)  ==> (x <=_u y)
151;; and equivalent operand-order variants.
152(rule (simplify (select ty (ult cty x y) (iconst_u ty 1) (eq ty x y))) (ule ty x y))
153(rule (simplify (select ty (uge cty x y) (eq ty x y) (iconst_u ty 1))) (ule ty x y))
154(rule (simplify (select ty (ugt cty y x) (iconst_u ty 1) (eq ty x y))) (ule ty x y))
155(rule (simplify (select ty (ule cty y x) (eq ty x y) (iconst_u ty 1))) (ule ty x y))
156(rule (simplify (select ty (ult cty x y) (iconst_u ty 1) (eq ty y x))) (ule ty x y))
157(rule (simplify (select ty (uge cty x y) (eq ty y x) (iconst_u ty 1))) (ule ty x y))
158(rule (simplify (select ty (ugt cty y x) (iconst_u ty 1) (eq ty y x))) (ule ty x y))
159(rule (simplify (select ty (ule cty y x) (eq ty y x) (iconst_u ty 1))) (ule ty x y))
160
161;; (x < y) ? 1 : (x > y)  ==> (x != y)
162;; and equivalent operand-order variants.
163(rule (simplify (select ty (slt cty x y) (iconst_u ty 1) (sgt ty x y))) (ne ty x y))
164(rule (simplify (select ty (sge cty x y) (sgt ty x y) (iconst_u ty 1))) (ne ty x y))
165(rule (simplify (select ty (sgt cty y x) (iconst_u ty 1) (sgt ty x y))) (ne ty x y))
166(rule (simplify (select ty (sle cty y x) (sgt ty x y) (iconst_u ty 1))) (ne ty x y))
167(rule (simplify (select ty (slt cty x y) (iconst_u ty 1) (slt ty y x))) (ne ty x y))
168(rule (simplify (select ty (sge cty x y) (slt ty y x) (iconst_u ty 1))) (ne ty x y))
169(rule (simplify (select ty (sgt cty y x) (iconst_u ty 1) (slt ty y x))) (ne ty x y))
170(rule (simplify (select ty (sle cty y x) (slt ty y x) (iconst_u ty 1))) (ne ty x y))
171(rule (simplify (select ty (ult cty x y) (iconst_u ty 1) (ugt ty x y))) (ne ty x y))
172(rule (simplify (select ty (uge cty x y) (ugt ty x y) (iconst_u ty 1))) (ne ty x y))
173(rule (simplify (select ty (ugt cty y x) (iconst_u ty 1) (ugt ty x y))) (ne ty x y))
174(rule (simplify (select ty (ule cty y x) (ugt ty x y) (iconst_u ty 1))) (ne ty x y))
175(rule (simplify (select ty (ult cty x y) (iconst_u ty 1) (ult ty y x))) (ne ty x y))
176(rule (simplify (select ty (uge cty x y) (ult ty y x) (iconst_u ty 1))) (ne ty x y))
177(rule (simplify (select ty (ugt cty y x) (iconst_u ty 1) (ult ty y x))) (ne ty x y))
178(rule (simplify (select ty (ule cty y x) (ult ty y x) (iconst_u ty 1))) (ne ty x y))
179
180;; (x ? 1 : (x | y))  ==>  (x ? 1 : y)
181(rule (simplify (select ty x (iconst_u ty 1) (bor ty x y))) (select ty x (iconst_u ty 1) y))
182(rule (simplify (select ty x (iconst_u ty 1) (bor ty y x))) (select ty x (iconst_u ty 1) y))
183
184;; if x == n then (y - n) else (y - x)  ==>  (y - x)
185;; and equivalent predicate/operand-order variants.
186(rule (simplify (select ty (eq cty x (iconst_u ty n)) (isub ty y (iconst_u ty n)) (isub ty y x))) (isub ty y x))
187(rule (simplify (select ty (ne cty x (iconst_u ty n)) (isub ty y x) (isub ty y (iconst_u ty n)))) (isub ty y x))
188(rule (simplify (select ty (eq cty (iconst_u ty n) x) (isub ty y (iconst_u ty n)) (isub ty y x))) (isub ty y x))
189(rule (simplify (select ty (ne cty (iconst_u ty n) x) (isub ty y x) (isub ty y (iconst_u ty n)))) (isub ty y x))
190
191;; select(cond, eq(z, y), eq(p, y))  ==>  eq(y, select(cond, z, p))
192(rule (simplify (select ty x (eq ty z y) (eq ty (iconst_u cty p) y))) (eq ty y (select cty x z (iconst_u cty p))))
193(rule (simplify (select ty x (eq ty z y) (eq ty y (iconst_u cty p)))) (eq ty y (select cty x z (iconst_u cty p))))
194(rule (simplify (select ty x (eq ty y z) (eq ty (iconst_u cty p) y))) (eq ty y (select cty x z (iconst_u cty p))))
195(rule (simplify (select ty x (eq ty y z) (eq ty y (iconst_u cty p)))) (eq ty y (select cty x z (iconst_u cty p))))
196