<html>
<head>
<base href="https://llvm.org/bugs/" />
</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 --- - LICM incorrectly hoists load" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24078&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=gX4MqxEOAeqIG8c5EGG835LZG8x786l-6YDqwrzkwTg&s=iXC_xpmdORNEM9xEBKpsx7uziYf6uL2H7AIkaZYdfAI&e=">24078</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>LICM incorrectly hoists load
</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>All
</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>sanjoy@playingwithpointers.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Running opt -licm on
define i32 @x(i32* %x, i1* %y) {
entry:
br label %loop
loop:
%v = phi i32 [ 0 , %entry ], [ %v.inc, %exit.inner ], [ %v, %loop ]
%c = load volatile i1, i1* %y
br i1 %c, label %exit.inner, label %loop
exit.inner:
%c1 = load volatile i1, i1* %y
%x.val = load i32, i32* %x
%v.inc = add i32 %v, %x.val
br i1 %c1, label %exit.real, label %loop
exit.real:
ret i32 %v
}
results in
; ModuleID = '/Users/sanjoy/tmp/inf.ll'
define i32 @x(i32* %x, i1* %y) {
entry:
%x.val = load i32, i32* %x
br label %loop.outer
loop.outer: ; preds = %exit.inner, %entry
%v.ph = phi i32 [ %v.inc, %exit.inner ], [ 0, %entry ]
br label %loop
loop: ; preds = %loop.outer, %loop
%c = load volatile i1, i1* %y
br i1 %c, label %exit.inner, label %loop
exit.inner: ; preds = %loop
%c1 = load volatile i1, i1* %y
%v.inc = add i32 %v.ph, %x.val
br i1 %c1, label %exit.real, label %loop.outer
exit.real: ; preds = %exit.inner
%v.ph.lcssa = phi i32 [ %v.ph, %exit.inner ]
ret i32 %v.ph.lcssa
}
For an non-dereferenceable %x, the original program is well defined if
%c is always false. But the new program unconditionally dereferences
%x, effectively introducing UB if %x is not dereferenceable.
The bug is in isGuaranteedToExecute. It assumes that if an
instruction dominates all the loop exits then it will always be
executed by the loop "on its way out". But there may never be a way
out of the loop.</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>