llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.33k stars 12.13k forks source link

inconsistent behaviors at -O3 #45392

Open llvmbot opened 4 years ago

llvmbot commented 4 years ago
Bugzilla Link 46047
Version unspecified
OS Linux
Attachments the binary
Reporter LLVM Bugzilla Contributor
CC @dwblaikie,@JDevlieghere

Extended Description

$ clang --version clang version 11.0.0 (/home/yibiao/.cache/yay/llvm-git/llvm-project 871beba234a83a2a02da9dedbd59b91a1bfbd7af) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin

$ lldb --version lldb version 11.0.0 clang revision 871beba234a83a2a02da9dedbd59b91a1bfbd7af llvm revision 871beba234a83a2a02da9dedbd59b91a1bfbd7af

$ clang -O3 -g small.c

$ lldb a.out (lldb) target create "a.out" Current executable set to '/home/yibiao/Debugger/a.out' (x86_64). (lldb) b 11 Breakpoint 1: where = a.out`main + 79 at small.c:11:3, address = 0x000000000040117f (lldb) r Process 565482 launched: '/home/yibiao/Debugger/a.out' (x86_64) Process 565482 exited with status = 0 (0x00000000) (lldb)

/**** As showed above, Line 11 is not hit by LLDB when setting breakpoint at Line 11. However, Line 11 is hit by LLDB when using step-i. ****/

$ lldb a.out (lldb) target create "a.out" Current executable set to '/home/yibiao/Debugger/a.out' (x86_64). (lldb) b main Breakpoint 1: where = a.out`main + 1 at small.c:6:10, address = 0x0000000000401131 (lldb) r Process 565440 launched: '/home/yibiao/Debugger/a.out' (x86_64) Process 565440 stopped

$ cat small.c

include

int a, b, c, d[10];

int main() { for (int e=0; e<10; e++) d[e] = 1; if (d[0]) c = a = (b == 0 || 1 % b); if (a != 1) abort(); return 0; }

dwblaikie commented 4 years ago

Yep, GCC does the same thing - tail duplicates.

And GDB does the same thing - doesn't break on line 11.

dwblaikie commented 4 years ago

Looks like tail duplication:

main: # @​main .Lfunc_begin0: .loc 1 4 0 # ./example.cpp:4:0 .cfi_startproc

%bb.0:

    push    rax
    .cfi_def_cfa_offset 16

.Ltmp0:

DEBUG_VALUE: e <- 3

    .loc    1 6 10 prologue_end     # ./example.cpp:6:10
    movaps  xmm0, xmmword ptr [rip + .LCPI0_0] # xmm0 = [1,1,1,1]
    movaps  xmmword ptr [rip + .Ld$local], xmm0

.Ltmp1:

DEBUG_VALUE: e <- 7

    movaps  xmmword ptr [rip + .Ld$local+16], xmm0
    movabs  rax, 4294967297

.Ltmp2:

DEBUG_VALUE: e <- 8

    mov     qword ptr [rip + .Ld$local+32], rax

.Ltmp3:

DEBUG_VALUE: e <- 10

    .loc    1 8 14                  # ./example.cpp:8:14
    mov     ecx, dword ptr [rip + .Lb$local]
    .loc    1 8 16 is_stmt 0        # ./example.cpp:8:16
    test    ecx, ecx
    .loc    1 8 21                  # ./example.cpp:8:21
    je      .LBB0_1

.Ltmp4:

%bb.2:

    .loc    1 8 26                  # ./example.cpp:8:26
    mov     eax, 1
    xor     edx, edx
    idiv    ecx
    .loc    1 8 24                  # ./example.cpp:8:24
    xor     eax, eax
    test    edx, edx
    setne   al
    .loc    1 8 11                  # ./example.cpp:8:11
    mov     dword ptr [rip + .La$local], eax
    .loc    1 8 7                   # ./example.cpp:8:7
    mov     dword ptr [rip + .Lc$local], eax
    .loc    1 9 7 is_stmt 1         # ./example.cpp:9:7
    je      .LBB0_4

%bb.3:

    .loc    1 11 3                  # ./example.cpp:11:3
    xor     eax, eax
    pop     rcx
    .cfi_def_cfa_offset 8
    ret

.LBB0_1: .cfi_def_cfa_offset 16 .loc 1 8 11 # ./example.cpp:8:11 mov dword ptr [rip + .La$local], 1 .loc 1 8 7 is_stmt 0 # ./example.cpp:8:7 mov dword ptr [rip + .Lc$local], 1 .loc 1 11 3 is_stmt 1 # ./example.cpp:11:3 xor eax, eax pop rcx .cfi_def_cfa_offset 8 ret .LBB0_4: .cfi_def_cfa_offset 16 .loc 1 10 5 # ./example.cpp:10:5 call abort

I'm guessing the second ret is the one that's reached (haven't looked at the code long enough to confirm) - and lldb's strategy of taking all instances of the location and breaking on the first one misses here. I wonder how GDB behaves with this code (& what GCC's code looks like)