Incr->eraseFromParent();
}
+/// Return true if it is OK to use SIToFPInst for an inducation variable
+/// with given inital and exit values.
+static bool useSIToFPInst(ConstantFP &InitV, ConstantFP &ExitV,
+ uint64_t intIV, uint64_t intEV) {
+
+ if (InitV.getValueAPF().isNegative() || ExitV.getValueAPF().isNegative())
+ return true;
+
+ // If the iteration range can be handled by SIToFPInst then use it.
+ APInt Max = APInt::getSignedMaxValue(32);
+ if (Max.getZExtValue() > abs(intEV - intIV))
+ return true;
+
+ return false;
+}
+
+/// convertToInt - Convert APF to an integer, if possible.
static bool convertToInt(const APFloat &APF, uint64_t *intVal) {
bool isExact = false;
Incr->replaceAllUsesWith(UndefValue::get(Incr->getType()));
DeadInsts.insert(Incr);
- // Replace floating induction variable.
- if (EV->getValueAPF().isNegative()
- || InitValue->getValueAPF().isNegative()) {
+ // Replace floating induction variable. Give SIToFPInst preference over
+ // UIToFPInst because it is faster on platforms that are widely used.
+ if (useSIToFPInst(*InitValue, *EV, newInitValue, intEV)) {
SIToFPInst *Conv = new SIToFPInst(NewPHI, PH->getType(), "indvar.conv",
PH->getParent()->getFirstNonPHI());
PH->replaceAllUsesWith(Conv);
--- /dev/null
+; 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)