[llvm] r211543 - [FastISel][X86] Optimize selects when the condition comes from a compare.
Stephan Bergmann
sbergman at redhat.com
Wed Jun 25 08:08:55 PDT 2014
On 06/25/2014 01:58 PM, Stephan Bergmann wrote:
> This commit smells like it broke things at least on X86_64 Linux.
> Compiling
>
>> void SB(signed char x) {
>> int n(x ? 0 : -1);
>> for (;;) {
>> fprintf(stderr,"\n\nx=%d n=%d\n\n",(int)x,(int)n);
>> return;
>> }
>> }
>
> with -O0 and -fsanitize=address and -fsanitize=undefined (that's at
> least how I stumbled across it) generates broken code for the
>
> int n(x ? 0 : -1)
>
> line:
>
>> movl $0, %eax # eax: 0
>> movq 80(%rsp), %rcx # 8-byte Reload # rcx: &x
>> cmpb $0, (%rcx) # z: x == 0
>> setne %dl # dl: x
>> != 0
>> subl $1, %eax # eax: -1
>> seto %sil # sil: 0
>> xorb $1, %sil # sil: 1
>> testb $1, %sil # z: 0
>> movb %dl, 69(%rsp) # 1-byte Spill
>> movl %eax, 64(%rsp) # 4-byte Spill
>> jne .LBB84_10 # taken
>> # BB#9: # %handler.negate_overflow
>> .Ltmp7419:
>> callq __asan_handle_no_return at PLT
>> leaq .L__unnamed_1810(%rip), %rax
>> movabsq $1, %rsi
>> movq %rax, %rdi
>> callq __ubsan_handle_negate_overflow_abort at PLT
>> .Ltmp7420:
>> .LBB84_10: # %cont
>> movl $0, %eax
>> .Ltmp7421:
>> movb 63(%rsp), %cl # 1-byte Reload
>> cmpb $0, %cl
>> movl 64(%rsp), %edx # 4-byte Reload
>> cmovnel %eax, %edx
>
> While the 1-byte spill of x!=0 writes to 69(%rsp), its 1-byte reload
> (after the ubsan handler for the case that computing -1 = 0 - 1 would
> have overflown) erroneously reads from 63(%rsp).
...looks like X86FastISel::X86FastEmitCMoveSelect ->
X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT) -> getRegForValue(Op0) comes
up with a different virtual register than the one that got spilled out,
for whatever reason (way beyond my humble debugging attempts).
Stephan
More information about the llvm-commits
mailing list