[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