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

            Bug ID: 121685
           Summary: Failure to vectorize because of failed invariant
                    motion
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

#include <vector>

void fun(std::vector<int>& blacksq, std::vector<int>& m_mcowner) 
{
  for (unsigned int i = 0; i < blacksq.size(); i++) {
      if (blacksq[i]) {
          m_mcowner[i]++;
      }
  }
}

is not vectorized because the scalar loop IL is

  if (_22 != 0)
    goto <bb 15>; [50.00%]
  else
    goto <bb 16>; [50.00%]

  <bb 15> [local count: 507140075]:
  _24 = m_mcowner_11(D)->D.27773._M_impl.D.27088._M_start;
  _34 = _24 + _20;
  _35 = *_34;
  _36 = _35 + 1;
  *_34 = _36;

  <bb 16> [local count: 1014280150]:

so the load of the base address of the m_mcowner vector isn't hoisted from
the loop.  That is in turn because this load can trap (from GIMPLE IL
semantics, maybe not from C++ semantics).

Splitting the loop on the if (_22 != 0) condition would allow the hoisting
to occur in the second half of the loop iterations.  There is some
related (but not exactly like this) code in the loop splitting pass,
splitting on a "semi-invariant" condition.

A better solution would be to declare the hoisting valid from a C++ perspective
and mark the load appropriately somehow.

Reply via email to