From cd40233429fce385ae4b22301ce705273a6951a1 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 17 Nov 2008 23:27:13 +0000 Subject: [PATCH] While handling floating point IVs lift restrictions on initial value and increment value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59471 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/IndVarSimplify.cpp | 67 ++++++++++++------- .../IndVarsSimplify/2008-11-03-Floating.ll | 50 +++++++++++++- 2 files changed, 91 insertions(+), 26 deletions(-) diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index d5809784ca0..ba19fbfc963 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -446,7 +446,6 @@ bool IndVarSimplify::doInitialization(Loop *L, LPPassManager &LPM) { bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { - LI = &getAnalysis(); SE = &getAnalysis(); @@ -723,6 +722,19 @@ void IndVarSimplify::OptimizeCanonicalIVType(Loop *L) { Incr->eraseFromParent(); } +static bool convertToInt(const APFloat &APF, uint64_t *intVal) { + + bool isExact = false; + if (APF.convertToInteger(intVal, 32, APF.isNegative(), + APFloat::rmTowardZero, &isExact) + != APFloat::opOK) + return false; + if (!isExact) + return false; + return true; + +} + /// HandleFloatingPointIV - If the loop has floating induction variable /// then insert corresponding integer induction variable if possible. /// For example, @@ -739,12 +751,14 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH, unsigned BackEdge = IncomingEdge^1; // Check incoming value. - ConstantFP *CZ = dyn_cast(PH->getIncomingValue(IncomingEdge)); - if (!CZ) return; - APFloat PHInit = CZ->getValueAPF(); - if (!PHInit.isPosZero()) return; - - // Check IV increment. + ConstantFP *InitValue = dyn_cast(PH->getIncomingValue(IncomingEdge)); + if (!InitValue) return; + uint64_t newInitValue = Type::Int32Ty->getPrimitiveSizeInBits(); + if (!convertToInt(InitValue->getValueAPF(), &newInitValue)) + return; + + // Check IV increment. Reject this PH if increement operation is not + // an add or increment value can not be represented by an integer. BinaryOperator *Incr = dyn_cast(PH->getIncomingValue(BackEdge)); if (!Incr) return; @@ -755,11 +769,12 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH, IncrVIndex = 0; IncrValue = dyn_cast(Incr->getOperand(IncrVIndex)); if (!IncrValue) return; - APFloat IVAPF = IncrValue->getValueAPF(); - APFloat One = APFloat(IVAPF.getSemantics(), 1); - if (!IVAPF.bitwiseIsEqual(One)) return; + uint64_t newIncrValue = Type::Int32Ty->getPrimitiveSizeInBits(); + if (!convertToInt(IncrValue->getValueAPF(), &newIncrValue)) + return; - // Check Incr uses. + // Check Incr uses. One user is PH and the other users is exit condition used + // by the conditional terminator. Value::use_iterator IncrUse = Incr->use_begin(); Instruction *U1 = cast(IncrUse++); if (IncrUse == Incr->use_end()) return; @@ -777,23 +792,17 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH, if (BI->getCondition() != EC) return; } - // Find exit value. + // Find exit value. If exit value can not be represented as an interger then + // do not handle this floating point PH. ConstantFP *EV = NULL; unsigned EVIndex = 1; if (EC->getOperand(1) == Incr) EVIndex = 0; EV = dyn_cast(EC->getOperand(EVIndex)); if (!EV) return; - APFloat EVAPF = EV->getValueAPF(); - if (EVAPF.isNegative()) return; - - // Find corresponding integer exit value. uint64_t intEV = Type::Int32Ty->getPrimitiveSizeInBits(); - bool isExact = false; - if (EVAPF.convertToInteger(&intEV, 32, false, APFloat::rmTowardZero, &isExact) - != APFloat::opOK) + if (!convertToInt(EV->getValueAPF(), &intEV)) return; - if (!isExact) return; // Find new predicate for integer comparison. CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; @@ -826,11 +835,12 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH, // Insert new integer induction variable. PHINode *NewPHI = PHINode::Create(Type::Int32Ty, PH->getName()+".int", PH); - NewPHI->addIncoming(Constant::getNullValue(NewPHI->getType()), + NewPHI->addIncoming(ConstantInt::get(Type::Int32Ty, newInitValue), PH->getIncomingBlock(IncomingEdge)); Value *NewAdd = BinaryOperator::CreateAdd(NewPHI, - ConstantInt::get(Type::Int32Ty, 1), + ConstantInt::get(Type::Int32Ty, + newIncrValue), Incr->getName()+".int", Incr); NewPHI->addIncoming(NewAdd, PH->getIncomingBlock(BackEdge)); @@ -849,9 +859,16 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH, DeadInsts.insert(Incr); // Replace floating induction variable. - UIToFPInst *Conv = new UIToFPInst(NewPHI, PH->getType(), "indvar.conv", - PH->getParent()->getFirstNonPHI()); - PH->replaceAllUsesWith(Conv); + if (EV->getValueAPF().isNegative() + || InitValue->getValueAPF().isNegative()) { + SIToFPInst *Conv = new SIToFPInst(NewPHI, PH->getType(), "indvar.conv", + PH->getParent()->getFirstNonPHI()); + PH->replaceAllUsesWith(Conv); + } else { + UIToFPInst *Conv = new UIToFPInst(NewPHI, PH->getType(), "indvar.conv", + PH->getParent()->getFirstNonPHI()); + PH->replaceAllUsesWith(Conv); + } DeadInsts.insert(PH); } diff --git a/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll b/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll index b7574fea486..6fc065f83f6 100644 --- a/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll +++ b/test/Transforms/IndVarsSimplify/2008-11-03-Floating.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 1 +; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep icmp | count 4 define void @bar() nounwind { entry: br label %bb @@ -15,3 +15,51 @@ return: ; preds = %bb } 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 ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, 2.000000e+00 ; [#uses=2] + %2 = fcmp olt double %1, -1.000000e+00 ; [#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 ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, 1.000000e+00 ; [#uses=2] + %2 = fcmp olt double %1, -1.000000e+00 ; [#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 ] ; [#uses=2] + %0 = tail call i32 @foo(double %x.0.reg2mem.0) nounwind ; [#uses=0] + %1 = add double %x.0.reg2mem.0, -1.000000e+00 ; [#uses=2] + %2 = fcmp olt double %1, 1.000000e+00 ; [#uses=1] + br i1 %2, label %bb, label %return + +return: ; preds = %bb + ret void +} + + -- 2.34.1