https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122757
Bug ID: 122757
Summary: [16 Regression] Copy prop for agegrates into calls
makes worse code for constants in some cases
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Target: aarch64
Take:
```
typedef struct sf { float a; float b; float c;} SF;
void sf_packing (SF i, SF j);
void
call_sf_packing (void)
{
SF A = {1.0F, 2.0F, 3.0F};
sf_packing ( A, A);
}
```
Before we would get:
```
fmov s0, 1.0e+0
fmov s1, 2.0e+0
fmov s2, 3.0e+0
sub sp, sp, #16
fmov s3, s0
fmov s4, s1
fmov s5, s2
add sp, sp, 16
b sf_packing
```
But after we get:
```
adrp x1, .LC0
add x0, x1, :lo12:.LC0
ldr s0, [x1, #:lo12:.LC0]
ldp s1, s2, [x0, 4]
fmov s3, s0
fmov s4, s1
fmov s5, s2
b sf_packing
.LC0:
.word 1065353216
.word 1073741824
.word 1077936128
```
I would have expected the middle-end do the right thing when expanding here but
it does not:
```
(insn 7 6 8 2 (set (reg:DI 102)
(high:DI (symbol_ref/f:DI ("*.LC0") [flags 0x2] <var_decl
0x75bc2b72eed8 *.LC0>))) "/app/example.c":8:2 -1
(nil))
(insn 8 7 9 2 (set (reg/f:DI 101)
(lo_sum:DI (reg:DI 102)
(symbol_ref/f:DI ("*.LC0") [flags 0x2] <var_decl 0x75bc2b72eed8
*.LC0>))) "/app/example.c":8:2 -1
(expr_list:REG_EQUAL (symbol_ref/f:DI ("*.LC0") [flags 0x2] <var_decl
0x75bc2b72eed8 *.LC0>)
(nil)))
(insn 9 8 10 2 (set (reg:SF 103)
(mem/u/c:SF (reg/f:DI 101) [0 S4 A64])) "/app/example.c":8:2 -1
(nil))
(insn 10 9 11 2 (set (reg:SF 104)
(mem/u/c:SF (plus:DI (reg/f:DI 101)
(const_int 4 [0x4])) [0 S4 A32])) "/app/example.c":8:2 -1
(nil))
(insn 11 10 12 2 (set (reg:SF 105)
(mem/u/c:SF (plus:DI (reg/f:DI 101)
(const_int 8 [0x8])) [0 S4 A64])) "/app/example.c":8:2 -1
(nil))
```
That is it does not see if the value that is in the constant (which is part of
the constant pool) could be loaded directly into the reg and/or even add a
REG_EQUAL marker.