diff options
Diffstat (limited to 'test/Transforms/Inline')
55 files changed, 3217 insertions, 0 deletions
diff --git a/test/Transforms/Inline/2003-09-14-InlineValue.ll b/test/Transforms/Inline/2003-09-14-InlineValue.ll new file mode 100644 index 0000000..49a27e1 --- /dev/null +++ b/test/Transforms/Inline/2003-09-14-InlineValue.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -inline -disable-output + +declare i32 @External() + +define internal i32 @Callee() { + %I = call i32 @External( ) ; <i32> [#uses=2] + %J = add i32 %I, %I ; <i32> [#uses=1] + ret i32 %J +} + +define i32 @Caller() { + %V = invoke i32 @Callee( ) + to label %Ok unwind label %Bad ; <i32> [#uses=1] + +Ok: ; preds = %0 + ret i32 %V + +Bad: ; preds = %0 + ret i32 0 +} + diff --git a/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll b/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll new file mode 100644 index 0000000..5ced3b8 --- /dev/null +++ b/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -inline -disable-output + +define i32 @main() { +entry: + invoke void @__main( ) + to label %LongJmpBlkPre unwind label %LongJmpBlkPre + +LongJmpBlkPre: ; preds = %entry, %entry + %i.3 = phi i32 [ 0, %entry ], [ 0, %entry ] ; <i32> [#uses=0] + ret i32 0 +} + +define void @__main() { + ret void +} + diff --git a/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll b/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll new file mode 100644 index 0000000..4418f77 --- /dev/null +++ b/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -inline -disable-output + +define i32 @main() { +entry: + invoke void @__main( ) + to label %Call2Invoke unwind label %LongJmpBlkPre + +Call2Invoke: ; preds = %entry + br label %LongJmpBlkPre + +LongJmpBlkPre: ; preds = %Call2Invoke, %entry + %i.3 = phi i32 [ 0, %entry ], [ 0, %Call2Invoke ] ; <i32> [#uses=0] + ret i32 0 +} + +define void @__main() { + call void @__llvm_getGlobalCtors( ) + call void @__llvm_getGlobalDtors( ) + ret void +} + +declare void @__llvm_getGlobalCtors() + +declare void @__llvm_getGlobalDtors() + diff --git a/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll b/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll new file mode 100644 index 0000000..1bd5529 --- /dev/null +++ b/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -inline -disable-output + +define i32 @main() { +entry: + invoke void @__main( ) + to label %else unwind label %RethrowExcept + +else: ; preds = %LJDecisionBB, %entry + %i.2 = phi i32 [ 36, %entry ], [ %i.2, %LJDecisionBB ] ; <i32> [#uses=1] + br label %LJDecisionBB + +LJDecisionBB: ; preds = %else + br label %else + +RethrowExcept: ; preds = %entry + ret i32 0 +} + +define void @__main() { + ret void +} + + diff --git a/test/Transforms/Inline/2003-10-13-AllocaDominanceProblem.ll b/test/Transforms/Inline/2003-10-13-AllocaDominanceProblem.ll new file mode 100644 index 0000000..4a80d37 --- /dev/null +++ b/test/Transforms/Inline/2003-10-13-AllocaDominanceProblem.ll @@ -0,0 +1,19 @@ +; RUN: opt < %s -inline -disable-output + +define i32 @reload() { +reloadentry: + br label %A + +A: ; preds = %reloadentry + call void @callee( ) + ret i32 0 +} + +define internal void @callee() { +entry: + %X = alloca i8, i32 0 ; <i8*> [#uses=0] + %Y = bitcast i32 0 to i32 ; <i32> [#uses=1] + %Z = alloca i8, i32 %Y ; <i8*> [#uses=0] + ret void +} + diff --git a/test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll b/test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll new file mode 100644 index 0000000..9afd450 --- /dev/null +++ b/test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll @@ -0,0 +1,20 @@ +; The inliner is breaking inlining invoke instructions where there is a PHI +; node in the exception destination, and the inlined function contains an +; unwind instruction. + +; RUN: opt < %s -inline -disable-output + +define linkonce void @foo() { + unwind +} + +define i32 @test() { +BB1: + invoke void @foo( ) + to label %Cont unwind label %Cont + +Cont: ; preds = %BB1, %BB1 + %A = phi i32 [ 0, %BB1 ], [ 0, %BB1 ] ; <i32> [#uses=1] + ret i32 %A +} + diff --git a/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll b/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll new file mode 100644 index 0000000..3899451 --- /dev/null +++ b/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -inline -disable-output + +; Inlining the first call caused the inliner function to delete the second +; call. Then the inliner tries to inline the second call, which no longer +; exists. + +define internal void @Callee1() { + unwind +} + +define void @Callee2() { + ret void +} + +define void @caller() { + call void @Callee1( ) + call void @Callee2( ) + ret void +} + diff --git a/test/Transforms/Inline/2004-04-20-InlineLinkOnce.ll b/test/Transforms/Inline/2004-04-20-InlineLinkOnce.ll new file mode 100644 index 0000000..fabad30 --- /dev/null +++ b/test/Transforms/Inline/2004-04-20-InlineLinkOnce.ll @@ -0,0 +1,11 @@ +; RUN: opt < %s -inline -prune-eh -disable-output + +define linkonce void @caller() { + call void @callee( ) + ret void +} + +define linkonce void @callee() { + ret void +} + diff --git a/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll b/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll new file mode 100644 index 0000000..733cbb9 --- /dev/null +++ b/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll @@ -0,0 +1,11 @@ +; RUN: opt < %s -inline -disable-output + +define i32 @test() { + unwind +} + +define i32 @caller() { + %X = call i32 @test( ) ; <i32> [#uses=1] + ret i32 %X +} + diff --git a/test/Transforms/Inline/2006-01-14-CallGraphUpdate.ll b/test/Transforms/Inline/2006-01-14-CallGraphUpdate.ll new file mode 100644 index 0000000..415495e --- /dev/null +++ b/test/Transforms/Inline/2006-01-14-CallGraphUpdate.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -inline -prune-eh -disable-output + + %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>" = type { %"struct.std::locale::facet" } + %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >" = type { i32 (...)**, i32*, i32*, i32*, i32*, i32*, i32*, %"struct.std::locale" } + %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" } + %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 } + %"struct.std::ios_base::_Words" = type { i8*, i32 } + %"struct.std::locale" = type { %"struct.std::locale::_Impl"* } + %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** } + %"struct.std::locale::facet" = type { i32 (...)**, i32 } + %"struct.std::ostreambuf_iterator<wchar_t,std::char_traits<wchar_t> >" = type { %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >"*, i32 } + +define void @_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewl(%"struct.std::ostreambuf_iterator<wchar_t,std::char_traits<wchar_t> >"* %agg.result, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"* %this, %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >"* %__s.0__, i32 %__s.1__, %"struct.std::ios_base"* %__io, i32 %__fill, i32 %__v) { +entry: + tail call fastcc void @_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_( ) + ret void +} + +define fastcc void @_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_() { +entry: + %tmp.38 = shl i32 0, 3 ; <i32> [#uses=1] + %tmp.39 = alloca i8, i32 %tmp.38 ; <i8*> [#uses=0] + ret void +} + diff --git a/test/Transforms/Inline/2006-07-12-InlinePruneCGUpdate.ll b/test/Transforms/Inline/2006-07-12-InlinePruneCGUpdate.ll new file mode 100644 index 0000000..6934562 --- /dev/null +++ b/test/Transforms/Inline/2006-07-12-InlinePruneCGUpdate.ll @@ -0,0 +1,840 @@ +; RUN: opt < %s -inline -prune-eh -disable-output +; PR827 +@_ZTV8CRjii = internal global [1 x i32 (...)*] [ i32 (...)* @_ZN8CRjii12NlFeeEPN5Jr7sE ] ; <[1 x i32 (...)*]*> [#uses=0] + +define internal i32 @_ZN8CRjii12NlFeeEPN5Jr7sE(...) { +entry: + br i1 false, label %cond_true, label %cond_false179 + +cond_true: ; preds = %entry + br label %bb9 + +bb: ; preds = %cond_true14 + br label %bb9 + +bb9: ; preds = %bb, %cond_true + br i1 false, label %cond_true14, label %cond_false + +cond_true14: ; preds = %bb9 + br label %bb + +cond_false: ; preds = %bb9 + br label %bb15 + +cond_next: ; No predecessors! + br label %bb15 + +bb15: ; preds = %cond_next, %cond_false + br label %bb24 + +bb17: ; preds = %cond_true29 + br label %bb24 + +bb24: ; preds = %bb17, %bb15 + br i1 false, label %cond_true29, label %cond_false30 + +cond_true29: ; preds = %bb24 + br label %bb17 + +cond_false30: ; preds = %bb24 + br label %bb32 + +cond_next31: ; No predecessors! + br label %bb32 + +bb32: ; preds = %cond_next31, %cond_false30 + br label %bb41 + +bb34: ; preds = %cond_true46 + br label %bb41 + +bb41: ; preds = %bb34, %bb32 + br i1 false, label %cond_true46, label %cond_false47 + +cond_true46: ; preds = %bb41 + br label %bb34 + +cond_false47: ; preds = %bb41 + br label %bb49 + +cond_next48: ; No predecessors! + br label %bb49 + +bb49: ; preds = %cond_next48, %cond_false47 + br label %bb58 + +bb51: ; preds = %cond_true63 + br label %bb58 + +bb58: ; preds = %bb51, %bb49 + br i1 false, label %cond_true63, label %cond_false64 + +cond_true63: ; preds = %bb58 + br label %bb51 + +cond_false64: ; preds = %bb58 + br label %bb66 + +cond_next65: ; No predecessors! + br label %bb66 + +bb66: ; preds = %cond_next65, %cond_false64 + br label %bb76 + +bb68: ; preds = %cond_true81 + br label %bb76 + +bb76: ; preds = %bb68, %bb66 + br i1 false, label %cond_true81, label %cond_false82 + +cond_true81: ; preds = %bb76 + br label %bb68 + +cond_false82: ; preds = %bb76 + br label %bb84 + +cond_next83: ; No predecessors! + br label %bb84 + +bb84: ; preds = %cond_next83, %cond_false82 + br label %bb94 + +bb86: ; preds = %cond_true99 + br label %bb94 + +bb94: ; preds = %bb86, %bb84 + br i1 false, label %cond_true99, label %cond_false100 + +cond_true99: ; preds = %bb94 + br label %bb86 + +cond_false100: ; preds = %bb94 + br label %bb102 + +cond_next101: ; No predecessors! + br label %bb102 + +bb102: ; preds = %cond_next101, %cond_false100 + br label %bb112 + +bb104: ; preds = %cond_true117 + br label %bb112 + +bb112: ; preds = %bb104, %bb102 + br i1 false, label %cond_true117, label %cond_false118 + +cond_true117: ; preds = %bb112 + br label %bb104 + +cond_false118: ; preds = %bb112 + br label %bb120 + +cond_next119: ; No predecessors! + br label %bb120 + +bb120: ; preds = %cond_next119, %cond_false118 + br label %bb130 + +bb122: ; preds = %cond_true135 + br label %bb130 + +bb130: ; preds = %bb122, %bb120 + br i1 false, label %cond_true135, label %cond_false136 + +cond_true135: ; preds = %bb130 + br label %bb122 + +cond_false136: ; preds = %bb130 + br label %bb138 + +cond_next137: ; No predecessors! + br label %bb138 + +bb138: ; preds = %cond_next137, %cond_false136 + br label %bb148 + +bb140: ; preds = %cond_true153 + call fastcc void @_Zjrf1( ) + br label %bb148 + +bb148: ; preds = %bb140, %bb138 + br i1 false, label %cond_true153, label %cond_false154 + +cond_true153: ; preds = %bb148 + br label %bb140 + +cond_false154: ; preds = %bb148 + br label %bb156 + +cond_next155: ; No predecessors! + br label %bb156 + +bb156: ; preds = %cond_next155, %cond_false154 + br label %bb166 + +bb158: ; preds = %cond_true171 + br label %bb166 + +bb166: ; preds = %bb158, %bb156 + br i1 false, label %cond_true171, label %cond_false172 + +cond_true171: ; preds = %bb166 + br label %bb158 + +cond_false172: ; preds = %bb166 + br label %bb174 + +cond_next173: ; No predecessors! + br label %bb174 + +bb174: ; preds = %cond_next173, %cond_false172 + br label %cleanup + +cleanup: ; preds = %bb174 + br label %finally + +finally: ; preds = %cleanup + br label %cond_next180 + +cond_false179: ; preds = %entry + br label %cond_next180 + +cond_next180: ; preds = %cond_false179, %finally + br label %return + +return: ; preds = %cond_next180 + ret i32 0 +} + +define internal fastcc void @_Zjrf2() { +entry: + br label %bb3 + +bb: ; preds = %cond_true + br label %bb3 + +bb3: ; preds = %bb, %entry + %tmp5 = load i8** null ; <i8*> [#uses=1] + %tmp = icmp ne i8* null, %tmp5 ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %cond_false + +cond_true: ; preds = %bb3 + br label %bb + +cond_false: ; preds = %bb3 + br label %bb6 + +cond_next: ; No predecessors! + br label %bb6 + +bb6: ; preds = %cond_next, %cond_false + br label %return + +return: ; preds = %bb6 + ret void +} + +define internal fastcc void @_Zjrf3() { +entry: + call fastcc void @_Zjrf2( ) + br label %return + +return: ; preds = %entry + ret void +} + +define internal fastcc void @_Zjrf4() { +entry: + br label %bb6 + +bb: ; preds = %cond_true + br label %bb6 + +bb6: ; preds = %bb, %entry + br i1 false, label %cond_true, label %cond_false + +cond_true: ; preds = %bb6 + br label %bb + +cond_false: ; preds = %bb6 + br label %bb8 + +cond_next: ; No predecessors! + br label %bb8 + +bb8: ; preds = %cond_next, %cond_false + br i1 false, label %cond_true9, label %cond_false12 + +cond_true9: ; preds = %bb8 + call fastcc void @_Zjrf3( ) + br label %cond_next13 + +cond_false12: ; preds = %bb8 + br label %cond_next13 + +cond_next13: ; preds = %cond_false12, %cond_true9 + br label %return + +return: ; preds = %cond_next13 + ret void +} + +define internal fastcc void @_Zjrf5() { +entry: + call fastcc void @_Zjrf4( ) + br label %return + +return: ; preds = %entry + ret void +} + +define internal fastcc void @_Zjrf6() { +entry: + call fastcc void @_Zjrf5( ) + br label %return + +return: ; preds = %entry + ret void +} + +define internal fastcc void @_Zjrf7() { +entry: + br label %cleanup + +cleanup: ; preds = %entry + br label %finally + +finally: ; preds = %cleanup + call fastcc void @_Zjrf6( ) + br label %cleanup9 + +cleanup9: ; preds = %finally + br label %finally8 + +finally8: ; preds = %cleanup9 + br label %cleanup11 + +cleanup11: ; preds = %finally8 + br label %finally10 + +finally10: ; preds = %cleanup11 + br label %finally23 + +finally23: ; preds = %finally10 + br label %return + +return: ; preds = %finally23 + ret void +} + +define internal fastcc void @_Zjrf11() { +entry: + br label %bb7 + +bb: ; preds = %cond_true + br label %bb7 + +bb7: ; preds = %bb, %entry + br i1 false, label %cond_true, label %cond_false + +cond_true: ; preds = %bb7 + br label %bb + +cond_false: ; preds = %bb7 + br label %bb9 + +cond_next: ; No predecessors! + br label %bb9 + +bb9: ; preds = %cond_next, %cond_false + br label %return + ; No predecessors! + br i1 false, label %cond_true12, label %cond_false15 + +cond_true12: ; preds = %0 + call fastcc void @_Zjrf3( ) + br label %cond_next16 + +cond_false15: ; preds = %0 + br label %cond_next16 + +cond_next16: ; preds = %cond_false15, %cond_true12 + br label %return + +return: ; preds = %cond_next16, %bb9 + ret void +} + +define internal fastcc void @_Zjrf9() { +entry: + call fastcc void @_Zjrf11( ) + br label %return + +return: ; preds = %entry + ret void +} + +define internal fastcc void @_Zjrf10() { +entry: + call fastcc void @_Zjrf9( ) + br label %return + +return: ; preds = %entry + ret void +} + +define internal fastcc void @_Zjrf8() { +entry: + br i1 false, label %cond_true, label %cond_false201 + +cond_true: ; preds = %entry + br i1 false, label %cond_true36, label %cond_false + +cond_true36: ; preds = %cond_true + br label %cleanup + +cleanup: ; preds = %cond_true36 + br label %finally + +finally: ; preds = %cleanup + br label %cond_next189 + +cond_false: ; preds = %cond_true + br i1 false, label %cond_true99, label %cond_false137 + +cond_true99: ; preds = %cond_false + br label %cleanup136 + +cleanup136: ; preds = %cond_true99 + br label %finally135 + +finally135: ; preds = %cleanup136 + br label %cond_next + +cond_false137: ; preds = %cond_false + call fastcc void @_Zjrf10( ) + br label %cleanup188 + +cleanup188: ; preds = %cond_false137 + br label %finally187 + +finally187: ; preds = %cleanup188 + br label %cond_next + +cond_next: ; preds = %finally187, %finally135 + br label %cond_next189 + +cond_next189: ; preds = %cond_next, %finally + br label %cond_next202 + +cond_false201: ; preds = %entry + br label %cond_next202 + +cond_next202: ; preds = %cond_false201, %cond_next189 + br label %return + +return: ; preds = %cond_next202 + ret void +} + +define internal fastcc void @_Zjrf1() { +entry: + br label %bb492 + +bb: ; preds = %cond_true499 + br label %cleanup + +cleanup: ; preds = %bb + br label %finally + +finally: ; preds = %cleanup + br label %cleanup11 + +cleanup11: ; preds = %finally + br label %finally10 + +finally10: ; preds = %cleanup11 + br i1 false, label %cond_true, label %cond_false286 + +cond_true: ; preds = %finally10 + br label %cleanup26 + +cleanup26: ; preds = %cond_true + br label %finally25 + +finally25: ; preds = %cleanup26 + br label %bb30 + +bb27: ; preds = %cond_true37 + br label %bb30 + +bb30: ; preds = %bb27, %finally25 + br i1 false, label %cond_true37, label %cond_false + +cond_true37: ; preds = %bb30 + br label %bb27 + +cond_false: ; preds = %bb30 + br label %bb38 + +cond_next: ; No predecessors! + br label %bb38 + +bb38: ; preds = %cond_next, %cond_false + br label %bb148 + +bb40: ; preds = %cond_true156 + br label %bb139 + +bb41: ; preds = %cond_true142 + call fastcc void @_Zjrf7( ) + br label %bb105 + +bb44: ; preds = %cond_true112 + br label %bb74 + +bb66: ; preds = %cond_true80 + br label %bb74 + +bb74: ; preds = %bb66, %bb44 + br i1 false, label %cond_true80, label %cond_false81 + +cond_true80: ; preds = %bb74 + br label %bb66 + +cond_false81: ; preds = %bb74 + br label %bb83 + +cond_next82: ; No predecessors! + br label %bb83 + +bb83: ; preds = %cond_next82, %cond_false81 + br label %cleanup97 + +cleanup97: ; preds = %bb83 + br label %finally96 + +finally96: ; preds = %cleanup97 + br label %cleanup99 + +cleanup99: ; preds = %finally96 + br label %finally98 + +finally98: ; preds = %cleanup99 + br label %bb105 + +bb105: ; preds = %finally98, %bb41 + br i1 false, label %cond_true112, label %cond_false113 + +cond_true112: ; preds = %bb105 + br label %bb44 + +cond_false113: ; preds = %bb105 + br label %bb115 + +cond_next114: ; No predecessors! + br label %bb115 + +bb115: ; preds = %cond_next114, %cond_false113 + br i1 false, label %cond_true119, label %cond_false123 + +cond_true119: ; preds = %bb115 + call fastcc void @_Zjrf8( ) + br label %cond_next124 + +cond_false123: ; preds = %bb115 + br label %cond_next124 + +cond_next124: ; preds = %cond_false123, %cond_true119 + br i1 false, label %cond_true131, label %cond_false132 + +cond_true131: ; preds = %cond_next124 + br label %cleanup135 + +cond_false132: ; preds = %cond_next124 + br label %cond_next133 + +cond_next133: ; preds = %cond_false132 + br label %cleanup136 + +cleanup135: ; preds = %cond_true131 + br label %done + +cleanup136: ; preds = %cond_next133 + br label %finally134 + +finally134: ; preds = %cleanup136 + br label %bb139 + +bb139: ; preds = %finally134, %bb40 + br i1 false, label %cond_true142, label %cond_false143 + +cond_true142: ; preds = %bb139 + br label %bb41 + +cond_false143: ; preds = %bb139 + br label %bb145 + +cond_next144: ; No predecessors! + br label %bb145 + +bb145: ; preds = %cond_next144, %cond_false143 + br label %bb148 + +bb148: ; preds = %bb145, %bb38 + br i1 false, label %cond_true156, label %cond_false157 + +cond_true156: ; preds = %bb148 + br label %bb40 + +cond_false157: ; preds = %bb148 + br label %bb159 + +cond_next158: ; No predecessors! + br label %bb159 + +bb159: ; preds = %cond_next158, %cond_false157 + br label %done + +done: ; preds = %bb159, %cleanup135 + br label %bb214 + +bb185: ; preds = %cond_true218 + br i1 false, label %cond_true193, label %cond_false206 + +cond_true193: ; preds = %bb185 + br label %cond_next211 + +cond_false206: ; preds = %bb185 + br label %cond_next211 + +cond_next211: ; preds = %cond_false206, %cond_true193 + br label %bb214 + +bb214: ; preds = %cond_next211, %done + br i1 false, label %cond_true218, label %cond_false219 + +cond_true218: ; preds = %bb214 + br label %bb185 + +cond_false219: ; preds = %bb214 + br label %bb221 + +cond_next220: ; No predecessors! + br label %bb221 + +bb221: ; preds = %cond_next220, %cond_false219 + br i1 false, label %cond_true236, label %cond_false245 + +cond_true236: ; preds = %bb221 + br label %cond_next249 + +cond_false245: ; preds = %bb221 + br label %cond_next249 + +cond_next249: ; preds = %cond_false245, %cond_true236 + br i1 false, label %cond_true272, label %cond_false277 + +cond_true272: ; preds = %cond_next249 + br label %cond_next278 + +cond_false277: ; preds = %cond_next249 + br label %cond_next278 + +cond_next278: ; preds = %cond_false277, %cond_true272 + br label %cleanup285 + +cleanup285: ; preds = %cond_next278 + br label %finally284 + +finally284: ; preds = %cleanup285 + br label %cond_next287 + +cond_false286: ; preds = %finally10 + br label %cond_next287 + +cond_next287: ; preds = %cond_false286, %finally284 + br i1 false, label %cond_true317, label %cond_false319 + +cond_true317: ; preds = %cond_next287 + br label %cond_next321 + +cond_false319: ; preds = %cond_next287 + br label %cond_next321 + +cond_next321: ; preds = %cond_false319, %cond_true317 + br label %bb348 + +bb335: ; preds = %cond_true355 + br label %bb348 + +bb348: ; preds = %bb335, %cond_next321 + br i1 false, label %cond_true355, label %cond_false356 + +cond_true355: ; preds = %bb348 + br label %bb335 + +cond_false356: ; preds = %bb348 + br label %bb358 + +cond_next357: ; No predecessors! + br label %bb358 + +bb358: ; preds = %cond_next357, %cond_false356 + br i1 false, label %cond_true363, label %cond_false364 + +cond_true363: ; preds = %bb358 + br label %bb388 + +cond_false364: ; preds = %bb358 + br label %cond_next365 + +cond_next365: ; preds = %cond_false364 + br i1 false, label %cond_true370, label %cond_false371 + +cond_true370: ; preds = %cond_next365 + br label %bb388 + +cond_false371: ; preds = %cond_next365 + br label %cond_next372 + +cond_next372: ; preds = %cond_false371 + br i1 false, label %cond_true385, label %cond_false386 + +cond_true385: ; preds = %cond_next372 + br label %bb388 + +cond_false386: ; preds = %cond_next372 + br label %cond_next387 + +cond_next387: ; preds = %cond_false386 + br label %bb389 + +bb388: ; preds = %cond_true385, %cond_true370, %cond_true363 + br label %bb389 + +bb389: ; preds = %bb388, %cond_next387 + br i1 false, label %cond_true392, label %cond_false443 + +cond_true392: ; preds = %bb389 + br label %bb419 + +bb402: ; preds = %cond_true425 + br i1 false, label %cond_true406, label %cond_false412 + +cond_true406: ; preds = %bb402 + br label %cond_next416 + +cond_false412: ; preds = %bb402 + br label %cond_next416 + +cond_next416: ; preds = %cond_false412, %cond_true406 + br label %bb419 + +bb419: ; preds = %cond_next416, %cond_true392 + br i1 false, label %cond_true425, label %cond_false426 + +cond_true425: ; preds = %bb419 + br label %bb402 + +cond_false426: ; preds = %bb419 + br label %bb428 + +cond_next427: ; No predecessors! + br label %bb428 + +bb428: ; preds = %cond_next427, %cond_false426 + br label %cond_next478 + +cond_false443: ; preds = %bb389 + br label %bb460 + +bb450: ; preds = %cond_true466 + br label %bb460 + +bb460: ; preds = %bb450, %cond_false443 + br i1 false, label %cond_true466, label %cond_false467 + +cond_true466: ; preds = %bb460 + br label %bb450 + +cond_false467: ; preds = %bb460 + br label %bb469 + +cond_next468: ; No predecessors! + br label %bb469 + +bb469: ; preds = %cond_next468, %cond_false467 + br label %cond_next478 + +cond_next478: ; preds = %bb469, %bb428 + br label %cleanup485 + +cleanup485: ; preds = %cond_next478 + br label %finally484 + +finally484: ; preds = %cleanup485 + br label %cleanup487 + +cleanup487: ; preds = %finally484 + br label %finally486 + +finally486: ; preds = %cleanup487 + br label %cleanup489 + +cleanup489: ; preds = %finally486 + br label %finally488 + +finally488: ; preds = %cleanup489 + br label %bb492 + +bb492: ; preds = %finally488, %entry + br i1 false, label %cond_true499, label %cond_false500 + +cond_true499: ; preds = %bb492 + br label %bb + +cond_false500: ; preds = %bb492 + br label %bb502 + +cond_next501: ; No predecessors! + br label %bb502 + +bb502: ; preds = %cond_next501, %cond_false500 + br label %return + +return: ; preds = %bb502 + ret void +} + +define internal fastcc void @_ZSt26__unguarded_insertion_sortIN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEEEvT_S7_() { +entry: + br label %bb12 + +bb: ; preds = %cond_true + br label %cleanup + +cleanup: ; preds = %bb + br label %finally + +finally: ; preds = %cleanup + br label %bb12 + +bb12: ; preds = %finally, %entry + br i1 false, label %cond_true, label %cond_false + +cond_true: ; preds = %bb12 + br label %bb + +cond_false: ; preds = %bb12 + br label %bb14 + +cond_next: ; No predecessors! + br label %bb14 + +bb14: ; preds = %cond_next, %cond_false + br label %return + +return: ; preds = %bb14 + ret void +} diff --git a/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll b/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll new file mode 100644 index 0000000..37cba98 --- /dev/null +++ b/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll @@ -0,0 +1,245 @@ +; RUN: opt < %s -inline -prune-eh -disable-output +; PR993 +target datalayout = "e-p:32:32" +target triple = "i386-unknown-openbsd3.9" +deplibs = [ "stdc++", "c", "crtend" ] + %"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { i8* } + %"struct.__gnu_cxx::char_producer<char>" = type { i32 (...)** } + %struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, i8*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } + %struct.__sbuf = type { i8*, i32 } + %"struct.std::__basic_file<char>" = type { %struct.__sFILE*, i1 } + %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>" = type { %"struct.std::locale::facet" } + %"struct.std::bad_alloc" = type { %"struct.__gnu_cxx::char_producer<char>" } + %"struct.std::basic_filebuf<char,std::char_traits<char> >" = type { %"struct.std::basic_streambuf<char,std::char_traits<char> >", i32, %"struct.std::__basic_file<char>", i32, %union.__mbstate_t, %union.__mbstate_t, i8*, i32, i1, i1, i1, i1, i8, i8*, i8*, i1, %"struct.std::codecvt<char,char,__mbstate_t>"*, i8*, i32, i8*, i8* } + %"struct.std::basic_ios<char,std::char_traits<char> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8, i1, %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, %"struct.std::ctype<char>"*, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"*, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"* } + %"struct.std::basic_iostream<char,std::char_traits<char> >" = type { %"struct.std::locale::facet", %"struct.__gnu_cxx::char_producer<char>", %"struct.std::basic_ios<char,std::char_traits<char> >" } + %"struct.std::basic_ofstream<char,std::char_traits<char> >" = type { %"struct.__gnu_cxx::char_producer<char>", %"struct.std::basic_filebuf<char,std::char_traits<char> >", %"struct.std::basic_ios<char,std::char_traits<char> >" } + %"struct.std::basic_ostream<char,std::char_traits<char> >" = type { i32 (...)**, %"struct.std::basic_ios<char,std::char_traits<char> >" } + %"struct.std::basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" = type { i32, i32, i32 } + %"struct.std::codecvt<char,char,__mbstate_t>" = type { %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>", i32* } + %"struct.std::ctype<char>" = type { %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>", i32*, i1, i32*, i32*, i32* } + %"struct.std::domain_error" = type { %"struct.std::logic_error" } + %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %struct.__sbuf, [8 x %struct.__sbuf], i32, %struct.__sbuf*, %"struct.std::locale" } + %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 } + %"struct.std::ios_base::_Words" = type { i8*, i32 } + %"struct.std::locale" = type { %"struct.std::locale::_Impl"* } + %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** } + %"struct.std::locale::facet" = type { i32 (...)**, i32 } + %"struct.std::logic_error" = type { %"struct.__gnu_cxx::char_producer<char>", %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" } + %union.__mbstate_t = type { i64, [120 x i8] } +@.str_1 = external global [17 x i8] ; <[17 x i8]*> [#uses=0] +@.str_9 = external global [24 x i8] ; <[24 x i8]*> [#uses=0] + +define void @main() { +entry: + call fastcc void @_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode( ) + ret void +} + +define fastcc void @_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode() { +entry: + %tmp.6 = icmp eq %"struct.std::basic_filebuf<char,std::char_traits<char> >"* null, null ; <i1> [#uses=1] + br i1 %tmp.6, label %then, label %UnifiedReturnBlock + +then: ; preds = %entry + tail call fastcc void @_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate( ) + ret void + +UnifiedReturnBlock: ; preds = %entry + ret void +} + +define fastcc void @_ZN10__cxxabiv111__terminateEPFvvE() { +entry: + unreachable +} + +define void @_ZNSdD0Ev() { +entry: + unreachable +} + +define void @_ZThn8_NSdD1Ev() { +entry: + ret void +} + +define void @_ZNSt13basic_filebufIcSt11char_traitsIcEED0Ev() { +entry: + ret void +} + +define void @_ZNSt13basic_filebufIcSt11char_traitsIcEE9pbackfailEi() { +entry: + unreachable +} + +define fastcc void @_ZNSoD2Ev() { +entry: + unreachable +} + +define fastcc void @_ZNSt9basic_iosIcSt11char_traitsIcEED2Ev() { +entry: + unreachable +} + +define fastcc void @_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate() { +entry: + tail call fastcc void @_ZSt19__throw_ios_failurePKc( ) + ret void +} + +declare fastcc void @_ZNSaIcED1Ev() + +define fastcc void @_ZNSsC1EPKcRKSaIcE() { +entry: + tail call fastcc void @_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcE12__false_type( ) + unreachable +} + +define fastcc void @_ZSt14__convert_to_vIyEvPKcRT_RSt12_Ios_IostateRKPii() { +entry: + ret void +} + +define fastcc void @_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej() { +entry: + ret void +} + +define fastcc void @_ZSt19__throw_ios_failurePKc() { +entry: + call fastcc void @_ZNSsC1EPKcRKSaIcE( ) + unwind +} + +define void @_GLOBAL__D__ZSt23lexicographical_compareIPKaS1_EbT_S2_T0_S3_() { +entry: + ret void +} + +define void @_ZNSt9bad_allocD1Ev() { +entry: + unreachable +} + +define fastcc void @_ZSt19__throw_logic_errorPKc() { +entry: + invoke fastcc void @_ZNSt11logic_errorC1ERKSs( ) + to label %try_exit.0 unwind label %try_catch.0 + +try_catch.0: ; preds = %entry + unreachable + +try_exit.0: ; preds = %entry + unwind +} + +define fastcc void @_ZNSt11logic_errorC1ERKSs() { +entry: + call fastcc void @_ZNSsC1ERKSs( ) + ret void +} + +define void @_ZNSt12domain_errorD1Ev() { +entry: + unreachable +} + +define fastcc void @_ZSt20__throw_length_errorPKc() { +entry: + call fastcc void @_ZNSt12length_errorC1ERKSs( ) + unwind +} + +define fastcc void @_ZNSt12length_errorC1ERKSs() { +entry: + invoke fastcc void @_ZNSsC1ERKSs( ) + to label %_ZNSt11logic_errorC2ERKSs.exit unwind label %invoke_catch.i + +invoke_catch.i: ; preds = %entry + unwind + +_ZNSt11logic_errorC2ERKSs.exit: ; preds = %entry + ret void +} + +define fastcc void @_ZNSs4_Rep9_S_createEjRKSaIcE() { +entry: + call fastcc void @_ZSt20__throw_length_errorPKc( ) + unreachable +} + +define fastcc void @_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcESt20forward_iterator_tag() { +entry: + unreachable +} + +define fastcc void @_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcE12__false_type() { +entry: + br i1 false, label %then.1.i, label %endif.1.i + +then.1.i: ; preds = %entry + call fastcc void @_ZSt19__throw_logic_errorPKc( ) + br label %endif.1.i + +endif.1.i: ; preds = %then.1.i, %entry + call fastcc void @_ZNSs4_Rep9_S_createEjRKSaIcE( ) + unreachable +} + +define fastcc void @_ZNSsC1ERKSs() { +entry: + call fastcc void @_ZNSs4_Rep7_M_grabERKSaIcES2_( ) + invoke fastcc void @_ZNSaIcEC1ERKS_( ) + to label %invoke_cont.1 unwind label %invoke_catch.1 + +invoke_catch.1: ; preds = %entry + call fastcc void @_ZNSaIcED1Ev( ) + unwind + +invoke_cont.1: ; preds = %entry + call fastcc void @_ZNSaIcEC2ERKS_( ) + ret void +} + +define fastcc void @_ZNSaIcEC1ERKS_() { +entry: + ret void +} + +define fastcc void @_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc() { +entry: + ret void +} + +define fastcc void @_ZNSs4_Rep7_M_grabERKSaIcES2_() { +entry: + br i1 false, label %else.i, label %cond_true + +cond_true: ; preds = %entry + ret void + +else.i: ; preds = %entry + tail call fastcc void @_ZNSs4_Rep9_S_createEjRKSaIcE( ) + unreachable +} + +define fastcc void @_ZNSaIcEC2ERKS_() { +entry: + ret void +} + +define fastcc void @_ZN9__gnu_cxx12__pool_allocILb1ELi0EE8allocateEj() { +entry: + ret void +} + +define fastcc void @_ZN9__gnu_cxx12__pool_allocILb1ELi0EE9_S_refillEj() { +entry: + unreachable +} diff --git a/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll b/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll new file mode 100644 index 0000000..279823a --- /dev/null +++ b/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll @@ -0,0 +1,338 @@ +; RUN: opt < %s -inline -prune-eh -disable-output +; PR992 +target datalayout = "e-p:32:32" +target triple = "i686-pc-linux-gnu" +deplibs = [ "stdc++", "c", "crtend" ] + %struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i32, [52 x i8] } + %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 } + %"struct.__cxxabiv1::__array_type_info" = type { %"struct.std::type_info" } + %"struct.__cxxabiv1::__si_class_type_info" = type { %"struct.__cxxabiv1::__array_type_info", %"struct.__cxxabiv1::__array_type_info"* } + %"struct.__gnu_cxx::_Rope_rep_alloc_base<char,std::allocator<char>, true>" = type { i32 } + %"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { i8* } + %"struct.__gnu_cxx::__normal_iterator<const wchar_t*,std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > >" = type { i32* } + %"struct.__gnu_cxx::char_producer<char>" = type { i32 (...)** } + %"struct.__gnu_cxx::stdio_sync_filebuf<char,std::char_traits<char> >" = type { %"struct.std::basic_streambuf<char,std::char_traits<char> >", %struct._IO_FILE*, i32 } + %"struct.__gnu_cxx::stdio_sync_filebuf<wchar_t,std::char_traits<wchar_t> >" = type { %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >", %struct._IO_FILE*, i32 } + %struct.__locale_struct = type { [13 x %struct.locale_data*], i16*, i32*, i32*, [13 x i8*] } + %struct.__mbstate_t = type { i32, %"struct.__gnu_cxx::_Rope_rep_alloc_base<char,std::allocator<char>, true>" } + %struct.locale_data = type opaque + %"struct.std::__basic_file<char>" = type { %struct._IO_FILE*, i1 } + %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>" = type { %"struct.std::locale::facet" } + %"struct.std::basic_filebuf<char,std::char_traits<char> >" = type { %"struct.std::basic_streambuf<char,std::char_traits<char> >", i32, %"struct.std::__basic_file<char>", i32, %struct.__mbstate_t, %struct.__mbstate_t, i8*, i32, i1, i1, i1, i1, i8, i8*, i8*, i1, %"struct.std::codecvt<char,char,__mbstate_t>"*, i8*, i32, i8*, i8* } + %"struct.std::basic_filebuf<wchar_t,std::char_traits<wchar_t> >" = type { %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >", i32, %"struct.std::__basic_file<char>", i32, %struct.__mbstate_t, %struct.__mbstate_t, i32*, i32, i1, i1, i1, i1, i32, i32*, i32*, i1, %"struct.std::codecvt<char,char,__mbstate_t>"*, i8*, i32, i8*, i8* } + %"struct.std::basic_fstream<char,std::char_traits<char> >" = type { { %"struct.std::locale::facet", %"struct.__gnu_cxx::char_producer<char>" }, %"struct.std::basic_filebuf<char,std::char_traits<char> >", %"struct.std::basic_ios<char,std::char_traits<char> >" } + %"struct.std::basic_fstream<wchar_t,std::char_traits<wchar_t> >" = type { { %"struct.std::locale::facet", %"struct.__gnu_cxx::char_producer<char>" }, %"struct.std::basic_filebuf<wchar_t,std::char_traits<wchar_t> >", %"struct.std::basic_ios<wchar_t,std::char_traits<wchar_t> >" } + %"struct.std::basic_ios<char,std::char_traits<char> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8, i1, %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, %"struct.std::ctype<char>"*, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"*, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"* } + %"struct.std::basic_ios<wchar_t,std::char_traits<wchar_t> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<wchar_t,std::char_traits<wchar_t> >"*, i32, i1, %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >"*, %"struct.std::codecvt<char,char,__mbstate_t>"*, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"*, %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>"* } + %"struct.std::basic_iostream<wchar_t,std::char_traits<wchar_t> >" = type { %"struct.std::locale::facet", %"struct.__gnu_cxx::char_producer<char>", %"struct.std::basic_ios<wchar_t,std::char_traits<wchar_t> >" } + %"struct.std::basic_ostream<char,std::char_traits<char> >" = type { i32 (...)**, %"struct.std::basic_ios<char,std::char_traits<char> >" } + %"struct.std::basic_ostream<wchar_t,std::char_traits<wchar_t> >" = type { i32 (...)**, %"struct.std::basic_ios<wchar_t,std::char_traits<wchar_t> >" } + %"struct.std::basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" } + %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >" = type { i32 (...)**, i32*, i32*, i32*, i32*, i32*, i32*, %"struct.std::locale" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" = type { i32, i32, i32 } + %"struct.std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >" = type { %"struct.__gnu_cxx::__normal_iterator<const wchar_t*,std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > >" } + %"struct.std::codecvt<char,char,__mbstate_t>" = type { %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>", %struct.__locale_struct* } + %"struct.std::collate<char>" = type { %"struct.std::locale::facet", %struct.__locale_struct* } + %"struct.std::collate_byname<char>" = type { %"struct.std::collate<char>" } + %"struct.std::ctype<char>" = type { %"struct.std::__codecvt_abstract_base<char,char,__mbstate_t>", %struct.__locale_struct*, i1, i32*, i32*, i16* } + %"struct.std::ctype_byname<char>" = type { %"struct.std::ctype<char>" } + %"struct.std::domain_error" = type { %"struct.std::logic_error" } + %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" } + %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 } + %"struct.std::ios_base::_Words" = type { i8*, i32 } + %"struct.std::istreambuf_iterator<char,std::char_traits<char> >" = type { %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, i32 } + %"struct.std::istreambuf_iterator<wchar_t,std::char_traits<wchar_t> >" = type { %"struct.std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >"*, i32 } + %"struct.std::locale" = type { %"struct.std::locale::_Impl"* } + %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** } + %"struct.std::locale::facet" = type { i32 (...)**, i32 } + %"struct.std::logic_error" = type { %"struct.__gnu_cxx::char_producer<char>", %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" } + %"struct.std::type_info" = type { i32 (...)**, i8* } +@.str_11 = external global [42 x i8] ; <[42 x i8]*> [#uses=0] +@.str_9 = external global [24 x i8] ; <[24 x i8]*> [#uses=0] +@.str_1 = external global [17 x i8] ; <[17 x i8]*> [#uses=0] + +define void @main() { +entry: + tail call fastcc void @_ZNSolsEi( ) + ret void +} + +define fastcc void @_ZNSolsEi() { +entry: + %tmp.22 = icmp eq i32 0, 0 ; <i1> [#uses=1] + br i1 %tmp.22, label %else, label %then + +then: ; preds = %entry + ret void + +else: ; preds = %entry + tail call fastcc void @_ZNSolsEl( ) + ret void +} + +define void @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_() { +entry: + ret void +} + +define fastcc void @_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate() { +entry: + tail call fastcc void @_ZSt19__throw_ios_failurePKc( ) + ret void +} + +define fastcc void @_ZNSo3putEc() { +entry: + ret void +} + +define fastcc void @_ZNSolsEl() { +entry: + %tmp.21.i = icmp eq %"struct.std::basic_ostream<char,std::char_traits<char> >"* null, null ; <i1> [#uses=1] + br i1 %tmp.21.i, label %endif.0.i, label %shortcirc_next.i + +shortcirc_next.i: ; preds = %entry + ret void + +endif.0.i: ; preds = %entry + call fastcc void @_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate( ) + ret void +} + +define fastcc void @_ZSt19__throw_ios_failurePKc() { +entry: + call fastcc void @_ZNSsC1EPKcRKSaIcE( ) + ret void +} + +define fastcc void @_ZNSt8ios_baseD2Ev() { +entry: + unreachable +} + +define void @_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE5uflowEv() { +entry: + unreachable +} + +define void @_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED1Ev() { +entry: + unreachable +} + +define void @_ZNSt15basic_streambufIcSt11char_traitsIcEE6setbufEPci() { +entry: + ret void +} + +define fastcc void @_ZSt9use_facetISt5ctypeIcEERKT_RKSt6locale() { +entry: + ret void +} + +declare fastcc void @_ZNSaIcED1Ev() + +define fastcc void @_ZSt19__throw_logic_errorPKc() { +entry: + call fastcc void @_ZNSt11logic_errorC1ERKSs( ) + ret void +} + +define fastcc void @_ZNSs4_Rep9_S_createEjRKSaIcE() { +entry: + br i1 false, label %then.0, label %endif.0 + +then.0: ; preds = %entry + call fastcc void @_ZSt20__throw_length_errorPKc( ) + ret void + +endif.0: ; preds = %entry + ret void +} + +define fastcc void @_ZSt20__throw_length_errorPKc() { +entry: + call fastcc void @_ZNSt12length_errorC1ERKSs( ) + unwind +} + +define fastcc void @_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcE12__false_type() { +entry: + br i1 false, label %then.1.i, label %endif.1.i + +then.1.i: ; preds = %entry + call fastcc void @_ZSt19__throw_logic_errorPKc( ) + ret void + +endif.1.i: ; preds = %entry + call fastcc void @_ZNSs4_Rep9_S_createEjRKSaIcE( ) + unreachable +} + +define fastcc void @_ZNSsC1ERKSs() { +entry: + call fastcc void @_ZNSs4_Rep7_M_grabERKSaIcES2_( ) + invoke fastcc void @_ZNSaIcEC1ERKS_( ) + to label %invoke_cont.1 unwind label %invoke_catch.1 + +invoke_catch.1: ; preds = %entry + call fastcc void @_ZNSaIcED1Ev( ) + unwind + +invoke_cont.1: ; preds = %entry + call fastcc void @_ZNSaIcEC2ERKS_( ) + ret void +} + +define fastcc void @_ZNSs7reserveEj() { +entry: + ret void +} + +define fastcc void @_ZNSaIcEC1ERKS_() { +entry: + ret void +} + +define fastcc void @_ZNSs4_Rep7_M_grabERKSaIcES2_() { +entry: + br i1 false, label %else.i, label %cond_true + +cond_true: ; preds = %entry + ret void + +else.i: ; preds = %entry + tail call fastcc void @_ZNSs4_Rep9_S_createEjRKSaIcE( ) + ret void +} + +define fastcc void @_ZNSsC1EPKcRKSaIcE() { +entry: + tail call fastcc void @_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcE12__false_type( ) + unreachable +} + +define fastcc void @_ZNSaIcEC2ERKS_() { +entry: + ret void +} + +define void @_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev() { +entry: + unreachable +} + +define void @_ZNSt14collate_bynameIcED1Ev() { +entry: + unreachable +} + +define void @_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy() { +entry: + ret void +} + +define void @_ZNSt23__codecvt_abstract_baseIcc11__mbstate_tED1Ev() { +entry: + unreachable +} + +define void @_ZNSt12ctype_bynameIcED0Ev() { +entry: + unreachable +} + +define fastcc void @_ZNSt8messagesIwEC1Ej() { +entry: + ret void +} + +define fastcc void @_ZSt14__convert_to_vIlEvPKcRT_RSt12_Ios_IostateRKP15__locale_structi() { +entry: + ret void +} + +define fastcc void @_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Ej() { +entry: + ret void +} + +define fastcc void @_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Ej() { +entry: + ret void +} + +define fastcc void @_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs() { +entry: + unreachable +} + +define fastcc void @_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_() { +entry: + ret void +} + +define void @_ZNSt14basic_iostreamIwSt11char_traitsIwEED0Ev() { +entry: + unreachable +} + +define void @_ZNSt15basic_streambufIcSt11char_traitsIcEE9showmanycEv() { +entry: + ret void +} + +define void @_ZNSt9exceptionD0Ev() { +entry: + unreachable +} + +define fastcc void @_ZNSt11logic_errorC1ERKSs() { +entry: + call fastcc void @_ZNSsC1ERKSs( ) + ret void +} + +define fastcc void @_ZNSt11logic_errorD2Ev() { +entry: + unreachable +} + +define fastcc void @_ZNSt12length_errorC1ERKSs() { +entry: + invoke fastcc void @_ZNSsC1ERKSs( ) + to label %_ZNSt11logic_errorC2ERKSs.exit unwind label %invoke_catch.i + +invoke_catch.i: ; preds = %entry + unwind + +_ZNSt11logic_errorC2ERKSs.exit: ; preds = %entry + ret void +} + +define void @_ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_() { +entry: + ret void +} + +define fastcc void @_ZNSbIwSt11char_traitsIwESaIwEE16_S_construct_auxIPKwEEPwT_S7_RKS1_12__false_type() { +entry: + ret void +} + +define void @_ZTv0_n12_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev() { +entry: + ret void +} + +define void @_ZNSt13basic_fstreamIcSt11char_traitsIcEED1Ev() { +entry: + unreachable +} + +define fastcc void @_ZNSt5ctypeIcEC1EPKtbj() { +entry: + ret void +} diff --git a/test/Transforms/Inline/2007-04-15-InlineEH.ll b/test/Transforms/Inline/2007-04-15-InlineEH.ll new file mode 100644 index 0000000..635f93e --- /dev/null +++ b/test/Transforms/Inline/2007-04-15-InlineEH.ll @@ -0,0 +1,49 @@ +; RUN: opt < %s -inline -S | not grep {invoke void asm} +; PR1335 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64" +target triple = "i686-pc-linux-gnu" + %struct.gnat__strings__string_access = type { i8*, %struct.string___XUB* } + %struct.string___XUB = type { i32, i32 } + +define void @bc__support__high_resolution_time__clock() { +entry: + call void asm "rdtsc\0A\09movl %eax, $0\0A\09movl %edx, $1", "=*imr,=*imr,~{dirflag},~{fpsr},~{flags},~{dx},~{ax}"( i32* null, i32* null ) nounwind + unreachable +} + +define fastcc void @bc__support__high_resolution_time__initialize_clock_rate() { +entry: + invoke void @gnat__os_lib__getenv( %struct.gnat__strings__string_access* null ) + to label %invcont unwind label %cleanup144 + +invcont: ; preds = %entry + invoke void @ada__calendar__delays__delay_for( ) + to label %invcont64 unwind label %cleanup144 + +invcont64: ; preds = %invcont + invoke void @ada__calendar__clock( ) + to label %invcont65 unwind label %cleanup144 + +invcont65: ; preds = %invcont64 + invoke void @bc__support__high_resolution_time__clock( ) + to label %invcont67 unwind label %cleanup144 + +invcont67: ; preds = %invcont65 + ret void + +cleanup144: ; preds = %invcont65, %invcont64, %invcont, %entry + unwind +} + +declare void @gnat__os_lib__getenv(%struct.gnat__strings__string_access*) + +declare void @ada__calendar__delays__delay_for() + +declare void @ada__calendar__clock() + +define void @bc__support__high_resolution_time___elabb() { +entry: + call fastcc void @bc__support__high_resolution_time__initialize_clock_rate( ) + ret void +} diff --git a/test/Transforms/Inline/2007-06-06-NoInline.ll b/test/Transforms/Inline/2007-06-06-NoInline.ll new file mode 100644 index 0000000..d5a7953 --- /dev/null +++ b/test/Transforms/Inline/2007-06-06-NoInline.ll @@ -0,0 +1,46 @@ +; RUN: opt < %s -inline -S | grep "define internal i32 @bar" +@llvm.noinline = appending global [1 x i8*] [ i8* bitcast (i32 (i32, i32)* @bar to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define internal i32 @bar(i32 %x, i32 %y) { +entry: + %x_addr = alloca i32 ; <i32*> [#uses=2] + %y_addr = alloca i32 ; <i32*> [#uses=2] + %retval = alloca i32, align 4 ; <i32*> [#uses=2] + %tmp = alloca i32, align 4 ; <i32*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %x, i32* %x_addr + store i32 %y, i32* %y_addr + %tmp1 = load i32* %x_addr ; <i32> [#uses=1] + %tmp2 = load i32* %y_addr ; <i32> [#uses=1] + %tmp3 = add i32 %tmp1, %tmp2 ; <i32> [#uses=1] + store i32 %tmp3, i32* %tmp + %tmp4 = load i32* %tmp ; <i32> [#uses=1] + store i32 %tmp4, i32* %retval + br label %return + +return: ; preds = %entry + %retval5 = load i32* %retval ; <i32> [#uses=1] + ret i32 %retval5 +} + +define i32 @foo(i32 %a, i32 %b) { +entry: + %a_addr = alloca i32 ; <i32*> [#uses=2] + %b_addr = alloca i32 ; <i32*> [#uses=2] + %retval = alloca i32, align 4 ; <i32*> [#uses=2] + %tmp = alloca i32, align 4 ; <i32*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %a, i32* %a_addr + store i32 %b, i32* %b_addr + %tmp1 = load i32* %b_addr ; <i32> [#uses=1] + %tmp2 = load i32* %a_addr ; <i32> [#uses=1] + %tmp3 = call i32 @bar( i32 %tmp1, i32 %tmp2 ) ; <i32> [#uses=1] + store i32 %tmp3, i32* %tmp + %tmp4 = load i32* %tmp ; <i32> [#uses=1] + store i32 %tmp4, i32* %retval + br label %return + +return: ; preds = %entry + %retval5 = load i32* %retval ; <i32> [#uses=1] + ret i32 %retval5 +} diff --git a/test/Transforms/Inline/2007-06-25-WeakInline.ll b/test/Transforms/Inline/2007-06-25-WeakInline.ll new file mode 100644 index 0000000..929891a --- /dev/null +++ b/test/Transforms/Inline/2007-06-25-WeakInline.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -inline -S | grep call + +; 'bar' can be overridden at link-time, don't inline it. + +define void @foo() { +entry: + tail call void @bar( ) ; <i32> [#uses=0] + ret void +} + +define weak void @bar() { + ret void +} + diff --git a/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll b/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll new file mode 100644 index 0000000..979157e --- /dev/null +++ b/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll @@ -0,0 +1,19 @@ +; RUN: opt < %s -inline -S | grep nounwind +; RUN: opt < %s -inline -S | grep unreachable + +declare i1 @extern() + +define internal i32 @test() { +entry: + %n = call i1 @extern( ) + br i1 %n, label %r, label %u +r: + ret i32 0 +u: + unwind +} + +define i32 @caller() { + %X = call i32 @test( ) nounwind + ret i32 %X +} diff --git a/test/Transforms/Inline/2008-03-04-StructRet.ll b/test/Transforms/Inline/2008-03-04-StructRet.ll new file mode 100644 index 0000000..3311d56 --- /dev/null +++ b/test/Transforms/Inline/2008-03-04-StructRet.ll @@ -0,0 +1,28 @@ +; RUN: opt < %s -inline -disable-output + %struct.Benchmark = type { i32 (...)** } + %struct.Complex = type { double, double } + %struct.ComplexBenchmark = type { %struct.Benchmark } + +define %struct.Complex @_Zml7ComplexS_1(double %a.0, double %a.1, double %b.0, double %b.1) nounwind { +entry: + %mrv = alloca %struct.Complex ; <%struct.Complex*> [#uses=2] + %mrv.gep = getelementptr %struct.Complex* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld = load double* %mrv.gep ; <double> [#uses=1] + %mrv.gep1 = getelementptr %struct.Complex* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld2 = load double* %mrv.gep1 ; <double> [#uses=1] + ret double %mrv.ld, double %mrv.ld2 +} + +define void @_ZNK16ComplexBenchmark9oop_styleEv(%struct.ComplexBenchmark* %this) nounwind { +entry: + %tmp = alloca %struct.Complex ; <%struct.Complex*> [#uses=0] + br label %bb31 +bb: ; preds = %bb31 + call %struct.Complex @_Zml7ComplexS_1( double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00 ) nounwind ; <%struct.Complex>:0 [#uses=1] + %gr = getresult %struct.Complex %0, 1 ; <double> [#uses=0] + br label %bb31 +bb31: ; preds = %bb, %entry + br i1 false, label %bb, label %return +return: ; preds = %bb31 + ret void +} diff --git a/test/Transforms/Inline/2008-03-07-Inline-2.ll b/test/Transforms/Inline/2008-03-07-Inline-2.ll new file mode 100644 index 0000000..0c968e6 --- /dev/null +++ b/test/Transforms/Inline/2008-03-07-Inline-2.ll @@ -0,0 +1,53 @@ +; RUN: opt < %s -inline -disable-output + %struct.Demand = type { double, double } + %struct.branch = type { %struct.Demand, double, double, double, double, %struct.branch*, [12 x %struct.leaf*] } + %struct.leaf = type { %struct.Demand, double, double } +@P = external global double ; <double*> [#uses=1] + +define %struct.leaf* @build_leaf() nounwind { +entry: + unreachable +} + +define %struct.Demand @Compute_Branch2(%struct.branch* %br, double %theta_R, double %theta_I, double %pi_R, double %pi_I) nounwind { +entry: + %mrv = alloca %struct.Demand ; <%struct.Demand*> [#uses=4] + %a2 = alloca %struct.Demand ; <%struct.Demand*> [#uses=0] + br i1 false, label %bb46, label %bb +bb: ; preds = %entry + %mrv.gep = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld = load double* %mrv.gep ; <double> [#uses=1] + %mrv.gep1 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld2 = load double* %mrv.gep1 ; <double> [#uses=1] + ret double %mrv.ld, double %mrv.ld2 +bb46: ; preds = %entry + br label %bb72 +bb49: ; preds = %bb72 + call %struct.Demand @Compute_Leaf1( %struct.leaf* null, double 0.000000e+00, double 0.000000e+00 ) nounwind ; <%struct.Demand>:0 [#uses=1] + %gr = getresult %struct.Demand %0, 1 ; <double> [#uses=0] + br label %bb72 +bb72: ; preds = %bb49, %bb46 + br i1 false, label %bb49, label %bb77 +bb77: ; preds = %bb72 + %mrv.gep3 = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld4 = load double* %mrv.gep3 ; <double> [#uses=1] + %mrv.gep5 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld6 = load double* %mrv.gep5 ; <double> [#uses=1] + ret double %mrv.ld4, double %mrv.ld6 +} + +define %struct.Demand @Compute_Leaf1(%struct.leaf* %l, double %pi_R, double %pi_I) nounwind { +entry: + %mrv = alloca %struct.Demand ; <%struct.Demand*> [#uses=2] + %tmp10 = load double* @P, align 8 ; <double> [#uses=1] + %tmp11 = fcmp olt double %tmp10, 0.000000e+00 ; <i1> [#uses=1] + br i1 %tmp11, label %bb, label %bb13 +bb: ; preds = %entry + br label %bb13 +bb13: ; preds = %bb, %entry + %mrv.gep = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld = load double* %mrv.gep ; <double> [#uses=1] + %mrv.gep1 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld2 = load double* %mrv.gep1 ; <double> [#uses=1] + ret double %mrv.ld, double %mrv.ld2 +} diff --git a/test/Transforms/Inline/2008-03-07-Inline.ll b/test/Transforms/Inline/2008-03-07-Inline.ll new file mode 100644 index 0000000..86afb2d --- /dev/null +++ b/test/Transforms/Inline/2008-03-07-Inline.ll @@ -0,0 +1,57 @@ +; RUN: opt < %s -inline -disable-output + %struct.Demand = type { double, double } + %struct.branch = type { %struct.Demand, double, double, double, double, %struct.branch*, [12 x %struct.leaf*] } + %struct.leaf = type { %struct.Demand, double, double } +@P = external global double ; <double*> [#uses=1] + +define %struct.leaf* @build_leaf() nounwind { +entry: + unreachable +} + +define %struct.Demand @Compute_Branch2(%struct.branch* %br, double %theta_R, double %theta_I, double %pi_R, double %pi_I) nounwind { +entry: + %mrv = alloca %struct.Demand ; <%struct.Demand*> [#uses=4] + %a2 = alloca %struct.Demand ; <%struct.Demand*> [#uses=0] + br i1 false, label %bb46, label %bb +bb: ; preds = %entry + %mrv.gep = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld = load double* %mrv.gep ; <double> [#uses=1] + %mrv.gep1 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld2 = load double* %mrv.gep1 ; <double> [#uses=1] + ret double %mrv.ld, double %mrv.ld2 +bb46: ; preds = %entry + br label %bb72 +bb49: ; preds = %bb72 + call %struct.Demand @Compute_Leaf1( %struct.leaf* null, double 0.000000e+00, double 0.000000e+00 ) nounwind ; <%struct.Demand>:0 [#uses=1] + %gr = getresult %struct.Demand %0, 1 ; <double> [#uses=0] + br label %bb72 +bb72: ; preds = %bb49, %bb46 + br i1 false, label %bb49, label %bb77 +bb77: ; preds = %bb72 + %mrv.gep3 = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld4 = load double* %mrv.gep3 ; <double> [#uses=1] + %mrv.gep5 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld6 = load double* %mrv.gep5 ; <double> [#uses=1] + ret double %mrv.ld4, double %mrv.ld6 +} + +define %struct.Demand @Compute_Leaf1(%struct.leaf* %l, double %pi_R, double %pi_I) nounwind { +entry: + %mrv = alloca %struct.Demand ; <%struct.Demand*> [#uses=4] + %tmp10 = load double* @P, align 8 ; <double> [#uses=1] + %tmp11 = fcmp olt double %tmp10, 0.000000e+00 ; <i1> [#uses=1] + br i1 %tmp11, label %bb, label %bb13 +bb: ; preds = %entry + %mrv.gep = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld = load double* %mrv.gep ; <double> [#uses=1] + %mrv.gep1 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld2 = load double* %mrv.gep1 ; <double> [#uses=1] + ret double %mrv.ld, double %mrv.ld2 +bb13: ; preds = %entry + %mrv.gep3 = getelementptr %struct.Demand* %mrv, i32 0, i32 0 ; <double*> [#uses=1] + %mrv.ld4 = load double* %mrv.gep3 ; <double> [#uses=1] + %mrv.gep5 = getelementptr %struct.Demand* %mrv, i32 0, i32 1 ; <double*> [#uses=1] + %mrv.ld6 = load double* %mrv.gep5 ; <double> [#uses=1] + ret double %mrv.ld4, double %mrv.ld6 +} diff --git a/test/Transforms/Inline/2008-09-02-AlwaysInline.ll b/test/Transforms/Inline/2008-09-02-AlwaysInline.ll new file mode 100644 index 0000000..39095c4 --- /dev/null +++ b/test/Transforms/Inline/2008-09-02-AlwaysInline.ll @@ -0,0 +1,10 @@ +; RUN: opt < %s -inline-threshold=0 -inline -S | not grep call + +define i32 @fn2() alwaysinline { + ret i32 1 +} + +define i32 @fn3() { + %r = call i32 @fn2() + ret i32 %r +} diff --git a/test/Transforms/Inline/2008-09-02-NoInline.ll b/test/Transforms/Inline/2008-09-02-NoInline.ll new file mode 100644 index 0000000..33c8949 --- /dev/null +++ b/test/Transforms/Inline/2008-09-02-NoInline.ll @@ -0,0 +1,10 @@ +; RUN: opt < %s -inline -S | grep call | count 1 + +define i32 @fn2() noinline { + ret i32 1 +} + +define i32 @fn3() { + %r = call i32 @fn2() + ret i32 %r +} diff --git a/test/Transforms/Inline/2008-10-30-AlwaysInline.ll b/test/Transforms/Inline/2008-10-30-AlwaysInline.ll new file mode 100644 index 0000000..11e5012 --- /dev/null +++ b/test/Transforms/Inline/2008-10-30-AlwaysInline.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -always-inline -S | not grep call + +; Ensure that threshold doesn't disrupt always inline. +; RUN: opt < %s -inline-threshold=-2000000001 -always-inline -S | not grep call + + +define internal i32 @if0() alwaysinline { + ret i32 1 +} + +define i32 @f0() { + %r = call i32 @if0() + ret i32 %r +} diff --git a/test/Transforms/Inline/2008-11-04-AlwaysInline.ll b/test/Transforms/Inline/2008-11-04-AlwaysInline.ll new file mode 100644 index 0000000..bc9787b --- /dev/null +++ b/test/Transforms/Inline/2008-11-04-AlwaysInline.ll @@ -0,0 +1,7 @@ +; RUN: opt < %s -always-inline -S | grep {@foo} +; Ensure that foo is not removed by always inliner +; PR 2945 + +define internal i32 @foo() nounwind { + ret i32 0 +} diff --git a/test/Transforms/Inline/2009-01-08-NoInlineDynamicAlloca.ll b/test/Transforms/Inline/2009-01-08-NoInlineDynamicAlloca.ll new file mode 100644 index 0000000..db2a799 --- /dev/null +++ b/test/Transforms/Inline/2009-01-08-NoInlineDynamicAlloca.ll @@ -0,0 +1,36 @@ +; RUN: opt < %s -inline -S | grep call +; Do not inline calls to variable-sized alloca. + +@q = common global i8* null ; <i8**> [#uses=1] + +define i8* @a(i32 %i) nounwind { +entry: + %i_addr = alloca i32 ; <i32*> [#uses=2] + %retval = alloca i8* ; <i8**> [#uses=1] + %p = alloca i8* ; <i8**> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %i, i32* %i_addr + %0 = load i32* %i_addr, align 4 ; <i32> [#uses=1] + %1 = alloca i8, i32 %0 ; <i8*> [#uses=1] + store i8* %1, i8** %p, align 4 + %2 = load i8** %p, align 4 ; <i8*> [#uses=1] + store i8* %2, i8** @q, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i8** %retval ; <i8*> [#uses=1] + ret i8* %retval1 +} + +define void @b(i32 %i) nounwind { +entry: + %i_addr = alloca i32 ; <i32*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %i, i32* %i_addr + %0 = load i32* %i_addr, align 4 ; <i32> [#uses=1] + %1 = call i8* @a(i32 %0) nounwind ; <i8*> [#uses=0] + br label %return + +return: ; preds = %entry + ret void +} diff --git a/test/Transforms/Inline/2009-01-12-RecursiveInline.ll b/test/Transforms/Inline/2009-01-12-RecursiveInline.ll new file mode 100644 index 0000000..1a3325a --- /dev/null +++ b/test/Transforms/Inline/2009-01-12-RecursiveInline.ll @@ -0,0 +1,92 @@ +; RUN: opt < %s -inline -S | grep {call.*fib} | count 4 +; First call to fib from fib is inlined, producing 2 instead of 1, total 3. +; Second call to fib from fib is not inlined because new body of fib exceeds +; inlining limit of 200. Plus call in main = 4 total. + +; ModuleID = '<stdin>' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.6" +@"\01LC" = internal constant [5 x i8] c"%ld\0A\00" ; <[5 x i8]*> [#uses=1] + +define i32 @fib(i32 %n) nounwind { +entry: + %n_addr = alloca i32 ; <i32*> [#uses=4] + %retval = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %n, i32* %n_addr + %1 = load i32* %n_addr, align 4 ; <i32> [#uses=1] + %2 = icmp ule i32 %1, 1 ; <i1> [#uses=1] + br i1 %2, label %bb, label %bb1 + +bb: ; preds = %entry + store i32 1, i32* %0, align 4 + br label %bb2 + +bb1: ; preds = %entry + %3 = load i32* %n_addr, align 4 ; <i32> [#uses=1] + %4 = sub i32 %3, 2 ; <i32> [#uses=1] + %5 = call i32 @fib(i32 %4) nounwind ; <i32> [#uses=1] + %6 = load i32* %n_addr, align 4 ; <i32> [#uses=1] + %7 = sub i32 %6, 1 ; <i32> [#uses=1] + %8 = call i32 @fib(i32 %7) nounwind ; <i32> [#uses=1] + %9 = add i32 %5, %8 ; <i32> [#uses=1] + store i32 %9, i32* %0, align 4 + br label %bb2 + +bb2: ; preds = %bb1, %bb + %10 = load i32* %0, align 4 ; <i32> [#uses=1] + store i32 %10, i32* %retval, align 4 + br label %return + +return: ; preds = %bb2 + %retval3 = load i32* %retval ; <i32> [#uses=1] + ret i32 %retval3 +} + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + %argc_addr = alloca i32 ; <i32*> [#uses=2] + %argv_addr = alloca i8** ; <i8***> [#uses=2] + %retval = alloca i32 ; <i32*> [#uses=2] + %N = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=2] + %iftmp.0 = alloca i32 ; <i32*> [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %argc, i32* %argc_addr + store i8** %argv, i8*** %argv_addr + %1 = load i32* %argc_addr, align 4 ; <i32> [#uses=1] + %2 = icmp eq i32 %1, 2 ; <i1> [#uses=1] + br i1 %2, label %bb, label %bb1 + +bb: ; preds = %entry + %3 = load i8*** %argv_addr, align 4 ; <i8**> [#uses=1] + %4 = getelementptr i8** %3, i32 1 ; <i8**> [#uses=1] + %5 = load i8** %4, align 4 ; <i8*> [#uses=1] + %6 = call i32 @atoi(i8* %5) nounwind ; <i32> [#uses=1] + store i32 %6, i32* %iftmp.0, align 4 + br label %bb2 + +bb1: ; preds = %entry + store i32 43, i32* %iftmp.0, align 4 + br label %bb2 + +bb2: ; preds = %bb1, %bb + %7 = load i32* %iftmp.0, align 4 ; <i32> [#uses=1] + store i32 %7, i32* %N, align 4 + %8 = load i32* %N, align 4 ; <i32> [#uses=1] + %9 = call i32 @fib(i32 %8) nounwind ; <i32> [#uses=1] + %10 = call i32 (i8*, ...)* @printf(i8* getelementptr ([5 x i8]* @"\01LC", i32 0, i32 0), i32 %9) nounwind ; <i32> [#uses=0] + store i32 0, i32* %0, align 4 + %11 = load i32* %0, align 4 ; <i32> [#uses=1] + store i32 %11, i32* %retval, align 4 + br label %return + +return: ; preds = %bb2 + %retval3 = load i32* %retval ; <i32> [#uses=1] + ret i32 %retval3 +} + +declare i32 @atoi(i8*) + +declare i32 @printf(i8*, ...) nounwind diff --git a/test/Transforms/Inline/2009-01-13-RecursiveInlineCrash.ll b/test/Transforms/Inline/2009-01-13-RecursiveInlineCrash.ll new file mode 100644 index 0000000..7d8d16b --- /dev/null +++ b/test/Transforms/Inline/2009-01-13-RecursiveInlineCrash.ll @@ -0,0 +1,293 @@ +; RUN: opt < %s -inline -argpromotion -disable-output +; ModuleID = '<stdin>' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.6" + %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* } +@NumNodes = external global i32 ; <i32*> [#uses=0] +@"\01LC" = external constant [43 x i8] ; <[43 x i8]*> [#uses=0] +@"\01LC1" = external constant [19 x i8] ; <[19 x i8]*> [#uses=0] +@"\01LC2" = external constant [17 x i8] ; <[17 x i8]*> [#uses=0] + +declare i32 @dealwithargs(i32, i8** nocapture) nounwind + +declare i32 @atoi(i8*) + +define internal fastcc i32 @adj(i32 %d, i32 %ct) nounwind readnone { +entry: + switch i32 %d, label %return [ + i32 0, label %bb + i32 1, label %bb10 + i32 2, label %bb5 + i32 3, label %bb15 + ] + +bb: ; preds = %entry + switch i32 %ct, label %bb3 [ + i32 1, label %return + i32 0, label %return + ] + +bb3: ; preds = %bb + ret i32 0 + +bb5: ; preds = %entry + switch i32 %ct, label %bb8 [ + i32 3, label %return + i32 2, label %return + ] + +bb8: ; preds = %bb5 + ret i32 0 + +bb10: ; preds = %entry + switch i32 %ct, label %bb13 [ + i32 1, label %return + i32 3, label %return + ] + +bb13: ; preds = %bb10 + ret i32 0 + +bb15: ; preds = %entry + switch i32 %ct, label %bb18 [ + i32 2, label %return + i32 0, label %return + ] + +bb18: ; preds = %bb15 + ret i32 0 + +return: ; preds = %bb15, %bb15, %bb10, %bb10, %bb5, %bb5, %bb, %bb, %entry + ret i32 1 +} + +declare fastcc i32 @reflect(i32, i32) nounwind readnone + +declare i32 @CountTree(%struct.quad_struct* nocapture) nounwind readonly + +define internal fastcc %struct.quad_struct* @child(%struct.quad_struct* nocapture %tree, i32 %ct) nounwind readonly { +entry: + switch i32 %ct, label %bb5 [ + i32 0, label %bb1 + i32 1, label %bb + i32 2, label %bb3 + i32 3, label %bb2 + ] + +bb: ; preds = %entry + %0 = getelementptr %struct.quad_struct* %tree, i32 0, i32 3 ; <%struct.quad_struct**> [#uses=1] + %1 = load %struct.quad_struct** %0, align 4 ; <%struct.quad_struct*> [#uses=1] + ret %struct.quad_struct* %1 + +bb1: ; preds = %entry + %2 = getelementptr %struct.quad_struct* %tree, i32 0, i32 2 ; <%struct.quad_struct**> [#uses=1] + %3 = load %struct.quad_struct** %2, align 4 ; <%struct.quad_struct*> [#uses=1] + ret %struct.quad_struct* %3 + +bb2: ; preds = %entry + %4 = getelementptr %struct.quad_struct* %tree, i32 0, i32 5 ; <%struct.quad_struct**> [#uses=1] + %5 = load %struct.quad_struct** %4, align 4 ; <%struct.quad_struct*> [#uses=1] + ret %struct.quad_struct* %5 + +bb3: ; preds = %entry + %6 = getelementptr %struct.quad_struct* %tree, i32 0, i32 4 ; <%struct.quad_struct**> [#uses=1] + %7 = load %struct.quad_struct** %6, align 4 ; <%struct.quad_struct*> [#uses=1] + ret %struct.quad_struct* %7 + +bb5: ; preds = %entry + ret %struct.quad_struct* null +} + +define internal fastcc %struct.quad_struct* @gtequal_adj_neighbor(%struct.quad_struct* nocapture %tree, i32 %d) nounwind readonly { +entry: + %0 = getelementptr %struct.quad_struct* %tree, i32 0, i32 6 ; <%struct.quad_struct**> [#uses=1] + %1 = load %struct.quad_struct** %0, align 4 ; <%struct.quad_struct*> [#uses=4] + %2 = getelementptr %struct.quad_struct* %tree, i32 0, i32 1 ; <i32*> [#uses=1] + %3 = load i32* %2, align 4 ; <i32> [#uses=2] + %4 = icmp eq %struct.quad_struct* %1, null ; <i1> [#uses=1] + br i1 %4, label %bb3, label %bb + +bb: ; preds = %entry + %5 = call fastcc i32 @adj(i32 %d, i32 %3) nounwind ; <i32> [#uses=1] + %6 = icmp eq i32 %5, 0 ; <i1> [#uses=1] + br i1 %6, label %bb3, label %bb1 + +bb1: ; preds = %bb + %7 = call fastcc %struct.quad_struct* @gtequal_adj_neighbor(%struct.quad_struct* %1, i32 %d) nounwind ; <%struct.quad_struct*> [#uses=1] + br label %bb3 + +bb3: ; preds = %bb1, %bb, %entry + %q.0 = phi %struct.quad_struct* [ %7, %bb1 ], [ %1, %bb ], [ %1, %entry ] ; <%struct.quad_struct*> [#uses=4] + %8 = icmp eq %struct.quad_struct* %q.0, null ; <i1> [#uses=1] + br i1 %8, label %bb7, label %bb4 + +bb4: ; preds = %bb3 + %9 = getelementptr %struct.quad_struct* %q.0, i32 0, i32 0 ; <i32*> [#uses=1] + %10 = load i32* %9, align 4 ; <i32> [#uses=1] + %11 = icmp eq i32 %10, 2 ; <i1> [#uses=1] + br i1 %11, label %bb5, label %bb7 + +bb5: ; preds = %bb4 + %12 = call fastcc i32 @reflect(i32 %d, i32 %3) nounwind ; <i32> [#uses=1] + %13 = call fastcc %struct.quad_struct* @child(%struct.quad_struct* %q.0, i32 %12) nounwind ; <%struct.quad_struct*> [#uses=1] + ret %struct.quad_struct* %13 + +bb7: ; preds = %bb4, %bb3 + ret %struct.quad_struct* %q.0 +} + +declare fastcc i32 @sum_adjacent(%struct.quad_struct* nocapture, i32, i32, i32) nounwind readonly + +define i32 @perimeter(%struct.quad_struct* nocapture %tree, i32 %size) nounwind readonly { +entry: + %0 = getelementptr %struct.quad_struct* %tree, i32 0, i32 0 ; <i32*> [#uses=1] + %1 = load i32* %0, align 4 ; <i32> [#uses=1] + %2 = icmp eq i32 %1, 2 ; <i1> [#uses=1] + br i1 %2, label %bb, label %bb2 + +bb: ; preds = %entry + %3 = getelementptr %struct.quad_struct* %tree, i32 0, i32 4 ; <%struct.quad_struct**> [#uses=1] + %4 = load %struct.quad_struct** %3, align 4 ; <%struct.quad_struct*> [#uses=1] + %5 = sdiv i32 %size, 2 ; <i32> [#uses=1] + %6 = call i32 @perimeter(%struct.quad_struct* %4, i32 %5) nounwind ; <i32> [#uses=1] + %7 = getelementptr %struct.quad_struct* %tree, i32 0, i32 5 ; <%struct.quad_struct**> [#uses=1] + %8 = load %struct.quad_struct** %7, align 4 ; <%struct.quad_struct*> [#uses=1] + %9 = sdiv i32 %size, 2 ; <i32> [#uses=1] + %10 = call i32 @perimeter(%struct.quad_struct* %8, i32 %9) nounwind ; <i32> [#uses=1] + %11 = add i32 %10, %6 ; <i32> [#uses=1] + %12 = getelementptr %struct.quad_struct* %tree, i32 0, i32 3 ; <%struct.quad_struct**> [#uses=1] + %13 = load %struct.quad_struct** %12, align 4 ; <%struct.quad_struct*> [#uses=1] + %14 = sdiv i32 %size, 2 ; <i32> [#uses=1] + %15 = call i32 @perimeter(%struct.quad_struct* %13, i32 %14) nounwind ; <i32> [#uses=1] + %16 = add i32 %15, %11 ; <i32> [#uses=1] + %17 = getelementptr %struct.quad_struct* %tree, i32 0, i32 2 ; <%struct.quad_struct**> [#uses=1] + %18 = load %struct.quad_struct** %17, align 4 ; <%struct.quad_struct*> [#uses=1] + %19 = sdiv i32 %size, 2 ; <i32> [#uses=1] + %20 = call i32 @perimeter(%struct.quad_struct* %18, i32 %19) nounwind ; <i32> [#uses=1] + %21 = add i32 %20, %16 ; <i32> [#uses=1] + ret i32 %21 + +bb2: ; preds = %entry + %22 = getelementptr %struct.quad_struct* %tree, i32 0, i32 0 ; <i32*> [#uses=1] + %23 = load i32* %22, align 4 ; <i32> [#uses=1] + %24 = icmp eq i32 %23, 0 ; <i1> [#uses=1] + br i1 %24, label %bb3, label %bb23 + +bb3: ; preds = %bb2 + %25 = call fastcc %struct.quad_struct* @gtequal_adj_neighbor(%struct.quad_struct* %tree, i32 0) nounwind ; <%struct.quad_struct*> [#uses=4] + %26 = icmp eq %struct.quad_struct* %25, null ; <i1> [#uses=1] + br i1 %26, label %bb8, label %bb4 + +bb4: ; preds = %bb3 + %27 = getelementptr %struct.quad_struct* %25, i32 0, i32 0 ; <i32*> [#uses=1] + %28 = load i32* %27, align 4 ; <i32> [#uses=1] + %29 = icmp eq i32 %28, 1 ; <i1> [#uses=1] + br i1 %29, label %bb8, label %bb6 + +bb6: ; preds = %bb4 + %30 = getelementptr %struct.quad_struct* %25, i32 0, i32 0 ; <i32*> [#uses=1] + %31 = load i32* %30, align 4 ; <i32> [#uses=1] + %32 = icmp eq i32 %31, 2 ; <i1> [#uses=1] + br i1 %32, label %bb7, label %bb8 + +bb7: ; preds = %bb6 + %33 = call fastcc i32 @sum_adjacent(%struct.quad_struct* %25, i32 3, i32 2, i32 %size) nounwind ; <i32> [#uses=1] + br label %bb8 + +bb8: ; preds = %bb7, %bb6, %bb4, %bb3 + %retval1.1 = phi i32 [ 0, %bb6 ], [ %33, %bb7 ], [ %size, %bb4 ], [ %size, %bb3 ] ; <i32> [#uses=3] + %34 = call fastcc %struct.quad_struct* @gtequal_adj_neighbor(%struct.quad_struct* %tree, i32 1) nounwind ; <%struct.quad_struct*> [#uses=4] + %35 = icmp eq %struct.quad_struct* %34, null ; <i1> [#uses=1] + br i1 %35, label %bb10, label %bb9 + +bb9: ; preds = %bb8 + %36 = getelementptr %struct.quad_struct* %34, i32 0, i32 0 ; <i32*> [#uses=1] + %37 = load i32* %36, align 4 ; <i32> [#uses=1] + %38 = icmp eq i32 %37, 1 ; <i1> [#uses=1] + br i1 %38, label %bb10, label %bb11 + +bb10: ; preds = %bb9, %bb8 + %39 = add i32 %retval1.1, %size ; <i32> [#uses=1] + br label %bb13 + +bb11: ; preds = %bb9 + %40 = getelementptr %struct.quad_struct* %34, i32 0, i32 0 ; <i32*> [#uses=1] + %41 = load i32* %40, align 4 ; <i32> [#uses=1] + %42 = icmp eq i32 %41, 2 ; <i1> [#uses=1] + br i1 %42, label %bb12, label %bb13 + +bb12: ; preds = %bb11 + %43 = call fastcc i32 @sum_adjacent(%struct.quad_struct* %34, i32 2, i32 0, i32 %size) nounwind ; <i32> [#uses=1] + %44 = add i32 %43, %retval1.1 ; <i32> [#uses=1] + br label %bb13 + +bb13: ; preds = %bb12, %bb11, %bb10 + %retval1.2 = phi i32 [ %retval1.1, %bb11 ], [ %44, %bb12 ], [ %39, %bb10 ] ; <i32> [#uses=3] + %45 = call fastcc %struct.quad_struct* @gtequal_adj_neighbor(%struct.quad_struct* %tree, i32 2) nounwind ; <%struct.quad_struct*> [#uses=4] + %46 = icmp eq %struct.quad_struct* %45, null ; <i1> [#uses=1] + br i1 %46, label %bb15, label %bb14 + +bb14: ; preds = %bb13 + %47 = getelementptr %struct.quad_struct* %45, i32 0, i32 0 ; <i32*> [#uses=1] + %48 = load i32* %47, align 4 ; <i32> [#uses=1] + %49 = icmp eq i32 %48, 1 ; <i1> [#uses=1] + br i1 %49, label %bb15, label %bb16 + +bb15: ; preds = %bb14, %bb13 + %50 = add i32 %retval1.2, %size ; <i32> [#uses=1] + br label %bb18 + +bb16: ; preds = %bb14 + %51 = getelementptr %struct.quad_struct* %45, i32 0, i32 0 ; <i32*> [#uses=1] + %52 = load i32* %51, align 4 ; <i32> [#uses=1] + %53 = icmp eq i32 %52, 2 ; <i1> [#uses=1] + br i1 %53, label %bb17, label %bb18 + +bb17: ; preds = %bb16 + %54 = call fastcc i32 @sum_adjacent(%struct.quad_struct* %45, i32 0, i32 1, i32 %size) nounwind ; <i32> [#uses=1] + %55 = add i32 %54, %retval1.2 ; <i32> [#uses=1] + br label %bb18 + +bb18: ; preds = %bb17, %bb16, %bb15 + %retval1.3 = phi i32 [ %retval1.2, %bb16 ], [ %55, %bb17 ], [ %50, %bb15 ] ; <i32> [#uses=3] + %56 = call fastcc %struct.quad_struct* @gtequal_adj_neighbor(%struct.quad_struct* %tree, i32 3) nounwind ; <%struct.quad_struct*> [#uses=4] + %57 = icmp eq %struct.quad_struct* %56, null ; <i1> [#uses=1] + br i1 %57, label %bb20, label %bb19 + +bb19: ; preds = %bb18 + %58 = getelementptr %struct.quad_struct* %56, i32 0, i32 0 ; <i32*> [#uses=1] + %59 = load i32* %58, align 4 ; <i32> [#uses=1] + %60 = icmp eq i32 %59, 1 ; <i1> [#uses=1] + br i1 %60, label %bb20, label %bb21 + +bb20: ; preds = %bb19, %bb18 + %61 = add i32 %retval1.3, %size ; <i32> [#uses=1] + ret i32 %61 + +bb21: ; preds = %bb19 + %62 = getelementptr %struct.quad_struct* %56, i32 0, i32 0 ; <i32*> [#uses=1] + %63 = load i32* %62, align 4 ; <i32> [#uses=1] + %64 = icmp eq i32 %63, 2 ; <i1> [#uses=1] + br i1 %64, label %bb22, label %bb23 + +bb22: ; preds = %bb21 + %65 = call fastcc i32 @sum_adjacent(%struct.quad_struct* %56, i32 1, i32 3, i32 %size) nounwind ; <i32> [#uses=1] + %66 = add i32 %65, %retval1.3 ; <i32> [#uses=1] + ret i32 %66 + +bb23: ; preds = %bb21, %bb2 + %retval1.0 = phi i32 [ 0, %bb2 ], [ %retval1.3, %bb21 ] ; <i32> [#uses=1] + ret i32 %retval1.0 +} + +declare i32 @main(i32, i8** nocapture) noreturn nounwind + +declare i32 @printf(i8*, ...) nounwind + +declare void @exit(i32) noreturn nounwind + +declare fastcc i32 @CheckOutside(i32, i32) nounwind readnone + +declare fastcc i32 @CheckIntersect(i32, i32, i32) nounwind readnone + +declare %struct.quad_struct* @MakeTree(i32, i32, i32, i32, i32, %struct.quad_struct*, i32, i32) nounwind diff --git a/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll b/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll new file mode 100644 index 0000000..c8629ea2 --- /dev/null +++ b/test/Transforms/Inline/2009-05-07-CallUsingSelfCrash.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -inline -disable-output +; PR4123 + %struct.S0 = type <{ i32 }> + %struct.S1 = type <{ i8, i8, i8, i8, %struct.S0 }> + %struct.S2 = type <{ %struct.S1, i32 }> + +define void @func_113(%struct.S1* noalias nocapture sret %agg.result, i8 signext %p_114) noreturn nounwind { +entry: + unreachable + +for.inc: ; preds = %for.inc + %call48 = call fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %call48) ; <i8> [#uses=1] + br label %for.inc +} + +define fastcc signext i8 @safe_sub_func_uint8_t_u_u(i8 signext %_ui1) nounwind readnone { +entry: + ret i8 %_ui1 +} + diff --git a/test/Transforms/Inline/PR4909.ll b/test/Transforms/Inline/PR4909.ll new file mode 100644 index 0000000..24545f9 --- /dev/null +++ b/test/Transforms/Inline/PR4909.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -partial-inliner -disable-output + +define i32 @f() { +entry: + br label %return + +return: ; preds = %entry + ret i32 undef +} + +define i32 @g() { +entry: + %0 = call i32 @f() + ret i32 %0 +} diff --git a/test/Transforms/Inline/alloca-in-scc.ll b/test/Transforms/Inline/alloca-in-scc.ll new file mode 100644 index 0000000..d539255 --- /dev/null +++ b/test/Transforms/Inline/alloca-in-scc.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -inline | llvm-dis + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin10.0" + +define i32 @main(i32 %argc, i8** %argv) nounwind ssp { +entry: + call fastcc void @c() nounwind + unreachable +} + +define internal fastcc void @a() nounwind ssp { +entry: + %al = alloca [3 x i32], align 4 + %0 = getelementptr inbounds [3 x i32]* %al, i32 0, i32 2 + + call fastcc void @c() nounwind + unreachable +} + +define internal fastcc void @b() nounwind ssp { +entry: + tail call fastcc void @a() nounwind ssp + unreachable +} + +define internal fastcc void @c() nounwind ssp { +entry: + call fastcc void @b() nounwind + unreachable +} diff --git a/test/Transforms/Inline/alloca_test.ll b/test/Transforms/Inline/alloca_test.ll new file mode 100644 index 0000000..e5791d5 --- /dev/null +++ b/test/Transforms/Inline/alloca_test.ll @@ -0,0 +1,23 @@ +; This test ensures that alloca instructions in the entry block for an inlined +; function are moved to the top of the function they are inlined into. +; +; RUN: opt -S -inline %s | FileCheck %s + +define i32 @func(i32 %i) { + %X = alloca i32 ; <i32*> [#uses=1] + store i32 %i, i32* %X + ret i32 %i +} + +declare void @bar() + +define i32 @main(i32 %argc) { +Entry: +; CHECK: Entry +; CHECK-NEXT: alloca + call void @bar( ) + %X = call i32 @func( i32 7 ) ; <i32> [#uses=1] + %Y = add i32 %X, %argc ; <i32> [#uses=1] + ret i32 %Y +} + diff --git a/test/Transforms/Inline/always_inline_dyn_alloca.ll b/test/Transforms/Inline/always_inline_dyn_alloca.ll new file mode 100644 index 0000000..25cfc49 --- /dev/null +++ b/test/Transforms/Inline/always_inline_dyn_alloca.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -inline -S | not grep callee +; rdar://6655932 + +; If callee is marked alwaysinline, inline it! Even if callee has dynamic +; alloca and caller does not, + +define internal void @callee(i32 %N) alwaysinline { + %P = alloca i32, i32 %N + ret void +} + +define void @foo(i32 %N) { + call void @callee( i32 %N ) + ret void +} diff --git a/test/Transforms/Inline/array_merge.ll b/test/Transforms/Inline/array_merge.ll new file mode 100644 index 0000000..0d176b8 --- /dev/null +++ b/test/Transforms/Inline/array_merge.ll @@ -0,0 +1,26 @@ +; RUN: opt < %s -inline -S | FileCheck %s +; rdar://7173846 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin10.0" + +define internal void @foo() nounwind ssp { +entry: + %A = alloca [100 x i32] + %B = alloca [100 x i32] + call void @bar([100 x i32]* %A, [100 x i32]* %B) nounwind + ret void +} + +declare void @bar([100 x i32]*, [100 x i32]*) + +define void @test() nounwind ssp { +entry: +; CHECK: @test() +; CHECK-NEXT: entry: +; CHECK-NEXT: %A.i = alloca +; CHECK-NEXT: %B.i = alloca +; CHECK-NEXT: call void + call void @foo() nounwind + call void @foo() nounwind + ret void +} diff --git a/test/Transforms/Inline/basictest.ll b/test/Transforms/Inline/basictest.ll new file mode 100644 index 0000000..6531b9e --- /dev/null +++ b/test/Transforms/Inline/basictest.ll @@ -0,0 +1,47 @@ +; RUN: opt < %s -inline -scalarrepl -S | FileCheck %s +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" + +define i32 @test1f(i32 %i) { + ret i32 %i +} + +define i32 @test1(i32 %W) { + %X = call i32 @test1f(i32 7) + %Y = add i32 %X, %W + ret i32 %Y +; CHECK: @test1( +; CHECK-NEXT: %Y = add i32 7, %W +; CHECK-NEXT: ret i32 %Y +} + + + +; rdar://7339069 + +%T = type { i32, i32 } + +; CHECK-NOT: @test2f +define internal %T* @test2f(i1 %cond, %T* %P) { + br i1 %cond, label %T, label %F + +T: + %A = getelementptr %T* %P, i32 0, i32 0 + store i32 42, i32* %A + ret %T* %P + +F: + ret %T* %P +} + +define i32 @test2(i1 %cond) { + %A = alloca %T + + %B = call %T* @test2f(i1 %cond, %T* %A) + %C = getelementptr %T* %B, i32 0, i32 0 + %D = load i32* %C + ret i32 %D + +; CHECK: @test2( +; CHECK-NOT: = alloca +; CHECK: ret i32 42 +} diff --git a/test/Transforms/Inline/byval.ll b/test/Transforms/Inline/byval.ll new file mode 100644 index 0000000..c3552f6 --- /dev/null +++ b/test/Transforms/Inline/byval.ll @@ -0,0 +1,28 @@ +; RUN: opt < %s -inline -S | grep {llvm.memcpy} + +; Inlining a byval struct should cause an explicit copy into an alloca. + + %struct.ss = type { i32, i64 } +@.str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1] + +define internal void @f(%struct.ss* byval %b) nounwind { +entry: + %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2] + %tmp1 = load i32* %tmp, align 4 ; <i32> [#uses=1] + %tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1] + store i32 %tmp2, i32* %tmp, align 4 + ret void +} + +declare i32 @printf(i8*, ...) nounwind + +define i32 @main() nounwind { +entry: + %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] + %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1] + store i32 1, i32* %tmp1, align 8 + %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1] + store i64 2, i64* %tmp4, align 4 + call void @f( %struct.ss* byval %S ) nounwind + ret i32 0 +} diff --git a/test/Transforms/Inline/byval2.ll b/test/Transforms/Inline/byval2.ll new file mode 100644 index 0000000..a7ab77c --- /dev/null +++ b/test/Transforms/Inline/byval2.ll @@ -0,0 +1,28 @@ +; RUN: opt < %s -inline -S | not grep {llvm.memcpy} + +; Inlining a byval struct should NOT cause an explicit copy +; into an alloca if the function is readonly + + %struct.ss = type { i32, i64 } +@.str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1] + +define internal i32 @f(%struct.ss* byval %b) nounwind readonly { +entry: + %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2] + %tmp1 = load i32* %tmp, align 4 ; <i32> [#uses=1] + %tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1] + ret i32 %tmp2 +} + +declare i32 @printf(i8*, ...) nounwind + +define i32 @main() nounwind { +entry: + %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] + %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1] + store i32 1, i32* %tmp1, align 8 + %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1] + store i64 2, i64* %tmp4, align 4 + %X = call i32 @f( %struct.ss* byval %S ) nounwind + ret i32 %X +} diff --git a/test/Transforms/Inline/callgraph-update.ll b/test/Transforms/Inline/callgraph-update.ll new file mode 100644 index 0000000..ff0120b --- /dev/null +++ b/test/Transforms/Inline/callgraph-update.ll @@ -0,0 +1,33 @@ +; RUN: opt < %s -inline -loop-rotate -verify-dom-info -verify-loop-info -disable-output +; PR3601 +declare void @solve() + +define internal fastcc void @read() { + br label %bb4 + +bb3: + br label %bb4 + +bb4: + call void @solve() + br i1 false, label %bb5, label %bb3 + +bb5: + unreachable +} + +define internal fastcc void @parse() { + call fastcc void @read() + ret void +} + +define void @main() { + invoke fastcc void @parse() + to label %invcont unwind label %lpad + +invcont: + unreachable + +lpad: + unreachable +} diff --git a/test/Transforms/Inline/casts.ll b/test/Transforms/Inline/casts.ll new file mode 100644 index 0000000..166185a --- /dev/null +++ b/test/Transforms/Inline/casts.ll @@ -0,0 +1,19 @@ +; RUN: opt < %s -inline -S | grep {ret i32 1} +; ModuleID = 'short.opt.bc' + +define i32 @testBool(i1 %X) { + %tmp = zext i1 %X to i32 ; <i32> [#uses=1] + ret i32 %tmp +} + +define i32 @testByte(i8 %X) { + %tmp = icmp ne i8 %X, 0 ; <i1> [#uses=1] + %tmp.i = zext i1 %tmp to i32 ; <i32> [#uses=1] + ret i32 %tmp.i +} + +define i32 @main() { + %rslt = call i32 @testByte( i8 123 ) ; <i32> [#uses=1] + ret i32 %rslt +} + diff --git a/test/Transforms/Inline/cfg_preserve_test.ll b/test/Transforms/Inline/cfg_preserve_test.ll new file mode 100644 index 0000000..9597109 --- /dev/null +++ b/test/Transforms/Inline/cfg_preserve_test.ll @@ -0,0 +1,16 @@ +; This test ensures that inlining an "empty" function does not destroy the CFG +; +; RUN: opt < %s -inline -S | not grep br + +define i32 @func(i32 %i) { + ret i32 %i +} + +declare void @bar() + +define i32 @main(i32 %argc) { +Entry: + %X = call i32 @func( i32 7 ) ; <i32> [#uses=1] + ret i32 %X +} + diff --git a/test/Transforms/Inline/crash.ll b/test/Transforms/Inline/crash.ll new file mode 100644 index 0000000..f34b44c --- /dev/null +++ b/test/Transforms/Inline/crash.ll @@ -0,0 +1,88 @@ +; RUN: opt < %s -inline -argpromotion -instcombine -disable-output + +; This test was failing because the inliner would inline @list_DeleteElement +; into @list_DeleteDuplicates and then into @inf_GetBackwardPartnerLits, +; turning the indirect call into a direct one. This allowed instcombine to see +; the bitcast and eliminate it, deleting the original call and introducing +; another one. This crashed the inliner because the new call was not in the +; callgraph. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin10.0" + + +define void @list_DeleteElement(i32 (i8*, i8*)* nocapture %Test) nounwind ssp { +entry: + %0 = call i32 %Test(i8* null, i8* undef) nounwind + ret void +} + + +define void @list_DeleteDuplicates(i32 (i8*, i8*)* nocapture %Test) nounwind ssp { +foo: + call void @list_DeleteElement(i32 (i8*, i8*)* %Test) nounwind ssp + call fastcc void @list_Rplacd1284() nounwind ssp + unreachable + +} + +define internal i32 @inf_LiteralsHaveSameSubtermAndAreFromSameClause(i32* nocapture %L1, i32* nocapture %L2) nounwind readonly ssp { +entry: + unreachable +} + + +define internal fastcc void @inf_GetBackwardPartnerLits(i32* nocapture %Flags) nounwind ssp { +test: + call void @list_DeleteDuplicates(i32 (i8*, i8*)* bitcast (i32 (i32*, i32*)* @inf_LiteralsHaveSameSubtermAndAreFromSameClause to i32 (i8*, i8*)*)) nounwind + ret void +} + + +define void @inf_BackwardEmptySortPlusPlus() nounwind ssp { +entry: + call fastcc void @inf_GetBackwardPartnerLits(i32* null) nounwind ssp + unreachable +} + +define void @inf_BackwardWeakening() nounwind ssp { +entry: + call fastcc void @inf_GetBackwardPartnerLits(i32* null) nounwind ssp + unreachable +} + +declare fastcc void @list_Rplacd1284() nounwind ssp + + + + +;============================ +; PR5208 + +define void @AAA() { +entry: + %A = alloca i8, i32 undef, align 1 + invoke fastcc void @XXX() + to label %invcont98 unwind label %lpad156 + +invcont98: + unreachable + +lpad156: + unreachable +} + +declare fastcc void @YYY() + +define internal fastcc void @XXX() { +entry: + %B = alloca i8, i32 undef, align 1 + invoke fastcc void @YYY() + to label %bb260 unwind label %lpad + +bb260: + ret void + +lpad: + unwind +} diff --git a/test/Transforms/Inline/delete-call.ll b/test/Transforms/Inline/delete-call.ll new file mode 100644 index 0000000..3505608 --- /dev/null +++ b/test/Transforms/Inline/delete-call.ll @@ -0,0 +1,22 @@ +; RUN: opt %s -S -inline -functionattrs -stats |& grep {Number of call sites deleted, not inlined} +; RUN: opt %s -S -inline -stats |& grep {Number of functions inlined} + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin9.8" + +define internal i32 @test(i32 %x, i32 %y, i32 %z) nounwind { +entry: + %0 = add nsw i32 %y, %z ; <i32> [#uses=1] + %1 = mul i32 %0, %x ; <i32> [#uses=1] + %2 = mul i32 %y, %z ; <i32> [#uses=1] + %3 = add nsw i32 %1, %2 ; <i32> [#uses=1] + ret i32 %3 +} + +define i32 @test2() nounwind { +entry: + %0 = call i32 @test(i32 1, i32 2, i32 4) nounwind ; <i32> [#uses=1] + ret i32 14 +} + + diff --git a/test/Transforms/Inline/dg.exp b/test/Transforms/Inline/dg.exp new file mode 100644 index 0000000..f200589 --- /dev/null +++ b/test/Transforms/Inline/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/Inline/dynamic_alloca_test.ll b/test/Transforms/Inline/dynamic_alloca_test.ll new file mode 100644 index 0000000..0286535 --- /dev/null +++ b/test/Transforms/Inline/dynamic_alloca_test.ll @@ -0,0 +1,35 @@ +; Test that functions with dynamic allocas get inlined in a case where +; naively inlining it would result in a miscompilation. +; Functions with dynamic allocas can only be inlined into functions that +; already have dynamic allocas. + +; RUN: opt < %s -inline -S | \ +; RUN: grep llvm.stacksave +; RUN: opt < %s -inline -S | not grep callee + + +declare void @ext(i32*) + +define internal void @callee(i32 %N) { + %P = alloca i32, i32 %N ; <i32*> [#uses=1] + call void @ext( i32* %P ) + ret void +} + +define void @foo(i32 %N) { +; <label>:0 + %P = alloca i32, i32 %N ; <i32*> [#uses=1] + call void @ext( i32* %P ) + br label %Loop + +Loop: ; preds = %Loop, %0 + %count = phi i32 [ 0, %0 ], [ %next, %Loop ] ; <i32> [#uses=2] + %next = add i32 %count, 1 ; <i32> [#uses=1] + call void @callee( i32 %N ) + %cond = icmp eq i32 %count, 100000 ; <i1> [#uses=1] + br i1 %cond, label %out, label %Loop + +out: ; preds = %Loop + ret void +} + diff --git a/test/Transforms/Inline/externally_available.ll b/test/Transforms/Inline/externally_available.ll new file mode 100644 index 0000000..43fe5d3 --- /dev/null +++ b/test/Transforms/Inline/externally_available.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -inline -constprop -S > %t +; RUN: not grep test_function %t +; RUN: grep {ret i32 5} %t + + +; test_function should not be emitted to the .s file. +define available_externally i32 @test_function() { + ret i32 4 +} + + +define i32 @result() { + %A = call i32 @test_function() + %B = add i32 %A, 1 + ret i32 %B +}
\ No newline at end of file diff --git a/test/Transforms/Inline/indirect_resolve.ll b/test/Transforms/Inline/indirect_resolve.ll new file mode 100644 index 0000000..76182e2 --- /dev/null +++ b/test/Transforms/Inline/indirect_resolve.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -inline | llvm-dis +; PR4834 + +define i32 @main() { + %funcall1_ = call fastcc i32 ()* ()* @f1() + %executecommandptr1_ = call i32 %funcall1_() + ret i32 %executecommandptr1_ +} + +define internal fastcc i32 ()* @f1() nounwind readnone { + ret i32 ()* @f2 +} + +define internal i32 @f2() nounwind readnone { + ret i32 1 +} diff --git a/test/Transforms/Inline/inline-invoke-tail.ll b/test/Transforms/Inline/inline-invoke-tail.ll new file mode 100644 index 0000000..961f678 --- /dev/null +++ b/test/Transforms/Inline/inline-invoke-tail.ll @@ -0,0 +1,35 @@ +; RUN: opt < %s -inline -S | not grep {tail call void @llvm.memcpy.i32} +; PR3550 + +define internal void @foo(i32* %p, i32* %q) { + %pp = bitcast i32* %p to i8* + %qq = bitcast i32* %q to i8* + tail call void @llvm.memcpy.i32(i8* %pp, i8* %qq, i32 4, i32 1) + ret void +} + +declare void @llvm.memcpy.i32(i8* nocapture, i8* nocapture, i32, i32) nounwind + +define i32 @main() { + %a = alloca i32 ; <i32*> [#uses=3] + %b = alloca i32 ; <i32*> [#uses=2] + store i32 1, i32* %a, align 4 + store i32 0, i32* %b, align 4 + invoke void @foo(i32* %a, i32* %b) + to label %invcont unwind label %lpad + +invcont: + %retval = load i32* %a, align 4 + ret i32 %retval + +lpad: + %eh_ptr = call i8* @llvm.eh.exception() + %eh_select = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) + unreachable +} + +declare i8* @llvm.eh.exception() nounwind + +declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/Inline/inline-tail.ll b/test/Transforms/Inline/inline-tail.ll new file mode 100644 index 0000000..8bb059d --- /dev/null +++ b/test/Transforms/Inline/inline-tail.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -inline -S | not grep tail + +declare void @bar(i32*) + +define internal void @foo(i32* %P) { + tail call void @bar( i32* %P ) + ret void +} + +define void @caller() { + %A = alloca i32 ; <i32*> [#uses=1] + call void @foo( i32* %A ) + ret void +} + diff --git a/test/Transforms/Inline/inline_cleanup.ll b/test/Transforms/Inline/inline_cleanup.ll new file mode 100644 index 0000000..4c64721 --- /dev/null +++ b/test/Transforms/Inline/inline_cleanup.ll @@ -0,0 +1,63 @@ +; Test that the inliner doesn't leave around dead allocas, and that it folds +; uncond branches away after it is done specializing. + +; RUN: opt < %s -inline -S | \ +; RUN: not grep {alloca.*uses=0} +; RUN: opt < %s -inline -S | \ +; RUN: not grep {br label} +@A = weak global i32 0 ; <i32*> [#uses=1] +@B = weak global i32 0 ; <i32*> [#uses=1] +@C = weak global i32 0 ; <i32*> [#uses=1] + +define internal fastcc void @foo(i32 %X) { +entry: + %ALL = alloca i32, align 4 ; <i32*> [#uses=1] + %tmp1 = and i32 %X, 1 ; <i32> [#uses=1] + %tmp1.upgrd.1 = icmp eq i32 %tmp1, 0 ; <i1> [#uses=1] + br i1 %tmp1.upgrd.1, label %cond_next, label %cond_true + +cond_true: ; preds = %entry + store i32 1, i32* @A + br label %cond_next + +cond_next: ; preds = %cond_true, %entry + %tmp4 = and i32 %X, 2 ; <i32> [#uses=1] + %tmp4.upgrd.2 = icmp eq i32 %tmp4, 0 ; <i1> [#uses=1] + br i1 %tmp4.upgrd.2, label %cond_next7, label %cond_true5 + +cond_true5: ; preds = %cond_next + store i32 1, i32* @B + br label %cond_next7 + +cond_next7: ; preds = %cond_true5, %cond_next + %tmp10 = and i32 %X, 4 ; <i32> [#uses=1] + %tmp10.upgrd.3 = icmp eq i32 %tmp10, 0 ; <i1> [#uses=1] + br i1 %tmp10.upgrd.3, label %cond_next13, label %cond_true11 + +cond_true11: ; preds = %cond_next7 + store i32 1, i32* @C + br label %cond_next13 + +cond_next13: ; preds = %cond_true11, %cond_next7 + %tmp16 = and i32 %X, 8 ; <i32> [#uses=1] + %tmp16.upgrd.4 = icmp eq i32 %tmp16, 0 ; <i1> [#uses=1] + br i1 %tmp16.upgrd.4, label %UnifiedReturnBlock, label %cond_true17 + +cond_true17: ; preds = %cond_next13 + call void @ext( i32* %ALL ) + ret void + +UnifiedReturnBlock: ; preds = %cond_next13 + ret void +} + +declare void @ext(i32*) + +define void @test() { +entry: + tail call fastcc void @foo( i32 1 ) + tail call fastcc void @foo( i32 2 ) + tail call fastcc void @foo( i32 3 ) + tail call fastcc void @foo( i32 8 ) + ret void +} diff --git a/test/Transforms/Inline/inline_constprop.ll b/test/Transforms/Inline/inline_constprop.ll new file mode 100644 index 0000000..537c69b --- /dev/null +++ b/test/Transforms/Inline/inline_constprop.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -inline -S | not grep callee +; RUN: opt < %s -inline -S | not grep div + + +define internal i32 @callee(i32 %A, i32 %B) { + %C = sdiv i32 %A, %B ; <i32> [#uses=1] + ret i32 %C +} + +define i32 @test() { + %X = call i32 @callee( i32 10, i32 3 ) ; <i32> [#uses=1] + ret i32 %X +} + diff --git a/test/Transforms/Inline/inline_dce.ll b/test/Transforms/Inline/inline_dce.ll new file mode 100644 index 0000000..5143d02 --- /dev/null +++ b/test/Transforms/Inline/inline_dce.ll @@ -0,0 +1,25 @@ +; This checks to ensure that the inline pass deletes functions if they get +; inlined into all of their callers. + +; RUN: opt < %s -inline -S | \ +; RUN: not grep @reallysmall + +define internal i32 @reallysmall(i32 %A) { + ret i32 %A +} + +define void @caller1() { + call i32 @reallysmall( i32 5 ) ; <i32>:1 [#uses=0] + ret void +} + +define void @caller2(i32 %A) { + call i32 @reallysmall( i32 %A ) ; <i32>:1 [#uses=0] + ret void +} + +define i32 @caller3(i32 %A) { + %B = call i32 @reallysmall( i32 %A ) ; <i32> [#uses=1] + ret i32 %B +} + diff --git a/test/Transforms/Inline/inline_prune.ll b/test/Transforms/Inline/inline_prune.ll new file mode 100644 index 0000000..658a422 --- /dev/null +++ b/test/Transforms/Inline/inline_prune.ll @@ -0,0 +1,45 @@ +; RUN: opt < %s -inline -S | \ +; RUN: not grep {callee\[12\](} +; RUN: opt < %s -inline -S | not grep mul + +define internal i32 @callee1(i32 %A, i32 %B) { + %cond = icmp eq i32 %A, 123 ; <i1> [#uses=1] + br i1 %cond, label %T, label %F + +T: ; preds = %0 + %C = mul i32 %B, %B ; <i32> [#uses=1] + ret i32 %C + +F: ; preds = %0 + ret i32 0 +} + +define internal i32 @callee2(i32 %A, i32 %B) { + switch i32 %A, label %T [ + i32 10, label %F + i32 1234, label %G + ] + ; No predecessors! + %cond = icmp eq i32 %A, 123 ; <i1> [#uses=1] + br i1 %cond, label %T, label %F + +T: ; preds = %1, %0 + %C = mul i32 %B, %B ; <i32> [#uses=1] + ret i32 %C + +F: ; preds = %1, %0 + ret i32 0 + +G: ; preds = %0 + %D = mul i32 %B, %B ; <i32> [#uses=1] + %E = mul i32 %D, %B ; <i32> [#uses=1] + ret i32 %E +} + +define i32 @test(i32 %A) { + %X = call i32 @callee1( i32 10, i32 %A ) ; <i32> [#uses=1] + %Y = call i32 @callee2( i32 10, i32 %A ) ; <i32> [#uses=1] + %Z = add i32 %X, %Y ; <i32> [#uses=1] + ret i32 %Z +} + diff --git a/test/Transforms/Inline/invoke_test-1.ll b/test/Transforms/Inline/invoke_test-1.ll new file mode 100644 index 0000000..0d27e2a --- /dev/null +++ b/test/Transforms/Inline/invoke_test-1.ll @@ -0,0 +1,24 @@ +; Test that we can inline a simple function, turning the calls in it into invoke +; instructions + +; RUN: opt < %s -inline -S | \ +; RUN: not grep {call\[^e\]} + +declare void @might_throw() + +define internal void @callee() { + call void @might_throw( ) + ret void +} + +; caller returns true if might_throw throws an exception... +define i32 @caller() { + invoke void @callee( ) + to label %cont unwind label %exc + +cont: ; preds = %0 + ret i32 0 + +exc: ; preds = %0 + ret i32 1 +} diff --git a/test/Transforms/Inline/invoke_test-2.ll b/test/Transforms/Inline/invoke_test-2.ll new file mode 100644 index 0000000..bbb9ab0 --- /dev/null +++ b/test/Transforms/Inline/invoke_test-2.ll @@ -0,0 +1,30 @@ +; Test that if an invoked function is inlined, and if that function cannot +; throw, that the dead handler is now unreachable. + +; RUN: opt < %s -inline -simplifycfg -S | \ +; RUN: not grep UnreachableExceptionHandler + +declare void @might_throw() + +define internal i32 @callee() { + invoke void @might_throw( ) + to label %cont unwind label %exc + +cont: ; preds = %0 + ret i32 0 + +exc: ; preds = %0 + ret i32 1 +} + +; caller returns true if might_throw throws an exception... callee cannot throw. +define i32 @caller() { + %X = invoke i32 @callee( ) + to label %cont unwind label %UnreachableExceptionHandler ; <i32> [#uses=1] + +cont: ; preds = %0 + ret i32 %X + +UnreachableExceptionHandler: ; preds = %0 + ret i32 -1 +} diff --git a/test/Transforms/Inline/invoke_test-3.ll b/test/Transforms/Inline/invoke_test-3.ll new file mode 100644 index 0000000..b360526 --- /dev/null +++ b/test/Transforms/Inline/invoke_test-3.ll @@ -0,0 +1,32 @@ +; Test that any rethrown exceptions in an inlined function are automatically +; turned into branches to the invoke destination. + +; RUN: opt < %s -inline -S | not grep unwind$ + +declare void @might_throw() + +define internal i32 @callee() { + invoke void @might_throw( ) + to label %cont unwind label %exc + +cont: ; preds = %0 + ret i32 0 + +exc: ; preds = %0a + ; This just rethrows the exception! + unwind +} + +; caller returns true if might_throw throws an exception... which gets +; propagated by callee. +define i32 @caller() { + %X = invoke i32 @callee( ) + to label %cont unwind label %Handler ; <i32> [#uses=1] + +cont: ; preds = %0 + ret i32 %X + +Handler: ; preds = %0 +; This consumes an exception thrown by might_throw + ret i32 1 +} diff --git a/test/Transforms/Inline/nested-inline.ll b/test/Transforms/Inline/nested-inline.ll new file mode 100644 index 0000000..1292667 --- /dev/null +++ b/test/Transforms/Inline/nested-inline.ll @@ -0,0 +1,111 @@ +; RUN: opt < %s -inline -S | FileCheck %s +; Test that bar and bar2 are both inlined throughout and removed. +@A = weak global i32 0 ; <i32*> [#uses=1] +@B = weak global i32 0 ; <i32*> [#uses=1] +@C = weak global i32 0 ; <i32*> [#uses=1] + +define fastcc void @foo(i32 %X) { +entry: +; CHECK: @foo + %ALL = alloca i32, align 4 ; <i32*> [#uses=1] + %tmp1 = and i32 %X, 1 ; <i32> [#uses=1] + %tmp1.upgrd.1 = icmp eq i32 %tmp1, 0 ; <i1> [#uses=1] + br i1 %tmp1.upgrd.1, label %cond_next, label %cond_true + +cond_true: ; preds = %entry + store i32 1, i32* @A + br label %cond_next + +cond_next: ; preds = %cond_true, %entry + %tmp4 = and i32 %X, 2 ; <i32> [#uses=1] + %tmp4.upgrd.2 = icmp eq i32 %tmp4, 0 ; <i1> [#uses=1] + br i1 %tmp4.upgrd.2, label %cond_next7, label %cond_true5 + +cond_true5: ; preds = %cond_next + store i32 1, i32* @B + br label %cond_next7 + +cond_next7: ; preds = %cond_true5, %cond_next + %tmp10 = and i32 %X, 4 ; <i32> [#uses=1] + %tmp10.upgrd.3 = icmp eq i32 %tmp10, 0 ; <i1> [#uses=1] + br i1 %tmp10.upgrd.3, label %cond_next13, label %cond_true11 + +cond_true11: ; preds = %cond_next7 + store i32 1, i32* @C + br label %cond_next13 + +cond_next13: ; preds = %cond_true11, %cond_next7 + %tmp16 = and i32 %X, 8 ; <i32> [#uses=1] + %tmp16.upgrd.4 = icmp eq i32 %tmp16, 0 ; <i1> [#uses=1] + br i1 %tmp16.upgrd.4, label %UnifiedReturnBlock, label %cond_true17 + +cond_true17: ; preds = %cond_next13 + call void @ext( i32* %ALL ) + ret void + +UnifiedReturnBlock: ; preds = %cond_next13 + ret void +} + +; CHECK-NOT: @bar +define internal fastcc void @bar(i32 %X) { +entry: + %ALL = alloca i32, align 4 ; <i32*> [#uses=1] + %tmp1 = and i32 %X, 1 ; <i32> [#uses=1] + %tmp1.upgrd.1 = icmp eq i32 %tmp1, 0 ; <i1> [#uses=1] + br i1 %tmp1.upgrd.1, label %cond_next, label %cond_true + +cond_true: ; preds = %entry + store i32 1, i32* @A + br label %cond_next + +cond_next: ; preds = %cond_true, %entry + %tmp4 = and i32 %X, 2 ; <i32> [#uses=1] + %tmp4.upgrd.2 = icmp eq i32 %tmp4, 0 ; <i1> [#uses=1] + br i1 %tmp4.upgrd.2, label %cond_next7, label %cond_true5 + +cond_true5: ; preds = %cond_next + store i32 1, i32* @B + br label %cond_next7 + +cond_next7: ; preds = %cond_true5, %cond_next + %tmp10 = and i32 %X, 4 ; <i32> [#uses=1] + %tmp10.upgrd.3 = icmp eq i32 %tmp10, 0 ; <i1> [#uses=1] + br i1 %tmp10.upgrd.3, label %cond_next13, label %cond_true11 + +cond_true11: ; preds = %cond_next7 + store i32 1, i32* @C + br label %cond_next13 + +cond_next13: ; preds = %cond_true11, %cond_next7 + %tmp16 = and i32 %X, 8 ; <i32> [#uses=1] + %tmp16.upgrd.4 = icmp eq i32 %tmp16, 0 ; <i1> [#uses=1] + br i1 %tmp16.upgrd.4, label %UnifiedReturnBlock, label %cond_true17 + +cond_true17: ; preds = %cond_next13 + call void @foo( i32 %X ) + ret void + +UnifiedReturnBlock: ; preds = %cond_next13 + ret void +} + +define internal fastcc void @bar2(i32 %X) { +entry: + call void @foo( i32 %X ) + ret void +} + +declare void @ext(i32*) + +define void @test(i32 %X) { +entry: +; CHECK: test +; CHECK-NOT: @bar + tail call fastcc void @bar( i32 %X ) + tail call fastcc void @bar( i32 %X ) + tail call fastcc void @bar2( i32 %X ) + tail call fastcc void @bar2( i32 %X ) + ret void +; CHECK: ret +} |