<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, May 23, 2018 at 3:40 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"><div class="HOEnZb"><div class="h5">Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> writes:<br>
<br>
> On Wed, May 23, 2018 at 12:13 PM, Francisco Jerez <<a href="mailto:currojerez@riseup.net">currojerez@riseup.net</a>><br>
> wrote:<br>
><br>
>> Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> writes:<br>
>><br>
>> > Prior to gen8, the flag reg and subreg numbers are in different<br>
>> > locations on 3src instructions than on smaller instructions.  In order<br>
>> > for brw_set_default_flag_reg to work properly, we need to copy the value<br>
>> > out of the 2src location and write it into the 3src location as part of<br>
>> > brw_alu3.<br>
>> ><br>
>> > Cc: <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.<wbr>org</a><br>
>> > ---<br>
>> >  src/intel/compiler/brw_eu_<wbr>emit.c | 12 ++++++++++++<br>
>> >  1 file changed, 12 insertions(+)<br>
>> ><br>
>> > diff --git a/src/intel/compiler/brw_eu_<wbr>emit.c<br>
>> b/src/intel/compiler/brw_eu_<wbr>emit.c<br>
>> > index 4f51d51..fc39d94 100644<br>
>> > --- a/src/intel/compiler/brw_eu_<wbr>emit.c<br>
>> > +++ b/src/intel/compiler/brw_eu_<wbr>emit.c<br>
>> > @@ -824,6 +824,18 @@ brw_alu3(struct brw_codegen *p, unsigned opcode,<br>
>> struct brw_reg dest,<br>
>> >               dest.type == BRW_REGISTER_TYPE_DF ||<br>
>> >               dest.type == BRW_REGISTER_TYPE_D  ||<br>
>> >               dest.type == BRW_REGISTER_TYPE_UD);<br>
>> > +<br>
>> > +      /* Flag registers are in a different spot on 3src instructions so<br>
>> we<br>
>> > +       * need to move the value if we want brw_set_default_flag_reg to<br>
>> work<br>
>> > +       * properly.<br>
>> > +       */<br>
>> > +      unsigned flag_reg_nr =<br>
>> > +         devinfo->gen >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0;<br>
>> > +      unsigned flag_subreg_nr = brw_inst_flag_subreg_nr(<wbr>devinfo, inst);<br>
>> > +      if (devinfo->gen >= 7)<br>
>> > +         brw_inst_set_3src_a16_flag_<wbr>reg_nr(devinfo, inst, flag_reg_nr);<br>
>> > +      brw_inst_set_3src_a16_flag_<wbr>subreg_nr(devinfo, inst,<br>
>> flag_subreg_nr);<br>
>> > +<br>
>><br>
>> This seems really gross...<br>
><br>
><br>
> Yes, yes it is.  The grossness is not lost on me.<br>
><br>
><br>
>> brw_next_insn() with a 3-source opcode gives<br>
>> you a corrupted 3-source instruction initialized as if it were a<br>
>> 2-source one.  This fixes the 3-source flag register field hoping that<br>
>> all other fields of p->current will magically match the 3-source<br>
>> instruction layout, and hoping that the stray bits of the 2-source flag<br>
>> register field will be overwritten by something else in this function.<br>
>><br>
><br>
> Yes, it does.  However, I did go through and check and I believe that the<br>
> flag [sub]reg number field is the only field that actually moves.  Of<br>
> course, this is not something we can guarantee going forward, but I think<br>
> we're ok today.<br>
><br>
><br>
>> Proper fix would be to get rid of the p->current thing altogether IMO<br>
>> and use a mechanism to track instruction defaults based on their<br>
>> semantics rather than on the binary encoding of an instruction which has<br>
>> unknown encoding...<br>
><br>
><br>
> Agreed.  It really bothered me when I found this bug and I think we would<br>
> benefit significantly from having a semantic stack rather than this<br>
> "default instruction" concept.<br>
><br>
><br>
>> That would be rather invasive though, a compromise<br>
>> might be to fix it in brw_next_insn() by starting with a clean<br>
>> instruction and initializing it from scratch with the 3src helpers...<br>
>><br>
><br>
> Yes, fixing it in brw_next_insn() might be a better place.  Given that all<br>
> the other fields match up, I'm a bit inclined to just move this fix to<br>
> brw_next_insn() for now and plan to follow up with a logical instruction<br>
> control stack.  Would that be ok?<br>
><br>
<br>
</div></div>Yeah, I suppose, but this patch still only fixes half of the problem,<br>
there are still bogus bits set on the 3-source instruction by the memcpy<br>
from p->current, which we rely on other code overwriting for<br>
correctness, which seems extremely fragile (assuming it's working at all<br>
for all codepaths below).  It would be better (and probably<br>
straightforward enough for it to make it to stable releases) to<br>
initialize the new instruction to zero in brw_next_insn() and initialize<br>
the instruction fields manually by using the 3src helpers in case we get<br>
a 3-source opcode.<br><div class="HOEnZb"><div class="h5"></div></div></blockquote><div><br></div><div>Yeah.  I hadn't thought about other bits carying over. :(  I'll see what we I can do about just getting rid of the memcpy for 3src instructions.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
><br>
>> >        if (devinfo->gen == 6) {<br>
>> >           brw_inst_set_3src_a16_dst_reg_<wbr>file(devinfo, inst,<br>
>> >                                              dest.file ==<br>
>> BRW_MESSAGE_REGISTER_FILE);<br>
>> > --<br>
>> > 2.5.0.400.gff86faf<br>
>> ><br>
>> > ______________________________<wbr>_________________<br>
>> > mesa-stable mailing list<br>
>> > <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.<wbr>org</a><br>
>> > <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-stable" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-stable</a><br>
>><br>
</div></div></blockquote></div><br></div></div>