<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - (Simple)LoopUnswitch introduces branch on poison if call doesn't return"
href="https://bugs.llvm.org/show_bug.cgi?id=51671">51671</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>(Simple)LoopUnswitch introduces branch on poison if call doesn't return
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Keywords</th>
<td>miscompilation
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Loop Optimizer
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>nunoplopes@sapo.pt
</td>
</tr>
<tr>
<th>CC</th>
<td>aeubanks@google.com, alina.sbirlea@gmail.com, florian_hahn@apple.com, llvm-bugs@lists.llvm.org, max.kazantsev@azul.com, nikita.ppv@gmail.com
</td>
</tr></table>
<p>
<div>
<pre>Tests:
- Transforms/LoopUnswitch/preserve-analyses.ll
- Transforms/SimpleLoopUnswitch/delete-dead-blocks.ll
- Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
In the test below, @pci_get_device may not return. In that case, the source
function will not branch on the undef %conv56.
The target function always branches on %conv56 regardless of whether
@pci_get_device returns or not.
The fix is to freeze the condition if the code doesn't provably reach the
branch.
define void @pnp_check_irq() {
%entry:
%conv56 = trunc i64 undef to i32
br label %while.cond.i
%while.cond.i:
%call.i25 = call * @pci_get_device()
br i1 undef, label %if.then65, label %while.body.i
%if.then65:
assume i1 0
%while.body.i:
br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge
%if.then31.i.i:
switch i32 %conv56, label %while.cond.i.backedge [
i32 14, label %if.then42.i.i
i32 15, label %if.then42.i.i
]
%if.then42.i.i:
%call.i25.lcssa48 = phi * [ %call.i25, %if.then31.i.i ], [ %call.i25,
%if.then31.i.i ]
assume i1 0
%while.cond.i.backedge:
br label %while.cond.i
}
=>
define void @pnp_check_irq() {
%entry:
%conv56 = trunc i64 undef to i32
%0 = icmp eq i32 %conv56, 14
br i1 %0, label %entry.split.us, label %entry.entry.split_crit_edge
%entry.entry.split_crit_edge:
br label %entry.split
%entry.split:
%1 = icmp eq i32 %conv56, 15
br i1 %1, label %entry.split.split.us, label
%entry.split.entry.split.split_crit_edge
%entry.split.split.us:
br label %while.cond.i.us1
%while.cond.i.us1:
%call.i25.us2 = call * @pci_get_device()
br i1 1, label %if.then65.us-lcssa.us-lcssa.us, label %while.body.i.us3
%if.then65.us-lcssa.us-lcssa.us:
br label %if.then65.us-lcssa
%while.body.i.us3:
br i1 undef, label %if.then31.i.i.us4, label %while.cond.i.backedge.us5
%if.then31.i.i.us4:
switch i32 15, label %while.cond.i.backedge.us5 [
i32 14, label %if.then42.i.i.us-lcssa.us-lcssa.us
i32 15, label %if.then42.i.i.us-lcssa.us-lcssa.us
]
%if.then42.i.i.us-lcssa.us-lcssa.us:
%call.i25.lcssa48.ph.ph.us = phi * [ %call.i25.us2, %if.then31.i.i.us4 ], [
%call.i25.us2, %if.then31.i.i.us4 ]
br label %if.then42.i.i.us-lcssa
%while.cond.i.backedge.us5:
br label %while.cond.i.us1
%entry.split.entry.split.split_crit_edge:
br label %entry.split.split
%entry.split.split:
br label %while.cond.i
%while.cond.i:
%call.i25 = call * @pci_get_device()
br i1 1, label %if.then65.us-lcssa.us-lcssa, label %while.body.i
%if.then65.us-lcssa.us-lcssa:
br label %if.then65.us-lcssa
%if.then65.us-lcssa:
br label %if.then65
%while.body.i:
br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge
%if.then31.i.i:
switch i32 %conv56, label %while.cond.i.backedge [
i32 14, label %if.then42.i.i.us-lcssa.us-lcssa
i32 15, label %if.then42.i.i.us-lcssa.us-lcssa
]
%if.then42.i.i.us-lcssa.us-lcssa:
%call.i25.lcssa48.ph.ph = phi * [ %call.i25, %if.then31.i.i ], [ %call.i25,
%if.then31.i.i ]
br label %if.then42.i.i.us-lcssa
%if.then42.i.i.us-lcssa:
%call.i25.lcssa48.ph = phi * [ %call.i25.lcssa48.ph.ph,
%if.then42.i.i.us-lcssa.us-lcssa ], [ %call.i25.lcssa48.ph.ph.us,
%if.then42.i.i.us-lcssa.us-lcssa.us ]
br label %if.then42.i.i
%while.cond.i.backedge:
br label %while.cond.i
%entry.split.us:
br label %while.cond.i.us
%while.cond.i.us:
%call.i25.us = call * @pci_get_device()
br i1 1, label %if.then65.us-lcssa.us, label %while.body.i.us
%if.then65.us-lcssa.us:
br label %if.then65
%if.then65:
assume i1 0
%while.body.i.us:
br i1 undef, label %if.then31.i.i.us, label %while.cond.i.backedge.us
%if.then31.i.i.us:
switch i32 14, label %while.cond.i.backedge.us [
i32 14, label %if.then42.i.i.us-lcssa.us
i32 15, label %if.then42.i.i.us-lcssa.us
]
%if.then42.i.i.us-lcssa.us:
%call.i25.lcssa48.ph.us = phi * [ %call.i25.us, %if.then31.i.i.us ], [
%call.i25.us, %if.then31.i.i.us ]
br label %if.then42.i.i
%if.then42.i.i:
%call.i25.lcssa48 = phi * [ %call.i25.lcssa48.ph, %if.then42.i.i.us-lcssa ],
[ %call.i25.lcssa48.ph.us, %if.then42.i.i.us-lcssa.us ]
assume i1 0
%while.cond.i.backedge.us:
br label %while.cond.i.us
}
Transformation doesn't verify!
ERROR: Source is more defined than target
Example:
Source:
i32 %conv56 = any
* %call.i25 = poison
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0
Block 1 > size: 0 align: 1
Target:
i32 %conv56 = #xfffffff1 (4294967281, -15)
i1 %0 = #x0 (0)
i1 %1 = #x0 (0)
* %call.i25.us2 = poison
* %call.i25 = poison
* %call.i25.us = poison</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>