[llvm-bugs] [Bug 51670] New: LoopUnroll: runtime check introduces branch on poison if fn call doesn't return
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Aug 30 03:35:57 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=51670
Bug ID: 51670
Summary: LoopUnroll: runtime check introduces branch on poison
if fn call doesn't return
Product: libraries
Version: trunk
Hardware: All
OS: All
Status: NEW
Keywords: miscompilation
Severity: normal
Priority: P
Component: Loop Optimizer
Assignee: unassignedbugs at nondot.org
Reporter: nunoplopes at sapo.pt
CC: atrick at apple.com, haicheng at codeaurora.org,
llvm-bugs at lists.llvm.org, meheff at google.com,
nikita.ppv at gmail.com, zhaoshiz at quicinc.com
Test: Transforms/LoopUnroll/loop-remarks.ll
In the test below, @baz may not return. In that case, the source function will
not branch on the possibly poison %exitcond (poison if %n poison).
The target function always branches on %n regardless of whether @baz returns or
not.
The fix is to freeze %n if the code doesn't provably reach the branch.
define i32 @runtime(i32 %n) {
%entry:
br label %for.body
%for.body:
%s.06 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
%i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%add = add nsw i32 %i.05, 4
%call = call i32 @baz(i32 %add)
%add1 = add nsw i32 %call, %s.06
%inc = add nsw i32 %i.05, 1
%exitcond = icmp eq i32 %inc, %n
br i1 %exitcond, label %for.end, label %for.body
%for.end:
ret i32 %add1
}
=>
define i32 @runtime(i32 %n) {
%entry:
%0 = add i32 %n, 4294967295
%xtraiter = and i32 %n, 3
%1 = icmp ult i32 %0, 3
br i1 %1, label %for.end.unr-lcssa, label %entry.new
%entry.new:
%unroll_iter = sub i32 %n, %xtraiter
br label %for.body
%for.body:
%s.06 = phi i32 [ 0, %entry.new ], [ %add1.3, %for.body ]
%i.05 = phi i32 [ 0, %entry.new ], [ %inc.3, %for.body ]
%niter = phi i32 [ %unroll_iter, %entry.new ], [ %niter.nsub.3, %for.body ]
%add = add nsw i32 %i.05, 4
%call = call i32 @baz(i32 %add)
%add1 = add nsw i32 %call, %s.06
%inc = add nsw nuw i32 %i.05, 1
%niter.nsub = sub i32 %niter, 1
%add.1 = add nsw i32 %inc, 4
%call.1 = call i32 @baz(i32 %add.1)
%add1.1 = add nsw i32 %call.1, %add1
%inc.1 = add nsw nuw i32 %inc, 1
%niter.nsub.1 = sub i32 %niter.nsub, 1
%add.2 = add nsw i32 %inc.1, 4
%call.2 = call i32 @baz(i32 %add.2)
%add1.2 = add nsw i32 %call.2, %add1.1
%inc.2 = add nsw nuw i32 %inc.1, 1
%niter.nsub.2 = sub i32 %niter.nsub.1, 1
%add.3 = add nsw i32 %inc.2, 4
%call.3 = call i32 @baz(i32 %add.3)
%add1.3 = add nsw i32 %call.3, %add1.2
%inc.3 = add nsw i32 %inc.2, 1
%niter.nsub.3 = sub i32 %niter.nsub.2, 1
%niter.ncmp.3 = icmp eq i32 %niter.nsub.3, 0
br i1 %niter.ncmp.3, label %for.end.unr-lcssa.loopexit, label %for.body
%for.end.unr-lcssa.loopexit:
%add1.lcssa.ph.ph = phi i32 [ %add1.3, %for.body ]
%s.06.unr.ph = phi i32 [ %add1.3, %for.body ]
%i.05.unr.ph = phi i32 [ %inc.3, %for.body ]
br label %for.end.unr-lcssa
%for.end.unr-lcssa:
%add1.lcssa.ph = phi i32 [ undef, %entry ], [ %add1.lcssa.ph.ph,
%for.end.unr-lcssa.loopexit ]
%s.06.unr = phi i32 [ 0, %entry ], [ %s.06.unr.ph,
%for.end.unr-lcssa.loopexit ]
%i.05.unr = phi i32 [ 0, %entry ], [ %i.05.unr.ph,
%for.end.unr-lcssa.loopexit ]
%lcmp.mod = icmp ne i32 %xtraiter, 0
br i1 %lcmp.mod, label %for.body.epil.preheader, label %for.end
%for.body.epil.preheader:
br label %for.body.epil
%for.body.epil:
%add.epil = add nsw i32 %i.05.unr, 4
%call.epil = call i32 @baz(i32 %add.epil)
%add1.epil = add nsw i32 %call.epil, %s.06.unr
%inc.epil = add nsw i32 %i.05.unr, 1
%epil.iter.sub = sub i32 %xtraiter, 1
%epil.iter.cmp = icmp ne i32 %epil.iter.sub, 0
br i1 %epil.iter.cmp, label %for.body.epil.1, label %for.end.epilog-lcssa
%for.body.epil.1:
%add.epil.1 = add nsw i32 %inc.epil, 4
%call.epil.1 = call i32 @baz(i32 %add.epil.1)
%add1.epil.1 = add nsw i32 %call.epil.1, %add1.epil
%inc.epil.1 = add nsw i32 %inc.epil, 1
%epil.iter.sub.1 = sub i32 %epil.iter.sub, 1
%epil.iter.cmp.1 = icmp ne i32 %epil.iter.sub.1, 0
br i1 %epil.iter.cmp.1, label %for.body.epil.2, label %for.end.epilog-lcssa
%for.body.epil.2:
%add.epil.2 = add nsw i32 %inc.epil.1, 4
%call.epil.2 = call i32 @baz(i32 %add.epil.2)
%add1.epil.2 = add nsw i32 %call.epil.2, %add1.epil.1
br label %for.end.epilog-lcssa
%for.end.epilog-lcssa:
%add1.lcssa.ph1 = phi i32 [ %add1.epil, %for.body.epil ], [ %add1.epil.1,
%for.body.epil.1 ], [ %add1.epil.2, %for.body.epil.2 ]
br label %for.end
%for.end:
%add1.lcssa = phi i32 [ %add1.lcssa.ph, %for.end.unr-lcssa ], [
%add1.lcssa.ph1, %for.end.epilog-lcssa ]
ret i32 %add1.lcssa
}
Transformation doesn't verify!
ERROR: Source is more defined than target
Example:
i32 %n = poison
Source:
i32 %s.06 = #x00000000 (0)
i32 %i.05 = #x00000000 (0)
i32 %add = #x00000004 (4)
i32 %call = poison
i32 %add1 = poison
i32 %inc = #x00000001 (1)
i1 %exitcond = poison
Target:
i32 %0 = poison
i32 %xtraiter = poison
i1 %1 = poison
--
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/20210830/31db83fe/attachment.html>
More information about the llvm-bugs
mailing list