nir: fix gather_ssa_types
authorJonathan Marek <jonathan@marek.ca>
Fri, 31 May 2019 19:08:54 +0000 (15:08 -0400)
committerJonathan Marek <jonathan@marek.ca>
Fri, 31 May 2019 21:35:26 +0000 (21:35 +0000)
Consts and undefs can be used as different types (common with "0" constant)
so don't copy types from consts/undefs, only to them. It doesn't entirely
solve the problem that the type given to the const could be wrong , but
now the only realistic case is with "0" which is the same when casted to
float, so it doesn't matter for lower_int_to_float.

The other change is to get type information for load input/uniform and
store output, and use that to get correct results.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir_gather_ssa_types.c

index fa648fe33262421d487e1f69d6c9f17a9bfe9a22..a1a7df0ca45a9771b247839d800114bea41cadb8 100644 (file)
@@ -51,27 +51,33 @@ set_type(unsigned idx, nir_alu_type type, BITSET_WORD *float_types,
 }
 
 static void
-copy_types(unsigned a, unsigned b, BITSET_WORD *float_types,
-           BITSET_WORD *int_types, bool *progress)
+copy_type(unsigned src, unsigned dst, bool src_is_sink,
+          BITSET_WORD *types, bool *progress)
 {
-   /* If the bits do not agree then one of them is set but not both.  Flag
-    * progress and set both bits.
-    */
-   if (float_types && (BITSET_TEST(float_types, a) !=
-                       BITSET_TEST(float_types, b))) {
-      *progress = true;
-      BITSET_SET(float_types, a);
-      BITSET_SET(float_types, b);
-   }
+   if (!types)
+      return;
 
-   if (int_types && (BITSET_TEST(int_types, a) !=
-                     BITSET_TEST(int_types, b))) {
+   if (BITSET_TEST(types, dst)) {
+      if (BITSET_TEST(types, src))
+         return;
+      BITSET_SET(types, src);
+      *progress = true;
+   } else if (BITSET_TEST(types, src) && !src_is_sink) {
+      BITSET_SET(types, dst);
       *progress = true;
-      BITSET_SET(int_types, a);
-      BITSET_SET(int_types, b);
    }
 }
 
+static void
+copy_types(nir_src src, nir_dest *dest, BITSET_WORD *float_types,
+           BITSET_WORD *int_types, bool *progress)
+{
+   bool src_is_sink = nir_src_is_const(src) ||
+                      src.ssa->parent_instr->type == nir_instr_type_ssa_undef;
+   copy_type(src.ssa->index, dest->ssa.index, src_is_sink, float_types, progress);
+   copy_type(src.ssa->index, dest->ssa.index, src_is_sink, int_types, progress);
+}
+
 /** Gather up ALU types for SSA values
  *
  * This pass attempts to determine, for each SSA value, the type of data (int
@@ -107,9 +113,7 @@ nir_gather_ssa_types(nir_function_impl *impl,
                case nir_op_vec3:
                case nir_op_vec4:
                   for (unsigned i = 0; i < info->num_inputs; i++) {
-                     assert(alu->src[i].src.is_ssa);
-                     copy_types(alu->src[i].src.ssa->index,
-                                alu->dest.dest.ssa.index,
+                     copy_types(alu->src[i].src, &alu->dest.dest,
                                 float_types, int_types, &progress);
                   }
                   break;
@@ -118,11 +122,9 @@ nir_gather_ssa_types(nir_function_impl *impl,
                case nir_op_b32csel:
                   set_type(alu->src[0].src.ssa->index, nir_type_bool,
                            float_types, int_types, &progress);
-                  copy_types(alu->src[1].src.ssa->index,
-                             alu->dest.dest.ssa.index,
+                  copy_types(alu->src[1].src, &alu->dest.dest,
                              float_types, int_types, &progress);
-                  copy_types(alu->src[2].src.ssa->index,
-                             alu->dest.dest.ssa.index,
+                  copy_types(alu->src[2].src, &alu->dest.dest,
                              float_types, int_types, &progress);
                   break;
 
@@ -178,20 +180,35 @@ nir_gather_ssa_types(nir_function_impl *impl,
                   break;
                }
 
-               default: {
-                  /* For the most part, we leave other intrinsics alone.  Most
-                   * of them don't matter in OpenGL ES 2.0 drivers anyway.
-                   * However, we should at least check if this is some sort of
-                   * IO intrinsic and flag it's offset and index sources.
-                   */
-                  nir_src *offset_src = nir_get_io_offset_src(intrin);
-                  if (offset_src) {
-                     assert(offset_src->is_ssa);
-                     set_type(offset_src->ssa->index, nir_type_int,
-                              float_types, int_types, &progress);
-                  }
+               case nir_intrinsic_load_input:
+               case nir_intrinsic_load_uniform:
+                  assert(intrin->dest.is_ssa);
+                  set_type(intrin->dest.ssa.index,
+                           nir_intrinsic_type(intrin),
+                           float_types, int_types, &progress);
+                  break;
+
+               case nir_intrinsic_store_output:
+                  assert(intrin->src[0].is_ssa);
+                  set_type(intrin->src[0].ssa->index,
+                           nir_intrinsic_type(intrin),
+                           float_types, int_types, &progress);
+                  break;
+
+               default:
                   break;
                }
+
+               /* For the most part, we leave other intrinsics alone.  Most
+                * of them don't matter in OpenGL ES 2.0 drivers anyway.
+                * However, we should at least check if this is some sort of
+                * IO intrinsic and flag it's offset and index sources.
+                */
+               nir_src *offset_src = nir_get_io_offset_src(intrin);
+               if (offset_src) {
+                  assert(offset_src->is_ssa);
+                  set_type(offset_src->ssa->index, nir_type_int,
+                           float_types, int_types, &progress);
                }
                break;
             }
@@ -200,8 +217,7 @@ nir_gather_ssa_types(nir_function_impl *impl,
                nir_phi_instr *phi = nir_instr_as_phi(instr);
                assert(phi->dest.is_ssa);
                nir_foreach_phi_src(src, phi) {
-                  assert(src->src.is_ssa);
-                  copy_types(src->src.ssa->index, phi->dest.ssa.index,
+                  copy_types(src->src, &phi->dest,
                              float_types, int_types, &progress);
                }
                break;