<p dir="ltr"><br>
On Sep 18, 2015 10:09 AM, "Alejandro Piñeiro" <<a href="mailto:apinheiro@igalia.com">apinheiro@igalia.com</a>> wrote:<br>
><br>
> SEL and MOV instructions, as long as they don't have source modifiers, are<br>
> just copying bits around.  So those kind of instruction could be propagated<br>
> even if there are type mismatches. This is needed because NIR generates<br>
> integer SEL and MOV instructions whenever it doesn't know what else to<br>
> generate.<br>
><br>
> This commit adds support for copy propagation using current instruction<br>
> as reference.<br>
><br>
> v2: include check for saturate, as Jason Ekstrand suggested<br>
> v3: check that the dst.type and the src type are the same, in order to<br>
>     solve (among others) the following deqp regression with v2:<br>
>     dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uint_vertex</p>
<p dir="ltr">Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>></p>
<p dir="ltr">The other will take more thinking.</p>
<p dir="ltr">> ---<br>
><br>
> All the patches I sent to this series were tested against a full piglit run.<br>
> But while I was waiting for the review, I decided to run a full dEQP run, and<br>
> I found that v2 regressed on the following tests:<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uint_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec2_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec3_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec4_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uint_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec2_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec3_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec4_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.highp_uint_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.highp_uvec2_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.highp_uvec3_vertex<br>
>   * dEQP-GLES3.functional.shaders.operator.unary_operator.minus.highp_uvec4_vertex<br>
>   * dEQP-GLES3.functional.shaders.matrix.mul.const.lowp_mat3x2_mat3_vertex<br>
><br>
> On those tests we found situation like this:<br>
>    7: mov vgrf6.0.x:D, -vgrf5.xxxx:D<br>
>    8: mov vgrf0.0.x:F, vgrf6.xxxx:UD<br>
><br>
> That with v2 was propagated as:<br>
>    7: mov vgrf6.0.x:D, -vgrf5.xxxx:D<br>
>    8: mov vgrf0.0.x:D, -vgrf5.xxxx:D<br>
><br>
> Causing the regression. It was fixed by checking too that the type of the<br>
> destination and the source are the same.<br>
><br>
>  .../drivers/dri/i965/brw_vec4_copy_propagation.cpp | 30 ++++++++++++++++++++--<br>
>  1 file changed, 28 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp<br>
> index 5a15eb8..1522eea 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp<br>
> @@ -249,6 +249,18 @@ try_constant_propagate(const struct brw_device_info *devinfo,<br>
>  }<br>
><br>
>  static bool<br>
> +can_change_source_types(vec4_instruction *inst)<br>
> +{<br>
> +   return inst->dst.type == inst->src[0].type &&<br>
> +      !inst->src[0].abs && !inst->src[0].negate && !inst->saturate &&<br>
> +      (inst->opcode == BRW_OPCODE_MOV ||<br>
> +       (inst->opcode == BRW_OPCODE_SEL &&<br>
> +        inst->dst.type == inst->src[1].type &&<br>
> +        inst->predicate != BRW_PREDICATE_NONE &&<br>
> +        !inst->src[1].abs && !inst->src[1].negate));<br>
> +}<br>
> +<br>
> +static bool<br>
>  try_copy_propagate(const struct brw_device_info *devinfo,<br>
>                     vec4_instruction *inst,<br>
>                     int arg, struct copy_entry *entry)<br>
> @@ -308,7 +320,9 @@ try_copy_propagate(const struct brw_device_info *devinfo,<br>
>          value.swizzle != BRW_SWIZZLE_XYZW) && !inst->can_do_source_mods(devinfo))<br>
>        return false;<br>
><br>
> -   if (has_source_modifiers && value.type != inst->src[arg].type)<br>
> +   if (has_source_modifiers &&<br>
> +       value.type != inst->src[arg].type &&<br>
> +       !can_change_source_types(inst))<br>
>        return false;<br>
><br>
>     if (has_source_modifiers &&<br>
> @@ -362,7 +376,19 @@ try_copy_propagate(const struct brw_device_info *devinfo,<br>
>        }<br>
>     }<br>
><br>
> -   value.type = inst->src[arg].type;<br>
> +   if (has_source_modifiers &&<br>
> +       value.type != inst->src[arg].type) {<br>
> +      /* We are propagating source modifiers from a MOV with a different<br>
> +       * type.  If we got here, then we can just change the source and<br>
> +       * destination types of the instruction and keep going.<br>
> +       */<br>
> +      assert(can_change_source_types(inst));<br>
> +      for (int i = 0; i < 3; i++) {<br>
> +         inst->src[i].type = value.type;<br>
> +      }<br>
> +      inst->dst.type = value.type;<br>
> +   } else<br>
> +      value.type = inst->src[arg].type;<br>
>     inst->src[arg] = value;<br>
>     return true;<br>
>  }<br>
> --<br>
> 2.1.4<br>
><br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>