Skip to content

[AArch64] Avoid materialising bitwise immediate arguments by decomposing into 2 arguments #148987

@Kmeakin

Description

@Kmeakin

The ORR, AND and EOR instructions only accept immediates in a specific form. For immediates that do not fit in this form, we have to materialise it with MOV+MOVK. However, sometimes instead of materialising, we could decompose the immediate into two immediates that are accepted.

C++ example: https://godbolt.org/z/vzzaTzseE
(The volatile keyword is required to prevent LLVM performing constant folding)
alive proof: https://alive2.llvm.org/ce/z/NmrTqz

#include <cstdint>

typedef uint32_t u32;

u32 src1(u32 x) { return x | 0xF0'00'00'F0; }
u32 tgt1(volatile u32 x) {
    x |= 0xF0'00'00'0;
    x |= 0x00'00'00'F0;
    return x;
}

u32 src2(u32 x) { return x & 0xF0'00'00'F0; }
u32 tgt2(volatile u32 x) {
    x &= 0xF0'00'00'FF;
    x &= 0xFF'FF'FF'F0;
    return x;
}

u32 src3(u32 x) { return x ^ 0xF0'00'00'F0; }
u32 tgt3(volatile u32 x) {
    x ^= 0xF0'00'00'00;
    x ^= 0x00'00'00'F0;
    return x;
}
src1(unsigned int):
        mov     w8, #240
        movk    w8, #61440, lsl #16
        orr     w0, w0, w8
        ret

tgt1(unsigned int):
        sub     sp, sp, #16
        str     w0, [sp, #12]
        ldr     w8, [sp, #12]
        orr     w8, w8, #0xf000000
        str     w8, [sp, #12]
        ldr     w8, [sp, #12]
        orr     w8, w8, #0xf0
        str     w8, [sp, #12]
        ldr     w0, [sp, #12]
        add     sp, sp, #16
        ret

src2(unsigned int):
        and     w8, w0, #0xfffffff0
        and     w0, w8, #0xf00000ff
        ret

tgt2(unsigned int):
        sub     sp, sp, #16
        str     w0, [sp, #12]
        ldr     w8, [sp, #12]
        and     w8, w8, #0xf00000ff
        str     w8, [sp, #12]
        ldr     w8, [sp, #12]
        and     w8, w8, #0xfffffff0
        str     w8, [sp, #12]
        ldr     w0, [sp, #12]
        add     sp, sp, #16
        ret

src3(unsigned int):
        mov     w8, #240
        movk    w8, #61440, lsl #16
        eor     w0, w0, w8
        ret

tgt3(unsigned int):
        sub     sp, sp, #16
        str     w0, [sp, #12]
        ldr     w8, [sp, #12]
        eor     w8, w8, #0xf0000000
        str     w8, [sp, #12]
        ldr     w8, [sp, #12]
        eor     w8, w8, #0xf0
        str     w8, [sp, #12]
        ldr     w0, [sp, #12]
        add     sp, sp, #16
        ret

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions