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

    <tr>
        <th>Summary</th>
        <td>
            Interprocedural Register Allocation allows non-allocatable registers to be clobbered
        </td>
    </tr>

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

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

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

<pre>
    When Interprocedural Register Allocation is enabled, the elimination of callee-saved register saves in local functions (in `TargetFrameLowering::getCalleeSaves`) doesn't take account of non-allocatable registers (including link/return registers) that might still need to be saved by the callee.

In order to show up, this needs
  - no frame pointer
  - calls to local function (visible to IPRA, static) or libcall, and no other function calls.
  - ipra enabled

A fairly concise example is in:

```c
__attribute__((noinline)) static int leaf(int x) {
  return x * 31;
}

__attribute__((noinline)) static unsigned int mid(int x) {
    return leaf(x) + 2;
}

__attribute__((noinline)) int top(int x) {
    return mid(x) + 1;
}
```

Compiled with:

```bash
./build/bin/clang -S -O  t.c -mllvm -enable-ipra -fomit-frame-pointer
```

The function `mid`'s callee save set should include $ra to ensure return from mid `->` top, but the whole callee-save set is skipped and the `jr` loops.

```asm
mid:                                    # @mid
// ...
# %bb.0:                                # %entry
        jal     leaf
        nop
        jr      $ra
        addiu   $2, $2, 2
```

Proposed fix would be to retain written-but-non-allocatable registers in the save set in `TargetFrameLowering::getCalleeSaves` even when it meets the IPRA NoCSR criteria.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJydVV1vqzgQ_TXkZQRKIJ8PPKTpRqq02r1qr7SPlQ1DcGtsZJum_fc7Y5Kmkdp7u4sQCM9w5sycGVva-q38p0UDdyag652tsB6c0HCPB-VpCbZa20oEZQ0oD2iE1Fgn-Q5Ci4BadcqMVttAJbRGTL14wRrcGYE_PSgDDKShGUzFP3hI8jWtJsvpT-EOGPZOdPinPaJT5pAUW7ppdRcxHxiDPJN8A7VFb5J8FSCIZwRRVXYwgeMba1Ix8mWa7xROoSo91AQNWpnnJN87DIMzFyfGDq0I0KlDG8AHpTUYpFSCBYkwpiXfYuZjqlkyvU2m2_F5RzVwNSVM7r61Rxj6sU5UN4bxoxtASkSh4Wyht4oLf7EwrmeE62JxAi_KK86KjHc_7reM7QPVvmLi1lFakv_mdWFqjmGJqbtgROzsEkv1Trwr-iGRLTRCOf0GlTWV8iTzq-h6iqxYRlbmgzOLEu9q_H58FCE4JYeAj4_Emm5DSVLNkXgy1ZE0IQXQKJooTYBXNiWrmzO9kzqvlPkWillSnCzJ6vZj-G-HG4xXB0MCcrBO1V-EfQ98ojba8xvI_z8DjhNs_7uII6n3gJ-lfK71x_g72_WKFISjCu1X4kjh23Epo86Xg9I1v0nNfF9pQUORPkD6N0DIKkg7rV86SMfWSGObpI3tVEhj16ZXXfspqZ80IpfeXU45N57elT9NTpwm8Bh4VAbNsvB4IqU-p3DU42j84PBcnMbZjivEYGlS_EGvsaY7oMrHkTy2VuPHPSjCU8_6Z9X3VCCeCnakf58cA2hre599WjDhu3GFmRdRpt9dSV5AMo-pjlj5nm7IsnMEtucLKbPpNxBP3miCe7u0Cl9PtC_wFTv0ymKoINeu7gxGRb02ibpWw2jKuYrnd_4LVX8421tPlWzUKxyjbDLuRySSoK386FQIaFJSJP16LyZHVuGi0H88AwBf6MA68qmlaJQRg4-AvCnCX3b3cA8VESEIkU2wnC2Xs81iOV-uJ3VZ1JtiIyZBBY3ld848TuHof3GyjGdDpa2U6LCeDE6XbQi9Z_axAw40l4PMKtvRB0_W6ZVS6CesAn0q7wfKLd8vVvN1PmnLZdNM55t8UQixahqJq3m9aRZyNa3WRVMslxMtJGpfJoubZHE7UWU-zfPpupjN5sU8X2Xz2UIiTmdYiTXKjaS-xE4onXHgzLrDxJWRgxwOnoyasvEXo_Bxs8QzvhhCa11ZdTiJVMvI819ztoSW">