#include "midgard_nir.h"

#include "nir.h"
#include "nir_builder.h"
#include "nir_search.h"
#include "nir_search_helpers.h"

/* What follows is NIR algebraic transform code for the following 1
 * transforms:
 *    ('~fadd', ('fadd', 'a', 'b'), 'a') => ('fadd', ('fadd', 'a', 'a'), 'b')
 */


static const nir_search_value_union midgard_nir_lower_algebraic_early_values[] = {
   /* ('~fadd', ('fadd', 'a', 'b'), 'a') => ('fadd', ('fadd', 'a', 'a'), 'b') */
   { .variable = {
      { nir_search_value_variable, -2 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -2 },
      1, /* b */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      nir_op_fadd,
      1, 1,
      { 0, 1 },
      -1,
   } },
   /* search0_1 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      true,
      false,
      false,
      nir_op_fadd,
      0, 2,
      { 2, 0 },
      -1,
   } },

   /* replace0_0_0 -> 0 in the cache */
   /* replace0_0_1 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      nir_op_fadd,
      -1, 0,
      { 0, 0 },
      -1,
   } },
   /* replace0_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      nir_op_fadd,
      0, 1,
      { 4, 1 },
      -1,
   } },

};



static const struct transform midgard_nir_lower_algebraic_early_transforms[] = {
   { ~0, ~0, ~0 }, /* Sentinel */

   { 3, 5, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

};

static const struct per_op_table midgard_nir_lower_algebraic_early_pass_op_table[nir_num_search_ops] = {
   [nir_op_fadd] = {
      .filter = (const uint16_t []) {
         0,
         0,
         1,
         1,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         2,
         3,
         3,
         3,
      },
   },
};

/* Mapping from state index to offset in transforms (0 being no transforms) */
static const uint16_t midgard_nir_lower_algebraic_early_transform_offsets[] = {
   0,
   0,
   0,
   1,
};

static const nir_algebraic_table midgard_nir_lower_algebraic_early_table = {
   .transforms = midgard_nir_lower_algebraic_early_transforms,
   .transform_offsets = midgard_nir_lower_algebraic_early_transform_offsets,
   .pass_op_table = midgard_nir_lower_algebraic_early_pass_op_table,
   .values = midgard_nir_lower_algebraic_early_values,
   .expression_cond = NULL,
   .variable_cond = NULL,
};

bool
midgard_nir_lower_algebraic_early(nir_shader *shader)
{
   bool progress = false;
   bool condition_flags[1];
   const nir_shader_compiler_options *options = shader->options;
   const shader_info *info = &shader->info;
   (void) options;
   (void) info;

   STATIC_ASSERT(6 == ARRAY_SIZE(midgard_nir_lower_algebraic_early_values));
   condition_flags[0] = true;

   nir_foreach_function(function, shader) {
      if (function->impl) {
         progress |= nir_algebraic_impl(function->impl, condition_flags,
                                        &midgard_nir_lower_algebraic_early_table);
      }
   }

   return progress;
}


#include "nir.h"
#include "nir_builder.h"
#include "nir_search.h"
#include "nir_search_helpers.h"

/* What follows is NIR algebraic transform code for the following 54
 * transforms:
 *    ('ineg', 'a') => ('isub', 0, 'a')
 *    ('fsub', 'a', 'b') => ('fadd', 'a', ('fneg', 'b'))
 *    ('b32csel', 'a', 'b@32', 0) => ('iand', 'a', 'b')
 *    ('b32csel', 'a', 0, 'b@32') => ('iand', ('inot', 'a'), 'b')
 *    ('~fmin', ('fmax', 'a', -1.0), 1.0) => ('fsat_signed_mali', 'a')
 *    ('~fmax', ('fmin', 'a', 1.0), -1.0) => ('fsat_signed_mali', 'a')
 *    ('fmax', 'a', 0.0) => ('fclamp_pos_mali', 'a')
 *    ('ishl', 'a@16', 'b') => ('u2u16', ('ishl', ('u2u32', 'a'), 'b'))
 *    ('ishr', 'a@16', 'b') => ('i2i16', ('ishr', ('i2i32', 'a'), 'b'))
 *    ('ushr', 'a@16', 'b') => ('u2u16', ('ushr', ('u2u32', 'a'), 'b'))
 *    ('ishl', 'a@8', 'b') => ('u2u8', ('u2u16', ('ishl', ('u2u32', ('u2u16', 'a')), 'b')))
 *    ('ishr', 'a@8', 'b') => ('i2i8', ('i2i16', ('ishr', ('i2i32', ('i2i16', 'a')), 'b')))
 *    ('ushr', 'a@8', 'b') => ('u2u8', ('u2u16', ('ushr', ('u2u32', ('u2u16', 'a')), 'b')))
 *    ('fmul', 'a', 2.0) => ('fadd', 'a', 'a')
 *    ('ufind_msb', 'a@8') => ('isub', 31, ('uclz', ('u2u32', 'a')))
 *    ('ufind_msb', 'a@16') => ('isub', 31, ('uclz', ('u2u32', 'a')))
 *    ('ufind_msb', 'a@32') => ('isub', 31, ('uclz', 'a'))
 *    ('u2u8', 'a@32') => ('u2u8', ('u2u16', 'a'))
 *    ('u2u8', 'a@64') => ('u2u8', ('u2u16', ('u2u32', 'a')))
 *    ('u2u16', 'a@64') => ('u2u16', ('u2u32', 'a'))
 *    ('u2u32', 'a@8') => ('u2u32', ('u2u16', 'a'))
 *    ('u2u64', 'a@8') => ('u2u64', ('u2u32', ('u2u16', 'a')))
 *    ('u2u64', 'a@16') => ('u2u64', ('u2u32', 'a'))
 *    ('i2i8', 'a@32') => ('i2i8', ('i2i16', 'a'))
 *    ('i2i8', 'a@64') => ('i2i8', ('i2i16', ('i2i32', 'a')))
 *    ('i2i16', 'a@64') => ('i2i16', ('i2i32', 'a'))
 *    ('i2i32', 'a@8') => ('i2i32', ('i2i16', 'a'))
 *    ('i2i64', 'a@8') => ('i2i64', ('i2i32', ('i2i16', 'a')))
 *    ('i2i64', 'a@16') => ('i2i64', ('i2i32', 'a'))
 *    ('f2f16', 'a@64') => ('f2f16', ('f2f32', 'a'))
 *    ('f2f64', 'a@16') => ('f2f64', ('f2f32', 'a'))
 *    ('i2f16', 'a@64') => ('f2f16', ('f2f32', ('i2f64', 'a')))
 *    ('i2f32', 'a@8') => ('i2f32', ('i2i32', ('i2i16', 'a')))
 *    ('i2f64', 'a@8') => ('i2f64', ('i2i64', ('i2i32', ('i2i16', 'a'))))
 *    ('i2f64', 'a@16') => ('i2f64', ('i2i64', ('i2i32', 'a')))
 *    ('u2f16', 'a@64') => ('f2f16', ('f2f32', ('u2f64', 'a')))
 *    ('u2f32', 'a@8') => ('u2f32', ('u2u32', ('u2u16', 'a')))
 *    ('u2f64', 'a@8') => ('u2f64', ('u2u64', ('u2u32', ('u2u16', 'a'))))
 *    ('u2f64', 'a@16') => ('u2f64', ('u2u64', ('u2u32', 'a')))
 *    ('f2i8', 'a@32') => ('i2i8', ('i2i16', ('f2i32', 'a')))
 *    ('f2i8', 'a@64') => ('i2i8', ('i2i16', ('i2i32', ('f2i64', 'a'))))
 *    ('f2i16', 'a@64') => ('i2i16', ('i2i32', ('f2i64', 'a')))
 *    ('f2i64', 'a@16') => ('f2i64', ('f2f64', ('f2f32', 'a')))
 *    ('f2u8', 'a@32') => ('u2u8', ('u2u16', ('f2u32', 'a')))
 *    ('f2u8', 'a@64') => ('u2u8', ('u2u16', ('u2u32', ('f2u64', 'a'))))
 *    ('f2u16', 'a@64') => ('u2u16', ('u2u32', ('f2u64', 'a')))
 *    ('f2u64', 'a@16') => ('f2u64', ('f2f64', ('f2f32', 'a')))
 *    ('fge', 'a', '#b') => ('inot', ('flt', 'a', 'b'))
 *    ('fge32', 'a', '#b') => ('inot', ('flt32', 'a', 'b'))
 *    ('ige32', 'a', '#b') => ('inot', ('ilt32', 'a', 'b'))
 *    ('uge32', 'a', '#b') => ('inot', ('ult32', 'a', 'b'))
 *    ('flt32', '#a', 'b') => ('inot', ('fge32', 'a', 'b'))
 *    ('ilt32', '#a', 'b') => ('inot', ('ige32', 'a', 'b'))
 *    ('ult32', '#a', 'b') => ('inot', ('uge32', 'a', 'b'))
 */


static const nir_search_value_union midgard_nir_lower_algebraic_late_values[] = {
   /* ('ineg', 'a') => ('isub', 0, 'a') */
   { .variable = {
      { nir_search_value_variable, -1 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_ineg,
      -1, 0,
      { 0 },
      -1,
   } },

   { .constant = {
      { nir_search_value_constant, -1 },
      nir_type_int, { 0x0 /* 0 */ },
   } },
   /* replace1_1 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_isub,
      -1, 0,
      { 2, 0 },
      -1,
   } },

   /* ('fsub', 'a', 'b') => ('fadd', 'a', ('fneg', 'b')) */
   { .variable = {
      { nir_search_value_variable, -2 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -2 },
      1, /* b */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      nir_op_fsub,
      -1, 0,
      { 4, 5 },
      -1,
   } },

   /* replace2_0 -> 4 in the cache */
   /* replace2_1_0 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      nir_op_fneg,
      -1, 0,
      { 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      nir_op_fadd,
      0, 1,
      { 4, 7 },
      -1,
   } },

   /* ('b32csel', 'a', 'b@32', 0) => ('iand', 'a', 'b') */
   { .variable = {
      { nir_search_value_variable, 32 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, 32 },
      1, /* b */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .constant = {
      { nir_search_value_constant, 32 },
      nir_type_int, { 0x0 /* 0 */ },
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_b32csel,
      -1, 0,
      { 9, 10, 11 },
      -1,
   } },

   /* replace3_0 -> 9 in the cache */
   /* replace3_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_iand,
      0, 1,
      { 9, 10 },
      -1,
   } },

   /* ('b32csel', 'a', 0, 'b@32') => ('iand', ('inot', 'a'), 'b') */
   /* search4_0 -> 9 in the cache */
   /* search4_1 -> 11 in the cache */
   /* search4_2 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_b32csel,
      -1, 0,
      { 9, 11, 10 },
      -1,
   } },

   /* replace4_0_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 9 },
      -1,
   } },
   /* replace4_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_iand,
      0, 1,
      { 15, 10 },
      -1,
   } },

   /* ('~fmin', ('fmax', 'a', -1.0), 1.0) => ('fsat_signed_mali', 'a') */
   /* search5_0_0 -> 0 in the cache */
   { .constant = {
      { nir_search_value_constant, -1 },
      nir_type_float, { 0xbff0000000000000 /* -1.0 */ },
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fmax,
      1, 1,
      { 0, 17 },
      -1,
   } },
   { .constant = {
      { nir_search_value_constant, -1 },
      nir_type_float, { 0x3ff0000000000000 /* 1.0 */ },
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      true,
      false,
      false,
      nir_op_fmin,
      0, 2,
      { 18, 19 },
      -1,
   } },

   /* replace5_0 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fsat_signed_mali,
      -1, 0,
      { 0 },
      -1,
   } },

   /* ('~fmax', ('fmin', 'a', 1.0), -1.0) => ('fsat_signed_mali', 'a') */
   /* search6_0_0 -> 0 in the cache */
   /* search6_0_1 -> 19 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fmin,
      1, 1,
      { 0, 19 },
      -1,
   } },
   /* search6_1 -> 17 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      true,
      false,
      false,
      nir_op_fmax,
      0, 2,
      { 22, 17 },
      -1,
   } },

   /* replace6_0 -> 0 in the cache */
   /* replace6 -> 21 in the cache */

   /* ('fmax', 'a', 0.0) => ('fclamp_pos_mali', 'a') */
   /* search7_0 -> 0 in the cache */
   { .constant = {
      { nir_search_value_constant, -1 },
      nir_type_float, { 0x0 /* 0.0 */ },
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fmax,
      0, 1,
      { 0, 24 },
      -1,
   } },

   /* replace7_0 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fclamp_pos_mali,
      -1, 0,
      { 0 },
      -1,
   } },

   /* ('ishl', 'a@16', 'b') => ('u2u16', ('ishl', ('u2u32', 'a'), 'b')) */
   { .variable = {
      { nir_search_value_variable, 16 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   /* search8_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_ishl,
      -1, 0,
      { 27, 10 },
      -1,
   } },

   /* replace8_0_0_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2u32,
      -1, 0,
      { 27 },
      -1,
   } },
   /* replace8_0_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ishl,
      -1, 0,
      { 29, 10 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('ishr', 'a@16', 'b') => ('i2i16', ('ishr', ('i2i32', 'a'), 'b')) */
   /* search9_0 -> 27 in the cache */
   /* search9_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_ishr,
      -1, 0,
      { 27, 10 },
      -1,
   } },

   /* replace9_0_0_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2i32,
      -1, 0,
      { 27 },
      -1,
   } },
   /* replace9_0_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ishr,
      -1, 0,
      { 33, 10 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 34 },
      -1,
   } },

   /* ('ushr', 'a@16', 'b') => ('u2u16', ('ushr', ('u2u32', 'a'), 'b')) */
   /* search10_0 -> 27 in the cache */
   /* search10_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_ushr,
      -1, 0,
      { 27, 10 },
      -1,
   } },

   /* replace10_0_0_0 -> 27 in the cache */
   /* replace10_0_0 -> 29 in the cache */
   /* replace10_0_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ushr,
      -1, 0,
      { 29, 10 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 37 },
      -1,
   } },

   /* ('ishl', 'a@8', 'b') => ('u2u8', ('u2u16', ('ishl', ('u2u32', ('u2u16', 'a')), 'b'))) */
   { .variable = {
      { nir_search_value_variable, 8 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   /* search11_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_ishl,
      -1, 0,
      { 39, 10 },
      -1,
   } },

   /* replace11_0_0_0_0_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 39 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2u32,
      -1, 0,
      { 41 },
      -1,
   } },
   /* replace11_0_0_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ishl,
      -1, 0,
      { 42, 10 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 43 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 44 },
      -1,
   } },

   /* ('ishr', 'a@8', 'b') => ('i2i8', ('i2i16', ('ishr', ('i2i32', ('i2i16', 'a')), 'b'))) */
   /* search12_0 -> 39 in the cache */
   /* search12_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_ishr,
      -1, 0,
      { 39, 10 },
      -1,
   } },

   /* replace12_0_0_0_0_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 39 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2i32,
      -1, 0,
      { 47 },
      -1,
   } },
   /* replace12_0_0_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ishr,
      -1, 0,
      { 48, 10 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 49 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 50 },
      -1,
   } },

   /* ('ushr', 'a@8', 'b') => ('u2u8', ('u2u16', ('ushr', ('u2u32', ('u2u16', 'a')), 'b'))) */
   /* search13_0 -> 39 in the cache */
   /* search13_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_ushr,
      -1, 0,
      { 39, 10 },
      -1,
   } },

   /* replace13_0_0_0_0_0 -> 39 in the cache */
   /* replace13_0_0_0_0 -> 41 in the cache */
   /* replace13_0_0_0 -> 42 in the cache */
   /* replace13_0_0_1 -> 10 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ushr,
      -1, 0,
      { 42, 10 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 53 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 54 },
      -1,
   } },

   /* ('fmul', 'a', 2.0) => ('fadd', 'a', 'a') */
   /* search14_0 -> 0 in the cache */
   { .constant = {
      { nir_search_value_constant, -1 },
      nir_type_float, { 0x4000000000000000 /* 2.0 */ },
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fmul,
      0, 1,
      { 0, 56 },
      -1,
   } },

   /* replace14_0 -> 0 in the cache */
   /* replace14_1 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fadd,
      -1, 0,
      { 0, 0 },
      -1,
   } },

   /* ('ufind_msb', 'a@8') => ('isub', 31, ('uclz', ('u2u32', 'a'))) */
   /* search15_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ufind_msb,
      -1, 0,
      { 39 },
      -1,
   } },

   { .constant = {
      { nir_search_value_constant, 32 },
      nir_type_int, { 0x1f /* 31 */ },
   } },
   /* replace15_1_0_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2u32,
      -1, 0,
      { 39 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_uclz,
      -1, 0,
      { 61 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_isub,
      -1, 0,
      { 60, 62 },
      -1,
   } },

   /* ('ufind_msb', 'a@16') => ('isub', 31, ('uclz', ('u2u32', 'a'))) */
   /* search16_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ufind_msb,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace16_0 -> 60 in the cache */
   /* replace16_1_0_0 -> 27 in the cache */
   /* replace16_1_0 -> 29 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_uclz,
      -1, 0,
      { 29 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_isub,
      -1, 0,
      { 60, 65 },
      -1,
   } },

   /* ('ufind_msb', 'a@32') => ('isub', 31, ('uclz', 'a')) */
   /* search17_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ufind_msb,
      -1, 0,
      { 9 },
      -1,
   } },

   /* replace17_0 -> 60 in the cache */
   /* replace17_1_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_uclz,
      -1, 0,
      { 9 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_isub,
      -1, 0,
      { 60, 68 },
      -1,
   } },

   /* ('u2u8', 'a@32') => ('u2u8', ('u2u16', 'a')) */
   /* search18_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 9 },
      -1,
   } },

   /* replace18_0_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 9 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 71 },
      -1,
   } },

   /* ('u2u8', 'a@64') => ('u2u8', ('u2u16', ('u2u32', 'a'))) */
   { .variable = {
      { nir_search_value_variable, 64 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace19_0_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2u32,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 75 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 76 },
      -1,
   } },

   /* ('u2u16', 'a@64') => ('u2u16', ('u2u32', 'a')) */
   /* search20_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace20_0_0 -> 73 in the cache */
   /* replace20_0 -> 75 in the cache */
   /* replace20 -> 76 in the cache */

   /* ('u2u32', 'a@8') => ('u2u32', ('u2u16', 'a')) */
   /* search21_0 -> 39 in the cache */
   /* search21 -> 61 in the cache */

   /* replace21_0_0 -> 39 in the cache */
   /* replace21_0 -> 41 in the cache */
   /* replace21 -> 42 in the cache */

   /* ('u2u64', 'a@8') => ('u2u64', ('u2u32', ('u2u16', 'a'))) */
   /* search22_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2u64,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace22_0_0_0 -> 39 in the cache */
   /* replace22_0_0 -> 41 in the cache */
   /* replace22_0 -> 42 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2u64,
      -1, 0,
      { 42 },
      -1,
   } },

   /* ('u2u64', 'a@16') => ('u2u64', ('u2u32', 'a')) */
   /* search23_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2u64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace23_0_0 -> 27 in the cache */
   /* replace23_0 -> 29 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2u64,
      -1, 0,
      { 29 },
      -1,
   } },

   /* ('i2i8', 'a@32') => ('i2i8', ('i2i16', 'a')) */
   /* search24_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 9 },
      -1,
   } },

   /* replace24_0_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 9 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 84 },
      -1,
   } },

   /* ('i2i8', 'a@64') => ('i2i8', ('i2i16', ('i2i32', 'a'))) */
   /* search25_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace25_0_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2i32,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 87 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 88 },
      -1,
   } },

   /* ('i2i16', 'a@64') => ('i2i16', ('i2i32', 'a')) */
   /* search26_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace26_0_0 -> 73 in the cache */
   /* replace26_0 -> 87 in the cache */
   /* replace26 -> 88 in the cache */

   /* ('i2i32', 'a@8') => ('i2i32', ('i2i16', 'a')) */
   /* search27_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2i32,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace27_0_0 -> 39 in the cache */
   /* replace27_0 -> 47 in the cache */
   /* replace27 -> 48 in the cache */

   /* ('i2i64', 'a@8') => ('i2i64', ('i2i32', ('i2i16', 'a'))) */
   /* search28_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2i64,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace28_0_0_0 -> 39 in the cache */
   /* replace28_0_0 -> 47 in the cache */
   /* replace28_0 -> 48 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2i64,
      -1, 0,
      { 48 },
      -1,
   } },

   /* ('i2i64', 'a@16') => ('i2i64', ('i2i32', 'a')) */
   /* search29_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2i64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace29_0_0 -> 27 in the cache */
   /* replace29_0 -> 33 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2i64,
      -1, 0,
      { 33 },
      -1,
   } },

   /* ('f2f16', 'a@64') => ('f2f16', ('f2f32', 'a')) */
   /* search30_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_f2f16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace30_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_f2f32,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_f2f16,
      -1, 0,
      { 97 },
      -1,
   } },

   /* ('f2f64', 'a@16') => ('f2f64', ('f2f32', 'a')) */
   /* search31_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2f64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace31_0_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_f2f32,
      -1, 0,
      { 27 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2f64,
      -1, 0,
      { 100 },
      -1,
   } },

   /* ('i2f16', 'a@64') => ('f2f16', ('f2f32', ('i2f64', 'a'))) */
   /* search32_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2f16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace32_0_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2f64,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_f2f32,
      -1, 0,
      { 103 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_f2f16,
      -1, 0,
      { 104 },
      -1,
   } },

   /* ('i2f32', 'a@8') => ('i2f32', ('i2i32', ('i2i16', 'a'))) */
   /* search33_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2f32,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace33_0_0_0 -> 39 in the cache */
   /* replace33_0_0 -> 47 in the cache */
   /* replace33_0 -> 48 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2f32,
      -1, 0,
      { 48 },
      -1,
   } },

   /* ('i2f64', 'a@8') => ('i2f64', ('i2i64', ('i2i32', ('i2i16', 'a')))) */
   /* search34_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2f64,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace34_0_0_0_0 -> 39 in the cache */
   /* replace34_0_0_0 -> 47 in the cache */
   /* replace34_0_0 -> 48 in the cache */
   /* replace34_0 -> 93 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2f64,
      -1, 0,
      { 93 },
      -1,
   } },

   /* ('i2f64', 'a@16') => ('i2f64', ('i2i64', ('i2i32', 'a'))) */
   /* search35_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2f64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace35_0_0_0 -> 27 in the cache */
   /* replace35_0_0 -> 33 in the cache */
   /* replace35_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_i2f64,
      -1, 0,
      { 95 },
      -1,
   } },

   /* ('u2f16', 'a@64') => ('f2f16', ('f2f32', ('u2f64', 'a'))) */
   /* search36_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2f16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace36_0_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2f64,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_f2f32,
      -1, 0,
      { 113 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_f2f16,
      -1, 0,
      { 114 },
      -1,
   } },

   /* ('u2f32', 'a@8') => ('u2f32', ('u2u32', ('u2u16', 'a'))) */
   /* search37_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2f32,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace37_0_0_0 -> 39 in the cache */
   /* replace37_0_0 -> 41 in the cache */
   /* replace37_0 -> 42 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2f32,
      -1, 0,
      { 42 },
      -1,
   } },

   /* ('u2f64', 'a@8') => ('u2f64', ('u2u64', ('u2u32', ('u2u16', 'a')))) */
   /* search38_0 -> 39 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2f64,
      -1, 0,
      { 39 },
      -1,
   } },

   /* replace38_0_0_0_0 -> 39 in the cache */
   /* replace38_0_0_0 -> 41 in the cache */
   /* replace38_0_0 -> 42 in the cache */
   /* replace38_0 -> 80 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2f64,
      -1, 0,
      { 80 },
      -1,
   } },

   /* ('u2f64', 'a@16') => ('u2f64', ('u2u64', ('u2u32', 'a'))) */
   /* search39_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2f64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace39_0_0_0 -> 27 in the cache */
   /* replace39_0_0 -> 29 in the cache */
   /* replace39_0 -> 82 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_u2f64,
      -1, 0,
      { 82 },
      -1,
   } },

   /* ('f2i8', 'a@32') => ('i2i8', ('i2i16', ('f2i32', 'a'))) */
   /* search40_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_f2i8,
      -1, 0,
      { 9 },
      -1,
   } },

   /* replace40_0_0_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_f2i32,
      -1, 0,
      { 9 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 123 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 124 },
      -1,
   } },

   /* ('f2i8', 'a@64') => ('i2i8', ('i2i16', ('i2i32', ('f2i64', 'a')))) */
   /* search41_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_f2i8,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace41_0_0_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2i64,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_i2i32,
      -1, 0,
      { 127 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_i2i16,
      -1, 0,
      { 128 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_i2i8,
      -1, 0,
      { 129 },
      -1,
   } },

   /* ('f2i16', 'a@64') => ('i2i16', ('i2i32', ('f2i64', 'a'))) */
   /* search42_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_f2i16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace42_0_0_0 -> 73 in the cache */
   /* replace42_0_0 -> 127 in the cache */
   /* replace42_0 -> 128 in the cache */
   /* replace42 -> 129 in the cache */

   /* ('f2i64', 'a@16') => ('f2i64', ('f2f64', ('f2f32', 'a'))) */
   /* search43_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2i64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace43_0_0_0 -> 27 in the cache */
   /* replace43_0_0 -> 100 in the cache */
   /* replace43_0 -> 101 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2i64,
      -1, 0,
      { 101 },
      -1,
   } },

   /* ('f2u8', 'a@32') => ('u2u8', ('u2u16', ('f2u32', 'a'))) */
   /* search44_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_f2u8,
      -1, 0,
      { 9 },
      -1,
   } },

   /* replace44_0_0_0 -> 9 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_f2u32,
      -1, 0,
      { 9 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 135 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 136 },
      -1,
   } },

   /* ('f2u8', 'a@64') => ('u2u8', ('u2u16', ('u2u32', ('f2u64', 'a')))) */
   /* search45_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_f2u8,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace45_0_0_0_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2u64,
      -1, 0,
      { 73 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_u2u32,
      -1, 0,
      { 139 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_u2u16,
      -1, 0,
      { 140 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 8 },
      false,
      false,
      false,
      nir_op_u2u8,
      -1, 0,
      { 141 },
      -1,
   } },

   /* ('f2u16', 'a@64') => ('u2u16', ('u2u32', ('f2u64', 'a'))) */
   /* search46_0 -> 73 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      false,
      false,
      false,
      nir_op_f2u16,
      -1, 0,
      { 73 },
      -1,
   } },

   /* replace46_0_0_0 -> 73 in the cache */
   /* replace46_0_0 -> 139 in the cache */
   /* replace46_0 -> 140 in the cache */
   /* replace46 -> 141 in the cache */

   /* ('f2u64', 'a@16') => ('f2u64', ('f2f64', ('f2f32', 'a'))) */
   /* search47_0 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2u64,
      -1, 0,
      { 27 },
      -1,
   } },

   /* replace47_0_0_0 -> 27 in the cache */
   /* replace47_0_0 -> 100 in the cache */
   /* replace47_0 -> 101 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      false,
      false,
      false,
      nir_op_f2u64,
      -1, 0,
      { 101 },
      -1,
   } },

   /* ('fge', 'a', '#b') => ('inot', ('flt', 'a', 'b')) */
   /* search48_0 -> 4 in the cache */
   { .variable = {
      { nir_search_value_variable, -2 },
      1, /* b */
      true,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      nir_op_fge,
      -1, 0,
      { 4, 146 },
      -1,
   } },

   /* replace48_0_0 -> 4 in the cache */
   /* replace48_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      nir_op_flt,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 148 },
      -1,
   } },

   /* ('fge32', 'a', '#b') => ('inot', ('flt32', 'a', 'b')) */
   /* search49_0 -> 4 in the cache */
   /* search49_1 -> 146 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_fge32,
      -1, 0,
      { 4, 146 },
      -1,
   } },

   /* replace49_0_0 -> 4 in the cache */
   /* replace49_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_flt32,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 151 },
      -1,
   } },

   /* ('ige32', 'a', '#b') => ('inot', ('ilt32', 'a', 'b')) */
   /* search50_0 -> 4 in the cache */
   /* search50_1 -> 146 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ige32,
      -1, 0,
      { 4, 146 },
      -1,
   } },

   /* replace50_0_0 -> 4 in the cache */
   /* replace50_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ilt32,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 154 },
      -1,
   } },

   /* ('uge32', 'a', '#b') => ('inot', ('ult32', 'a', 'b')) */
   /* search51_0 -> 4 in the cache */
   /* search51_1 -> 146 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_uge32,
      -1, 0,
      { 4, 146 },
      -1,
   } },

   /* replace51_0_0 -> 4 in the cache */
   /* replace51_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ult32,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 157 },
      -1,
   } },

   /* ('flt32', '#a', 'b') => ('inot', ('fge32', 'a', 'b')) */
   { .variable = {
      { nir_search_value_variable, -2 },
      0, /* a */
      true,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   /* search52_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_flt32,
      -1, 0,
      { 159, 5 },
      -1,
   } },

   /* replace52_0_0 -> 4 in the cache */
   /* replace52_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_fge32,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 161 },
      -1,
   } },

   /* ('ilt32', '#a', 'b') => ('inot', ('ige32', 'a', 'b')) */
   /* search53_0 -> 159 in the cache */
   /* search53_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ilt32,
      -1, 0,
      { 159, 5 },
      -1,
   } },

   /* replace53_0_0 -> 4 in the cache */
   /* replace53_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ige32,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 164 },
      -1,
   } },

   /* ('ult32', '#a', 'b') => ('inot', ('uge32', 'a', 'b')) */
   /* search54_0 -> 159 in the cache */
   /* search54_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_ult32,
      -1, 0,
      { 159, 5 },
      -1,
   } },

   /* replace54_0_0 -> 4 in the cache */
   /* replace54_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_uge32,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 167 },
      -1,
   } },

};



static const struct transform midgard_nir_lower_algebraic_late_transforms[] = {
   { ~0, ~0, ~0 }, /* Sentinel */

   { 1, 3, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 6, 8, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 12, 13, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 14, 16, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 12, 13, 0 },
   { 14, 16, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 25, 26, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 28, 31, 0 },
   { 40, 45, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 32, 35, 0 },
   { 46, 51, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 36, 38, 0 },
   { 52, 55, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 57, 58, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 59, 63, 0 },
   { 64, 66, 0 },
   { 67, 69, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 70, 72, 0 },
   { 74, 77, 0 },
   { 78, 76, 0 },
   { 61, 42, 0 },
   { 79, 80, 0 },
   { 81, 82, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 83, 85, 0 },
   { 86, 89, 0 },
   { 90, 88, 0 },
   { 91, 48, 0 },
   { 92, 93, 0 },
   { 94, 95, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 96, 98, 0 },
   { 99, 101, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 102, 105, 0 },
   { 106, 107, 0 },
   { 108, 109, 0 },
   { 110, 111, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 112, 115, 0 },
   { 116, 117, 0 },
   { 118, 119, 0 },
   { 120, 121, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 122, 125, 0 },
   { 126, 130, 0 },
   { 131, 129, 0 },
   { 132, 133, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 134, 137, 0 },
   { 138, 142, 0 },
   { 143, 141, 0 },
   { 144, 145, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 147, 149, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 150, 152, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 153, 155, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 156, 158, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 160, 162, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 163, 165, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 166, 168, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 23, 21, 0 },
   { 25, 26, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 20, 21, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

};

static const struct per_op_table midgard_nir_lower_algebraic_late_pass_op_table[nir_num_search_ops] = {
   [nir_op_ineg] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         2,
      },
   },
   [nir_op_fsub] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         3,
      },
   },
   [nir_op_b32csel] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         4,
         5,
         6,
         0,
         4,
         5,
         6,
      },
   },
   [nir_op_fmin] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         0,
         7,
         0,
         7,
         7,
         29,
         0,
         29,
         0,
      },
   },
   [nir_op_fmax] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         0,
         8,
         0,
         8,
         8,
         28,
         0,
         28,
         0,
      },
   },
   [nir_op_ishl] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         9,
      },
   },
   [nir_op_ishr] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         10,
      },
   },
   [nir_op_ushr] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         11,
      },
   },
   [nir_op_fmul] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         12,
         12,
         12,
      },
   },
   [nir_op_ufind_msb] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         13,
      },
   },
   [nir_search_op_u2u] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         14,
      },
   },
   [nir_search_op_i2i] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         15,
      },
   },
   [nir_search_op_f2f] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         16,
      },
   },
   [nir_search_op_i2f] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         17,
      },
   },
   [nir_search_op_u2f] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         18,
      },
   },
   [nir_search_op_f2i] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         19,
      },
   },
   [nir_search_op_f2u] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         20,
      },
   },
   [nir_op_fge] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         21,
         0,
         21,
      },
   },
   [nir_op_fge32] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         22,
         0,
         22,
      },
   },
   [nir_op_ige32] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         23,
         0,
         23,
      },
   },
   [nir_op_uge32] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         24,
         0,
         24,
      },
   },
   [nir_op_flt32] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         0,
         25,
         25,
      },
   },
   [nir_op_ilt32] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         0,
         26,
         26,
      },
   },
   [nir_op_ult32] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         0,
         0,
         27,
         27,
      },
   },
};

/* Mapping from state index to offset in transforms (0 being no transforms) */
static const uint16_t midgard_nir_lower_algebraic_late_transform_offsets[] = {
   0,
   0,
   1,
   3,
   5,
   7,
   9,
   0,
   12,
   14,
   17,
   20,
   23,
   25,
   29,
   36,
   43,
   46,
   51,
   56,
   61,
   66,
   68,
   70,
   72,
   74,
   76,
   78,
   80,
   83,
};

static const nir_algebraic_table midgard_nir_lower_algebraic_late_table = {
   .transforms = midgard_nir_lower_algebraic_late_transforms,
   .transform_offsets = midgard_nir_lower_algebraic_late_transform_offsets,
   .pass_op_table = midgard_nir_lower_algebraic_late_pass_op_table,
   .values = midgard_nir_lower_algebraic_late_values,
   .expression_cond = NULL,
   .variable_cond = NULL,
};

bool
midgard_nir_lower_algebraic_late(nir_shader *shader)
{
   bool progress = false;
   bool condition_flags[1];
   const nir_shader_compiler_options *options = shader->options;
   const shader_info *info = &shader->info;
   (void) options;
   (void) info;

   STATIC_ASSERT(169 == ARRAY_SIZE(midgard_nir_lower_algebraic_late_values));
   condition_flags[0] = true;

   nir_foreach_function(function, shader) {
      if (function->impl) {
         progress |= nir_algebraic_impl(function->impl, condition_flags,
                                        &midgard_nir_lower_algebraic_late_table);
      }
   }

   return progress;
}


#include "nir.h"
#include "nir_builder.h"
#include "nir_search.h"
#include "nir_search_helpers.h"

/* What follows is NIR algebraic transform code for the following 2
 * transforms:
 *    ('fsin', 'a') => ('fsin', ('fdiv', 'a', 3.141592653589793))
 *    ('fcos', 'a') => ('fcos', ('fdiv', 'a', 3.141592653589793))
 */


static const nir_search_value_union midgard_nir_scale_trig_values[] = {
   /* ('fsin', 'a') => ('fsin', ('fdiv', 'a', 3.141592653589793)) */
   { .variable = {
      { nir_search_value_variable, -1 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fsin,
      -1, 0,
      { 0 },
      -1,
   } },

   /* replace55_0_0 -> 0 in the cache */
   { .constant = {
      { nir_search_value_constant, -1 },
      nir_type_float, { 0x400921fb54442d18 /* 3.141592653589793 */ },
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fdiv,
      -1, 0,
      { 0, 2 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fsin,
      -1, 0,
      { 3 },
      -1,
   } },

   /* ('fcos', 'a') => ('fcos', ('fdiv', 'a', 3.141592653589793)) */
   /* search56_0 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fcos,
      -1, 0,
      { 0 },
      -1,
   } },

   /* replace56_0_0 -> 0 in the cache */
   /* replace56_0_1 -> 2 in the cache */
   /* replace56_0 -> 3 in the cache */
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_fcos,
      -1, 0,
      { 3 },
      -1,
   } },

};



static const struct transform midgard_nir_scale_trig_transforms[] = {
   { ~0, ~0, ~0 }, /* Sentinel */

   { 1, 4, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 5, 6, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

};

static const struct per_op_table midgard_nir_scale_trig_pass_op_table[nir_num_search_ops] = {
   [nir_op_fsin] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         2,
      },
   },
   [nir_op_fcos] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         3,
      },
   },
};

/* Mapping from state index to offset in transforms (0 being no transforms) */
static const uint16_t midgard_nir_scale_trig_transform_offsets[] = {
   0,
   0,
   1,
   3,
};

static const nir_algebraic_table midgard_nir_scale_trig_table = {
   .transforms = midgard_nir_scale_trig_transforms,
   .transform_offsets = midgard_nir_scale_trig_transform_offsets,
   .pass_op_table = midgard_nir_scale_trig_pass_op_table,
   .values = midgard_nir_scale_trig_values,
   .expression_cond = NULL,
   .variable_cond = NULL,
};

bool
midgard_nir_scale_trig(nir_shader *shader)
{
   bool progress = false;
   bool condition_flags[1];
   const nir_shader_compiler_options *options = shader->options;
   const shader_info *info = &shader->info;
   (void) options;
   (void) info;

   STATIC_ASSERT(7 == ARRAY_SIZE(midgard_nir_scale_trig_values));
   condition_flags[0] = true;

   nir_foreach_function(function, shader) {
      if (function->impl) {
         progress |= nir_algebraic_impl(function->impl, condition_flags,
                                        &midgard_nir_scale_trig_table);
      }
   }

   return progress;
}


#include "nir.h"
#include "nir_builder.h"
#include "nir_search.h"
#include "nir_search_helpers.h"

/* What follows is NIR algebraic transform code for the following 1
 * transforms:
 *    ('inot', ('inot', 'a')) => a
 */


static const nir_search_value_union midgard_nir_cancel_inot_values[] = {
   /* ('inot', ('inot', 'a')) => a */
   { .variable = {
      { nir_search_value_variable, -1 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 0 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, -1 },
      false,
      false,
      false,
      nir_op_inot,
      -1, 0,
      { 1 },
      -1,
   } },

   /* replace57 -> 0 in the cache */

};



static const struct transform midgard_nir_cancel_inot_transforms[] = {
   { ~0, ~0, ~0 }, /* Sentinel */

   { 2, 0, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

};

static const struct per_op_table midgard_nir_cancel_inot_pass_op_table[nir_num_search_ops] = {
   [nir_op_inot] = {
      .filter = (const uint16_t []) {
         0,
         0,
         1,
         1,
      },
      
      .num_filtered_states = 2,
      .table = (const uint16_t []) {
      
         2,
         3,
      },
   },
};

/* Mapping from state index to offset in transforms (0 being no transforms) */
static const uint16_t midgard_nir_cancel_inot_transform_offsets[] = {
   0,
   0,
   0,
   1,
};

static const nir_algebraic_table midgard_nir_cancel_inot_table = {
   .transforms = midgard_nir_cancel_inot_transforms,
   .transform_offsets = midgard_nir_cancel_inot_transform_offsets,
   .pass_op_table = midgard_nir_cancel_inot_pass_op_table,
   .values = midgard_nir_cancel_inot_values,
   .expression_cond = NULL,
   .variable_cond = NULL,
};

bool
midgard_nir_cancel_inot(nir_shader *shader)
{
   bool progress = false;
   bool condition_flags[1];
   const nir_shader_compiler_options *options = shader->options;
   const shader_info *info = &shader->info;
   (void) options;
   (void) info;

   STATIC_ASSERT(3 == ARRAY_SIZE(midgard_nir_cancel_inot_values));
   condition_flags[0] = true;

   nir_foreach_function(function, shader) {
      if (function->impl) {
         progress |= nir_algebraic_impl(function->impl, condition_flags,
                                        &midgard_nir_cancel_inot_table);
      }
   }

   return progress;
}

