By the way, CLANG 2.9 produce same behavior as my front-end:
Try clang
clang -O2 -S -emit-llvm rec.c -o rec.ll
on following example:
/*— Recurrence recognition. */
static int expect = {
1, 1, 1, 1 /* t0: 0 - 3 */
};
extern void check() ;
#define N sizeof(expect) / sizeof(int)
static int result[N];
static void
t0(int n)
{
int i;
for (i=0; i<n; i++)
result[i+1] = result[i];
}
void
test() {
result[0] = 1;
t0(3);
check(result, expect, N);
}
LL file generated is:
; ModuleID = ‘ka50.c’
target datalayout = “e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64”
target triple = “x86_64-unknown-linux-gnu”
@result = internal global [4 x i32] zeroinitializer, align 16
@expect = internal global [4 x i32] [i32 1, i32 1, i32 1, i32 1], align 16
define void @test() nounwind {
store i32 1, i32* getelementptr inbounds ([4 x i32]* @result, i64 0, i64 0), align 16, !tbaa !0
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (i32* getelementptr inbounds ([4 x i32]* @result, i64 0, i64 1) to i8*), i8* bitcast ([4 x i32]* @result to i8*), i64 12, i32 4, i1 false) nounwind
tail call void (…)* @check(i32* getelementptr inbounds ([4 x i32]* @result, i64 0, i64 0), i32* getelementptr inbounds ([4 x i32]* @expect, i64 0, i64 0), i64 4) nounwind
ret void
}
declare void @check(…)
Then assembly produced is:
test: # @test
.Leh_func_begin0:
BB#0:
pushq %rbp
.Ltmp0:
movq %rsp, %rbp
.Ltmp1:
movl $1, result(%rip)
movl result+8(%rip), %eax
movl %eax, result+12(%rip)
movq result(%rip), %rax
movq %rax, result+4(%rip)
movl $result, %edi
movl $expect, %esi
movl $4, %edx
xorb %al, %al
callq check
popq %rbp
ret
As you can see resul+8 is read before being written and thus the problem.
Hope that clarifies the problem.
2011/12/9 Seb <babslachem@gmail.com>