mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
rename a function to indicate that it checks for profitability as well
as legality. Make load sinking and gep sinking more careful: we only do it when it won't pessimize loads from the stack. This has the added benefit of not producing code that is unanalyzable to SROA. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65209 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3d2445f5d9
commit
36d3e326df
@ -10180,6 +10180,9 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
||||
|
||||
SmallVector<Value*, 16> FixedOperands(FirstInst->op_begin(),
|
||||
FirstInst->op_end());
|
||||
// This is true if all GEP bases are allocas and if all indices into them are
|
||||
// constants.
|
||||
bool AllBasePointersAreAllocas = true;
|
||||
|
||||
// Scan to see if all operands are the same opcode, all have one use, and all
|
||||
// kill their operands (i.e. the operands have one use).
|
||||
@ -10189,6 +10192,12 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
||||
GEP->getNumOperands() != FirstInst->getNumOperands())
|
||||
return 0;
|
||||
|
||||
// Keep track of whether or not all GEPs are of alloca pointers.
|
||||
if (AllBasePointersAreAllocas &&
|
||||
(!isa<AllocaInst>(GEP->getOperand(0)) ||
|
||||
!GEP->hasAllConstantIndices()))
|
||||
AllBasePointersAreAllocas = false;
|
||||
|
||||
// Compare the operand lists.
|
||||
for (unsigned op = 0, e = FirstInst->getNumOperands(); op != e; ++op) {
|
||||
if (FirstInst->getOperand(op) == GEP->getOperand(op))
|
||||
@ -10209,6 +10218,15 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
||||
}
|
||||
}
|
||||
|
||||
// If all of the base pointers of the PHI'd GEPs are from allocas, don't
|
||||
// bother doing this transformation. At best, this will just safe a bit of
|
||||
// offset calculation, but all the predecessors will have to materialize the
|
||||
// stack address into a register anyway. We'd actually rather *clone* the
|
||||
// load up into the predecessors so that we have a load of a gep of an alloca,
|
||||
// which can usually all be folded into the load.
|
||||
if (AllBasePointersAreAllocas)
|
||||
return 0;
|
||||
|
||||
// Otherwise, this is safe to transform. Insert PHI nodes for each operand
|
||||
// that is variable.
|
||||
SmallVector<PHINode*, 16> OperandPhis(FixedOperands.size());
|
||||
@ -10247,15 +10265,15 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
||||
}
|
||||
|
||||
|
||||
/// isSafeToSinkLoad - Return true if we know that it is safe sink the load out
|
||||
/// of the block that defines it. This means that it must be obvious the value
|
||||
/// of the load is not changed from the point of the load to the end of the
|
||||
/// block it is in.
|
||||
/// isSafeAndProfitableToSinkLoad - Return true if we know that it is safe sink
|
||||
/// the load out of the block that defines it. This means that it must be
|
||||
/// obvious the value of the load is not changed from the point of the load to
|
||||
/// the end of the block it is in.
|
||||
///
|
||||
/// Finally, it is safe, but not profitable, to sink a load targetting a
|
||||
/// non-address-taken alloca. Doing so will cause us to not promote the alloca
|
||||
/// to a register.
|
||||
static bool isSafeToSinkLoad(LoadInst *L) {
|
||||
static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
|
||||
BasicBlock::iterator BBI = L, E = L->getParent()->end();
|
||||
|
||||
for (++BBI; BBI != E; ++BBI)
|
||||
@ -10277,10 +10295,20 @@ static bool isSafeToSinkLoad(LoadInst *L) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isAddressTaken)
|
||||
if (!isAddressTaken && AI->isStaticAlloca())
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this load is a load from a GEP with a constant offset from an alloca,
|
||||
// then we don't want to sink it. In its present form, it will be
|
||||
// load [constant stack offset]. Sinking it will cause us to have to
|
||||
// materialize the stack addresses in each predecessor in a register only to
|
||||
// do a shared load from register in the successor.
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(L->getOperand(0)))
|
||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(GEP->getOperand(0)))
|
||||
if (AI->isStaticAlloca() && GEP->hasAllConstantIndices())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -10311,7 +10339,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
||||
// We can't sink the load if the loaded value could be modified between the
|
||||
// load and the PHI.
|
||||
if (LI->getParent() != PN.getIncomingBlock(0) ||
|
||||
!isSafeToSinkLoad(LI))
|
||||
!isSafeAndProfitableToSinkLoad(LI))
|
||||
return 0;
|
||||
|
||||
// If the PHI is of volatile loads and the load block has multiple
|
||||
@ -10341,7 +10369,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
||||
// the load and the PHI.
|
||||
if (LI->isVolatile() != isVolatile ||
|
||||
LI->getParent() != PN.getIncomingBlock(i) ||
|
||||
!isSafeToSinkLoad(LI))
|
||||
!isSafeAndProfitableToSinkLoad(LI))
|
||||
return 0;
|
||||
|
||||
// If the PHI is of volatile loads and the load block has multiple
|
||||
@ -10350,7 +10378,6 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
||||
if (isVolatile &&
|
||||
LI->getParent()->getTerminator()->getNumSuccessors() != 1)
|
||||
return 0;
|
||||
|
||||
|
||||
} else if (I->getOperand(1) != ConstantOp) {
|
||||
return 0;
|
||||
|
278
test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll
Normal file
278
test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll
Normal file
@ -0,0 +1,278 @@
|
||||
; RUN: llvm-as < %s | opt -instcombine -scalarrepl | llvm-dis | not grep { = alloca}
|
||||
; rdar://6417724
|
||||
; Instcombine shouldn't do anything to this function that prevents promoting the allocas inside it.
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i386-apple-darwin9.6"
|
||||
%"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >" = type { i32* }
|
||||
%"struct.std::_Vector_base<int,std::allocator<int> >" = type { %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl" }
|
||||
%"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl" = type { i32*, i32*, i32* }
|
||||
%"struct.std::bidirectional_iterator_tag" = type <{ i8 }>
|
||||
%"struct.std::forward_iterator_tag" = type <{ i8 }>
|
||||
%"struct.std::input_iterator_tag" = type <{ i8 }>
|
||||
%"struct.std::random_access_iterator_tag" = type <{ i8 }>
|
||||
%"struct.std::vector<int,std::allocator<int> >" = type { %"struct.std::_Vector_base<int,std::allocator<int> >" }
|
||||
|
||||
define i32* @_Z3fooRSt6vectorIiSaIiEE(%"struct.std::vector<int,std::allocator<int> >"* %X) {
|
||||
entry:
|
||||
%0 = alloca %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >" ; <%"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"*> [#uses=2]
|
||||
%__first_addr.i.i = alloca %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >" ; <%"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"*> [#uses=31]
|
||||
%__last_addr.i.i = alloca %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >" ; <%"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"*> [#uses=4]
|
||||
%unnamed_arg.i = alloca %"struct.std::bidirectional_iterator_tag", align 8 ; <%"struct.std::bidirectional_iterator_tag"*> [#uses=1]
|
||||
%1 = alloca %"struct.std::bidirectional_iterator_tag" ; <%"struct.std::bidirectional_iterator_tag"*> [#uses=1]
|
||||
%__first_addr.i = alloca %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >" ; <%"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"*> [#uses=2]
|
||||
%2 = alloca %"struct.std::bidirectional_iterator_tag" ; <%"struct.std::bidirectional_iterator_tag"*> [#uses=2]
|
||||
%3 = alloca %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >" ; <%"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"*> [#uses=2]
|
||||
%4 = alloca i32 ; <i32*> [#uses=8]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
store i32 42, i32* %4, align 4
|
||||
%5 = getelementptr %"struct.std::vector<int,std::allocator<int> >"* %X, i32 0, i32 0 ; <%"struct.std::_Vector_base<int,std::allocator<int> >"*> [#uses=1]
|
||||
%6 = getelementptr %"struct.std::_Vector_base<int,std::allocator<int> >"* %5, i32 0, i32 0 ; <%"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl"*> [#uses=1]
|
||||
%7 = getelementptr %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl"* %6, i32 0, i32 1 ; <i32**> [#uses=1]
|
||||
%8 = load i32** %7, align 4 ; <i32*> [#uses=1]
|
||||
%9 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %3, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %8, i32** %9, align 4
|
||||
%10 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %3, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%11 = load i32** %10, align 4 ; <i32*> [#uses=1]
|
||||
%tmp2.i = ptrtoint i32* %11 to i32 ; <i32> [#uses=1]
|
||||
%tmp1.i = inttoptr i32 %tmp2.i to i32* ; <i32*> [#uses=1]
|
||||
%tmp3 = ptrtoint i32* %tmp1.i to i32 ; <i32> [#uses=1]
|
||||
%tmp2 = inttoptr i32 %tmp3 to i32* ; <i32*> [#uses=1]
|
||||
%12 = getelementptr %"struct.std::vector<int,std::allocator<int> >"* %X, i32 0, i32 0 ; <%"struct.std::_Vector_base<int,std::allocator<int> >"*> [#uses=1]
|
||||
%13 = getelementptr %"struct.std::_Vector_base<int,std::allocator<int> >"* %12, i32 0, i32 0 ; <%"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl"*> [#uses=1]
|
||||
%14 = getelementptr %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl"* %13, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%15 = load i32** %14, align 4 ; <i32*> [#uses=1]
|
||||
%16 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %0, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %15, i32** %16, align 4
|
||||
%17 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %0, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%18 = load i32** %17, align 4 ; <i32*> [#uses=1]
|
||||
%tmp2.i17 = ptrtoint i32* %18 to i32 ; <i32> [#uses=1]
|
||||
%tmp1.i18 = inttoptr i32 %tmp2.i17 to i32* ; <i32*> [#uses=1]
|
||||
%tmp8 = ptrtoint i32* %tmp1.i18 to i32 ; <i32> [#uses=1]
|
||||
%tmp6 = inttoptr i32 %tmp8 to i32* ; <i32*> [#uses=1]
|
||||
%19 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %tmp6, i32** %19
|
||||
%20 = getelementptr %"struct.std::bidirectional_iterator_tag"* %1, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||
%21 = load i8* %20, align 1 ; <i8> [#uses=1]
|
||||
%22 = or i8 %21, 0 ; <i8> [#uses=1]
|
||||
%23 = or i8 %22, 0 ; <i8> [#uses=1]
|
||||
%24 = or i8 %23, 0 ; <i8> [#uses=0]
|
||||
%25 = getelementptr %"struct.std::bidirectional_iterator_tag"* %2, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||
store i8 0, i8* %25, align 1
|
||||
%elt.i = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%val.i = load i32** %elt.i ; <i32*> [#uses=1]
|
||||
%tmp.i = bitcast %"struct.std::bidirectional_iterator_tag"* %unnamed_arg.i to i8* ; <i8*> [#uses=1]
|
||||
%tmp9.i = bitcast %"struct.std::bidirectional_iterator_tag"* %2 to i8* ; <i8*> [#uses=1]
|
||||
call void @llvm.memcpy.i64(i8* %tmp.i, i8* %tmp9.i, i64 1, i32 1)
|
||||
%26 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %val.i, i32** %26
|
||||
%27 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__last_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %tmp2, i32** %27
|
||||
%28 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__last_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%29 = load i32** %28, align 4 ; <i32*> [#uses=1]
|
||||
%30 = ptrtoint i32* %29 to i32 ; <i32> [#uses=1]
|
||||
%31 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%32 = load i32** %31, align 4 ; <i32*> [#uses=1]
|
||||
%33 = ptrtoint i32* %32 to i32 ; <i32> [#uses=1]
|
||||
%34 = sub i32 %30, %33 ; <i32> [#uses=1]
|
||||
%35 = ashr i32 %34, 2 ; <i32> [#uses=1]
|
||||
%36 = ashr i32 %35, 2 ; <i32> [#uses=1]
|
||||
br label %bb12.i.i
|
||||
|
||||
bb.i.i: ; preds = %bb12.i.i
|
||||
%37 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%38 = load i32** %37, align 4 ; <i32*> [#uses=1]
|
||||
%39 = load i32* %38, align 4 ; <i32> [#uses=1]
|
||||
%40 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%41 = icmp eq i32 %39, %40 ; <i1> [#uses=1]
|
||||
%42 = zext i1 %41 to i8 ; <i8> [#uses=1]
|
||||
%toBool.i.i = icmp ne i8 %42, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool.i.i, label %bb1.i.i, label %bb2.i.i
|
||||
|
||||
bb1.i.i: ; preds = %bb.i.i
|
||||
%43 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%44 = load i32** %43, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb2.i.i: ; preds = %bb.i.i
|
||||
%45 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%46 = load i32** %45, align 4 ; <i32*> [#uses=1]
|
||||
%47 = getelementptr i32* %46, i64 1 ; <i32*> [#uses=1]
|
||||
%48 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %47, i32** %48, align 4
|
||||
%49 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%50 = load i32** %49, align 4 ; <i32*> [#uses=1]
|
||||
%51 = load i32* %50, align 4 ; <i32> [#uses=1]
|
||||
%52 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%53 = icmp eq i32 %51, %52 ; <i1> [#uses=1]
|
||||
%54 = zext i1 %53 to i8 ; <i8> [#uses=1]
|
||||
%toBool3.i.i = icmp ne i8 %54, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool3.i.i, label %bb4.i.i, label %bb5.i.i
|
||||
|
||||
bb4.i.i: ; preds = %bb2.i.i
|
||||
%55 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%56 = load i32** %55, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb5.i.i: ; preds = %bb2.i.i
|
||||
%57 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%58 = load i32** %57, align 4 ; <i32*> [#uses=1]
|
||||
%59 = getelementptr i32* %58, i64 1 ; <i32*> [#uses=1]
|
||||
%60 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %59, i32** %60, align 4
|
||||
%61 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%62 = load i32** %61, align 4 ; <i32*> [#uses=1]
|
||||
%63 = load i32* %62, align 4 ; <i32> [#uses=1]
|
||||
%64 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%65 = icmp eq i32 %63, %64 ; <i1> [#uses=1]
|
||||
%66 = zext i1 %65 to i8 ; <i8> [#uses=1]
|
||||
%toBool6.i.i = icmp ne i8 %66, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool6.i.i, label %bb7.i.i, label %bb8.i.i
|
||||
|
||||
bb7.i.i: ; preds = %bb5.i.i
|
||||
%67 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%68 = load i32** %67, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb8.i.i: ; preds = %bb5.i.i
|
||||
%69 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%70 = load i32** %69, align 4 ; <i32*> [#uses=1]
|
||||
%71 = getelementptr i32* %70, i64 1 ; <i32*> [#uses=1]
|
||||
%72 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %71, i32** %72, align 4
|
||||
%73 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%74 = load i32** %73, align 4 ; <i32*> [#uses=1]
|
||||
%75 = load i32* %74, align 4 ; <i32> [#uses=1]
|
||||
%76 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%77 = icmp eq i32 %75, %76 ; <i1> [#uses=1]
|
||||
%78 = zext i1 %77 to i8 ; <i8> [#uses=1]
|
||||
%toBool9.i.i = icmp ne i8 %78, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool9.i.i, label %bb10.i.i, label %bb11.i.i
|
||||
|
||||
bb10.i.i: ; preds = %bb8.i.i
|
||||
%79 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%80 = load i32** %79, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb11.i.i: ; preds = %bb8.i.i
|
||||
%81 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%82 = load i32** %81, align 4 ; <i32*> [#uses=1]
|
||||
%83 = getelementptr i32* %82, i64 1 ; <i32*> [#uses=1]
|
||||
%84 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %83, i32** %84, align 4
|
||||
%85 = sub i32 %__trip_count.0.i.i, 1 ; <i32> [#uses=1]
|
||||
br label %bb12.i.i
|
||||
|
||||
bb12.i.i: ; preds = %bb11.i.i, %entry
|
||||
%__trip_count.0.i.i = phi i32 [ %36, %entry ], [ %85, %bb11.i.i ] ; <i32> [#uses=2]
|
||||
%86 = icmp sgt i32 %__trip_count.0.i.i, 0 ; <i1> [#uses=1]
|
||||
br i1 %86, label %bb.i.i, label %bb13.i.i
|
||||
|
||||
bb13.i.i: ; preds = %bb12.i.i
|
||||
%87 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__last_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%88 = load i32** %87, align 4 ; <i32*> [#uses=1]
|
||||
%89 = ptrtoint i32* %88 to i32 ; <i32> [#uses=1]
|
||||
%90 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%91 = load i32** %90, align 4 ; <i32*> [#uses=1]
|
||||
%92 = ptrtoint i32* %91 to i32 ; <i32> [#uses=1]
|
||||
%93 = sub i32 %89, %92 ; <i32> [#uses=1]
|
||||
%94 = ashr i32 %93, 2 ; <i32> [#uses=1]
|
||||
switch i32 %94, label %bb26.i.i [
|
||||
i32 1, label %bb22.i.i
|
||||
i32 2, label %bb18.i.i
|
||||
i32 3, label %bb14.i.i
|
||||
]
|
||||
|
||||
bb14.i.i: ; preds = %bb13.i.i
|
||||
%95 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%96 = load i32** %95, align 4 ; <i32*> [#uses=1]
|
||||
%97 = load i32* %96, align 4 ; <i32> [#uses=1]
|
||||
%98 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%99 = icmp eq i32 %97, %98 ; <i1> [#uses=1]
|
||||
%100 = zext i1 %99 to i8 ; <i8> [#uses=1]
|
||||
%toBool15.i.i = icmp ne i8 %100, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool15.i.i, label %bb16.i.i, label %bb17.i.i
|
||||
|
||||
bb16.i.i: ; preds = %bb14.i.i
|
||||
%101 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%102 = load i32** %101, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb17.i.i: ; preds = %bb14.i.i
|
||||
%103 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%104 = load i32** %103, align 4 ; <i32*> [#uses=1]
|
||||
%105 = getelementptr i32* %104, i64 1 ; <i32*> [#uses=1]
|
||||
%106 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %105, i32** %106, align 4
|
||||
br label %bb18.i.i
|
||||
|
||||
bb18.i.i: ; preds = %bb17.i.i, %bb13.i.i
|
||||
%107 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%108 = load i32** %107, align 4 ; <i32*> [#uses=1]
|
||||
%109 = load i32* %108, align 4 ; <i32> [#uses=1]
|
||||
%110 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%111 = icmp eq i32 %109, %110 ; <i1> [#uses=1]
|
||||
%112 = zext i1 %111 to i8 ; <i8> [#uses=1]
|
||||
%toBool19.i.i = icmp ne i8 %112, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool19.i.i, label %bb20.i.i, label %bb21.i.i
|
||||
|
||||
bb20.i.i: ; preds = %bb18.i.i
|
||||
%113 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%114 = load i32** %113, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb21.i.i: ; preds = %bb18.i.i
|
||||
%115 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%116 = load i32** %115, align 4 ; <i32*> [#uses=1]
|
||||
%117 = getelementptr i32* %116, i64 1 ; <i32*> [#uses=1]
|
||||
%118 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %117, i32** %118, align 4
|
||||
br label %bb22.i.i
|
||||
|
||||
bb22.i.i: ; preds = %bb21.i.i, %bb13.i.i
|
||||
%119 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%120 = load i32** %119, align 4 ; <i32*> [#uses=1]
|
||||
%121 = load i32* %120, align 4 ; <i32> [#uses=1]
|
||||
%122 = load i32* %4, align 4 ; <i32> [#uses=1]
|
||||
%123 = icmp eq i32 %121, %122 ; <i1> [#uses=1]
|
||||
%124 = zext i1 %123 to i8 ; <i8> [#uses=1]
|
||||
%toBool23.i.i = icmp ne i8 %124, 0 ; <i1> [#uses=1]
|
||||
br i1 %toBool23.i.i, label %bb24.i.i, label %bb25.i.i
|
||||
|
||||
bb24.i.i: ; preds = %bb22.i.i
|
||||
%125 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%126 = load i32** %125, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
bb25.i.i: ; preds = %bb22.i.i
|
||||
%127 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%128 = load i32** %127, align 4 ; <i32*> [#uses=1]
|
||||
%129 = getelementptr i32* %128, i64 1 ; <i32*> [#uses=1]
|
||||
%130 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__first_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
store i32* %129, i32** %130, align 4
|
||||
br label %bb26.i.i
|
||||
|
||||
bb26.i.i: ; preds = %bb25.i.i, %bb13.i.i
|
||||
%131 = getelementptr %"struct.__gnu_cxx::__normal_iterator<int*,std::vector<int, std::allocator<int> > >"* %__last_addr.i.i, i32 0, i32 0 ; <i32**> [#uses=1]
|
||||
%132 = load i32** %131, align 4 ; <i32*> [#uses=1]
|
||||
br label %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
|
||||
_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit: ; preds = %bb26.i.i, %bb24.i.i, %bb20.i.i, %bb16.i.i, %bb10.i.i, %bb7.i.i, %bb4.i.i, %bb1.i.i
|
||||
%.0.0.i.i = phi i32* [ %132, %bb26.i.i ], [ %126, %bb24.i.i ], [ %114, %bb20.i.i ], [ %102, %bb16.i.i ], [ %80, %bb10.i.i ], [ %68, %bb7.i.i ], [ %56, %bb4.i.i ], [ %44, %bb1.i.i ] ; <i32*> [#uses=1]
|
||||
%tmp2.i.i = ptrtoint i32* %.0.0.i.i to i32 ; <i32> [#uses=1]
|
||||
%tmp1.i.i = inttoptr i32 %tmp2.i.i to i32* ; <i32*> [#uses=1]
|
||||
%tmp4.i = ptrtoint i32* %tmp1.i.i to i32 ; <i32> [#uses=1]
|
||||
%tmp3.i = inttoptr i32 %tmp4.i to i32* ; <i32*> [#uses=1]
|
||||
%tmp8.i = ptrtoint i32* %tmp3.i to i32 ; <i32> [#uses=1]
|
||||
%tmp6.i = inttoptr i32 %tmp8.i to i32* ; <i32*> [#uses=1]
|
||||
%tmp12 = ptrtoint i32* %tmp6.i to i32 ; <i32> [#uses=1]
|
||||
%tmp10 = inttoptr i32 %tmp12 to i32* ; <i32*> [#uses=1]
|
||||
%tmp16 = ptrtoint i32* %tmp10 to i32 ; <i32> [#uses=1]
|
||||
br label %return
|
||||
|
||||
return: ; preds = %_ZSt4findIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiET_S7_S7_RKT0_.exit
|
||||
%tmp14 = inttoptr i32 %tmp16 to i32* ; <i32*> [#uses=1]
|
||||
ret i32* %tmp14
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
|
Loading…
Reference in New Issue
Block a user