nir: reset ssa-defs as non-divergent during divergence analysis instead of upfront
[mesa.git] / src / compiler / spirv / vtn_alu.c
index 3134849ba90c722ebeffe7693c7f4409d9920189..fc3fb3c4d68843fa77871df57e085cecb29ee091 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <math.h>
 #include "vtn_private.h"
+#include "spirv_info.h"
 
 /*
  * Normally, column vectors in SPIR-V correspond to a single NIR SSA
@@ -207,72 +208,10 @@ vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
       }
       break;
 
-   default: vtn_fail("unknown matrix opcode");
+   default: vtn_fail_with_opcode("unknown matrix opcode", opcode);
    }
 }
 
-static void
-vtn_handle_bitcast(struct vtn_builder *b, struct vtn_ssa_value *dest,
-                   struct nir_ssa_def *src)
-{
-   if (glsl_get_vector_elements(dest->type) == src->num_components) {
-      /* From the definition of OpBitcast in the SPIR-V 1.2 spec:
-       *
-       * "If Result Type has the same number of components as Operand, they
-       * must also have the same component width, and results are computed per
-       * component."
-       */
-      dest->def = nir_imov(&b->nb, src);
-      return;
-   }
-
-   /* From the definition of OpBitcast in the SPIR-V 1.2 spec:
-    *
-    * "If Result Type has a different number of components than Operand, the
-    * total number of bits in Result Type must equal the total number of bits
-    * in Operand. Let L be the type, either Result Type or Operand’s type, that
-    * has the larger number of components. Let S be the other type, with the
-    * smaller number of components. The number of components in L must be an
-    * integer multiple of the number of components in S. The first component
-    * (that is, the only or lowest-numbered component) of S maps to the first
-    * components of L, and so on, up to the last component of S mapping to the
-    * last components of L. Within this mapping, any single component of S
-    * (mapping to multiple components of L) maps its lower-ordered bits to the
-    * lower-numbered components of L."
-    */
-   unsigned src_bit_size = src->bit_size;
-   unsigned dest_bit_size = glsl_get_bit_size(dest->type);
-   unsigned src_components = src->num_components;
-   unsigned dest_components = glsl_get_vector_elements(dest->type);
-   vtn_assert(src_bit_size * src_components == dest_bit_size * dest_components);
-
-   nir_ssa_def *dest_chan[4];
-   if (src_bit_size > dest_bit_size) {
-      vtn_assert(src_bit_size % dest_bit_size == 0);
-      unsigned divisor = src_bit_size / dest_bit_size;
-      for (unsigned comp = 0; comp < src_components; comp++) {
-         vtn_assert(src_bit_size == 64);
-         vtn_assert(dest_bit_size == 32);
-         nir_ssa_def *split =
-            nir_unpack_64_2x32(&b->nb, nir_channel(&b->nb, src, comp));
-         for (unsigned i = 0; i < divisor; i++)
-            dest_chan[divisor * comp + i] = nir_channel(&b->nb, split, i);
-      }
-   } else {
-      vtn_assert(dest_bit_size % src_bit_size == 0);
-      unsigned divisor = dest_bit_size / src_bit_size;
-      for (unsigned comp = 0; comp < dest_components; comp++) {
-         unsigned channels = ((1 << divisor) - 1) << (comp * divisor);
-         nir_ssa_def *src_chan =
-            nir_channels(&b->nb, src, channels);
-         vtn_assert(dest_bit_size == 64);
-         vtn_assert(src_bit_size == 32);
-         dest_chan[comp] = nir_pack_64_2x32(&b->nb, src_chan);
-      }
-   }
-   dest->def = nir_vec(&b->nb, dest_chan, dest_components);
-}
-
 nir_op
 vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,
                                 SpvOp opcode, bool *swap,
@@ -322,6 +261,21 @@ vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,
    case SpvOpBitReverse:            return nir_op_bitfield_reverse;
    case SpvOpBitCount:              return nir_op_bit_count;
 
+   case SpvOpUCountLeadingZerosINTEL: return nir_op_uclz;
+   /* SpvOpUCountTrailingZerosINTEL is handled elsewhere. */
+   case SpvOpAbsISubINTEL:          return nir_op_uabs_isub;
+   case SpvOpAbsUSubINTEL:          return nir_op_uabs_usub;
+   case SpvOpIAddSatINTEL:          return nir_op_iadd_sat;
+   case SpvOpUAddSatINTEL:          return nir_op_uadd_sat;
+   case SpvOpIAverageINTEL:         return nir_op_ihadd;
+   case SpvOpUAverageINTEL:         return nir_op_uhadd;
+   case SpvOpIAverageRoundedINTEL:  return nir_op_irhadd;
+   case SpvOpUAverageRoundedINTEL:  return nir_op_urhadd;
+   case SpvOpISubSatINTEL:          return nir_op_isub_sat;
+   case SpvOpUSubSatINTEL:          return nir_op_usub_sat;
+   case SpvOpIMul32x16INTEL:        return nir_op_imul_32x16;
+   case SpvOpUMul32x16INTEL:        return nir_op_umul_32x16;
+
    /* The ordered / unordered operators need special implementation besides
     * the logical operator to use since they also need to check if operands are
     * ordered.
@@ -402,7 +356,7 @@ vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,
    case SpvOpDPdyCoarse:   return nir_op_fddy_coarse;
 
    default:
-      vtn_fail("No NIR equivalent");
+      vtn_fail("No NIR equivalent: %u", opcode);
    }
 }
 
@@ -425,7 +379,7 @@ handle_rounding_mode(struct vtn_builder *b, struct vtn_value *val, int member,
    assert(dec->scope == VTN_DEC_DECORATION);
    if (dec->decoration != SpvDecorationFPRoundingMode)
       return;
-   switch (dec->literals[0]) {
+   switch (dec->operands[0]) {
    case SpvFPRoundingModeRTE:
       *out_rounding_mode = nir_rounding_mode_rtne;
       break;
@@ -438,6 +392,24 @@ handle_rounding_mode(struct vtn_builder *b, struct vtn_value *val, int member,
    }
 }
 
+static void
+handle_no_wrap(struct vtn_builder *b, struct vtn_value *val, int member,
+               const struct vtn_decoration *dec, void *_alu)
+{
+   nir_alu_instr *alu = _alu;
+   switch (dec->decoration) {
+   case SpvDecorationNoSignedWrap:
+      alu->no_signed_wrap = true;
+      break;
+   case SpvDecorationNoUnsignedWrap:
+      alu->no_unsigned_wrap = true;
+      break;
+   default:
+      /* Do nothing. */
+      break;
+   }
+}
+
 void
 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
                const uint32_t *w, unsigned count)
@@ -457,7 +429,7 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
    if (glsl_type_is_matrix(vtn_src[0]->type) ||
        (num_inputs >= 2 && glsl_type_is_matrix(vtn_src[1]->type))) {
       vtn_handle_matrix_alu(b, opcode, val, vtn_src[0], vtn_src[1]);
-      b->nb.exact = false;
+      b->nb.exact = b->exact;
       return;
    }
 
@@ -471,7 +443,7 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
    switch (opcode) {
    case SpvOpAny:
       if (src[0]->num_components == 1) {
-         val->ssa->def = nir_imov(&b->nb, src[0]);
+         val->ssa->def = nir_mov(&b->nb, src[0]);
       } else {
          nir_op op;
          switch (src[0]->num_components) {
@@ -481,14 +453,14 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
          default: vtn_fail("invalid number of components");
          }
          val->ssa->def = nir_build_alu(&b->nb, op, src[0],
-                                       nir_imm_int(&b->nb, NIR_FALSE),
+                                       nir_imm_false(&b->nb),
                                        NULL, NULL);
       }
       break;
 
    case SpvOpAll:
       if (src[0]->num_components == 1) {
-         val->ssa->def = nir_imov(&b->nb, src[0]);
+         val->ssa->def = nir_mov(&b->nb, src[0]);
       } else {
          nir_op op;
          switch (src[0]->num_components) {
@@ -498,7 +470,7 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
          default: vtn_fail("invalid number of components");
          }
          val->ssa->def = nir_build_alu(&b->nb, op, src[0],
-                                       nir_imm_int(&b->nb, NIR_TRUE),
+                                       nir_imm_true(&b->nb),
                                        NULL, NULL);
       }
       break;
@@ -516,28 +488,32 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
       break;
 
    case SpvOpIAddCarry:
-      vtn_assert(glsl_type_is_struct(val->ssa->type));
+      vtn_assert(glsl_type_is_struct_or_ifc(val->ssa->type));
       val->ssa->elems[0]->def = nir_iadd(&b->nb, src[0], src[1]);
       val->ssa->elems[1]->def = nir_uadd_carry(&b->nb, src[0], src[1]);
       break;
 
    case SpvOpISubBorrow:
-      vtn_assert(glsl_type_is_struct(val->ssa->type));
+      vtn_assert(glsl_type_is_struct_or_ifc(val->ssa->type));
       val->ssa->elems[0]->def = nir_isub(&b->nb, src[0], src[1]);
       val->ssa->elems[1]->def = nir_usub_borrow(&b->nb, src[0], src[1]);
       break;
 
-   case SpvOpUMulExtended:
-      vtn_assert(glsl_type_is_struct(val->ssa->type));
-      val->ssa->elems[0]->def = nir_imul(&b->nb, src[0], src[1]);
-      val->ssa->elems[1]->def = nir_umul_high(&b->nb, src[0], src[1]);
+   case SpvOpUMulExtended: {
+      vtn_assert(glsl_type_is_struct_or_ifc(val->ssa->type));
+      nir_ssa_def *umul = nir_umul_2x32_64(&b->nb, src[0], src[1]);
+      val->ssa->elems[0]->def = nir_unpack_64_2x32_split_x(&b->nb, umul);
+      val->ssa->elems[1]->def = nir_unpack_64_2x32_split_y(&b->nb, umul);
       break;
+   }
 
-   case SpvOpSMulExtended:
-      vtn_assert(glsl_type_is_struct(val->ssa->type));
-      val->ssa->elems[0]->def = nir_imul(&b->nb, src[0], src[1]);
-      val->ssa->elems[1]->def = nir_imul_high(&b->nb, src[0], src[1]);
+   case SpvOpSMulExtended: {
+      vtn_assert(glsl_type_is_struct_or_ifc(val->ssa->type));
+      nir_ssa_def *smul = nir_imul_2x32_64(&b->nb, src[0], src[1]);
+      val->ssa->elems[0]->def = nir_unpack_64_2x32_split_x(&b->nb, smul);
+      val->ssa->elems[1]->def = nir_unpack_64_2x32_split_y(&b->nb, smul);
       break;
+   }
 
    case SpvOpFwidth:
       val->ssa->def = nir_fadd(&b->nb,
@@ -619,10 +595,6 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
       break;
    }
 
-   case SpvOpBitcast:
-      vtn_handle_bitcast(b, val->ssa, src[0]);
-      break;
-
    case SpvOpFConvert: {
       nir_alu_type src_alu_type = nir_get_nir_type_for_glsl_type(vtn_src[0]->type);
       nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(type);
@@ -635,6 +607,60 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
       break;
    }
 
+   case SpvOpBitFieldInsert:
+   case SpvOpBitFieldSExtract:
+   case SpvOpBitFieldUExtract:
+   case SpvOpShiftLeftLogical:
+   case SpvOpShiftRightArithmetic:
+   case SpvOpShiftRightLogical: {
+      bool swap;
+      unsigned src0_bit_size = glsl_get_bit_size(vtn_src[0]->type);
+      unsigned dst_bit_size = glsl_get_bit_size(type);
+      nir_op op = vtn_nir_alu_op_for_spirv_opcode(b, opcode, &swap,
+                                                  src0_bit_size, dst_bit_size);
+
+      assert (op == nir_op_ushr || op == nir_op_ishr || op == nir_op_ishl ||
+              op == nir_op_bitfield_insert || op == nir_op_ubitfield_extract ||
+              op == nir_op_ibitfield_extract);
+
+      for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++) {
+         unsigned src_bit_size =
+            nir_alu_type_get_type_size(nir_op_infos[op].input_types[i]);
+         if (src_bit_size == 0)
+            continue;
+         if (src_bit_size != src[i]->bit_size) {
+            assert(src_bit_size == 32);
+            /* Convert the Shift, Offset and Count  operands to 32 bits, which is the bitsize
+             * supported by the NIR instructions. See discussion here:
+             *
+             * https://lists.freedesktop.org/archives/mesa-dev/2018-April/193026.html
+             */
+            src[i] = nir_u2u32(&b->nb, src[i]);
+         }
+      }
+      val->ssa->def = nir_build_alu(&b->nb, op, src[0], src[1], src[2], src[3]);
+      break;
+   }
+
+   case SpvOpSignBitSet: {
+      unsigned src_bit_size = glsl_get_bit_size(vtn_src[0]->type);
+      if (src[0]->num_components == 1)
+         val->ssa->def =
+            nir_ushr(&b->nb, src[0], nir_imm_int(&b->nb, src_bit_size - 1));
+      else
+         val->ssa->def =
+            nir_ishr(&b->nb, src[0], nir_imm_int(&b->nb, src_bit_size - 1));
+
+      val->ssa->def = nir_i2b(&b->nb, val->ssa->def);
+      break;
+   }
+
+   case SpvOpUCountTrailingZerosINTEL:
+      val->ssa->def = nir_umin(&b->nb,
+                               nir_find_lsb(&b->nb, src[0]),
+                               nir_imm_int(&b->nb, 32u));
+      break;
+
    default: {
       bool swap;
       unsigned src_bit_size = glsl_get_bit_size(vtn_src[0]->type);
@@ -648,10 +674,74 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
          src[1] = tmp;
       }
 
+      switch (op) {
+      case nir_op_ishl:
+      case nir_op_ishr:
+      case nir_op_ushr:
+         if (src[1]->bit_size != 32)
+            src[1] = nir_u2u32(&b->nb, src[1]);
+         break;
+      default:
+         break;
+      }
+
       val->ssa->def = nir_build_alu(&b->nb, op, src[0], src[1], src[2], src[3]);
       break;
    } /* default */
    }
 
-   b->nb.exact = false;
+   switch (opcode) {
+   case SpvOpIAdd:
+   case SpvOpIMul:
+   case SpvOpISub:
+   case SpvOpShiftLeftLogical:
+   case SpvOpSNegate: {
+      nir_alu_instr *alu = nir_instr_as_alu(val->ssa->def->parent_instr);
+      vtn_foreach_decoration(b, val, handle_no_wrap, alu);
+      break;
+   }
+   default:
+      /* Do nothing. */
+      break;
+   }
+
+   b->nb.exact = b->exact;
+}
+
+void
+vtn_handle_bitcast(struct vtn_builder *b, const uint32_t *w, unsigned count)
+{
+   vtn_assert(count == 4);
+   /* From the definition of OpBitcast in the SPIR-V 1.2 spec:
+    *
+    *    "If Result Type has the same number of components as Operand, they
+    *    must also have the same component width, and results are computed per
+    *    component.
+    *
+    *    If Result Type has a different number of components than Operand, the
+    *    total number of bits in Result Type must equal the total number of
+    *    bits in Operand. Let L be the type, either Result Type or Operand’s
+    *    type, that has the larger number of components. Let S be the other
+    *    type, with the smaller number of components. The number of components
+    *    in L must be an integer multiple of the number of components in S.
+    *    The first component (that is, the only or lowest-numbered component)
+    *    of S maps to the first components of L, and so on, up to the last
+    *    component of S mapping to the last components of L. Within this
+    *    mapping, any single component of S (mapping to multiple components of
+    *    L) maps its lower-ordered bits to the lower-numbered components of L."
+    */
+
+   struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
+   struct vtn_ssa_value *vtn_src = vtn_ssa_value(b, w[3]);
+   struct nir_ssa_def *src = vtn_src->def;
+   struct vtn_ssa_value *val = vtn_create_ssa_value(b, type->type);
+
+   vtn_assert(glsl_type_is_vector_or_scalar(vtn_src->type));
+
+   vtn_fail_if(src->num_components * src->bit_size !=
+               glsl_get_vector_elements(type->type) * glsl_get_bit_size(type->type),
+               "Source and destination of OpBitcast must have the same "
+               "total number of bits");
+   val->def = nir_bitcast_vector(&b->nb, src, glsl_get_bit_size(type->type));
+   vtn_push_ssa(b, w[2], type, val);
 }