Constfold trunc,rint,nearbyint,ceil and floor using APFloat

A patch by Chakshu Grover!
This patch allows constfolding of trunc,rint,nearbyint,ceil and floor intrinsics using APFloat class.
Differential Revision: http://reviews.llvm.org/D11144

llvm-svn: 242763
This commit is contained in:
Karthik Bhat 2015-07-21 08:52:23 +00:00
parent 6268bacc0f
commit d818e38ff9
2 changed files with 98 additions and 4 deletions

View File

@ -1236,6 +1236,9 @@ bool llvm::canConstantFoldCallTo(const Function *F) {
case Intrinsic::sqrt:
case Intrinsic::sin:
case Intrinsic::cos:
case Intrinsic::trunc:
case Intrinsic::rint:
case Intrinsic::nearbyint:
case Intrinsic::pow:
case Intrinsic::powi:
case Intrinsic::bswap:
@ -1422,6 +1425,36 @@ static Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID,
return ConstantFP::get(Ty->getContext(), V);
}
if (IntrinsicID == Intrinsic::floor) {
APFloat V = Op->getValueAPF();
V.roundToIntegral(APFloat::rmTowardNegative);
return ConstantFP::get(Ty->getContext(), V);
}
if (IntrinsicID == Intrinsic::ceil) {
APFloat V = Op->getValueAPF();
V.roundToIntegral(APFloat::rmTowardPositive);
return ConstantFP::get(Ty->getContext(), V);
}
if (IntrinsicID == Intrinsic::trunc) {
APFloat V = Op->getValueAPF();
V.roundToIntegral(APFloat::rmTowardZero);
return ConstantFP::get(Ty->getContext(), V);
}
if (IntrinsicID == Intrinsic::rint) {
APFloat V = Op->getValueAPF();
V.roundToIntegral(APFloat::rmNearestTiesToEven);
return ConstantFP::get(Ty->getContext(), V);
}
if (IntrinsicID == Intrinsic::nearbyint) {
APFloat V = Op->getValueAPF();
V.roundToIntegral(APFloat::rmNearestTiesToEven);
return ConstantFP::get(Ty->getContext(), V);
}
/// We only fold functions with finite arguments. Folding NaN and inf is
/// likely to be aborted with an exception anyway, and some host libms
/// have known errors raising exceptions.
@ -1448,10 +1481,6 @@ static Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID,
return ConstantFoldFP(exp, V, Ty);
case Intrinsic::exp2:
return ConstantFoldFP(exp2, V, Ty);
case Intrinsic::floor:
return ConstantFoldFP(floor, V, Ty);
case Intrinsic::ceil:
return ConstantFoldFP(ceil, V, Ty);
case Intrinsic::sin:
return ConstantFoldFP(sin, V, Ty);
case Intrinsic::cos:

View File

@ -19,6 +19,11 @@ declare i32 @llvm.ctpop.i32(i32) nounwind readnone
declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone
declare double @llvm.cos.f64(double %Val) nounwind readonly
declare double @llvm.sin.f64(double %Val) nounwind readonly
declare double @llvm.floor.f64(double %Val) nounwind readonly
declare double @llvm.ceil.f64(double %Val) nounwind readonly
declare double @llvm.trunc.f64(double %Val) nounwind readonly
declare double @llvm.rint.f64(double %Val) nounwind readonly
declare double @llvm.nearbyint.f64(double %Val) nounwind readonly
define i8 @uaddtest1(i8 %A, i8 %B) {
%x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B)
@ -447,3 +452,63 @@ entry:
; CHECK-LABEL: @sin(
; CHECK: store volatile double 0.000000e+00, double* %P
}
define void @floor(double *%P) {
entry:
%B = tail call double @llvm.floor.f64(double 1.5) nounwind
store volatile double %B, double* %P
%C = tail call double @llvm.floor.f64(double -1.5) nounwind
store volatile double %C, double* %P
ret void
; CHECK-LABEL: @floor(
; CHECK: store volatile double 1.000000e+00, double* %P, align 8
; CHECK: store volatile double -2.000000e+00, double* %P, align 8
}
define void @ceil(double *%P) {
entry:
%B = tail call double @llvm.ceil.f64(double 1.5) nounwind
store volatile double %B, double* %P
%C = tail call double @llvm.ceil.f64(double -1.5) nounwind
store volatile double %C, double* %P
ret void
; CHECK-LABEL: @ceil(
; CHECK: store volatile double 2.000000e+00, double* %P, align 8
; CHECK: store volatile double -1.000000e+00, double* %P, align 8
}
define void @trunc(double *%P) {
entry:
%B = tail call double @llvm.trunc.f64(double 1.5) nounwind
store volatile double %B, double* %P
%C = tail call double @llvm.trunc.f64(double -1.5) nounwind
store volatile double %C, double* %P
ret void
; CHECK-LABEL: @trunc(
; CHECK: store volatile double 1.000000e+00, double* %P, align 8
; CHECK: store volatile double -1.000000e+00, double* %P, align 8
}
define void @rint(double *%P) {
entry:
%B = tail call double @llvm.rint.f64(double 1.5) nounwind
store volatile double %B, double* %P
%C = tail call double @llvm.rint.f64(double -1.5) nounwind
store volatile double %C, double* %P
ret void
; CHECK-LABEL: @rint(
; CHECK: store volatile double 2.000000e+00, double* %P, align 8
; CHECK: store volatile double -2.000000e+00, double* %P, align 8
}
define void @nearbyint(double *%P) {
entry:
%B = tail call double @llvm.nearbyint.f64(double 1.5) nounwind
store volatile double %B, double* %P
%C = tail call double @llvm.nearbyint.f64(double -1.5) nounwind
store volatile double %C, double* %P
ret void
; CHECK-LABEL: @nearbyint(
; CHECK: store volatile double 2.000000e+00, double* %P, align 8
; CHECK: store volatile double -2.000000e+00, double* %P, align 8
}