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

    <tr>
        <th>Summary</th>
        <td>
            [IPRA][RISCV] ra save/restore unexpectedly optimised out of function
        </td>
    </tr>

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

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

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

<pre>
    This was found as part of an effort to evaluate if it would be beneficial to enable IPRA for RISC-V. The issue can be seen in SPEC (built with a hack to disable the MachineOutliner to workaround #119556), but a reduced example from the GCC torture suite is used in this bug report.

Tested ipra on top of `99bd2e3f123baf9a14acc9b31ee0f557288118a6` (28th Jan)

A reduced example of the problem based on 20090113-3.c in the GCC  torture suite is below:

```
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

%struct.bitmap_iterator = type { ptr, ptr, i32, i64 }

define i32 @main() nounwind {
entry:
  call void @foobar(ptr null)
  ret i32 0
}

define internal void @foobar(ptr %live_throughout.0.val) norecurse nounwind {
entry:
  %rsi = alloca %struct.bitmap_iterator, align 8
  %regno = alloca i32, i32 0, align 4
 call void @bmp_iter_set_init(ptr %rsi, ptr %live_throughout.0.val, ptr %regno)
  ret void
}

declare void @bmp_iter_set_init(ptr, ptr, ptr)
```
Removing the norecurse attribute from foobar "fixes" the bad compile.

Reproduce with `llc -enable-ipra < tc.ll`

foobar ends up with liveins: `$x10` for the bad compile but liveins: `$x10, $x1` for the good one, and the regmask for the call to foobar doesn't have `$x1` in it for the bad compile.

The generated assembly for `-enable-ipra` (note that `foobar` calls another function but doesn't save/restore `ra` around it):

```
        .attribute      4, 16
        .attribute      5, "rv64i2p1"
        .file   "<stdin>"
        .text
        .globl  main # -- Begin function main
        .p2align        2
        .type   main,@function
main: # @main
# %bb.0:                                # %entry
        addi    sp, sp, -16
        sd      ra, 8(sp)                       # 8-byte Folded Spill
        li      a0, 0
        call    foobar
        li      a0, 0
        ld      ra, 8(sp) # 8-byte Folded Reload
        addi    sp, sp, 16
        ret
.Lfunc_end0:
        .size   main, .Lfunc_end0-main
 # -- End function
        .p2align        2 # -- Begin function foobar
        .type   foobar,@function
foobar: # @foobar
# %bb.0:                                # %entry
        addi    sp, sp, -48
        mv      a1, a0
        addi    a0, sp, 16
        addi    a2, sp, 12
        call    bmp_iter_set_init
        addi    sp, sp, 48
        ret
.Lfunc_end1:
        .size   foobar, .Lfunc_end1-foobar
 # -- End function
        .section        ".note.GNU-stack","",@progbits
```


The generated assembly without `-enable-ipra` (note the save/restore of `ra` in `foobar`):
```
        .attribute      4, 16
        .attribute      5, "rv64i2p1"
        .file   "<stdin>"
        .text
        .globl  main # -- Begin function main
        .p2align        2
        .type   main,@function
main: # @main
# %bb.0:                                # %entry
        addi    sp, sp, -16
        sd      ra, 8(sp)                       # 8-byte Folded Spill
        li      a0, 0
        call    foobar
        li      a0, 0
        ld      ra, 8(sp) # 8-byte Folded Reload
        addi    sp, sp, 16
        ret
.Lfunc_end0:
        .size   main, .Lfunc_end0-main
 # -- End function
        .p2align        2 # -- Begin function foobar
        .type   foobar,@function
foobar: # @foobar
# %bb.0:                                # %entry
        addi    sp, sp, -48
        sd      ra, 40(sp)                      # 8-byte Folded Spill
        mv      a1, a0
        addi    a0, sp, 8
        addi    a2, sp, 4
        call    bmp_iter_set_init
        ld      ra, 40(sp)                      # 8-byte Folded Reload
        addi    sp, sp, 48
        ret
.Lfunc_end1:
        .size   foobar, .Lfunc_end1-foobar
                                        # -- End function
        .section        ".note.GNU-stack","",@progbits
```

A similar problem is found in SPEC's `557.xz_r` - in the `match` function, no registers are callee-saved including the return address and the return address is used internally.

Filing as a bug at this point as I know @topperc was looking in this sort of area, though am happy to dig further if nothing immediately jumps to mind.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWFtv47gO_jXKC-FAlmMnfshDJp0u5uBcBp05-1rINp1oK0uGJKfN_voDys6l1xng7L5NEcSpRFIkP-qzROm92hnENcs_sfxmJoewt27dqYe9VNrJTuq9nVW2Oa6_75WHR-mhtYNpQHropQtgW5AGsG2tCxAs4EHqQQYE1YIK8GgH3UCFUKHBVtVK6ihlZKURvny920BrHdx9-bZNfp_D9z2C8n5AqKUhNY9oQBn49vXzFphYVYPSAR5V2IOEvawfyFqjfDQX9gj_kvVeGfzPELQy6Gj60boH6aLXTGRpWuZ5wUTJxBaqIYAEh81QYwP4JLteI7TOdtHYb9stBOvC4BD8oCgqD4PHhlwKlJBq2IHD3rowZ3zD-OY7-kDzvZNgDQTbU4pYwcuyagRmbSqySralTBeyrssqSxF5m-dLsVql6UoWrOAUqFiFPfxDGnI0Gt68ctO20cne2UpjB5Ukx6wBwXnJ0zRLsnk9OjpG8jqUCrV9ZNlmXIEVfPrwTZBuhwEaGaSWRzsEYNkNMCEw6Vi2waRn2aZYxK9EnX-kYsWyTSpWicnEOPaNxoS42AxOkfeTPad8fSgWyWAejH00iVZmeEp2Zhh16CNyH9xQh3mlQif7exXQyWBdNBGOPQJbfoI-OEJ0eqhMxEexALa8GQ012CqDNAVswTupDCPXSjB2MI-KymP5ifENmuCOY1YAaqk1HKxqSKe1tpKOiVUfHJhB6xEdAIch2qXUvVrPBHRGvmOFiVyrA96HvbPDbm-HMOfzg9SjXw7rwXn80EMmcudVTIbU2tYS3s0YpURqtTOwOqvizthr5VPmYjRn-QXJP8tF1Y127z2Ge2VUuATkvJqg-CC883z04DqRtMLzPNZaOvzRylfox0f5oqTvsLMHZXZxP1xSK0NwqhrCtO1HcKgyW_WEngkR5SvZQG27XmmcNvod9s7ShhzZiBVc6xqSkdmSuP9ZtoVQz7UeHWB8M1lH03gY-lGT8qOMZ9mGjDCxeErJ48iLL5aOfPWmvCB2XDyl14o7a4kPMKJomjjmcNdJ_3CWiZAGewq7segNE8sAe3nAs32yqgzx-RtOnYiPVkRDhYb0evDYVfoYFVjBr_MyMZyxgShbBpqf9kTBo0cepLFhjw7awdRBWRMjv3jn5QGZuHXog3XRz9HsRPNUEuWbvMZ4OT8jzni5oOSkxRsz-ZhT4Q7FQok-PfFROW-VJgEayLY-NMqw7PNlOuBTmH7utK004yVxDb17IEngE-6UucQVaWiU7kXca4yXZ1PHHid1JrZEHZMa45s4SDUgsjOdEVlmtKeqas5p8gd_k_RIJ3FJ2TSK8dL3FP34nZzS4xvGSydpbMXEimbLDwyvkuoYEG6tbrCBb73SerSjaQUZa3aChDBnvJyK4B0h_dbyrxe6Q21l8240p2AcEkjzf1JG79E0_FQu5dyrP6-yDlcyyZTlE5afTQNXkLwA8R3Er6M8IXx6JbzAeBq-oHzR_RtwXqzGue5AAmmkDf5MfMTjeSJPU-JqSjyD9TVfv-fCyYOX4KSvwDkn7AqeNDmn5wOAPE7_0QaeEwnNf_v3fxMfZP1Am1hs47cYweid3VUq-Fc08gHlEavHE9NHtIcvOWw8JY5ixBZXnHghs19M9ovJfjHZTzPZFc4L_jHQH-L8c4y4epcQFz_Dh_r_cfYHtfLXEetP_v39_LsBrzqlpTtfgNWpNzH1C5hYeuLRPF_On_68j6fL5HQhZgXvZKj38cB88lBswVg6Iysf0HmgWweBhpgQW5PlWg_N6RLhMAzOgGwah95fnbGfDV9aBuM9UB-nE_Ot0mRJepCxjyDD2FPorTKBhr8A3YlptwTb9-jq2H_R1j6Q3qkF4e3UhnEYi4dePrs9yA72su-PY4NkB-3g4olatUBn62ih67BRMqA-wh9D13uS7ZRp5rNmnTVlVsoZrtNltkqLRZqms_26SKslX4m2LYp0Wec8y7Dli4Iv65LnBZYztRZc5DwVZZqLNE_neVZly6KRxWKVFku-YguOnVR6rvWhm1u3m8WGzzoVizITMy0r1D72o4Qw-Di2g6ge8puZW5NSUg07zxZcKx_8xUxQQcdG1pevdxuW37D8092Xb9vfWX4DTr583Q4Gn3qsAzb6CLYPqlOxfTLEXJ4qYjY4vd6H0NN1i4lbJm53KuyHal7bjolbWnx6JL2zf2AdmLiNLnsmbqeYDmvxvwAAAP__Mmq6XA">