diff options
-rw-r--r-- | include/llvm/Analysis/ScalarEvolution.h | 48 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 192 | ||||
-rw-r--r-- | test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll | 1 | ||||
-rw-r--r-- | test/Analysis/ScalarEvolution/max-trip-count.ll | 32 | ||||
-rw-r--r-- | test/Analysis/ScalarEvolution/trip-count3.ll | 74 |
5 files changed, 277 insertions, 70 deletions
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index fabf764..7404f9c 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -217,9 +217,39 @@ namespace llvm { /// std::map<Value*, SCEVHandle> Scalars; + /// BackedgeTakenInfo - Information about the backedge-taken count + /// of a loop. This currently inclues an exact count and a maximum count. + /// + struct BackedgeTakenInfo { + /// Exact - An expression indicating the exact backedge-taken count of + /// the loop if it is known, or a SCEVCouldNotCompute otherwise. + SCEVHandle Exact; + + /// Exact - An expression indicating the least maximum backedge-taken + /// count of the loop that is known, or a SCEVCouldNotCompute. + SCEVHandle Max; + + /*implicit*/ BackedgeTakenInfo(SCEVHandle exact) : + Exact(exact), Max(exact) {} + + /*implicit*/ BackedgeTakenInfo(SCEV *exact) : + Exact(exact), Max(exact) {} + + BackedgeTakenInfo(SCEVHandle exact, SCEVHandle max) : + Exact(exact), Max(max) {} + + /// hasAnyInfo - Test whether this BackedgeTakenInfo contains any + /// computed information, or whether it's all SCEVCouldNotCompute + /// values. + bool hasAnyInfo() const { + return !isa<SCEVCouldNotCompute>(Exact) || + !isa<SCEVCouldNotCompute>(Max); + } + }; + /// BackedgeTakenCounts - Cache the backedge-taken count of the loops for /// this function as they are computed. - std::map<const Loop*, SCEVHandle> BackedgeTakenCounts; + std::map<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts; /// ConstantEvolutionLoopExitValue - This map contains entries for all of /// the PHI instructions that we attempt to compute constant evolutions for. @@ -244,9 +274,14 @@ namespace llvm { const SCEVHandle &SymName, const SCEVHandle &NewVal); + /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given + /// loop, lazily computing new values if the loop hasn't been analyzed + /// yet. + const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L); + /// ComputeBackedgeTakenCount - Compute the number of times the specified /// loop will iterate. - SCEVHandle ComputeBackedgeTakenCount(const Loop *L); + BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L); /// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition /// of 'icmp op load X, cst', try to see if we can compute the trip count. @@ -277,8 +312,8 @@ namespace llvm { /// HowManyLessThans - Return the number of times a backedge containing the /// specified less-than comparison will execute. If not computable, return /// UnknownValue. isSigned specifies whether the less-than is signed. - SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, - bool isSigned); + BackedgeTakenInfo HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, + bool isSigned); /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB /// (which may not be an immediate predecessor) which has exactly one @@ -431,6 +466,11 @@ namespace llvm { /// SCEVHandle getBackedgeTakenCount(const Loop *L); + /// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except + /// return the least SCEV value that is known never to be less than the + /// actual backedge taken count. + SCEVHandle getMaxBackedgeTakenCount(const Loop *L); + /// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop /// has an analyzable loop-invariant backedge-taken count. bool hasLoopInvariantBackedgeTakenCount(const Loop *L); diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 027ce6f..252eabe 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -715,8 +715,8 @@ SCEVHandle ScalarEvolution::getZeroExtendExpr(const SCEVHandle &Op, // in infinite recursion. In the later case, the analysis code will // cope with a conservative value, and it will take care to purge // that value once it has finished. - SCEVHandle BECount = getBackedgeTakenCount(AR->getLoop()); - if (!isa<SCEVCouldNotCompute>(BECount)) { + SCEVHandle MaxBECount = getMaxBackedgeTakenCount(AR->getLoop()); + if (!isa<SCEVCouldNotCompute>(MaxBECount)) { // Manually compute the final value for AR, checking for // overflow. SCEVHandle Start = AR->getStart(); @@ -724,20 +724,20 @@ SCEVHandle ScalarEvolution::getZeroExtendExpr(const SCEVHandle &Op, // Check whether the backedge-taken count can be losslessly casted to // the addrec's type. The count is always unsigned. - SCEVHandle CastedBECount = - getTruncateOrZeroExtend(BECount, Start->getType()); - if (BECount == - getTruncateOrZeroExtend(CastedBECount, BECount->getType())) { + SCEVHandle CastedMaxBECount = + getTruncateOrZeroExtend(MaxBECount, Start->getType()); + if (MaxBECount == + getTruncateOrZeroExtend(CastedMaxBECount, MaxBECount->getType())) { const Type *WideTy = IntegerType::get(getTypeSizeInBits(Start->getType()) * 2); - // Check whether Start+Step*BECount has no unsigned overflow. + // Check whether Start+Step*MaxBECount has no unsigned overflow. SCEVHandle ZMul = - getMulExpr(CastedBECount, + getMulExpr(CastedMaxBECount, getTruncateOrZeroExtend(Step, Start->getType())); SCEVHandle Add = getAddExpr(Start, ZMul); if (getZeroExtendExpr(Add, WideTy) == getAddExpr(getZeroExtendExpr(Start, WideTy), - getMulExpr(getZeroExtendExpr(CastedBECount, WideTy), + getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getZeroExtendExpr(Step, WideTy)))) // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), @@ -747,12 +747,12 @@ SCEVHandle ScalarEvolution::getZeroExtendExpr(const SCEVHandle &Op, // Similar to above, only this time treat the step value as signed. // This covers loops that count down. SCEVHandle SMul = - getMulExpr(CastedBECount, + getMulExpr(CastedMaxBECount, getTruncateOrSignExtend(Step, Start->getType())); Add = getAddExpr(Start, SMul); if (getZeroExtendExpr(Add, WideTy) == getAddExpr(getZeroExtendExpr(Start, WideTy), - getMulExpr(getZeroExtendExpr(CastedBECount, WideTy), + getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getSignExtendExpr(Step, WideTy)))) // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), @@ -797,8 +797,8 @@ SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, // in infinite recursion. In the later case, the analysis code will // cope with a conservative value, and it will take care to purge // that value once it has finished. - SCEVHandle BECount = getBackedgeTakenCount(AR->getLoop()); - if (!isa<SCEVCouldNotCompute>(BECount)) { + SCEVHandle MaxBECount = getMaxBackedgeTakenCount(AR->getLoop()); + if (!isa<SCEVCouldNotCompute>(MaxBECount)) { // Manually compute the final value for AR, checking for // overflow. SCEVHandle Start = AR->getStart(); @@ -806,20 +806,20 @@ SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, // Check whether the backedge-taken count can be losslessly casted to // the addrec's type. The count is always unsigned. - SCEVHandle CastedBECount = - getTruncateOrZeroExtend(BECount, Start->getType()); - if (BECount == - getTruncateOrZeroExtend(CastedBECount, BECount->getType())) { + SCEVHandle CastedMaxBECount = + getTruncateOrZeroExtend(MaxBECount, Start->getType()); + if (MaxBECount == + getTruncateOrZeroExtend(CastedMaxBECount, MaxBECount->getType())) { const Type *WideTy = IntegerType::get(getTypeSizeInBits(Start->getType()) * 2); - // Check whether Start+Step*BECount has no signed overflow. + // Check whether Start+Step*MaxBECount has no signed overflow. SCEVHandle SMul = - getMulExpr(CastedBECount, + getMulExpr(CastedMaxBECount, getTruncateOrSignExtend(Step, Start->getType())); SCEVHandle Add = getAddExpr(Start, SMul); if (getSignExtendExpr(Add, WideTy) == getAddExpr(getSignExtendExpr(Start, WideTy), - getMulExpr(getZeroExtendExpr(CastedBECount, WideTy), + getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getSignExtendExpr(Step, WideTy)))) // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), @@ -2060,34 +2060,48 @@ SCEVHandle ScalarEvolution::createSCEV(Value *V) { /// hasLoopInvariantBackedgeTakenCount). /// SCEVHandle ScalarEvolution::getBackedgeTakenCount(const Loop *L) { + return getBackedgeTakenInfo(L).Exact; +} + +/// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except +/// return the least SCEV value that is known never to be less than the +/// actual backedge taken count. +SCEVHandle ScalarEvolution::getMaxBackedgeTakenCount(const Loop *L) { + return getBackedgeTakenInfo(L).Max; +} + +const ScalarEvolution::BackedgeTakenInfo & +ScalarEvolution::getBackedgeTakenInfo(const Loop *L) { // Initially insert a CouldNotCompute for this loop. If the insertion // succeeds, procede to actually compute a backedge-taken count and // update the value. The temporary CouldNotCompute value tells SCEV // code elsewhere that it shouldn't attempt to request a new // backedge-taken count, which could result in infinite recursion. - std::pair<std::map<const Loop*, SCEVHandle>::iterator, bool> Pair = + std::pair<std::map<const Loop*, BackedgeTakenInfo>::iterator, bool> Pair = BackedgeTakenCounts.insert(std::make_pair(L, getCouldNotCompute())); if (Pair.second) { - SCEVHandle ItCount = ComputeBackedgeTakenCount(L); - if (ItCount != UnknownValue) { - assert(ItCount->isLoopInvariant(L) && + BackedgeTakenInfo ItCount = ComputeBackedgeTakenCount(L); + if (ItCount.Exact != UnknownValue) { + assert(ItCount.Exact->isLoopInvariant(L) && + ItCount.Max->isLoopInvariant(L) && "Computed trip count isn't loop invariant for loop!"); ++NumTripCountsComputed; - // Now that we know the trip count for this loop, forget any - // existing SCEV values for PHI nodes in this loop since they - // are only conservative estimates made without the benefit - // of trip count information. - for (BasicBlock::iterator I = L->getHeader()->begin(); - PHINode *PN = dyn_cast<PHINode>(I); ++I) - deleteValueFromRecords(PN); - // Update the value in the map. Pair.first->second = ItCount; } else if (isa<PHINode>(L->getHeader()->begin())) { // Only count loops that have phi nodes as not being computable. ++NumTripCountsNotComputed; } + + // Now that we know more about the trip count for this loop, forget any + // existing SCEV values for PHI nodes in this loop since they are only + // conservative estimates made without the benefit + // of trip count information. + if (ItCount.hasAnyInfo()) + for (BasicBlock::iterator I = L->getHeader()->begin(); + PHINode *PN = dyn_cast<PHINode>(I); ++I) + deleteValueFromRecords(PN); } return Pair.first->second; } @@ -2102,7 +2116,8 @@ void ScalarEvolution::forgetLoopBackedgeTakenCount(const Loop *L) { /// ComputeBackedgeTakenCount - Compute the number of times the backedge /// of the specified loop will execute. -SCEVHandle ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) { +ScalarEvolution::BackedgeTakenInfo +ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) { // If the loop has a non-one exit block count, we can't analyze it. SmallVector<BasicBlock*, 8> ExitBlocks; L->getExitBlocks(ExitBlocks); @@ -2223,25 +2238,25 @@ SCEVHandle ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) { break; } case ICmpInst::ICMP_SLT: { - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true); - if (!isa<SCEVCouldNotCompute>(TC)) return TC; + BackedgeTakenInfo BTI = HowManyLessThans(LHS, RHS, L, true); + if (BTI.hasAnyInfo()) return BTI; break; } case ICmpInst::ICMP_SGT: { - SCEVHandle TC = HowManyLessThans(getNotSCEV(LHS), - getNotSCEV(RHS), L, true); - if (!isa<SCEVCouldNotCompute>(TC)) return TC; + BackedgeTakenInfo BTI = HowManyLessThans(getNotSCEV(LHS), + getNotSCEV(RHS), L, true); + if (BTI.hasAnyInfo()) return BTI; break; } case ICmpInst::ICMP_ULT: { - SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false); - if (!isa<SCEVCouldNotCompute>(TC)) return TC; + BackedgeTakenInfo BTI = HowManyLessThans(LHS, RHS, L, false); + if (BTI.hasAnyInfo()) return BTI; break; } case ICmpInst::ICMP_UGT: { - SCEVHandle TC = HowManyLessThans(getNotSCEV(LHS), - getNotSCEV(RHS), L, false); - if (!isa<SCEVCouldNotCompute>(TC)) return TC; + BackedgeTakenInfo BTI = HowManyLessThans(getNotSCEV(LHS), + getNotSCEV(RHS), L, false); + if (BTI.hasAnyInfo()) return BTI; break; } default: @@ -3093,7 +3108,7 @@ bool ScalarEvolution::isLoopGuardedByCond(const Loop *L, /// HowManyLessThans - Return the number of times a backedge containing the /// specified less-than comparison will execute. If not computable, return /// UnknownValue. -SCEVHandle ScalarEvolution:: +ScalarEvolution::BackedgeTakenInfo ScalarEvolution:: HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool isSigned) { // Only handle: "ADDREC < LoopInvariant". if (!RHS->isLoopInvariant(L)) return UnknownValue; @@ -3104,34 +3119,81 @@ HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool isSigned) { if (AddRec->isAffine()) { // FORNOW: We only support unit strides. - SCEVHandle One = getIntegerSCEV(1, RHS->getType()); - if (AddRec->getOperand(1) != One) + unsigned BitWidth = getTypeSizeInBits(AddRec->getType()); + SCEVHandle Step = AddRec->getStepRecurrence(*this); + SCEVHandle NegOne = getIntegerSCEV(-1, AddRec->getType()); + + // TODO: handle non-constant strides. + const SCEVConstant *CStep = dyn_cast<SCEVConstant>(Step); + if (!CStep || CStep->isZero()) + return UnknownValue; + if (CStep->getValue()->getValue() == 1) { + // With unit stride, the iteration never steps past the limit value. + } else if (CStep->getValue()->getValue().isStrictlyPositive()) { + if (const SCEVConstant *CLimit = dyn_cast<SCEVConstant>(RHS)) { + // Test whether a positive iteration iteration can step past the limit + // value and past the maximum value for its type in a single step. + if (isSigned) { + APInt Max = APInt::getSignedMaxValue(BitWidth); + if ((Max - CStep->getValue()->getValue()) + .slt(CLimit->getValue()->getValue())) + return UnknownValue; + } else { + APInt Max = APInt::getMaxValue(BitWidth); + if ((Max - CStep->getValue()->getValue()) + .ult(CLimit->getValue()->getValue())) + return UnknownValue; + } + } else + // TODO: handle non-constant limit values below. + return UnknownValue; + } else + // TODO: handle negative strides below. return UnknownValue; - // We know the LHS is of the form {n,+,1} and the RHS is some loop-invariant - // m. So, we count the number of iterations in which {n,+,1} < m is true. - // Note that we cannot simply return max(m-n,0) because it's not safe to + // We know the LHS is of the form {n,+,s} and the RHS is some loop-invariant + // m. So, we count the number of iterations in which {n,+,s} < m is true. + // Note that we cannot simply return max(m-n,0)/s because it's not safe to // treat m-n as signed nor unsigned due to overflow possibility. // First, we get the value of the LHS in the first iteration: n SCEVHandle Start = AddRec->getOperand(0); - if (isLoopGuardedByCond(L, - isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - getMinusSCEV(AddRec->getOperand(0), One), RHS)) { - // Since we know that the condition is true in order to enter the loop, - // we know that it will run exactly m-n times. - return getMinusSCEV(RHS, Start); - } else { - // Then, we get the value of the LHS in the first iteration in which the - // above condition doesn't hold. This equals to max(m,n). - SCEVHandle End = isSigned ? getSMaxExpr(RHS, Start) - : getUMaxExpr(RHS, Start); - - // Finally, we subtract these two values to get the number of times the - // backedge is executed: max(m,n)-n. - return getMinusSCEV(End, Start); - } + // Determine the minimum constant start value. + SCEVHandle MinStart = isa<SCEVConstant>(Start) ? Start : + getConstant(isSigned ? APInt::getSignedMinValue(BitWidth) : + APInt::getMinValue(BitWidth)); + + // If we know that the condition is true in order to enter the loop, + // then we know that it will run exactly (m-n)/s times. Otherwise, we + // only know if will execute (max(m,n)-n)/s times. In both cases, the + // division must round up. + SCEVHandle End = RHS; + if (!isLoopGuardedByCond(L, + isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + getMinusSCEV(Start, Step), RHS)) + End = isSigned ? getSMaxExpr(RHS, Start) + : getUMaxExpr(RHS, Start); + + // Determine the maximum constant end value. + SCEVHandle MaxEnd = isa<SCEVConstant>(End) ? End : + getConstant(isSigned ? APInt::getSignedMaxValue(BitWidth) : + APInt::getMaxValue(BitWidth)); + + // Finally, we subtract these two values and divide, rounding up, to get + // the number of times the backedge is executed. + SCEVHandle BECount = getUDivExpr(getAddExpr(getMinusSCEV(End, Start), + getAddExpr(Step, NegOne)), + Step); + + // The maximum backedge count is similar, except using the minimum start + // value and the maximum end value. + SCEVHandle MaxBECount = getUDivExpr(getAddExpr(getMinusSCEV(MaxEnd, + MinStart), + getAddExpr(Step, NegOne)), + Step); + + return BackedgeTakenInfo(BECount, MaxBECount); } return UnknownValue; diff --git a/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll b/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll index ac746e2..78cda0e 100644 --- a/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll +++ b/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | opt -analyze -scalar-evolution |& grep {/u 3} -; XFAIL: * define i32 @f(i32 %x) nounwind readnone { entry: diff --git a/test/Analysis/ScalarEvolution/max-trip-count.ll b/test/Analysis/ScalarEvolution/max-trip-count.ll new file mode 100644 index 0000000..ab88f13 --- /dev/null +++ b/test/Analysis/ScalarEvolution/max-trip-count.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \ +; RUN: | grep {\{(ptrtoint i32\\* %d to iPTR),+,4\}<bb>} + +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/Analysis/ScalarEvolution/trip-count3.ll b/test/Analysis/ScalarEvolution/trip-count3.ll new file mode 100644 index 0000000..a95138f --- /dev/null +++ b/test/Analysis/ScalarEvolution/trip-count3.ll @@ -0,0 +1,74 @@ +; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \ +; RUN: | grep {backedge-taken count is ((64 + (-64 smax (-1 + (-1 \\* %0))) + %0) /u 64)} + +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.FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] } + %struct.SHA_INFO = type { [5 x i32], i32, i32, [16 x i32] } + %struct._IO_marker = type { %struct._IO_marker*, %struct.FILE*, i32 } +@_2E_str = external constant [26 x i8] ; <[26 x i8]*> [#uses=0] +@stdin = external global %struct.FILE* ; <%struct.FILE**> [#uses=0] +@_2E_str1 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0] +@_2E_str12 = external constant [30 x i8] ; <[30 x i8]*> [#uses=0] + +declare void @sha_init(%struct.SHA_INFO* nocapture) nounwind + +declare fastcc void @sha_transform(%struct.SHA_INFO* nocapture) nounwind + +declare void @sha_print(%struct.SHA_INFO* nocapture) nounwind + +declare i32 @printf(i8* nocapture, ...) nounwind + +declare void @sha_final(%struct.SHA_INFO* nocapture) nounwind + +declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind + +declare void @sha_update(%struct.SHA_INFO* nocapture, i8* nocapture, i32) nounwind + +declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind + +declare i64 @fread(i8* noalias nocapture, i64, i64, %struct.FILE* noalias nocapture) nounwind + +declare i32 @main(i32, i8** nocapture) nounwind + +declare noalias %struct.FILE* @fopen(i8* noalias nocapture, i8* noalias nocapture) nounwind + +declare i32 @fclose(%struct.FILE* nocapture) nounwind + +declare void @sha_stream(%struct.SHA_INFO* nocapture, %struct.FILE* nocapture) nounwind + +define void @sha_stream_bb3_2E_i(%struct.SHA_INFO* %sha_info, i8* %data1, i32, i8** %buffer_addr.0.i.out, i32* %count_addr.0.i.out) nounwind { +newFuncRoot: + br label %bb3.i + +sha_update.exit.exitStub: ; preds = %bb3.i + store i8* %buffer_addr.0.i, i8** %buffer_addr.0.i.out + store i32 %count_addr.0.i, i32* %count_addr.0.i.out + ret void + +bb2.i: ; preds = %bb3.i + %1 = getelementptr %struct.SHA_INFO* %sha_info, i64 0, i32 3 ; <[16 x i32]*> [#uses=1] + %2 = bitcast [16 x i32]* %1 to i8* ; <i8*> [#uses=1] + call void @llvm.memcpy.i64(i8* %2, i8* %buffer_addr.0.i, i64 64, i32 1) nounwind + %3 = getelementptr %struct.SHA_INFO* %sha_info, i64 0, i32 3, i64 0 ; <i32*> [#uses=1] + %4 = bitcast i32* %3 to i8* ; <i8*> [#uses=1] + br label %codeRepl + +codeRepl: ; preds = %bb2.i + call void @sha_stream_bb3_2E_i_bb1_2E_i_2E_i(i8* %4) + br label %byte_reverse.exit.i + +byte_reverse.exit.i: ; preds = %codeRepl + call fastcc void @sha_transform(%struct.SHA_INFO* %sha_info) nounwind + %5 = getelementptr i8* %buffer_addr.0.i, i64 64 ; <i8*> [#uses=1] + %6 = add i32 %count_addr.0.i, -64 ; <i32> [#uses=1] + br label %bb3.i + +bb3.i: ; preds = %byte_reverse.exit.i, %newFuncRoot + %buffer_addr.0.i = phi i8* [ %data1, %newFuncRoot ], [ %5, %byte_reverse.exit.i ] ; <i8*> [#uses=3] + %count_addr.0.i = phi i32 [ %0, %newFuncRoot ], [ %6, %byte_reverse.exit.i ] ; <i32> [#uses=3] + %7 = icmp sgt i32 %count_addr.0.i, 63 ; <i1> [#uses=1] + br i1 %7, label %bb2.i, label %sha_update.exit.exitStub +} + +declare void @sha_stream_bb3_2E_i_bb1_2E_i_2E_i(i8*) nounwind |