We have identified what we consider to be a compiler bug. Verified with the latest version of the compiler (2013 SP1) just now.
A simple code sample to illustrate the issue can be found at this address:
https://gist.github.com/lemire/6642148
and I also include it below.
It suffices to compile and run the code as directed. A print-out will then show the result of the computation vs. the expected result. The function that triggers the issue has only 7 (simple) lines. It appears that the keyword "restrict" is needed for the bug to appear.
We checked the assembly generated by the compiler and it makes no sense to us.
Note that the same code sample was tested successfully with several compilers including gcc.
Context: we identified this bug while working on a fast integer compression library (https://github.com/lemire/FastPFor). After getting the library to pass all tests with clang, gcc, VS2012... the intel compiler gave us grief. The code sample is the simplest case we could come up with to trigger the bug. To get around the bug, we simply manually unrolled the loop. This is obviously not very desirable in general.
// compile with:
// icc -std=c99 -O2 iccbug.c -o iccbug
// then run iccbug
// Tested in Linux Ubuntu 12.10 (Intel Core i7)
#include <stdint.h>
#include <stdio.h>
// expect: out[0] = in[0] + in[1] + in[2] + in[3];
// out[1] = in[4] + in[5] + in[6] + in[7];
__attribute__((noinline))
void broken_with_O2(int * restrict in, int * out) {
for(int outer = 0; outer < 2; outer++) {
*out = *in++;
for (int inner = 1; inner < 4; inner++) {
*out += *in++;
}
++out;
}
}
int main() {
int in[8] = {1,1,1,1,1,1,1,1};
int out[2];
broken_with_O2(&in[0],&out[0]);
printf(" got = %d %dn",out[0], out[1]);
printf(" expected = %d %dn", 4,4);
}