<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/202147>202147</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [RISC-V][lld] ld.lld emit relocs relax unimplemented (before LLVM 15)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lld
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          XiaobingHou1219
      </td>
    </tr>
</table>

<pre>
    I ran into this while reducing a RISC-V linker testcase. The reproducer is small, and I have been seeing the same result consistently across three reruns.

### Summary
ld.lld 14.0.6 rejects the legal input at link time with relocation R_RISCV_ALIGN requires unimplemented linker relaxation; recompile with -mno-relax. ld.lld 15.0.7 and 22.1.0 accept the same input.

### Expected behavior
Link a tiny RV64 executable with two relaxable call sites and a trailing alignment marker under --emit-relocs, so the linker must both relax and rewrite final relocations.

### Environment
- linker route: llvm-mc 22 plus ld.lld version replay
- march: rv64i
- mabi: lp64
- first failing stage: link
- local stability check: True

### Reduced testcase
These are the reduced input files from the minimized reproducer I used locally:

#### `case.s`
```asm
# REQUIRES: riscv
## Test that we can handle --emit-relocs while relaxing.

# RUN: rm -rf %t && mkdir %t && cd %t

# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax %s -o 32.o -riscv-align-rvc=0
# RUN: ld.lld -Ttext=0x10000 --emit-relocs 32.o -o 32
# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 32 | FileCheck %s

# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s -o 64.o -riscv-align-rvc=0
# RUN: ld.lld -Ttext=0x10000 --emit-relocs 64.o -o 64
# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 64 | FileCheck %s

## -r should keep original relocations.
# RUN: ld.lld -r 64.o -o 64.r
# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 64.r | FileCheck %s --check-prefix=CHECKR

## --no-relax should keep original relocations.
# RUN: ld.lld --emit-relocs --no-relax 64.o -o 64.norelax
# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 64.norelax | FileCheck %s --check-prefix=CHECKNORELAX

# CHECK: <_start>:
# CHECK-NEXT:     jal ra, 0x10008 <f>
# CHECK-NEXT: R_RISCV_JAL f
# CHECK-NEXT:         R_RISCV_RELAX *ABS*
# CHECK-NEXT: jal ra, 0x10008 <f>
# CHECK-NEXT:         R_RISCV_JAL f
# CHECK-NEXT: R_RISCV_RELAX *ABS*
# CHECK-EMPTY:
# CHECK-NEXT: <f>:
# CHECK-NEXT:     jalr zero, 0x0(ra)
# CHECK-NEXT:         R_RISCV_ALIGN *ABS*+0x4

# CHECKR:      <_start>:
# CHECKR-NEXT:     auipc ra, 0x0
# CHECKR-NEXT:         R_RISCV_CALL_PLT f
# CHECKR-NEXT: R_RISCV_RELAX *ABS*
# CHECKR-NEXT:     jalr ra, 0x0(ra)
# CHECKR-NEXT: auipc ra, 0x0
# CHECKR-NEXT:         R_RISCV_CALL_PLT f
# CHECKR-NEXT:         R_RISCV_RELAX *ABS*
# CHECKR-NEXT:     jalr ra, 0x0(ra)
# CHECKR-NEXT:     addi zero, zero, 0x0
# CHECKR-NEXT: R_RISCV_ALIGN *ABS*+0x4
# CHECKR-EMPTY:
# CHECKR-NEXT: <f>:
# CHECKR-NEXT:     jalr zero, 0x0(ra)

# CHECKNORELAX: <_start>:
# CHECKNORELAX-NEXT:     auipc ra, 0x0
# CHECKNORELAX-NEXT: R_RISCV_CALL_PLT f
# CHECKNORELAX-NEXT:         R_RISCV_RELAX *ABS*
# CHECKNORELAX-NEXT:     jalr ra, 0x10(ra)
# CHECKNORELAX-NEXT: auipc ra, 0x0
# CHECKNORELAX-NEXT:         R_RISCV_CALL_PLT f
# CHECKNORELAX-NEXT:         R_RISCV_RELAX *ABS*
# CHECKNORELAX-NEXT: jalr ra, 0x8(ra)
# CHECKNORELAX-EMPTY:
# CHECKNORELAX-NEXT: <f>:
# CHECKNORELAX-NEXT:     jalr zero, 0x0(ra)
# CHECKNORELAX-NEXT: R_RISCV_ALIGN *ABS*+0x4

.global _start
_start:
  call f
 call f
  .balign 8
f:
  ret
```

### Reproduction notes
- This packaged root does not have a single canonical `run.ps1` wrapper.
- Use the reduced inputs under `case/` and follow the commands documented in `case/README.md`.
- Stable witness outputs, when present, are preserved under `verify/run1..run3/`.

### What I checked
- Reduced inputs are preserved under case/.
- Stable witness outputs are preserved under verify/run1..run3/.
- The strict recheck says stable normalized run signatures across three runs: True.
- Tracker guidance link: https://llvm.org/docs/HowToSubmitABug.html
- evidence summary: 3 clean reproductions under hunt/verify/lld_emit_relocs_relax_unimplemented_before_15/run1..run3 show stable assembly success for 64.o, stable 14.0.6 link-time rejection on R_RISCV_ALIGN, and stable 15/22 successful links with objdump outputs materialized in 64.15.objdump.txt and 64.22.objdump.txt.

### Notes
upstream////llvm-project//lld//test//ELF//riscv-relax-emit-relocs.s and LLVM 18.1.0 lld release notes

Root key: `lld.riscv.emit_relocs_relax_unimplemented_before_15`
Case id: `20260527-lld-emit-relocs-relax-unimplemented`

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0WFtz4joS_jXmpcsuX8CBBx4IkD3ZZWbPEmZ29omS7QZrIkteSeZyfv2WZJvbQEhqsimKiuW-fP11S6ibKEXXHHHo9B6d3qRDKp0LOfxBiUgoX_8hqiAMBp1EZPvhM0jCgXItQOdUwTanDEFiVqWUr4HA_Pll7H4HRvkrStCodEoUerDIjVgpRValKIEqUAVhzAnHQHgGz5CTDUKCyEEhGls6R1CkMGqqYhpSwRVVGrlmeyCpFEqBziUaAVlx5Tn-xPFHzXcY1R94qYqCyH29zDKPsQyCrud7MUj8ialW1hPDNWFAeVlpINriB00LhC3VOUhkIiWaCg7zpQnx-3I0e_7bV5D434pKVFBxWpQMC-QaszZ8iYzsrJoTPYLEVBSl4cvadAsuXCvhQYur5_negyUkDL3A84GkKZb6yIUFeCPS6a7E1HhPMCcbKmQtMDOhENCU72H-Pe4C7jCtNElaIHorGqRmKSWMgaIalcVBQEtCmU0uo2tuAoSCSBNexTOU4LpYUO1aipTJpxI1ozUHRaU0JKImkeysUYlbSTXCinLCTsi9lcMp31AprO_6lXtgWFQanWgEjG0Kt0ghDKFklWoZ3aBUJmsSS0b2rXJBZJobLbmJu_S4mlBrqoy77dqKSqVh1TCgNFnX3ih_PSARKWHmVUIZ1XtIc0xfjdBCVng9nrnZL5gdtkf9fpGjQiASLX2ykalLckUZKlhJUdiXBeW0oH9hdrqnnqFSpvYMHrZ3otFV58a_E_t2Vyon9pvXsV9_iCoOCjCf_uvb83z6YqmiKt2c2oIFKlOZRMPWlA2HnPCM4XlBHE4IRnaUry8TDPNvX631Aly5AifsaXDC2AljKF4zKs9W0sw-3jDRVoBruNL7Ep1oIpKf4GpJS2aebAhRCG5BtJZONHHCx7oonbCnwBUQhZ4A18q5ttxduUmdaOL_6q2uL3ehcaeNxC7wfd-_CL62Z-xehyuSn1lVlOBmZh9x4apcbF1Jti7lioP7BbgwQIhCYwychzE8UYZjU2MW9e-REXffICPufi4ZtT1j9xPIiLv3yTAOXAkqFxXL4BWxBCHp-tah82s88gSzJz8FtSev4AbXtaeGW0pc0Z0TTcZ_TMf_mF-Lx21_NX4jrrO0nFg8iZYLu_Q5MTfG3h_513_Op7PRj8vitu8MCicaL5UmUjvR9HjQtRLu1-mPhREzfz8NKcT8LtVV2TfKK6N3Q6n9gf_7aAartyybv1bYwgUnHI0eX5zwJqAPg7n08yaod4KZfvlz8Z83WGsh3eVVwl8oRR2N74R9E9ngvZHU96cjyPDR33WvJnx-UH877fMzX6SiZXog239T9hTXeDSbLf-cLX6hef5Bnue_0nVEc52so8r_Ef3HSve3orB5yDJ6qJPTernH7lsFctS6Uczz-9V8JbLb5Xyu2h5Pd0-iRvADhXmpcTex11y8P73XtM-SHNzK8qXmx8J6d91-bnhnofXvRHajtC5t3iywm9zePzVvVcHdQ9NbM5EQBk1N2rW2PhsRqFu8hujzB_ASe9ODfr2wOtGSqC96hVvNTd2R2G6ZC42q7ZQWOVVQkvSVrE3nIoSGTKAyQnX7T0BRvrZNKBecmr7KiX1Zca9UgRP7sJWkLFF6rcVv6kqzpJrGtOlynPDJqJq-cyUYE1urkYqiIDxTkIm0arp2yk905tPR5MvUKzIn9g_-Xg5tM0elQFTa-DO53ObIoZSoTI8ajm0bZx_lBrMjoA1Kuto74ZOseOB5suJRje9G5_tv01491z0lZi2M-Xm413w1UdxBflX1OkbvmEUEpSVNNUi0wECRvbIdMEPgQhaE1b1pxUHRNSe6kqguZjYVV22TfDQtSWq6-nVFM8LTeoZgpHKtSyNuuAqfzB3UE3LthE-ZnTk8_SG2C_FSJQXVo8dq7eW6YK1R3NAMjTHVTIKiEUSQMiT80D3b-3ITfl6ZDD4dWGAsW5r78rK-Ly_tVXZ5Nu9ZJrgSEpdB74w1c0PftrwQpbBI2B5UlaYmBStRtxd2ZFLLNHMpE7Vrh0_1hMpspMvJUzs4azWN5zBsja8qZq2oesLT3tfbrBdEo6RNlig3MIKe10h5eqet6bjrheHp6o0a_Xrc41WptERS1Hk6ZsstpTCRtCtZ_Y9G1SxNZ4103W5ajk-7FK-eRs1m379A0LejMdPJSGRIFJ4eM_X33Bwur2iT7cQ-Y5lnLXvvz2R7vo2NA5o1lkI_jP1e-OAylp0CbCCfGTuY6GTDKBtEA9LBYfDQ9_tRHMdBJx8GQX8V9HrdftzL-inxI-ylZDDoreJBmmQxdujQOoz9hyDsBX7ghYNkEHQHyQpx1Y_irtP1sSCUee2m6FClKjRqQfehw0iCTNnJbhha3kOnN-nIoc1KUq2V0_UZVVodDWiqmR0G17Ncpzdxeo9GtzdpO0gTODT9Y93anc8_nbBfE9lkrOeEg04l2fB8I6-pzqvES0XR1Mmv5WKjMVu8CWgzDP8XAAD__8retB4">