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

    <tr>
        <th>Summary</th>
        <td>
            [RISC-V][lld] ld.lld variant cc flags not preserved in relocatable output (before LLVM 16)
        </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/15.0.7 keep the R_RISCV_CALL_PLT relocation set but drop every [VARIANT_CC] symbol marking from the relocatable output. ld.lld 16.0.6+ preserve the symbol flags correctly.

### Expected behavior
Partially link two ordinary RV64 objects carrying a mix of variant-cc and non-variant-cc local, hidden, global, and IFUNC symbols.

### Environment
- linker route: llvm-mc 22 plus ld.lld version replay with GNU ld semantic control
- 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:

#### `variant_cc-1.s`
```asm
.text

.variant_cc cc_global_default_def
.variant_cc cc_global_default_undef
.variant_cc cc_global_default_ifunc
.variant_cc cc_global_hidden_def
.variant_cc cc_global_hidden_ifunc
.variant_cc cc_local
.variant_cc cc_local_ifunc

.global cc_global_default_def
.global cc_global_default_undef
.global cc_global_default_ifunc
.global cc_global_hidden_def
.global cc_global_hidden_ifunc
.global nocc_global_default_def
.global nocc_global_default_undef
.global nocc_global_default_ifunc
.global nocc_global_hidden_def
.global nocc_global_hidden_ifunc

.hidden cc_global_hidden_def
.hidden cc_global_hidden_ifunc
.hidden nocc_global_hidden_def
.hidden nocc_global_hidden_ifunc

.type cc_global_default_ifunc, %gnu_indirect_function
.type cc_global_hidden_ifunc, %gnu_indirect_function
.type cc_local_ifunc, %gnu_indirect_function
.type nocc_global_default_ifunc, %gnu_indirect_function
.type nocc_global_hidden_ifunc, %gnu_indirect_function
.type nocc_local_ifunc, %gnu_indirect_function

cc_global_default_def:
# cc_global_default_undef:
cc_global_hidden_def:
cc_global_default_ifunc:
cc_global_hidden_ifunc:
cc_local:
cc_local_ifunc:
nocc_global_default_def:
# nocc_global_default_undef:
nocc_global_hidden_def:
nocc_global_default_ifunc:
nocc_global_hidden_ifunc:
nocc_local:
nocc_local_ifunc:
        call cc_global_default_def
        call cc_global_default_undef
        call cc_global_hidden_def
        call cc_global_default_ifunc
        call cc_global_hidden_ifunc
        call cc_local
        call cc_local_ifunc
        call nocc_global_default_def
        call nocc_global_default_undef
        call nocc_global_hidden_def
        call nocc_global_default_ifunc
        call nocc_global_hidden_ifunc
        call nocc_local
        call nocc_local_ifunc
```

#### `variant_cc-2.s`
```asm
.text

.variant_cc cc_global_default_def
.variant_cc cc_global_default_undef
.variant_cc cc_global_default_ifunc
.variant_cc cc_global_hidden_def
.variant_cc cc_global_hidden_ifunc
.variant_cc cc_local2
.variant_cc cc_local2_ifunc

.global cc_global_default_def
.global cc_global_default_undef
.global cc_global_default_ifunc
.global cc_global_hidden_def
.global cc_global_hidden_ifunc
.global nocc_global_default_def
.global nocc_global_default_undef
.global nocc_global_default_ifunc
.global nocc_global_hidden_def
.global nocc_global_hidden_ifunc

.hidden cc_global_hidden_def
.hidden cc_global_hidden_ifunc
.hidden nocc_global_hidden_def
.hidden nocc_global_hidden_ifunc

# .type cc_global_default_ifunc, %gnu_indirect_function
# .type cc_global_hidden_ifunc, %gnu_indirect_function
.type cc_local2_ifunc, %gnu_indirect_function
# .type nocc_global_default_ifunc, %gnu_indirect_function
# .type nocc_global_hidden_ifunc, %gnu_indirect_function
.type nocc_local2_ifunc, %gnu_indirect_function

# cc_global_default_def:
# cc_global_default_undef:
# cc_global_hidden_def:
# cc_global_default_ifunc:
# cc_global_hidden_ifunc:
cc_local2:
cc_local2_ifunc:
# nocc_global_default_def:
# nocc_global_default_undef:
# nocc_global_hidden_def:
# nocc_global_default_ifunc:
# nocc_global_hidden_ifunc:
nocc_local2:
nocc_local2_ifunc:
        call cc_global_default_def
        call cc_global_default_undef
        call cc_global_hidden_def
        call cc_global_default_ifunc
        call cc_global_hidden_ifunc
        call cc_local2
        call cc_local2_ifunc
        call nocc_global_default_def
        call nocc_global_default_undef
        call nocc_global_hidden_def
        call nocc_global_default_ifunc
        call nocc_global_hidden_ifunc
        call nocc_local2
        call nocc_local2_ifunc
```

### 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_variant_cc_flags_not_preserved_in_relocatable_output_before_16/run1..run3 show stable assembly success for variant_cc-1.o and variant_cc-2.o, stable 14/15 relocatable outputs whose r.14.readelf.txt and r.15.readelf.txt contain 24 R_RISCV_CALL_PLT relocations but zero [VARIANT_CC] markings, and stable 16/21 outputs whose readelf files preserve the expected [VARIANT_CC] markings on local, hidden, global, and IFUNC symbols.

### Notes
upstream////binutils-gdb//ld//testsuite//ld-riscv-elf//variant_cc-r.d

Root key: `lld.riscv.variant_cc_flags_not_preserved_in_relocatable_output_before_16`
Case id: `20260527-lld-variant-cc-relocatable-flags-not-preserved`

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWV9v4rgW_zTh5YiIBEjbBx5oO71bqTtaMZ3e-4Yc-0C8dezIf2DYT3_lOEAoCe1s92k1Emoq-5yfzz-fHP1CjOFriTiLprfR9H5AnC2Unv2PE5Vzuf5NuSRNbga5YrvZI2gigUurwBbcwLbgAkEjc5TLNRBYPH67G76A4PIVNVg0lhKDMTwXXqzSijmKGrgBUxIhovQOiGTwCAXZIOSIEgyix7IFgiGlVzNOWKBKGm4sSit2QKhWxoAtNHoB7aSJo9F9NJo3f9Nx-ME3V5ZE78KyYLEQDJJJPIqzKH1IpvEovoJXxKo-b7H09r8s7-ZPT8s_np5Bo1CUWK68WRZyZ4FpVQFuUO8gmt6-zBeP86_Py7u7aHoPZlfmSkBJ9Kt3YaVVWeM2MCQXCMrZytkY9rZkwZZbqDQa1BsMngeklSBrA1RpjdSKXY-PX35USC0yyLEgG650EPiDaMuJELs6HWC3CpRmXBK9g8VLNgGV_4nUGqBE613IX8l_gFrBhmhOpB1SWqdHKjlsLXln6tQVnDGU_r-1UDk5pvPh-9e7xoe-xHyRG66VLFHasDXcV41WzmI0noMQm3JYUkhTqIQz-5BtUBufEY2VIDvYclvAf75-B8HAYEmk5dRXi9VK7JFLomnhIfUmm_Djas7rc6pssl9bcW0srAgXPiDGknUwhcvXg5nefb-Vc8HtDmiB9NULPWuH3c4u_A1BdrgQYf-5QINANDZFEmS4rJyFFRdojhVUcslL_hey9i16BGeQBXvELhrPOw_350fZqMnfktJhEpsoGzVi2Sj8iCnDSmzxh20jxUdVoHQZUr1kuCJOWP_8iJiTHxTkKyfpJcFQdO-d20j1o4Ui7t1pazZSAfliCHpF2u73CrWNPRM6c7tPogNFqg8Y3SXUYXaX2DtH9pneIXMe9bBxKRB9Em2rGpmLVvXLnFtldxX2ZjC9gyidrqVbcsm4b91Lv-5fI93qJ8d8XLtdqB_U6s_e3wD4O2bX-j9lePjbXcDjY7PrvXTjM4RW5s83T6PSq3y2HfrJ24U3cn0Xse1H_z3sQunwpT_HFwA6BE49Okvc8XVz498_l_piv0irwZwLvb2h_TAnF7QHplum9Rp4u9qlcbGTXhLqcPRSM7oE9Y5Z_e62stqzfqK1nww-OFWkv6aKJorpha1fc8WvuaLfKn-rPjlbdEF8Zr5If_7gTwwZ3SCfGzQ-7sGFWeJnp41TmY63dDfIm1drF0j35JGer3SA_TPzx1upHu_en0N6gPpmkbRr7d83jaQ9y__ieSTt3fj4RAKLhhmp6TqpLJogMYTnghuoCH0la2SglbLAFBovFIhHAobLtUCgRCrJKRF-uNFOxpVJomwEW02qCnW8R_xuOkgbAz6q2qvWJE_64FWJZLBSQqhtrUFVWRLJDDBFXYnS1totncWX-f3vX-KSRdnocN63QB5uuZVoTEMiGt_StgXKwB1KW_NvGg9UIjsatEHNV7sofdBOJnGsnRwH-3rouf8WxMJj4LaQ7c1YnLrbdVbjxTuWd6p22xgfs4hgrObUgsbaMDBkZ2omTviGr0siAkfmJBi-lsQ6jeYNW-yk2ZN1R2hN6CtqWDvOiKQY-L7xHAprKy_uY5U-CLEpY6XXUfrAFDVR-vCb2j6rby4vuZ3funVc2PJAOuKGM_RgpuGgx3MYAxVI5IHF87W6L5vC-Qw-HKIgBFseR8hlzQUvpbLLQ9yWXC5b3PIyBHeZ40ppXCbZSSjBFGq7DxYxBstc7MA4Sn1eVkrDCUWo6sI9me-Vr68GIJnU_HkHtW1gWyiDoONkEmskDMUqtj9sjafjZHqySJW0hEtIJ5fYd1NT73-hVueke8O2mz35vDfQe58mb40KRzf06gnljnsWvfcEUPKf4b6_HpuTq4zVSMpQYOGXc-ksF2a4ZnlTeCw8LRprHLe4Xx5qbuhmiGIVVlr50jFrn77wXe8V6yqMspEQLK5140-W2L4b3xGDwFkDn47SbDRNr4ZCsNang2ELalifNpTKDg-nHdAGbDZmN-MbMsBZcnU9uh5nV1fjQTG7GU-v6PSKYJZM0uQ6S_IJuZ5OVilJxhnmyYDP6rOz0VWSTtPpOCYjlq3IdJSwLM1XWRJNRlgSLuL9bR5wYxx6tSRLB4LkKEz9MSxNhQ98Gk3vB3pWf43I3dpEk5HgxpojgOVW1N_PwuevaHofTW-97vT-8NEixAAobT7q-HfPsQFy2XGTIEqvQ6Dh6enl97qkbwZOi9lpW1pzW7g8pqpselTzGFZa_YnUN5XaRd-wGi83s_T_AQAA__-TxmYa">