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.