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