This is an archive of the discontinued LLVM Phabricator instance.

ConstantFolding- Trunc, rint and nearbyint
ClosedPublic

Authored by chakshugrover on Jul 13 2015, 7:13 AM.

Details

Summary

Allow constfolding of llvm.trunc.*, llvm.rint.* and llvm.nearbyint.* intrinsics
This patch const folds llvm.trunc.*, llvm.rint.* and llvm.nearbyint.* intrinsics whenever feasible.

Diff Detail

Repository
rL LLVM

Event Timeline

chakshugrover retitled this revision from to ConstantFolding- Trunc, rint and nearbyint .
chakshugrover updated this object.
chakshugrover added a subscriber: llvm-commits.

Chakshu Grover wrote:

chakshugrover created this revision.
chakshugrover added a subscriber: llvm-commits.

Allow constfolding of llvm.trunc.*, llvm.rint.* and llvm.nearbyint.* intrinsics
This patch const folds llvm.trunc.*, llvm.rint.* and llvm.nearbyint.* intrinsics whenever feasible.

http://reviews.llvm.org/D11144

Files:

lib/Analysis/ConstantFolding.cpp
test/Transforms/InstCombine/intrinsics.ll

Index: test/Transforms/InstCombine/intrinsics.ll

  • test/Transforms/InstCombine/intrinsics.ll

+++ test/Transforms/InstCombine/intrinsics.ll
@@ -19,6 +19,9 @@

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.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 +450,39 @@

; CHECK-LABEL: @sin(
; CHECK: store volatile double 0.000000e+00, double* %P
}

+
+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
+}

Index: lib/Analysis/ConstantFolding.cpp

  • lib/Analysis/ConstantFolding.cpp

+++ lib/Analysis/ConstantFolding.cpp
@@ -1236,6 +1236,9 @@

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:

@@ -1456,6 +1459,12 @@

  return ConstantFoldFP(sin, V, Ty);
case Intrinsic::cos:
  return ConstantFoldFP(cos, V, Ty);

+ case Intrinsic::trunc:
+ return ConstantFoldFP(trunc, V, Ty);
+ case Intrinsic::rint:
+ return ConstantFoldFP(rint, V, Ty);
+ case Intrinsic::nearbyint:
+ return ConstantFoldFP(nearbyint, V, Ty);

I realize you're continuing an existing pattern, but I want to complain
about all of these: they will have different results when run on
different host machines. That's really not acceptable, but it's
something we've tolerated for expedience.

Can you implement these in terms of the llvm::APInt API, so that they
don't depend on the host math library?

Nick

}

if (!TLI)

llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

As discussed, I have implemented trunc, float, ceil in terms of llvm::APFloat API but for implementing rint and nearbyint, I require the knowledge of current rounding mode. Can you please suggest?
Thanks and Regards

Chakshu Grover wrote:

chakshugrover updated this revision to Diff 29891.
chakshugrover added a comment.

As discussed, I have implemented trunc, float, ceil in terms of llvm::APFloat API but for implementing rint and nearbyint, I require the knowledge of current rounding mode. Can you please suggest?

We don't support rounding modes, so assume round towards nearest.

Thanks and Regards

http://reviews.llvm.org/D11144

Files:

lib/Analysis/ConstantFolding.cpp
test/Transforms/InstCombine/intrinsics.ll

I have made all the required changes.
All ( ceil, floor, trunc, rint and nearbyint ) are now implemented using Tizen::APFloat API. Please let me know
Thanks and Regards
Chakshu

nicholas accepted this revision.Jul 21 2015, 12:48 AM
nicholas added a reviewer: nicholas.

LGTM.

Thanks for the fix to floor and ceil too.

This revision is now accepted and ready to land.Jul 21 2015, 12:48 AM
This revision was automatically updated to reflect the committed changes.