<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/57523>57523</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
IRCE introduces UB by changing order of condition checks
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
loopoptim
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
nunoplopes
</td>
</tr>
</table>
<pre>
IRCE reorders order of condition checks. For example see this minimized test case from `IRCE/bad_expander.ll`:
```llvm
define void @test_03(i1 %maybe_exit, i64 %num) {
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ]
%iv.next = add i64 %iv, 1
br i1 %maybe_exit, label %range_check, label %exit
range_check:
%rc = icmp slt i64 %iv.next, %num
br i1 %rc, label %guarded, label %exit
guarded:
%dummy = add i64 %iv.next, 0
%tmp7 = icmp slt i64 %iv.next, 42
br i1 %tmp7, label %loop, label %exit
exit:
ret void
}
```
If `%maybe_exit` is false, the function returns straight away.
However, IRCE gives us this:
```llvm
entry:
%0 = add i64 %num, -9223372036854775807
%smax = call i64 @llvm.smax.i64(i64 %0, i64 1)
%1 = sub i64 %num, %smax
%smin = call i64 @llvm.smin.i64(i64 %num, i64 0)
%smax1 = call i64 @llvm.smax.i64(i64 %smin, i64 -1)
%2 = add nsw i64 %smax1, 1
%3 = mul i64 %1, %2
%smin2 = call i64 @llvm.smin.i64(i64 %3, i64 42)
%exit.mainloop.at = call i64 @llvm.smax.i64(i64 %smin2, i64 0)
%4 = icmp slt i64 0, %exit.mainloop.at
br i1 %4, label %loop.preheader, label %main.pseudo.exit
loop.preheader:
br label %loop
loop:
%iv = phi i64 [ %iv.next, %guarded ], [ 0, %loop.preheader ]
%iv.next = add i64 %iv, 1
%rc = icmp slt i64 %iv.next, %num
%or.cond = select i1 %maybe_exit, i1 true, i1 false
br i1 %or.cond, label %guarded, label %exit.loopexit4
```
So we branch first on a value derived from `%num`. If that's `poison`, we end up triggering UB.
Either the condition or the variables used by the hoisted condition must be frozen.
cc @max-quazan @nikic @serguei-katkov
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJytVk1zozgQ_TX4ogolBIb44MMkmdTOdbfmnBLQBk1AYvThxPn12xL4AzzJZKe2TBnUar1-LXU_KFV92H77-_4r0aB0DdqQcCNqRyola2GFkqRqoXo2MXlUmsAr74cOiAEgthWG9EKKXrxBTSwYSypugOy06kmUU48csceS10_wOnCJyHHX4USUfonoQ0S_-Odwdd2-H0017IQEsleiJlFGPeoTTSN2KxISsXXPDyUgnLARuyciz7xRuj5iGxIVdyMGSKsPpyCElJp0vITO-3ZKDVPw8B_GZ1f0EHsSpQ9kaMWIv74j1AfDqQCMlocwxongHkt4tZNH4zjuYB18LiGDT8DldX3kLfZ-VXJB81dJnqhrLht4CscxswfHi5Qu_WaZ6SowEFU_ENPZM43LDPxmLgnpahZwSvJDEkefGYHa9f3hehdO4emFr-2H4nd0M3ZF1S-bEQsH_BHTMD7T1GBD9U0uxcOiVC-Xftv5Op-fWE4J9sWOdwZ8WNtiQzhZhVZCbKelIcZqLprWEv7CD_GI9Zd6gT1ovya0ZCP2YIgzoc8-6phltSMdutzj0CH35GbDWJoWjKb57TorivUtLS6WmZ6_hpUV77pxaRYCxX4mRoPvwxGRHvsvwda7wEgCgHHlIvQEP4sm5HvRhJxHm0D8iM7jedDks6Q98BHnZkGcnfZMmhdyWoDosyZFYxo8e9cdvZIpQbbIjn02vfRICgt6RspXVNxzIX0Vx9z-l0TZOzuWXXfVSd8W4a66K7tqrXjQ0AKvx8o9TXmQeDDgahUvG26x7H_U6Q_leJLsY65zFn8k2H8gqThSOvYv17FPoIPK_lL20Wa1g-lx1JPlcUxQnxLn2CfsH7IPBO0fRV4A8bmsWrITGl_pKFuc7HnngOA-oSjVpxf8lFpOY4JKaFssGFYYPzMoYZQMLvceETBfN2BComkQRDbk-92ke18FSqQOOnn-5lCjYc-14GUXdBDjlodgbRHc4vDs3jskWoYvjzeQ8WVGVeXbBBvk5qfjb1z6kRTPIpgN6MaBuHnm9lntV7BN8pwlSYq_Vb1N60264SsrbAfjZ5JAqVW1q5DQ9ztPp2rxXevTefe7aeV0t22tHYKGs0e8GszYlXhyqGmPQcfH282g1Q8sBxwKYxwYfFgXa5au2m1WQkrXyW5XVkkBeZbxosjzmjGoaMXqahXO2myxwiPGemEQfRAd90zQMBYi8yWgBit6b1o_rMSWUcbohrKE0nWaxLeM5QXb3WZlBownG9wjwFbu4qAzSjcrvQ1US9cYLz94EuY8yY0RjQQINBCfO9sqvZVOqqHD6jOrkNg2ZPUvnyoKNA">