[PATCH v2] RISC-V: Add second-pass relaxation for JAL to C.J/C.JAL

Nelson Chu nelson.chu1990@gmail.com
Thu Jan 15 04:27:26 GMT 2026


Thanks, committed.

On Wed, Jan 14, 2026 at 5:47 PM Kito Cheng <kito.cheng@gmail.com> wrote:
>
> Verified with following configuration with riscv-gnu-toolchain, and no
> new regression:
>
>       rv32i/  ilp32/ medlow
>    rv32iac/  ilp32/ medlow
>     rv32im/  ilp32/ medlow
>   rv32imac/  ilp32/ medlow
>  rv32imafc/ ilp32f/ medlow
>     rv64gc/  lp64d/ medlow
>   rv64imac/   lp64/ medlow
>
> Nelson Chu <nelson.chu1990@gmail.com> 於 2026年1月14日週三 上午11:28寫道:
> >
> > Okay, since this definitely helps the code size reduction, so LGTM.
> > Let me know if we already pass at least the gcc/binutils regressions
> > of riscv-gnu-toolchain in case of any accident, then I will commit ;)
> >
> > Thanks
> > Nelson
> >
> > On Mon, Jan 12, 2026 at 4:27 PM Kito Cheng via Binutils
> > <binutils@sourceware.org> wrote:
> > >
> > > When linker relaxation converts CALL (auipc+jalr, 8 bytes) to JAL
> > > (4 bytes), further relaxation to C.J or C.JAL (2 bytes) may become
> > > possible as code shrinks and jump distances decrease.
> > >
> > > This patch adds _bfd_riscv_relax_jal to perform this second-pass
> > > relaxation.  To enable this, we introduce R_RISCV_DELETE_AND_RELAX,
> > > a new internal relocation that combines piecewise deletion with
> > > preservation of relaxation capability.  When _bfd_riscv_relax_call
> > > relaxes CALL to JAL, it marks the deletion as R_RISCV_DELETE_AND_RELAX
> > > instead of R_RISCV_DELETE.  After the piecewise deletion is resolved,
> > > R_RISCV_DELETE_AND_RELAX is converted back to R_RISCV_RELAX at the
> > > JAL instruction offset, allowing _bfd_riscv_relax_jal to further
> > > relax JAL to C.J/C.JAL.
> > >
> > > C.JAL is only available on RV32 (rd=ra), while C.J is available on
> > > both RV32 and RV64 (rd=x0).
> > >
> > > Changes since v1:
> > > - Use R_RISCV_DELETE_AND_RELAX with piecewise deletion instead of
> > >   calling _riscv_relax_delete_immediate directly, to maintain
> > >   relaxation performance.
> > > - Add preserve_relax parameter to riscv_relax_delete_bytes to
> > >   simplify the logic in _bfd_riscv_relax_call.
> > > ---
> > >  bfd/elfnn-riscv.c                          | 130 ++++++++++++++++++---
> > >  bfd/elfxx-riscv.c                          |   3 +
> > >  include/elf/riscv.h                        |  13 ++-
> > >  ld/testsuite/ld-riscv-elf/j-to-cj-32.d     |  33 ++++++
> > >  ld/testsuite/ld-riscv-elf/j-to-cj-64.d     |  34 ++++++
> > >  ld/testsuite/ld-riscv-elf/j-to-cj.s        |  59 ++++++++++
> > >  ld/testsuite/ld-riscv-elf/jal-to-cjal.d    |  34 ++++++
> > >  ld/testsuite/ld-riscv-elf/jal-to-cjal.s    |  59 ++++++++++
> > >  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   3 +
> > >  9 files changed, 344 insertions(+), 24 deletions(-)
> > >  create mode 100644 ld/testsuite/ld-riscv-elf/j-to-cj-32.d
> > >  create mode 100644 ld/testsuite/ld-riscv-elf/j-to-cj-64.d
> > >  create mode 100644 ld/testsuite/ld-riscv-elf/j-to-cj.s
> > >  create mode 100644 ld/testsuite/ld-riscv-elf/jal-to-cjal.d
> > >  create mode 100644 ld/testsuite/ld-riscv-elf/jal-to-cjal.s


More information about the Binutils mailing list