nir/algebraic: Replace checks that a value is between (or not) [0, 1]
[mesa.git] / src / compiler / nir / nir_search_helpers.h
1 /*
2 * Copyright © 2016 Red Hat
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rob Clark <robclark@freedesktop.org>
25 */
26
27 #ifndef _NIR_SEARCH_HELPERS_
28 #define _NIR_SEARCH_HELPERS_
29
30 #include "nir.h"
31 #include "util/bitscan.h"
32 #include <math.h>
33
34 static inline bool
35 is_pos_power_of_two(nir_alu_instr *instr, unsigned src, unsigned num_components,
36 const uint8_t *swizzle)
37 {
38 /* only constant srcs: */
39 if (!nir_src_is_const(instr->src[src].src))
40 return false;
41
42 for (unsigned i = 0; i < num_components; i++) {
43 switch (nir_op_infos[instr->op].input_types[src]) {
44 case nir_type_int: {
45 int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
46 if (val <= 0 || !util_is_power_of_two_or_zero64(val))
47 return false;
48 break;
49 }
50 case nir_type_uint: {
51 uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
52 if (val == 0 || !util_is_power_of_two_or_zero64(val))
53 return false;
54 break;
55 }
56 default:
57 return false;
58 }
59 }
60
61 return true;
62 }
63
64 static inline bool
65 is_neg_power_of_two(nir_alu_instr *instr, unsigned src, unsigned num_components,
66 const uint8_t *swizzle)
67 {
68 /* only constant srcs: */
69 if (!nir_src_is_const(instr->src[src].src))
70 return false;
71
72 for (unsigned i = 0; i < num_components; i++) {
73 switch (nir_op_infos[instr->op].input_types[src]) {
74 case nir_type_int: {
75 int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
76 if (val >= 0 || !util_is_power_of_two_or_zero64(-val))
77 return false;
78 break;
79 }
80 default:
81 return false;
82 }
83 }
84
85 return true;
86 }
87
88 static inline bool
89 is_zero_to_one(nir_alu_instr *instr, unsigned src, unsigned num_components,
90 const uint8_t *swizzle)
91 {
92 /* only constant srcs: */
93 if (!nir_src_is_const(instr->src[src].src))
94 return false;
95
96 for (unsigned i = 0; i < num_components; i++) {
97 switch (nir_op_infos[instr->op].input_types[src]) {
98 case nir_type_float: {
99 double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
100 if (isnan(val) || val < 0.0f || val > 1.0f)
101 return false;
102 break;
103 }
104 default:
105 return false;
106 }
107 }
108
109 return true;
110 }
111
112 /**
113 * Exclusive compare with (0, 1).
114 *
115 * This differs from \c is_zero_to_one because that function tests 0 <= src <=
116 * 1 while this function tests 0 < src < 1.
117 */
118 static inline bool
119 is_gt_0_and_lt_1(nir_alu_instr *instr, unsigned src, unsigned num_components,
120 const uint8_t *swizzle)
121 {
122 /* only constant srcs: */
123 if (!nir_src_is_const(instr->src[src].src))
124 return false;
125
126 for (unsigned i = 0; i < num_components; i++) {
127 switch (nir_op_infos[instr->op].input_types[src]) {
128 case nir_type_float: {
129 double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
130 if (isnan(val) || val <= 0.0f || val >= 1.0f)
131 return false;
132 break;
133 }
134 default:
135 return false;
136 }
137 }
138
139 return true;
140 }
141
142 static inline bool
143 is_not_const_zero(nir_alu_instr *instr, unsigned src, unsigned num_components,
144 const uint8_t *swizzle)
145 {
146 if (nir_src_as_const_value(instr->src[src].src) == NULL)
147 return true;
148
149 for (unsigned i = 0; i < num_components; i++) {
150 switch (nir_op_infos[instr->op].input_types[src]) {
151 case nir_type_float:
152 if (nir_src_comp_as_float(instr->src[src].src, swizzle[i]) == 0.0)
153 return false;
154 break;
155 case nir_type_bool:
156 case nir_type_int:
157 case nir_type_uint:
158 if (nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) == 0)
159 return false;
160 break;
161 default:
162 return false;
163 }
164 }
165
166 return true;
167 }
168
169 static inline bool
170 is_not_const(nir_alu_instr *instr, unsigned src, UNUSED unsigned num_components,
171 UNUSED const uint8_t *swizzle)
172 {
173 return !nir_src_is_const(instr->src[src].src);
174 }
175
176 static inline bool
177 is_not_fmul(nir_alu_instr *instr, unsigned src,
178 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
179 {
180 nir_alu_instr *src_alu =
181 nir_src_as_alu_instr(instr->src[src].src);
182
183 if (src_alu == NULL)
184 return true;
185
186 if (src_alu->op == nir_op_fneg)
187 return is_not_fmul(src_alu, 0, 0, NULL);
188
189 return src_alu->op != nir_op_fmul;
190 }
191
192 static inline bool
193 is_fsign(nir_alu_instr *instr, unsigned src,
194 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
195 {
196 nir_alu_instr *src_alu =
197 nir_src_as_alu_instr(instr->src[src].src);
198
199 if (src_alu == NULL)
200 return false;
201
202 if (src_alu->op == nir_op_fneg)
203 src_alu = nir_src_as_alu_instr(src_alu->src[0].src);
204
205 return src_alu->op == nir_op_fsign;
206 }
207
208 static inline bool
209 is_not_const_and_not_fsign(nir_alu_instr *instr, unsigned src,
210 unsigned num_components, const uint8_t *swizzle)
211 {
212 return is_not_const(instr, src, num_components, swizzle) &&
213 !is_fsign(instr, src, num_components, swizzle);
214 }
215
216 static inline bool
217 is_used_once(nir_alu_instr *instr)
218 {
219 bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses);
220 bool zero_use = list_empty(&instr->dest.dest.ssa.uses);
221
222 if (zero_if_use && zero_use)
223 return false;
224
225 if (!zero_if_use && list_is_singular(&instr->dest.dest.ssa.uses))
226 return false;
227
228 if (!zero_use && list_is_singular(&instr->dest.dest.ssa.if_uses))
229 return false;
230
231 if (!list_is_singular(&instr->dest.dest.ssa.if_uses) &&
232 !list_is_singular(&instr->dest.dest.ssa.uses))
233 return false;
234
235 return true;
236 }
237
238 static inline bool
239 is_used_by_if(nir_alu_instr *instr)
240 {
241 return !list_empty(&instr->dest.dest.ssa.if_uses);
242 }
243
244 static inline bool
245 is_not_used_by_if(nir_alu_instr *instr)
246 {
247 return list_empty(&instr->dest.dest.ssa.if_uses);
248 }
249
250 static inline bool
251 is_used_by_non_fsat(nir_alu_instr *instr)
252 {
253 nir_foreach_use(src, &instr->dest.dest.ssa) {
254 const nir_instr *const user_instr = src->parent_instr;
255
256 if (user_instr->type != nir_instr_type_alu)
257 return true;
258
259 const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
260
261 assert(instr != user_alu);
262 if (user_alu->op != nir_op_fsat)
263 return true;
264 }
265
266 return false;
267 }
268
269 /**
270 * Returns true if a NIR ALU src represents a constant integer
271 * of either 32 or 64 bits, and the higher word (bit-size / 2)
272 * of all its components is zero.
273 */
274 static inline bool
275 is_upper_half_zero(nir_alu_instr *instr, unsigned src,
276 unsigned num_components, const uint8_t *swizzle)
277 {
278 if (nir_src_as_const_value(instr->src[src].src) == NULL)
279 return false;
280
281 for (unsigned i = 0; i < num_components; i++) {
282 unsigned half_bit_size = nir_src_bit_size(instr->src[src].src) / 2;
283 uint32_t high_bits = ((1 << half_bit_size) - 1) << half_bit_size;
284 if ((nir_src_comp_as_uint(instr->src[src].src,
285 swizzle[i]) & high_bits) != 0) {
286 return false;
287 }
288 }
289
290 return true;
291 }
292
293 /**
294 * Returns true if a NIR ALU src represents a constant integer
295 * of either 32 or 64 bits, and the lower word (bit-size / 2)
296 * of all its components is zero.
297 */
298 static inline bool
299 is_lower_half_zero(nir_alu_instr *instr, unsigned src,
300 unsigned num_components, const uint8_t *swizzle)
301 {
302 if (nir_src_as_const_value(instr->src[src].src) == NULL)
303 return false;
304
305 for (unsigned i = 0; i < num_components; i++) {
306 uint32_t low_bits =
307 (1 << (nir_src_bit_size(instr->src[src].src) / 2)) - 1;
308 if ((nir_src_comp_as_int(instr->src[src].src, swizzle[i]) & low_bits) != 0)
309 return false;
310 }
311
312 return true;
313 }
314
315 static inline bool
316 no_signed_wrap(nir_alu_instr *instr)
317 {
318 return instr->no_signed_wrap;
319 }
320
321 static inline bool
322 no_unsigned_wrap(nir_alu_instr *instr)
323 {
324 return instr->no_unsigned_wrap;
325 }
326
327 #endif /* _NIR_SEARCH_ */