diff options
Diffstat (limited to 'test/Transforms/IndVarSimplify')
65 files changed, 2945 insertions, 0 deletions
diff --git a/test/Transforms/IndVarSimplify/2002-09-09-PointerIndVar.ll b/test/Transforms/IndVarSimplify/2002-09-09-PointerIndVar.ll new file mode 100644 index 000000000000..228772eb82cc --- /dev/null +++ b/test/Transforms/IndVarSimplify/2002-09-09-PointerIndVar.ll @@ -0,0 +1,17 @@ +; Induction variable pass is doing bad things with pointer induction vars, +; trying to do arithmetic on them directly. +; +; RUN: llvm-as < %s | opt -indvars +; +define void @test(i32 %A, i32 %S, i8* %S.upgrd.1) { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %PIV = phi i8* [ %S.upgrd.1, %0 ], [ %PIVNext.upgrd.3, %Loop ] ; <i8*> [#uses=1] + %PIV.upgrd.2 = ptrtoint i8* %PIV to i64 ; <i64> [#uses=1] + %PIVNext = add i64 %PIV.upgrd.2, 8 ; <i64> [#uses=1] + %PIVNext.upgrd.3 = inttoptr i64 %PIVNext to i8* ; <i8*> [#uses=1] + br label %Loop +} + diff --git a/test/Transforms/IndVarSimplify/2003-04-16-ExprAnalysis.ll b/test/Transforms/IndVarSimplify/2003-04-16-ExprAnalysis.ll new file mode 100644 index 000000000000..2487ea95e27d --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-04-16-ExprAnalysis.ll @@ -0,0 +1,17 @@ +; This is a test case for the expression analysis code, not really indvars. +; It was assuming any constant of int type was a ConstantInteger. +; +; RUN: llvm-as < %s | opt -indvars + +@X = global i32 7 ; <i32*> [#uses=1] + +define void @test(i32 %A) { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %IV = phi i32 [ %A, %0 ], [ %IVNext, %Loop ] ; <i32> [#uses=1] + %IVNext = add i32 %IV, ptrtoint (i32* @X to i32) ; <i32> [#uses=1] + br label %Loop +} + diff --git a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll b/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll new file mode 100644 index 000000000000..96190991f73a --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep indvar + +define i32 @test() { +; <label>:0 + br i1 true, label %LoopHead, label %LoopHead + +LoopHead: ; preds = %LoopHead, %0, %0 + %A = phi i32 [ 7, %0 ], [ 7, %0 ], [ %B, %LoopHead ] ; <i32> [#uses=1] + %B = add i32 %A, 1 ; <i32> [#uses=2] + br i1 false, label %LoopHead, label %Out + +Out: ; preds = %LoopHead + ret i32 %B +} + diff --git a/test/Transforms/IndVarSimplify/2003-09-23-NotAtTop.ll b/test/Transforms/IndVarSimplify/2003-09-23-NotAtTop.ll new file mode 100644 index 000000000000..d70e60497978 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-09-23-NotAtTop.ll @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | %prcontext Loop: 1 | grep %indvar + +; The indvar simplification code should ensure that the first PHI in the block +; is the canonical one! + +define i32 @test() { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %NonIndvar = phi i32 [ 200, %0 ], [ %NonIndvarNext, %Loop ] ; <i32> [#uses=1] + %Canonical = phi i32 [ 0, %0 ], [ %CanonicalNext, %Loop ] ; <i32> [#uses=2] + store i32 %Canonical, i32* null + %NonIndvarNext = sdiv i32 %NonIndvar, 2 ; <i32> [#uses=1] + %CanonicalNext = add i32 %Canonical, 1 ; <i32> [#uses=1] + br label %Loop +} + diff --git a/test/Transforms/IndVarSimplify/2003-12-10-IndVarDeadCode.ll b/test/Transforms/IndVarSimplify/2003-12-10-IndVarDeadCode.ll new file mode 100644 index 000000000000..bd9d1ef5cb9d --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-12-10-IndVarDeadCode.ll @@ -0,0 +1,25 @@ +; The induction variable canonicalization pass shouldn't leave dead +; instructions laying around! +; +; RUN: llvm-as < %s | opt -indvars | llvm-dis | \ +; RUN: not grep {#uses=0} + +define i32 @mul(i32 %x, i32 %y) { +entry: + br label %tailrecurse + +tailrecurse: ; preds = %endif, %entry + %accumulator.tr = phi i32 [ %x, %entry ], [ %tmp.9, %endif ] ; <i32> [#uses=2] + %y.tr = phi i32 [ %y, %entry ], [ %tmp.8, %endif ] ; <i32> [#uses=2] + %tmp.1 = icmp eq i32 %y.tr, 0 ; <i1> [#uses=1] + br i1 %tmp.1, label %return, label %endif + +endif: ; preds = %tailrecurse + %tmp.8 = add i32 %y.tr, -1 ; <i32> [#uses=1] + %tmp.9 = add i32 %accumulator.tr, %x ; <i32> [#uses=1] + br label %tailrecurse + +return: ; preds = %tailrecurse + ret i32 %accumulator.tr +} + diff --git a/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll b/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll new file mode 100644 index 000000000000..11af997e83bd --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-12-10-RemoveInstrCrash.ll @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +define void @test() { +entry: + %inc.2 = add i32 1, 1 ; <i32> [#uses=1] + br i1 false, label %no_exit, label %loopexit + +no_exit: ; preds = %no_exit, %entry + %j.0.pn = phi i32 [ %inc.3, %no_exit ], [ %inc.2, %entry ] ; <i32> [#uses=1] + %k.0.pn = phi i32 [ %inc.4, %no_exit ], [ 1, %entry ] ; <i32> [#uses=1] + %inc.3 = add i32 %j.0.pn, 1 ; <i32> [#uses=1] + %inc.4 = add i32 %k.0.pn, 1 ; <i32> [#uses=1] + br i1 false, label %no_exit, label %loopexit + +loopexit: ; preds = %no_exit, %entry + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll b/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll new file mode 100644 index 000000000000..b964d78d6952 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-12-15-Crash.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +define void @_ZN17CoinFactorization7cleanupEv() { +entry: + br i1 false, label %loopexit.14, label %cond_continue.3 + +cond_continue.3: ; preds = %entry + ret void + +loopexit.14: ; preds = %entry + %tmp.738 = sub i32 0, 0 ; <i32> [#uses=1] + br i1 false, label %no_exit.15.preheader, label %loopexit.15 + +no_exit.15.preheader: ; preds = %loopexit.14 + br label %no_exit.15 + +no_exit.15: ; preds = %no_exit.15, %no_exit.15.preheader + %highC.0 = phi i32 [ %tmp.738, %no_exit.15.preheader ], [ %dec.0, %no_exit.15 ] ; <i32> [#uses=1] + %dec.0 = add i32 %highC.0, -1 ; <i32> [#uses=1] + br i1 false, label %no_exit.15, label %loopexit.15 + +loopexit.15: ; preds = %no_exit.15, %loopexit.14 + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll b/test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll new file mode 100644 index 000000000000..cf8c80472dfe --- /dev/null +++ b/test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep indvar | not grep i32 + +@G = global i64 0 ; <i64*> [#uses=1] + +define void @test() { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %X = phi i64 [ 1, %0 ], [ %X.next, %Loop ] ; <i64> [#uses=2] + %X.next = add i64 %X, 1 ; <i64> [#uses=1] + store i64 %X, i64* @G + br label %Loop +} + diff --git a/test/Transforms/IndVarSimplify/2004-03-10-PHIInsertionBug.ll b/test/Transforms/IndVarSimplify/2004-03-10-PHIInsertionBug.ll new file mode 100644 index 000000000000..248b29b32d2c --- /dev/null +++ b/test/Transforms/IndVarSimplify/2004-03-10-PHIInsertionBug.ll @@ -0,0 +1,26 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +define void @test() { + br label %endif.0.i + +endif.0.i: ; preds = %0 + br i1 false, label %then.3.i, label %endif.3.i + +then.3.i: ; preds = %endif.0.i + br label %endif.3.i + +endif.3.i: ; preds = %then.3.i, %endif.0.i + %inxm.0.i = phi i32 [ 8, %then.3.i ], [ 0, %endif.0.i ] ; <i32> [#uses=1] + %doinner.1.i = phi i32 [ 0, %then.3.i ], [ 0, %endif.0.i ] ; <i32> [#uses=0] + br label %loopentry.2.i + +loopentry.2.i: ; preds = %no_exit.2.i, %endif.3.i + %inxk.0.i = phi i32 [ %tmp.210.i, %no_exit.2.i ], [ 0, %endif.3.i ] ; <i32> [#uses=1] + br label %no_exit.2.i + +no_exit.2.i: ; preds = %loopentry.2.i + %tmp.210.i = sub i32 %inxk.0.i, %inxm.0.i ; <i32> [#uses=2] + %tmp.213.i = add i32 %tmp.210.i, 0 ; <i32> [#uses=0] + br label %loopentry.2.i +} + diff --git a/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll b/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll new file mode 100644 index 000000000000..54d85472a891 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll @@ -0,0 +1,283 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; ModuleID = '2004-04-05-InvokeCastCrash.ll' + %struct.__false_type = type { i8 } + %"struct.__gnu_cxx::_Hashtable_node<const llvm::Constant*>" = type { %"struct.__gnu_cxx::_Hashtable_node<const llvm::Constant*>"*, %"struct.llvm::Constant"* } + %"struct.__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >" = type { %"struct.__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >"*, %"struct.std::pair<const llvm::Value* const,int>" } + %"struct.__gnu_cxx::hash_map<const llvm::Value*,int,__gnu_cxx::hash<const llvm::Value*>,std::equal_to<const llvm::Value*>,std::allocator<int> >" = type { %"struct.__gnu_cxx::hashtable<std::pair<const llvm::Value* const, int>,const llvm::Value*,__gnu_cxx::hash<const llvm::Value*>,std::_Select1st<std::pair<const llvm::Value* const, int> >,std::equal_to<const llvm::Value*>,std::allocator<int> >" } + %"struct.__gnu_cxx::hash_set<const llvm::Constant*,__gnu_cxx::hash<const llvm::Constant*>,std::equal_to<const llvm::Constant*>,std::allocator<const llvm::Constant*> >" = type { %"struct.__gnu_cxx::hashtable<const llvm::Constant*,const llvm::Constant*,__gnu_cxx::hash<const llvm::Constant*>,std::_Identity<const llvm::Constant*>,std::equal_to<const llvm::Constant*>,std::allocator<const llvm::Constant*> >" } + %"struct.__gnu_cxx::hashtable<const llvm::Constant*,const llvm::Constant*,__gnu_cxx::hash<const llvm::Constant*>,std::_Identity<const llvm::Constant*>,std::equal_to<const llvm::Constant*>,std::allocator<const llvm::Constant*> >" = type { %struct.__false_type, %struct.__false_type, %struct.__false_type, %struct.__false_type, %"struct.std::vector<__gnu_cxx::_Hashtable_node<const llvm::Constant*>*,std::allocator<const llvm::Constant*> >", i32 } + %"struct.__gnu_cxx::hashtable<std::pair<const llvm::Value* const, int>,const llvm::Value*,__gnu_cxx::hash<const llvm::Value*>,std::_Select1st<std::pair<const llvm::Value* const, int> >,std::equal_to<const llvm::Value*>,std::allocator<int> >" = type { %struct.__false_type, %struct.__false_type, %struct.__false_type, %struct.__false_type, %"struct.std::vector<__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >*,std::allocator<int> >", i32 } + %"struct.llvm::AbstractTypeUser" = type { i32 (...)** } + %"struct.llvm::Annotable" = type { i32 (...)**, %"struct.llvm::Annotation"* } + %"struct.llvm::Annotation" = type { i32 (...)**, %"struct.llvm::AnnotationID", %"struct.llvm::Annotation"* } + %"struct.llvm::AnnotationID" = type { i32 } + %"struct.llvm::Argument" = type { %"struct.llvm::Value", %"struct.llvm::Function"*, %"struct.llvm::Argument"*, %"struct.llvm::Argument"* } + %"struct.llvm::BasicBlock" = type { %"struct.llvm::Value", %"struct.llvm::iplist<llvm::Instruction,llvm::ilist_traits<llvm::Instruction> >", %"struct.llvm::BasicBlock"*, %"struct.llvm::BasicBlock"* } + %"struct.llvm::Constant" = type opaque + %"struct.llvm::DerivedType" = type { %"struct.llvm::Type", %"struct.llvm::AbstractTypeUser", %"struct.std::vector<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" } + %"struct.llvm::Function" = type { %"struct.llvm::GlobalValue", %"struct.llvm::Annotable", %"struct.llvm::iplist<llvm::BasicBlock,llvm::ilist_traits<llvm::BasicBlock> >", %"struct.llvm::iplist<llvm::Argument,llvm::ilist_traits<llvm::Argument> >", %"struct.llvm::SymbolTable"*, %"struct.llvm::Function"*, %"struct.llvm::Function"* } + %"struct.llvm::FunctionPass" = type { %"struct.llvm::Pass" } + %"struct.llvm::FunctionType" = type { %"struct.llvm::DerivedType", i1 } + %"struct.llvm::GlobalValue" = type { %"struct.llvm::User", i32, %"struct.llvm::Module"* } + %"struct.llvm::Instruction" = type { %"struct.llvm::User", %"struct.llvm::Annotable", %"struct.llvm::BasicBlock"*, %"struct.llvm::Instruction"*, %"struct.llvm::Instruction"*, i32 } + %"struct.llvm::IntrinsicLowering" = type opaque + %"struct.llvm::MachineBasicBlock" = type { %"struct.llvm::ilist<llvm::MachineInstr>", %"struct.llvm::MachineBasicBlock"*, %"struct.llvm::MachineBasicBlock"*, %"struct.llvm::BasicBlock"* } + %"struct.llvm::MachineConstantPool" = type opaque + %"struct.llvm::MachineFrameInfo" = type opaque + %"struct.llvm::MachineFunction" = type { %"struct.llvm::Annotation", %"struct.llvm::Function"*, %"struct.llvm::TargetMachine"*, %"struct.llvm::iplist<llvm::MachineBasicBlock,llvm::ilist_traits<llvm::MachineBasicBlock> >", %"struct.llvm::SSARegMap"*, %"struct.llvm::MachineFunctionInfo"*, %"struct.llvm::MachineFrameInfo"*, %"struct.llvm::MachineConstantPool"* } + %"struct.llvm::MachineFunctionInfo" = type { %"struct.__gnu_cxx::hash_set<const llvm::Constant*,__gnu_cxx::hash<const llvm::Constant*>,std::equal_to<const llvm::Constant*>,std::allocator<const llvm::Constant*> >", %"struct.__gnu_cxx::hash_map<const llvm::Value*,int,__gnu_cxx::hash<const llvm::Value*>,std::equal_to<const llvm::Value*>,std::allocator<int> >", i32, i32, i32, i32, i32, i32, i32, i1, i1, i1, %"struct.llvm::MachineFunction"* } + %"struct.llvm::MachineFunctionPass" = type { %"struct.llvm::FunctionPass" } + %"struct.llvm::MachineInstr" = type { i16, i8, %"struct.std::vector<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >", %"struct.llvm::MachineInstr"*, %"struct.llvm::MachineInstr"*, %"struct.llvm::MachineBasicBlock"* } + %"struct.llvm::MachineInstrBuilder" = type { %"struct.llvm::MachineInstr"* } + %"struct.llvm::MachineOperand" = type { %"union.llvm::MachineOperand::._65", i32, i32 } + %"struct.llvm::Module" = type opaque + %"struct.llvm::PATypeHandle" = type { %"struct.llvm::Type"*, %"struct.llvm::AbstractTypeUser"* } + %"struct.llvm::PATypeHolder" = type { %"struct.llvm::Type"* } + %"struct.llvm::Pass" = type { i32 (...)**, %"struct.llvm::AbstractTypeUser"*, %"struct.llvm::PassInfo"*, %"struct.std::vector<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" } + %"struct.llvm::PassInfo" = type { i8*, i8*, %"struct.std::type_info"*, i8, %"struct.std::vector<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >", %"struct.llvm::Pass"* ()*, %"struct.llvm::Pass"* (%"struct.llvm::TargetMachine"*)* } + %"struct.llvm::SSARegMap" = type opaque + %"struct.llvm::SymbolTable" = type opaque + %"struct.llvm::SymbolTableListTraits<llvm::Argument,llvm::Function,llvm::Function,llvm::ilist_traits<llvm::Argument> >" = type { %"struct.llvm::Function"*, %"struct.llvm::Function"* } + %"struct.llvm::SymbolTableListTraits<llvm::Instruction,llvm::BasicBlock,llvm::Function,llvm::ilist_traits<llvm::Instruction> >" = type { %"struct.llvm::Function"*, %"struct.llvm::BasicBlock"* } + %"struct.llvm::TargetData" = type { %"struct.llvm::FunctionPass", i1, i8, i8, i8, i8, i8, i8, i8, i8 } + %"struct.llvm::TargetFrameInfo" = type { i32 (...)**, i32, i32, i32 } + %"struct.llvm::TargetInstrDescriptor" = type { i8*, i32, i32, i32, i1, i32, i32, i32, i32, i32, i32*, i32* } + %"struct.llvm::TargetInstrInfo" = type { i32 (...)**, %"struct.llvm::TargetInstrDescriptor"*, i32, i32 } + %"struct.llvm::TargetMachine" = type { i32 (...)**, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >", %"struct.llvm::TargetData", %"struct.llvm::IntrinsicLowering"* } + %"struct.llvm::TargetRegClassInfo" = type { i32 (...)**, i32, i32, i32 } + %"struct.llvm::TargetRegInfo" = type { i32 (...)**, %"struct.std::vector<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*> >", %"struct.llvm::TargetMachine"* } + %"struct.llvm::Type" = type { %"struct.llvm::Value", i32, i32, i1, i32, %"struct.llvm::Type"*, %"struct.std::vector<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle> >" } + %"struct.llvm::Use" = type { %"struct.llvm::Value"*, %"struct.llvm::User"*, %"struct.llvm::Use"*, %"struct.llvm::Use"* } + %"struct.llvm::User" = type { %"struct.llvm::Value", %"struct.std::vector<llvm::Use,std::allocator<llvm::Use> >" } + %"struct.llvm::Value" = type { i32 (...)**, %"struct.llvm::iplist<llvm::Use,llvm::ilist_traits<llvm::Use> >", %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >", %"struct.llvm::PATypeHolder", i32 } + %"struct.llvm::_GLOBAL__N_::InsertPrologEpilogCode" = type { %"struct.llvm::MachineFunctionPass" } + %"struct.llvm::ilist<llvm::MachineInstr>" = type { %"struct.llvm::iplist<llvm::MachineInstr,llvm::ilist_traits<llvm::MachineInstr> >" } + %"struct.llvm::ilist_iterator<const llvm::MachineBasicBlock>" = type { %"struct.llvm::MachineBasicBlock"* } + %"struct.llvm::ilist_traits<llvm::Argument>" = type { %"struct.llvm::SymbolTableListTraits<llvm::Argument,llvm::Function,llvm::Function,llvm::ilist_traits<llvm::Argument> >" } + %"struct.llvm::ilist_traits<llvm::Instruction>" = type { %"struct.llvm::SymbolTableListTraits<llvm::Instruction,llvm::BasicBlock,llvm::Function,llvm::ilist_traits<llvm::Instruction> >" } + %"struct.llvm::iplist<llvm::Argument,llvm::ilist_traits<llvm::Argument> >" = type { %"struct.llvm::ilist_traits<llvm::Argument>", %"struct.llvm::Argument"*, %"struct.llvm::Argument"* } + %"struct.llvm::iplist<llvm::BasicBlock,llvm::ilist_traits<llvm::BasicBlock> >" = type { %"struct.llvm::ilist_traits<llvm::Argument>", %"struct.llvm::BasicBlock"*, %"struct.llvm::BasicBlock"* } + %"struct.llvm::iplist<llvm::Instruction,llvm::ilist_traits<llvm::Instruction> >" = type { %"struct.llvm::ilist_traits<llvm::Instruction>", %"struct.llvm::Instruction"*, %"struct.llvm::Instruction"* } + %"struct.llvm::iplist<llvm::MachineBasicBlock,llvm::ilist_traits<llvm::MachineBasicBlock> >" = type { %"struct.llvm::MachineBasicBlock"*, %"struct.llvm::MachineBasicBlock"* } + %"struct.llvm::iplist<llvm::MachineInstr,llvm::ilist_traits<llvm::MachineInstr> >" = type { %"struct.llvm::ilist_iterator<const llvm::MachineBasicBlock>", %"struct.llvm::MachineInstr"*, %"struct.llvm::MachineInstr"* } + %"struct.llvm::iplist<llvm::Use,llvm::ilist_traits<llvm::Use> >" = type { %"struct.llvm::Use"*, %"struct.llvm::Use"* } + %"struct.std::_Vector_alloc_base<__gnu_cxx::_Hashtable_node<const llvm::Constant*>*,std::allocator<const llvm::Constant*>, true>" = type { %"struct.__gnu_cxx::_Hashtable_node<const llvm::Constant*>"**, %"struct.__gnu_cxx::_Hashtable_node<const llvm::Constant*>"**, %"struct.__gnu_cxx::_Hashtable_node<const llvm::Constant*>"** } + %"struct.std::_Vector_alloc_base<__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >*,std::allocator<int>, true>" = type { %"struct.__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >"**, %"struct.__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >"**, %"struct.__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >"** } + %"struct.std::_Vector_alloc_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*>, true>" = type { %"struct.llvm::PassInfo"**, %"struct.llvm::PassInfo"**, %"struct.llvm::PassInfo"** } + %"struct.std::_Vector_alloc_base<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*>, true>" = type { %"struct.llvm::TargetFrameInfo"**, %"struct.llvm::TargetFrameInfo"**, %"struct.llvm::TargetFrameInfo"** } + %"struct.std::_Vector_alloc_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*>, true>" = type { %"struct.llvm::AbstractTypeUser"**, %"struct.llvm::AbstractTypeUser"**, %"struct.llvm::AbstractTypeUser"** } + %"struct.std::_Vector_alloc_base<llvm::MachineInstr*,std::allocator<llvm::MachineInstr*>, true>" = type { %"struct.llvm::MachineInstr"**, %"struct.llvm::MachineInstr"**, %"struct.llvm::MachineInstr"** } + %"struct.std::_Vector_alloc_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand>, true>" = type { %"struct.llvm::MachineOperand"*, %"struct.llvm::MachineOperand"*, %"struct.llvm::MachineOperand"* } + %"struct.std::_Vector_alloc_base<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle>, true>" = type { %"struct.llvm::PATypeHandle"*, %"struct.llvm::PATypeHandle"*, %"struct.llvm::PATypeHandle"* } + %"struct.std::_Vector_alloc_base<llvm::Use,std::allocator<llvm::Use>, true>" = type { %"struct.llvm::Use"*, %"struct.llvm::Use"*, %"struct.llvm::Use"* } + %"struct.std::_Vector_alloc_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> >, true>" = type { %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>"*, %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>"*, %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>"* } + %"struct.std::_Vector_base<__gnu_cxx::_Hashtable_node<const llvm::Constant*>*,std::allocator<const llvm::Constant*> >" = type { %"struct.std::_Vector_alloc_base<__gnu_cxx::_Hashtable_node<const llvm::Constant*>*,std::allocator<const llvm::Constant*>, true>" } + %"struct.std::_Vector_base<__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >*,std::allocator<int> >" = type { %"struct.std::_Vector_alloc_base<__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >*,std::allocator<int>, true>" } + %"struct.std::_Vector_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >" = type { %"struct.std::_Vector_alloc_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*>, true>" } + %"struct.std::_Vector_base<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*> >" = type { %"struct.std::_Vector_alloc_base<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*>, true>" } + %"struct.std::_Vector_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" = type { %"struct.std::_Vector_alloc_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*>, true>" } + %"struct.std::_Vector_base<llvm::MachineInstr*,std::allocator<llvm::MachineInstr*> >" = type { %"struct.std::_Vector_alloc_base<llvm::MachineInstr*,std::allocator<llvm::MachineInstr*>, true>" } + %"struct.std::_Vector_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >" = type { %"struct.std::_Vector_alloc_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand>, true>" } + %"struct.std::_Vector_base<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle> >" = type { %"struct.std::_Vector_alloc_base<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle>, true>" } + %"struct.std::_Vector_base<llvm::Use,std::allocator<llvm::Use> >" = type { %"struct.std::_Vector_alloc_base<llvm::Use,std::allocator<llvm::Use>, true>" } + %"struct.std::_Vector_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" = type { %"struct.std::_Vector_alloc_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> >, true>" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider" } + %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider" = type { i8* } + %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>" = type { %"struct.llvm::PassInfo"*, %"struct.llvm::Pass"* } + %"struct.std::pair<const llvm::Value* const,int>" = type { %"struct.llvm::Value"*, i32 } + %"struct.std::type_info" = type { i32 (...)**, i8* } + %"struct.std::vector<__gnu_cxx::_Hashtable_node<const llvm::Constant*>*,std::allocator<const llvm::Constant*> >" = type { %"struct.std::_Vector_base<__gnu_cxx::_Hashtable_node<const llvm::Constant*>*,std::allocator<const llvm::Constant*> >" } + %"struct.std::vector<__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >*,std::allocator<int> >" = type { %"struct.std::_Vector_base<__gnu_cxx::_Hashtable_node<std::pair<const llvm::Value* const, int> >*,std::allocator<int> >" } + %"struct.std::vector<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >" = type { %"struct.std::_Vector_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >" } + %"struct.std::vector<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*> >" = type { %"struct.std::_Vector_base<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*> >" } + %"struct.std::vector<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" = type { %"struct.std::_Vector_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" } + %"struct.std::vector<llvm::MachineInstr*,std::allocator<llvm::MachineInstr*> >" = type { %"struct.std::_Vector_base<llvm::MachineInstr*,std::allocator<llvm::MachineInstr*> >" } + %"struct.std::vector<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >" = type { %"struct.std::_Vector_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >" } + %"struct.std::vector<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle> >" = type { %"struct.std::_Vector_base<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle> >" } + %"struct.std::vector<llvm::Use,std::allocator<llvm::Use> >" = type { %"struct.std::_Vector_base<llvm::Use,std::allocator<llvm::Use> >" } + %"struct.std::vector<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" = type { %"struct.std::_Vector_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" } + %"union.llvm::MachineOperand::._65" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* } + +declare void @_Znwj() + +declare void @_ZN4llvm12MachineInstrC1Esjbb() + +declare void @_ZNSt6vectorIPN4llvm12MachineInstrESaIS2_EE9push_backERKS2_() + +declare void @_ZNK4llvm8Function15getFunctionTypeEv() + +declare void @_ZNK4llvm19MachineInstrBuilder7addMRegEiNS_14MachineOperand7UseTypeE() + +declare void @_ZNK4llvm19MachineInstrBuilder7addSImmEi() + +define void @_ZN4llvm11_GLOBAL__N_22InsertPrologEpilogCode20runOnMachineFunctionERNS_15MachineFunctionE(%"struct.llvm::MachineFunction"* %F) { +entry: + %tmp.8.i = invoke %"struct.llvm::TargetFrameInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.0.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetFrameInfo"*> [#uses=0] + +invoke_catch.0.i: ; preds = %invoke_cont.49.i, %invoke_cont.48.i, %invoke_cont.47.i, %invoke_cont.i53.i, %no_exit.i, %invoke_cont.44.i, %invoke_cont.43.i, %invoke_cont.42.i, %invoke_cont.41.i, %invoke_cont.40.i, %invoke_cont.39.i, %invoke_cont.38.i, %invoke_cont.37.i, %then.2.i, %invoke_cont.35.i, %invoke_cont.34.i, %then.1.i, %endif.0.i, %invoke_cont.9.i, %invoke_cont.8.i, %invoke_cont.7.i, %invoke_cont.i.i, %then.0.i, %invoke_cont.4.i, %invoke_cont.3.i, %invoke_cont.2.i, %invoke_cont.1.i, %endif.0.i.i, %tmp.7.i.noexc.i, %invoke_cont.0.i, %entry + ret void + +invoke_cont.0.i: ; preds = %entry + %tmp.7.i1.i = invoke %"struct.llvm::TargetFrameInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %tmp.7.i.noexc.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetFrameInfo"*> [#uses=2] + +tmp.7.i.noexc.i: ; preds = %invoke_cont.0.i + %tmp.17.i2.i = invoke i32 null( %"struct.llvm::TargetFrameInfo"* %tmp.7.i1.i ) + to label %endif.0.i.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +endif.0.i.i: ; preds = %tmp.7.i.noexc.i + %tmp.38.i4.i = invoke i32 null( %"struct.llvm::TargetFrameInfo"* %tmp.7.i1.i ) + to label %tmp.38.i.noexc.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +tmp.38.i.noexc.i: ; preds = %endif.0.i.i + br i1 false, label %invoke_cont.1.i, label %then.1.i.i + +then.1.i.i: ; preds = %tmp.38.i.noexc.i + ret void + +invoke_cont.1.i: ; preds = %tmp.38.i.noexc.i + %tmp.21.i = invoke %"struct.llvm::TargetRegInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.2.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetRegInfo"*> [#uses=1] + +invoke_cont.2.i: ; preds = %invoke_cont.1.i + %tmp.28.i = invoke i32 null( %"struct.llvm::TargetRegInfo"* %tmp.21.i ) + to label %invoke_cont.3.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +invoke_cont.3.i: ; preds = %invoke_cont.2.i + %tmp.36.i = invoke %"struct.llvm::TargetInstrInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.4.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetInstrInfo"*> [#uses=1] + +invoke_cont.4.i: ; preds = %invoke_cont.3.i + %tmp.43.i = invoke i1 null( %"struct.llvm::TargetInstrInfo"* %tmp.36.i, i16 383, i64 0 ) + to label %invoke_cont.5.i unwind label %invoke_catch.0.i ; <i1> [#uses=1] + +invoke_cont.5.i: ; preds = %invoke_cont.4.i + br i1 %tmp.43.i, label %then.0.i, label %else.i + +then.0.i: ; preds = %invoke_cont.5.i + invoke void @_Znwj( ) + to label %tmp.0.i.noexc.i unwind label %invoke_catch.0.i + +tmp.0.i.noexc.i: ; preds = %then.0.i + invoke void @_ZN4llvm12MachineInstrC1Esjbb( ) + to label %invoke_cont.i.i unwind label %cond_true.i.i + +cond_true.i.i: ; preds = %tmp.0.i.noexc.i + ret void + +invoke_cont.i.i: ; preds = %tmp.0.i.noexc.i + invoke void @_ZNK4llvm19MachineInstrBuilder7addMRegEiNS_14MachineOperand7UseTypeE( ) + to label %invoke_cont.7.i unwind label %invoke_catch.0.i + +invoke_cont.7.i: ; preds = %invoke_cont.i.i + invoke void @_ZNK4llvm19MachineInstrBuilder7addSImmEi( ) + to label %invoke_cont.8.i unwind label %invoke_catch.0.i + +invoke_cont.8.i: ; preds = %invoke_cont.7.i + invoke void @_ZNK4llvm19MachineInstrBuilder7addMRegEiNS_14MachineOperand7UseTypeE( ) + to label %invoke_cont.9.i unwind label %invoke_catch.0.i + +invoke_cont.9.i: ; preds = %invoke_cont.8.i + invoke void @_ZNSt6vectorIPN4llvm12MachineInstrESaIS2_EE9push_backERKS2_( ) + to label %endif.0.i unwind label %invoke_catch.0.i + +else.i: ; preds = %invoke_cont.5.i + ret void + +endif.0.i: ; preds = %invoke_cont.9.i + invoke void @_ZNK4llvm8Function15getFunctionTypeEv( ) + to label %invoke_cont.33.i unwind label %invoke_catch.0.i + +invoke_cont.33.i: ; preds = %endif.0.i + br i1 false, label %then.1.i, label %endif.1.i + +then.1.i: ; preds = %invoke_cont.33.i + invoke void @_ZNK4llvm8Function15getFunctionTypeEv( ) + to label %invoke_cont.34.i unwind label %invoke_catch.0.i + +invoke_cont.34.i: ; preds = %then.1.i + %tmp.121.i = invoke %"struct.llvm::TargetRegInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.35.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetRegInfo"*> [#uses=1] + +invoke_cont.35.i: ; preds = %invoke_cont.34.i + %tmp.128.i = invoke i32 null( %"struct.llvm::TargetRegInfo"* %tmp.121.i ) + to label %invoke_cont.36.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +invoke_cont.36.i: ; preds = %invoke_cont.35.i + br i1 false, label %then.2.i, label %endif.1.i + +then.2.i: ; preds = %invoke_cont.36.i + %tmp.140.i = invoke %"struct.llvm::TargetRegInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.37.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetRegInfo"*> [#uses=0] + +invoke_cont.37.i: ; preds = %then.2.i + %tmp.148.i = invoke %"struct.llvm::TargetRegInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.38.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetRegInfo"*> [#uses=1] + +invoke_cont.38.i: ; preds = %invoke_cont.37.i + %tmp.155.i = invoke i32 null( %"struct.llvm::TargetRegInfo"* %tmp.148.i, %"struct.llvm::Type"* null, i1 false ) + to label %invoke_cont.39.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +invoke_cont.39.i: ; preds = %invoke_cont.38.i + %tmp.163.i = invoke %"struct.llvm::TargetFrameInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.40.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetFrameInfo"*> [#uses=1] + +invoke_cont.40.i: ; preds = %invoke_cont.39.i + %tmp.170.i = invoke i32 null( %"struct.llvm::TargetFrameInfo"* %tmp.163.i ) + to label %invoke_cont.41.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +invoke_cont.41.i: ; preds = %invoke_cont.40.i + %tmp.177.i = invoke %"struct.llvm::TargetFrameInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.42.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetFrameInfo"*> [#uses=1] + +invoke_cont.42.i: ; preds = %invoke_cont.41.i + %tmp.184.i = invoke i32 null( %"struct.llvm::TargetFrameInfo"* %tmp.177.i ) + to label %invoke_cont.43.i unwind label %invoke_catch.0.i ; <i32> [#uses=1] + +invoke_cont.43.i: ; preds = %invoke_cont.42.i + %tmp.191.i = invoke %"struct.llvm::TargetFrameInfo"* null( %"struct.llvm::TargetMachine"* null ) + to label %invoke_cont.44.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetFrameInfo"*> [#uses=1] + +invoke_cont.44.i: ; preds = %invoke_cont.43.i + %tmp.198.i = invoke i32 null( %"struct.llvm::TargetFrameInfo"* %tmp.191.i, %"struct.llvm::MachineFunction"* %F, i1* null ) + to label %invoke_cont.45.i unwind label %invoke_catch.0.i ; <i32> [#uses=0] + +invoke_cont.45.i: ; preds = %invoke_cont.44.i + br i1 false, label %no_exit.i, label %endif.1.i + +no_exit.i: ; preds = %invoke_cont.50.i, %invoke_cont.45.i + %nextArgOffset.0.i.1 = phi i32 [ %tmp.221.i, %invoke_cont.50.i ], [ 0, %invoke_cont.45.i ] ; <i32> [#uses=1] + invoke void @_Znwj( ) + to label %tmp.0.i.noexc55.i unwind label %invoke_catch.0.i + +tmp.0.i.noexc55.i: ; preds = %no_exit.i + invoke void @_ZN4llvm12MachineInstrC1Esjbb( ) + to label %invoke_cont.i53.i unwind label %cond_true.i52.i + +cond_true.i52.i: ; preds = %tmp.0.i.noexc55.i + ret void + +invoke_cont.i53.i: ; preds = %tmp.0.i.noexc55.i + invoke void @_ZNK4llvm19MachineInstrBuilder7addMRegEiNS_14MachineOperand7UseTypeE( ) + to label %invoke_cont.47.i unwind label %invoke_catch.0.i + +invoke_cont.47.i: ; preds = %invoke_cont.i53.i + invoke void @_ZNK4llvm19MachineInstrBuilder7addMRegEiNS_14MachineOperand7UseTypeE( ) + to label %invoke_cont.48.i unwind label %invoke_catch.0.i + +invoke_cont.48.i: ; preds = %invoke_cont.47.i + invoke void @_ZNK4llvm19MachineInstrBuilder7addSImmEi( ) + to label %invoke_cont.49.i unwind label %invoke_catch.0.i + +invoke_cont.49.i: ; preds = %invoke_cont.48.i + invoke void @_ZNSt6vectorIPN4llvm12MachineInstrESaIS2_EE9push_backERKS2_( ) + to label %invoke_cont.50.i unwind label %invoke_catch.0.i + +invoke_cont.50.i: ; preds = %invoke_cont.49.i + %tmp.221.i = add i32 %nextArgOffset.0.i.1, %tmp.184.i ; <i32> [#uses=1] + br i1 false, label %no_exit.i, label %endif.1.i + +endif.1.i: ; preds = %invoke_cont.50.i, %invoke_cont.45.i, %invoke_cont.36.i, %invoke_cont.33.i + ret void +} diff --git a/test/Transforms/IndVarSimplify/2004-04-07-ScalarEvolutionCrash.ll b/test/Transforms/IndVarSimplify/2004-04-07-ScalarEvolutionCrash.ll new file mode 100644 index 000000000000..b4eb3db19095 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2004-04-07-ScalarEvolutionCrash.ll @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +define void @.outPlank_21() { +entry: + br i1 false, label %loopexit.0, label %no_exit.0 + +no_exit.0: ; preds = %entry + ret void + +loopexit.0: ; preds = %entry + br i1 false, label %no_exit.1, label %loopexit.1 + +no_exit.1: ; preds = %loopexit.2, %loopexit.0 + %i.0.0 = phi i32 [ %inc, %loopexit.2 ], [ 0, %loopexit.0 ] ; <i32> [#uses=1] + br i1 false, label %loopexit.2, label %no_exit.2 + +no_exit.2: ; preds = %no_exit.1 + ret void + +loopexit.2: ; preds = %no_exit.1 + %inc = add i32 %i.0.0, 1 ; <i32> [#uses=1] + br i1 false, label %no_exit.1, label %loopexit.1 + +loopexit.1: ; preds = %loopexit.2, %loopexit.0 + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll b/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll new file mode 100644 index 000000000000..afee7e189180 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +define void @_ZN5ArrayISt7complexIdEEC2ERK10dim_vector() { +entry: + %tmp.7 = invoke i32 @_ZN5ArrayISt7complexIdEE8get_sizeERK10dim_vector( ) + to label %invoke_cont.0 unwind label %cond_true.1 ; <i32> [#uses=2] + +cond_true.1: ; preds = %entry + unwind + +invoke_cont.0: ; preds = %entry + %tmp.4.i = bitcast i32 %tmp.7 to i32 ; <i32> [#uses=0] + %tmp.14.0.i5 = add i32 %tmp.7, -1 ; <i32> [#uses=1] + br label %no_exit.i + +no_exit.i: ; preds = %no_exit.i, %invoke_cont.0 + %tmp.14.0.i.0 = phi i32 [ %tmp.14.0.i, %no_exit.i ], [ %tmp.14.0.i5, %invoke_cont.0 ] ; <i32> [#uses=1] + %tmp.14.0.i = add i32 %tmp.14.0.i.0, -1 ; <i32> [#uses=1] + br label %no_exit.i +} + +declare i32 @_ZN5ArrayISt7complexIdEE8get_sizeERK10dim_vector() + diff --git a/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll b/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll new file mode 100644 index 000000000000..a1beec646891 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll @@ -0,0 +1,61 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +declare void @q_atomic_increment() + +declare void @_Z9qt_assertPKcS0_i() + +define void @_ZN13QMetaResourceC1EPKh() { +entry: + invoke void @_Z9qt_assertPKcS0_i( ) + to label %endif.1 unwind label %then.i.i551 + +then.i.i551: ; preds = %entry + ret void + +endif.1: ; preds = %entry + br i1 false, label %then.2, label %then.i.i + +then.2: ; preds = %endif.1 + invoke void @q_atomic_increment( ) + to label %loopentry.0 unwind label %invoke_catch.6 + +invoke_catch.6: ; preds = %then.2 + ret void + +loopentry.0: ; preds = %then.2 + br i1 false, label %shortcirc_next.i, label %endif.3 + +endif.3: ; preds = %loopentry.0 + ret void + +shortcirc_next.i: ; preds = %loopentry.0 + br i1 false, label %_ZNK7QString2atEi.exit, label %then.i + +then.i: ; preds = %shortcirc_next.i + ret void + +_ZNK7QString2atEi.exit: ; preds = %shortcirc_next.i + br i1 false, label %endif.4, label %then.4 + +then.4: ; preds = %_ZNK7QString2atEi.exit + ret void + +endif.4: ; preds = %_ZNK7QString2atEi.exit + %tmp.115 = load i8* null ; <i8> [#uses=1] + br i1 false, label %loopexit.1, label %no_exit.0 + +no_exit.0: ; preds = %no_exit.0, %endif.4 + %bytes_in_len.4.5 = phi i8 [ %dec, %no_exit.0 ], [ %tmp.115, %endif.4 ] ; <i8> [#uses=1] + %off.5.5.in = phi i32 [ %off.5.5, %no_exit.0 ], [ 0, %endif.4 ] ; <i32> [#uses=1] + %off.5.5 = add i32 %off.5.5.in, 1 ; <i32> [#uses=2] + %dec = add i8 %bytes_in_len.4.5, -1 ; <i8> [#uses=2] + %tmp.123631 = icmp eq i8 %dec, 0 ; <i1> [#uses=1] + br i1 %tmp.123631, label %loopexit.1, label %no_exit.0 + +loopexit.1: ; preds = %no_exit.0, %endif.4 + %off.5.in.6 = phi i32 [ 0, %endif.4 ], [ %off.5.5, %no_exit.0 ] ; <i32> [#uses=0] + ret void + +then.i.i: ; preds = %endif.1 + ret void +} diff --git a/test/Transforms/IndVarSimplify/2005-02-26-ExitValueCompute.ll b/test/Transforms/IndVarSimplify/2005-02-26-ExitValueCompute.ll new file mode 100644 index 000000000000..853d5ad50146 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2005-02-26-ExitValueCompute.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | \ +; RUN: grep {ret i32 152} + +define i32 @main() { +entry: + br label %no_exit + +no_exit: ; preds = %no_exit, %entry + %i.1.0 = phi i32 [ 0, %entry ], [ %inc, %no_exit ] ; <i32> [#uses=2] + %tmp.4 = icmp sgt i32 %i.1.0, 50 ; <i1> [#uses=1] + %tmp.7 = select i1 %tmp.4, i32 100, i32 0 ; <i32> [#uses=1] + %i.0 = add i32 %i.1.0, 1 ; <i32> [#uses=1] + %inc = add i32 %i.0, %tmp.7 ; <i32> [#uses=3] + %tmp.1 = icmp slt i32 %inc, 100 ; <i1> [#uses=1] + br i1 %tmp.1, label %no_exit, label %loopexit + +loopexit: ; preds = %no_exit + ret i32 %inc +} + diff --git a/test/Transforms/IndVarSimplify/2005-06-15-InstMoveCrash.ll b/test/Transforms/IndVarSimplify/2005-06-15-InstMoveCrash.ll new file mode 100644 index 000000000000..ba4db9f95995 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2005-06-15-InstMoveCrash.ll @@ -0,0 +1,37 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +define void @main() { +entry: + br label %no_exit.1.outer + +no_exit.1.outer: ; preds = %endif.0, %entry + %l_14237116.1.0.ph = phi i8 [ -46, %entry ], [ 0, %endif.0 ] ; <i8> [#uses=1] + %i.0.0.0.ph = phi i32 [ 0, %entry ], [ %inc.1, %endif.0 ] ; <i32> [#uses=1] + br label %no_exit.1 + +no_exit.1: ; preds = %_Z13func_47880058cc.exit, %no_exit.1.outer + br i1 false, label %_Z13func_47880058cc.exit, label %then.i + +then.i: ; preds = %no_exit.1 + br label %_Z13func_47880058cc.exit + +_Z13func_47880058cc.exit: ; preds = %then.i, %no_exit.1 + br i1 false, label %then.0, label %no_exit.1 + +then.0: ; preds = %_Z13func_47880058cc.exit + %tmp.6 = bitcast i8 %l_14237116.1.0.ph to i8 ; <i8> [#uses=1] + br i1 false, label %endif.0, label %then.1 + +then.1: ; preds = %then.0 + br label %endif.0 + +endif.0: ; preds = %then.1, %then.0 + %inc.1 = add i32 %i.0.0.0.ph, 1 ; <i32> [#uses=2] + %tmp.2 = icmp sgt i32 %inc.1, 99 ; <i1> [#uses=1] + br i1 %tmp.2, label %loopexit.0, label %no_exit.1.outer + +loopexit.0: ; preds = %endif.0 + %tmp.28 = zext i8 %tmp.6 to i32 ; <i32> [#uses=0] + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll b/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll new file mode 100644 index 000000000000..5ee8cea74a38 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2005-11-18-Crash.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +@fixtab = external global [29 x [29 x [2 x i32]]] ; <[29 x [29 x [2 x i32]]]*> [#uses=1] + +define void @init_optabs() { +entry: + br label %no_exit.0 + +no_exit.0: ; preds = %no_exit.0, %entry + %p.0.0 = phi i32* [ getelementptr ([29 x [29 x [2 x i32]]]* @fixtab, i32 0, i32 0, i32 0, i32 0), %entry ], [ %inc.0, %no_exit.0 ] ; <i32*> [#uses=1] + %inc.0 = getelementptr i32* %p.0.0, i32 1 ; <i32*> [#uses=1] + br i1 false, label %no_exit.0, label %no_exit.1 + +no_exit.1: ; preds = %no_exit.0 + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2006-03-31-NegativeStride.ll b/test/Transforms/IndVarSimplify/2006-03-31-NegativeStride.ll new file mode 100644 index 000000000000..32abee9d1cc8 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2006-03-31-NegativeStride.ll @@ -0,0 +1,22 @@ +; PR726 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | \ +; RUN: grep {ret i32 27} + +; Make sure to compute the right exit value based on negative strides. + +define i32 @test() { +entry: + br label %cond_true + +cond_true: ; preds = %cond_true, %entry + %a.0.0 = phi i32 [ 10, %entry ], [ %tmp4, %cond_true ] ; <i32> [#uses=2] + %b.0.0 = phi i32 [ 0, %entry ], [ %tmp2, %cond_true ] ; <i32> [#uses=1] + %tmp2 = add i32 %b.0.0, %a.0.0 ; <i32> [#uses=2] + %tmp4 = add i32 %a.0.0, -1 ; <i32> [#uses=2] + %tmp = icmp sgt i32 %tmp4, 7 ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %bb7 + +bb7: ; preds = %cond_true + ret i32 %tmp2 +} + diff --git a/test/Transforms/IndVarSimplify/2006-06-16-Indvar-LCSSA-Crash.ll b/test/Transforms/IndVarSimplify/2006-06-16-Indvar-LCSSA-Crash.ll new file mode 100644 index 000000000000..986831b9a6e4 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2006-06-16-Indvar-LCSSA-Crash.ll @@ -0,0 +1,22 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +define void @get_block() { +endif.0: + br label %no_exit.30 + +no_exit.30: ; preds = %no_exit.30, %endif.0 + %x.12.0 = phi i32 [ %inc.28, %no_exit.30 ], [ -2, %endif.0 ] ; <i32> [#uses=1] + %tmp.583 = load i16* null ; <i16> [#uses=1] + %tmp.584 = zext i16 %tmp.583 to i32 ; <i32> [#uses=1] + %tmp.588 = load i32* null ; <i32> [#uses=1] + %tmp.589 = mul i32 %tmp.584, %tmp.588 ; <i32> [#uses=1] + %tmp.591 = add i32 %tmp.589, 0 ; <i32> [#uses=1] + %inc.28 = add i32 %x.12.0, 1 ; <i32> [#uses=2] + %tmp.565 = icmp sgt i32 %inc.28, 3 ; <i1> [#uses=1] + br i1 %tmp.565, label %loopexit.30, label %no_exit.30 + +loopexit.30: ; preds = %no_exit.30 + %tmp.591.lcssa = phi i32 [ %tmp.591, %no_exit.30 ] ; <i32> [#uses=0] + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2006-09-20-LFTR-Crash.ll b/test/Transforms/IndVarSimplify/2006-09-20-LFTR-Crash.ll new file mode 100644 index 000000000000..6a478ab5f5fd --- /dev/null +++ b/test/Transforms/IndVarSimplify/2006-09-20-LFTR-Crash.ll @@ -0,0 +1,44 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; ModuleID = '2006-09-20-LFTR-Crash.ll' + %struct.p7prior_s = type { i32, i32, [200 x float], [200 x [7 x float]], i32, [200 x float], [200 x [20 x float]], i32, [200 x float], [200 x [20 x float]] } + +define void @P7DefaultPrior() { +entry: + switch i32 0, label %UnifiedReturnBlock [ + i32 2, label %bb160 + i32 3, label %bb + ] + +bb: ; preds = %entry + br i1 false, label %cond_true.i, label %sre_malloc.exit + +cond_true.i: ; preds = %bb + unreachable + +sre_malloc.exit: ; preds = %bb + br label %cond_true + +cond_true: ; preds = %cond_true66, %cond_true, %sre_malloc.exit + %tmp59 = phi i32 [ 1, %sre_malloc.exit ], [ %phitmp, %cond_true66 ], [ %tmp59, %cond_true ] ; <i32> [#uses=2] + %indvar245.0.ph = phi i32 [ 0, %sre_malloc.exit ], [ %indvar.next246, %cond_true66 ], [ %indvar245.0.ph, %cond_true ] ; <i32> [#uses=2] + br i1 false, label %bb57, label %cond_true + +bb57: ; preds = %cond_true + %tmp65 = icmp sgt i32 0, %tmp59 ; <i1> [#uses=1] + %indvar.next246 = add i32 %indvar245.0.ph, 1 ; <i32> [#uses=2] + br i1 %tmp65, label %cond_true66, label %bb69 + +cond_true66: ; preds = %bb57 + %q.1.0 = bitcast i32 %indvar.next246 to i32 ; <i32> [#uses=1] + %phitmp = add i32 %q.1.0, 1 ; <i32> [#uses=1] + br label %cond_true + +bb69: ; preds = %bb57 + ret void + +bb160: ; preds = %entry + ret void + +UnifiedReturnBlock: ; preds = %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll b/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll new file mode 100644 index 000000000000..903e81d3bf96 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2006-12-10-BitCast.ll @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +target datalayout = "e-p:32:32" +target triple = "i686-apple-darwin8" + %struct.vorbis_dsp_state = type { i32, %struct.vorbis_info*, float**, float**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64, i64, i64, i64, i64, i64, i8* } + %struct.vorbis_info = type { i32, i32, i32, i32, i32, i32, i32, i8* } + +define void @_ve_envelope_search() { +entry: + br i1 false, label %cond_true27, label %bb137 + +cond_true27: ; preds = %entry + br i1 false, label %cond_true52, label %bb80 + +cond_true52: ; preds = %cond_true27 + %tmp152.i = bitcast float 0.000000e+00 to i32 ; <i32> [#uses=1] + br label %cond_next182.i + +cond_next182.i: ; preds = %cond_next182.i, %cond_true52 + %decay.i.0 = phi i32 [ %tmp195.i.upgrd.1, %cond_next182.i ], [ %tmp152.i, %cond_true52 ] ; <i32> [#uses=1] + %tmp194.i53 = bitcast i32 %decay.i.0 to float ; <float> [#uses=1] + %tmp195.i = sub float %tmp194.i53, 8.000000e+00 ; <float> [#uses=1] + %tmp195.i.upgrd.1 = bitcast float %tmp195.i to i32 ; <i32> [#uses=1] + br i1 false, label %cond_next182.i, label %bb418.i.preheader + +bb418.i.preheader: ; preds = %cond_next182.i + ret void + +bb80: ; preds = %cond_true27 + ret void + +bb137: ; preds = %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/2007-01-06-TripCount.ll b/test/Transforms/IndVarSimplify/2007-01-06-TripCount.ll new file mode 100644 index 000000000000..dd151e84d00e --- /dev/null +++ b/test/Transforms/IndVarSimplify/2007-01-06-TripCount.ll @@ -0,0 +1,38 @@ +; PR1015 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | not grep {ret i32 0} + +target datalayout = "e-p:32:32" +target triple = "i686-apple-darwin8" +@foo = internal constant [5 x i8] c"\00abc\00" ; <[5 x i8]*> [#uses=1] +@str = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + + +define i32 @test(i32 %J) { +entry: + br label %bb2 + +bb: ; preds = %cond_next, %cond_true + %tmp1 = add i32 %i.0, 1 ; <i32> [#uses=1] + br label %bb2 + +bb2: ; preds = %bb, %entry + %i.0 = phi i32 [ 0, %entry ], [ %tmp1, %bb ] ; <i32> [#uses=4] + %tmp = icmp eq i32 %i.0, 0 ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %cond_next + +cond_true: ; preds = %bb2 + br label %bb + +cond_next: ; preds = %bb2 + %tmp2 = getelementptr [5 x i8]* @foo, i32 0, i32 %i.0 ; <i8*> [#uses=1] + %tmp3 = load i8* %tmp2 ; <i8> [#uses=1] + %tmp5 = icmp eq i8 %tmp3, 0 ; <i1> [#uses=1] + br i1 %tmp5, label %bb6, label %bb + +bb6: ; preds = %cond_next + br label %return + +return: ; preds = %bb6 + ret i32 %i.0 +} + diff --git a/test/Transforms/IndVarSimplify/2007-01-08-X86-64-Pointer.ll b/test/Transforms/IndVarSimplify/2007-01-08-X86-64-Pointer.ll new file mode 100644 index 000000000000..7078494a9295 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2007-01-08-X86-64-Pointer.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep {(%rdi,%rax,8)} +; RUN: llvm-as < %s | llc -march=x86-64 | not grep {addq.*8} + +define void @foo(double* %y) nounwind { +entry: + br label %bb + +bb: + %i = phi i64 [ 0, %entry ], [ %k, %bb ] + %j = getelementptr double* %y, i64 %i + store double 0.000000e+00, double* %j + %k = add i64 %i, 1 + %n = icmp eq i64 %k, 0 + br i1 %n, label %return, label %bb + +return: + ret void +} + diff --git a/test/Transforms/IndVarSimplify/2007-06-06-DeleteDanglesPtr.ll b/test/Transforms/IndVarSimplify/2007-06-06-DeleteDanglesPtr.ll new file mode 100644 index 000000000000..363c98c493bf --- /dev/null +++ b/test/Transforms/IndVarSimplify/2007-06-06-DeleteDanglesPtr.ll @@ -0,0 +1,117 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; PR1487 + + %struct.AVClass = type { i8*, i8* (i8*)*, %struct.AVOption* } + %struct.AVCodec = type { i8*, i32, i32, i32, i32 (%struct.AVCodecContext*)*, i32 (%struct.AVCodecContext*, i8*, i32, i8*)*, i32 (%struct.AVCodecContext*)*, i32 (%struct.AVCodecContext*, i8*, i32*, i8*, i32)*, i32, %struct.AVCodec*, void (%struct.AVCodecContext*)*, %struct.AVCodecTag*, i32* } + %struct.AVCodecContext = type { %struct.AVClass*, i32, i32, i32, i32, i32, i8*, i32, %struct.AVCodecTag, i32, i32, i32, i32, i32, void (%struct.AVCodecContext*, %struct.AVFrame*, i32*, i32, i32, i32)*, i32, i32, i32, i32, i32, i32, i32, float, float, i32, i32, i32, i32, float, i32, i32, i32, %struct.AVCodec*, i8*, i32, i32, void (%struct.AVCodecContext*, i8*, i32, i32)*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, [32 x i8], i32, i32, i32, i32, i32, i32, i32, float, i32, i32 (%struct.AVCodecContext*, %struct.AVFrame*)*, void (%struct.AVCodecContext*, %struct.AVFrame*)*, i32, i32, i32, i32, i8*, i8*, float, float, i32, %struct.RcOverride*, i32, i8*, i32, i32, i32, float, float, float, float, i32, float, float, float, float, float, i32, i32, i32, i32*, i32, i32, i32, i32, %struct.AVCodecTag, %struct.AVFrame*, i32, i32, [4 x i64], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 (%struct.AVCodecContext*, i32*)*, i32, i32, i32, i32, i32, i32, i8*, i32, i32, i32, i32, i32, i32, i16*, i16*, i32, i32, i32, i32, %struct.AVPaletteControl*, i32, i32 (%struct.AVCodecContext*, %struct.AVFrame*)*, i32, i32, i32, i32, i32, i32, i32, i32 (%struct.AVCodecContext*, i32 (%struct.AVCodecContext*, i8*)*, i8**, i32*, i32)*, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, i32, i32, i32, i32, i32, i32, i32, i32, float, i32, i32, i32, i32, i32, i32, float, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64 } + %struct.AVCodecTag = type { i32, i32 } + %struct.AVFrame = type { [4 x i8*], [4 x i32], [4 x i8*], i32, i32, i64, i32, i32, i32, i32, i32, i8*, i32, i8*, [2 x [2 x i16]*], i32*, i8, i8*, [4 x i64], i32, i32, i32, i32, i32, %struct.AVPanScan*, i32, i32, i16*, [2 x i8*] } + %struct.AVOption = type { i8*, i8*, i32, i32, double, double, double, i32, i8* } + %struct.AVPaletteControl = type { i32, [256 x i32] } + %struct.AVPanScan = type { i32, i32, i32, [3 x [2 x i16]] } + %struct.RcOverride = type { i32, i32, i32, float } + +define i32 @smc_decode_frame(%struct.AVCodecContext* %avctx, i8* %data, i32* %data_size, i8* %buf, i32 %buf_size) { +entry: + br i1 false, label %cond_next, label %cond_true + +cond_true: ; preds = %entry + ret i32 -1 + +cond_next: ; preds = %entry + br i1 false, label %bb.outer5.split.split.split.us, label %cond_true194.split + +bb.outer5.split.split.split.us: ; preds = %cond_next + br i1 false, label %cond_next188.us503.us, label %bb.us481 + +bb275.us493.us: ; preds = %cond_next188.us503.us, %cond_next188.us503.us + ret i32 0 + +cond_next188.us503.us: ; preds = %bb.outer5.split.split.split.us + switch i32 0, label %bb1401 [ + i32 0, label %cond_next202.bb215_crit_edge.split + i32 16, label %bb215 + i32 32, label %bb275.us493.us + i32 48, label %bb275.us493.us + i32 64, label %cond_next202.bb417_crit_edge.split + i32 80, label %bb417 + i32 96, label %cond_next202.bb615_crit_edge.split + i32 112, label %bb615 + i32 128, label %cond_next202.bb716_crit_edge.split + i32 144, label %bb716 + i32 160, label %cond_next202.bb882_crit_edge.split + i32 176, label %bb882 + i32 192, label %cond_next202.bb1062_crit_edge.split + i32 208, label %bb1062 + i32 224, label %bb1326.us.outer.outer + ] + +bb.us481: ; preds = %bb.outer5.split.split.split.us + ret i32 0 + +cond_true194.split: ; preds = %cond_next + ret i32 %buf_size + +cond_next202.bb1062_crit_edge.split: ; preds = %cond_next188.us503.us + ret i32 0 + +cond_next202.bb882_crit_edge.split: ; preds = %cond_next188.us503.us + ret i32 0 + +cond_next202.bb716_crit_edge.split: ; preds = %cond_next188.us503.us + ret i32 0 + +cond_next202.bb615_crit_edge.split: ; preds = %cond_next188.us503.us + ret i32 0 + +cond_next202.bb417_crit_edge.split: ; preds = %cond_next188.us503.us + ret i32 0 + +cond_next202.bb215_crit_edge.split: ; preds = %cond_next188.us503.us + ret i32 0 + +bb215: ; preds = %cond_next188.us503.us + ret i32 0 + +bb417: ; preds = %cond_next188.us503.us + ret i32 0 + +bb615: ; preds = %cond_next188.us503.us + ret i32 0 + +bb716: ; preds = %cond_next188.us503.us + ret i32 0 + +bb882: ; preds = %cond_next188.us503.us + ret i32 0 + +bb1062: ; preds = %cond_next188.us503.us + ret i32 0 + +bb1326.us: ; preds = %bb1326.us.outer.outer, %bb1347.loopexit.us, %bb1326.us + %pixel_y.162036.us.ph = phi i32 [ %tmp1352.us, %bb1347.loopexit.us ], [ 0, %bb1326.us.outer.outer ], [ %pixel_y.162036.us.ph, %bb1326.us ] ; <i32> [#uses=2] + %stream_ptr.142038.us.ph = phi i32 [ %tmp1339.us, %bb1347.loopexit.us ], [ %stream_ptr.142038.us.ph.ph, %bb1326.us.outer.outer ], [ %stream_ptr.142038.us.ph, %bb1326.us ] ; <i32> [#uses=2] + %pixel_x.232031.us = phi i32 [ %tmp1341.us, %bb1326.us ], [ 0, %bb1326.us.outer.outer ], [ 0, %bb1347.loopexit.us ] ; <i32> [#uses=3] + %block_ptr.222030.us = add i32 0, %pixel_x.232031.us ; <i32> [#uses=1] + %stream_ptr.132032.us = add i32 %pixel_x.232031.us, %stream_ptr.142038.us.ph ; <i32> [#uses=1] + %tmp1341.us = add i32 %pixel_x.232031.us, 1 ; <i32> [#uses=2] + %tmp1344.us = icmp slt i32 %tmp1341.us, 4 ; <i1> [#uses=1] + br i1 %tmp1344.us, label %bb1326.us, label %bb1347.loopexit.us + +bb1347.loopexit.us: ; preds = %bb1326.us + %tmp1339.us = add i32 %stream_ptr.132032.us, 1 ; <i32> [#uses=2] + %tmp1337.us = add i32 %block_ptr.222030.us, 1 ; <i32> [#uses=0] + %tmp1352.us = add i32 %pixel_y.162036.us.ph, 1 ; <i32> [#uses=2] + %tmp1355.us = icmp slt i32 %tmp1352.us, 4 ; <i1> [#uses=1] + br i1 %tmp1355.us, label %bb1326.us, label %bb1358 + +bb1358: ; preds = %bb1347.loopexit.us + br label %bb1326.us.outer.outer + +bb1326.us.outer.outer: ; preds = %bb1358, %cond_next188.us503.us + %stream_ptr.142038.us.ph.ph = phi i32 [ %tmp1339.us, %bb1358 ], [ 0, %cond_next188.us503.us ] ; <i32> [#uses=1] + br label %bb1326.us + +bb1401: ; preds = %cond_next188.us503.us + ret i32 0 +} diff --git a/test/Transforms/IndVarSimplify/2007-11-23-BitcastCrash.ll b/test/Transforms/IndVarSimplify/2007-11-23-BitcastCrash.ll new file mode 100644 index 000000000000..555cadda6de3 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2007-11-23-BitcastCrash.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; PR1814 +target datalayout = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32" + +define void @FuncAt1938470480(i32, i32, i32, i32, i32, i32, i32, i32, i64, i64, i64, i64, i64, i64, i64, i64, i1, i1, i1, i1, i1, i1) { +EntryBlock: + br label %asmBlockAt738ab7f3 + +asmBlockAt738ab9b0: ; preds = %asmBlockAt738ab7f3 + %.lcssa6 = phi i64 [ %23, %asmBlockAt738ab7f3 ] ; <i64> [#uses=0] + ret void + +asmBlockAt738ab7f3: ; preds = %asmBlockAt738ab7f3, %EntryBlock + %ebp95 = phi i32 [ 128, %EntryBlock ], [ %24, %asmBlockAt738ab7f3 ] ; <i32> [#uses=2] + sub <4 x i16> zeroinitializer, zeroinitializer ; <<4 x i16>>:22 [#uses=1] + bitcast <4 x i16> %22 to i64 ; <i64>:23 [#uses=1] + add i32 %ebp95, -64 ; <i32>:24 [#uses=1] + icmp ult i32 %ebp95, 64 ; <i1>:25 [#uses=1] + br i1 %25, label %asmBlockAt738ab9b0, label %asmBlockAt738ab7f3 +} diff --git a/test/Transforms/IndVarSimplify/2008-06-15-SCEVExpanderBug.ll b/test/Transforms/IndVarSimplify/2008-06-15-SCEVExpanderBug.ll new file mode 100644 index 000000000000..aac8d9789464 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2008-06-15-SCEVExpanderBug.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; PR2434 + +define fastcc void @regcppop() nounwind { +entry: + %tmp61 = add i32 0, -5 ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %bb, %entry + %PL_savestack_ix.tmp.0 = phi i32 [ %tmp61, %entry ], [ %tmp127, %bb ] ; <i32> [#uses=2] + %indvar10 = phi i32 [ 0, %entry ], [ %indvar.next11, %bb ] ; <i32> [#uses=2] + %tmp13 = mul i32 %indvar10, -4 ; <i32> [#uses=0] + %tmp111 = add i32 %PL_savestack_ix.tmp.0, -3 ; <i32> [#uses=0] + %tmp127 = add i32 %PL_savestack_ix.tmp.0, -4 ; <i32> [#uses=1] + %indvar.next11 = add i32 %indvar10, 1 ; <i32> [#uses=1] + br label %bb +} diff --git a/test/Transforms/IndVarSimplify/2008-09-02-IVType.ll b/test/Transforms/IndVarSimplify/2008-09-02-IVType.ll new file mode 100644 index 000000000000..8111cbe3a489 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2008-09-02-IVType.ll @@ -0,0 +1,58 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep sext | count 1 +; ModuleID = '<stdin>' + + %struct.App1Marker = type <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }> + %struct.ComponentInstanceRecord = type <{ [1 x i32] }> + %struct.DCPredictors = type { [5 x i16] } + %struct.DecodeTable = type { i16, i16, i16, i16, i8**, i8** } + %struct.ICMDataProcRecord = type <{ i16 (i8**, i32, i32)*, i32 }> + %struct.JPEGBitStream = type { i8*, i32, i32, i32, i32, i32, %struct.App1Marker*, i8*, i32, i16, i16, i32 } + %struct.JPEGGlobals = type { [2048 x i8], %struct.JPEGBitStream, i8*, i32, i32, %struct.ComponentInstanceRecord*, %struct.ComponentInstanceRecord*, i32, %struct.OpaqueQTMLMutex*, %struct.Rect, i32, i32, %struct.SharedGlobals, %struct.DCPredictors, i8, i8, void (i8*, i16**, i32, %struct.YUVGeneralParams*)*, %struct.YUVGeneralParams, i16, i16, i32, [5 x i16*], [5 x %struct.DecodeTable*], [5 x %struct.DecodeTable*], [5 x i8], [5 x i8], [4 x [65 x i16]], [4 x %struct.DecodeTable], [4 x %struct.DecodeTable], [4 x i8*], [4 x i8*], i16, i16, i32, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, [18 x i8], [18 x i8], [18 x i8], [18 x i8], i32, i32, i8**, i8**, i8, i8, i8, i8, i16, i16, %struct.App1Marker*, i8, i8, i8, i8, i32**, i8*, i16*, i8*, i16*, i8, [3 x i8], i32, [3 x i32], [3 x i32], [3 x i32], [3 x i32], [3 x i32], [3 x i16*], [3 x i16*], [3 x i8**], [3 x %struct.DecodeTable*], [3 x %struct.DecodeTable*], [3 x i32], i32, [3 x i16*], i32, i32, i32, [3 x i32], i8, i8, i8, i8, %struct.ICMDataProcRecord*, i32, i32, i8**, i8**, i8**, i8**, i32, i32, i8*, i32, i32, i16*, i16*, i8*, i32, i32, i32, i32, i32, i32, i32, [16 x <2 x i64>], [1280 x i8], i8 } + %struct.OpaqueQTMLMutex = type opaque + %struct.Rect = type { i16, i16, i16, i16 } + %struct.SharedDGlobals = type { %struct.DecodeTable, %struct.DecodeTable, %struct.DecodeTable, %struct.DecodeTable } + %struct.SharedEGlobals = type { i8**, i8**, i8**, i8** } + %struct.SharedGlobals = type { %struct.SharedEGlobals*, %struct.SharedDGlobals* } + %struct.YUVGeneralParams = type { i16*, i8*, i8*, i8*, i8*, i8*, void (i8*, i16**, i32, %struct.YUVGeneralParams*)*, i16, i16, i16, [6 x i8], void (i8*, i16**, i32, %struct.YUVGeneralParams*)*, i16, i16 } +@llvm.used = appending global [1 x i8*] [ i8* bitcast (i16 (%struct.JPEGGlobals*)* @ExtractBufferedBlocksIgnored to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define i16 @ExtractBufferedBlocksIgnored(%struct.JPEGGlobals* %globp) signext nounwind { +entry: + %tmp4311 = getelementptr %struct.JPEGGlobals* %globp, i32 0, i32 70 ; <i32*> [#uses=1] + %tmp4412 = load i32* %tmp4311, align 16 ; <i32> [#uses=2] + %tmp4613 = icmp sgt i32 %tmp4412, 0 ; <i1> [#uses=1] + br i1 %tmp4613, label %bb, label %bb49 + +bb: ; preds = %bb28, %entry + %component.09 = phi i16 [ 0, %entry ], [ %tmp37, %bb28 ] ; <i16> [#uses=2] + %tmp12 = sext i16 %component.09 to i32 ; <i32> [#uses=2] + %tmp6 = getelementptr %struct.JPEGGlobals* %globp, i32 0, i32 77, i32 %tmp12 ; <i16**> [#uses=2] + %tmp7 = load i16** %tmp6, align 4 ; <i16*> [#uses=2] + %tmp235 = getelementptr %struct.JPEGGlobals* %globp, i32 0, i32 71, i32 %tmp12 ; <i32*> [#uses=1] + %tmp246 = load i32* %tmp235, align 4 ; <i32> [#uses=2] + %tmp267 = icmp sgt i32 %tmp246, 0 ; <i1> [#uses=1] + br i1 %tmp267, label %bb8, label %bb28 + +bb8: ; preds = %bb8, %bb + %indvar = phi i32 [ 0, %bb ], [ %indvar.next2, %bb8 ] ; <i32> [#uses=3] + %theDCTBufferIter.01.rec = shl i32 %indvar, 6 ; <i32> [#uses=1] + %tmp10.rec = add i32 %theDCTBufferIter.01.rec, 64 ; <i32> [#uses=1] + %tmp10 = getelementptr i16* %tmp7, i32 %tmp10.rec ; <i16*> [#uses=1] + %i.02 = trunc i32 %indvar to i16 ; <i16> [#uses=1] + %tmp13 = add i16 %i.02, 1 ; <i16> [#uses=1] + %phitmp = sext i16 %tmp13 to i32 ; <i32> [#uses=1] + %tmp26 = icmp slt i32 %phitmp, %tmp246 ; <i1> [#uses=1] + %indvar.next2 = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 %tmp26, label %bb8, label %bb28 + +bb28: ; preds = %bb8, %bb + %theDCTBufferIter.0.lcssa = phi i16* [ %tmp7, %bb ], [ %tmp10, %bb8 ] ; <i16*> [#uses=1] + store i16* %theDCTBufferIter.0.lcssa, i16** %tmp6, align 4 + %tmp37 = add i16 %component.09, 1 ; <i16> [#uses=2] + %phitmp15 = sext i16 %tmp37 to i32 ; <i32> [#uses=1] + %tmp46 = icmp slt i32 %phitmp15, 42 ; <i1> [#uses=1] + br i1 %tmp46, label %bb, label %bb49 + +bb49: ; preds = %bb28, %entry + ret i16 0 +} diff --git a/test/Transforms/IndVarSimplify/2008-10-03-CouldNotCompute.ll b/test/Transforms/IndVarSimplify/2008-10-03-CouldNotCompute.ll new file mode 100644 index 000000000000..c78188d4d223 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2008-10-03-CouldNotCompute.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | opt -indvars +; PR2857 + +@foo = external global i32 ; <i32*> [#uses=1] + +define void @test(i32 %n, i32 %arg) { +entry: + br i1 false, label %bb.nph, label %return + +bb.nph: ; preds = %entry + %0 = load i32* @foo, align 4 ; <i32> [#uses=1] + %1 = sext i32 %0 to i64 ; <i64> [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %.in = phi i32 [ %2, %bb ], [ %n, %bb.nph ] ; <i32> [#uses=1] + %val.02 = phi i64 [ %5, %bb ], [ 0, %bb.nph ] ; <i64> [#uses=2] + %result.01 = phi i64 [ %4, %bb ], [ 0, %bb.nph ] ; <i64> [#uses=1] + %2 = add i32 %.in, -1 ; <i32> [#uses=2] + %3 = mul i64 %1, %val.02 ; <i64> [#uses=1] + %4 = add i64 %3, %result.01 ; <i64> [#uses=2] + %5 = add i64 %val.02, 1 ; <i64> [#uses=1] + %6 = icmp sgt i32 %2, 0 ; <i1> [#uses=1] + br i1 %6, label %bb, label %bb3.bb4_crit_edge + +bb3.bb4_crit_edge: ; preds = %bb + %.lcssa = phi i64 [ %4, %bb ] ; <i64> [#uses=0] + ret void + +return: ; preds = %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/2008-11-03-Floating.ll b/test/Transforms/IndVarSimplify/2008-11-03-Floating.ll new file mode 100644 index 000000000000..6fc065f83f63 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2008-11-03-Floating.ll @@ -0,0 +1,65 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 4 +define void @bar() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; <double> [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; <i32> [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.000000e+00 ; <double> [#uses=2] + %2 = fcmp olt double %1, 1.000000e+04 ; <i1> [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +declare i32 @foo(double) + +define void @bar2() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ -10.000000e+00, %entry ], [ %1, %bb ] ; <double> [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; <i32> [#uses=0] + %1 = add double %x.0.reg2mem.0, 2.000000e+00 ; <double> [#uses=2] + %2 = fcmp olt double %1, -1.000000e+00 ; <i1> [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + + +define void @bar3() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; <double> [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; <i32> [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.000000e+00 ; <double> [#uses=2] + %2 = fcmp olt double %1, -1.000000e+00 ; <i1> [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +define void @bar4() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 40.000000e+00, %entry ], [ %1, %bb ] ; <double> [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; <i32> [#uses=0] + %1 = add double %x.0.reg2mem.0, -1.000000e+00 ; <double> [#uses=2] + %2 = fcmp olt double %1, 1.000000e+00 ; <i1> [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + + diff --git a/test/Transforms/IndVarSimplify/2008-11-17-Floating.ll b/test/Transforms/IndVarSimplify/2008-11-17-Floating.ll new file mode 100644 index 000000000000..faf1da3058c4 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2008-11-17-Floating.ll @@ -0,0 +1,35 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 2 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep sitofp | count 1 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep uitofp | count 1 + +define void @bar() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; <double> [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; <i32> [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.0e+0 ; <double> [#uses=2] + %2 = fcmp olt double %1, 2147483646.0e+0 ; <i1> [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +define void @bar1() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %x.0.reg2mem.0 = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] ; <double> [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; <i32> [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.0e+0 ; <double> [#uses=2] + %2 = fcmp olt double %1, 2147483647.0e+0 ; <i1> [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +declare i32 @foo(double) diff --git a/test/Transforms/IndVarSimplify/2008-11-25-APFloatAssert.ll b/test/Transforms/IndVarSimplify/2008-11-25-APFloatAssert.ll new file mode 100644 index 000000000000..9fd0eb9e65ae --- /dev/null +++ b/test/Transforms/IndVarSimplify/2008-11-25-APFloatAssert.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | opt -indvars + +define void @t() nounwind { +entry: + br label %bb23.i91 + +bb23.i91: ; preds = %bb23.i91, %entry + %result.0.i89 = phi ppc_fp128 [ 0xM00000000000000000000000000000000, %entry ], [ %0, %bb23.i91 ] ; <ppc_fp128> [#uses=2] + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; <ppc_fp128> [#uses=1] + br label %bb23.i91 +} diff --git a/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll b/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll new file mode 100644 index 000000000000..134c9c74d3a9 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll @@ -0,0 +1,114 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | not grep {sext} +; ModuleID = '<stdin>' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin9.6" +@a = external global i32* ; <i32**> [#uses=3] +@b = external global i32* ; <i32**> [#uses=3] +@c = external global i32* ; <i32**> [#uses=3] +@d = external global i32* ; <i32**> [#uses=3] +@e = external global i32* ; <i32**> [#uses=3] +@f = external global i32* ; <i32**> [#uses=3] + +define void @foo() nounwind { +bb1.thread: + br label %bb1 + +bb1: ; preds = %bb1, %bb1.thread + %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %84, %bb1 ] ; <i32> [#uses=19] + %0 = load i32** @a, align 8 ; <i32*> [#uses=1] + %1 = load i32** @b, align 8 ; <i32*> [#uses=1] + %2 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %3 = getelementptr i32* %1, i64 %2 ; <i32*> [#uses=1] + %4 = load i32* %3, align 1 ; <i32> [#uses=1] + %5 = load i32** @c, align 8 ; <i32*> [#uses=1] + %6 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %7 = getelementptr i32* %5, i64 %6 ; <i32*> [#uses=1] + %8 = load i32* %7, align 1 ; <i32> [#uses=1] + %9 = add i32 %8, %4 ; <i32> [#uses=1] + %10 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %11 = getelementptr i32* %0, i64 %10 ; <i32*> [#uses=1] + store i32 %9, i32* %11, align 1 + %12 = load i32** @a, align 8 ; <i32*> [#uses=1] + %13 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %14 = load i32** @b, align 8 ; <i32*> [#uses=1] + %15 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %16 = sext i32 %15 to i64 ; <i64> [#uses=1] + %17 = getelementptr i32* %14, i64 %16 ; <i32*> [#uses=1] + %18 = load i32* %17, align 1 ; <i32> [#uses=1] + %19 = load i32** @c, align 8 ; <i32*> [#uses=1] + %20 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %21 = sext i32 %20 to i64 ; <i64> [#uses=1] + %22 = getelementptr i32* %19, i64 %21 ; <i32*> [#uses=1] + %23 = load i32* %22, align 1 ; <i32> [#uses=1] + %24 = add i32 %23, %18 ; <i32> [#uses=1] + %25 = sext i32 %13 to i64 ; <i64> [#uses=1] + %26 = getelementptr i32* %12, i64 %25 ; <i32*> [#uses=1] + store i32 %24, i32* %26, align 1 + %27 = load i32** @a, align 8 ; <i32*> [#uses=1] + %28 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %29 = load i32** @b, align 8 ; <i32*> [#uses=1] + %30 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %31 = sext i32 %30 to i64 ; <i64> [#uses=1] + %32 = getelementptr i32* %29, i64 %31 ; <i32*> [#uses=1] + %33 = load i32* %32, align 1 ; <i32> [#uses=1] + %34 = load i32** @c, align 8 ; <i32*> [#uses=1] + %35 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %36 = sext i32 %35 to i64 ; <i64> [#uses=1] + %37 = getelementptr i32* %34, i64 %36 ; <i32*> [#uses=1] + %38 = load i32* %37, align 1 ; <i32> [#uses=1] + %39 = add i32 %38, %33 ; <i32> [#uses=1] + %40 = sext i32 %28 to i64 ; <i64> [#uses=1] + %41 = getelementptr i32* %27, i64 %40 ; <i32*> [#uses=1] + store i32 %39, i32* %41, align 1 + %42 = load i32** @d, align 8 ; <i32*> [#uses=1] + %43 = load i32** @e, align 8 ; <i32*> [#uses=1] + %44 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %45 = getelementptr i32* %43, i64 %44 ; <i32*> [#uses=1] + %46 = load i32* %45, align 1 ; <i32> [#uses=1] + %47 = load i32** @f, align 8 ; <i32*> [#uses=1] + %48 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %49 = getelementptr i32* %47, i64 %48 ; <i32*> [#uses=1] + %50 = load i32* %49, align 1 ; <i32> [#uses=1] + %51 = add i32 %50, %46 ; <i32> [#uses=1] + %52 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %53 = getelementptr i32* %42, i64 %52 ; <i32*> [#uses=1] + store i32 %51, i32* %53, align 1 + %54 = load i32** @d, align 8 ; <i32*> [#uses=1] + %55 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %56 = load i32** @e, align 8 ; <i32*> [#uses=1] + %57 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %58 = sext i32 %57 to i64 ; <i64> [#uses=1] + %59 = getelementptr i32* %56, i64 %58 ; <i32*> [#uses=1] + %60 = load i32* %59, align 1 ; <i32> [#uses=1] + %61 = load i32** @f, align 8 ; <i32*> [#uses=1] + %62 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %63 = sext i32 %62 to i64 ; <i64> [#uses=1] + %64 = getelementptr i32* %61, i64 %63 ; <i32*> [#uses=1] + %65 = load i32* %64, align 1 ; <i32> [#uses=1] + %66 = add i32 %65, %60 ; <i32> [#uses=1] + %67 = sext i32 %55 to i64 ; <i64> [#uses=1] + %68 = getelementptr i32* %54, i64 %67 ; <i32*> [#uses=1] + store i32 %66, i32* %68, align 1 + %69 = load i32** @d, align 8 ; <i32*> [#uses=1] + %70 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %71 = load i32** @e, align 8 ; <i32*> [#uses=1] + %72 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %73 = sext i32 %72 to i64 ; <i64> [#uses=1] + %74 = getelementptr i32* %71, i64 %73 ; <i32*> [#uses=1] + %75 = load i32* %74, align 1 ; <i32> [#uses=1] + %76 = load i32** @f, align 8 ; <i32*> [#uses=1] + %77 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %78 = sext i32 %77 to i64 ; <i64> [#uses=1] + %79 = getelementptr i32* %76, i64 %78 ; <i32*> [#uses=1] + %80 = load i32* %79, align 1 ; <i32> [#uses=1] + %81 = add i32 %80, %75 ; <i32> [#uses=1] + %82 = sext i32 %70 to i64 ; <i64> [#uses=1] + %83 = getelementptr i32* %69, i64 %82 ; <i32*> [#uses=1] + store i32 %81, i32* %83, align 1 + %84 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2] + %85 = icmp sgt i32 %84, 23646 ; <i1> [#uses=1] + br i1 %85, label %return, label %bb1 + +return: ; preds = %bb1 + ret void +} diff --git a/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll b/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll new file mode 100644 index 000000000000..4d26803b437d --- /dev/null +++ b/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll @@ -0,0 +1,160 @@ +; RUN: llvm-as < %s | opt -indvars -instcombine | llvm-dis | not grep {\[sz\]ext} +; ModuleID = '<stdin>' +;extern int *a, *b, *c, *d, *e, *f; /* 64 bit */ +;extern int K[256]; +;void foo () { +; int i; +; for (i=0; i<23647; i++) { +; a[(i&15)] = b[i&15]+c[i&15]; +; a[(i+1)&15] = b[(i+1)&15]+c[(i+1)&15]; +; a[(i+2)&15] = b[(i+2)&15]+c[(i+2)&15]; +; d[i&15] = e[i&15]+f[i&15] +K[i]; +; d[(i+1)&15] = e[(i+1)&15]+f[(i+1)&15]+K[i+1]; +; d[(i+2)&15] = e[(i+2)&15]+f[(i+2)&15]+K[i+2]; +; } +;} +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin9.6" +@a = external global i32* ; <i32**> [#uses=3] +@b = external global i32* ; <i32**> [#uses=3] +@c = external global i32* ; <i32**> [#uses=3] +@d = external global i32* ; <i32**> [#uses=3] +@e = external global i32* ; <i32**> [#uses=3] +@f = external global i32* ; <i32**> [#uses=3] +@K = external global [256 x i32] ; <[256 x i32]*> [#uses=3] + +define void @foo() nounwind { +bb1.thread: + br label %bb1 + +bb1: ; preds = %bb1, %bb1.thread + %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %116, %bb1 ] ; <i32> [#uses=22] + %0 = load i32** @a, align 8 ; <i32*> [#uses=1] + %1 = and i32 %i.0.reg2mem.0, 15 ; <i32> [#uses=1] + %2 = load i32** @b, align 8 ; <i32*> [#uses=1] + %3 = and i32 %i.0.reg2mem.0, 15 ; <i32> [#uses=1] + %4 = zext i32 %3 to i64 ; <i64> [#uses=1] + %5 = getelementptr i32* %2, i64 %4 ; <i32*> [#uses=1] + %6 = load i32* %5, align 1 ; <i32> [#uses=1] + %7 = load i32** @c, align 8 ; <i32*> [#uses=1] + %8 = and i32 %i.0.reg2mem.0, 15 ; <i32> [#uses=1] + %9 = zext i32 %8 to i64 ; <i64> [#uses=1] + %10 = getelementptr i32* %7, i64 %9 ; <i32*> [#uses=1] + %11 = load i32* %10, align 1 ; <i32> [#uses=1] + %12 = add i32 %11, %6 ; <i32> [#uses=1] + %13 = zext i32 %1 to i64 ; <i64> [#uses=1] + %14 = getelementptr i32* %0, i64 %13 ; <i32*> [#uses=1] + store i32 %12, i32* %14, align 1 + %15 = load i32** @a, align 8 ; <i32*> [#uses=1] + %16 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %17 = and i32 %16, 15 ; <i32> [#uses=1] + %18 = load i32** @b, align 8 ; <i32*> [#uses=1] + %19 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %20 = and i32 %19, 15 ; <i32> [#uses=1] + %21 = zext i32 %20 to i64 ; <i64> [#uses=1] + %22 = getelementptr i32* %18, i64 %21 ; <i32*> [#uses=1] + %23 = load i32* %22, align 1 ; <i32> [#uses=1] + %24 = load i32** @c, align 8 ; <i32*> [#uses=1] + %25 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %26 = and i32 %25, 15 ; <i32> [#uses=1] + %27 = zext i32 %26 to i64 ; <i64> [#uses=1] + %28 = getelementptr i32* %24, i64 %27 ; <i32*> [#uses=1] + %29 = load i32* %28, align 1 ; <i32> [#uses=1] + %30 = add i32 %29, %23 ; <i32> [#uses=1] + %31 = zext i32 %17 to i64 ; <i64> [#uses=1] + %32 = getelementptr i32* %15, i64 %31 ; <i32*> [#uses=1] + store i32 %30, i32* %32, align 1 + %33 = load i32** @a, align 8 ; <i32*> [#uses=1] + %34 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %35 = and i32 %34, 15 ; <i32> [#uses=1] + %36 = load i32** @b, align 8 ; <i32*> [#uses=1] + %37 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %38 = and i32 %37, 15 ; <i32> [#uses=1] + %39 = zext i32 %38 to i64 ; <i64> [#uses=1] + %40 = getelementptr i32* %36, i64 %39 ; <i32*> [#uses=1] + %41 = load i32* %40, align 1 ; <i32> [#uses=1] + %42 = load i32** @c, align 8 ; <i32*> [#uses=1] + %43 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %44 = and i32 %43, 15 ; <i32> [#uses=1] + %45 = zext i32 %44 to i64 ; <i64> [#uses=1] + %46 = getelementptr i32* %42, i64 %45 ; <i32*> [#uses=1] + %47 = load i32* %46, align 1 ; <i32> [#uses=1] + %48 = add i32 %47, %41 ; <i32> [#uses=1] + %49 = zext i32 %35 to i64 ; <i64> [#uses=1] + %50 = getelementptr i32* %33, i64 %49 ; <i32*> [#uses=1] + store i32 %48, i32* %50, align 1 + %51 = load i32** @d, align 8 ; <i32*> [#uses=1] + %52 = and i32 %i.0.reg2mem.0, 15 ; <i32> [#uses=1] + %53 = load i32** @e, align 8 ; <i32*> [#uses=1] + %54 = and i32 %i.0.reg2mem.0, 15 ; <i32> [#uses=1] + %55 = zext i32 %54 to i64 ; <i64> [#uses=1] + %56 = getelementptr i32* %53, i64 %55 ; <i32*> [#uses=1] + %57 = load i32* %56, align 1 ; <i32> [#uses=1] + %58 = load i32** @f, align 8 ; <i32*> [#uses=1] + %59 = and i32 %i.0.reg2mem.0, 15 ; <i32> [#uses=1] + %60 = zext i32 %59 to i64 ; <i64> [#uses=1] + %61 = getelementptr i32* %58, i64 %60 ; <i32*> [#uses=1] + %62 = load i32* %61, align 1 ; <i32> [#uses=1] + %63 = sext i32 %i.0.reg2mem.0 to i64 ; <i64> [#uses=1] + %64 = getelementptr [256 x i32]* @K, i64 0, i64 %63 ; <i32*> [#uses=1] + %65 = load i32* %64, align 4 ; <i32> [#uses=1] + %66 = add i32 %62, %57 ; <i32> [#uses=1] + %67 = add i32 %66, %65 ; <i32> [#uses=1] + %68 = zext i32 %52 to i64 ; <i64> [#uses=1] + %69 = getelementptr i32* %51, i64 %68 ; <i32*> [#uses=1] + store i32 %67, i32* %69, align 1 + %70 = load i32** @d, align 8 ; <i32*> [#uses=1] + %71 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %72 = and i32 %71, 15 ; <i32> [#uses=1] + %73 = load i32** @e, align 8 ; <i32*> [#uses=1] + %74 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %75 = and i32 %74, 15 ; <i32> [#uses=1] + %76 = zext i32 %75 to i64 ; <i64> [#uses=1] + %77 = getelementptr i32* %73, i64 %76 ; <i32*> [#uses=1] + %78 = load i32* %77, align 1 ; <i32> [#uses=1] + %79 = load i32** @f, align 8 ; <i32*> [#uses=1] + %80 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %81 = and i32 %80, 15 ; <i32> [#uses=1] + %82 = zext i32 %81 to i64 ; <i64> [#uses=1] + %83 = getelementptr i32* %79, i64 %82 ; <i32*> [#uses=1] + %84 = load i32* %83, align 1 ; <i32> [#uses=1] + %85 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=1] + %86 = sext i32 %85 to i64 ; <i64> [#uses=1] + %87 = getelementptr [256 x i32]* @K, i64 0, i64 %86 ; <i32*> [#uses=1] + %88 = load i32* %87, align 4 ; <i32> [#uses=1] + %89 = add i32 %84, %78 ; <i32> [#uses=1] + %90 = add i32 %89, %88 ; <i32> [#uses=1] + %91 = zext i32 %72 to i64 ; <i64> [#uses=1] + %92 = getelementptr i32* %70, i64 %91 ; <i32*> [#uses=1] + store i32 %90, i32* %92, align 1 + %93 = load i32** @d, align 8 ; <i32*> [#uses=1] + %94 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %95 = and i32 %94, 15 ; <i32> [#uses=1] + %96 = load i32** @e, align 8 ; <i32*> [#uses=1] + %97 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %98 = and i32 %97, 15 ; <i32> [#uses=1] + %99 = zext i32 %98 to i64 ; <i64> [#uses=1] + %100 = getelementptr i32* %96, i64 %99 ; <i32*> [#uses=1] + %101 = load i32* %100, align 1 ; <i32> [#uses=1] + %102 = load i32** @f, align 8 ; <i32*> [#uses=1] + %103 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %104 = and i32 %103, 15 ; <i32> [#uses=1] + %105 = zext i32 %104 to i64 ; <i64> [#uses=1] + %106 = getelementptr i32* %102, i64 %105 ; <i32*> [#uses=1] + %107 = load i32* %106, align 1 ; <i32> [#uses=1] + %108 = add i32 %i.0.reg2mem.0, 2 ; <i32> [#uses=1] + %109 = sext i32 %108 to i64 ; <i64> [#uses=1] + %110 = getelementptr [256 x i32]* @K, i64 0, i64 %109 ; <i32*> [#uses=1] + %111 = load i32* %110, align 4 ; <i32> [#uses=1] + %112 = add i32 %107, %101 ; <i32> [#uses=1] + %113 = add i32 %112, %111 ; <i32> [#uses=1] + %114 = zext i32 %95 to i64 ; <i64> [#uses=1] + %115 = getelementptr i32* %93, i64 %114 ; <i32*> [#uses=1] + store i32 %113, i32* %115, align 1 + %116 = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2] + %117 = icmp sgt i32 %116, 23646 ; <i1> [#uses=1] + br i1 %117, label %return, label %bb1 + +return: ; preds = %bb1 + ret void +} diff --git a/test/Transforms/IndVarSimplify/2009-04-22-IndvarCrash.ll b/test/Transforms/IndVarSimplify/2009-04-22-IndvarCrash.ll new file mode 100644 index 000000000000..f39458f17968 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2009-04-22-IndvarCrash.ll @@ -0,0 +1,35 @@ +; RUN: llvm-as < %s | opt -indvars +; rdar://6817574 + +define i32 @t1() nounwind ssp { +entry: + br label %bb32 + +bb32: ; preds = %bb32, %entry + %mbPartIdx.0.reg2mem.0 = phi i8 [ %2, %bb32 ], [ 0, %entry ] ; <i8> [#uses=3] + %0 = and i8 %mbPartIdx.0.reg2mem.0, 1 ; <i8> [#uses=0] + %1 = zext i8 %mbPartIdx.0.reg2mem.0 to i64 ; <i64> [#uses=0] + %2 = add i8 %mbPartIdx.0.reg2mem.0, 1 ; <i8> [#uses=2] + %3 = icmp ugt i8 %2, 3 ; <i1> [#uses=1] + br i1 %3, label %bb41, label %bb32 + +bb41: ; preds = %bb32 + ret i32 0 +} + +define i32 @t2() nounwind ssp { +entry: + br label %bb116 + +bb116: ; preds = %bb116, %entry + %mbPartIdx.1.reg2mem.0 = phi i8 [ %3, %bb116 ], [ 0, %entry ] ; <i8> [#uses=3] + %0 = and i8 %mbPartIdx.1.reg2mem.0, 1 ; <i8> [#uses=1] + %1 = zext i8 %mbPartIdx.1.reg2mem.0 to i64 ; <i64> [#uses=0] + %2 = zext i8 %0 to i32 ; <i32> [#uses=0] + %3 = add i8 %mbPartIdx.1.reg2mem.0, 1 ; <i8> [#uses=2] + %4 = icmp ugt i8 %3, 3 ; <i1> [#uses=1] + br i1 %4, label %bb131, label %bb116 + +bb131: ; preds = %bb116 + unreachable +} diff --git a/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll b/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll new file mode 100644 index 000000000000..700f294eb885 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | grep next +; PR4086 +declare void @foo() + +define void @test() { +entry: + br label %loop_body + +loop_body: + %i = phi float [ %nexti, %loop_body ], [ 0.0, %entry ] + tail call void @foo() + %nexti = add float %i, 1.0 + %less = fcmp olt float %nexti, 2.0 + br i1 %less, label %loop_body, label %done + +done: + ret void +} diff --git a/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll b/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll new file mode 100644 index 000000000000..ecbb23192e92 --- /dev/null +++ b/test/Transforms/IndVarSimplify/2009-05-24-useafterfree.ll @@ -0,0 +1,41 @@ +; RUN: llvm-as < %s | opt -indvars +; PR4258 +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:32:32" +target triple = "i386-linux-gnu" + +define void @0(i32*, i32*, i32, i32) nounwind { + br i1 false, label %bb.nph1.preheader, label %.outer._crit_edge + +bb.nph1.preheader: ; preds = %4 + %smax = select i1 false, i32 -1, i32 0 ; <i32> [#uses=1] + %tmp12 = sub i32 0, %smax ; <i32> [#uses=1] + br label %bb.nph1 + +bb.nph1: ; preds = %.outer, %bb.nph1.preheader + br i1 false, label %bb.nph3.preheader, label %.outer + +bb.nph3.preheader: ; preds = %bb.nph1 + br label %bb.nph3 + +bb.nph3: ; preds = %bb.nph3, %bb.nph3.preheader + %indvar7 = phi i32 [ %indvar.next8, %bb.nph3 ], [ 0, %bb.nph3.preheader ] ; <i32> [#uses=3] + %tmp9 = mul i32 %indvar7, -1 ; <i32> [#uses=1] + %tmp13 = add i32 %tmp9, %tmp12 ; <i32> [#uses=1] + %tmp14 = add i32 %tmp13, -2 ; <i32> [#uses=1] + %5 = icmp sgt i32 %tmp14, 0 ; <i1> [#uses=1] + %indvar.next8 = add i32 %indvar7, 1 ; <i32> [#uses=1] + br i1 %5, label %bb.nph3, label %.outer.loopexit + +.outer.loopexit: ; preds = %bb.nph3 + %indvar7.lcssa = phi i32 [ %indvar7, %bb.nph3 ] ; <i32> [#uses=0] + br label %.outer + +.outer: ; preds = %.outer.loopexit, %bb.nph1 + br i1 false, label %bb.nph1, label %.outer._crit_edge.loopexit + +.outer._crit_edge.loopexit: ; preds = %.outer + br label %.outer._crit_edge + +.outer._crit_edge: ; preds = %.outer._crit_edge.loopexit, %4 + ret void +} diff --git a/test/Transforms/IndVarSimplify/ada-loops.ll b/test/Transforms/IndVarSimplify/ada-loops.ll new file mode 100644 index 000000000000..56325b36cbbe --- /dev/null +++ b/test/Transforms/IndVarSimplify/ada-loops.ll @@ -0,0 +1,90 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: grep phi %t | count 4 +; RUN: grep {= phi i32} %t | count 4 +; RUN: not grep {sext i} %t +; RUN: not grep {zext i} %t +; RUN: not grep {trunc i} %t +; RUN: not grep {add i8} %t +; PR1301 + +; Do a bunch of analysis and prove that the loops can use an i32 trip +; count without casting. + +; ModuleID = 'ada.bc' +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" + +define void @kinds__sbytezero([256 x i32]* nocapture %a) nounwind { +bb.thread: + %tmp46 = getelementptr [256 x i32]* %a, i32 0, i32 0 ; <i32*> [#uses=1] + store i32 0, i32* %tmp46 + br label %bb + +bb: ; preds = %bb, %bb.thread + %i.0.reg2mem.0 = phi i8 [ -128, %bb.thread ], [ %tmp8, %bb ] ; <i8> [#uses=1] + %tmp8 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=3] + %tmp1 = sext i8 %tmp8 to i32 ; <i32> [#uses=1] + %tmp3 = add i32 %tmp1, 128 ; <i32> [#uses=1] + %tmp4 = getelementptr [256 x i32]* %a, i32 0, i32 %tmp3 ; <i32*> [#uses=1] + store i32 0, i32* %tmp4 + %0 = icmp eq i8 %tmp8, 127 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +return: ; preds = %bb + ret void +} + +define void @kinds__ubytezero([256 x i32]* nocapture %a) nounwind { +bb.thread: + %tmp35 = getelementptr [256 x i32]* %a, i32 0, i32 0 ; <i32*> [#uses=1] + store i32 0, i32* %tmp35 + br label %bb + +bb: ; preds = %bb, %bb.thread + %i.0.reg2mem.0 = phi i8 [ 0, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=1] + %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=3] + %tmp1 = zext i8 %tmp7 to i32 ; <i32> [#uses=1] + %tmp3 = getelementptr [256 x i32]* %a, i32 0, i32 %tmp1 ; <i32*> [#uses=1] + store i32 0, i32* %tmp3 + %0 = icmp eq i8 %tmp7, -1 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +return: ; preds = %bb + ret void +} + +define void @kinds__srangezero([21 x i32]* nocapture %a) nounwind { +bb.thread: + br label %bb + +bb: ; preds = %bb, %bb.thread + %i.0.reg2mem.0 = phi i8 [ -10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2] + %tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1] + %tmp4 = add i32 %tmp12, 10 ; <i32> [#uses=1] + %tmp5 = getelementptr [21 x i32]* %a, i32 0, i32 %tmp4 ; <i32*> [#uses=1] + store i32 0, i32* %tmp5 + %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2] + %0 = icmp sgt i8 %tmp7, 10 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +return: ; preds = %bb + ret void +} + +define void @kinds__urangezero([21 x i32]* nocapture %a) nounwind { +bb.thread: + br label %bb + +bb: ; preds = %bb, %bb.thread + %i.0.reg2mem.0 = phi i8 [ 10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2] + %tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1] + %tmp4 = add i32 %tmp12, -10 ; <i32> [#uses=1] + %tmp5 = getelementptr [21 x i32]* %a, i32 0, i32 %tmp4 ; <i32*> [#uses=1] + store i32 0, i32* %tmp5 + %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2] + %0 = icmp sgt i8 %tmp7, 30 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +return: ; preds = %bb + ret void +} diff --git a/test/Transforms/IndVarSimplify/addrec-gep.ll b/test/Transforms/IndVarSimplify/addrec-gep.ll new file mode 100644 index 000000000000..132d4f8a871c --- /dev/null +++ b/test/Transforms/IndVarSimplify/addrec-gep.ll @@ -0,0 +1,78 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: grep getelementptr %t | count 1 +; RUN: grep {mul .*, 37} %t | count 1 +; RUN: grep {add .*, 5203} %t | count 1 +; RUN: not grep cast %t + +; This test tests several things. The load and store should use the +; same address instead of having it computed twice, and SCEVExpander should +; be able to reconstruct the full getelementptr, despite it having a few +; obstacles set in its way. + +target datalayout = "e-p:64:64:64" + +define void @foo(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind { +entry: + %tmp = icmp sgt i64 %n, 0 ; <i1> [#uses=1] + br i1 %tmp, label %bb.nph3, label %return + +bb.nph: ; preds = %bb2.preheader + %tmp1 = mul i64 %tmp16, %i.02 ; <i64> [#uses=1] + %tmp2 = mul i64 %tmp19, %i.02 ; <i64> [#uses=1] + br label %bb1 + +bb1: ; preds = %bb2, %bb.nph + %j.01 = phi i64 [ %tmp9, %bb2 ], [ 0, %bb.nph ] ; <i64> [#uses=3] + %tmp3 = add i64 %j.01, %tmp1 ; <i64> [#uses=1] + %tmp4 = add i64 %j.01, %tmp2 ; <i64> [#uses=1] + %z0 = add i64 %tmp4, 5203 + %tmp5 = getelementptr double* %p, i64 %z0 ; <double*> [#uses=1] + %tmp6 = load double* %tmp5, align 8 ; <double> [#uses=1] + %tmp7 = fdiv double %tmp6, 2.100000e+00 ; <double> [#uses=1] + %z1 = add i64 %tmp4, 5203 + %tmp8 = getelementptr double* %p, i64 %z1 ; <double*> [#uses=1] + store double %tmp7, double* %tmp8, align 8 + %tmp9 = add i64 %j.01, 1 ; <i64> [#uses=2] + br label %bb2 + +bb2: ; preds = %bb1 + %tmp10 = icmp slt i64 %tmp9, %m ; <i1> [#uses=1] + br i1 %tmp10, label %bb1, label %bb2.bb3_crit_edge + +bb2.bb3_crit_edge: ; preds = %bb2 + br label %bb3 + +bb3: ; preds = %bb2.preheader, %bb2.bb3_crit_edge + %tmp11 = add i64 %i.02, 1 ; <i64> [#uses=2] + br label %bb4 + +bb4: ; preds = %bb3 + %tmp12 = icmp slt i64 %tmp11, %n ; <i1> [#uses=1] + br i1 %tmp12, label %bb2.preheader, label %bb4.return_crit_edge + +bb4.return_crit_edge: ; preds = %bb4 + br label %bb4.return_crit_edge.split + +bb4.return_crit_edge.split: ; preds = %bb.nph3, %bb4.return_crit_edge + br label %return + +bb.nph3: ; preds = %entry + %tmp13 = icmp sgt i64 %m, 0 ; <i1> [#uses=1] + %tmp14 = mul i64 %n, 37 ; <i64> [#uses=1] + %tmp15 = mul i64 %tmp14, %o ; <i64> [#uses=1] + %tmp16 = mul i64 %tmp15, %q ; <i64> [#uses=1] + %tmp17 = mul i64 %n, 37 ; <i64> [#uses=1] + %tmp18 = mul i64 %tmp17, %o ; <i64> [#uses=1] + %tmp19 = mul i64 %tmp18, %q ; <i64> [#uses=1] + br i1 %tmp13, label %bb.nph3.split, label %bb4.return_crit_edge.split + +bb.nph3.split: ; preds = %bb.nph3 + br label %bb2.preheader + +bb2.preheader: ; preds = %bb.nph3.split, %bb4 + %i.02 = phi i64 [ %tmp11, %bb4 ], [ 0, %bb.nph3.split ] ; <i64> [#uses=3] + br i1 true, label %bb.nph, label %bb3 + +return: ; preds = %bb4.return_crit_edge.split, %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/avoid-i0.ll b/test/Transforms/IndVarSimplify/avoid-i0.ll new file mode 100644 index 000000000000..3456bd3d6c9c --- /dev/null +++ b/test/Transforms/IndVarSimplify/avoid-i0.ll @@ -0,0 +1,126 @@ +; RUN: llvm-as < %s | opt -indvars +; PR4052 +; PR4054 + +; Don't treat an and with 0 as a mask (trunc+zext). + +define i32 @int80(i8 signext %p_71) nounwind { +entry: + br label %bb + +bb: ; preds = %bb6, %entry + %p_71_addr.0 = phi i8 [ %p_71, %entry ], [ %0, %bb6 ] ; <i8> [#uses=0] + br i1 false, label %bb4, label %bb1 + +bb1: ; preds = %bb + ret i32 0 + +bb4: ; preds = %bb4, %bb + br i1 false, label %bb6, label %bb4 + +bb6: ; preds = %bb4 + %0 = and i8 0, 0 ; <i8> [#uses=1] + br label %bb +} + +@x = common global i32 0 ; <i32*> [#uses=1] + +define signext i8 @safe_sub_func_int32_t_s_s(i32 %_si1, i8 signext %_si2) nounwind { +entry: + %_si1_addr = alloca i32 ; <i32*> [#uses=3] + %_si2_addr = alloca i8 ; <i8*> [#uses=3] + %retval = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %_si1, i32* %_si1_addr + store i8 %_si2, i8* %_si2_addr + %1 = load i8* %_si2_addr, align 1 ; <i8> [#uses=1] + %2 = sext i8 %1 to i32 ; <i32> [#uses=1] + %3 = load i32* %_si1_addr, align 4 ; <i32> [#uses=1] + %4 = xor i32 %2, %3 ; <i32> [#uses=1] + %5 = load i8* %_si2_addr, align 1 ; <i8> [#uses=1] + %6 = sext i8 %5 to i32 ; <i32> [#uses=1] + %7 = sub i32 7, %6 ; <i32> [#uses=1] + %8 = load i32* %_si1_addr, align 4 ; <i32> [#uses=1] + %9 = shl i32 %8, %7 ; <i32> [#uses=1] + %10 = and i32 %4, %9 ; <i32> [#uses=1] + %11 = icmp slt i32 %10, 0 ; <i1> [#uses=1] + %12 = zext i1 %11 to i32 ; <i32> [#uses=1] + store i32 %12, i32* %0, align 4 + %13 = load i32* %0, align 4 ; <i32> [#uses=1] + store i32 %13, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; <i32> [#uses=1] + %retval12 = trunc i32 %retval1 to i8 ; <i8> [#uses=1] + ret i8 %retval12 +} + +define i32 @safe_sub_func_uint64_t_u_u(i32 %_ui1, i32 %_ui2) nounwind { +entry: + %_ui1_addr = alloca i32 ; <i32*> [#uses=2] + %_ui2_addr = alloca i32 ; <i32*> [#uses=1] + %retval = alloca i32 ; <i32*> [#uses=2] + %0 = alloca i32 ; <i32*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %_ui1, i32* %_ui1_addr + store i32 %_ui2, i32* %_ui2_addr + %1 = load i32* %_ui1_addr, align 4 ; <i32> [#uses=1] + %2 = sub i32 %1, 1 ; <i32> [#uses=1] + store i32 %2, i32* %0, align 4 + %3 = load i32* %0, align 4 ; <i32> [#uses=1] + store i32 %3, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; <i32> [#uses=1] + ret i32 %retval1 +} + +define void @int87(i8 signext %p_48, i8 signext %p_49) nounwind { +entry: + %p_48_addr = alloca i8 ; <i8*> [#uses=1] + %p_49_addr = alloca i8 ; <i8*> [#uses=1] + %l_52 = alloca i32 ; <i32*> [#uses=7] + %vol.0 = alloca i32 ; <i32*> [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i8 %p_48, i8* %p_48_addr + store i8 %p_49, i8* %p_49_addr + br label %bb4 + +bb: ; preds = %bb4 + %0 = volatile load i32* @x, align 4 ; <i32> [#uses=1] + store i32 %0, i32* %vol.0, align 4 + store i32 0, i32* %l_52, align 4 + br label %bb2 + +bb1: ; preds = %bb2 + %1 = load i32* %l_52, align 4 ; <i32> [#uses=1] + %2 = call i32 @safe_sub_func_uint64_t_u_u(i32 %1, i32 1) nounwind ; <i32> [#uses=1] + store i32 %2, i32* %l_52, align 4 + br label %bb2 + +bb2: ; preds = %bb1, %bb + %3 = load i32* %l_52, align 4 ; <i32> [#uses=1] + %4 = icmp eq i32 %3, 0 ; <i1> [#uses=1] + br i1 %4, label %bb1, label %bb3 + +bb3: ; preds = %bb2 + %5 = load i32* %l_52, align 4 ; <i32> [#uses=1] + %6 = call signext i8 @safe_sub_func_int32_t_s_s(i32 %5, i8 signext 1) nounwind ; <i8> [#uses=1] + %7 = sext i8 %6 to i32 ; <i32> [#uses=1] + store i32 %7, i32* %l_52, align 4 + br label %bb4 + +bb4: ; preds = %bb3, %entry + %8 = load i32* %l_52, align 4 ; <i32> [#uses=1] + %9 = icmp ne i32 %8, 0 ; <i1> [#uses=1] + br i1 %9, label %bb, label %bb5 + +bb5: ; preds = %bb4 + br label %return + +return: ; preds = %bb5 + ret void +} diff --git a/test/Transforms/IndVarSimplify/casted-argument.ll b/test/Transforms/IndVarSimplify/casted-argument.ll new file mode 100644 index 000000000000..6d7aaa9161ad --- /dev/null +++ b/test/Transforms/IndVarSimplify/casted-argument.ll @@ -0,0 +1,50 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; PR4009 +; PR4038 + +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:32:32" +target triple = "i386-pc-linux-gnu" + +define void @safe_bcopy(i8* %to) nounwind { +entry: + %cmp11 = icmp ult i8* %to, null ; <i1> [#uses=1] + br i1 %cmp11, label %loop, label %return + +return: ; preds = %entry + ret void + +loop: ; preds = %loop, %if.else + %pn = phi i8* [ %ge, %loop ], [ null, %entry ] ; <i8*> [#uses=1] + %cp = ptrtoint i8* %to to i32 ; <i32> [#uses=1] + %su = sub i32 0, %cp ; <i32> [#uses=1] + %ge = getelementptr i8* %pn, i32 %su ; <i8*> [#uses=2] + tail call void @bcopy(i8* %ge) nounwind + br label %loop +} + +define void @safe_bcopy_4038(i8* %from, i8* %to, i32 %size) nounwind { +entry: + br i1 false, label %if.else, label %if.then12 + +if.then12: ; preds = %entry + ret void + +if.else: ; preds = %entry + %sub.ptr.rhs.cast40 = ptrtoint i8* %from to i32 ; <i32> [#uses=1] + br label %if.end54 + +if.end54: ; preds = %if.end54, %if.else + %sub.ptr4912.pn = phi i8* [ %sub.ptr4912, %if.end54 ], [ null, %if.else ] ; <i8*> [#uses=1] + %sub.ptr7 = phi i8* [ %sub.ptr, %if.end54 ], [ null, %if.else ] ; <i8*> [#uses=2] + %sub.ptr.rhs.cast46.pn = ptrtoint i8* %from to i32 ; <i32> [#uses=1] + %sub.ptr.lhs.cast45.pn = ptrtoint i8* %to to i32 ; <i32> [#uses=1] + %sub.ptr.sub47.pn = sub i32 %sub.ptr.rhs.cast46.pn, %sub.ptr.lhs.cast45.pn ; <i32> [#uses=1] + %sub.ptr4912 = getelementptr i8* %sub.ptr4912.pn, i32 %sub.ptr.sub47.pn ; <i8*> [#uses=2] + tail call void @bcopy_4038(i8* %sub.ptr4912, i8* %sub.ptr7, i32 0) nounwind + %sub.ptr = getelementptr i8* %sub.ptr7, i32 %sub.ptr.rhs.cast40 ; <i8*> [#uses=1] + br label %if.end54 +} + +declare void @bcopy(i8* nocapture) nounwind + +declare void @bcopy_4038(i8*, i32) nounwind diff --git a/test/Transforms/IndVarSimplify/complex-scev.ll b/test/Transforms/IndVarSimplify/complex-scev.ll new file mode 100644 index 000000000000..4bfc4e981af5 --- /dev/null +++ b/test/Transforms/IndVarSimplify/complex-scev.ll @@ -0,0 +1,29 @@ +; The i induction variable looks like a wrap-around, but it really is just +; a simple affine IV. Make sure that indvars eliminates it. + +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep phi | count 1 + +define void @foo() { +entry: + br label %bb6 + +bb6: ; preds = %cond_true, %entry + %j.0 = phi i32 [ 1, %entry ], [ %tmp5, %cond_true ] ; <i32> [#uses=3] + %i.0 = phi i32 [ 0, %entry ], [ %j.0, %cond_true ] ; <i32> [#uses=1] + %tmp7 = call i32 (...)* @foo2( ) ; <i32> [#uses=1] + %tmp = icmp ne i32 %tmp7, 0 ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %return + +cond_true: ; preds = %bb6 + %tmp2 = call i32 (...)* @bar( i32 %i.0, i32 %j.0 ) ; <i32> [#uses=0] + %tmp5 = add i32 %j.0, 1 ; <i32> [#uses=1] + br label %bb6 + +return: ; preds = %bb6 + ret void +} + +declare i32 @bar(...) + +declare i32 @foo2(...) + diff --git a/test/Transforms/IndVarSimplify/dg.exp b/test/Transforms/IndVarSimplify/dg.exp new file mode 100644 index 000000000000..f2005891a59a --- /dev/null +++ b/test/Transforms/IndVarSimplify/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/IndVarSimplify/divide-pointer.ll b/test/Transforms/IndVarSimplify/divide-pointer.ll new file mode 100644 index 000000000000..747d47eb8690 --- /dev/null +++ b/test/Transforms/IndVarSimplify/divide-pointer.ll @@ -0,0 +1,95 @@ +; RUN: llvm-as < %s | opt -indvars +; PR4271 + +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" + %struct.xyz = type <{ i64, i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i64, [8 x i8], i64, i64, i32, i32, [4 x i32], i32, i32, i32, i32, i32, i32, [76 x i32], i32, [2 x %struct.uvw] }> + %struct.uvw = type <{ i64, i64 }> + +define i32 @foo(%struct.xyz* %header, i8* %p2, i8* %p3, i8* nocapture %p4) nounwind { +entry: + br label %while.body.i + +while.body.i: ; preds = %while.body.i, %entry + br i1 undef, label %while.body.i, label %bcopy_internal.exit + +bcopy_internal.exit: ; preds = %while.body.i + %conv135 = ptrtoint %struct.xyz* %header to i32 ; <i32> [#uses=1] + %shr136 = lshr i32 %conv135, 12 ; <i32> [#uses=1] + br label %for.body + +for.body: ; preds = %for.body, %bcopy_internal.exit + %ppnum.052 = phi i32 [ %inc, %for.body ], [ %shr136, %bcopy_internal.exit ] ; <i32> [#uses=1] + %inc = add i32 %ppnum.052, 1 ; <i32> [#uses=2] + %cmp = icmp ugt i32 %inc, undef ; <i1> [#uses=1] + br i1 %cmp, label %if.then199, label %for.body + +if.then199: ; preds = %if.then199, %for.body + br label %if.then199 +} + +define i32 @same_thing_but_signed(%struct.xyz* %header, i8* %p2, i8* %p3, i8* nocapture %p4) nounwind { +entry: + br label %while.body.i + +while.body.i: ; preds = %while.body.i, %entry + br i1 undef, label %while.body.i, label %bcopy_internal.exit + +bcopy_internal.exit: ; preds = %while.body.i + %conv135 = ptrtoint %struct.xyz* %header to i32 ; <i32> [#uses=1] + %shr136 = ashr i32 %conv135, 12 ; <i32> [#uses=1] + br label %for.body + +for.body: ; preds = %for.body, %bcopy_internal.exit + %ppnum.052 = phi i32 [ %inc, %for.body ], [ %shr136, %bcopy_internal.exit ] ; <i32> [#uses=1] + %inc = add i32 %ppnum.052, 1 ; <i32> [#uses=2] + %cmp = icmp ugt i32 %inc, undef ; <i1> [#uses=1] + br i1 %cmp, label %if.then199, label %for.body + +if.then199: ; preds = %if.then199, %for.body + br label %if.then199 +} + +define i32 @same_thing_but_multiplied(%struct.xyz* %header, i8* %p2, i8* %p3, i8* nocapture %p4) nounwind { +entry: + br label %while.body.i + +while.body.i: ; preds = %while.body.i, %entry + br i1 undef, label %while.body.i, label %bcopy_internal.exit + +bcopy_internal.exit: ; preds = %while.body.i + %conv135 = ptrtoint %struct.xyz* %header to i32 ; <i32> [#uses=1] + %shr136 = shl i32 %conv135, 12 ; <i32> [#uses=1] + br label %for.body + +for.body: ; preds = %for.body, %bcopy_internal.exit + %ppnum.052 = phi i32 [ %inc, %for.body ], [ %shr136, %bcopy_internal.exit ] ; <i32> [#uses=1] + %inc = add i32 %ppnum.052, 1 ; <i32> [#uses=2] + %cmp = icmp ugt i32 %inc, undef ; <i1> [#uses=1] + br i1 %cmp, label %if.then199, label %for.body + +if.then199: ; preds = %if.then199, %for.body + br label %if.then199 +} + +define i32 @same_thing_but_xored(%struct.xyz* %header, i8* %p2, i8* %p3, i8* nocapture %p4) nounwind { +entry: + br label %while.body.i + +while.body.i: ; preds = %while.body.i, %entry + br i1 undef, label %while.body.i, label %bcopy_internal.exit + +bcopy_internal.exit: ; preds = %while.body.i + %conv135 = ptrtoint %struct.xyz* %header to i32 ; <i32> [#uses=1] + %shr136 = xor i32 %conv135, 12 ; <i32> [#uses=1] + br label %for.body + +for.body: ; preds = %for.body, %bcopy_internal.exit + %ppnum.052 = phi i32 [ %inc, %for.body ], [ %shr136, %bcopy_internal.exit ] ; <i32> [#uses=1] + %inc = add i32 %ppnum.052, 1 ; <i32> [#uses=2] + %cmp = icmp ugt i32 %inc, undef ; <i1> [#uses=1] + br i1 %cmp, label %if.then199, label %for.body + +if.then199: ; preds = %if.then199, %for.body + br label %if.then199 +} diff --git a/test/Transforms/IndVarSimplify/exit_value_tests.ll b/test/Transforms/IndVarSimplify/exit_value_tests.ll new file mode 100644 index 000000000000..b39f40f48664 --- /dev/null +++ b/test/Transforms/IndVarSimplify/exit_value_tests.ll @@ -0,0 +1,114 @@ +; Test that we can evaluate the exit values of various expression types. Since +; these loops all have predictable exit values we can replace the use outside +; of the loop with a closed-form computation, making the loop dead. +; +; RUN: llvm-as < %s | opt -indvars -loop-deletion -simplifycfg | \ +; RUN: llvm-dis | not grep br + +define i32 @polynomial_constant() { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %A1 = phi i32 [ 0, %0 ], [ %A2, %Loop ] ; <i32> [#uses=3] + %B1 = phi i32 [ 0, %0 ], [ %B2, %Loop ] ; <i32> [#uses=1] + %A2 = add i32 %A1, 1 ; <i32> [#uses=1] + %B2 = add i32 %B1, %A1 ; <i32> [#uses=2] + %C = icmp eq i32 %A1, 1000 ; <i1> [#uses=1] + br i1 %C, label %Out, label %Loop + +Out: ; preds = %Loop + ret i32 %B2 +} + +define i32 @NSquare(i32 %N) { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %X = phi i32 [ 0, %0 ], [ %X2, %Loop ] ; <i32> [#uses=4] + %X2 = add i32 %X, 1 ; <i32> [#uses=1] + %c = icmp eq i32 %X, %N ; <i1> [#uses=1] + br i1 %c, label %Out, label %Loop + +Out: ; preds = %Loop + %Y = mul i32 %X, %X ; <i32> [#uses=1] + ret i32 %Y +} + +define i32 @NSquareOver2(i32 %N) { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %X = phi i32 [ 0, %0 ], [ %X2, %Loop ] ; <i32> [#uses=3] + %Y = phi i32 [ 15, %0 ], [ %Y2, %Loop ] ; <i32> [#uses=1] + %Y2 = add i32 %Y, %X ; <i32> [#uses=2] + %X2 = add i32 %X, 1 ; <i32> [#uses=1] + %c = icmp eq i32 %X, %N ; <i1> [#uses=1] + br i1 %c, label %Out, label %Loop + +Out: ; preds = %Loop + ret i32 %Y2 +} + +define i32 @strength_reduced() { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %A1 = phi i32 [ 0, %0 ], [ %A2, %Loop ] ; <i32> [#uses=3] + %B1 = phi i32 [ 0, %0 ], [ %B2, %Loop ] ; <i32> [#uses=1] + %A2 = add i32 %A1, 1 ; <i32> [#uses=1] + %B2 = add i32 %B1, %A1 ; <i32> [#uses=2] + %C = icmp eq i32 %A1, 1000 ; <i1> [#uses=1] + br i1 %C, label %Out, label %Loop + +Out: ; preds = %Loop + ret i32 %B2 +} + +define i32 @chrec_equals() { +entry: + br label %no_exit + +no_exit: ; preds = %no_exit, %entry + %i0 = phi i32 [ 0, %entry ], [ %i1, %no_exit ] ; <i32> [#uses=3] + %ISq = mul i32 %i0, %i0 ; <i32> [#uses=1] + %i1 = add i32 %i0, 1 ; <i32> [#uses=2] + %tmp.1 = icmp ne i32 %ISq, 10000 ; <i1> [#uses=1] + br i1 %tmp.1, label %no_exit, label %loopexit + +loopexit: ; preds = %no_exit + ret i32 %i1 +} + +define i16 @cast_chrec_test() { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %A1 = phi i32 [ 0, %0 ], [ %A2, %Loop ] ; <i32> [#uses=2] + %B1 = trunc i32 %A1 to i16 ; <i16> [#uses=2] + %A2 = add i32 %A1, 1 ; <i32> [#uses=1] + %C = icmp eq i16 %B1, 1000 ; <i1> [#uses=1] + br i1 %C, label %Out, label %Loop + +Out: ; preds = %Loop + ret i16 %B1 +} + +define i32 @linear_div_fold() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 4, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 8 ; <i32> [#uses=1] + %RV = udiv i32 %i, 2 ; <i32> [#uses=1] + %c = icmp ne i32 %i, 68 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %RV +} diff --git a/test/Transforms/IndVarSimplify/gep-with-mul-base.ll b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll new file mode 100644 index 000000000000..e63c88c65e68 --- /dev/null +++ b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll @@ -0,0 +1,58 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: grep add %t | count 8 +; RUN: grep mul %t | count 7 + +define void @foo(i64 %n, i64 %m, i64 %o, double* nocapture %p) nounwind { +entry: + %tmp = icmp sgt i64 %n, 0 ; <i1> [#uses=1] + br i1 %tmp, label %bb.nph, label %return + +bb.nph: ; preds = %entry + %tmp1 = mul i64 %n, 37 ; <i64> [#uses=1] + %tmp2 = mul i64 %tmp1, %m ; <i64> [#uses=1] + %tmp3 = mul i64 %tmp2, %o ; <i64> [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %i.01 = phi i64 [ %tmp3, %bb.nph ], [ %tmp13, %bb ] ; <i64> [#uses=3] + %tmp9 = getelementptr double* %p, i64 %i.01 ; <double*> [#uses=1] + %tmp10 = load double* %tmp9, align 8 ; <double> [#uses=1] + %tmp11 = fdiv double %tmp10, 2.100000e+00 ; <double> [#uses=1] + store double %tmp11, double* %tmp9, align 8 + %tmp13 = add i64 %i.01, 1 ; <i64> [#uses=2] + %tmp14 = icmp slt i64 %tmp13, %n ; <i1> [#uses=1] + br i1 %tmp14, label %bb, label %return.loopexit + +return.loopexit: ; preds = %bb + br label %return + +return: ; preds = %return.loopexit, %entry + ret void +} +define void @bar(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind { +entry: + %tmp = icmp sgt i64 %n, 0 ; <i1> [#uses=1] + br i1 %tmp, label %bb.nph, label %return + +bb.nph: ; preds = %entry + %tmp1 = mul i64 %n, %q ; <i64> [#uses=1] + %tmp2 = mul i64 %tmp1, %m ; <i64> [#uses=1] + %tmp3 = mul i64 %tmp2, %o ; <i64> [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %i.01 = phi i64 [ %tmp3, %bb.nph ], [ %tmp13, %bb ] ; <i64> [#uses=3] + %tmp9 = getelementptr double* %p, i64 %i.01 ; <double*> [#uses=1] + %tmp10 = load double* %tmp9, align 8 ; <double> [#uses=1] + %tmp11 = fdiv double %tmp10, 2.100000e+00 ; <double> [#uses=1] + store double %tmp11, double* %tmp9, align 8 + %tmp13 = add i64 %i.01, 1 ; <i64> [#uses=2] + %tmp14 = icmp slt i64 %tmp13, %n ; <i1> [#uses=1] + br i1 %tmp14, label %bb, label %return.loopexit + +return.loopexit: ; preds = %bb + br label %return + +return: ; preds = %return.loopexit, %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/interesting-invoke-use.ll b/test/Transforms/IndVarSimplify/interesting-invoke-use.ll new file mode 100644 index 000000000000..b90d1e0ecf35 --- /dev/null +++ b/test/Transforms/IndVarSimplify/interesting-invoke-use.ll @@ -0,0 +1,57 @@ +; RUN: llvm-as < %s | opt -indvars + +; An invoke has a result value which is used in an "Interesting" +; expression inside the loop. IndVars should be able to rewrite +; the expression in the correct place. + +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:32:32" +target triple = "i386-pc-linux-gnu" + %struct.string___XUB = type { i32, i32 } + %struct.string___XUP = type { [0 x i8]*, %struct.string___XUB* } +@.str7 = external constant [24 x i8] ; <[24 x i8]*> [#uses=1] +@C.17.316 = external constant %struct.string___XUB ; <%struct.string___XUB*> [#uses=1] + +define void @_ada_c35503g() { +entry: + br label %bb + +bb: ; preds = %bb, %entry + br i1 false, label %bb65.loopexit, label %bb + +bb65.loopexit: ; preds = %bb + br label %bb123 + +bb123: ; preds = %bb178, %bb65.loopexit + %i.0 = phi i32 [ %3, %bb178 ], [ 0, %bb65.loopexit ] ; <i32> [#uses=3] + %0 = invoke i32 @report__ident_int(i32 1) + to label %invcont127 unwind label %lpad266 ; <i32> [#uses=1] + +invcont127: ; preds = %bb123 + %1 = sub i32 %i.0, %0 ; <i32> [#uses=1] + %2 = icmp eq i32 0, %1 ; <i1> [#uses=1] + br i1 %2, label %bb178, label %bb128 + +bb128: ; preds = %invcont127 + invoke void @system__img_int__image_integer(%struct.string___XUP* noalias sret null, i32 %i.0) + to label %invcont129 unwind label %lpad266 + +invcont129: ; preds = %bb128 + invoke void @system__string_ops__str_concat(%struct.string___XUP* noalias sret null, [0 x i8]* bitcast ([24 x i8]* @.str7 to [0 x i8]*), %struct.string___XUB* @C.17.316, [0 x i8]* null, %struct.string___XUB* null) + to label %invcont138 unwind label %lpad266 + +invcont138: ; preds = %invcont129 + unreachable + +bb178: ; preds = %invcont127 + %3 = add i32 %i.0, 1 ; <i32> [#uses=1] + br label %bb123 + +lpad266: ; preds = %invcont129, %bb128, %bb123 + unreachable +} + +declare void @system__img_int__image_integer(%struct.string___XUP* noalias sret, i32) + +declare void @system__string_ops__str_concat(%struct.string___XUP* noalias sret, [0 x i8]*, %struct.string___XUB*, [0 x i8]*, %struct.string___XUB*) + +declare i32 @report__ident_int(i32) diff --git a/test/Transforms/IndVarSimplify/iterationCount_zext_or_trunc.ll b/test/Transforms/IndVarSimplify/iterationCount_zext_or_trunc.ll new file mode 100644 index 000000000000..747c781e993f --- /dev/null +++ b/test/Transforms/IndVarSimplify/iterationCount_zext_or_trunc.ll @@ -0,0 +1,25 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +; ModuleID = 'testcase.bc' +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" + +define i32 @testcase(i5 zeroext %k) { +entry: + br label %bb2 + +bb: ; preds = %bb2 + %tmp1 = add i32 %tmp2, %result ; <i32> [#uses=1] + %indvar_next1 = add i5 %k_0, 1 ; <i5> [#uses=1] + br label %bb2 + +bb2: ; preds = %bb, %entry + %k_0 = phi i5 [ 0, %entry ], [ %indvar_next1, %bb ] ; <i5> [#uses=2] + %result = phi i32 [ 0, %entry ], [ %tmp1, %bb ] ; <i32> [#uses=2] + %tmp2 = zext i5 %k_0 to i32 ; <i32> [#uses=1] + %exitcond = icmp eq i32 %tmp2, 16 ; <i1> [#uses=1] + br i1 %exitcond, label %bb3, label %bb + +bb3: ; preds = %bb2 + ret i32 %result +} diff --git a/test/Transforms/IndVarSimplify/iv-zext.ll b/test/Transforms/IndVarSimplify/iv-zext.ll new file mode 100644 index 000000000000..76d48de0d3c5 --- /dev/null +++ b/test/Transforms/IndVarSimplify/iv-zext.ll @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: not grep and %t +; RUN: not grep zext %t + +target datalayout = "-p:64:64:64" + +define void @foo(double* %d, i64 %n) nounwind { +entry: + br label %loop + +loop: + %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ] + %indvar.i8 = and i64 %indvar, 255 + %t0 = getelementptr double* %d, i64 %indvar.i8 + %t1 = load double* %t0 + %t2 = mul double %t1, 0.1 + store double %t2, double* %t0 + %indvar.i24 = and i64 %indvar, 16777215 + %t3 = getelementptr double* %d, i64 %indvar.i24 + %t4 = load double* %t3 + %t5 = mul double %t4, 2.3 + store double %t5, double* %t3 + %t6 = getelementptr double* %d, i64 %indvar + %t7 = load double* %t6 + %t8 = mul double %t7, 4.5 + store double %t8, double* %t6 + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp eq i64 %indvar.next, 10 + br i1 %exitcond, label %return, label %loop + +return: + ret void +} diff --git a/test/Transforms/IndVarSimplify/lftr-other-uses.ll b/test/Transforms/IndVarSimplify/lftr-other-uses.ll new file mode 100644 index 000000000000..c8f1e9598340 --- /dev/null +++ b/test/Transforms/IndVarSimplify/lftr-other-uses.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output + +; Don't RAUW the loop's original comparison instruction if it has +; other uses which aren't dominated by the new comparison instruction. + + %struct.DecRefPicMarking_s = type { i32, i32, i32, i32, i32, %struct.DecRefPicMarking_s* } + %struct.datapartition = type { %typedef.Bitstream*, %typedef.DecodingEnvironment, i32 (%struct.syntaxelement*, %struct.img_par*, %struct.inp_par*, %struct.datapartition*)* } + %struct.img_par = type { i32, i32, i32, i32, i32*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [16 x [16 x i16]], [6 x [32 x i32]], [16 x [16 x i32]], [4 x [12 x [4 x [4 x i32]]]], [16 x i32], i32**, i32*, i32***, i32**, i32, i32, i32, i32, %typedef.Slice*, %struct.macroblock*, i32, i32, i32, i32, i32, i32, i32**, %struct.DecRefPicMarking_s*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [3 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32***, i32***, i32****, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.timeb, %struct.timeb, i32, i32, i32, i32, i32, i32, i32, i32 } + %struct.inp_par = type { [100 x i8], [100 x i8], [100 x i8], i32, i32, i32, i32, i32, i32, i32 } + %struct.macroblock = type { i32, i32, i32, %struct.macroblock*, %struct.macroblock*, i32, [2 x [4 x [4 x [2 x i32]]]], i32, i64, i64, i32, i32, [4 x i32], [4 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } + %struct.syntaxelement = type { i32, i32, i32, i32, i32, i32, i32, i32, void (i32, i32, i32*, i32*)*, void (%struct.syntaxelement*, %struct.inp_par*, %struct.img_par*, %typedef.DecodingEnvironment*)* } + %struct.timeb = type { i32, i16, i16, i16 } + %typedef.BiContextType = type { i16, i8 } + %typedef.Bitstream = type { i32, i32, i32, i32, i8*, i32 } + %typedef.DecodingEnvironment = type { i32, i32, i32, i32, i32, i8*, i32* } + %typedef.MotionInfoContexts = type { [4 x [11 x %typedef.BiContextType]], [2 x [9 x %typedef.BiContextType]], [2 x [10 x %typedef.BiContextType]], [2 x [6 x %typedef.BiContextType]], [4 x %typedef.BiContextType], [4 x %typedef.BiContextType], [3 x %typedef.BiContextType] } + %typedef.Slice = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.datapartition*, %typedef.MotionInfoContexts*, %typedef.TextureInfoContexts*, i32, i32*, i32*, i32*, i32, i32*, i32*, i32*, i32 (%struct.img_par*, %struct.inp_par*)*, i32, i32, i32, i32 } + %typedef.TextureInfoContexts = type { [2 x %typedef.BiContextType], [4 x %typedef.BiContextType], [3 x [4 x %typedef.BiContextType]], [10 x [4 x %typedef.BiContextType]], [10 x [15 x %typedef.BiContextType]], [10 x [15 x %typedef.BiContextType]], [10 x [5 x %typedef.BiContextType]], [10 x [5 x %typedef.BiContextType]], [10 x [15 x %typedef.BiContextType]], [10 x [15 x %typedef.BiContextType]] } + +define void @readCBP_CABAC(%struct.syntaxelement* %se, %struct.inp_par* %inp, %struct.img_par* %img.1, %typedef.DecodingEnvironment* %dep_dp) { +entry: + br label %loopentry.0 + +loopentry.0: ; preds = %loopentry.1, %entry + %mb_y.0 = phi i32 [ 0, %entry ], [ %tmp.152, %loopentry.1 ] ; <i32> [#uses=2] + %tmp.14 = icmp sle i32 %mb_y.0, 3 ; <i1> [#uses=2] + %tmp.15 = zext i1 %tmp.14 to i32 ; <i32> [#uses=0] + br i1 %tmp.14, label %loopentry.1, label %loopexit.0 + +loopentry.1: ; preds = %loopentry.0 + %tmp.152 = add i32 %mb_y.0, 2 ; <i32> [#uses=1] + br label %loopentry.0 + +loopexit.0: ; preds = %loopentry.0 + unreachable +} diff --git a/test/Transforms/IndVarSimplify/lftr_simple.ll b/test/Transforms/IndVarSimplify/lftr_simple.ll new file mode 100644 index 000000000000..3f7c289a4885 --- /dev/null +++ b/test/Transforms/IndVarSimplify/lftr_simple.ll @@ -0,0 +1,22 @@ +; LFTR should eliminate the need for the computation of i*i completely. It +; is only used to compute the exit value. +; RUN: llvm-as < %s | opt -indvars -dce | llvm-dis | not grep mul + +@A = external global i32 ; <i32*> [#uses=1] + +define i32 @quadratic_setlt() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 7, %entry ], [ %i.next, %loop ] ; <i32> [#uses=5] + %i.next = add i32 %i, 1 ; <i32> [#uses=1] + store i32 %i, i32* @A + %i2 = mul i32 %i, %i ; <i32> [#uses=1] + %c = icmp slt i32 %i2, 1000 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + diff --git a/test/Transforms/IndVarSimplify/loop_evaluate_1.ll b/test/Transforms/IndVarSimplify/loop_evaluate_1.ll new file mode 100644 index 000000000000..dfb42e4feae3 --- /dev/null +++ b/test/Transforms/IndVarSimplify/loop_evaluate_1.ll @@ -0,0 +1,21 @@ +; RUN: llvm-as < %s | opt -indvars -loop-deletion -simplifycfg | llvm-dis | not grep br +; +; Testcase distilled from 256.bzip2 + +define i32 @main() { +entry: + br label %loopentry + +loopentry: ; preds = %loopentry, %entry + %indvar1 = phi i32 [ 0, %entry ], [ %indvar.next2, %loopentry ] ; <i32> [#uses=1] + %h.0 = phi i32 [ %tmp.2, %loopentry ], [ 4, %entry ] ; <i32> [#uses=1] + %tmp.1 = mul i32 %h.0, 3 ; <i32> [#uses=1] + %tmp.2 = add i32 %tmp.1, 1 ; <i32> [#uses=2] + %indvar.next2 = add i32 %indvar1, 1 ; <i32> [#uses=2] + %exitcond3 = icmp ne i32 %indvar.next2, 4 ; <i1> [#uses=1] + br i1 %exitcond3, label %loopentry, label %loopexit + +loopexit: ; preds = %loopentry + ret i32 %tmp.2 +} + diff --git a/test/Transforms/IndVarSimplify/loop_evaluate_2.ll b/test/Transforms/IndVarSimplify/loop_evaluate_2.ll new file mode 100644 index 000000000000..efcf20a93442 --- /dev/null +++ b/test/Transforms/IndVarSimplify/loop_evaluate_2.ll @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | opt -indvars -loop-deletion -simplifycfg | opt \ +; RUN: -analyze -loops | not grep "^Loop Containing" +; PR1179 + +define i32 @ltst(i32 %x) { +entry: + icmp sgt i32 %x, 0 ; <i1>:0 [#uses=1] + br i1 %0, label %bb.preheader, label %bb8 + +bb.preheader: ; preds = %entry + br label %bb + +bb: ; preds = %bb, %bb.preheader + %i.01.0 = phi i32 [ %tmp4, %bb ], [ 0, %bb.preheader ] ; <i32> [#uses=1] + %j.03.0 = phi i32 [ %tmp2, %bb ], [ 0, %bb.preheader ] ; <i32> [#uses=1] + %tmp4 = add i32 %i.01.0, 1 ; <i32> [#uses=2] + %tmp2 = add i32 %j.03.0, 1 ; <i32> [#uses=2] + icmp slt i32 %tmp4, %x ; <i1>:1 [#uses=1] + br i1 %1, label %bb, label %bb8.loopexit + +bb8.loopexit: ; preds = %bb + br label %bb8 + +bb8: ; preds = %bb8.loopexit, %entry + %j.03.1 = phi i32 [ 0, %entry ], [ %tmp2, %bb8.loopexit ] ; <i32> [#uses=1] + ret i32 %j.03.1 +} + diff --git a/test/Transforms/IndVarSimplify/loop_evaluate_3.ll b/test/Transforms/IndVarSimplify/loop_evaluate_3.ll new file mode 100644 index 000000000000..2a2f69dd4866 --- /dev/null +++ b/test/Transforms/IndVarSimplify/loop_evaluate_3.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep {ret i32 600000} +; PR1179 + +define i32 @foo() { +entry: + br label %bb5 + +bb5: ; preds = %bb5, %entry + %i.01.0 = phi i32 [ 0, %entry ], [ %tmp2, %bb5 ] ; <i32> [#uses=1] + %x.03.0 = phi i32 [ 0, %entry ], [ %tmp4, %bb5 ] ; <i32> [#uses=1] + %tmp2 = add i32 %i.01.0, 3 ; <i32> [#uses=2] + %tmp4 = add i32 %x.03.0, 1 ; <i32> [#uses=2] + icmp slt i32 %tmp4, 200000 ; <i1>:0 [#uses=1] + br i1 %0, label %bb5, label %bb7 + +bb7: ; preds = %bb5 + ret i32 %tmp2 +} + diff --git a/test/Transforms/IndVarSimplify/loop_evaluate_4.ll b/test/Transforms/IndVarSimplify/loop_evaluate_4.ll new file mode 100644 index 000000000000..6c6a362f48e6 --- /dev/null +++ b/test/Transforms/IndVarSimplify/loop_evaluate_4.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep {ret i32 9900} +; PR1179 + +define i32 @test4() { +entry: + br label %bb7 + +bb7: ; preds = %bb7, %entry + %v.01.0 = phi i32 [ 0, %entry ], [ %tmp4, %bb7 ] ; <i32> [#uses=1] + %i.03.0 = phi i32 [ 0, %entry ], [ %tmp6, %bb7 ] ; <i32> [#uses=2] + %tmp2 = shl i32 %i.03.0, 1 ; <i32> [#uses=1] + %tmp4 = add i32 %tmp2, %v.01.0 ; <i32> [#uses=2] + %tmp6 = add i32 %i.03.0, 1 ; <i32> [#uses=2] + icmp slt i32 %tmp6, 100 ; <i1>:0 [#uses=1] + br i1 %0, label %bb7, label %bb9 + +bb9: ; preds = %bb7 + ret i32 %tmp4 +} + diff --git a/test/Transforms/IndVarSimplify/loop_evaluate_5.ll b/test/Transforms/IndVarSimplify/loop_evaluate_5.ll new file mode 100644 index 000000000000..c6ce4a2122da --- /dev/null +++ b/test/Transforms/IndVarSimplify/loop_evaluate_5.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep {120, %bb2.bb3_crit_edge} +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" + +; Indvars should be able to compute an exit value for %tmp1. + +define i32 @testcase(i5 zeroext %k) nounwind readnone { +entry: + br i1 false, label %bb3, label %bb.nph + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb2, %bb.nph + %result2 = phi i32 [ %tmp1, %bb2 ], [ 0, %bb.nph ] ; <i32> [#uses=1] + %k_01 = phi i5 [ %indvar_next1, %bb2 ], [ 0, %bb.nph ] ; <i5> [#uses=2] + %tmp2 = zext i5 %k_01 to i32 ; <i32> [#uses=1] + %tmp1 = add i32 %tmp2, %result2 ; <i32> [#uses=2] + %indvar_next1 = add i5 %k_01, 1 ; <i5> [#uses=2] + br label %bb2 + +bb2: ; preds = %bb + %phitmp = icmp eq i5 %indvar_next1, -16 ; <i1> [#uses=1] + br i1 %phitmp, label %bb2.bb3_crit_edge, label %bb + +bb2.bb3_crit_edge: ; preds = %bb2 + br label %bb3 + +bb3: ; preds = %bb2.bb3_crit_edge, %entry + %result.lcssa = phi i32 [ %tmp1, %bb2.bb3_crit_edge ], [ 0, %entry ] ; <i32> [#uses=1] + ret i32 %result.lcssa +} diff --git a/test/Transforms/IndVarSimplify/loop_evaluate_6.ll b/test/Transforms/IndVarSimplify/loop_evaluate_6.ll new file mode 100644 index 000000000000..35fbf52b7ef0 --- /dev/null +++ b/test/Transforms/IndVarSimplify/loop_evaluate_6.ll @@ -0,0 +1,29 @@ +; RUN: llvm-as < %s | opt -indvars -loop-deletion | llvm-dis | grep phi | count 1 + +; Indvars should be able to evaluate this loop, allowing loop deletion +; to delete it. + +define i32 @test(i32 %x_offs) nounwind readnone { +entry: + %0 = icmp sgt i32 %x_offs, 4 ; <i1> [#uses=1] + br i1 %0, label %bb.nph, label %bb2 + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb1, %bb.nph + %x_offs_addr.01 = phi i32 [ %1, %bb1 ], [ %x_offs, %bb.nph ] ; <i32> [#uses=1] + %1 = add i32 %x_offs_addr.01, -4 ; <i32> [#uses=3] + br label %bb1 + +bb1: ; preds = %bb + %2 = icmp sgt i32 %1, 4 ; <i1> [#uses=1] + br i1 %2, label %bb, label %bb1.bb2_crit_edge + +bb1.bb2_crit_edge: ; preds = %bb1 + br label %bb2 + +bb2: ; preds = %bb1.bb2_crit_edge, %entry + %x_offs_addr.0.lcssa = phi i32 [ %1, %bb1.bb2_crit_edge ], [ %x_offs, %entry ] ; <i32> [#uses=1] + ret i32 %x_offs_addr.0.lcssa +} diff --git a/test/Transforms/IndVarSimplify/pointer-indvars.ll b/test/Transforms/IndVarSimplify/pointer-indvars.ll new file mode 100644 index 000000000000..c9da1579e983 --- /dev/null +++ b/test/Transforms/IndVarSimplify/pointer-indvars.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep indvar +@G = global i32* null ; <i32**> [#uses=1] +@Array = external global [40 x i32] ; <[40 x i32]*> [#uses=1] + +define void @test() { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %X = phi i32* [ getelementptr ([40 x i32]* @Array, i64 0, i64 0), %0 ], [ %X.next, %Loop ] ; <i32*> [#uses=2] + %X.next = getelementptr i32* %X, i64 1 ; <i32*> [#uses=1] + store i32* %X, i32** @G + br label %Loop +} + diff --git a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll new file mode 100644 index 000000000000..95726ea08189 --- /dev/null +++ b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis \ +; RUN: | grep {\[%\]p.2.ip.1 = getelementptr \\\[3 x \\\[3 x double\\\]\\\]\\* \[%\]p, i64 2, i64 \[%\]tmp, i64 1} + +; Indvars shouldn't expand this to +; %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 0, i64 %tmp, i64 19 +; or something. That's valid, but more obscure. + +define void @foo([3 x [3 x double]]* noalias %p) nounwind { +entry: + br label %loop + +loop: + %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] + %ip = add i64 %i, 1 + %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 2, i64 %ip, i64 1 + volatile store double 0.0, double* %p.2.ip.1 + %i.next = add i64 %i, 1 + br label %loop +} diff --git a/test/Transforms/IndVarSimplify/preserve-gep.ll b/test/Transforms/IndVarSimplify/preserve-gep.ll new file mode 100644 index 000000000000..2c8c224fb905 --- /dev/null +++ b/test/Transforms/IndVarSimplify/preserve-gep.ll @@ -0,0 +1,39 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: not grep ptrtoint %t +; RUN: not grep inttoptr %t +; RUN: grep getelementptr %t | count 1 + +; Indvars shouldn't leave getelementptrs expanded out as +; inttoptr+ptrtoint in its output in common cases. + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.Foo = type { i32, i32, [10 x i32], i32 } + +define void @me(%struct.Foo* nocapture %Bar) nounwind { +entry: + br i1 false, label %return, label %bb.nph + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb1, %bb.nph + %i.01 = phi i64 [ %4, %bb1 ], [ 0, %bb.nph ] ; <i64> [#uses=3] + %0 = getelementptr %struct.Foo* %Bar, i64 %i.01, i32 2, i64 3 ; <i32*> [#uses=1] + %1 = load i32* %0, align 4 ; <i32> [#uses=1] + %2 = mul i32 %1, 113 ; <i32> [#uses=1] + %3 = getelementptr %struct.Foo* %Bar, i64 %i.01, i32 2, i64 3 ; <i32*> [#uses=1] + store i32 %2, i32* %3, align 4 + %4 = add i64 %i.01, 1 ; <i64> [#uses=2] + br label %bb1 + +bb1: ; preds = %bb + %phitmp = icmp sgt i64 %4, 19999 ; <i1> [#uses=1] + br i1 %phitmp, label %bb1.return_crit_edge, label %bb + +bb1.return_crit_edge: ; preds = %bb1 + br label %return + +return: ; preds = %bb1.return_crit_edge, %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll b/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll new file mode 100644 index 000000000000..0a91ec88064f --- /dev/null +++ b/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: grep sext %t | count 1 +; RUN: grep phi %t | count 1 +; RUN: grep {phi i64} %t + +; Indvars should insert a 64-bit induction variable to eliminate the +; sext for the addressing, however it shouldn't eliminate the sext +; on the other phi, since that value undergoes signed wrapping. + +define void @foo(i32* nocapture %d, i32 %n) nounwind { +entry: + %0 = icmp sgt i32 %n, 0 ; <i1> [#uses=1] + br i1 %0, label %bb.nph, label %return + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb1, %bb.nph + %i.02 = phi i32 [ %5, %bb1 ], [ 0, %bb.nph ] ; <i32> [#uses=2] + %p.01 = phi i8 [ %4, %bb1 ], [ -1, %bb.nph ] ; <i8> [#uses=2] + %1 = sext i8 %p.01 to i32 ; <i32> [#uses=1] + %2 = sext i32 %i.02 to i64 ; <i64> [#uses=1] + %3 = getelementptr i32* %d, i64 %2 ; <i32*> [#uses=1] + store i32 %1, i32* %3, align 4 + %4 = add i8 %p.01, 1 ; <i8> [#uses=1] + %5 = add i32 %i.02, 1 ; <i32> [#uses=2] + br label %bb1 + +bb1: ; preds = %bb + %6 = icmp slt i32 %5, %n ; <i1> [#uses=1] + br i1 %6, label %bb, label %bb1.return_crit_edge + +bb1.return_crit_edge: ; preds = %bb1 + br label %return + +return: ; preds = %bb1.return_crit_edge, %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll b/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll new file mode 100644 index 000000000000..48c060c48d22 --- /dev/null +++ b/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll @@ -0,0 +1,99 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: not grep sext %t + +define i64 @test(i64* nocapture %first, i32 %count) nounwind readonly { +entry: + %t0 = icmp sgt i32 %count, 0 ; <i1> [#uses=1] + br i1 %t0, label %bb.nph, label %bb2 + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb1, %bb.nph + %result.02 = phi i64 [ %t5, %bb1 ], [ 0, %bb.nph ] ; <i64> [#uses=1] + %n.01 = phi i32 [ %t6, %bb1 ], [ 0, %bb.nph ] ; <i32> [#uses=2] + %t1 = sext i32 %n.01 to i64 ; <i64> [#uses=1] + %t2 = getelementptr i64* %first, i64 %t1 ; <i64*> [#uses=1] + %t3 = load i64* %t2, align 8 ; <i64> [#uses=1] + %t4 = lshr i64 %t3, 4 ; <i64> [#uses=1] + %t5 = add i64 %t4, %result.02 ; <i64> [#uses=2] + %t6 = add i32 %n.01, 1 ; <i32> [#uses=2] + br label %bb1 + +bb1: ; preds = %bb + %t7 = icmp slt i32 %t6, %count ; <i1> [#uses=1] + br i1 %t7, label %bb, label %bb1.bb2_crit_edge + +bb1.bb2_crit_edge: ; preds = %bb1 + %.lcssa = phi i64 [ %t5, %bb1 ] ; <i64> [#uses=1] + br label %bb2 + +bb2: ; preds = %bb1.bb2_crit_edge, %entry + %result.0.lcssa = phi i64 [ %.lcssa, %bb1.bb2_crit_edge ], [ 0, %entry ] ; <i64> [#uses=1] + ret i64 %result.0.lcssa +} + +define void @foo(i16 signext %N, i32* nocapture %P) nounwind { +entry: + %t0 = icmp sgt i16 %N, 0 ; <i1> [#uses=1] + br i1 %t0, label %bb.nph, label %return + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb1, %bb.nph + %i.01 = phi i16 [ %t3, %bb1 ], [ 0, %bb.nph ] ; <i16> [#uses=2] + %t1 = sext i16 %i.01 to i64 ; <i64> [#uses=1] + %t2 = getelementptr i32* %P, i64 %t1 ; <i32*> [#uses=1] + store i32 123, i32* %t2, align 4 + %t3 = add i16 %i.01, 1 ; <i16> [#uses=2] + br label %bb1 + +bb1: ; preds = %bb + %t4 = icmp slt i16 %t3, %N ; <i1> [#uses=1] + br i1 %t4, label %bb, label %bb1.return_crit_edge + +bb1.return_crit_edge: ; preds = %bb1 + br label %return + +return: ; preds = %bb1.return_crit_edge, %entry + ret void +} + +; Test cases from PR1301: + +define void @kinds__srangezero([21 x i32]* nocapture %a) nounwind { +bb.thread: + br label %bb + +bb: ; preds = %bb, %bb.thread + %i.0.reg2mem.0 = phi i8 [ -10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2] + %tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1] + %tmp4 = add i32 %tmp12, 10 ; <i32> [#uses=1] + %tmp5 = getelementptr [21 x i32]* %a, i32 0, i32 %tmp4 ; <i32*> [#uses=1] + store i32 0, i32* %tmp5 + %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2] + %0 = icmp sgt i8 %tmp7, 10 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +return: ; preds = %bb + ret void +} + +define void @kinds__urangezero([21 x i32]* nocapture %a) nounwind { +bb.thread: + br label %bb + +bb: ; preds = %bb, %bb.thread + %i.0.reg2mem.0 = phi i8 [ 10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2] + %tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1] + %tmp4 = add i32 %tmp12, -10 ; <i32> [#uses=1] + %tmp5 = getelementptr [21 x i32]* %a, i32 0, i32 %tmp4 ; <i32*> [#uses=1] + store i32 0, i32* %tmp5 + %tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2] + %0 = icmp sgt i8 %tmp7, 30 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +return: ; preds = %bb + ret void +} diff --git a/test/Transforms/IndVarSimplify/signed-trip-count.ll b/test/Transforms/IndVarSimplify/signed-trip-count.ll new file mode 100644 index 000000000000..cd61d11394ee --- /dev/null +++ b/test/Transforms/IndVarSimplify/signed-trip-count.ll @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t +; RUN: not grep sext %t +; RUN: grep phi %t | count 1 + +define void @foo(i64* nocapture %x, i32 %n) nounwind { +entry: + %tmp102 = icmp sgt i32 %n, 0 ; <i1> [#uses=1] + br i1 %tmp102, label %bb.nph, label %return + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb7, %bb.nph + %i.01 = phi i32 [ %tmp6, %bb7 ], [ 0, %bb.nph ] ; <i32> [#uses=3] + %tmp1 = sext i32 %i.01 to i64 ; <i64> [#uses=1] + %tmp4 = getelementptr i64* %x, i32 %i.01 ; <i64*> [#uses=1] + store i64 %tmp1, i64* %tmp4, align 8 + %tmp6 = add i32 %i.01, 1 ; <i32> [#uses=2] + br label %bb7 + +bb7: ; preds = %bb + %tmp10 = icmp slt i32 %tmp6, %n ; <i1> [#uses=1] + br i1 %tmp10, label %bb, label %bb7.return_crit_edge + +bb7.return_crit_edge: ; preds = %bb7 + br label %return + +return: ; preds = %bb7.return_crit_edge, %entry + ret void +} diff --git a/test/Transforms/IndVarSimplify/subtract.ll b/test/Transforms/IndVarSimplify/subtract.ll new file mode 100644 index 000000000000..51065cc1a8a3 --- /dev/null +++ b/test/Transforms/IndVarSimplify/subtract.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep indvar + +@G = global i64 0 ; <i64*> [#uses=1] + +define void @test(i64 %V) { +; <label>:0 + br label %Loop + +Loop: ; preds = %Loop, %0 + %X = phi i64 [ 1, %0 ], [ %X.next, %Loop ] ; <i64> [#uses=2] + %X.next = sub i64 %X, %V ; <i64> [#uses=1] + store i64 %X, i64* @G + br label %Loop +} + diff --git a/test/Transforms/IndVarSimplify/tripcount_compute.ll b/test/Transforms/IndVarSimplify/tripcount_compute.ll new file mode 100644 index 000000000000..9ffce813023a --- /dev/null +++ b/test/Transforms/IndVarSimplify/tripcount_compute.ll @@ -0,0 +1,100 @@ +; These tests ensure that we can compute the trip count of various forms of +; loops. If the trip count of the loop is computable, then we will know what +; the exit value of the loop will be for some value, allowing us to substitute +; it directly into users outside of the loop, making the loop dead. +; +; RUN: llvm-as < %s | opt -indvars -loop-deletion -simplifycfg | llvm-dis | not grep br + +define i32 @linear_setne() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 1 ; <i32> [#uses=1] + %c = icmp ne i32 %i, 100 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + +define i32 @linear_setne_2() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 2 ; <i32> [#uses=1] + %c = icmp ne i32 %i, 100 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + +define i32 @linear_setne_overflow() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 1024 ; <i32> [#uses=1] + %c = icmp ne i32 %i, 0 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + +define i32 @linear_setlt() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 1 ; <i32> [#uses=1] + %c = icmp slt i32 %i, 100 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + +define i32 @quadratic_setlt() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 7, %entry ], [ %i.next, %loop ] ; <i32> [#uses=4] + %i.next = add i32 %i, 3 ; <i32> [#uses=1] + %i2 = mul i32 %i, %i ; <i32> [#uses=1] + %c = icmp slt i32 %i2, 1000 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + +define i32 @chained() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 1 ; <i32> [#uses=1] + %c = icmp ne i32 %i, 100 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + br label %loop2 + +loop2: ; preds = %loop2, %loopexit + %j = phi i32 [ %i, %loopexit ], [ %j.next, %loop2 ] ; <i32> [#uses=3] + %j.next = add i32 %j, 1 ; <i32> [#uses=1] + %c2 = icmp ne i32 %j, 200 ; <i1> [#uses=1] + br i1 %c2, label %loop2, label %loopexit2 + +loopexit2: ; preds = %loop2 + ret i32 %j +} diff --git a/test/Transforms/IndVarSimplify/tripcount_infinite.ll b/test/Transforms/IndVarSimplify/tripcount_infinite.ll new file mode 100644 index 000000000000..d5965f4ed6f0 --- /dev/null +++ b/test/Transforms/IndVarSimplify/tripcount_infinite.ll @@ -0,0 +1,38 @@ +; These tests have an infinite trip count. We obviously shouldn't remove the +; loops! :) +; +; RUN: llvm-as < %s | opt -indvars -adce -simplifycfg | llvm-dis | grep icmp | wc -l > %t2 +; RUN: llvm-as < %s | llvm-dis | grep icmp | wc -l > %t1 +; RUN: diff %t1 %t2 + +;; test for (i = 1; i != 100; i += 2) +define i32 @infinite_linear() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 1, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3] + %i.next = add i32 %i, 2 ; <i32> [#uses=1] + %c = icmp ne i32 %i, 100 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + +;; test for (i = 1; i*i != 63; ++i) +define i32 @infinite_quadratic() { +entry: + br label %loop + +loop: ; preds = %loop, %entry + %i = phi i32 [ 1, %entry ], [ %i.next, %loop ] ; <i32> [#uses=4] + %isquare = mul i32 %i, %i ; <i32> [#uses=1] + %i.next = add i32 %i, 1 ; <i32> [#uses=1] + %c = icmp ne i32 %isquare, 63 ; <i1> [#uses=1] + br i1 %c, label %loop, label %loopexit + +loopexit: ; preds = %loop + ret i32 %i +} + diff --git a/test/Transforms/IndVarSimplify/variable-stride-ivs.ll b/test/Transforms/IndVarSimplify/variable-stride-ivs.ll new file mode 100644 index 000000000000..759ba8e177bc --- /dev/null +++ b/test/Transforms/IndVarSimplify/variable-stride-ivs.ll @@ -0,0 +1,43 @@ +; RUN: llvm-as < %s | opt -indvars -instcombine | llvm-dis | \ +; RUN: grep {store i32 0} +; Test that -indvars can reduce variable stride IVs. If it can reduce variable +; stride iv's, it will make %iv. and %m.0.0 isomorphic to each other without +; cycles, allowing the tmp.21 subtraction to be eliminated. +; END. + +define void @vnum_test8(i32* %data) { +entry: + %tmp.1 = getelementptr i32* %data, i32 3 ; <i32*> [#uses=1] + %tmp.2 = load i32* %tmp.1 ; <i32> [#uses=2] + %tmp.4 = getelementptr i32* %data, i32 4 ; <i32*> [#uses=1] + %tmp.5 = load i32* %tmp.4 ; <i32> [#uses=2] + %tmp.8 = getelementptr i32* %data, i32 2 ; <i32*> [#uses=1] + %tmp.9 = load i32* %tmp.8 ; <i32> [#uses=3] + %tmp.125 = icmp sgt i32 %tmp.2, 0 ; <i1> [#uses=1] + br i1 %tmp.125, label %no_exit.preheader, label %return + +no_exit.preheader: ; preds = %entry + %tmp.16 = getelementptr i32* %data, i32 %tmp.9 ; <i32*> [#uses=1] + br label %no_exit + +no_exit: ; preds = %no_exit, %no_exit.preheader + %iv.ui = phi i32 [ 0, %no_exit.preheader ], [ %iv..inc.ui, %no_exit ] ; <i32> [#uses=1] + %iv. = phi i32 [ %tmp.5, %no_exit.preheader ], [ %iv..inc, %no_exit ] ; <i32> [#uses=2] + %m.0.0 = phi i32 [ %tmp.5, %no_exit.preheader ], [ %tmp.24, %no_exit ] ; <i32> [#uses=2] + store i32 2, i32* %tmp.16 + %tmp.21 = sub i32 %m.0.0, %iv. ; <i32> [#uses=1] + store i32 %tmp.21, i32* %data + %tmp.24 = add i32 %m.0.0, %tmp.9 ; <i32> [#uses=1] + %iv..inc = add i32 %tmp.9, %iv. ; <i32> [#uses=1] + %iv..inc.ui = add i32 %iv.ui, 1 ; <i32> [#uses=2] + %iv..inc1 = bitcast i32 %iv..inc.ui to i32 ; <i32> [#uses=1] + %tmp.12 = icmp slt i32 %iv..inc1, %tmp.2 ; <i1> [#uses=1] + br i1 %tmp.12, label %no_exit, label %return.loopexit + +return.loopexit: ; preds = %no_exit + br label %return + +return: ; preds = %return.loopexit, %entry + ret void +} + |
