1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

Fix duplicate code in ConstantFolding

llvm-svn: 202913
This commit is contained in:
Matt Arsenault 2014-03-05 00:01:58 +00:00
parent 432d40e686
commit 7ae64140ae

View File

@ -1244,15 +1244,7 @@ bool llvm::canConstantFoldCallTo(const Function *F) {
} }
} }
static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, static Constant *GetConstantFoldFPValue(double V, Type *Ty) {
Type *Ty) {
sys::llvm_fenv_clearexcept();
V = NativeFP(V);
if (sys::llvm_fenv_testexcept()) {
sys::llvm_fenv_clearexcept();
return 0;
}
if (Ty->isHalfTy()) { if (Ty->isHalfTy()) {
APFloat APF(V); APFloat APF(V);
bool unused; bool unused;
@ -1264,6 +1256,19 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
if (Ty->isDoubleTy()) if (Ty->isDoubleTy())
return ConstantFP::get(Ty->getContext(), APFloat(V)); return ConstantFP::get(Ty->getContext(), APFloat(V));
llvm_unreachable("Can only constant fold half/float/double"); 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), static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
@ -1275,17 +1280,7 @@ static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
return 0; return 0;
} }
if (Ty->isHalfTy()) { return GetConstantFoldFPValue(V, Ty);
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");
} }
/// ConstantFoldConvertToInt - Attempt to an SSE floating point to integer /// 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); 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 /// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful. /// with the specified arguments, returning null if unsuccessful.
Constant * Constant *
@ -1351,17 +1361,7 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
/// the host native double versions. Float versions are not called /// the host native double versions. Float versions are not called
/// directly but for all these it is true (float)(f((double)arg)) == /// directly but for all these it is true (float)(f((double)arg)) ==
/// f(arg). Long double not supported yet. /// f(arg). Long double not supported yet.
double V; double V = getValueAsDouble(Op);
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();
}
switch (F->getIntrinsicID()) { switch (F->getIntrinsicID()) {
default: break; default: break;
@ -1526,34 +1526,13 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) { if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy()) if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return 0; return 0;
double Op1V; double Op1V = getValueAsDouble(Op1);
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();
}
if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) { if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
if (Op2->getType() != Op1->getType()) if (Op2->getType() != Op1->getType())
return 0; return 0;
double Op2V; double Op2V = getValueAsDouble(Op2);
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();
}
if (F->getIntrinsicID() == Intrinsic::pow) { if (F->getIntrinsicID() == Intrinsic::pow) {
return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty); return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
} }