aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/IndVarSimplify.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-04-03 06:41:49 +0000
committerChris Lattner <sabre@nondot.org>2010-04-03 06:41:49 +0000
commitbbb91498da1a4dc77332bf93d7c13060f0c63a70 (patch)
tree3c966e74ad370ac1d3ce388b3ec75a3ccc0bd8fb /lib/Transforms/Scalar/IndVarSimplify.cpp
parent43b85273ee11536c81b14dca0114cd8b9407db8e (diff)
downloadexternal_llvm-bbb91498da1a4dc77332bf93d7c13060f0c63a70.tar.gz
external_llvm-bbb91498da1a4dc77332bf93d7c13060f0c63a70.tar.bz2
external_llvm-bbb91498da1a4dc77332bf93d7c13060f0c63a70.zip
add a comment and fix some consistency issues, converting
to a signed vs unsigned value depending on the sign of the constant fp means that we can't distinguish between a truly negative number and a positive number so large the 32nd bit is set. So, do don't this! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100283 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index 70be671808..c2035f4b85 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -623,16 +623,17 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) {
}
}
-/// convertToInt - Convert APF to an integer, if possible.
-static bool convertToInt(const APFloat &APF, uint64_t &intVal) {
+/// ConvertToSInt - Convert APF to an integer, if possible.
+static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) {
bool isExact = false;
if (&APF.getSemantics() == &APFloat::PPCDoubleDouble)
return false;
- if (APF.convertToInteger(&intVal, 32, APF.isNegative(),
- APFloat::rmTowardZero, &isExact) != APFloat::opOK)
- return false;
- if (!isExact)
+ // See if we can convert this to an int64_t
+ uint64_t UIntVal;
+ if (APF.convertToInteger(&UIntVal, 64, true, APFloat::rmTowardZero,
+ &isExact) != APFloat::opOK || !isExact)
return false;
+ IntVal = UIntVal;
return true;
}
@@ -654,8 +655,8 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) {
dyn_cast<ConstantFP>(PN->getIncomingValue(IncomingEdge));
if (!InitValueVal) return;
- uint64_t InitValue;
- if (!convertToInt(InitValueVal->getValueAPF(), InitValue))
+ int64_t InitValue;
+ if (!ConvertToSInt(InitValueVal->getValueAPF(), InitValue))
return;
// Check IV increment. Reject this PN if increment operation is not
@@ -667,9 +668,9 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) {
// If this is not an add of the PHI with a constantfp, or if the constant fp
// is not an integer, bail out.
ConstantFP *IncValueVal = dyn_cast<ConstantFP>(Incr->getOperand(1));
- uint64_t IntValue;
+ int64_t IntValue;
if (IncValueVal == 0 || Incr->getOperand(0) != PN ||
- !convertToInt(IncValueVal->getValueAPF(), IntValue))
+ !ConvertToSInt(IncValueVal->getValueAPF(), IntValue))
return;
// Check Incr uses. One user is PN and the other user is an exit condition
@@ -694,9 +695,20 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) {
// If it isn't a comparison with an integer-as-fp (the exit value), we can't
// transform it.
ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1));
- uint64_t ExitValue;
- if (ExitValueVal == 0 || !convertToInt(ExitValueVal->getValueAPF(),ExitValue))
+ int64_t ExitValue;
+ if (ExitValueVal == 0 ||
+ !ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue))
return;
+
+ // We convert the floating point induction variable to a signed i32 value if
+ // we can. This is only safe if the comparison will not overflow in a way
+ // that won't be trapped by the integer equivalent operations. Check for this
+ // now.
+ // TODO: We could use i64 if it is native and the range requires it.
+
+
+
+ const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext());
// Find new predicate for integer comparison.
CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE;
@@ -714,9 +726,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) {
case CmpInst::FCMP_ULE: NewPred = CmpInst::ICMP_SLE; break;
}
- const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext());
-
- // Insert new i32 integer induction variable.
+ // Insert new integer induction variable.
PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN);
NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue),
PN->getIncomingBlock(IncomingEdge));