Closed
Description
Consider this C code:
#if !__has_extension(gnu_asm_goto_with_outputs_full)
#error Need the gnu_asm_goto_with_outputs_full extension
#endif
int main(void) {
int x = 123;
asm goto("mov %1, %0\n\tjmp %l[label]" : "=r" (x) : "r" (45) : : label);
x = 6;
label:
return x;
}
It's supposed to return 45. But when compiled on Clang trunk (4be1764) without optimizations, it produces this assembly:
main: # @main
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp)
movl $123, -8(%rbp)
movl $45, %eax
movl %eax, %eax
jmp .LBB0_3
movl %eax, -16(%rbp) # 4-byte Spill
movl %eax, -12(%rbp) # 4-byte Spill
jmp .LBB0_1
.LBB0_1:
movl -12(%rbp), %eax # 4-byte Reload
movl %eax, -8(%rbp)
movl $6, -8(%rbp)
.LBB0_2:
movl -8(%rbp), %eax
popq %rbp
retq
.LBB0_3: # Block address taken
movl -16(%rbp), %eax # 4-byte Reload
movl %eax, -8(%rbp)
jmp .LBB0_2
Which ends up returning uninitialized memory (the -16(%rbp)
from the third-to-last line) instead. If I instead compile with any optimization level (other than -O0
), then it produces correct assembly.