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

            Bug ID: 127778
           Summary: RISC-V: Missed optimization for non-stack base +
                    [2048, 4094] after PR120811
           Product: gcc
           Version: 16.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: luismgsilva at outlook dot com
  Target Milestone: ---

Created attachment 65783
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65783&action=edit
RISC-V: Restore sum-of-two-s12 add split without undoing PR120811

PR target/120811 removed `*add<mode>3_const_sum_of_two_s12` so that post-reload
combine would not squash the `addi` pairs LRA emits for out-of-range frame
offsets.  That pattern was also the split for an ordinary (non-SP/FP) base plus
a constant in `(2048, 4094]` or `[-4096, -2049]`: `addi` of 2047 or -2048, with
the remainder folded into the memory operand.

After the removal those addresses are materialized with `li`/`lui` and `add`.
This shows up in Dhrystone `Proc_8` on the store to `Arr_2[Int_Loc +
20][Int_Loc]`.  The row displacement is `20 * 50 * sizeof (int) == 4000`.

Reduced testcase, compiled with `-O2 -march=rv32gc -mabi=ilp32`:

    void
    store_4000 (int *p, int v)
    {
      p[1000] = v;
    }

GCC 15:

    addi    a0,a0,2047
    sw      a1,1953(a0)     # 2047 + 1953 = 4000

GCC 16:

    li      a5,4096
    add     a0,a0,a5
    sw      a1,-96(a0)      # 4096 - 96 = 4000

The same sequence appears for a load from `p[1000]`.

The attached patch restores `*add<mode>3_const_sum_of_two_s12` for bases other
than the stack pointer, the frame pointer, and other frame-related registers.
`store_4000` returns to the GCC 15 sequence, and the LRA reloads covered by
`gcc.target/riscv/pr120811.c` stay an `addi` from `sp` plus a load or store
with a signed 12-bit offset.

Reply via email to