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.