[llvm-bugs] [Bug 33357] New: jump-threading creating dead loop, causing LazyValueInfo to recurse infinitely
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu Jun 8 04:06:22 PDT 2017
https://bugs.llvm.org/show_bug.cgi?id=33357
Bug ID: 33357
Summary: jump-threading creating dead loop, causing
LazyValueInfo to recurse infinitely
Product: new-bugs
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: new bugs
Assignee: unassignedbugs at nondot.org
Reporter: mikael.holmen at ericsson.com
CC: llvm-bugs at lists.llvm.org
Created attachment 18592
--> https://bugs.llvm.org/attachment.cgi?id=18592&action=edit
reproducer
I've stumbled on a case where LazyValueInfo recurses infinitely and crashes due
to a rewrite done by jump-threading.
Reproduce with the following bugpoint reduced reproducer:
opt -S -Os -O1 -o - reduced.ll
I have so far failed to reproduce it when only invoking opt with
-jump-threading but I suppose it should be possible.
Short version of the problem:
-----------------------------
Should LavyValueInfo be able to handle
%0 = and i1 %0, %tobool5
placed in a loop that is dead due to a jump-threading rewrite, or shouldn't
jump-threading call LazyValueInfo on instructions in the dead loop at all?
Details:
-----------------------------
(bugpoint-reduced) Input to jump-threading:
define void @f4(i32 %p1) local_unnamed_addr #1 {
entry:
%cmp = icmp eq i32 %p1, 0
br i1 undef, label %if.end16, label %for.cond.preheader
for.cond.preheader: ; preds = %entry
%conv12 = trunc i32 %p1 to i16
br label %for.cond
for.cond: ; preds = %if.end,
%if.then14, %for.cond.preheader
%f.0.in = phi i1 [ %cmp, %for.cond.preheader ], [ %0, %if.then14 ], [ %0,
%if.end ]
%call4 = tail call i16 @f1()
%tobool5 = icmp ne i16 %call4, 0
%0 = and i1 %f.0.in, %tobool5
br i1 %0, label %if.then11, label %if.end
if.then11: ; preds = %for.cond
store i16 %conv12, i16* @a, align 1
br label %if.end
if.end: ; preds = %if.then11,
%for.cond
br i1 %cmp, label %for.cond, label %if.then14
if.then14: ; preds = %if.end
store i16 1, i16* @b, align 1
br label %for.cond
if.end16: ; preds = %entry
ret void
}
Then
entry:
%cmp = icmp eq i32 %p1, 0
br i1 undef, label %if.end16, label %for.cond.preheader
is quickly replaced with
entry:
%cmp = icmp eq i32 %p1, 0
br label %if.end16
due to the original condition being undef:
In block 'entry' folding undef terminator: br i1 undef, label %if.end16,
label %for.cond.preheader
The function now looks like:
define void @f4(i32 %p1) local_unnamed_addr #1 {
entry:
%cmp = icmp eq i32 %p1, 0
br label %if.end16
for.cond.preheader: ; No predecessors!
%conv12 = trunc i32 %p1 to i16
br label %for.cond
for.cond: ; preds = %if.end,
%if.then14, %for.cond.preheader
%f.0.in = phi i1 [ %cmp, %for.cond.preheader ], [ %0, %if.then14 ], [ %0,
%if.end ]
%call4 = tail call i16 @f1()
%tobool5 = icmp ne i16 %call4, 0
%0 = and i1 %f.0.in, %tobool5
br i1 %0, label %if.then11, label %if.end
if.then11: ; preds = %for.cond
store i16 %conv12, i16* @a, align 1
br label %if.end
if.end: ; preds = %if.then11,
%for.cond
br i1 %cmp, label %for.cond, label %if.then14
if.then14: ; preds = %if.end
store i16 1, i16* @b, align 1
br label %for.cond
if.end16: ; preds = %entry
ret void
}
Note that for.cond.preheader is dead, no predecessors anymore.
Jump-threading therefore removes it:
JT: Deleting dead block 'for.cond.preheader' with terminator: br label
%for.cond
and the edge from for.cond.preheader to for.cond is also removed, leaving
for.cond like:
for.cond: ; preds = %if.end, %if.then14
%call4 = tail call i16 @f1()
%tobool5 = icmp ne i16 %call4, 0
%0 = and i1 %0, %tobool5
br i1 %0, label %if.then11, label %if.end
Especially notice the instruction:
%0 = and i1 %0, %tobool5
Operand 1 of the instruction was previously the result of a phi node, but since
we removed the dead block the phi could be simplified and removed, and we now
have an instruction referencing itself.
This instruction is later examined by LazyValueInfo and we end up in:
static LVILatticeVal
getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
DenseMap<Value*, LVILatticeVal> &Visited) {
auto I = Visited.find(Cond);
if (I != Visited.end())
return I->second;
auto Result = getValueFromConditionImpl(Val, Cond, isTrueDest, Visited);
Visited[Cond] = Result;
return Result;
}
For an "and", getValueFromConditionImpl in turn will call getValueFromCondition
on both its operands. Since operand 1 of it is the "and" itself, we have
infinite recursion.
getValueFromCondition does have a visited list, but instructions are only
inserted in that after the instruction has been fully examined, so it doesn't
help us in this case.
Who's to blame?
--
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/20170608/f75db2f7/attachment.html>
More information about the llvm-bugs
mailing list