llvm / llvm-project

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

[AArch64] Redundant `cmp` not eliminated #99390

Open Kmeakin opened 1 month ago

Kmeakin commented 1 month ago

https://godbolt.org/z/av7vTE7as

#include <cstdint>
#include <numeric>

typedef uint32_t u32;

u32 midpoint_u32(u32 a, u32 b) { return std::midpoint(a, b); }

Generated code:

_Z12midpoint_u32jj:                     // @_Z12midpoint_u32jj
        cmp     w0, w1
        csel    w8, w0, w1, lo
        csel    w9, w0, w1, hi
        cmp     w0, w1
        sub     w8, w9, w8
        lsr     w8, w8, #1
        cneg    w8, w8, hi
        add     w0, w8, w0
        ret

The 2nd cmp is unnecessary: the flags register still contains the result of the first cmp instruction

llvmbot commented 1 month ago

@llvm/issue-subscribers-backend-aarch64

Author: Karl Meakin (Kmeakin)

https://godbolt.org/z/av7vTE7as ```c++ #include <cstdint> #include <numeric> typedef uint32_t u32; u32 midpoint_u32(u32 a, u32 b) { return std::midpoint(a, b); } ``` Generated code: ```asm _Z12midpoint_u32jj: // @_Z12midpoint_u32jj cmp w0, w1 csel w8, w0, w1, lo csel w9, w0, w1, hi cmp w0, w1 sub w8, w9, w8 lsr w8, w8, #1 cneg w8, w8, hi add w0, w8, w0 ret ``` The 2nd `cmp` is unnecessary: the flags register still contains the result of the first `cmp` instruction
davemgreen commented 1 month ago

I would guess this is because the SUB is emitted as SUBS and the ordering of the instructions is slightly different pre-scheduling.