<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 26, 2016 at 8:46 PM, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The conditional mod of these instructions determines the semantics of<br>
the comparison itself (rather than being evaluated based on the result<br>
of the instruction as is usually the case for most other instructions<br>
that allow conditional mods), so it's in general not legal to<br>
propagate a conditional mod into a CMP instruction.  This prevents<br>
cmod propagation from (mis)optimizing:<br>
<br>
 cmp.z.f0 tmp, ...<br>
 mov.z.f0 null, tmp<br>
<br>
into:<br>
<br>
 cmp.z.f0 tmp, ...<br>
<br>
which gives the negation of the flag result of the original sequence.<br>
I could reproduce this easily with SIMD32 but I don't see any reason<br>
why the problem would be SIMD32-specific, it was most likely working<br>
by luck.<br>
<br>
Cc: <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.org</a><br>
---<br>
 src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp | 12 ++++++++++++<br>
 1 file changed, 12 insertions(+)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp<br>
index 98d4ff6..af1e3eb 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp<br>
@@ -129,6 +129,18 @@ opt_cmod_propagation_local(const brw_device_info *devinfo, bblock_t *block)<br>
                break;<br>
             }<br>
<br>
+            /* The conditional mod of the CMP/CMPN instructions behaves<br>
+             * specially because the flag output is not calculated from the<br>
+             * result of the instruction, but the other way around, which<br>
+             * means that even if the condmod to propagate and the condmod<br>
+             * from the CMP instruction are the same they will in general give<br>
+             * different results because they are evaluated based on different<br>
+             * inputs.<br>
+             */<br>
+            if (scan_inst->opcode == BRW_OPCODE_CMP ||<br>
+                scan_inst->opcode == BRW_OPCODE_CMPN)<br>
+               break;<br></blockquote><div><br></div><div>This should also be a problem with the vec4 version.  Mind fixing that too?  You can do it as part of this patch or as a follow-on.  I don't care.<br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
             /* Otherwise, try propagating the conditional. */<br>
             enum brw_conditional_mod cond =<br>
                inst->src[0].negate ? brw_swap_cmod(inst->conditional_mod)<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.7.3<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="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>