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.