https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126328

            Bug ID: 126328
           Summary: x86 costing rejects forming of *sse3_haddv2df3_low
                    from vec_select of sse3_haddv2df
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

Created attachment 65099
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65099&action=edit
required patch

Trying 7 -> 8:
    7:
r106:V2DF=vec_concat(vec_select(r109:V2DF,parallel)+vec_select(r109:V2DF,parallel),vec_select(r109:V2DF,parallel)+vec_select(r109:V2DF,parallel))
      REG_DEAD r109:V2DF
    8: r105:DF=vec_select(r106:V2DF,parallel)
      REG_DEAD r106:V2DF
Successfully matched this instruction:
(set (reg:DF 105)
    (plus:DF (vec_select:DF (reg:V2DF 109 [ p ])
            (parallel [
                    (const_int 0 [0])
                ]))
        (vec_select:DF (reg:V2DF 109 [ p ])
            (parallel [
                    (const_int 1 [0x1])
                ]))))
rejecting combination of insns 7 and 8
original costs 4 + 4 = 8
replacement cost 17


this is with a missed simplify-rtx routine fixed (see attachment).  The
costing is because

    case VEC_CONCAT:
      /* ??? Assume all of these vector manipulation patterns are
         recognizable.  In which case they all pretty much have the
         same cost.
         ??? We should still recruse when computing cost.  */
     *total = cost->sse_op;
     return true;

but when the PLUS is outermost instead of two inside the CONCANT we have

      else if (X87_FLOAT_MODE_P (mode))
        *total = cost->fadd;
...
      return false;

which costs a more expensive add plus two vec_select.

This happens when BB vectorization vectorizes the two reductions in the
lanes of the vector CTOR for gcc.target/i386/pr54400.c:

#include <x86intrin.h>

__m128d i1 (__m128d p, __m128d q)
{
  __m128d r = { p[0] + p[1], q[0] + q[1] };
  return r;
}

and we then fail to recover the overall haddpd pattern.


I'm a bit lost as to how to fix this on the x86 costing side in a targeted
manner.  It seems we do not recog() combine replacement candidates before
costing.

Reply via email to