llvm-gcc doesnt honor volatile quantifier of the array type?

Hi,

I encountered a problem about volatile quantifier when using llvm-gcc, here is the example:

#define N 10

int sum(volatile int a[N]) {
int sum = 0;
unsigned i = 0;
for (i = 0; i < N; ++i)
sum += a[i];

return sum;
}

If I compile it as C code, then llvm-gcc will dump:

define i32 @sum(i32* nocapture %a) nounwind {
bb1.thread:
%0 = volatile load i32* %a, align 4 ; [#uses=1]
%1 = getelementptr i32* %a, i32 1 ; <i32*> [#uses=1]
%2 = volatile load i32* %1, align 4 ; [#uses=1]
%3 = add i32 %2, %0 ; [#uses=1]

}

We can see the load is “volatile”, this is correct and expected.

But when I compile the example as C++ code, then llvm-gcc dump:

define i32 @_Z3sumPVi(i32* nocapture %a) nounwind readonly {
bb1.thread:
%0 = load i32* %a, align 4 ; [#uses=1]
%1 = getelementptr i32* %a, i32 1 ; <i32*> [#uses=1]
%2 = load i32* %1, align 4 ; [#uses=1]
%3 = add i32 %2, %0 ; [#uses=1]

}

No volatile keeps, is it expected or a bug for llvm-gcc?

Anyone can help me? Thanks in advance.

Sheng.

This looks wrong to me, though the x86 backend produces code that does the right thing (reads each element once).

If you change the code (see below) to read each element twice, llvm-gcc still does the right thing but llvm-g++ does not (i.e. it fails to read aech location twice). Current versions of gcc/g++ also look wrong.

All 4 compilers (gcc,g++,llvm-gcc,llvm-g++) do the right thing when the array is global.

John

#define N 3

typedef volatile int vint;

int sum(vint a[N]) {
   int sum = 0;
   unsigned i;
   for (i = 0; i < N; i++)
     sum += a[i] + a[i];
   return sum;
}

I filed a bug on this:

http://llvm.org/bugs/show_bug.cgi?id=3320

John