nir/builder: Handle i2b conversions specially in nir_type_convert
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 2 Nov 2022 00:49:10 +0000 (17:49 -0700)
committerMarge Bot <emma+marge@anholt.net>
Wed, 14 Dec 2022 06:23:21 +0000 (06:23 +0000)
The shaders affected here are ones that were previously affected when
i2b was unconditionally lowered in opt_algebraic. There are a few places
where some transformations happen in a different order, so some
algebraic patterns are missed.

All Broadwell and newer Intel platforms had similar results. (Ice Lake shown)
total instructions in shared programs: 19914369 -> 19914566 (<.01%)
instructions in affected programs: 92375 -> 92572 (0.21%)
helped: 0 / HURT: 90

total cycles in shared programs: 853851470 -> 853867215 (<.01%)
cycles in affected programs: 12400663 -> 12416408 (0.13%)
helped: 28 / HURT: 69

Haswell and Ivy Bridge had similar results. (Haswell shown)
total instructions in shared programs: 16710721 -> 16710700 (<.01%)
instructions in affected programs: 108010 -> 107989 (-0.02%)
helped: 57 / HURT: 103

total cycles in shared programs: 884299412 -> 884306546 (<.01%)
cycles in affected programs: 12986423 -> 12993557 (0.05%)
helped: 87 / HURT: 102

total spills in shared programs: 14937 -> 14925 (-0.08%)
spills in affected programs: 12 -> 0
helped: 9 / HURT: 0

total fills in shared programs: 17569 -> 17557 (-0.07%)
fills in affected programs: 12 -> 0
helped: 9 / HURT: 0

Sandy Bridge
total instructions in shared programs: 13902341 -> 13902347 (<.01%)
instructions in affected programs: 7311 -> 7317 (0.08%)
helped: 3 / HURT: 8

total cycles in shared programs: 741795500 -> 741792266 (<.01%)
cycles in affected programs: 273308 -> 270074 (-1.18%)
helped: 9 / HURT: 2

No shader-db changes on any other Intel platform.

No fossil-db changes on any Intel platform.

Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15121>

src/compiler/nir/nir_builder.c

index 1d41638..78005b3 100644 (file)
@@ -442,14 +442,42 @@ nir_type_convert(nir_builder *b,
    assert(nir_alu_type_get_type_size(src_type) == 0 ||
           nir_alu_type_get_type_size(src_type) == src->bit_size);
 
-   src_type = (nir_alu_type) (src_type | src->bit_size);
+   const nir_alu_type dst_base =
+      (nir_alu_type) nir_alu_type_get_base_type(dest_type);
 
-   nir_op opcode =
-      nir_type_conversion_op(src_type, dest_type, rnd);
-   if (opcode == nir_op_mov)
-      return src;
+   const nir_alu_type src_base =
+      (nir_alu_type) nir_alu_type_get_base_type(src_type);
 
-   return nir_build_alu(b, opcode, src, NULL, NULL, NULL);
+   /* b2b and f2b use the regular type conversion path, but i2b is implemented
+    * as src != 0.
+    */
+   if (dst_base == nir_type_bool && (src_base == nir_type_int ||
+                                     src_base == nir_type_uint)) {
+      nir_op opcode;
+
+      const unsigned dst_bit_size = nir_alu_type_get_type_size(dest_type);
+
+      switch (dst_bit_size) {
+      case 1:  opcode = nir_op_ine;   break;
+      case 8:  opcode = nir_op_ine8;  break;
+      case 16: opcode = nir_op_ine16; break;
+      case 32: opcode = nir_op_ine32; break;
+      default: unreachable("Invalid Boolean size.");
+      }
+
+      return nir_build_alu(b, opcode, src,
+                           nir_imm_zero(b, src->num_components, src->bit_size),
+                           NULL, NULL);
+   } else {
+      src_type = (nir_alu_type) (src_type | src->bit_size);
+
+      nir_op opcode =
+         nir_type_conversion_op(src_type, dest_type, rnd);
+      if (opcode == nir_op_mov)
+         return src;
+
+      return nir_build_alu(b, opcode, src, NULL, NULL, NULL);
+   }
 }
 
 nir_ssa_def *