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 <math.h>
31 #include "util/bitscan.h"
32 #include "nir.h"
33 #include "nir_range_analysis.h"
34
35 static inline bool
is_pos_power_of_two(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)36 is_pos_power_of_two(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
37 unsigned src, unsigned num_components,
38 const uint8_t *swizzle)
39 {
40 /* only constant srcs: */
41 if (!nir_src_is_const(instr->src[src].src))
42 return false;
43
44 for (unsigned i = 0; i < num_components; i++) {
45 nir_alu_type type = nir_op_infos[instr->op].input_types[src];
46 switch (nir_alu_type_get_base_type(type)) {
47 case nir_type_int: {
48 int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
49 if (val <= 0 || !util_is_power_of_two_or_zero64(val))
50 return false;
51 break;
52 }
53 case nir_type_uint: {
54 uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
55 if (val == 0 || !util_is_power_of_two_or_zero64(val))
56 return false;
57 break;
58 }
59 default:
60 return false;
61 }
62 }
63
64 return true;
65 }
66
67 static inline bool
is_neg_power_of_two(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)68 is_neg_power_of_two(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
69 unsigned src, unsigned num_components,
70 const uint8_t *swizzle)
71 {
72 /* only constant srcs: */
73 if (!nir_src_is_const(instr->src[src].src))
74 return false;
75
76 int64_t int_min = u_intN_min(instr->src[src].src.ssa->bit_size);
77
78 for (unsigned i = 0; i < num_components; i++) {
79 nir_alu_type type = nir_op_infos[instr->op].input_types[src];
80 switch (nir_alu_type_get_base_type(type)) {
81 case nir_type_int: {
82 int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
83 /* "int_min" is a power-of-two, but negation can cause overflow. */
84 if (val == int_min || val >= 0 || !util_is_power_of_two_or_zero64(-val))
85 return false;
86 break;
87 }
88 default:
89 return false;
90 }
91 }
92
93 return true;
94 }
95
96 static inline bool
is_bitcount2(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)97 is_bitcount2(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
98 unsigned src, unsigned num_components,
99 const uint8_t *swizzle)
100 {
101 /* only constant srcs: */
102 if (!nir_src_is_const(instr->src[src].src))
103 return false;
104
105 for (unsigned i = 0; i < num_components; i++) {
106 uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
107 if (util_bitcount64(val) != 2)
108 return false;
109 }
110
111 return true;
112 }
113
114 static inline bool
is_nan(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)115 is_nan(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
116 unsigned src, unsigned num_components, const uint8_t *swizzle)
117 {
118 /* only constant srcs: */
119 if (!nir_src_is_const(instr->src[src].src))
120 return false;
121
122 for (unsigned i = 0; i < num_components; i++) {
123 if (!isnan(nir_src_comp_as_float(instr->src[src].src, swizzle[i])))
124 return false;
125 }
126
127 return true;
128 }
129
130 static inline bool
is_any_comp_nan(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)131 is_any_comp_nan(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
132 unsigned src, unsigned num_components, const uint8_t *swizzle)
133 {
134 /* only constant srcs: */
135 if (!nir_src_is_const(instr->src[src].src))
136 return false;
137
138 for (unsigned i = 0; i < num_components; i++) {
139 if (isnan(nir_src_comp_as_float(instr->src[src].src, swizzle[i])))
140 return true;
141 }
142
143 return false;
144 }
145
146 #define MULTIPLE(test) \
147 static inline bool \
148 is_unsigned_multiple_of_##test(UNUSED struct hash_table *ht, \
149 const nir_alu_instr *instr, \
150 unsigned src, unsigned num_components, \
151 const uint8_t *swizzle) \
152 { \
153 /* only constant srcs: */ \
154 if (!nir_src_is_const(instr->src[src].src)) \
155 return false; \
156 \
157 for (unsigned i = 0; i < num_components; i++) { \
158 uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]); \
159 if (val % test != 0) \
160 return false; \
161 } \
162 \
163 return true; \
164 }
165
166 MULTIPLE(2)
167 MULTIPLE(4)
168 MULTIPLE(8)
169 MULTIPLE(16)
170 MULTIPLE(32)
171 MULTIPLE(64)
172
173 static inline bool
is_zero_to_one(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)174 is_zero_to_one(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
175 unsigned src, unsigned num_components,
176 const uint8_t *swizzle)
177 {
178 /* only constant srcs: */
179 if (!nir_src_is_const(instr->src[src].src))
180 return false;
181
182 for (unsigned i = 0; i < num_components; i++) {
183 nir_alu_type type = nir_op_infos[instr->op].input_types[src];
184 switch (nir_alu_type_get_base_type(type)) {
185 case nir_type_float: {
186 double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
187 if (isnan(val) || val < 0.0f || val > 1.0f)
188 return false;
189 break;
190 }
191 default:
192 return false;
193 }
194 }
195
196 return true;
197 }
198
199 /**
200 * Exclusive compare with (0, 1).
201 *
202 * This differs from \c is_zero_to_one because that function tests 0 <= src <=
203 * 1 while this function tests 0 < src < 1.
204 */
205 static inline bool
is_gt_0_and_lt_1(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)206 is_gt_0_and_lt_1(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
207 unsigned src, unsigned num_components,
208 const uint8_t *swizzle)
209 {
210 /* only constant srcs: */
211 if (!nir_src_is_const(instr->src[src].src))
212 return false;
213
214 for (unsigned i = 0; i < num_components; i++) {
215 nir_alu_type type = nir_op_infos[instr->op].input_types[src];
216 switch (nir_alu_type_get_base_type(type)) {
217 case nir_type_float: {
218 double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
219 if (isnan(val) || val <= 0.0f || val >= 1.0f)
220 return false;
221 break;
222 }
223 default:
224 return false;
225 }
226 }
227
228 return true;
229 }
230
231 /**
232 * x & 1 != 0
233 */
234 static inline bool
is_odd(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)235 is_odd(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
236 unsigned src, unsigned num_components,
237 const uint8_t *swizzle)
238 {
239 /* only constant srcs: */
240 if (!nir_src_is_const(instr->src[src].src))
241 return false;
242
243 for (unsigned i = 0; i < num_components; i++) {
244 nir_alu_type type = nir_op_infos[instr->op].input_types[src];
245 switch (nir_alu_type_get_base_type(type)) {
246 case nir_type_int:
247 case nir_type_uint: {
248 if ((nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) & 1) == 0)
249 return false;
250 break;
251 }
252 default:
253 return false;
254 }
255 }
256
257 return true;
258 }
259
260 static inline bool
is_not_const_zero(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)261 is_not_const_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
262 unsigned src, unsigned num_components,
263 const uint8_t *swizzle)
264 {
265 if (nir_src_as_const_value(instr->src[src].src) == NULL)
266 return true;
267
268 for (unsigned i = 0; i < num_components; i++) {
269 nir_alu_type type = nir_op_infos[instr->op].input_types[src];
270 switch (nir_alu_type_get_base_type(type)) {
271 case nir_type_float:
272 if (nir_src_comp_as_float(instr->src[src].src, swizzle[i]) == 0.0)
273 return false;
274 break;
275 case nir_type_bool:
276 case nir_type_int:
277 case nir_type_uint:
278 if (nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) == 0)
279 return false;
280 break;
281 default:
282 return false;
283 }
284 }
285
286 return true;
287 }
288
289 /** Is value unsigned less than the limit? */
290 static inline bool
is_ult(const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle,uint64_t limit)291 is_ult(const nir_alu_instr *instr, unsigned src, unsigned num_components, const uint8_t *swizzle,
292 uint64_t limit)
293 {
294 /* only constant srcs: */
295 if (!nir_src_is_const(instr->src[src].src))
296 return false;
297
298 for (unsigned i = 0; i < num_components; i++) {
299 const uint64_t val =
300 nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
301
302 if (val >= limit)
303 return false;
304 }
305
306 return true;
307 }
308
309 /** Is value unsigned less than 32? */
310 static inline bool
is_ult_32(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)311 is_ult_32(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
312 unsigned src, unsigned num_components,
313 const uint8_t *swizzle)
314 {
315 return is_ult(instr, src, num_components, swizzle, 32);
316 }
317
318 /** Is value unsigned less than 0xfffc07fc? */
319 static inline bool
is_ult_0xfffc07fc(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)320 is_ult_0xfffc07fc(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
321 unsigned src, unsigned num_components,
322 const uint8_t *swizzle)
323 {
324 return is_ult(instr, src, num_components, swizzle, 0xfffc07fcU);
325 }
326
327 /** Is the first 5 bits of value unsigned greater than or equal 2? */
328 static inline bool
is_first_5_bits_uge_2(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)329 is_first_5_bits_uge_2(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
330 unsigned src, unsigned num_components,
331 const uint8_t *swizzle)
332 {
333 /* only constant srcs: */
334 if (!nir_src_is_const(instr->src[src].src))
335 return false;
336
337 for (unsigned i = 0; i < num_components; i++) {
338 const unsigned val =
339 nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
340
341 if ((val & 0x1f) < 2)
342 return false;
343 }
344
345 return true;
346 }
347
348 /** Is this a constant that could be either int16_t or uint16_t? */
349 static inline bool
is_16_bits(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)350 is_16_bits(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
351 unsigned src, unsigned num_components,
352 const uint8_t *swizzle)
353 {
354 /* only constant srcs: */
355 if (!nir_src_is_const(instr->src[src].src))
356 return false;
357
358 for (unsigned i = 0; i < num_components; i++) {
359 const int64_t val =
360 nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
361
362 if (val > 0xffff || val < -0x8000)
363 return false;
364 }
365
366 return true;
367 }
368
369 static inline bool
is_not_const(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)370 is_not_const(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
371 unsigned src, UNUSED unsigned num_components,
372 UNUSED const uint8_t *swizzle)
373 {
374 return !nir_src_is_const(instr->src[src].src);
375 }
376
377 static inline bool
is_not_fmul(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)378 is_not_fmul(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
379 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
380 {
381 nir_alu_instr *src_alu =
382 nir_src_as_alu_instr(instr->src[src].src);
383
384 if (src_alu == NULL)
385 return true;
386
387 if (src_alu->op == nir_op_fneg)
388 return is_not_fmul(ht, src_alu, 0, 0, NULL);
389
390 return src_alu->op != nir_op_fmul && src_alu->op != nir_op_fmulz;
391 }
392
393 static inline bool
is_fmul(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)394 is_fmul(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
395 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
396 {
397 nir_alu_instr *src_alu =
398 nir_src_as_alu_instr(instr->src[src].src);
399
400 if (src_alu == NULL)
401 return false;
402
403 if (src_alu->op == nir_op_fneg)
404 return is_fmul(ht, src_alu, 0, 0, NULL);
405
406 return src_alu->op == nir_op_fmul || src_alu->op == nir_op_fmulz;
407 }
408
409 static inline bool
is_fsign(const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)410 is_fsign(const nir_alu_instr *instr, unsigned src,
411 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
412 {
413 nir_alu_instr *src_alu =
414 nir_src_as_alu_instr(instr->src[src].src);
415
416 if (src_alu == NULL)
417 return false;
418
419 if (src_alu->op == nir_op_fneg)
420 src_alu = nir_src_as_alu_instr(src_alu->src[0].src);
421
422 return src_alu != NULL && src_alu->op == nir_op_fsign;
423 }
424
425 static inline bool
is_not_const_and_not_fsign(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)426 is_not_const_and_not_fsign(struct hash_table *ht, const nir_alu_instr *instr,
427 unsigned src, unsigned num_components,
428 const uint8_t *swizzle)
429 {
430 return is_not_const(ht, instr, src, num_components, swizzle) &&
431 !is_fsign(instr, src, num_components, swizzle);
432 }
433
434 static inline bool
is_used_once(const nir_alu_instr * instr)435 is_used_once(const nir_alu_instr *instr)
436 {
437 return list_is_singular(&instr->def.uses);
438 }
439
440 static inline bool
is_used_by_if(const nir_alu_instr * instr)441 is_used_by_if(const nir_alu_instr *instr)
442 {
443 return nir_def_used_by_if(&instr->def);
444 }
445
446 static inline bool
is_not_used_by_if(const nir_alu_instr * instr)447 is_not_used_by_if(const nir_alu_instr *instr)
448 {
449 return !is_used_by_if(instr);
450 }
451
452 static inline bool
is_used_by_non_fsat(const nir_alu_instr * instr)453 is_used_by_non_fsat(const nir_alu_instr *instr)
454 {
455 nir_foreach_use(src, &instr->def) {
456 const nir_instr *const user_instr = nir_src_parent_instr(src);
457
458 if (user_instr->type != nir_instr_type_alu)
459 return true;
460
461 const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
462
463 assert(instr != user_alu);
464 if (user_alu->op != nir_op_fsat)
465 return true;
466 }
467
468 return false;
469 }
470
471 static inline bool
is_only_used_as_float(const nir_alu_instr * instr)472 is_only_used_as_float(const nir_alu_instr *instr)
473 {
474 nir_foreach_use(src, &instr->def) {
475 const nir_instr *const user_instr = nir_src_parent_instr(src);
476 if (user_instr->type != nir_instr_type_alu)
477 return false;
478
479 const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
480 assert(instr != user_alu);
481
482 unsigned index = (nir_alu_src *)container_of(src, nir_alu_src, src) - user_alu->src;
483 nir_alu_type type = nir_op_infos[user_alu->op].input_types[index];
484 if (nir_alu_type_get_base_type(type) != nir_type_float)
485 return false;
486 }
487
488 return true;
489 }
490
491 static inline bool
is_only_used_by_fadd(const nir_alu_instr * instr)492 is_only_used_by_fadd(const nir_alu_instr *instr)
493 {
494 nir_foreach_use(src, &instr->def) {
495 const nir_instr *const user_instr = nir_src_parent_instr(src);
496 if (user_instr->type != nir_instr_type_alu)
497 return false;
498
499 const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
500 assert(instr != user_alu);
501
502 if (user_alu->op == nir_op_fneg || user_alu->op == nir_op_fabs) {
503 if (!is_only_used_by_fadd(user_alu))
504 return false;
505 } else if (user_alu->op != nir_op_fadd) {
506 return false;
507 }
508 }
509
510 return true;
511 }
512
513 static inline bool
only_lower_8_bits_used(const nir_alu_instr * instr)514 only_lower_8_bits_used(const nir_alu_instr *instr)
515 {
516 return (nir_def_bits_used(&instr->def) & ~0xffull) == 0;
517 }
518
519 static inline bool
only_lower_16_bits_used(const nir_alu_instr * instr)520 only_lower_16_bits_used(const nir_alu_instr *instr)
521 {
522 return (nir_def_bits_used(&instr->def) & ~0xffffull) == 0;
523 }
524
525 /**
526 * Returns true if a NIR ALU src represents a constant integer
527 * of either 32 or 64 bits, and the higher word (bit-size / 2)
528 * of all its components is zero.
529 */
530 static inline bool
is_upper_half_zero(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)531 is_upper_half_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
532 unsigned src, unsigned num_components,
533 const uint8_t *swizzle)
534 {
535 if (nir_src_as_const_value(instr->src[src].src) == NULL)
536 return false;
537
538 for (unsigned i = 0; i < num_components; i++) {
539 unsigned half_bit_size = nir_src_bit_size(instr->src[src].src) / 2;
540 uint64_t high_bits = u_bit_consecutive64(half_bit_size, half_bit_size);
541 if ((nir_src_comp_as_uint(instr->src[src].src,
542 swizzle[i]) &
543 high_bits) != 0) {
544 return false;
545 }
546 }
547
548 return true;
549 }
550
551 /**
552 * Returns true if a NIR ALU src represents a constant integer
553 * of either 32 or 64 bits, and the lower word (bit-size / 2)
554 * of all its components is zero.
555 */
556 static inline bool
is_lower_half_zero(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)557 is_lower_half_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
558 unsigned src, unsigned num_components,
559 const uint8_t *swizzle)
560 {
561 if (nir_src_as_const_value(instr->src[src].src) == NULL)
562 return false;
563
564 for (unsigned i = 0; i < num_components; i++) {
565 uint64_t low_bits = u_bit_consecutive64(0, nir_src_bit_size(instr->src[src].src) / 2);
566 if ((nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) & low_bits) != 0)
567 return false;
568 }
569
570 return true;
571 }
572
573 static inline bool
is_upper_half_negative_one(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)574 is_upper_half_negative_one(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
575 unsigned src, unsigned num_components,
576 const uint8_t *swizzle)
577 {
578 if (nir_src_as_const_value(instr->src[src].src) == NULL)
579 return false;
580
581 for (unsigned i = 0; i < num_components; i++) {
582 unsigned half_bit_size = nir_src_bit_size(instr->src[src].src) / 2;
583 uint64_t high_bits = u_bit_consecutive64(half_bit_size, half_bit_size);
584 if ((nir_src_comp_as_uint(instr->src[src].src,
585 swizzle[i]) &
586 high_bits) != high_bits) {
587 return false;
588 }
589 }
590
591 return true;
592 }
593
594 static inline bool
is_lower_half_negative_one(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)595 is_lower_half_negative_one(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
596 unsigned src, unsigned num_components,
597 const uint8_t *swizzle)
598 {
599 if (nir_src_as_const_value(instr->src[src].src) == NULL)
600 return false;
601
602 for (unsigned i = 0; i < num_components; i++) {
603 uint64_t low_bits = u_bit_consecutive64(0, nir_src_bit_size(instr->src[src].src) / 2);
604 if ((nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) & low_bits) != low_bits)
605 return false;
606 }
607
608 return true;
609 }
610
611 static inline bool
no_signed_wrap(const nir_alu_instr * instr)612 no_signed_wrap(const nir_alu_instr *instr)
613 {
614 return instr->no_signed_wrap;
615 }
616
617 static inline bool
no_unsigned_wrap(const nir_alu_instr * instr)618 no_unsigned_wrap(const nir_alu_instr *instr)
619 {
620 return instr->no_unsigned_wrap;
621 }
622
623 static inline bool
is_integral(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)624 is_integral(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
625 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
626 {
627 const struct ssa_result_range r = nir_analyze_range(ht, instr, src);
628
629 return r.is_integral;
630 }
631
632 /**
633 * Is the value finite?
634 */
635 static inline bool
is_finite(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)636 is_finite(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
637 unsigned src, UNUSED unsigned num_components,
638 UNUSED const uint8_t *swizzle)
639 {
640 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
641
642 return v.is_finite;
643 }
644
645 static inline bool
is_finite_not_zero(UNUSED struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)646 is_finite_not_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
647 unsigned src, UNUSED unsigned num_components,
648 UNUSED const uint8_t *swizzle)
649 {
650 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
651
652 return v.is_finite &&
653 (v.range == lt_zero || v.range == gt_zero || v.range == ne_zero);
654 }
655
656 #define RELATION(r) \
657 static inline bool \
658 is_##r(struct hash_table *ht, const nir_alu_instr *instr, \
659 unsigned src, UNUSED unsigned num_components, \
660 UNUSED const uint8_t *swizzle) \
661 { \
662 const struct ssa_result_range v = nir_analyze_range(ht, instr, src); \
663 return v.range == r; \
664 } \
665 \
666 static inline bool \
667 is_a_number_##r(struct hash_table *ht, const nir_alu_instr *instr, \
668 unsigned src, UNUSED unsigned num_components, \
669 UNUSED const uint8_t *swizzle) \
670 { \
671 const struct ssa_result_range v = nir_analyze_range(ht, instr, src); \
672 return v.is_a_number && v.range == r; \
673 }
674
675 RELATION(lt_zero)
RELATION(le_zero)676 RELATION(le_zero)
677 RELATION(gt_zero)
678 RELATION(ge_zero)
679 RELATION(ne_zero)
680
681 static inline bool
682 is_not_negative(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
683 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
684 {
685 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
686 return v.range == ge_zero || v.range == gt_zero || v.range == eq_zero;
687 }
688
689 static inline bool
is_a_number_not_negative(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)690 is_a_number_not_negative(struct hash_table *ht, const nir_alu_instr *instr,
691 unsigned src, UNUSED unsigned num_components,
692 UNUSED const uint8_t *swizzle)
693 {
694 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
695 return v.is_a_number &&
696 (v.range == ge_zero || v.range == gt_zero || v.range == eq_zero);
697 }
698
699 static inline bool
is_not_positive(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)700 is_not_positive(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
701 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
702 {
703 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
704 return v.range == le_zero || v.range == lt_zero || v.range == eq_zero;
705 }
706
707 static inline bool
is_a_number_not_positive(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)708 is_a_number_not_positive(struct hash_table *ht, const nir_alu_instr *instr,
709 unsigned src, UNUSED unsigned num_components,
710 UNUSED const uint8_t *swizzle)
711 {
712 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
713 return v.is_a_number &&
714 (v.range == le_zero || v.range == lt_zero || v.range == eq_zero);
715 }
716
717 static inline bool
is_not_zero(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)718 is_not_zero(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
719 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
720 {
721 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
722 return v.range == lt_zero || v.range == gt_zero || v.range == ne_zero;
723 }
724
725 static inline bool
is_a_number_not_zero(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)726 is_a_number_not_zero(struct hash_table *ht, const nir_alu_instr *instr,
727 unsigned src, UNUSED unsigned num_components,
728 UNUSED const uint8_t *swizzle)
729 {
730 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
731 return v.is_a_number &&
732 (v.range == lt_zero || v.range == gt_zero || v.range == ne_zero);
733 }
734
735 static inline bool
is_a_number(struct hash_table * ht,const nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)736 is_a_number(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
737 UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
738 {
739 const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
740 return v.is_a_number;
741 }
742
743 #endif /* _NIR_SEARCH_ */
744