An Optimizer Bug in Clang

Found out about an interesting bug in Clang, the popular C++ compiler that aims to do better than GNU GCC.    But clang, with optimization turned on, may incorrectly optimize away useful code.

The problem, along with a short test program, is described in a question by Chris_F at StackOverflow,

When compiled with GCC, it works correctly, always returning an exit code of 6. When compiled with clang, with no opimization or the lowest level, we still get 6. But with -O2 or -O3, the clang-compiled executable is missing a bunch of stuff, to wit, everything, and returns 1 not 6.  

The following test program source is given by mukunda in the accepted answer. It’s shorter and simpler than the test program given in the question.   

— test.cpp —
// Test program – clang optimization bug
// compile with
//     g++ -o testgcc3 -O3  -std=gnu++11  test.cpp
// should return 6   (warning: run time is about half a minute)
// bug in clang:
//     clang -o testclang2 -O2  -std=c++11 test.cpp
// will return 6 for -O0 -O1 but returns 1 for -O2 -O3

#include <cstdint>
int main()
    uint32_t i = 0;
    uint32_t count = 1;
    while (1)
        if( i < 5 )
        if (i == 0xFFFFFFFF)
    return count; // should return 6
—- end of file —-

I compiled this with GCC 4.9.0 and Clang 3.4 each at four levels of optimization. The return values I saw were:

GCC -O0    6
GCC -O1    6
GCC -O2    6
GCC -O3    6
Clang -O0  6
Clang -O1  6
Clang -O2  1
Clang -O3  1

At least the erroneous versions return 1, which by convention indicates some sorta trouble, rather than 0.  

It has been discovered that using -fno-vectorize with clang makes the problem go away.  Some commenters think this bug a case of, or related to,

I like clang overall, but stuff like this makes me nervous about compiling massive number crunching code with heavy optimizations, something we physicists like to do!