[LLVMbugs] [Bug 6222] New: Assert "getTerminator returned null" for a verified function
bugzilla-daemon at cs.uiuc.edu
bugzilla-daemon at cs.uiuc.edu
Wed Feb 3 09:48:08 PST 2010
http://llvm.org/bugs/show_bug.cgi?id=6222
Summary: Assert "getTerminator returned null" for a verified
function
Product: new-bugs
Version: trunk
Platform: Macintosh
URL: http://xlr.sf.net
OS/Version: MacOS X
Status: NEW
Keywords: crash-on-invalid, regression
Severity: normal
Priority: P2
Component: new bugs
AssignedTo: unassignedbugs at nondot.org
ReportedBy: christophe at taodyne.com
CC: llvmbugs at cs.uiuc.edu
This is exposed by test 02.Data/rects.xl in the test suite of the XL compiler.
We generate functions by exploring a tree of possibilities. In some cases, we
will drop code that we generated. This may result in a basic block that is not
properly terminated. This passes "verifyFunction" but then asserts in
JIT::getPointerToFunction.
The stack trace for the assert is:
#0 llvm::SuccIterator<llvm::TerminatorInst*, llvm::BasicBlock>::SuccIterator
(this=0x7fff5fbfd4a0, T=0x0) at CFG.h:99
#1 0x0000000100682e0f in llvm::succ_begin (BB=0x1022bbb80) at CFG.h:204
#2 0x0000000100696379 in llvm::GraphTraits<llvm::BasicBlock*>::child_begin
(N=0x1022bbb80) at CFG.h:231
#3 0x000000010083bc4d in llvm::DFSPass<llvm::GraphTraits<llvm::BasicBlock*> >
(DT=@0x1022263c0, V=0x1022bbb80, N=0) at DominatorInternals.h:65
#4 0x000000010083bfb3 in llvm::Calculate<llvm::Function, llvm::BasicBlock*>
(DT=@0x1022263c0, F=@0x1022bbaa0) at DominatorInternals.h:253
#5 0x000000010083c6a1 in
llvm::DominatorTreeBase<llvm::BasicBlock>::recalculate<llvm::Function>
(this=0x1022263c0, F=@0x1022bbaa0) at Dominators.h:671
#6 0x000000010083319b in llvm::DominatorTree::runOnFunction (this=0x102226390,
F=@0x1022bbaa0) at Dominators.cpp:58
#7 0x00000001008932f2 in llvm::FPPassManager::runOnFunction (this=0x102224bd0,
F=@0x1022bbaa0) at PassManager.cpp:1348
#8 0x0000000100894f65 in llvm::FunctionPassManagerImpl::run (this=0x102224660,
F=@0x1022bbaa0) at PassManager.cpp:1300
#9 0x0000000100895114 in llvm::FunctionPassManager::run (this=0x102223ca0,
F=@0x1022bbaa0) at PassManager.cpp:1230
#10 0x00000001005039d3 in llvm::JIT::runJITOnFunctionUnlocked
(this=0x102224560, F=0x1022ccef0, locked=@0x7fff5fbfdb00) at JIT.cpp:642
#11 0x0000000100503c72 in llvm::JIT::getPointerToFunction (this=0x102224560,
F=0x1022ccef0) at JIT.cpp:680
#12 0x000000010003e5ea in XL::CompiledUnit::Finalize (this=0x7fff5fbfdbe0) at
compiler.cpp:599
The basic block being looked at contains the following:
p debugv(BB)
allocas:
%result = alloca %tree* ; <%tree**> [#uses=3]
store %tree* %0, %tree** %result
%loc1 = alloca %tree* ; <%tree**> [#uses=1]
%loc2 = alloca %tree* ; <%tree**> [#uses=4]
%computed = alloca i1 ; <i1*> [#uses=4]
store i1 false, i1* %computed
%loc3 = alloca %tree* ; <%tree**> [#uses=1]
%loc4 = alloca %tree* ; <%tree**> [#uses=1]
%treek = load %tree** @xlcst7 ; <%tree*> [#uses=2]
store %tree* %treek, %tree** %loc2
%loc6 = alloca %tree* ; <%tree**> [#uses=2]
%computed7 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed7
%loc12 = alloca %tree* ; <%tree**> [#uses=2]
%computed15 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed15
%loc17 = alloca %tree* ; <%tree**> [#uses=6]
store %tree* %1, %tree** %loc17
%loc22 = alloca %tree* ; <%tree**> [#uses=9]
%computed23 = alloca i1 ; <i1*> [#uses=7]
store i1 false, i1* %computed23
%loc29 = alloca %tree* ; <%tree**> [#uses=2]
%computed30 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed30
%loc31 = alloca %tree* ; <%tree**> [#uses=4]
%computed34 = alloca i1 ; <i1*> [#uses=9]
store i1 false, i1* %computed34
%loc36 = alloca %tree* ; <%tree**> [#uses=20]
store %tree* %2, %tree** %loc36
%loc44 = alloca %tree* ; <%tree**> [#uses=2]
%computed45 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed45
%treek49 = load %tree** @xlcst9 ; <%tree*> [#uses=2]
store %tree* %treek49, %tree** %loc22
%loc55 = alloca %tree* ; <%tree**> [#uses=2]
%computed56 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed56
%loc68 = alloca %tree* ; <%tree**> [#uses=2]
%computed69 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed69
%treek87 = load %tree** @xlcst14 ; <%tree*> [#uses=2]
store %tree* %treek87, %tree** %loc6
The function doesn't really look like it uses that basic block anymore:
define internal %tree* @xl_eval15(%tree*, %tree*) {
allocas:
%treek = load %tree** @xlcst17 ; <%tree*> [#uses=1]
%treek71 = load %tree** @xlcst20 ; <%tree*> [#uses=0]
%glob = load %tree** @xlint16 ; <%tree*> [#uses=1]
%2 = tail call %tree* @xl_eval4(%tree* %treek, %tree* %1, %tree* %glob) ;
<%tree*> [#uses=1]
%3 = tail call %tree* @xl_evaluate(%tree* %2) ; <%tree*> [#uses=0]
%glob80 = load %tree** @xlcst19 ; <%tree*> [#uses=1]
%4 = tail call %tree* (%tree*, i32, ...)* @xl_new_closure(%tree* %glob80, i32
1, %tree* %1) ; <%tree*> [#uses=1]
%glob83 = load %tree** @xlcst20 ; <%tree*> [#uses=1]
%glob85 = load %tree** @xlint22 ; <%tree*> [#uses=1]
%5 = tail call %tree* @xl_eval3(%tree* %glob83, %tree* %4, %tree* %glob85) ;
<%tree*> [#uses=1]
%6 = tail call %tree* @xl_evaluate(%tree* %5) ; <%tree*> [#uses=1]
%7 = tail call %tree* @xl_evaluate(%tree* %6) ; <%tree*> [#uses=1]
ret %tree* %7
}
Before optimizations, it looked like:
define internal %tree* @xl_eval15(%tree*, %tree*) {
allocas:
%result = alloca %tree* ; <%tree**> [#uses=4]
store %tree* %0, %tree** %result
%loc1 = alloca %tree* ; <%tree**> [#uses=5]
%loc2 = alloca %tree* ; <%tree**> [#uses=4]
%computed = alloca i1 ; <i1*> [#uses=4]
store i1 false, i1* %computed
%loc3 = alloca %tree* ; <%tree**> [#uses=1]
%treek = load %tree** @xlcst17 ; <%tree*> [#uses=2]
store %tree* %treek, %tree** %loc2
%loc5 = alloca %tree* ; <%tree**> [#uses=8]
%computed6 = alloca i1 ; <i1*> [#uses=7]
store i1 false, i1* %computed6
%loc11 = alloca %tree* ; <%tree**> [#uses=5]
%computed12 = alloca i1 ; <i1*> [#uses=4]
store i1 false, i1* %computed12
%loc19 = alloca %tree* ; <%tree**> [#uses=1]
%computed20 = alloca i1 ; <i1*> [#uses=2]
store i1 false, i1* %computed20
%loc21 = alloca %tree* ; <%tree**> [#uses=2]
%computed24 = alloca i1 ; <i1*> [#uses=5]
store i1 false, i1* %computed24
%loc26 = alloca %tree* ; <%tree**> [#uses=10]
store %tree* %1, %tree** %loc26
%loc32 = alloca %tree* ; <%tree**> [#uses=1]
%computed33 = alloca i1 ; <i1*> [#uses=2]
store i1 false, i1* %computed33
%treek38 = load %tree** @xlcst19 ; <%tree*> [#uses=2]
store %tree* %treek38, %tree** %loc11
%loc44 = alloca %tree* ; <%tree**> [#uses=1]
%computed45 = alloca i1 ; <i1*> [#uses=2]
store i1 false, i1* %computed45
%loc57 = alloca %tree* ; <%tree**> [#uses=1]
%computed58 = alloca i1 ; <i1*> [#uses=2]
store i1 false, i1* %computed58
%treek71 = load %tree** @xlcst20 ; <%tree*> [#uses=2]
store %tree* %treek71, %tree** %loc5
%loc76 = alloca %tree* ; <%tree**> [#uses=2]
%2 = load %tree** @xlcst19 ; <%tree*> [#uses=1]
store %tree* %2, %tree** %loc76
%loc81 = alloca %tree* ; <%tree**> [#uses=3]
%3 = load %tree** @xlcst19 ; <%tree*> [#uses=1]
store %tree* %3, %tree** %loc81
%computed89 = alloca i1 ; <i1*> [#uses=3]
store i1 false, i1* %computed89
%computed92 = alloca i1 ; <i1*> [#uses=2]
store i1 false, i1* %computed92
br label %entry
entry: ; preds = %allocas
%loc = load %tree** %result ; <%tree*> [#uses=1]
store %tree* %loc, %tree** %loc1
%lazy = load i1* %computed ; <i1> [#uses=1]
br i1 %lazy, label %skip, label %work
exit: ; preds = %skip7
%retval = load %tree** %result ; <%tree*> [#uses=1]
ret %tree* %retval
skip: ; preds = %empty, %subexpr,
%entry
%loc4 = load %tree** %loc2 ; <%tree*> [#uses=1]
%4 = call %tree* @xl_evaluate(%tree* %loc4) ; <%tree*> [#uses=1]
store %tree* %4, %tree** %loc2
store i1 true, i1* %computed
%lazy9 = load i1* %computed6 ; <i1> [#uses=1]
br i1 %lazy9, label %skip7, label %work8
work: ; preds = %entry
br label %subexpr
subexpr: ; preds = %work
store %tree* %1, %tree** %loc3
%intk = load %tree** @xlint16 ; <%tree*> [#uses=0]
%glob = load %tree** @xlint16 ; <%tree*> [#uses=1]
%5 = call %tree* @xl_eval4(%tree* %treek, %tree* %1, %tree* %glob) ; <%tree*>
[#uses=1]
store %tree* %5, %tree** %loc2
store i1 true, i1* %computed
br label %skip
empty: ; No predecessors!
br label %skip
skip7: ; preds = %empty86,
%subexpr78, %skip
%loc87 = load %tree** %loc5 ; <%tree*> [#uses=1]
%6 = call %tree* @xl_evaluate(%tree* %loc87) ; <%tree*> [#uses=1]
store %tree* %6, %tree** %loc5
store i1 true, i1* %computed6
%loc88 = load %tree** %loc5 ; <%tree*> [#uses=1]
store %tree* %loc88, %tree** %loc1
store i1 true, i1* %computed89
%loc90 = load %tree** %loc1 ; <%tree*> [#uses=1]
%7 = call %tree* @xl_evaluate(%tree* %loc90) ; <%tree*> [#uses=1]
store %tree* %7, %tree** %loc1
store i1 true, i1* %computed89
%loc91 = load %tree** %loc1 ; <%tree*> [#uses=1]
store %tree* %loc91, %tree** %result
store i1 true, i1* %computed92
br label %exit
work8: ; preds = %skip
br label %subexpr78
subexpr10: ; No predecessors!
%lazy15 = load i1* %computed12 ; <i1> [#uses=1]
br i1 %lazy15, label %skip13, label %work14
skip13: ; preds = %fail53, %isGood62,
%isGood37, %subexpr10
%loc67 = load %tree** %loc11 ; <%tree*> [#uses=1]
%tagPtr = getelementptr %tree* %loc67, i32 0, i32 0 ; <i64*> [#uses=1]
%tag = load i64* %tagPtr ; <i64> [#uses=1]
%tagAndMask = and i64 %tag, 7 ; <i64> [#uses=1]
%isRightTag = icmp eq i64 %tagAndMask, 0 ; <i1> [#uses=1]
br i1 %isRightTag, label %isRightKind, label %fail66
work14: ; preds = %subexpr10
br label %subexpr16
subexpr16: ; preds = %work14
%glob17 = load %tree** @integer ; <%tree*> [#uses=0]
%glob18 = load %tree** @integer ; <%tree*> [#uses=1]
store %tree* %glob18, %tree** %loc19
store i1 true, i1* %computed20
store %tree* %1, %tree** %loc21
%lazy25 = load i1* %computed24 ; <i1> [#uses=1]
br i1 %lazy25, label %skip22, label %work23
skip22: ; preds = %work23, %subexpr16
%loc28 = load %tree** %loc26 ; <%tree*> [#uses=1]
%glob29 = load %tree** @integer ; <%tree*> [#uses=1]
%8 = call i1 @xl_type_check(%tree* %loc28, %tree* %glob29) ; <i1> [#uses=1]
br i1 %8, label %isGood, label %fail
work23: ; preds = %subexpr16
%loc27 = load %tree** %loc26 ; <%tree*> [#uses=1]
%9 = call %tree* @xl_evaluate(%tree* %loc27) ; <%tree*> [#uses=1]
store %tree* %9, %tree** %loc26
store i1 true, i1* %computed24
br label %skip22
fail: ; preds = %isGood, %skip22
br label %subexpr41
isGood: ; preds = %skip22
%glob30 = load %tree** @integer ; <%tree*> [#uses=0]
%glob31 = load %tree** @integer ; <%tree*> [#uses=1]
store %tree* %glob31, %tree** %loc32
store i1 true, i1* %computed33
%intk34 = load %tree** @xlint18 ; <%tree*> [#uses=0]
%glob35 = load %tree** @xlint18 ; <%tree*> [#uses=1]
%glob36 = load %tree** @integer ; <%tree*> [#uses=1]
%10 = call i1 @xl_type_check(%tree* %glob35, %tree* %glob36) ; <i1> [#uses=1]
br i1 %10, label %isGood37, label %fail
isGood37: ; preds = %isGood
%loc39 = load %tree** %loc26 ; <%tree*> [#uses=1]
%glob40 = load %tree** @xlint18 ; <%tree*> [#uses=1]
%11 = call %tree* @xl_BinarySubInt(%tree* %treek38, %tree* %loc39, %tree*
%glob40) ; <%tree*> [#uses=1]
store %tree* %11, %tree** %loc11
store i1 true, i1* %computed12
br label %skip13
subexpr41: ; preds = %fail
%glob42 = load %tree** @real ; <%tree*> [#uses=0]
%glob43 = load %tree** @real ; <%tree*> [#uses=1]
store %tree* %glob43, %tree** %loc44
store i1 true, i1* %computed45
%loc46 = load %tree** %loc26 ; <%tree*> [#uses=1]
store %tree* %loc46, %tree** %loc21
%lazy49 = load i1* %computed24 ; <i1> [#uses=1]
br i1 %lazy49, label %skip47, label %work48
skip47: ; preds = %work48, %subexpr41
%loc51 = load %tree** %loc26 ; <%tree*> [#uses=1]
%glob52 = load %tree** @real ; <%tree*> [#uses=1]
%12 = call i1 @xl_type_check(%tree* %loc51, %tree* %glob52) ; <i1> [#uses=1]
br i1 %12, label %isGood54, label %fail53
work48: ; preds = %subexpr41
%loc50 = load %tree** %loc26 ; <%tree*> [#uses=1]
%13 = call %tree* @xl_evaluate(%tree* %loc50) ; <%tree*> [#uses=1]
store %tree* %13, %tree** %loc26
store i1 true, i1* %computed24
br label %skip47
fail53: ; preds = %isGood54, %skip47
br label %skip13
isGood54: ; preds = %skip47
%glob55 = load %tree** @real ; <%tree*> [#uses=0]
%glob56 = load %tree** @real ; <%tree*> [#uses=1]
store %tree* %glob56, %tree** %loc57
store i1 true, i1* %computed58
%glob59 = load %tree** @xlint18 ; <%tree*> [#uses=0]
%glob60 = load %tree** @xlint18 ; <%tree*> [#uses=1]
%glob61 = load %tree** @real ; <%tree*> [#uses=1]
%14 = call i1 @xl_type_check(%tree* %glob60, %tree* %glob61) ; <i1> [#uses=1]
br i1 %14, label %isGood62, label %fail53
isGood62: ; preds = %isGood54
%glob63 = load %tree** @xlcst19 ; <%tree*> [#uses=1]
%loc64 = load %tree** %loc26 ; <%tree*> [#uses=1]
%glob65 = load %tree** @xlint18 ; <%tree*> [#uses=1]
%15 = call %tree* @xl_BinarySubReal(%tree* %glob63, %tree* %loc64, %tree*
%glob65) ; <%tree*> [#uses=1]
store %tree* %15, %tree** %loc11
store i1 true, i1* %computed12
br label %skip13
fail66: ; preds = %isRightKind,
%skip13
%glob72 = load %tree** @xlcst20 ; <%tree*> [#uses=1]
%16 = call %tree* @xl_type_error(%tree* %glob72) ; <%tree*> [#uses=1]
store %tree* %16, %tree** %loc5
store i1 true, i1* %computed6
unreachable
isRightKind: ; preds = %skip13
%loc68 = load %tree** %loc11 ; <%tree*> [#uses=1]
%17 = bitcast %tree* %loc68 to %integer* ; <%integer*> [#uses=1]
%18 = getelementptr %integer* %17, i32 0, i32 4 ; <i64*> [#uses=1]
%treeValue = load i64* %18 ; <i64> [#uses=1]
%isGood69 = icmp eq i64 %treeValue, 0 ; <i1> [#uses=1]
br i1 %isGood69, label %isGood70, label %fail66
isGood70: ; preds = %isRightKind
%19 = call %tree* @xl_type_error(%tree* %treek71) ; <%tree*> [#uses=1]
store %tree* %19, %tree** %loc5
store i1 true, i1* %computed6
unreachable
subexpr73: ; No predecessors!
%glob74 = load %tree** @xlcst19 ; <%tree*> [#uses=0]
%glob75 = load %tree** @xlcst19 ; <%tree*> [#uses=1]
%20 = call %tree* (%tree*, i32, ...)* @xl_new_closure(%tree* %glob75, i32 1,
%tree* %1) ; <%tree*> [#uses=1]
store %tree* %20, %tree** %loc76
%glob77 = load %tree** @xlcst20 ; <%tree*> [#uses=1]
%21 = call %tree* @xl_type_error(%tree* %glob77) ; <%tree*> [#uses=1]
store %tree* %21, %tree** %loc5
store i1 true, i1* %computed6
unreachable
subexpr78: ; preds = %work8
%glob79 = load %tree** @xlcst19 ; <%tree*> [#uses=0]
%glob80 = load %tree** @xlcst19 ; <%tree*> [#uses=1]
%22 = call %tree* (%tree*, i32, ...)* @xl_new_closure(%tree* %glob80, i32 1,
%tree* %1) ; <%tree*> [#uses=1]
store %tree* %22, %tree** %loc81
%intk82 = load %tree** @xlint22 ; <%tree*> [#uses=0]
%glob83 = load %tree** @xlcst20 ; <%tree*> [#uses=1]
%loc84 = load %tree** %loc81 ; <%tree*> [#uses=1]
%glob85 = load %tree** @xlint22 ; <%tree*> [#uses=1]
%23 = call %tree* @xl_eval3(%tree* %glob83, %tree* %loc84, %tree* %glob85) ;
<%tree*> [#uses=1]
store %tree* %23, %tree** %loc5
store i1 true, i1* %computed6
br label %skip7
empty86: ; No predecessors!
br label %skip7
}
I will fix my side (making sure there is a terminator), but I think that
verifyFunction should have caught it. Also, I am pretty sure that the same
input used to work, although due to numerous incompatible changes in the LLVM
source-code, I have not been able to do a full regression analysis.
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list