Skip to content

Commit

Permalink
Constfold trunc,rint,nearbyint,ceil and floor using APFloat
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kvbhat committed Jul 21, 2015
1 parent 6268bac commit d818e38
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 4 deletions.
37 changes: 33 additions & 4 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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.
Expand All @@ -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:
Expand Down
65 changes: 65 additions & 0 deletions llvm/test/Transforms/InstCombine/intrinsics.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
}

0 comments on commit d818e38

Please sign in to comment.