101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2016 Red Hat
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg *
2301e04c3fSmrg * Authors:
2401e04c3fSmrg *    Rob Clark <robclark@freedesktop.org>
2501e04c3fSmrg */
2601e04c3fSmrg
2701e04c3fSmrg#ifndef _NIR_SEARCH_HELPERS_
2801e04c3fSmrg#define _NIR_SEARCH_HELPERS_
2901e04c3fSmrg
3001e04c3fSmrg#include "nir.h"
3101e04c3fSmrg#include "util/bitscan.h"
327ec681f3Smrg#include "nir_range_analysis.h"
3301e04c3fSmrg#include <math.h>
3401e04c3fSmrg
3501e04c3fSmrgstatic inline bool
367ec681f3Smrgis_pos_power_of_two(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
377ec681f3Smrg                    unsigned src, unsigned num_components,
3801e04c3fSmrg                    const uint8_t *swizzle)
3901e04c3fSmrg{
4001e04c3fSmrg   /* only constant srcs: */
4101e04c3fSmrg   if (!nir_src_is_const(instr->src[src].src))
4201e04c3fSmrg      return false;
4301e04c3fSmrg
4401e04c3fSmrg   for (unsigned i = 0; i < num_components; i++) {
457ec681f3Smrg      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
467ec681f3Smrg      switch (nir_alu_type_get_base_type(type)) {
4701e04c3fSmrg      case nir_type_int: {
4801e04c3fSmrg         int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
4901e04c3fSmrg         if (val <= 0 || !util_is_power_of_two_or_zero64(val))
5001e04c3fSmrg            return false;
5101e04c3fSmrg         break;
5201e04c3fSmrg      }
5301e04c3fSmrg      case nir_type_uint: {
5401e04c3fSmrg         uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
5501e04c3fSmrg         if (val == 0 || !util_is_power_of_two_or_zero64(val))
5601e04c3fSmrg            return false;
5701e04c3fSmrg         break;
5801e04c3fSmrg      }
5901e04c3fSmrg      default:
6001e04c3fSmrg         return false;
6101e04c3fSmrg      }
6201e04c3fSmrg   }
6301e04c3fSmrg
6401e04c3fSmrg   return true;
6501e04c3fSmrg}
6601e04c3fSmrg
6701e04c3fSmrgstatic inline bool
687ec681f3Smrgis_neg_power_of_two(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
697ec681f3Smrg                    unsigned src, unsigned num_components,
7001e04c3fSmrg                    const uint8_t *swizzle)
7101e04c3fSmrg{
7201e04c3fSmrg   /* only constant srcs: */
7301e04c3fSmrg   if (!nir_src_is_const(instr->src[src].src))
7401e04c3fSmrg      return false;
7501e04c3fSmrg
767ec681f3Smrg   int64_t int_min = u_intN_min(instr->src[src].src.ssa->bit_size);
777ec681f3Smrg
7801e04c3fSmrg   for (unsigned i = 0; i < num_components; i++) {
797ec681f3Smrg      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
807ec681f3Smrg      switch (nir_alu_type_get_base_type(type)) {
8101e04c3fSmrg      case nir_type_int: {
8201e04c3fSmrg         int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
837ec681f3Smrg         /* "int_min" is a power-of-two, but negation can cause overflow. */
847ec681f3Smrg         if (val == int_min || val >= 0 || !util_is_power_of_two_or_zero64(-val))
8501e04c3fSmrg            return false;
8601e04c3fSmrg         break;
8701e04c3fSmrg      }
8801e04c3fSmrg      default:
8901e04c3fSmrg         return false;
9001e04c3fSmrg      }
9101e04c3fSmrg   }
9201e04c3fSmrg
9301e04c3fSmrg   return true;
9401e04c3fSmrg}
9501e04c3fSmrg
967ec681f3Smrg#define MULTIPLE(test)                                                  \
977ec681f3Smrgstatic inline bool                                                      \
987ec681f3Smrgis_unsigned_multiple_of_ ## test(UNUSED struct hash_table *ht,          \
997ec681f3Smrg                                 const nir_alu_instr *instr,            \
1007ec681f3Smrg                                 unsigned src, unsigned num_components, \
1017ec681f3Smrg                                 const uint8_t *swizzle)                \
1027ec681f3Smrg{                                                                       \
1037ec681f3Smrg   /* only constant srcs: */                                            \
1047ec681f3Smrg   if (!nir_src_is_const(instr->src[src].src))                          \
1057ec681f3Smrg      return false;                                                     \
1067ec681f3Smrg                                                                        \
1077ec681f3Smrg   for (unsigned i = 0; i < num_components; i++) {                      \
1087ec681f3Smrg      uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]); \
1097ec681f3Smrg      if (val % test != 0)                                              \
1107ec681f3Smrg         return false;                                                  \
1117ec681f3Smrg   }                                                                    \
1127ec681f3Smrg                                                                        \
1137ec681f3Smrg   return true;                                                         \
1147ec681f3Smrg}
1157ec681f3Smrg
1167ec681f3SmrgMULTIPLE(2)
1177ec681f3SmrgMULTIPLE(4)
1187ec681f3SmrgMULTIPLE(8)
1197ec681f3SmrgMULTIPLE(16)
1207ec681f3SmrgMULTIPLE(32)
1217ec681f3SmrgMULTIPLE(64)
1227ec681f3Smrg
12301e04c3fSmrgstatic inline bool
1247ec681f3Smrgis_zero_to_one(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
1257ec681f3Smrg               unsigned src, unsigned num_components,
12601e04c3fSmrg               const uint8_t *swizzle)
12701e04c3fSmrg{
12801e04c3fSmrg   /* only constant srcs: */
12901e04c3fSmrg   if (!nir_src_is_const(instr->src[src].src))
13001e04c3fSmrg      return false;
13101e04c3fSmrg
13201e04c3fSmrg   for (unsigned i = 0; i < num_components; i++) {
13301e04c3fSmrg      switch (nir_op_infos[instr->op].input_types[src]) {
13401e04c3fSmrg      case nir_type_float: {
13501e04c3fSmrg         double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
13601e04c3fSmrg         if (isnan(val) || val < 0.0f || val > 1.0f)
13701e04c3fSmrg            return false;
13801e04c3fSmrg         break;
13901e04c3fSmrg      }
14001e04c3fSmrg      default:
14101e04c3fSmrg         return false;
14201e04c3fSmrg      }
14301e04c3fSmrg   }
14401e04c3fSmrg
14501e04c3fSmrg   return true;
14601e04c3fSmrg}
14701e04c3fSmrg
1487ec681f3Smrg/**
1497ec681f3Smrg * Exclusive compare with (0, 1).
1507ec681f3Smrg *
1517ec681f3Smrg * This differs from \c is_zero_to_one because that function tests 0 <= src <=
1527ec681f3Smrg * 1 while this function tests 0 < src < 1.
1537ec681f3Smrg */
15401e04c3fSmrgstatic inline bool
1557ec681f3Smrgis_gt_0_and_lt_1(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
1567ec681f3Smrg                 unsigned src, unsigned num_components,
1577ec681f3Smrg                 const uint8_t *swizzle)
1587ec681f3Smrg{
1597ec681f3Smrg   /* only constant srcs: */
1607ec681f3Smrg   if (!nir_src_is_const(instr->src[src].src))
1617ec681f3Smrg      return false;
1627ec681f3Smrg
1637ec681f3Smrg   for (unsigned i = 0; i < num_components; i++) {
1647ec681f3Smrg      switch (nir_op_infos[instr->op].input_types[src]) {
1657ec681f3Smrg      case nir_type_float: {
1667ec681f3Smrg         double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
1677ec681f3Smrg         if (isnan(val) || val <= 0.0f || val >= 1.0f)
1687ec681f3Smrg            return false;
1697ec681f3Smrg         break;
1707ec681f3Smrg      }
1717ec681f3Smrg      default:
1727ec681f3Smrg         return false;
1737ec681f3Smrg      }
1747ec681f3Smrg   }
1757ec681f3Smrg
1767ec681f3Smrg   return true;
1777ec681f3Smrg}
1787ec681f3Smrg
1797ec681f3Smrgstatic inline bool
1807ec681f3Smrgis_not_const_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
1817ec681f3Smrg                  unsigned src, unsigned num_components,
1827e102996Smaya                  const uint8_t *swizzle)
18301e04c3fSmrg{
1847e102996Smaya   if (nir_src_as_const_value(instr->src[src].src) == NULL)
1857e102996Smaya      return true;
1867e102996Smaya
1877e102996Smaya   for (unsigned i = 0; i < num_components; i++) {
1887ec681f3Smrg      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
1897ec681f3Smrg      switch (nir_alu_type_get_base_type(type)) {
1907e102996Smaya      case nir_type_float:
1917e102996Smaya         if (nir_src_comp_as_float(instr->src[src].src, swizzle[i]) == 0.0)
1927e102996Smaya            return false;
1937e102996Smaya         break;
1947e102996Smaya      case nir_type_bool:
1957e102996Smaya      case nir_type_int:
1967e102996Smaya      case nir_type_uint:
1977e102996Smaya         if (nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) == 0)
1987e102996Smaya            return false;
1997e102996Smaya         break;
2007e102996Smaya      default:
2017e102996Smaya         return false;
2027e102996Smaya      }
2037e102996Smaya   }
2047e102996Smaya
2057e102996Smaya   return true;
20601e04c3fSmrg}
20701e04c3fSmrg
2087ec681f3Smrg/** Is value unsigned less than 0xfffc07fc? */
2097ec681f3Smrgstatic inline bool
2107ec681f3Smrgis_ult_0xfffc07fc(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
2117ec681f3Smrg                  unsigned src, unsigned num_components,
2127ec681f3Smrg                  const uint8_t *swizzle)
2137ec681f3Smrg{
2147ec681f3Smrg   /* only constant srcs: */
2157ec681f3Smrg   if (!nir_src_is_const(instr->src[src].src))
2167ec681f3Smrg      return false;
2177ec681f3Smrg
2187ec681f3Smrg   for (unsigned i = 0; i < num_components; i++) {
2197ec681f3Smrg      const unsigned val =
2207ec681f3Smrg         nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
2217ec681f3Smrg
2227ec681f3Smrg      if (val >= 0xfffc07fcU)
2237ec681f3Smrg         return false;
2247ec681f3Smrg   }
2257ec681f3Smrg
2267ec681f3Smrg   return true;
2277ec681f3Smrg}
2287ec681f3Smrg
22901e04c3fSmrgstatic inline bool
2307ec681f3Smrgis_not_const(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
2317ec681f3Smrg             unsigned src, UNUSED unsigned num_components,
2327e102996Smaya             UNUSED const uint8_t *swizzle)
23301e04c3fSmrg{
2347e102996Smaya   return !nir_src_is_const(instr->src[src].src);
23501e04c3fSmrg}
23601e04c3fSmrg
2377ec681f3Smrgstatic inline bool
2387ec681f3Smrgis_not_fmul(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
2397ec681f3Smrg            UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
2407ec681f3Smrg{
2417ec681f3Smrg   nir_alu_instr *src_alu =
2427ec681f3Smrg      nir_src_as_alu_instr(instr->src[src].src);
2437ec681f3Smrg
2447ec681f3Smrg   if (src_alu == NULL)
2457ec681f3Smrg      return true;
2467ec681f3Smrg
2477ec681f3Smrg   if (src_alu->op == nir_op_fneg)
2487ec681f3Smrg      return is_not_fmul(ht, src_alu, 0, 0, NULL);
2497ec681f3Smrg
2507ec681f3Smrg   return src_alu->op != nir_op_fmul;
2517ec681f3Smrg}
2527ec681f3Smrg
2537ec681f3Smrgstatic inline bool
2547ec681f3Smrgis_fmul(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
2557ec681f3Smrg        UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
2567ec681f3Smrg{
2577ec681f3Smrg   nir_alu_instr *src_alu =
2587ec681f3Smrg      nir_src_as_alu_instr(instr->src[src].src);
2597ec681f3Smrg
2607ec681f3Smrg   if (src_alu == NULL)
2617ec681f3Smrg      return false;
2627ec681f3Smrg
2637ec681f3Smrg   if (src_alu->op == nir_op_fneg)
2647ec681f3Smrg      return is_fmul(ht, src_alu, 0, 0, NULL);
2657ec681f3Smrg
2667ec681f3Smrg   return src_alu->op == nir_op_fmul;
2677ec681f3Smrg}
2687ec681f3Smrg
2697ec681f3Smrgstatic inline bool
2707ec681f3Smrgis_fsign(const nir_alu_instr *instr, unsigned src,
2717ec681f3Smrg         UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
2727ec681f3Smrg{
2737ec681f3Smrg   nir_alu_instr *src_alu =
2747ec681f3Smrg      nir_src_as_alu_instr(instr->src[src].src);
2757ec681f3Smrg
2767ec681f3Smrg   if (src_alu == NULL)
2777ec681f3Smrg      return false;
2787ec681f3Smrg
2797ec681f3Smrg   if (src_alu->op == nir_op_fneg)
2807ec681f3Smrg      src_alu = nir_src_as_alu_instr(src_alu->src[0].src);
2817ec681f3Smrg
2827ec681f3Smrg   return src_alu != NULL && src_alu->op == nir_op_fsign;
2837ec681f3Smrg}
2847ec681f3Smrg
2857ec681f3Smrgstatic inline bool
2867ec681f3Smrgis_not_const_and_not_fsign(struct hash_table *ht, const nir_alu_instr *instr,
2877ec681f3Smrg                           unsigned src, unsigned num_components,
2887ec681f3Smrg                           const uint8_t *swizzle)
2897ec681f3Smrg{
2907ec681f3Smrg   return is_not_const(ht, instr, src, num_components, swizzle) &&
2917ec681f3Smrg          !is_fsign(instr, src, num_components, swizzle);
2927ec681f3Smrg}
2937ec681f3Smrg
29401e04c3fSmrgstatic inline bool
29501e04c3fSmrgis_used_once(nir_alu_instr *instr)
29601e04c3fSmrg{
2977ec681f3Smrg   bool zero_if_use = list_is_empty(&instr->dest.dest.ssa.if_uses);
2987ec681f3Smrg   bool zero_use = list_is_empty(&instr->dest.dest.ssa.uses);
29901e04c3fSmrg
30001e04c3fSmrg   if (zero_if_use && zero_use)
30101e04c3fSmrg      return false;
30201e04c3fSmrg
30301e04c3fSmrg   if (!zero_if_use && list_is_singular(&instr->dest.dest.ssa.uses))
30401e04c3fSmrg     return false;
30501e04c3fSmrg
30601e04c3fSmrg   if (!zero_use && list_is_singular(&instr->dest.dest.ssa.if_uses))
30701e04c3fSmrg     return false;
30801e04c3fSmrg
30901e04c3fSmrg   if (!list_is_singular(&instr->dest.dest.ssa.if_uses) &&
31001e04c3fSmrg       !list_is_singular(&instr->dest.dest.ssa.uses))
31101e04c3fSmrg      return false;
31201e04c3fSmrg
31301e04c3fSmrg   return true;
31401e04c3fSmrg}
31501e04c3fSmrg
3167e102996Smayastatic inline bool
3177e102996Smayais_used_by_if(nir_alu_instr *instr)
3187e102996Smaya{
3197ec681f3Smrg   return !list_is_empty(&instr->dest.dest.ssa.if_uses);
3207e102996Smaya}
3217e102996Smaya
32201e04c3fSmrgstatic inline bool
32301e04c3fSmrgis_not_used_by_if(nir_alu_instr *instr)
32401e04c3fSmrg{
3257ec681f3Smrg   return list_is_empty(&instr->dest.dest.ssa.if_uses);
3267ec681f3Smrg}
3277ec681f3Smrg
3287ec681f3Smrgstatic inline bool
3297ec681f3Smrgis_used_by_non_fsat(nir_alu_instr *instr)
3307ec681f3Smrg{
3317ec681f3Smrg   nir_foreach_use(src, &instr->dest.dest.ssa) {
3327ec681f3Smrg      const nir_instr *const user_instr = src->parent_instr;
3337ec681f3Smrg
3347ec681f3Smrg      if (user_instr->type != nir_instr_type_alu)
3357ec681f3Smrg         return true;
3367ec681f3Smrg
3377ec681f3Smrg      const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
3387ec681f3Smrg
3397ec681f3Smrg      assert(instr != user_alu);
3407ec681f3Smrg      if (user_alu->op != nir_op_fsat)
3417ec681f3Smrg         return true;
3427ec681f3Smrg   }
3437ec681f3Smrg
3447ec681f3Smrg   return false;
3457ec681f3Smrg}
3467ec681f3Smrg
3477ec681f3Smrgstatic inline bool
3487ec681f3Smrgis_only_used_as_float(nir_alu_instr *instr)
3497ec681f3Smrg{
3507ec681f3Smrg   nir_foreach_use(src, &instr->dest.dest.ssa) {
3517ec681f3Smrg      const nir_instr *const user_instr = src->parent_instr;
3527ec681f3Smrg      if (user_instr->type != nir_instr_type_alu)
3537ec681f3Smrg         return false;
3547ec681f3Smrg
3557ec681f3Smrg      const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
3567ec681f3Smrg      assert(instr != user_alu);
3577ec681f3Smrg
3587ec681f3Smrg      unsigned index = (nir_alu_src*)container_of(src, nir_alu_src, src) - user_alu->src;
3597ec681f3Smrg      if (nir_op_infos[user_alu->op].input_types[index] != nir_type_float)
3607ec681f3Smrg         return false;
3617ec681f3Smrg   }
3627ec681f3Smrg
3637ec681f3Smrg   return true;
3647ec681f3Smrg}
3657ec681f3Smrg
3667ec681f3Smrgstatic inline bool
3677ec681f3Smrgonly_lower_8_bits_used(nir_alu_instr *instr)
3687ec681f3Smrg{
3697ec681f3Smrg   return (nir_ssa_def_bits_used(&instr->dest.dest.ssa) & ~0xffull) == 0;
3707ec681f3Smrg}
3717ec681f3Smrg
3727ec681f3Smrgstatic inline bool
3737ec681f3Smrgonly_lower_16_bits_used(nir_alu_instr *instr)
3747ec681f3Smrg{
3757ec681f3Smrg   return (nir_ssa_def_bits_used(&instr->dest.dest.ssa) & ~0xffffull) == 0;
3767ec681f3Smrg}
3777ec681f3Smrg
3787ec681f3Smrg/**
3797ec681f3Smrg * Returns true if a NIR ALU src represents a constant integer
3807ec681f3Smrg * of either 32 or 64 bits, and the higher word (bit-size / 2)
3817ec681f3Smrg * of all its components is zero.
3827ec681f3Smrg */
3837ec681f3Smrgstatic inline bool
3847ec681f3Smrgis_upper_half_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
3857ec681f3Smrg                   unsigned src, unsigned num_components,
3867ec681f3Smrg                   const uint8_t *swizzle)
3877ec681f3Smrg{
3887ec681f3Smrg   if (nir_src_as_const_value(instr->src[src].src) == NULL)
3897ec681f3Smrg      return false;
3907ec681f3Smrg
3917ec681f3Smrg   for (unsigned i = 0; i < num_components; i++) {
3927ec681f3Smrg      unsigned half_bit_size = nir_src_bit_size(instr->src[src].src) / 2;
3937ec681f3Smrg      uint32_t high_bits = ((1 << half_bit_size) - 1) << half_bit_size;
3947ec681f3Smrg      if ((nir_src_comp_as_uint(instr->src[src].src,
3957ec681f3Smrg                                swizzle[i]) & high_bits) != 0) {
3967ec681f3Smrg         return false;
3977ec681f3Smrg      }
3987ec681f3Smrg   }
3997ec681f3Smrg
4007ec681f3Smrg   return true;
4017ec681f3Smrg}
4027ec681f3Smrg
4037ec681f3Smrg/**
4047ec681f3Smrg * Returns true if a NIR ALU src represents a constant integer
4057ec681f3Smrg * of either 32 or 64 bits, and the lower word (bit-size / 2)
4067ec681f3Smrg * of all its components is zero.
4077ec681f3Smrg */
4087ec681f3Smrgstatic inline bool
4097ec681f3Smrgis_lower_half_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
4107ec681f3Smrg                   unsigned src, unsigned num_components,
4117ec681f3Smrg                   const uint8_t *swizzle)
4127ec681f3Smrg{
4137ec681f3Smrg   if (nir_src_as_const_value(instr->src[src].src) == NULL)
4147ec681f3Smrg      return false;
4157ec681f3Smrg
4167ec681f3Smrg   for (unsigned i = 0; i < num_components; i++) {
4177ec681f3Smrg      uint32_t low_bits =
4187ec681f3Smrg         (1 << (nir_src_bit_size(instr->src[src].src) / 2)) - 1;
4197ec681f3Smrg      if ((nir_src_comp_as_int(instr->src[src].src, swizzle[i]) & low_bits) != 0)
4207ec681f3Smrg         return false;
4217ec681f3Smrg   }
4227ec681f3Smrg
4237ec681f3Smrg   return true;
4247ec681f3Smrg}
4257ec681f3Smrg
4267ec681f3Smrgstatic inline bool
4277ec681f3Smrgno_signed_wrap(nir_alu_instr *instr)
4287ec681f3Smrg{
4297ec681f3Smrg   return instr->no_signed_wrap;
4307ec681f3Smrg}
4317ec681f3Smrg
4327ec681f3Smrgstatic inline bool
4337ec681f3Smrgno_unsigned_wrap(nir_alu_instr *instr)
4347ec681f3Smrg{
4357ec681f3Smrg   return instr->no_unsigned_wrap;
4367ec681f3Smrg}
4377ec681f3Smrg
4387ec681f3Smrgstatic inline bool
4397ec681f3Smrgis_integral(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
4407ec681f3Smrg            UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
4417ec681f3Smrg{
4427ec681f3Smrg   const struct ssa_result_range r = nir_analyze_range(ht, instr, src);
4437ec681f3Smrg
4447ec681f3Smrg   return r.is_integral;
4457ec681f3Smrg}
4467ec681f3Smrg
4477ec681f3Smrg/**
4487ec681f3Smrg * Is the value finite?
4497ec681f3Smrg */
4507ec681f3Smrgstatic inline bool
4517ec681f3Smrgis_finite(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
4527ec681f3Smrg          unsigned src, UNUSED unsigned num_components,
4537ec681f3Smrg          UNUSED const uint8_t *swizzle)
4547ec681f3Smrg{
4557ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
4567ec681f3Smrg
4577ec681f3Smrg   return v.is_finite;
4587ec681f3Smrg}
4597ec681f3Smrg
4607ec681f3Smrg
4617ec681f3Smrg#define RELATION(r)                                                     \
4627ec681f3Smrgstatic inline bool                                                      \
4637ec681f3Smrgis_ ## r (struct hash_table *ht, const nir_alu_instr *instr,            \
4647ec681f3Smrg          unsigned src, UNUSED unsigned num_components,                 \
4657ec681f3Smrg          UNUSED const uint8_t *swizzle)                                \
4667ec681f3Smrg{                                                                       \
4677ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);  \
4687ec681f3Smrg   return v.range == r;                                                 \
4697ec681f3Smrg}                                                                       \
4707ec681f3Smrg                                                                        \
4717ec681f3Smrgstatic inline bool                                                      \
4727ec681f3Smrgis_a_number_ ## r (struct hash_table *ht, const nir_alu_instr *instr,   \
4737ec681f3Smrg                   unsigned src, UNUSED unsigned num_components,        \
4747ec681f3Smrg                   UNUSED const uint8_t *swizzle)                       \
4757ec681f3Smrg{                                                                       \
4767ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src); \
4777ec681f3Smrg   return v.is_a_number && v.range == r;                                \
4787ec681f3Smrg}
4797ec681f3Smrg
4807ec681f3SmrgRELATION(lt_zero)
4817ec681f3SmrgRELATION(le_zero)
4827ec681f3SmrgRELATION(gt_zero)
4837ec681f3SmrgRELATION(ge_zero)
4847ec681f3SmrgRELATION(ne_zero)
4857ec681f3Smrg
4867ec681f3Smrgstatic inline bool
4877ec681f3Smrgis_not_negative(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
4887ec681f3Smrg                UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
4897ec681f3Smrg{
4907ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
4917ec681f3Smrg   return v.range == ge_zero || v.range == gt_zero || v.range == eq_zero;
4927ec681f3Smrg}
4937ec681f3Smrg
4947ec681f3Smrgstatic inline bool
4957ec681f3Smrgis_a_number_not_negative(struct hash_table *ht, const nir_alu_instr *instr,
4967ec681f3Smrg                         unsigned src, UNUSED unsigned num_components,
4977ec681f3Smrg                         UNUSED const uint8_t *swizzle)
4987ec681f3Smrg{
4997ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
5007ec681f3Smrg   return v.is_a_number &&
5017ec681f3Smrg          (v.range == ge_zero || v.range == gt_zero || v.range == eq_zero);
5027ec681f3Smrg}
5037ec681f3Smrg
5047ec681f3Smrg
5057ec681f3Smrgstatic inline bool
5067ec681f3Smrgis_not_positive(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
5077ec681f3Smrg                UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
5087ec681f3Smrg{
5097ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
5107ec681f3Smrg   return v.range == le_zero || v.range == lt_zero || v.range == eq_zero;
5117ec681f3Smrg}
5127ec681f3Smrg
5137ec681f3Smrgstatic inline bool
5147ec681f3Smrgis_a_number_not_positive(struct hash_table *ht, const nir_alu_instr *instr,
5157ec681f3Smrg                         unsigned src, UNUSED unsigned num_components,
5167ec681f3Smrg                         UNUSED const uint8_t *swizzle)
5177ec681f3Smrg{
5187ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
5197ec681f3Smrg   return v.is_a_number &&
5207ec681f3Smrg          (v.range == le_zero || v.range == lt_zero || v.range == eq_zero);
5217ec681f3Smrg}
5227ec681f3Smrg
5237ec681f3Smrgstatic inline bool
5247ec681f3Smrgis_not_zero(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
5257ec681f3Smrg            UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
5267ec681f3Smrg{
5277ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
5287ec681f3Smrg   return v.range == lt_zero || v.range == gt_zero || v.range == ne_zero;
5297ec681f3Smrg}
5307ec681f3Smrg
5317ec681f3Smrgstatic inline bool
5327ec681f3Smrgis_a_number_not_zero(struct hash_table *ht, const nir_alu_instr *instr,
5337ec681f3Smrg                     unsigned src, UNUSED unsigned num_components,
5347ec681f3Smrg                     UNUSED const uint8_t *swizzle)
5357ec681f3Smrg{
5367ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
5377ec681f3Smrg   return v.is_a_number &&
5387ec681f3Smrg          (v.range == lt_zero || v.range == gt_zero || v.range == ne_zero);
5397ec681f3Smrg}
5407ec681f3Smrg
5417ec681f3Smrgstatic inline bool
5427ec681f3Smrgis_a_number(struct hash_table *ht, const nir_alu_instr *instr, unsigned src,
5437ec681f3Smrg            UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
5447ec681f3Smrg{
5457ec681f3Smrg   const struct ssa_result_range v = nir_analyze_range(ht, instr, src);
5467ec681f3Smrg   return v.is_a_number;
54701e04c3fSmrg}
54801e04c3fSmrg
54901e04c3fSmrg#endif /* _NIR_SEARCH_ */
550