• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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