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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2026-06-29
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed.  We're correctly figuring the reduction

        hu += test0 + test1;

as root but pick the "wrong" two elements.  BB reduction handling needs
improvements here.  If you fix that we'll get

t.c:56:12: note:   Final SLP tree for instance 0x15a933f0:
t.c:56:12: note:   node 0x159a8620 (max_nunits=2, refcnt=2) vector(2) int
t.c:56:12: note:   op template: patt_185 = (int) patt_200;
t.c:56:12: note:        stmt 0 patt_185 = (int) patt_200;
t.c:56:12: note:        stmt 1 patt_180 = (int) patt_181;
t.c:56:12: note:        children 0x159a86d0
t.c:56:12: note:   node 0x159a86d0 (max_nunits=2, refcnt=2) vector(2) unsigned
long
t.c:56:12: note:   op template: patt_200 = test0_81 ? 1 : 0;
t.c:56:12: note:        stmt 0 patt_200 = test0_81 ? 1 : 0;
t.c:56:12: note:        stmt 1 patt_181 = test1_82 ? 1 : 0;
t.c:56:12: note:        children 0x159a8780 0x159a98b0 0x159a9960
t.c:56:12: note:   node 0x159a8780 (max_nunits=2, refcnt=2) vector(2)
<signed-boolean:1>
t.c:56:12: note:   op template: test0_81 = r2_0_70 < groupplcutoff2_80(D);
t.c:56:12: note:        stmt 0 test0_81 = r2_0_70 < groupplcutoff2_80(D);
t.c:56:12: note:        stmt 1 test1_82 = r2_1_71 < groupplcutoff2_80(D);
t.c:56:12: note:        children 0x159a8830 0x159a96a0
t.c:56:12: note:   node 0x159a8830 (max_nunits=2, refcnt=2) vector(2) double
t.c:56:12: note:   op template: r2_0_70 = _9 + r2_0_65;
t.c:56:12: note:        stmt 0 r2_0_70 = _9 + r2_0_65;
t.c:56:12: note:        stmt 1 r2_1_71 = _10 + r2_1_66;
t.c:56:12: note:        children 0x159a88e0 0x159a8c50
t.c:56:12: note:   node 0x159a88e0 (max_nunits=2, refcnt=2) vector(2) double
t.c:56:12: note:   op template: _9 = t_0_68 * t_0_68;
t.c:56:12: note:        stmt 0 _9 = t_0_68 * t_0_68;
t.c:56:12: note:        stmt 1 _10 = t_1_69 * t_1_69;
t.c:56:12: note:        children 0x159a8990 0x159a8990
t.c:56:12: note:   node 0x159a8990 (max_nunits=2, refcnt=3) vector(2) double
t.c:56:12: note:   op template: t_0_68 = p_i_z_67(D) - pj_z_0_108;
t.c:56:12: note:        stmt 0 t_0_68 = p_i_z_67(D) - pj_z_0_108;
t.c:56:12: note:        stmt 1 t_1_69 = p_i_z_67(D) - pj_z_1_109;
t.c:56:12: note:        children 0x159a8a40 0x159a8db0
t.c:56:12: note:   node (external) 0x159a8a40 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { p_i_z_67(D), p_i_z_67(D) }
t.c:56:12: note:   node (external) 0x159a8db0 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { pj_z_0_108, pj_z_1_109 }
t.c:56:12: note:   node 0x159a8c50 (max_nunits=2, refcnt=2) vector(2) double
t.c:56:12: note:   op template: r2_0_65 = _7 + r2_0_60;
t.c:56:12: note:        stmt 0 r2_0_65 = _7 + r2_0_60;
t.c:56:12: note:        stmt 1 r2_1_66 = _8 + r2_1_61;
t.c:56:12: note:        children 0x159a8e60 0x159a91d0
t.c:56:12: note:   node 0x159a8e60 (max_nunits=2, refcnt=2) vector(2) double
t.c:56:12: note:   op template: _7 = t_0_63 * t_0_63;
t.c:56:12: note:        stmt 0 _7 = t_0_63 * t_0_63;
t.c:56:12: note:        stmt 1 _8 = t_1_64 * t_1_64;
t.c:56:12: note:        children 0x159a8f10 0x159a8f10
t.c:56:12: note:   node 0x159a8f10 (max_nunits=2, refcnt=3) vector(2) double
t.c:56:12: note:   op template: t_0_63 = p_i_y_62(D) - pj_y_0_106;
t.c:56:12: note:        stmt 0 t_0_63 = p_i_y_62(D) - pj_y_0_106;
t.c:56:12: note:        stmt 1 t_1_64 = p_i_y_62(D) - pj_y_1_107;
t.c:56:12: note:        children 0x159a8fc0 0x159a9330
t.c:56:12: note:   node (external) 0x159a8fc0 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { p_i_y_62(D), p_i_y_62(D) }
t.c:56:12: note:   node (external) 0x159a9330 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { pj_y_0_106, pj_y_1_107 }
t.c:56:12: note:   node 0x159a91d0 (max_nunits=2, refcnt=2) vector(2) double
t.c:56:12: note:   op template: r2_0_60 = t_0_58 * t_0_58;
t.c:56:12: note:        stmt 0 r2_0_60 = t_0_58 * t_0_58;
t.c:56:12: note:        stmt 1 r2_1_61 = t_1_59 * t_1_59;
t.c:56:12: note:        children 0x159a93e0 0x159a93e0
t.c:56:12: note:   node 0x159a93e0 (max_nunits=2, refcnt=3) vector(2) double
t.c:56:12: note:   op template: t_0_58 = p_i_x_57(D) - pj_x_0_104;
t.c:56:12: note:        stmt 0 t_0_58 = p_i_x_57(D) - pj_x_0_104;
t.c:56:12: note:        stmt 1 t_1_59 = p_i_x_57(D) - pj_x_1_105;
t.c:56:12: note:        children 0x159a9490 0x159a9800
t.c:56:12: note:   node (external) 0x159a9490 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { p_i_x_57(D), p_i_x_57(D) }
t.c:56:12: note:   node (external) 0x159a9800 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { pj_x_0_104, pj_x_1_105 }
t.c:56:12: note:   node (external) 0x159a96a0 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { groupplcutoff2_80(D), groupplcutoff2_80(D) }
t.c:56:12: note:   node (constant) 0x159a98b0 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { 1, 1 }
t.c:56:12: note:   node (constant) 0x159a9960 (max_nunits=1, refcnt=1)
t.c:56:12: note:        { 0, 0 }

but in the end

t.c:56:12: missed:   not vectorized: basic block reduction epilogue operation
unsupported.
t.c:56:12: note:   removing SLP instance operations starting from: hu_86 = _26
+ _31;

because there's no reduc_plus_scalv2di and we do not consider open-coding
that in the vectorizer (yet).

But the first step is to improve on

              /* Make sure to have an even number of lanes as we later do
                 all-or-nothing discovery, not trying to split further.  */
              if ((chain.length () - remain_cnt) & 1)
                remain_cnt++;

the usual way would be to do a two-stage discovery, discover for all lanes
and then push non-matching ones to remain when analyzing the root.  Of course
you still have to be lucky to have lane zero the one with the most matching
other lanes.

Reply via email to