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