<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 - Loop Strength Reduction (`opt -loop-reduce`) reorders `icmp` with -1 and `add nuw`, yielding poison"
href="https://bugs.llvm.org/show_bug.cgi?id=46943">46943</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Loop Strength Reduction (`opt -loop-reduce`) reorders `icmp` with -1 and `add nuw`, yielding poison
</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>Loop Optimizer
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>pnkfelix@pnkfx.org
</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=23802" name="attach_23802" title="input LLVM IR to demonstrate bug">attachment 23802</a> <a href="attachment.cgi?id=23802&action=edit" title="input LLVM IR to demonstrate bug">[details]</a></span>
input LLVM IR to demonstrate bug
This is taken from
<a href="https://github.com/rust-lang/rust/issues/74498#issuecomment-661950983">https://github.com/rust-lang/rust/issues/74498#issuecomment-661950983</a>
Take this LLVM IR (attached as rust-issue-74498-comex.ll):
```
target datalayout =
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare void @dummy(i8 zeroext)
define i8 @test() {
br label %1
1:
%2 = phi i8 [ 0, %0 ], [ %4, %1 ]
call void @dummy(i8 %2)
%3 = icmp eq i8 %2, -1
%4 = add nuw i8 %2, 1
br i1 %3, label %5, label %1
5:
ret i8 %4
}
```
In this IR, %2 is being incremented until it reaches -1, at which point we
break. We use `add nuw` for the increments, which yields poison in %4, but the
poison should not matter because we will break out of the loop before using the
poison.
Now, feed that into `opt -loop-reduce`, you get the following result:
```
% ./bin/opt -loop-reduce -S rust-issue-74498-comex.ll -o
rust-issue-74498-comex2.ll
% cat rust-issue-74498-comex2.ll
; ModuleID = 'rust-issue-74498-comex.ll'
source_filename = "rust-issue-74498-comex.ll"
target datalayout =
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare void @dummy(i8 zeroext)
define i8 @test() {
br label %1
1: ; preds = %1, %0
%2 = phi i8 [ 0, %0 ], [ %3, %1 ]
call void @dummy(i8 %2)
%3 = add nuw i8 %2, 1
%4 = icmp eq i8 %3, 0
br i1 %4, label %5, label %1
5: ; preds = %1
ret i8 %3
}
%
```
The problem, as also pointed out on the Rust issue, is that the `add nuw` is
moved up above the `icmp`, which means that now we will get the poison result
and feed *that* into the icmp.
In our original program that drove this investigation, that then led to the
loop being further incorrectly optimized into an infinite loop. But I think
that in general this incorrect optimization could yield arbitrary undefined
behavior, if I understand correctly.</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>