<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Oct 9, 2018 at 11:24 AM Ian Romanick <<a href="mailto:idr@freedesktop.org">idr@freedesktop.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 10/09/2018 09:00 AM, Jason Ekstrand wrote:<br>
> This fixes a bug uncovered by my NIR integer division by constant<br>
> optimization series.<br>
> <br>
> Fixes: 19f9cb72c8b "i965/fs: Add pass to propagate conditional..."<br>
> Fixes: 627f94b72e0 "i965/vec4: adding vec4_cmod_propagation..."<br>
> Cc: Matt Turner <<a href="mailto:mattst88@gmail.com" target="_blank">mattst88@gmail.com</a>><br>
> ---<br>
>  .../compiler/brw_fs_cmod_propagation.cpp      | 25 ++++++++++++++++---<br>
>  src/intel/compiler/brw_reg.h                  |  9 +++++++<br>
>  .../compiler/brw_vec4_cmod_propagation.cpp    | 24 ++++++++++++++++--<br>
>  3 files changed, 53 insertions(+), 5 deletions(-)<br>
> <br>
> diff --git a/src/intel/compiler/brw_fs_cmod_propagation.cpp b/src/intel/compiler/brw_fs_cmod_propagation.cpp<br>
> index 5fb522f810f..4fdd04a9983 100644<br>
> --- a/src/intel/compiler/brw_fs_cmod_propagation.cpp<br>
> +++ b/src/intel/compiler/brw_fs_cmod_propagation.cpp<br>
> @@ -25,6 +25,25 @@<br>
>  #include "brw_cfg.h"<br>
>  #include "brw_eu.h"<br>
>  <br>
> +static bool<br>
> +can_add_cmod_to_inst(const fs_inst *inst)<br>
> +{<br>
> +   if (!inst->can_do_cmod())<br>
> +      return false;<br>
> +<br>
> +   /* The accumulator result appears to get used for the conditional modifier<br>
> +    * generation.  When negating a UD value, there is a 33rd bit generated for<br>
> +    * the sign in the accumulator value, so now you can't check, for example,<br>
> +    * equality with a 32-bit value.  See piglit fs-op-neg-uvec4.<br>
> +    */<br>
> +   for (unsigned i = 0; i < inst->sources; i++) {<br>
> +      if (type_is_unsigned_int(inst->src[i].type) && inst->src[i].negate)<br>
> +         return false;<br>
> +   }<br>
> +<br>
> +   return true;<br>
> +}<br>
> +<br>
<br>
This probably should go after the @file header comment. :)<br></blockquote><div><br></div><div>Yeah, probably.  I'll fix that.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also... it looks like this patch replaces every caller of<br>
::can_do_cmod() with can_add_cmod_to_inst.  Maybe just change<br>
can_do_cmod?  If you do that, I'd support changing the name to<br>
can_add_cmod_to_inst.<br></blockquote><div><br></div><div>It does and that was my first attempt.  Unfortunately, we need access to the sources for this and we don't have access in backend_instruction so this has to be done per-back-end.  I thought about changing can_do_cmod to just take an opcode and not an instruction to remove the implication that it's somehow comprehensive.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
>  /** @file brw_fs_cmod_propagation.cpp<br>
>   *<br>
>   * Implements a pass that propagates the conditional modifier from a CMP x 0.0<br>
> @@ -91,7 +110,7 @@ cmod_propagate_cmp_to_add(const gen_device_info *devinfo, bblock_t *block,<br>
>              negate ? brw_swap_cmod(inst->conditional_mod)<br>
>              : inst->conditional_mod;<br>
>  <br>
> -         if (scan_inst->can_do_cmod() &&<br>
> +         if (can_add_cmod_to_inst(scan_inst) &&<br>
>               ((!read_flag && scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) ||<br>
>                scan_inst->conditional_mod == cond)) {<br>
>              scan_inst->conditional_mod = cond;<br>
> @@ -146,7 +165,7 @@ cmod_propagate_not(const gen_device_info *devinfo, bblock_t *block,<br>
>               scan_inst->exec_size != inst->exec_size)<br>
>              break;<br>
>  <br>
> -         if (scan_inst->can_do_cmod() &&<br>
> +         if (can_add_cmod_to_inst(scan_inst) &&<br>
>               ((!read_flag && scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) ||<br>
>                scan_inst->conditional_mod == cond)) {<br>
>              scan_inst->conditional_mod = cond;<br>
> @@ -316,7 +335,7 @@ opt_cmod_propagation_local(const gen_device_info *devinfo, bblock_t *block)<br>
>                 inst->src[0].negate ? brw_swap_cmod(inst->conditional_mod)<br>
>                                     : inst->conditional_mod;<br>
>  <br>
> -            if (scan_inst->can_do_cmod() &&<br>
> +            if (can_add_cmod_to_inst(scan_inst) &&<br>
>                  ((!read_flag && scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) ||<br>
>                   scan_inst->conditional_mod == cond)) {<br>
>                 scan_inst->conditional_mod = cond;<br>
> diff --git a/src/intel/compiler/brw_reg.h b/src/intel/compiler/brw_reg.h<br>
> index ac12ab3d2dd..46d66198a1d 100644<br>
> --- a/src/intel/compiler/brw_reg.h<br>
> +++ b/src/intel/compiler/brw_reg.h<br>
> @@ -376,6 +376,15 @@ brw_int_type(unsigned sz, bool is_signed)<br>
>     }<br>
>  }<br>
>  <br>
> +static inline bool<br>
> +type_is_unsigned_int(enum brw_reg_type tp)<br>
> +{<br>
> +   return tp == BRW_REGISTER_TYPE_UB ||<br>
> +          tp == BRW_REGISTER_TYPE_UW ||<br>
> +          tp == BRW_REGISTER_TYPE_UD ||<br>
> +          tp == BRW_REGISTER_TYPE_UQ;<br>
> +}<br>
> +<br>
>  /**<br>
>   * Construct a brw_reg.<br>
>   * \param file      one of the BRW_x_REGISTER_FILE values<br>
> diff --git a/src/intel/compiler/brw_vec4_cmod_propagation.cpp b/src/intel/compiler/brw_vec4_cmod_propagation.cpp<br>
> index a1d46dc8dca..392e283d1f8 100644<br>
> --- a/src/intel/compiler/brw_vec4_cmod_propagation.cpp<br>
> +++ b/src/intel/compiler/brw_vec4_cmod_propagation.cpp<br>
> @@ -46,6 +46,26 @@ writemasks_incompatible(const vec4_instruction *earlier,<br>
>            (later->dst.writemask & ~earlier->dst.writemask) != 0;<br>
>  }<br>
>  <br>
> +static bool<br>
> +can_add_cmod_to_inst(const vec4_instruction *inst)<br>
> +{<br>
> +   if (!inst->can_do_cmod())<br>
> +      return false;<br>
> +<br>
> +   /* The accumulator result appears to get used for the conditional modifier<br>
> +    * generation.  When negating a UD value, there is a 33rd bit generated for<br>
> +    * the sign in the accumulator value, so now you can't check, for example,<br>
> +    * equality with a 32-bit value.  See piglit fs-op-neg-uvec4.<br>
> +    */<br>
> +   for (unsigned i = 0; i < 3; i++) {<br>
> +      if (inst->src[i].file != BAD_FILE &&<br>
> +          type_is_unsigned_int(inst->src[i].type) && inst->src[i].negate)<br>
> +         return false;<br>
> +   }<br>
> +<br>
> +   return true;<br>
> +}<br>
> +<br>
>  static bool<br>
>  opt_cmod_propagation_local(bblock_t *block)<br>
>  {<br>
> @@ -132,7 +152,7 @@ opt_cmod_propagation_local(bblock_t *block)<br>
>                 negate ? brw_swap_cmod(inst->conditional_mod)<br>
>                        : inst->conditional_mod;<br>
>  <br>
> -            if (scan_inst->can_do_cmod() &&<br>
> +            if (can_add_cmod_to_inst(scan_inst) &&<br>
>                  ((!read_flag && scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) ||<br>
>                   scan_inst->conditional_mod == cond)) {<br>
>                 scan_inst->conditional_mod = cond;<br>
> @@ -229,7 +249,7 @@ opt_cmod_propagation_local(bblock_t *block)<br>
>                 inst->src[0].negate ? brw_swap_cmod(inst->conditional_mod)<br>
>                                     : inst->conditional_mod;<br>
>  <br>
> -            if (scan_inst->can_do_cmod() &&<br>
> +            if (can_add_cmod_to_inst(scan_inst) &&<br>
>                  ((!read_flag && scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) ||<br>
>                   scan_inst->conditional_mod == cond)) {<br>
>                 scan_inst->conditional_mod = cond;<br>
> <br>
<br>
</blockquote></div></div>