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.

Reply via email to