https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119165

            Bug ID: 119165
           Summary: Missing use of movk
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64

Take:
```
uint64_t foo(uint32_t *raw){
    // load
    uint64_t res = *raw;
    // movk
    res |= (uint64_t)0xfffd << 48;
    // ret
    return res;
}
```

Currently GCC produces:
```
foo(unsigned int*):
.LFB3:
        .cfi_startproc
        ldr     w0, [x0]
        mov     x1, -844424930131968
        orr     x0, x0, x1
        ret
```

But since the 32bits upper bits of x0 are already 0, GCC should produce:
```
        ldr     w0, [x0]
        movk    x0, -844424930131968
        ret
```
That is have a split for:
(set (reg/i:DI 0 x0)
    (ior:DI (zero_extend:DI (mem:SI (reg/f:DI 107 [ rawD.4659 ]) [1 *raw_3(D)+0
S4 A32]))
        (const_int -844424930131968 [0xfffd000000000000])))


(and for:
(set (reg/i:DI 0 x0)
    (ior:DI (zero_extend:DI (reg:SI 106 [ rawD.4659 ]))
        (const_int -844424930131968 [0xfffd000000000000])))
)

Reply via email to