On Fri, Mar 12, 2021 at 03:34:09PM +0100, Uros Bizjak wrote:
> >  (define_insn "*avx2_pmaddwd"
> > -  [(set (match_operand:V8SI 0 "register_operand" "=x,v")
> > +  [(set (match_operand:V8SI 0 "register_operand" "=Yw")
> 
> I'm not sure contraction like this is correct. The prolbem is with vex
> vs. evex prefix, used in length calculation. When XMM16+ is used in
> the insn, and evex prefix is used, the unpatched version returns vex
> for alternative 0 due to (x,x,x) and evex for alternative 1, since one
> of registers satisfies only "v".
> 
> Patched version now always emits vex, which is wrong for XMM16+ registers.

That is true, but we have many thousands of those cases, where we just
use vex or maybe_vex or maybe_evex prefix with v or Yv or Yw or YW etc.
Adding extra alternatives for that would mean changing pretty much all of
sse.md.
I think it is much easier to imply length_evex when prefix is vex/maybe_vex when
any of the operands is EXT_REX_SSE_REG_P, subreg thereof,
MASK_REG_P, or subreg thereof.

The default definition of the "length" attribute has:
         (ior (eq_attr "prefix" "evex")
              (and (ior (eq_attr "prefix" "maybe_evex")
                        (eq_attr "prefix" "maybe_vex"))
                   (match_test "TARGET_AVX512F")))
           (plus (attr "length_evex")
                 (plus (attr "length_immediate")
                       (plus (attr "modrm")
                             (attr "length_address"))))
         (ior (eq_attr "prefix" "vex")
              (and (ior (eq_attr "prefix" "maybe_vex")
                        (eq_attr "prefix" "maybe_evex"))
                   (match_test "TARGET_AVX")))
           (plus (attr "length_vex")
                 (plus (attr "length_immediate")
                       (plus (attr "modrm")
                             (attr "length_address"))))]
That is just extremely rough guess, assuming all insns with
evex/maybe_evex/maybe_vex prefix will be EVEX encoded when TARGET_AVX512F
is clearly wrong, that is only true for instructions that don't have
a VEX counterpart (e.g. if they have mnemonics that is EVEX only), otherwise
it depends on whether either the operands will be 64-byte (we can perhaps
use for that the mode attribute at least by default) or whether any of the
operands is %[xy]mm16+ or %k*.
So (but I think this must be GCC 12 material) I'd say we should throw away
maybe_evex prefix altogether (replace with maybe_vex or vex),
use evex for the cases where it has EVEX only mnemonics and otherwise
call some function to look at the operands and mode attribute.

The maybe_vex decision on TARGET_AVX vs. !TARGET_AVX is on the other side
correct, we have all those %v etc. to make sure we emit VEX/EVEX encoded
instructions with -mavx rather than the old SSE* encodings.

I think some years ago I've used scripts and -dP etc. to verify the length
computations for vex, for evex it is known for years that it is inaccurate
unfortunately.

Maybe it is conservatively correct?  length_evex is hardcoded to 5,
while length_vex is 3 + 1 or 2 + 1.

In that case, perhaps I should for now change the vex on that particular
instruction to maybe_vex.  But I see still several hundreds of instructions
with vex prefix attribute and v etc. in constraints.
So, if we want a conservatively correct fix now, I'd say we should treat
even "vex" in the "length_evex" condition, so (untested):

2021-03-12  Jakub Jelinek  <ja...@redhat.com>

        * config/i386/i386.md (length): For TARGET_AVX512F treat
        also vex prefix conservatively as length_evex.

--- gcc/config/i386/i386.md.jj  2021-03-05 21:51:33.675350463 +0100
+++ gcc/config/i386/i386.md     2021-03-12 16:24:49.302919436 +0100
@@ -686,6 +686,7 @@
                       (attr "length_address")))
         (ior (eq_attr "prefix" "evex")
              (and (ior (eq_attr "prefix" "maybe_evex")
+                       (eq_attr "prefix" "vex")
                        (eq_attr "prefix" "maybe_vex"))
                   (match_test "TARGET_AVX512F")))
           (plus (attr "length_evex")

and if we eventually do something more accurate, perhaps vex could
stand for do the operand >= %xmm16 or %k? check (VEX can't ever encode
those), but perhaps don't do the mode attribute check?

        Jakub

Reply via email to