Issue 182427
Summary [AArch64] Materialise constants in NEON registers using `MOVI`/`MVNI`
Labels backend:AArch64, missed-optimization
Assignees
Reporter Kmeakin
    When materialising a constant in a NEON register, LLVM prefers to first materialise the constant into a scalar register, then copy into a NEON register using `FMOV`. However, in some cases, LLVM could use [`MOVI`](https://docsmirror.github.io/A64/2023-06/movi_advsimd.html) or [`MVNI` ](https://docsmirror.github.io/A64/2023-06/mvni_advsimd.html)

# Example
https://godbolt.org/z/6vG1Kn15E
```c++
#include <arm_neon.h>

#include <bit>

using half = __fp16;

half half_movi_1() { return std::bit_cast<half, short>(1); }
half half_movi_2() { return std::bit_cast<half, short>(2); }
half half_movi_3() { return std::bit_cast<half, short>(3); }

half half_mvni_0() { return std::bit_cast<half, short>(-1); }
half half_mvni_1() { return std::bit_cast<half, short>(-2); }
half half_mvni_2() { return std::bit_cast<half, short>(-3); }

float float_movi_1() { return std::bit_cast<float, int>(1); }
float float_movi_2() { return std::bit_cast<float, int>(2); }
float float_movi_3() { return std::bit_cast<float, int>(3); }

float float_mvni_0() { return std::bit_cast<float, int>(-1); }
float float_mvni_1() { return std::bit_cast<float, int>(-2); }
float float_mvni_2() { return std::bit_cast<float, int>(-3); }

double double_mvni_0() { return std::bit_cast<double, long>(0xffffffff'ffffffff); }
double double_mvni_1() { return std::bit_cast<double, long>(0xfffffffe'fffffffe); }
double double_mvni_2() { return std::bit_cast<double, long>(0xfffffffd'fffffffd); }
```

## GCC assembly
```asm
half_movi_1():
        movi    v0.4h, 0x1
        ret
half_movi_2():
        movi    v0.4h, 0x2
 ret
half_movi_3():
        movi    v0.4h, 0x3
 ret
half_mvni_0():
        mvni    v0.2s, 0
        ret
half_mvni_1():
 mvni    v0.4h, 0x1
        ret
half_mvni_2():
        mvni    v0.4h, 0x2
        ret
float_movi_1():
        movi    v0.2s, 0x1
 ret
float_movi_2():
        movi    v0.2s, 0x2
 ret
float_movi_3():
        movi    v0.2s, 0x3
 ret
float_mvni_0():
        mvni    v0.2s, 0
 ret
float_mvni_1():
        mvni    v0.2s, 0x1
 ret
float_mvni_2():
        mvni    v0.2s, 0x2
 ret
double_mvni_0():
        mvni    v0.4s, 0
 ret
double_mvni_1():
        mvni    v0.4s, 0x1
 ret
double_mvni_2():
        mvni    v0.4s, 0x2
        ret
double double_mvni_2() { return std::bit_cast<double, long>(0xfffffffd'fffffffd); }
```

## LLVM assembly
```asm
.LCPI0_0:
        .hword 0x0001
half_movi_1():
        adrp    x8, .LCPI0_0
        ldr     h0, [x8, :lo12:.LCPI0_0]
        ret

.LCPI1_0:
        .hword 0x0002
half_movi_2():
        adrp    x8, .LCPI1_0
        ldr     h0, [x8, :lo12:.LCPI1_0]
        ret

.LCPI2_0:
        .hword 0x0003
half_movi_3():
        adrp    x8, .LCPI2_0
        ldr     h0, [x8, :lo12:.LCPI2_0]
        ret

.LCPI3_0:
        .hword 0xffff
half_mvni_0():
        adrp    x8, .LCPI3_0
        ldr     h0, [x8, :lo12:.LCPI3_0]
        ret

.LCPI4_0:
        .hword 0xfffe
half_mvni_1():
        adrp    x8, .LCPI4_0
        ldr     h0, [x8, :lo12:.LCPI4_0]
        ret

.LCPI5_0:
        .hword 0xfffd
half_mvni_2():
        adrp    x8, .LCPI5_0
        ldr     h0, [x8, :lo12:.LCPI5_0]
        ret

float_movi_1():
        mov     w8, #1
        fmov    s0, w8
        ret

float_movi_2():
        mov w8, #2
        fmov    s0, w8
        ret

float_movi_3():
        mov w8, #3
        fmov    s0, w8
        ret

float_mvni_0():
        mov w8, #-1
        fmov    s0, w8
        ret

float_mvni_1():
 mov     w8, #-2
        fmov    s0, w8
        ret

float_mvni_2():
 mov     w8, #-3
        fmov    s0, w8
        ret

double_mvni_0():
 movi    d0, #0xffffffffffffffff
        ret

double_mvni_1():
 mov     x8, #-4294967298
        fmov    d0, x8
 ret

double_mvni_2():
        mov     x8, #-8589934595
        fmov d0, x8
        ret
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to