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

    <tr>
        <th>Summary</th>
        <td>
            -ffixed-reg option not respected in function prolog/epilog
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    The -ffixed-reg flag conflicts with the aarch64 ABI's callee saved register list, causing code such as
```c
void f(void) {
  register long x28 asm("x28") = 0xee;
  asm volatile("" : "+r"(x28)); // avoid mov being eliminated
}
```
compiled with -ffixed-x28 to generate prologs that save x28. This is a problem because as per `man gcc` codegen should not touch it:
```
-ffixed-reg
    Treat the register named reg as a fixed register; generated code should never refer to it (except perhaps as a stack pointer, frame pointer or in  some other
    fixed role).

    reg must be the name of a register.  The register names accepted are machine-specific and are defined in the "REGISTER_NAMES" macro in the machine description
    macro file.
```
and indeed with aarch64-linux-gnu-gcc, the above code simply generates a `mov x28,#0xee` whereas with clang -target aarch64-linux-gnu, it generates
```asm
0000000000000000 <f>:
       0: f81f0ffc      str x28, [sp, #-0x10]!
       4: 52801ddc      mov     w28, #0xee // =238
       8: f84107fc      ldr     x28, [sp], #0x10
       c: d65f03c0      ret
```
which saves and restores x28 as per the ABI, but breaking the flag's guarantees and diverging from gcc's behavior. Established projects such as Cosmopolitan (https://github.com/jart/cosmopolitan/blob/85c58be94279f9a6b8d6e57ca13d3b4912a82042/libc/runtime/set_tls.c#L64) depend on gcc's behavior, which leads me to believe this is a bug in LLVM.

The behavior is also the same with riscv64-linux-gnu.

While using inline assembly to circumvent this is possible, I believe it should be fixed to prevent future bugs in other projects.

It seems like AArch64RegisterInfo::isReservedReg(MachineFrameInfo, Reg) and Subtarget.isXRegisterReserved(MRI->getDwarfRegNum(Reg, false)) both become true when -ffixed-reg is specified and they should be respected when generating epilogs from what I can tell from the codebase, but I don't want to get overzealous with my observations.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx8Vktv4zgS_jX0pWBDpixbPviQOPEiQPcc0sHu3gZ8lCROU6RBUnKyv35RlOzEPY0Rgkjm4-NXr68oYjStQzyw6pFVTwsxpM6Hg-rwIqTF9GHRebuQXn8c3jqEZdOYd9TLgC00VrSgvGusUSnCxaQOUocgRFDddgMPjy-M7yIoYS0iRDGihoCtiQkDWBMT40dQYojGEZBGiIPqQERWPLHigW2L6U9Nv0dvNDSM1_TB-B7Y7nGagS-w3rXwzmsQsWe8Zpy_5_95ffkExTsiK2_7ROxh9FYkY5HNCzmw8gHy52PIrzpj7OmvfATGT4yfQGQ-vR9BIhmA1vTGiYR6pr97-sWO6afy_dlY1JPDrg4lyslDiw6DSAjn4K1vI6ROpOw6MmoFb52JYCIIWiAt9iCRPIggIpwxANsWvXDQKsW2RXZqiw5i5werwfkEyZOPTWLlw2_pfYnw1UkAbwFFysG9OdqJfgonnSwgb7rNkpuupug5tDMFHDFAwAYD2WsSMF7ju8JzIv6dOMcJMCahfsLZG0d4_AhNED1eB8AHMA4g-h7Bpw7DJ9mZiqeI7lezkbdZYtwPMYHEbBDZAb4BcSO_Anj71dIIQhFH1CACQi9UZxwu4xmVaYwC4aYJjY1xqIkbgTPOX5__9fLj7fn1zz8evj__oOzqhQr-umJGAo1RBXNOxrtPrtPKxlhc_TZWdKpxGq_JNFfe0ho3vC9bNywpD_hxKkvpR5xjYfqz_bhFiNxNeeNHyIl-ZLzMdbIt4NJhQDFXt7LCtbBMIrSY_n4anWTSJ-wvnKki80jxywOsPDasfL6lJExPQXXY1OumaBo1DcUUZo7Aqsd4zh-8XBbv64JVT4yv7xA2hFDxulhrPSOQlfRcZpTJ1GtRs_KJl_UdRj2x2KyL3ZWF1SG_75jQ6TPeurhDUISgt1VTlKqYhgKm30b00hnV5XqPOacCxuQDxlnScolTMLO2HkEOCWRA8ZMEiMZJk7PotoMIwiWccbQZMbS0qgm-z_JAqyR2YjQ-rOA5JiGtiR1qkpa_kCR9lmM4-tj7s7cmCUf12qV0jhSt7LTWpG6QK-V7xk9_iZAYP6kvOxg_Sesl46e6UlUtcb_hu32zF1tZ6y1WOyXWpS7lZr_moubFhjN-skYqxk9hcMn0yPgpYvoz2bhSjJffthvSc41ndBq8-5s95JvJlRaFjtAjiY1Ea3Cksr-KqBxaKsRv3_79_U4oqP6vWHmljT77N5Ja5FoIJqrxa_bfAfynMxZh6mzGWapwESP20n4QE2WCGvoRXbqROfsYjSTNOsLLjapJV-GUOAtb8nAOmPc2QxoCkhWRzMg6eIveHZ-XBBGxj2DNT4SHh1y5r7PCvbjGUzTLBxNfMWIYUb9iy3j9fVKnE0lvXsWPkGf2Oat-DHLSgpWJ_72iXRFo--vLkpXPLaaniwjNK7Z_DNSVM8QRGmEjTn0VpE8d9TLS8xQGJOFxd9cNE2GWWxJhpykeH1-8E5CmSaHz1lmFcmc-m9xLc-pfqKG-gBIOElo7DVJoSRmliHitqxfQ3jG-S3ARFCdqzgn8iOF_KKwfZk3sP8BLsliQdl-9vtCHUu_LvVjgYb3jdVnsy6pcdAchZbFTqKtys8N6iztdc6V2WDV7We5FvTAHXvDNuih267KqqnK1qyqpNprLUu9Uvd-wTYG9MHZl7divfGgXJsYBD-v1utztF1ZItDHf5zh3eIE8S9eY6mkRDrRpSQnDNgVdweInTDLJ4uGry33uR_na8Old46AZnMoz0y2F8dPk4sUQ7OEfxIGOml_LOU0ZP2WCkfHTbMF44P8PAAD__ygKXiA">