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])))
)