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       |                ^

Reply via email to