<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-bound-split miscompile (resulted in unconditional ubsan overflow reported in a test case)"
href="https://bugs.llvm.org/show_bug.cgi?id=51766">51766</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>loop-bound-split miscompile (resulted in unconditional ubsan overflow reported in a test case)
</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>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</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>bjorn.a.pettersson@ericsson.com
</td>
</tr>
<tr>
<th>CC</th>
<td>jingu.kang@arm.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Here is a reduced test case based on running some tests involving
loop-bound-split pass and having ubsan enabled.
;------------------------------------------------------------------------
; RUN: opt < %s -S -passes='loop-bound-split'
define i16 @main(i16 %qqq) {
entry:
br label %for.body
for.body:
%t0 = phi i16 [ 0, %entry ], [ %t8, %cont19 ]
%t1 = shl nuw nsw i16 %t0, 1
%t2 = add i16 %t1, %qqq
%.not9 = icmp ult i16 %t2, %qqq
br i1 %.not9, label %handler.pointer_overflow, label %cont15.critedge
handler.pointer_overflow:
call void @__ubsan_handle_pointer_overflow()
br label %cont19
cont15.critedge:
br label %cont19
cont19:
%t8 = add nuw nsw i16 %t0, 1
%exitcond.not = icmp eq i16 %t8, 3
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
for.cond.cleanup:
ret i16 0
}
declare dso_local void @__ubsan_handle_pointer_overflow()
;-------------------------------------------------------------------------
First iteration in the for.body we have %t0=0, which gives %t1=0, which gives
%t2=%qqq, which gives %.not9=false. So we should not jump to
%handler.pointer.overflow. And if %qqq for example it 100 we will bail out from
the loop before any unsigned wrap-around when calculating %t2.
However, loop-bound-split pass is transforming the IR above into this (which
has an unconditional branch from for.body to %handler.pointer_overflow):
;--------------------------------------------------------------------------
define i16 @main(i16 %qqq) {
entry:
br label %entry.split
entry.split: ; preds = %entry
%new.bound = call i16 @llvm.umin.i16(i16 %qqq, i16 2)
br label %for.body
for.body: ; preds = %cont19,
%entry.split
%t0 = phi i16 [ 0, %entry.split ], [ %t8, %cont19 ]
%t1 = shl nuw nsw i16 %t0, 1
%t2 = add i16 %t1, %qqq
%.not9 = icmp ult i16 %t2, %qqq
br i1 true, label %handler.pointer_overflow, label %cont15.critedge
handler.pointer_overflow: ; preds = %for.body
call void @__ubsan_handle_pointer_overflow()
br label %cont19
cont15.critedge: ; preds = %for.body
br label %cont19
cont19: ; preds = %cont15.critedge,
%handler.pointer_overflow
%t8 = add nuw nsw i16 %t0, 1
%exitcond.not = icmp eq i16 %t8, %new.bound
br i1 %exitcond.not, label %entry.split.split, label %for.body
entry.split.split: ; preds = %cont19
%t8.lcssa = phi i16 [ %t8, %cont19 ]
%0 = icmp ne i16 %t8.lcssa, 3
br i1 %0, label %for.body.split.preheader, label %for.cond.cleanup
for.body.split.preheader: ; preds = %entry.split.split
br label %for.body.split
for.body.split: ; preds =
%for.body.split.preheader, %cont19.split
%t0.split = phi i16 [ %t8.split, %cont19.split ], [ %new.bound,
%for.body.split.preheader ]
%t1.split = shl nuw nsw i16 %t0.split, 1
%t2.split = add i16 %t1.split, %qqq
%.not9.split = icmp ult i16 %t2.split, %qqq
br i1 false, label %handler.pointer_overflow.split, label
%cont15.critedge.split
cont15.critedge.split: ; preds = %for.body.split
br label %cont19.split
handler.pointer_overflow.split: ; preds = %for.body.split
call void @__ubsan_handle_pointer_overflow()
br label %cont19.split
cont19.split: ; preds =
%handler.pointer_overflow.split, %cont15.critedge.split
%t8.split = add nuw nsw i16 %t0.split, 1
%exitcond.not.split = icmp eq i16 %t8.split, 3
br i1 %exitcond.not.split, label %for.cond.cleanup.loopexit, label
%for.body.split
for.cond.cleanup.loopexit: ; preds = %cont19.split
br label %for.cond.cleanup
for.cond.cleanup: ; preds =
%for.cond.cleanup.loopexit, %entry.split.split
ret i16 0
}
declare dso_local void @__ubsan_handle_pointer_overflow()
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare i16 @llvm.umin.i16(i16, i16) #0
attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
;--------------------------------------------------------------------------</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>