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

    <tr>
        <th>Summary</th>
        <td>
            [RISCV][LLD] Unable to resolve R_RISCV_ALIGN when mixing +C and -C object files
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lld,
            backend:RISC-V
      </td>
    </tr>

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

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

<pre>
    When linking object files which were generated with and without compressed instructions, we will sometimes fail to resolve a R_RISCV_ALIGN relocation. 

In assert builds, this results in an assert failure with the following message: `ld.lld: ../llvm-project/lld/ELF/Arch/RISCV.cpp:687: bool relax(lld::elf::InputSection&): Assertion `static_cast<int32_t>(remove) >= 0 && "R_RISCV_ALIGN needs expanding the content"' failed.
`
In non-assert builds, you sometimes get linker errors such as `"section size decrease is too large: 4294967472" `.  This is likely not the only symptom of the broken internal invariant implied by the assert above.  

Here's a small stand alone reproducer:
```
$ cat without-c.c

// Other is left undefined in the link.  Calls to this function are simply
// spacing to get the offsets just right
void other();

void __attribute__((noinline, aligned(32))) foo() {
  other();
 other();
  other();
  // LLD uses a compressed instruction for relaxing this call
  foo();
  other();
  return;
}

// It's the alignment of this function that we can not satisfy.
void __attribute__((noinline, aligned(32))) bar() {
  return;
}

$ cat with-c.c
// Contents of this file don't matter, we just need an object file
// with 'C' in the attributes

$ cat repo.sh 
CC="/home/preames/llvm-dev/build/bin/clang -target riscv64-unknown-linux-gnu"

rm *.o
$CC -c with-c.c -march=rv64gc -O3
#$CC -S with-c.c -march=rv64gc -O3

$CC -c without-c.c -march=rv64g -O3
#$CC -S without-c.c -march=rv64g -O3
/home/preames/llvm-dev/build/bin/ld.lld with-c.o without-c.o --shared

```

I believe the root issue here is that we're enabling call relaxation based on whether *any* object file in the link had compressed enabled, not whether the object file corresponding to the section being processed does.  The following diff seems to fix at least my motivating case, but I don't know if this is a full fix or not.  

```
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index d0d75118e30d..ebbc9601ebf3 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -589,7 +589,7 @@ static void initSymbolAnchors() {
 // Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal.
 static void relaxCall(const InputSection &sec, size_t i, uint64_t loc,
                       Relocation &r, uint32_t &remove) {
-  const bool rvc = config->eflags & EF_RISCV_RVC;
+  const bool rvc = getEFlags(sec.file) & EF_RISCV_RVC;
   const Symbol &sym = *r.sym;
   const uint64_t insnPair = read64le(sec.content().data() + r.offset);
   const uint32_t rd = extractBits(insnPair, 32 + 11, 32 + 7);

```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykV0tv4zrS_TX0piBBoWTJXnjhR_x9AYK5F-k7PUuDokoWE4o0SMqJ59cPirIdp5NG7mAaRkcP6rAep04VhfdqbxAXbLpi081EDKGzbnFwKHr0k9o2p8W_OjSglXlRZg-2fkYZoFUaPbx2Snbwig5hjwadCNjAqwodCDNe2CGAtP3BoffYgDI-uEEGZY1nfA2vCK9Ka_C2x6B69NAKpSFYcOitPiIIeNo9PfxY_9wtHx_-7x_gUFspCCAFlm1Ythz_fzAgvEcXoB6UbiJ66JQnoEEHD8qAuK6hXQaHo62hQ2it1vaVHOzRe7FHli-BlZluUq0buklTxrdaH_vk4CzFIN42jG_vH7eMb5dOdoxvo62pPBxYvixnFX1ZW6vJbvHG-GxEY_kSdTtePJjDEH5gDArjJeNz-mgZDVXWkBU-iKDkTgofWL5WJuR8F1h-z_jMYW-PyPgc6D7fQAYRpATG-cfQGcTGA74dhGnIU_JbWhPQBMY541UMCzbpOa5ldg2tsSb5FN6THW4St8cQSYIO0DnrPPhBdiA8OcA496OH4NW_ERqUDoVHUB6CtaCFG0Ne8HkxL6ui4oxz-jIF-IvSqDxo9YL6BMaGaLo1-gT-1B-C7cG28Vnt7AsaUCagM0KDMkfhlDABVH_QChuoT3Hh2RlR2yOm8IFJ_48OGa88CPC9IHIGYrPQ1iA4PDjbDBIdJe8ap_E33vICpAgX9icylbfojBNZ4I_QoYtOYRtgMA22ysQCieZRIFOAtdCaAjQyuR3MGELhEDw5dPqA6Q9CxrzamIwYo7b1GDw8Dz6AU_sujF8crWrAkg2MzyLjVrdGxte7nQjBqXoIuNvFZTNjldHKIGVfaBKOhvFZzgkh_qC1dkQEVp0h4cuNvn74m6dnBx8fNzB4pMx8rSnQWjdW2shv5UEKrS8wV-O-3dBhGJx5j0q1-SKHDyHSJNKJgtGjCSMRb5MVOiIDghQmUteLoHx7Sv_XSNfCfY70d3a_U_OGl6M361EJ_LsHSiM0pElVgF6EQHGKkh3ZRGpCinrTED7gRWllvFqTsJxpfXXTf2WWw4NNfXcuxvWa5ZuoS9vO9sj49tyULjLc4JHxbZQj-qsM41uphdlDEkhOiPBeHssiGcyLsa8m0coMb8neDAR7Y4DrgfFlaq_mrNeQyGuYIOkFiXu-ccey2EtI_sgvS_Pz6h9_Z_Vn-LNA_PLN7zf4fv1_Eayxt10MtzcbWEgS3wmHzQfLfxG6sTlAjVrhEWOCnbUBlPcDQkdTAcn7yH_GK4eARtSaapPKcqzU2MuhFlTK1sBrh1EaGV8Kc2J8eUuwW3mETjS3MhChqUrWscwuOFEFbxCkdQ79wZ5boI0LLr2pRnp4cFaOmI1FHxvQ7YDQqLYFj9hHZW7VG4gAGoUP0J-gt0EdRRh99LF-6yHAw7WSiIqgzjWmSMvaQeuIYx2Z_ks7-iXqcfck2asA4psJBOrvRpSIqEyDb9BkTTW9u5thnjVpinUt52V2h3Wbw12WlUUxLk6S5Nt9L1Rcjb-_aQYrMlZkkExnc8bXFTC-ul6Or8YpCKJkKqPCj1NfW700srPOf9LCsww9EceuM-R6-fhIW9_c7v58_AvEoA6S8dWz0I6yKtNnypxMn4WmC-vgWeizZn8wJHKY-jTjM2mND3A7z9Es5lESBM09uwCKrgdlQlnsAmhL7y7q_eW_p-vAS2Du8jlNgPHB-_x3cT0BGC0ZB8-jBJoLpTWt2icsv8dWi72nj-F-e47E08_1e9fgqy8R9hjut_Qp4zOPMo2STxv_DgguMGOmYjBOfcRifOlSf-o_r73GRhlv_hTKxfUORVMWtF_c-jq2UtLTRgRxyT9fgUvHsedjS7-Bj7FzTQTGt-CEDCsVyK3LnhTlnEe0u7ubm-rzrHStz0mzyJt5PhcTXNyVs3k159l0OukWVc35vK6LaVZVRd3mszprptN8WjYzbMp8OlELnvE8q-7md7Mim05TbEo-q-e1LEuRVbxgRYa9UDolLU-t20-ixi7KfF4WEy1q1D6e4DiPhcaJVJzXQr6gofMG5Sb5SS-mm4lbxJZQD3vPikwrH_w7cFBBx9NgTCebbth09fi4YdMN_DMq7O3h7OP54pXOib2Ksxfjq3U8BCbrD0fGyeD0ogvh4Gl-jiW6V6Eb6lTa_tysPp-zorfUy6LD_wkAAP__z3mB_g">