#include "nak_private.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 68
 * transforms:
 *    ('imin', 'a', 'b') => ('bcsel', ('ilt', 'a', 'b'), 'a', 'b')
 *    ('imax', 'a', 'b') => ('bcsel', ('ilt', 'a', 'b'), 'b', 'a')
 *    ('umin', 'a', 'b') => ('bcsel', ('ult', 'a', 'b'), 'a', 'b')
 *    ('umax', 'a', 'b') => ('bcsel', ('ult', 'a', 'b'), 'b', 'a')
 *    ('iadd', 'a@64', ('ineg', 'b@64')) => ('isub', 'a', 'b')
 *    ('iadd', ('iadd(is_used_once)', 'a(is_not_const)', '#b'), 'c(is_not_const)') => ('iadd3', 'a', 'b', 'c')
 *    ('iadd', ('iadd(is_used_once)', 'a(is_not_const)', 'b(is_not_const)'), '#c') => ('iadd3', 'a', 'b', 'c')
 *    ('iadd(is_used_by_non_ldc_nv)', 'a@32', ('ishl', 'b@32', '#s@32')) => ('lea_nv', 'a', 'b', 's')
 *    ('iadd', 'a@64', ('ishl', 'b@64', '#s@32')) => ('lea_nv', 'a', 'b', 's')
 *    ('vec2', ('f2f16(is_used_once)', 'a@32'), ('f2f16(is_used_once)', 'b@32')) => ('f2f16', ('vec2', 'a', 'b'))
 *    ('vec2', ('f2f16_rtz(is_used_once)', 'a@32'), ('f2f16_rtz(is_used_once)', 'b@32')) => ('f2f16_rtz', ('vec2', 'a', 'b'))
 *    ('vec2', ('f2f16_rtne(is_used_once)', 'a@32'), ('f2f16_rtne(is_used_once)', 'b@32')) => ('f2f16_rtne', ('vec2', 'a', 'b'))
 *    ('f2f16_rtz(ninf)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a')
 *    ('f2f16(ninf)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a')
 *    ('f2f16_rtz(ninf)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a')
 *    ('f2f16(ninf)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a')
 *    ('f2f16_rtz', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f16', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f16_rtz', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a')
 *    ('f2f16', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a')
 *    ('f2f16_rtz', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a')
 *    ('f2f16', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a')
 *    ('f2f16_rtz', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f16', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f16_rtz', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a')
 *    ('f2f16', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a')
 *    ('f2f16_rtz(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f32(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f16_rtne(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f32(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f16(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f32(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f16', 'a@32'))) => ('fcos_normalized_2_pi', 'a')
 *    ('f2f16_rtz(contract)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a')
 *    ('f2f32(contract)', ('fexp2(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fexp2', 'a')
 *    ('f2f16_rtne(contract)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a')
 *    ('f2f32(contract)', ('fexp2(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fexp2', 'a')
 *    ('f2f16(contract)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a')
 *    ('f2f32(contract)', ('fexp2(is_used_once)', ('f2f16', 'a@32'))) => ('fexp2', 'a')
 *    ('f2f16_rtz(contract)', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a')
 *    ('f2f32(contract)', ('flog2(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('flog2', 'a')
 *    ('f2f16_rtne(contract)', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a')
 *    ('f2f32(contract)', ('flog2(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('flog2', 'a')
 *    ('f2f16(contract)', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a')
 *    ('f2f32(contract)', ('flog2(is_used_once)', ('f2f16', 'a@32'))) => ('flog2', 'a')
 *    ('f2f16_rtz(contract)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a')
 *    ('f2f32(contract)', ('frcp(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('frcp', 'a')
 *    ('f2f16_rtne(contract)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a')
 *    ('f2f32(contract)', ('frcp(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('frcp', 'a')
 *    ('f2f16(contract)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a')
 *    ('f2f32(contract)', ('frcp(is_used_once)', ('f2f16', 'a@32'))) => ('frcp', 'a')
 *    ('f2f16_rtz(contract)', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a')
 *    ('f2f32(contract)', ('frsq(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('frsq', 'a')
 *    ('f2f16_rtne(contract)', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a')
 *    ('f2f32(contract)', ('frsq(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('frsq', 'a')
 *    ('f2f16(contract)', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a')
 *    ('f2f32(contract)', ('frsq(is_used_once)', ('f2f16', 'a@32'))) => ('frsq', 'a')
 *    ('f2f16_rtz(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f32(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f16_rtne(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f32(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f16(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f32(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f16', 'a@32'))) => ('fsin_normalized_2_pi', 'a')
 *    ('f2f16_rtz(contract)', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a')
 *    ('f2f32(contract)', ('fsqrt(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fsqrt', 'a')
 *    ('f2f16_rtne(contract)', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a')
 *    ('f2f32(contract)', ('fsqrt(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fsqrt', 'a')
 *    ('f2f16(contract)', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a')
 *    ('f2f32(contract)', ('fsqrt(is_used_once)', ('f2f16', 'a@32'))) => ('fsqrt', 'a')
 */


static const nir_search_value_union nak_nir_lower_algebraic_late_values[] = {
   /* ('imin', 'a', 'b') => ('bcsel', ('ilt', 'a', 'b'), 'a', 'b') */
   { .variable = {
      { nir_search_value_variable, -2 },
      0, /* a */
      false,
      -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,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_imin,
      0, 1,
      { 0, 1 },
      -1,
   } },

   /* replace0_0_0 -> 0 in the cache */
   /* replace0_0_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_ilt,
      -1, 0,
      { 0, 1 },
      -1,
   } },
   /* replace0_1 -> 0 in the cache */
   /* replace0_2 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_bcsel,
      -1, 0,
      { 3, 0, 1 },
      -1,
   } },

   /* ('imax', 'a', 'b') => ('bcsel', ('ilt', 'a', 'b'), 'b', 'a') */
   /* search1_0 -> 0 in the cache */
   /* search1_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_imax,
      0, 1,
      { 0, 1 },
      -1,
   } },

   /* replace1_0_0 -> 0 in the cache */
   /* replace1_0_1 -> 1 in the cache */
   /* replace1_0 -> 3 in the cache */
   /* replace1_1 -> 1 in the cache */
   /* replace1_2 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_bcsel,
      -1, 0,
      { 3, 1, 0 },
      -1,
   } },

   /* ('umin', 'a', 'b') => ('bcsel', ('ult', 'a', 'b'), 'a', 'b') */
   /* search2_0 -> 0 in the cache */
   /* search2_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_umin,
      0, 1,
      { 0, 1 },
      -1,
   } },

   /* replace2_0_0 -> 0 in the cache */
   /* replace2_0_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_ult,
      -1, 0,
      { 0, 1 },
      -1,
   } },
   /* replace2_1 -> 0 in the cache */
   /* replace2_2 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_bcsel,
      -1, 0,
      { 8, 0, 1 },
      -1,
   } },

   /* ('umax', 'a', 'b') => ('bcsel', ('ult', 'a', 'b'), 'b', 'a') */
   /* search3_0 -> 0 in the cache */
   /* search3_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_umax,
      0, 1,
      { 0, 1 },
      -1,
   } },

   /* replace3_0_0 -> 0 in the cache */
   /* replace3_0_1 -> 1 in the cache */
   /* replace3_0 -> 8 in the cache */
   /* replace3_1 -> 1 in the cache */
   /* replace3_2 -> 0 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_bcsel,
      -1, 0,
      { 8, 1, 0 },
      -1,
   } },

   /* ('iadd', 'a@64', ('ineg', 'b@64')) => ('isub', 'a', 'b') */
   { .variable = {
      { nir_search_value_variable, 64 },
      0, /* a */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, 64 },
      1, /* b */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 64 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_ineg,
      -1, 0,
      { 13 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 64 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      0, 1,
      { 12, 14 },
      -1,
   } },

   /* replace4_0 -> 12 in the cache */
   /* replace4_1 -> 13 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_isub,
      -1, 0,
      { 12, 13 },
      -1,
   } },

   /* ('iadd', ('iadd(is_used_once)', 'a(is_not_const)', '#b'), 'c(is_not_const)') => ('iadd3', 'a', 'b', 'c') */
   { .variable = {
      { nir_search_value_variable, -3 },
      0, /* a */
      false,
      0,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -3 },
      1, /* b */
      true,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -3 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      1, 1,
      { 17, 18 },
      0,
   } },
   { .variable = {
      { nir_search_value_variable, -3 },
      2, /* c */
      false,
      0,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -3 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      0, 2,
      { 19, 20 },
      -1,
   } },

   { .variable = {
      { nir_search_value_variable, -3 },
      0, /* a */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -3 },
      1, /* b */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -3 },
      2, /* c */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -3 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd3,
      0, 1,
      { 22, 23, 24 },
      -1,
   } },

   /* ('iadd', ('iadd(is_used_once)', 'a(is_not_const)', 'b(is_not_const)'), '#c') => ('iadd3', 'a', 'b', 'c') */
   /* search6_0_0 -> 17 in the cache */
   { .variable = {
      { nir_search_value_variable, -3 },
      1, /* b */
      false,
      0,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -3 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      1, 1,
      { 17, 26 },
      0,
   } },
   { .variable = {
      { nir_search_value_variable, -3 },
      2, /* c */
      true,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, -3 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      0, 2,
      { 27, 28 },
      -1,
   } },

   /* replace6_0 -> 22 in the cache */
   /* replace6_1 -> 23 in the cache */
   /* replace6_2 -> 24 in the cache */
   /* replace6 -> 25 in the cache */

   /* ('iadd(is_used_by_non_ldc_nv)', 'a@32', ('ishl', 'b@32', '#s@32')) => ('lea_nv', 'a', 'b', 's') */
   { .variable = {
      { nir_search_value_variable, 32 },
      0, /* a */
      false,
      -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,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, 32 },
      2, /* s */
      true,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_ishl,
      -1, 0,
      { 31, 32 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      0, 1,
      { 30, 33 },
      1,
   } },

   /* replace7_0 -> 30 in the cache */
   /* replace7_1 -> 31 in the cache */
   { .variable = {
      { nir_search_value_variable, 32 },
      2, /* s */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_lea_nv,
      -1, 0,
      { 30, 31, 35 },
      -1,
   } },

   /* ('iadd', 'a@64', ('ishl', 'b@64', '#s@32')) => ('lea_nv', 'a', 'b', 's') */
   /* search8_0 -> 12 in the cache */
   /* search8_1_0 -> 13 in the cache */
   /* search8_1_1 -> 32 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_ishl,
      -1, 0,
      { 13, 32 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 64 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_iadd,
      0, 1,
      { 12, 37 },
      -1,
   } },

   /* replace8_0 -> 12 in the cache */
   /* replace8_1 -> 13 in the cache */
   /* replace8_2 -> 35 in the cache */
   { .expression = {
      { nir_search_value_expression, 64 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_lea_nv,
      -1, 0,
      { 12, 13, 35 },
      -1,
   } },

   /* ('vec2', ('f2f16(is_used_once)', 'a@32'), ('f2f16(is_used_once)', 'b@32')) => ('f2f16', ('vec2', 'a', 'b')) */
   /* search9_0_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 30 },
      0,
   } },
   /* search9_1_0 -> 31 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 31 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_vec2,
      -1, 0,
      { 40, 41 },
      -1,
   } },

   /* replace9_0_0 -> 30 in the cache */
   /* replace9_0_1 -> 31 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_vec2,
      -1, 0,
      { 30, 31 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 43 },
      -1,
   } },

   /* ('vec2', ('f2f16_rtz(is_used_once)', 'a@32'), ('f2f16_rtz(is_used_once)', 'b@32')) => ('f2f16_rtz', ('vec2', 'a', 'b')) */
   /* search10_0_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 30 },
      0,
   } },
   /* search10_1_0 -> 31 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 31 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_vec2,
      -1, 0,
      { 45, 46 },
      -1,
   } },

   /* replace10_0_0 -> 30 in the cache */
   /* replace10_0_1 -> 31 in the cache */
   /* replace10_0 -> 43 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 43 },
      -1,
   } },

   /* ('vec2', ('f2f16_rtne(is_used_once)', 'a@32'), ('f2f16_rtne(is_used_once)', 'b@32')) => ('f2f16_rtne', ('vec2', 'a', 'b')) */
   /* search11_0_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 30 },
      0,
   } },
   /* search11_1_0 -> 31 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 31 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_vec2,
      -1, 0,
      { 49, 50 },
      -1,
   } },

   /* replace11_0_0 -> 30 in the cache */
   /* replace11_0_1 -> 31 in the cache */
   /* replace11_0 -> 43 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 43 },
      -1,
   } },

   /* ('f2f16_rtz(ninf)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a') */
   { .variable = {
      { nir_search_value_variable, 16 },
      0, /* a */
      false,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 53 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_preserve_inf,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 55 },
      -1,
   } },

   /* replace12_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16(ninf)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a') */
   /* search13_0_0_0 -> 53 in the cache */
   /* search13_0_0 -> 54 in the cache */
   /* search13_0 -> 55 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_preserve_inf,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 55 },
      -1,
   } },

   /* replace13_0 -> 53 in the cache */
   /* replace13 -> 57 in the cache */

   /* ('f2f16_rtz(ninf)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a') */
   /* search14_0_0_0 -> 53 in the cache */
   /* search14_0_0 -> 54 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_preserve_inf,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 59 },
      -1,
   } },

   /* replace14_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16(ninf)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a') */
   /* search15_0_0_0 -> 53 in the cache */
   /* search15_0_0 -> 54 in the cache */
   /* search15_0 -> 59 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_preserve_inf,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 59 },
      -1,
   } },

   /* replace15_0 -> 53 in the cache */
   /* replace15 -> 61 in the cache */

   /* ('f2f16_rtz', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a') */
   /* search16_0_0_0 -> 53 in the cache */
   /* search16_0_0 -> 54 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 63 },
      -1,
   } },

   /* replace16_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a') */
   /* search17_0_0_0 -> 53 in the cache */
   /* search17_0_0 -> 54 in the cache */
   /* search17_0 -> 63 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 63 },
      -1,
   } },

   /* replace17_0 -> 53 in the cache */
   /* replace17 -> 65 in the cache */

   /* ('f2f16_rtz', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a') */
   /* search18_0_0_0 -> 53 in the cache */
   /* search18_0_0 -> 54 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 67 },
      -1,
   } },

   /* replace18_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a') */
   /* search19_0_0_0 -> 53 in the cache */
   /* search19_0_0 -> 54 in the cache */
   /* search19_0 -> 67 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 67 },
      -1,
   } },

   /* replace19_0 -> 53 in the cache */
   /* replace19 -> 69 in the cache */

   /* ('f2f16_rtz', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a') */
   /* search20_0_0_0 -> 53 in the cache */
   /* search20_0_0 -> 54 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 71 },
      -1,
   } },

   /* replace20_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a') */
   /* search21_0_0_0 -> 53 in the cache */
   /* search21_0_0 -> 54 in the cache */
   /* search21_0 -> 71 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 71 },
      -1,
   } },

   /* replace21_0 -> 53 in the cache */
   /* replace21 -> 73 in the cache */

   /* ('f2f16_rtz', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a') */
   /* search22_0_0_0 -> 53 in the cache */
   /* search22_0_0 -> 54 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 75 },
      -1,
   } },

   /* replace22_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a') */
   /* search23_0_0_0 -> 53 in the cache */
   /* search23_0_0 -> 54 in the cache */
   /* search23_0 -> 75 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 75 },
      -1,
   } },

   /* replace23_0 -> 53 in the cache */
   /* replace23 -> 77 in the cache */

   /* ('f2f16_rtz', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a') */
   /* search24_0_0_0 -> 53 in the cache */
   /* search24_0_0 -> 54 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 54 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 79 },
      -1,
   } },

   /* replace24_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 53 },
      -1,
   } },

   /* ('f2f16', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a') */
   /* search25_0_0_0 -> 53 in the cache */
   /* search25_0_0 -> 54 in the cache */
   /* search25_0 -> 79 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 79 },
      -1,
   } },

   /* replace25_0 -> 53 in the cache */
   /* replace25 -> 81 in the cache */

   /* ('f2f16_rtz(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a') */
   /* search26_0_0_0 -> 53 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 53 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 84 },
      -1,
   } },

   /* replace26_0 -> 53 in the cache */
   /* replace26 -> 65 in the cache */

   /* ('f2f32(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fcos_normalized_2_pi', 'a') */
   /* search27_0_0_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 30 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 87 },
      -1,
   } },

   /* replace27_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a') */
   /* search28_0_0_0 -> 53 in the cache */
   /* search28_0_0 -> 83 in the cache */
   /* search28_0 -> 84 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 84 },
      -1,
   } },

   /* replace28_0 -> 53 in the cache */
   /* replace28 -> 65 in the cache */

   /* ('f2f32(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fcos_normalized_2_pi', 'a') */
   /* search29_0_0_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 30 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 92 },
      -1,
   } },

   /* replace29_0 -> 30 in the cache */
   /* replace29 -> 89 in the cache */

   /* ('f2f16(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fcos_normalized_2_pi', 'a') */
   /* search30_0_0_0 -> 53 in the cache */
   /* search30_0_0 -> 83 in the cache */
   /* search30_0 -> 84 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 84 },
      -1,
   } },

   /* replace30_0 -> 53 in the cache */
   /* replace30 -> 65 in the cache */

   /* ('f2f32(contract)', ('fcos_normalized_2_pi(is_used_once)', ('f2f16', 'a@32'))) => ('fcos_normalized_2_pi', 'a') */
   /* search31_0_0_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 30 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fcos_normalized_2_pi,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 96 },
      -1,
   } },

   /* replace31_0 -> 30 in the cache */
   /* replace31 -> 89 in the cache */

   /* ('f2f16_rtz(contract)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a') */
   /* search32_0_0_0 -> 53 in the cache */
   /* search32_0_0 -> 83 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 98 },
      -1,
   } },

   /* replace32_0 -> 53 in the cache */
   /* replace32 -> 57 in the cache */

   /* ('f2f32(contract)', ('fexp2(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fexp2', 'a') */
   /* search33_0_0_0 -> 30 in the cache */
   /* search33_0_0 -> 86 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 100 },
      -1,
   } },

   /* replace33_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a') */
   /* search34_0_0_0 -> 53 in the cache */
   /* search34_0_0 -> 83 in the cache */
   /* search34_0 -> 98 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 98 },
      -1,
   } },

   /* replace34_0 -> 53 in the cache */
   /* replace34 -> 57 in the cache */

   /* ('f2f32(contract)', ('fexp2(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fexp2', 'a') */
   /* search35_0_0_0 -> 30 in the cache */
   /* search35_0_0 -> 91 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 104 },
      -1,
   } },

   /* replace35_0 -> 30 in the cache */
   /* replace35 -> 102 in the cache */

   /* ('f2f16(contract)', ('fexp2(is_used_once)', ('f2f32', 'a@16'))) => ('fexp2', 'a') */
   /* search36_0_0_0 -> 53 in the cache */
   /* search36_0_0 -> 83 in the cache */
   /* search36_0 -> 98 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 98 },
      -1,
   } },

   /* replace36_0 -> 53 in the cache */
   /* replace36 -> 57 in the cache */

   /* ('f2f32(contract)', ('fexp2(is_used_once)', ('f2f16', 'a@32'))) => ('fexp2', 'a') */
   /* search37_0_0_0 -> 30 in the cache */
   /* search37_0_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fexp2,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 107 },
      -1,
   } },

   /* replace37_0 -> 30 in the cache */
   /* replace37 -> 102 in the cache */

   /* ('f2f16_rtz(contract)', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a') */
   /* search38_0_0_0 -> 53 in the cache */
   /* search38_0_0 -> 83 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 109 },
      -1,
   } },

   /* replace38_0 -> 53 in the cache */
   /* replace38 -> 69 in the cache */

   /* ('f2f32(contract)', ('flog2(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('flog2', 'a') */
   /* search39_0_0_0 -> 30 in the cache */
   /* search39_0_0 -> 86 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 111 },
      -1,
   } },

   /* replace39_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a') */
   /* search40_0_0_0 -> 53 in the cache */
   /* search40_0_0 -> 83 in the cache */
   /* search40_0 -> 109 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 109 },
      -1,
   } },

   /* replace40_0 -> 53 in the cache */
   /* replace40 -> 69 in the cache */

   /* ('f2f32(contract)', ('flog2(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('flog2', 'a') */
   /* search41_0_0_0 -> 30 in the cache */
   /* search41_0_0 -> 91 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 115 },
      -1,
   } },

   /* replace41_0 -> 30 in the cache */
   /* replace41 -> 113 in the cache */

   /* ('f2f16(contract)', ('flog2(is_used_once)', ('f2f32', 'a@16'))) => ('flog2', 'a') */
   /* search42_0_0_0 -> 53 in the cache */
   /* search42_0_0 -> 83 in the cache */
   /* search42_0 -> 109 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 109 },
      -1,
   } },

   /* replace42_0 -> 53 in the cache */
   /* replace42 -> 69 in the cache */

   /* ('f2f32(contract)', ('flog2(is_used_once)', ('f2f16', 'a@32'))) => ('flog2', 'a') */
   /* search43_0_0_0 -> 30 in the cache */
   /* search43_0_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_flog2,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 118 },
      -1,
   } },

   /* replace43_0 -> 30 in the cache */
   /* replace43 -> 113 in the cache */

   /* ('f2f16_rtz(contract)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a') */
   /* search44_0_0_0 -> 53 in the cache */
   /* search44_0_0 -> 83 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 120 },
      -1,
   } },

   /* replace44_0 -> 53 in the cache */
   /* replace44 -> 61 in the cache */

   /* ('f2f32(contract)', ('frcp(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('frcp', 'a') */
   /* search45_0_0_0 -> 30 in the cache */
   /* search45_0_0 -> 86 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 122 },
      -1,
   } },

   /* replace45_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a') */
   /* search46_0_0_0 -> 53 in the cache */
   /* search46_0_0 -> 83 in the cache */
   /* search46_0 -> 120 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 120 },
      -1,
   } },

   /* replace46_0 -> 53 in the cache */
   /* replace46 -> 61 in the cache */

   /* ('f2f32(contract)', ('frcp(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('frcp', 'a') */
   /* search47_0_0_0 -> 30 in the cache */
   /* search47_0_0 -> 91 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 126 },
      -1,
   } },

   /* replace47_0 -> 30 in the cache */
   /* replace47 -> 124 in the cache */

   /* ('f2f16(contract)', ('frcp(is_used_once)', ('f2f32', 'a@16'))) => ('frcp', 'a') */
   /* search48_0_0_0 -> 53 in the cache */
   /* search48_0_0 -> 83 in the cache */
   /* search48_0 -> 120 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 120 },
      -1,
   } },

   /* replace48_0 -> 53 in the cache */
   /* replace48 -> 61 in the cache */

   /* ('f2f32(contract)', ('frcp(is_used_once)', ('f2f16', 'a@32'))) => ('frcp', 'a') */
   /* search49_0_0_0 -> 30 in the cache */
   /* search49_0_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frcp,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 129 },
      -1,
   } },

   /* replace49_0 -> 30 in the cache */
   /* replace49 -> 124 in the cache */

   /* ('f2f16_rtz(contract)', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a') */
   /* search50_0_0_0 -> 53 in the cache */
   /* search50_0_0 -> 83 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 131 },
      -1,
   } },

   /* replace50_0 -> 53 in the cache */
   /* replace50 -> 73 in the cache */

   /* ('f2f32(contract)', ('frsq(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('frsq', 'a') */
   /* search51_0_0_0 -> 30 in the cache */
   /* search51_0_0 -> 86 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 133 },
      -1,
   } },

   /* replace51_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a') */
   /* search52_0_0_0 -> 53 in the cache */
   /* search52_0_0 -> 83 in the cache */
   /* search52_0 -> 131 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 131 },
      -1,
   } },

   /* replace52_0 -> 53 in the cache */
   /* replace52 -> 73 in the cache */

   /* ('f2f32(contract)', ('frsq(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('frsq', 'a') */
   /* search53_0_0_0 -> 30 in the cache */
   /* search53_0_0 -> 91 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 137 },
      -1,
   } },

   /* replace53_0 -> 30 in the cache */
   /* replace53 -> 135 in the cache */

   /* ('f2f16(contract)', ('frsq(is_used_once)', ('f2f32', 'a@16'))) => ('frsq', 'a') */
   /* search54_0_0_0 -> 53 in the cache */
   /* search54_0_0 -> 83 in the cache */
   /* search54_0 -> 131 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 131 },
      -1,
   } },

   /* replace54_0 -> 53 in the cache */
   /* replace54 -> 73 in the cache */

   /* ('f2f32(contract)', ('frsq(is_used_once)', ('f2f16', 'a@32'))) => ('frsq', 'a') */
   /* search55_0_0_0 -> 30 in the cache */
   /* search55_0_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_frsq,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 140 },
      -1,
   } },

   /* replace55_0 -> 30 in the cache */
   /* replace55 -> 135 in the cache */

   /* ('f2f16_rtz(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a') */
   /* search56_0_0_0 -> 53 in the cache */
   /* search56_0_0 -> 83 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 142 },
      -1,
   } },

   /* replace56_0 -> 53 in the cache */
   /* replace56 -> 77 in the cache */

   /* ('f2f32(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fsin_normalized_2_pi', 'a') */
   /* search57_0_0_0 -> 30 in the cache */
   /* search57_0_0 -> 86 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 144 },
      -1,
   } },

   /* replace57_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a') */
   /* search58_0_0_0 -> 53 in the cache */
   /* search58_0_0 -> 83 in the cache */
   /* search58_0 -> 142 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 142 },
      -1,
   } },

   /* replace58_0 -> 53 in the cache */
   /* replace58 -> 77 in the cache */

   /* ('f2f32(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fsin_normalized_2_pi', 'a') */
   /* search59_0_0_0 -> 30 in the cache */
   /* search59_0_0 -> 91 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 148 },
      -1,
   } },

   /* replace59_0 -> 30 in the cache */
   /* replace59 -> 146 in the cache */

   /* ('f2f16(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f32', 'a@16'))) => ('fsin_normalized_2_pi', 'a') */
   /* search60_0_0_0 -> 53 in the cache */
   /* search60_0_0 -> 83 in the cache */
   /* search60_0 -> 142 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 142 },
      -1,
   } },

   /* replace60_0 -> 53 in the cache */
   /* replace60 -> 77 in the cache */

   /* ('f2f32(contract)', ('fsin_normalized_2_pi(is_used_once)', ('f2f16', 'a@32'))) => ('fsin_normalized_2_pi', 'a') */
   /* search61_0_0_0 -> 30 in the cache */
   /* search61_0_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsin_normalized_2_pi,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 151 },
      -1,
   } },

   /* replace61_0 -> 30 in the cache */
   /* replace61 -> 146 in the cache */

   /* ('f2f16_rtz(contract)', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a') */
   /* search62_0_0_0 -> 53 in the cache */
   /* search62_0_0 -> 83 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 83 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtz,
      -1, 0,
      { 153 },
      -1,
   } },

   /* replace62_0 -> 53 in the cache */
   /* replace62 -> 81 in the cache */

   /* ('f2f32(contract)', ('fsqrt(is_used_once)', ('f2f16_rtz', 'a@32'))) => ('fsqrt', 'a') */
   /* search63_0_0_0 -> 30 in the cache */
   /* search63_0_0 -> 86 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 86 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 155 },
      -1,
   } },

   /* replace63_0 -> 30 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_fast_math,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 30 },
      -1,
   } },

   /* ('f2f16_rtne(contract)', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a') */
   /* search64_0_0_0 -> 53 in the cache */
   /* search64_0_0 -> 83 in the cache */
   /* search64_0 -> 153 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16_rtne,
      -1, 0,
      { 153 },
      -1,
   } },

   /* replace64_0 -> 53 in the cache */
   /* replace64 -> 81 in the cache */

   /* ('f2f32(contract)', ('fsqrt(is_used_once)', ('f2f16_rtne', 'a@32'))) => ('fsqrt', 'a') */
   /* search65_0_0_0 -> 30 in the cache */
   /* search65_0_0 -> 91 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 91 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 159 },
      -1,
   } },

   /* replace65_0 -> 30 in the cache */
   /* replace65 -> 157 in the cache */

   /* ('f2f16(contract)', ('fsqrt(is_used_once)', ('f2f32', 'a@16'))) => ('fsqrt', 'a') */
   /* search66_0_0_0 -> 53 in the cache */
   /* search66_0_0 -> 83 in the cache */
   /* search66_0 -> 153 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f16,
      -1, 0,
      { 153 },
      -1,
   } },

   /* replace66_0 -> 53 in the cache */
   /* replace66 -> 81 in the cache */

   /* ('f2f32(contract)', ('fsqrt(is_used_once)', ('f2f16', 'a@32'))) => ('fsqrt', 'a') */
   /* search67_0_0_0 -> 30 in the cache */
   /* search67_0_0 -> 95 in the cache */
   { .expression = {
      { nir_search_value_expression, 16 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_fsqrt,
      -1, 0,
      { 95 },
      0,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      nir_fp_no_contract,
      nir_fp_fast_math,
      false,
      -1,
      nir_op_f2f32,
      -1, 0,
      { 162 },
      -1,
   } },

   /* replace67_0 -> 30 in the cache */
   /* replace67 -> 157 in the cache */

};

UNUSED static const nir_search_expression_cond nak_nir_lower_algebraic_late_expression_cond[] = {
   is_used_once,
   is_used_by_non_ldc_nv,
};

static const nir_search_variable_cond nak_nir_lower_algebraic_late_variable_cond[] = {
   (is_not_const),
};

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

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

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

   { 7, 9, 1 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 10, 11, 1 },
   { ~0, ~0, ~0 }, /* Sentinel */

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

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

   { 34, 36, 3 },
   { 38, 39, 3 },
   { ~0, ~0, ~0 }, /* Sentinel */

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

   { 21, 25, 2 },
   { 29, 25, 2 },
   { ~0, ~0, ~0 }, /* Sentinel */

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

   { 34, 36, 3 },
   { 38, 39, 3 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 15, 16, 0 },
   { 21, 25, 2 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 21, 25, 2 },
   { 34, 36, 3 },
   { 38, 39, 3 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 15, 16, 0 },
   { 34, 36, 3 },
   { 38, 39, 3 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 42, 44, 4 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 47, 48, 4 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 51, 52, 4 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 58, 57, 6 },
   { 106, 57, 5 },
   { 108, 102, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 101, 102, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 105, 102, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 62, 61, 6 },
   { 128, 61, 5 },
   { 130, 124, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 123, 124, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 127, 124, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 66, 65, 6 },
   { 94, 65, 5 },
   { 97, 89, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 88, 89, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 93, 89, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 70, 69, 6 },
   { 117, 69, 5 },
   { 119, 113, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 112, 113, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 116, 113, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 74, 73, 6 },
   { 139, 73, 5 },
   { 141, 135, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 134, 135, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 138, 135, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 78, 77, 6 },
   { 150, 77, 5 },
   { 152, 146, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 145, 146, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

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

   { 82, 81, 6 },
   { 161, 81, 5 },
   { 163, 157, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

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

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

   { 56, 57, 5 },
   { 99, 57, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 60, 61, 5 },
   { 121, 61, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 64, 65, 5 },
   { 85, 65, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 68, 69, 5 },
   { 110, 69, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 72, 73, 5 },
   { 132, 73, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 76, 77, 5 },
   { 143, 77, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 80, 81, 5 },
   { 154, 81, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 103, 57, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 125, 61, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 90, 65, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 114, 69, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 136, 73, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 147, 77, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 158, 81, 5 },
   { ~0, ~0, ~0 }, /* Sentinel */

};

static const struct per_op_table nak_nir_lower_algebraic_late_pass_op_table[nir_num_search_ops] = {
   [nir_op_imin] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         2,
      },
   },
   [nir_op_imax] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         3,
      },
   },
   [nir_op_umin] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         4,
      },
   },
   [nir_op_umax] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         5,
      },
   },
   [nir_op_iadd] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         2,
         3,
         4,
         5,
         0,
         0,
         0,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         2,
         2,
         2,
         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,
         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,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 6,
      .table = (const uint16_t []) {
      
         6,
         7,
         6,
         13,
         14,
         15,
         7,
         7,
         16,
         17,
         18,
         19,
         6,
         16,
         6,
         13,
         14,
         15,
         13,
         17,
         13,
         13,
         20,
         21,
         14,
         18,
         14,
         20,
         14,
         22,
         15,
         19,
         15,
         21,
         22,
         15,
      },
   },
   [nir_op_ineg] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         8,
      },
   },
   [nir_op_ishl] = {
      .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,
         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,
         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,
         9,
         0,
         9,
      },
   },
   [nir_op_vec2] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         0,
         0,
         0,
         0,
         23,
         0,
         0,
         0,
         0,
         24,
         0,
         0,
         0,
         0,
         25,
      },
   },
   [nir_search_op_f2f] = {
      .filter = (const uint16_t []) {
         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,
         1,
         2,
         3,
         4,
         5,
         6,
         7,
         8,
         9,
         10,
         11,
         12,
         13,
         14,
         15,
         16,
         17,
         18,
         19,
         20,
         21,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 22,
      .table = (const uint16_t []) {
      
         10,
         47,
         48,
         49,
         50,
         51,
         52,
         53,
         54,
         55,
         56,
         57,
         58,
         59,
         60,
         61,
         62,
         63,
         64,
         65,
         66,
         67,
      },
   },
   [nir_op_f2f16_rtz] = {
      .filter = (const uint16_t []) {
         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,
         1,
         0,
         0,
         2,
         0,
         0,
         3,
         0,
         0,
         4,
         0,
         0,
         5,
         0,
         0,
         6,
         0,
         0,
         7,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 8,
      .table = (const uint16_t []) {
      
         11,
         68,
         69,
         70,
         71,
         72,
         73,
         74,
      },
   },
   [nir_op_f2f16_rtne] = {
      .filter = (const uint16_t []) {
         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,
         1,
         0,
         0,
         2,
         0,
         0,
         3,
         0,
         0,
         4,
         0,
         0,
         5,
         0,
         0,
         6,
         0,
         0,
         7,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 8,
      .table = (const uint16_t []) {
      
         12,
         75,
         76,
         77,
         78,
         79,
         80,
         81,
      },
   },
   [nir_op_fexp2] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         26,
         27,
         28,
      },
   },
   [nir_op_frcp] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         29,
         30,
         31,
      },
   },
   [nir_op_fcos_normalized_2_pi] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         32,
         33,
         34,
      },
   },
   [nir_op_flog2] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         35,
         36,
         37,
      },
   },
   [nir_op_frsq] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         38,
         39,
         40,
      },
   },
   [nir_op_fsin_normalized_2_pi] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         41,
         42,
         43,
      },
   },
   [nir_op_fsqrt] = {
      .filter = (const uint16_t []) {
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         2,
         3,
         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,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         1,
         2,
         2,
         2,
         2,
         2,
         2,
         2,
         3,
         3,
         3,
         3,
         3,
         3,
         3,
      },
      
      .num_filtered_states = 4,
      .table = (const uint16_t []) {
      
         0,
         44,
         45,
         46,
      },
   },
};

/* Mapping from state index to offset in transforms (0 being no transforms) */
static const uint16_t nak_nir_lower_algebraic_late_transform_offsets[] = {
   0,
   0,
   1,
   3,
   5,
   7,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   9,
   11,
   13,
   16,
   18,
   21,
   23,
   26,
   29,
   33,
   37,
   39,
   41,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   43,
   47,
   49,
   51,
   55,
   57,
   59,
   63,
   65,
   67,
   71,
   73,
   75,
   79,
   81,
   83,
   87,
   89,
   91,
   95,
   97,
   99,
   102,
   105,
   108,
   111,
   114,
   117,
   120,
   122,
   124,
   126,
   128,
   130,
   132,
};

static const nir_algebraic_table nak_nir_lower_algebraic_late_table = {
   .transforms = nak_nir_lower_algebraic_late_transforms,
   .transform_offsets = nak_nir_lower_algebraic_late_transform_offsets,
   .pass_op_table = nak_nir_lower_algebraic_late_pass_op_table,
   .values = nak_nir_lower_algebraic_late_values,
   .expression_cond = nak_nir_lower_algebraic_late_expression_cond,
   .variable_cond = nak_nir_lower_algebraic_late_variable_cond,
};

bool
nak_nir_lower_algebraic_late(
   nir_shader *shader
   , const struct nak_compiler * nak
) {
   bool progress = false;
   bool condition_flags[7];
   const nir_shader_compiler_options *options = shader->options;
   const shader_info *info = &shader->info;
   (void) options;
   (void) info;

   STATIC_ASSERT(164 == ARRAY_SIZE(nak_nir_lower_algebraic_late_values));
   condition_flags[0] = true;
   condition_flags[1] = nak->sm >= 70 && nak->sm < 73;
   condition_flags[2] = options->has_iadd3;
   condition_flags[3] = nak->sm >= 70;
   condition_flags[4] = nak->sm >= 86;
   condition_flags[5] = nak->sm >= 73;
   condition_flags[6] = nak->sm >= 73 && nir_is_rounding_mode_rtz(info->float_controls_execution_mode, 16);

   nir_foreach_function_impl(impl, shader) {
     progress |= nir_algebraic_impl(impl, condition_flags, &nak_nir_lower_algebraic_late_table);
   }

   return progress;
}
