https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126053
Bug ID: 126053
Summary: GCC trunk vs Intel oneAPI : Missed SLP vectorization
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: Reshma.Roy at amd dot com
Target Milestone: ---
Created attachment 64903
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64903&action=edit
The preprocessed input file to be used for the command mentioned in the
description
----------------------------------------------------------------------
GCC trunk vs Intel oneAPI : Missed SLP vectorization
----------------------------------------------------------------------
Compiler Versions
oneAPI : Intel oneAPI 2025.3
gcc trunk : gcc (GCC) 17.0.0 20260623 (experimental)
commit da3f0b48d0b8b314143f5670bb1918419cee0d6f
Context
-------
We compared a hot loop from SPEC2017 becnhmark 508.namd_r in the file
ComputeNonbondedBase2.h:354-372 && 533-549 between GCC trunk and Oneapi.
The kernel lives in a header that is textually instantiated many times
where some instantiation were vectorized whereas the other not.
One such case is the instantiation in calc_pair_energy_fullelect where
its not vectorized whereas it is vectorized in calc_self_energy_fullelect.
The test case is reduced from the preprocesed file ComputeNonbondedStd.ii
Reduced Testcase
----------------
typedef double BigReal;
struct Position { BigReal x, y, z; };
struct CompAtom {
Position position;
float charge;
short vdwType;
unsigned char partition;
unsigned char nonbondedGroupSize;
};
struct Force { BigReal x, y, z; };
struct SimParams { BigReal offset_x, offset_y, offset_z; };
void calc_pair_energy_fullelect(
const CompAtom * __restrict p_1,
const CompAtom * __restrict p_i,
const SimParams * __restrict params,
const int * __restrict pairlisti, // neighbour index list
int npairi,
const BigReal * __restrict force_r_vals,
Force * __restrict f_1,
BigReal &f_i_x, BigReal &f_i_y, BigReal &f_i_z,
BigReal &virial_xx, BigReal &virial_xy, BigReal &virial_xz,
BigReal &virial_yy, BigReal &virial_yz, BigReal &virial_zz)
{
const BigReal p_i_x = params->offset_x + p_i->position.x;
const BigReal p_i_y = params->offset_y + p_i->position.y;
const BigReal p_i_z = params->offset_z + p_i->position.z;
for (int k = 0; k < npairi; ++k) {
const int j = pairlisti[k]; // indirect index
const CompAtom *p_j = p_1 + j;
Force *f_j = f_1 + j; // non-affine gather base
const BigReal p_ij_x = p_i_x - p_j->position.x;
const BigReal p_ij_y = p_i_y - p_j->position.y;
const BigReal p_ij_z = p_i_z - p_j->position.z;
const BigReal force_r = force_r_vals[k];
// ComputeNonbondedStd.ii:15087-15104
BigReal tmp_x = force_r * p_ij_x;
virial_xx += tmp_x * p_ij_x;
virial_xy += tmp_x * p_ij_y;
virial_xz += tmp_x * p_ij_z;
f_i_x += tmp_x;
f_j->x -= tmp_x; // scatter store, not vectorized
BigReal tmp_y = force_r * p_ij_y;
virial_yy += tmp_y * p_ij_y;
virial_yz += tmp_y * p_ij_z;
f_i_y += tmp_y;
f_j->y -= tmp_y;
BigReal tmp_z = force_r * p_ij_z;
virial_zz += tmp_z * p_ij_z;
f_i_z += tmp_z;
f_j->z -= tmp_z;
}
}
Compiler command used:
----------------------
gcc -O3 -march=znver5 -fdump-tree-slp-details -fopt-info-vec-missed -S -o
namd557_pair_fail.s namd557_pair_fail.ii 2> gcc_vec_missed_pair.txt
icx -O3 -march=graniterapids -S -Rpass=slp-vectorizer -o
namd557_pair_fail_icx.s
namd557_pair_fail.ii 2>icx_vect.log
Logs:
------
In the slp dump files when compiled with gcc we can see that the SLP fails.
It seems like SLP codegen aborts it. The logs also substantiate that:
namd557_pair_fail.cpp:91:16: missed: Build SLP failed: unrolling required in
basic block SLP
analyze_innermost: namd557_pair_fail.cpp:91:16: missed: failed: evolution of
base is not affine.
namd557_pair_fail.cpp:91:16: missed: Cannot determine insertion place for lane
extract
In icx Rpass logs we can see the SLP vectorization happened.
1 namd557_pair_fail.cpp:91:16: remark: Stores SLP vectorized with cost -9 and
with tree size 10 [-Rpass=slp-vectorizer]
2 91 | f_j->x -= tmp_x; // <-- scatter
store, not vectorized
3 | ^