I know that there is some recent discussions about the optimizations on volatile loads and stores, and the conclusion is that LLVM is doing the right thing. But this time the story seems different. See below for details. The test case will be posted shortly. ======================================================================= For my first example, LLVM is able to preserve both volatile load and store correctly. void PassThrough(volatile int* DataIn, volatile int* DataOut) { int i; int buffer[64]; for (i = 0; i < 64; i++) buffer[i] = *DataIn; for (i = 0; i < 64; i++) *DataOut = buffer[i]; } ======================================================================= For the second one, however, LICM will move the volatile store outside of the loop, which is apparently wrong. void Transpose(volatile int* DataIn, volatile int* DataOut) { int i, j; int buffer[64]; for (i = 0; i < 64; i++) buffer[i] = *DataIn; for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) *DataOut = buffer[j * 8 + i]; } ========================================================= What I did: llvm-gcc -O0 -c -emit-llvm test_volatile.c -o test.bc opt -mem2reg -licm test.bc -o new.bc -f
Created attachment 862 [details] test_volatile.c
This sounds like a real bug.
Nice catch. This impacts nested loops only. Thanks for the excellent testcase reduction. Fixed. Testcase here: Transforms/LICM/2007-05-22-VolatileSink.ll Patch here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070521/049945.html -Chris