<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">