[llvm-bugs] [Bug 46943] New: Loop Strength Reduction (`opt -loop-reduce`) reorders `icmp` with -1 and `add nuw`, yielding poison
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Jul 31 18:59:10 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=46943
Bug ID: 46943
Summary: Loop Strength Reduction (`opt -loop-reduce`) reorders
`icmp` with -1 and `add nuw`, yielding poison
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: normal
Priority: P
Component: Loop Optimizer
Assignee: unassignedbugs at nondot.org
Reporter: pnkfelix at pnkfx.org
CC: llvm-bugs at lists.llvm.org
Created attachment 23802
--> https://bugs.llvm.org/attachment.cgi?id=23802&action=edit
input LLVM IR to demonstrate bug
This is taken from
https://github.com/rust-lang/rust/issues/74498#issuecomment-661950983
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.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200801/1b08a29a/attachment.html>
More information about the llvm-bugs
mailing list