llvm / llvm-project

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

missing optimization (alias analysis issue?) #29986

Open llvmbot opened 8 years ago

llvmbot commented 8 years ago
Bugzilla Link 30638
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @hfinkel,@sebpop

Extended Description

The following code:

include

include

struct base { virtual ~base() {} };

void f(std::vector<std::unique_ptr >& v) { v.back().release(); v.pop_back(); }

GCC 6.2 is able to optimize to just two instructions:

    sub     QWORD PTR [rdi+8], 8
    ret

The code generated by clang 3.9.0 is less efficient:

    push    rbx
    mov     rax, qword ptr [rdi + 8]

    mov     qword ptr [rax - 8], 0

    mov     rax, qword ptr [rdi + 8]
    lea     rbx, [rax - 8]
    mov     qword ptr [rdi + 8], rbx

    mov     rdi, qword ptr [rax - 8]
    test    rdi, rdi
    je      .LBB0_2
    mov     rax, qword ptr [rdi]
    call    qword ptr [rax + 8]

.LBB0_2: mov qword ptr [rbx], 0 pop rbx ret

As [rax - 8] is reloaded after subtraction I tend believe it is an alias analysis issue.

fa778132-f3d5-4559-b45d-fa683057d467 commented 6 years ago

Confirmed: missed optimization.

Today's llvm for aarch64 produces 7 loads

str x19, [sp, #-32]!        // 8-byte Folded Spill
stp x29, x30, [sp, #&#8203;16]     // 8-byte Folded Spill
ldr x8, [x0, #&#8203;8]
stur    xzr, [x8, #-8]
ldr x8, [x0, #&#8203;8]
sub x19, x8, #&#8203;8             // =8
str x19, [x0, #&#8203;8]
ldur    x0, [x8, #-8]
add x29, sp, #&#8203;16            // =16
cbz x0, .LBB0_2

// %bb.1: ldr x8, [x0] ldr x8, [x8, #​8] blr x8 .LBB0_2: str xzr, [x19] ldp x29, x30, [sp, #​16] // 8-byte Folded Reload ldr x19, [sp], #​32 // 8-byte Folded Reload ret

versus only one load when compiling with gcc trunk:

ldr x1, [x0, 8]
sub x1, x1, #&#8203;8
str x1, [x0, 8]
ret