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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |segher at gcc dot gnu.org

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #2)
> (In reply to Hongtao Liu from comment #1)
> > We can have special handling for get_attr_type (insn) == sseadd1(only
> > *sse3_haddv2df3_low and *sse3_hsubv2df3_low) in ix86_insn_cost, directly
> > return insn cost instead of lowering to rtx_cost.
> 
> Ah yes, that way we can up the original cost (hopefully always recog'ed). 
> I'll give it a try.

Hmm, no, the original is *sse3_haddv2df3 and sse2_storelpd.  If we adjust
the original cost of the former to 17 we get

insn_cost 17 for     7:
r106:V2DF=vec_concat(vec_select(r101:V2DF,parallel)+vec_select(r101:V2DF,parallel),vec_select(r101:V2DF,parallel)+vec_select(r101:V2DF,parallel))
...
Trying 2 -> 7:
    2: r101:V2DF=r109:V2DF
      REG_DEAD r109:V2DF
    7:
r106:V2DF=vec_concat(vec_select(r101:V2DF,parallel)+vec_select(r101:V2DF,parallel),vec_select(r101:V2DF,parallel)+vec_select(r101:V2DF,parallel))
      REG_DEAD r101:V2DF
Successfully matched this instruction:
...
allowing combination of insns 2 and 7
original costs 4 + 17 = 21
replacement cost 4

so we are back to a cost of 4, because combine_validate_cost doesn't
re-recog before costing :/

That means, at least for combine, a costing strategy based on insn
attributes or pattern names doesn't work.

My hack:

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 56a90333cfc..4de46225f79 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -22700,6 +22700,13 @@ ix86_insn_cost (rtx_insn *insn, bool speed)
       == AVX_PARTIAL_XMM_UPDATE_TRUE)
     insn_cost += COSTS_N_INSNS (3);

+  if (INSN_CODE (insn) >= 0
+      && (get_attr_type (insn) == TYPE_SSEADD1
+         || strcmp (insn_data[INSN_CODE (insn)].name, "*sse3_haddv2df3") ==
0))
+    {
+      return 17;
+    }
+
   rtx pat = PATTERN (insn);
   /* A USE of a memory is more expensive than a use of a REG.
      For example *<absneg>mode2_1's use of a signbit mask.  */

so we'd have to do a full pattern match in ix86_insn_cost then.

An alternative would be to not short-cut costing sub-rtx for VEC_CONCAT
in case there's PLUS/MINUS inside?  That yields for original cost:

insn_cost 38 for     7:
r106:V2DF=vec_concat(vec_select(r101:V2DF,parallel)+vec_select(r101:V2DF,parallel),vec_select(r101:V2DF,parallel)+vec_select(r101:V2DF,parallel))

and

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])
                ]))))
allowing combination of insns 7 and 8
original costs 38 + 4 = 42
replacement cost 17

That works for the case at hand, but is still quite arbitrary cost,
but it avoids regressing gcc.target/i386/pr54400.c when we SLP vectorize
the horizontal reductions.

@@ -23538,8 +23547,10 @@ ix86_rtx_costs (rtx x, machine_mode mode, int
outer_code_i, int opno,
       /* ??? 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.  */
+        ??? We should still recurse when computing cost.  */
      *total = cost->sse_op;
+     if (GET_CODE (XEXP (x, 0)) == PLUS || GET_CODE (XEXP (x, 0)) == MINUS)
+       return false;
      return true;

     case VEC_SELECT:

Reply via email to