forked from OSchip/llvm-project
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:
parent
6268bacc0f
commit
d818e38ff9
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue