<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 - opt crashes with "-simple-loop-unswitch -loop-idiom": Assertion `hasDedicatedExits() && "getUniqueExitBlocks assumes the loop has canonical form exits!"' failed."
href="https://bugs.llvm.org/show_bug.cgi?id=37677">37677</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>opt crashes with "-simple-loop-unswitch -loop-idiom": Assertion `hasDedicatedExits() && "getUniqueExitBlocks assumes the loop has canonical form exits!"' failed.
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</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>new bugs
</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>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=20389" name="attach_20389" title="reproducer">attachment 20389</a> <a href="attachment.cgi?id=20389&action=edit" title="reproducer">[details]</a></span>
reproducer
opt -simple-loop-unswitch -loop-idiom -S -o - computeExitLimit.ll
gives
; opt: ../lib/Analysis/LoopInfo.cpp:397: void
llvm::Loop::getUniqueExitBlocks(SmallVectorImpl<llvm::BasicBlock *> &) const:
Assertion `hasDedicatedExits() && "getUniqueExitBlocks assumes the loop has
canonical form exits!"' failed.
; Stack dump:
; 0. Program arguments: ./build-all/bin/opt -simple-loop-unswitch
-loop-idiom -S -o - computeExitLimit.ll
; 1. Running pass 'Function Pass Manager' on module 'computeExitLimit.ll'.
; 2. Running pass 'Loop Pass Manager' on function '@f1'
; 3. Running pass 'Recognize loop idioms' on basic block
'%for.body4.lr.ph'
; #0 0x000000000218f664 PrintStackTraceSignalHandler(void*)
(./build-all/bin/opt+0x218f664)
; #1 0x000000000218d850 llvm::sys::RunSignalHandlers()
(./build-all/bin/opt+0x218d850)
; #2 0x000000000218f9c8 SignalHandler(int) (./build-all/bin/opt+0x218f9c8)
; #3 0x0000003fb500f7e0 __restore_rt (/lib64/libpthread.so.0+0x3fb500f7e0)
; #4 0x0000003fb4832495 __GI_raise (/lib64/libc.so.6+0x3fb4832495)
; #5 0x0000003fb4833c75 __GI_abort (/lib64/libc.so.6+0x3fb4833c75)
; #6 0x0000003fb482b60e __assert_fail_base (/lib64/libc.so.6+0x3fb482b60e)
; #7 0x0000003fb482b6d0 __GI___assert_perror_fail
(/lib64/libc.so.6+0x3fb482b6d0)
; #8 0x00000000016c2b01
llvm::Loop::getUniqueExitBlocks(llvm::SmallVectorImpl<llvm::BasicBlock*>&)
const (./build-all/bin/opt+0x16c2b01)
; #9 0x0000000001fcaa77 (anonymous
namespace)::LoopIdiomRecognize::runOnCountableLoop()
(./build-all/bin/opt+0x1fcaa77)
; #10 0x0000000001fca77a (anonymous
namespace)::LoopIdiomRecognize::runOnLoop(llvm::Loop*)
(./build-all/bin/opt+0x1fca77a)
; #11 0x0000000001fd32fe (anonymous
namespace)::LoopIdiomRecognizeLegacyPass::runOnLoop(llvm::Loop*,
llvm::LPPassManager&) (./build-all/bin/opt+0x1fd32fe)
; #12 0x00000000016ca345 llvm::LPPassManager::runOnFunction(llvm::Function&)
(./build-all/bin/opt+0x16ca345)
; #13 0x0000000001c1911a llvm::FPPassManager::runOnFunction(llvm::Function&)
(./build-all/bin/opt+0x1c1911a)
; #14 0x0000000001c19378 llvm::FPPassManager::runOnModule(llvm::Module&)
(./build-all/bin/opt+0x1c19378)
; #15 0x0000000001c198b1 llvm::legacy::PassManagerImpl::run(llvm::Module&)
(./build-all/bin/opt+0x1c198b1)
; #16 0x00000000007710e7 main (./build-all/bin/opt+0x7710e7)
; #17 0x0000003fb481ed1d __libc_start_main (/lib64/libc.so.6+0x3fb481ed1d)
; #18 0x000000000075aa6d _start (./build-all/bin/opt+0x75aa6d)
; Abort (core dumped)
This started happening after r329047:
[SCEV] Make computeExitLimit more simple and more powerful
Current implementation of `computeExitLimit` has a big piece of code
the only purpose of which is to prove that after the execution of this
block the latch will be executed. What it currently checks is actually a
subset of situations where the exiting block dominates latch.
This patch replaces all these checks for simple particular cases with
domination check over loop's latch which is the only necessary condition
of taking the exiting block into consideration. This change allows to
calculate exact loop taken count for simple loops like
for (int i = 0; i < 100; i++) {
if (cond) {...} else {...}
if (i > 50) break;
. . .
}
Differential Revision: <a href="https://reviews.llvm.org/D44677">https://reviews.llvm.org/D44677</a>
Reviewed By: efriedma
git-svn-id: <a href="https://llvm.org/svn/llvm-project/llvm/trunk@329047">https://llvm.org/svn/llvm-project/llvm/trunk@329047</a>
91177308-0d34-0410-b5e6-96231b3b80d8
(and I still get the same fault with trunk@333873)
This was found when running random passes on random input. We don't normally
use -simple-loop-unswitch, so this is not a big problem for us.
I haven't been able to figure out if -simple-loop-unswitch is doing something
bad, or if it is a problem with -loop-idiom or simply some pass-manager
limitation.
We for example do hit the same assert when using:
opt -passes='unswitch,loop(loop-idiom)' -S -o - computeExitLimit.ll
but not when doing
opt -passes='unswitch' -S -o - computeExitLimit.ll | opt
-passes='loop(loop-idiom)' -S -o -
so perhaps this is another problem with cached SCEV info?</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>