LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 21968 - Assertion failed: (!isa<IndirectBrInst>(TI) && "Cannot split critical edge from IndirectBrInst"), function SplitCriticalEdge
Summary: Assertion failed: (!isa<IndirectBrInst>(TI) && "Cannot split critical edge fr...
Status: RESOLVED FIXED
Alias: None
Product: new-bugs
Classification: Unclassified
Component: new bugs (show other bugs)
Version: trunk
Hardware: All All
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-18 15:02 PST by Dimitry Andric
Modified: 2015-02-20 14:49 PST (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments
Reduced test case for IndirectBrInst assertion failure (221 bytes, text/plain)
2014-12-18 15:02 PST, Dimitry Andric
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dimitry Andric 2014-12-18 15:02:43 PST
Created attachment 13574 [details]
Reduced test case for IndirectBrInst assertion failure

This is an assertion failure we encountered during the recent clang 3.5.0 ports exp-run, while building the radare2 port [1]:

Assertion failed: (!isa<IndirectBrInst>(TI) && "Cannot split critical edge from IndirectBrInst"), function SplitCriticalEdge, file /zpoudriere/jails/head-amd64-PR195480/usr/src/lib/clang/libllvmtransformutils/../../../contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp, line 148.
Stack dump:
0.	Program arguments: /usr/bin/cc -cc1 -triple x86_64-unknown-freebsd11.0 -emit-obj -disable-free -main-file-name json.c -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -relaxed-aliasing -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -gdwarf-2 -dwarf-column-info -coverage-file /wrkdirs/usr/ports/devel/radare2/work/radare2-0.9.6/shlr/sdb/src/json.o -resource-dir /usr/bin/../lib/clang/3.5.0 -dependency-file json.d -MT json.o -sys-header-deps -D _POSIX_C_SOURCE=200809L -D _XOPEN_SOURCE=700 -D _POSIX_C_SOURCE=200809L -D _XOPEN_SOURCE=700 -O2 -Wall -Wall -fdebug-compilation-dir /wrkdirs/usr/ports/devel/radare2/work/radare2-0.9.6/shlr/sdb/src -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -mstackrealign -fobjc-runtime=gnustep -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o json.o -x c json.c 
1.	<eof> parser at end of file
2.	Per-module optimization passes
3.	Running pass 'CallGraph Pass Manager' on module 'json.c'.
4.	Running pass 'Loop Pass Manager' on function '@js0n'
5.	Running pass 'Rotate Loops' on basic block '%for.cond'

This also reproduces with trunk r224516, with assertions enabled.  I have reduced this to a small test case, which I am attaching.

Compile with: clang -cc1 -triple x86_64-unknown-linux -S -O1 radare-json-reduced.c

[1] http://pb2.nyi.freebsd.org/data/head-amd64-PR195480-default/2014-12-12_23h17m02s/logs/errors/radare2-0.9.6.log
Comment 1 Dimitry Andric 2015-01-22 11:22:36 PST
The crash backtrace goes like this:

#0  0x00000008060c93fa in thr_kill () from /lib/libc.so.7
#1  0x00000008060c9368 in raise () from /lib/libc.so.7
#2  0x00000008060c78e9 in abort () from /lib/libc.so.7
#3  0x00000008060a6a61 in __assert () from /lib/libc.so.7
#4  0x000000000161500b in llvm::SplitCriticalEdge (TI=0x806d590e0, SuccNum=1, Options=...) at /share/dim/src/llvm/git/lib/Transforms/Utils/BreakCriticalEdges.cpp:138
#5  0x0000000001459e1c in llvm::SplitCriticalEdge (Src=0x806c179c0, Dst=0x806c174c0, Options=...) at /share/dim/src/llvm/git/include/llvm/Transforms/Utils/BasicBlockUtils.h:181
#6  0x000000000149df4d in (anonymous namespace)::LoopRotate::rotateLoop (this=0x806c16a40, L=0x806c2c4c0, SimplifiedLatch=false) at /share/dim/src/llvm/git/lib/Transforms/Scalar/LoopRotation.cpp:541
#7  0x000000000149cc42 in (anonymous namespace)::LoopRotate::runOnLoop (this=0x806c16a40, L=0x806c2c4c0, LPM=...) at /share/dim/src/llvm/git/lib/Transforms/Scalar/LoopRotation.cpp:118
#8  0x00000000023436d2 in llvm::LPPassManager::runOnFunction (this=0x806ccc000, F=...) at /share/dim/src/llvm/git/lib/Analysis/LoopPass.cpp:250
#9  0x0000000001109620 in llvm::FPPassManager::runOnFunction (this=0x806d29500, F=...) at /share/dim/src/llvm/git/lib/IR/LegacyPassManager.cpp:1530
#10 0x0000000002306212 in (anonymous namespace)::CGPassManager::RunPassOnSCC (this=0x806d29340, P=0x806d29500, CurSCC=..., CG=..., CallGraphUpToDate=@0x7fffffffa40e: true, DevirtualizedCall=@0x7fffffffa54b: false) at /share/dim/src/llvm/git/lib/Analysis/IPA/CallGraphSCCPass.cpp:151
#11 0x0000000002305af0 in (anonymous namespace)::CGPassManager::RunAllPassesOnSCC (this=0x806d29340, CurSCC=..., CG=..., DevirtualizedCall=@0x7fffffffa54b: false) at /share/dim/src/llvm/git/lib/Analysis/IPA/CallGraphSCCPass.cpp:416
#12 0x000000000230520c in (anonymous namespace)::CGPassManager::runOnModule (this=0x806d29340, M=...) at /share/dim/src/llvm/git/lib/Analysis/IPA/CallGraphSCCPass.cpp:472
#13 0x000000000110a296 in (anonymous namespace)::MPPassManager::runOnModule (this=0x806ccbc00, M=...) at /share/dim/src/llvm/git/lib/IR/LegacyPassManager.cpp:1608
#14 0x0000000001109bde in llvm::legacy::PassManagerImpl::run (this=0x806c82c00, M=...) at /share/dim/src/llvm/git/lib/IR/LegacyPassManager.cpp:1715
#15 0x000000000110aa81 in llvm::legacy::PassManager::run (this=0x806c18240, M=...) at /share/dim/src/llvm/git/lib/IR/LegacyPassManager.cpp:1748
#16 0x0000000001dd22d3 in (anonymous namespace)::EmitAssemblyHelper::EmitAssembly (this=0x7fffffffad30, Action=clang::Backend_EmitAssembly, OS=0x806c16300) at /share/dim/src/llvm/git/tools/clang/lib/CodeGen/BackendUtil.cpp:629
#17 0x0000000001dd1a52 in clang::EmitBackendOutput (Diags=..., CGOpts=..., TOpts=..., LOpts=..., TDesc=..., M=0x806c7cc00, Action=clang::Backend_EmitAssembly, OS=0x806c16300) at /share/dim/src/llvm/git/tools/clang/lib/CodeGen/BackendUtil.cpp:646
#18 0x0000000001db419f in clang::BackendConsumer::HandleTranslationUnit (this=0x806c3a180, C=...) at /share/dim/src/llvm/git/tools/clang/lib/CodeGen/CodeGenAction.cpp:174
#19 0x0000000002bceda0 in clang::ParseAST (S=..., PrintStats=false, SkipFunctionBodies=false) at /share/dim/src/llvm/git/tools/clang/lib/Parse/ParseAST.cpp:151
#20 0x00000000018f728a in clang::ASTFrontendAction::ExecuteAction (this=0x806c4a0f0) at /share/dim/src/llvm/git/tools/clang/lib/Frontend/FrontendAction.cpp:526
#21 0x0000000001db2bde in clang::CodeGenAction::ExecuteAction (this=0x806c4a0f0) at /share/dim/src/llvm/git/tools/clang/lib/CodeGen/CodeGenAction.cpp:727
#22 0x00000000018f6440 in clang::FrontendAction::Execute (this=0x806c4a0f0) at /share/dim/src/llvm/git/tools/clang/lib/Frontend/FrontendAction.cpp:428
#23 0x000000000189950e in clang::CompilerInstance::ExecuteAction (this=0x806c31140, Act=...) at /share/dim/src/llvm/git/tools/clang/lib/Frontend/CompilerInstance.cpp:811
#24 0x0000000001a76577 in clang::ExecuteCompilerInvocation (Clang=0x806c31140) at /share/dim/src/llvm/git/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:222
#25 0x00000000007629f1 in cc1_main (Argv=..., Argv0=0x7fffffffe808 "/home/dim/obj/llvm-fkp-test/bin/clang", MainAddr=0x754d60 <GetExecutablePath(char const*, bool)>) at /share/dim/src/llvm/git/tools/clang/tools/driver/cc1_main.cpp:110
#26 0x0000000000756b1b in ExecuteCC1Tool (argv=..., Tool=...) at /share/dim/src/llvm/git/tools/clang/tools/driver/driver.cpp:369
#27 0x00000000007552d2 in main (argc_=7, argv_=0x7fffffffe548) at /share/dim/src/llvm/git/tools/clang/tools/driver/driver.cpp:415
Comment 2 Davide Italiano 2015-02-20 00:58:08 PST
It's invalid to split a critical edge (i.e. an edge from a block wiht multiple successors to a block with multiple predecessors), that starts at IndirectrBrinst.
I think the right behaviour is that of stopping the rotation of the loop, e.g.

Index: LoopRotation.cpp
===================================================================
--- LoopRotation.cpp    (revision 229962)
+++ LoopRotation.cpp    (working copy)
@@ -535,6 +535,8 @@
       Loop *PredLoop = LI->getLoopFor(*PI);
       if (!PredLoop || PredLoop->contains(Exit))
         continue;
+      if (!isa<IndirectBrInst>(*TI))
+        return false;
       SplitLatchEdge |= L->getLoopLatch() == *PI;
       BasicBlock *ExitSplit = SplitCriticalEdge(
           *PI, Exit, CriticalEdgeSplittingOptions(DT, LI).setPreserveLCSSA());

I'm not sure this is 100% correct because I didn't analyze all the side-effects, but it's a start (among others, it passes clang test suite without complaining). Can you give it a shot and see the compiled executable is valid? I'll investigate further on this and ask for review once I'll be more confident
Comment 3 Benjamin Kramer 2015-02-20 14:49:43 PST
r230058 should help.