https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98176
--- Comment #2 from Hongyu Wang <wwwhhhyyy333 at gmail dot com> --- >> I doubt the call is the issue btw. The aliasing could be removed by float foo(int *x, int n, float tx) { float ret[n]; #pragma omp simd for (int i = 0; i < n; i++) { float s, c; s = c = tx * x[i]; ret[0] += s*c; } return ret[0]; } This is successfully vectorized, and the dump from lim2 has: Moving statement ret.1__I_lsm.7 = (*ret.1_18)[0]; But for float foo(int *x, int n, float tx) { float ret[n]; #pragma omp simd for (int i = 0; i < n; i++) { float s, c; sincosf( tx * x[i] , &s, &c ); ret[0] += s*c; } return ret[0]; } It still could not be vectorized. I did initial debugging and see tree-ssa-loop-im.c has if (nonpure_call_p (stmt)) { maybe_never = true; outermost = NULL; } So no store-motion chance for any future statement in such block. As a comparison, this could also be vectorized with simd clone: float foo(int *x, int n, float tx) { float ret[n]; #pragma omp simd for (int i = 0; i < n; i++) { float s, c; s = c = sinf( tx * x[i]); ret[0] += s*c; } return ret[0]; }