https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126080
Bug ID: 126080
Summary: BB SLP discovery fails to fork upon def type mismatch
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: rguenth at gcc dot gnu.org
Target Milestone: ---
Split out from PR126053
double x[4];
void foo (double *p)
{
int tem0 = x[0];
int tem1 = x[1];
int tem2 = x[2];
int tem3 = x[3];
tem0 = tem0 + p[0];
tem1 = tem1 + p[1];
tem2 = tem2 + 1.;
tem3 = tem3 + 1.;
x[0] = tem0;
x[1] = tem1;
x[2] = tem2;
x[3] = tem3;
}
shows that we give up SLP discovery on the tem + 1./*p stmt group:
t2.c:13:8: note: Build SLP for _7 = _5 + _6;
t2.c:13:8: note: Build SLP for _10 = _8 + _9;
t2.c:13:8: note: Build SLP for _12 = _11 + 1.0e+0;
t2.c:13:8: note: Build SLP for _14 = _13 + 1.0e+0;
t2.c:13:8: note: vect_is_simple_use: operand (double) tem0_20, type of def:
internal
t2.c:13:8: note: vect_is_simple_use: operand __MEM <double> (p_24(D)), type
of def: internal
t2.c:13:8: note: vect_is_simple_use: operand (double) tem1_21, type of def:
internal
t2.c:13:8: note: vect_is_simple_use: operand __MEM <double> (p_24(D) +
_Literal (double *) 8), type of def: internal
t2.c:13:8: note: vect_is_simple_use: operand (double) tem2_22, type of def:
internal
t2.c:13:8: note: vect_is_simple_use: operand 1.0e+0, type of def: constant
t2.c:13:8: missed: treating operand as external
resulting in
t2.c:13:8: note: node (external) 0x21e3c4f0 (max_nunits=1, refcnt=1)
t2.c:13:8: note: { _6, _9, 1.0e+0, 1.0e+0 }
even though a perfect split sits at SSE vector size boundary.
The solution is to consider forking the SLP graph instead of promoting
something external since we cannot rely on global failure to do
splitting at that level.
Re-merging can be done with a VEC_PERM node which as in this case ideally
has zero cost but could also handle the transition between different
vector sizes (SSE and AVX for the testcase at hand).