diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 478ee998d41..10f8e4ed684 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -1244,15 +1244,7 @@ bool llvm::canConstantFoldCallTo(const Function *F) { } } -static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, - Type *Ty) { - sys::llvm_fenv_clearexcept(); - V = NativeFP(V); - if (sys::llvm_fenv_testexcept()) { - sys::llvm_fenv_clearexcept(); - return 0; - } - +static Constant *GetConstantFoldFPValue(double V, Type *Ty) { if (Ty->isHalfTy()) { APFloat APF(V); bool unused; @@ -1264,6 +1256,19 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, if (Ty->isDoubleTy()) return ConstantFP::get(Ty->getContext(), APFloat(V)); llvm_unreachable("Can only constant fold half/float/double"); + +} + +static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, + Type *Ty) { + sys::llvm_fenv_clearexcept(); + V = NativeFP(V); + if (sys::llvm_fenv_testexcept()) { + sys::llvm_fenv_clearexcept(); + return 0; + } + + return GetConstantFoldFPValue(V, Ty); } static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), @@ -1275,17 +1280,7 @@ static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), return 0; } - if (Ty->isHalfTy()) { - APFloat APF(V); - bool unused; - APF.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, &unused); - return ConstantFP::get(Ty->getContext(), APF); - } - if (Ty->isFloatTy()) - return ConstantFP::get(Ty->getContext(), APFloat((float)V)); - if (Ty->isDoubleTy()) - return ConstantFP::get(Ty->getContext(), APFloat(V)); - llvm_unreachable("Can only constant fold half/float/double"); + return GetConstantFoldFPValue(V, Ty); } /// ConstantFoldConvertToInt - Attempt to an SSE floating point to integer @@ -1315,6 +1310,21 @@ static Constant *ConstantFoldConvertToInt(const APFloat &Val, return ConstantInt::get(Ty, UIntVal, /*isSigned=*/true); } +static double getValueAsDouble(ConstantFP *Op) { + Type *Ty = Op->getType(); + + if (Ty->isFloatTy()) + return Op->getValueAPF().convertToFloat(); + + if (Ty->isDoubleTy()) + return Op->getValueAPF().convertToDouble(); + + bool unused; + APFloat APF = Op->getValueAPF(); + APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &unused); + return APF.convertToDouble(); +} + /// ConstantFoldCall - Attempt to constant fold a call to the specified function /// with the specified arguments, returning null if unsuccessful. Constant * @@ -1351,17 +1361,7 @@ llvm::ConstantFoldCall(Function *F, ArrayRef Operands, /// the host native double versions. Float versions are not called /// directly but for all these it is true (float)(f((double)arg)) == /// f(arg). Long double not supported yet. - double V; - if (Ty->isFloatTy()) - V = Op->getValueAPF().convertToFloat(); - else if (Ty->isDoubleTy()) - V = Op->getValueAPF().convertToDouble(); - else { - bool unused; - APFloat APF = Op->getValueAPF(); - APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &unused); - V = APF.convertToDouble(); - } + double V = getValueAsDouble(Op); switch (F->getIntrinsicID()) { default: break; @@ -1526,34 +1526,13 @@ llvm::ConstantFoldCall(Function *F, ArrayRef Operands, if (ConstantFP *Op1 = dyn_cast(Operands[0])) { if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy()) return 0; - double Op1V; - if (Ty->isFloatTy()) - Op1V = Op1->getValueAPF().convertToFloat(); - else if (Ty->isDoubleTy()) - Op1V = Op1->getValueAPF().convertToDouble(); - else { - bool unused; - APFloat APF = Op1->getValueAPF(); - APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &unused); - Op1V = APF.convertToDouble(); - } + double Op1V = getValueAsDouble(Op1); if (ConstantFP *Op2 = dyn_cast(Operands[1])) { if (Op2->getType() != Op1->getType()) return 0; - double Op2V; - if (Ty->isFloatTy()) - Op2V = Op2->getValueAPF().convertToFloat(); - else if (Ty->isDoubleTy()) - Op2V = Op2->getValueAPF().convertToDouble(); - else { - bool unused; - APFloat APF = Op2->getValueAPF(); - APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &unused); - Op2V = APF.convertToDouble(); - } - + double Op2V = getValueAsDouble(Op2); if (F->getIntrinsicID() == Intrinsic::pow) { return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty); }