<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/234334>234334</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[TailCallElim] byval copy-back for the eliminated self-call overwrites the argument before a trailing load of it
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
llvm:optimizations,
generated by fuzzer
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ChoKyuWon
</td>
</tr>
</table>
<pre>
### reproducer
godbolt: https://godbolt.org/z/c6xb8nre8
```llvm
%S = type { i32, i32 }
@g = global %S { i32 7, i32 0 }
@h = global %S { i32 5, i32 0 }
define i32 @f(ptr byval(%S) align 4 %p, i32 %n) {
entry:
%c = icmp eq i32 %n, 0
br i1 %c, label %base, label %rec
base:
%bv = load i32, ptr %p, align 4
ret i32 %bv
rec:
%r = call i32 @f(ptr byval(%S) @g, i32 0)
%v = load i32, ptr %p, align 4
%s = add i32 %r, %v
ret i32 %s
}
; f(@h, 1) = f(@g, 0) + 5 = 7 + 5 = 12
define i32 @main() {
%r = call i32 @f(ptr byval(%S) @h, i32 1)
ret i32 %r
}
```
```console
$ opt -passes=tailcallelim -S repro.ll | grep -A5 '^rec:'
rec: ; preds = %tailrecurse
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %g, ptr align 1 @g, i64 8, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %p, ptr align 1 %g, i64 8, i1 false)
%v = load i32, ptr %p, align 4
%s = add i32 %accumulator.tr, %v
br label %tailrecurse
$ llubi repro.ll; echo $?
12
$ opt -passes=tailcallelim -S repro.ll | llubi -; echo $?
14
$ cat repro.c
struct S { int a[6]; };
struct S g = {{7}}, h = {{5}};
__attribute__((noinline)) int f(struct S s, int n) {
if (n == 0)
return s.a[0];
int r = f(g, 0);
return r + s.a[0];
}
int main(void) { return f(h, 1); }
$ clang -O2 repro.c && ./a.out; echo $?
14
$ clang -O2 -fno-optimize-sibling-calls repro.c && ./a.out; echo $?
12
```
### suggested fix
`eliminateCall` leaves the instructions between the call and the `ret` after the call, but `copyLocalTempOfByValueOperandIntoArguments` writes the next iteration's value into `F.getArg(OpndIdx)` at the call (`IRBuilder<> Builder(CI)`), so a trailing load of the byval argument that `canMoveAboveCall` accepted reads the new value.
Emit the copy-back into the argument just before the new back-edge branch (after the trailing instructions), or refuse trailing instructions that may read a byval argument.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykVl2P6rwR_jXmZgQKTkLggosAi7Rqq5X6HrWXKyeZBJ86dmo7nGV_fTXOB-yes2pPXykSYM_HM88zM0Q4JxuNuGfpgaWnhej9xdj98WL-cuv_afSiMNVtz3g8PGCxs6bqS7QsyhtTFUZ5Fudw8b5zLM4ZPzN-Hi9WxjaMn98ZP5ebt2KrLW5ZlNOziYZHqWtLv3n6B7D4BP7WIbDsADLmjB_pA1h2Gr2SqAlWjTKFUDB4DcaQTebR5JBEly-t05-so7zCWmocUiZRzfi28xaK21UoxrfkzvgOhJKNhoTCdTNCnmq6Y9mBRTlqb2_ERZQDXZUBhSzbDvDfD_ZHiMiksCDXwY6OlCgwYC2Eww8HFssBZ7i5hy-uIb4yoppYI9wTvhFvsLbop_zFdQhGUe-xbAhVCqX-Gw2kxcwh47spwv8OhvHUBWNRVRMqS0YU5TNcR2jnPogPQLhIYXJYB0DxaTpsBm7pkB8gDVfZw_c1_0ntVkgdqptE_H06LhMd64mOB_z2jn9q_U-TUBrtjMIwDAmYzsOyE86hY_HJC6kIBSrZwvKPYQpXSgHLjtBY7GCZp8B4xtKnUVCezeIC8dVZrAa6GU8pnsWytw4D0FDh1ciK6qCRXLXYlt1t1UX0yE0ylj3oF7q1mbSdz6aO2CSwDV_WUAtFXRzo-H-SdD8lGRN_leTPt6Aoy77tlfDGrvzHfizsfRo_UjiqplRfyFkdoh3LiwHGExafWZSHxvtNeYeYy18ES-6JS-FHL9oRztu-9DBuO-1BsPSwYemJglAXxodHq2GnUttnh4yusxOVfXk4Tsfj4Mii_PVVeG9l0Xt8fQ1jsNVGaiV1EILvQloaljmLC2ppD_pxyGQN5EupKNu8ScLw9FaDWxH4aAA_uGgPdh73edan69HPhnn_7D2vEAoyzjy15AhpcqbA82aZSBuZVkI3sHzhE9_A-IbxDawYP4uV6f1XSn1wXtbaLE3nZSvfcelkoaRultQE7ncC818slPm_2vVNg85jBbV8Gwypw6QWHo9CKbaJQKG4ogN_QZB60Eoa7aBA_wNRh4swuEJX4QfbRBY9uYrao50NiK2i9xA2WXf7qymF-oZt91Ifbv8QqseXDq3Q1bP2JrdN36L2jsL8sNKPCDS-eZAerSAQjGcOruRKkhuKfF416HN6qdi-dLp6rt5IH8Li70ipHTfR898PvVQVWhYfWfwE0y--PT4PTqFRj-AMCPBWSFJg2BqmDtHCjgcxggV_EUN5Qv_NXDEvzHWmUZQldsS0RVFNxfwY0K9YlD-1ckRoutuyEOW_hproaE7wvXceCqyNxTkCmS6xahAKK3R5oeruxM-wH7Ub6zIWLNa9-8JqKKcVtwAZxKdqCfSi2sfVLt6JBe7X2Y5v1muexovLfhvtynidRNm2iNd1XdeRSMtKbKKsyra7erOQex7xzTri6_UuTtbxiidxHPMki2Melds0YUmErZBqFf4HjG0W0rke9zxO4jhZhC3rwjsp5610pWk7qcauoI3OOA9vjnE-zpAYSx8vG9TURVhBcYO6f38n5Tm94No9OS6LvnH0NySdd3cQXnoVXoW_CalI2yclW5aeRnLu4tVmEGCepwocqjoMMJgr2oeunvUdpf1Ft0m_6K3af3qJlv7SF6vStIyfQ7XDx7Kz5juWnvFzIM0xfh55u-75fwIAAP__LZhxVw">