<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 - [LSR] LSR creates use-before-def case"
href="https://bugs.llvm.org/show_bug.cgi?id=43678">43678</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[LSR] LSR creates use-before-def case
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>evgueni.brevnov@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=22670" name="attach_22670" title="test case">attachment 22670</a> <a href="attachment.cgi?id=22670&action=edit" title="test case">[details]</a></span>
test case
You will get an error if you try to compile attached test case with the
following command
<span class="quote">> opt manual.nm.ll -passes=strength-reduce -S</span >
Instruction does not dominate all uses!
%0 = add i32 %local.osr.1, %local_5_49.us
%tmp2 = add i32 %0, 1
LLVM ERROR: Broken module found, compilation aborted!
I root caused the issue but don't know what would be a proper fix. The problem
is that hoist a user instruction to another block while expanding code for one
of its uses. As a result the user ends up placed before its uses.
During code expansion/rewriting for tmp1 in "%tmp2 = add i32 %tmp1, 1" we hoist
%tmp1 & %tmp2 from the second to the first block.
Here is the code in responsible for this:
// Check whether we can reuse this PHI node.
if (LSRMode) {
if (!isExpandedAddRecExprPHI(&PN, TempIncV, L))
continue;
if (L == IVIncInsertLoop && !hoistIVInc(TempIncV, IVIncInsertPos))
continue;
} else {
if (!isNormalAddRecExprPHI(&PN, TempIncV, L))
continue;
}
Note the call to hoistIVInc, where IVIncInsertPos is set once for entire
expansion. Since there is another post-inc use in the first block,
IVIncInsertPos points to an instruction there.
But actual IP determined at the beginning of LSRInstance::Expand ('IP =
AdjustInsertPositionForExpand(IP, LF, LU, Rewriter);') belongs to the second
block.
As a result we end up placing use in the first block while def in the second.
I verified that the following workaround helps to this case but it's definitely
not a solution:
index 7f119175c4a..660b49e70bc 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -5221,6 +5221,8 @@ Value *LSRInstance::Expand(const LSRUse &LU, const
LSRFixup &LF,
// Flush the operand list to suppress SCEVExpander hoisting of both folded
and
// unfolded offsets. LSR assumes they both live next to their uses.
if (!Ops.empty()) {
+ IP = AdjustInsertPositionForExpand(LF.UserInst->getIterator(), LF, LU,
Rewriter);
+ Rewriter.setInsertPoint(&*IP);
Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty);
Ops.clear();
Ops.push_back(SE.getUnknown(FullV));
Any thoughts?
Thanks
Evgeniy</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>