With current trunk, but also older gcc int f(char *s) { int c = 0; int i; for (i = 0; i < 64; i++) { c |= (*s == ',' || *s == '|' || *s == '!' /* || *s == '*' */); s++; } return c; } vectorizes with -O3 -mavx2 -fopt-info-optall-all tvcmp.c tvcmp.c:6:16: optimized: loop vectorized using 16 byte vectors tvcmp.c:2:5: note: vectorized 1 loops in function. tvcmp.c:7:10: optimized: loop with 3 iterations completely unrolled (header execution count 16535624) but when the fourth comparison is commented in it doesn't: BB 3 is always executed in loop 1 loop 1's coldest_outermost_loop is 1, hotter_than_inner_loop is NULL tvcmp.c:6:16: missed: couldn't vectorize loop tvcmp.c:6:16: missed: not vectorized: unsupported control flow in loop. tvcmp.c:2:5: note: vectorized 0 loops in function. tvcmp.c:10:9: note: ***** Analysis failed with vector mode V16QI tvcmp.c:10:9: note: ***** Skipping vector mode V16QI, which would repeat the analysis for V16QI
The issue seems to be that if-to-switch creates a switch () once you get to four conditions and switch statements are not handled by the pre-vectorizer if-conversion (or by vectorization natively).
GCC 8 vectorises it: https://godbolt.org/z/Y8Pvxsh5c.
(In reply to Sam James from comment #2) > GCC 8 vectorises it: https://godbolt.org/z/Y8Pvxsh5c. Not only does 8 vectorise it, but so does GCC 11, GCC 12. So, 9/13/14/15 are broken.
Not only does 8 vectorise it, but so does GCC 11, GCC 12. So, 9/10/13/14/15 are broken.
(In reply to Sam James from comment #2) > GCC 8 vectorises it: https://godbolt.org/z/Y8Pvxsh5c. The if-to-switch was not until GCC 11: r11-5605-g03eb09292ef228. What made GCC 9 fail was the conversion from bool to int though: /app/example.c:2:5: missed: not vectorized: relevant stmt not supported: patt_29 = (int) patt_30; But that worked in GCC 8. Though that was fixed in GCC 11. If you replace `c|=` with: ``` c |= (*s == ',' | *s == '|' | *s == '!' | *s == '*'); ``` GCC 11+ is able to vectorize it again. But the original testcase fails now due to if-to-switch .
As an interesting but irrelevant side comment clang seems to have the same bug.
Fixed for GCC 15 by a new feature in vectorizer if-conversion.