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
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
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
r230058 should help.