[llvm-bugs] [Bug 37677] New: opt crashes with "-simple-loop-unswitch -loop-idiom": Assertion `hasDedicatedExits() && "getUniqueExitBlocks assumes the loop has canonical form exits!"' failed.

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Jun 4 05:14:50 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=37677

            Bug ID: 37677
           Summary: opt crashes with "-simple-loop-unswitch -loop-idiom":
                    Assertion `hasDedicatedExits() && "getUniqueExitBlocks
                    assumes the loop has canonical form exits!"' failed.
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: bjorn.a.pettersson at ericsson.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 20389
  --> https://bugs.llvm.org/attachment.cgi?id=20389&action=edit
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: https://reviews.llvm.org/D44677
    Reviewed By: efriedma


    git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@329047
91177308-0d34-0410-b5e6-96231b3b80d8

(and I still get the same fault with trunk at 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?

-- 
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/20180604/87a54a87/attachment-0001.html>


More information about the llvm-bugs mailing list