From 08df6e64d5700d9469358ecfa4bdb46073116529 Mon Sep 17 00:00:00 2001 From: Evandro Menezes Date: Thu, 12 Sep 2019 21:23:22 +0000 Subject: [PATCH] [ConstantFolding] Expand folding of some library functions Expanding the folding of `nearbyint()`, `rint()` and `trunc()` to library functions, in addition to the current support for intrinsics. Differential revision: https://reviews.llvm.org/D67468 llvm-svn: 371774 --- llvm/lib/Analysis/ConstantFolding.cpp | 25 ++++- llvm/test/Analysis/ConstantFolding/rint.ll | 109 +++++++++++++++++++++ .../ConstantFolding}/round.ll | 16 +-- llvm/test/Analysis/ConstantFolding/trunc.ll | 105 ++++++++++++++++++++ 4 files changed, 245 insertions(+), 10 deletions(-) create mode 100644 llvm/test/Analysis/ConstantFolding/rint.ll rename llvm/test/{Transforms/InstCombine => Analysis/ConstantFolding}/round.ll (86%) create mode 100644 llvm/test/Analysis/ConstantFolding/trunc.ll diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 9c92616..7b3d815 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1491,17 +1491,21 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) { case 'l': return Name == "log" || Name == "logf" || Name == "log10" || Name == "log10f"; + case 'n': + return Name == "nearbyint" || Name == "nearbyintf"; case 'p': return Name == "pow" || Name == "powf"; case 'r': - return Name == "round" || Name == "roundf"; + return Name == "rint" || Name == "rintf" || + Name == "round" || Name == "roundf"; case 's': return Name == "sin" || Name == "sinf" || Name == "sinh" || Name == "sinhf" || Name == "sqrt" || Name == "sqrtf"; case 't': return Name == "tan" || Name == "tanf" || - Name == "tanh" || Name == "tanhf"; + Name == "tanh" || Name == "tanhf" || + Name == "trunc" || Name == "truncf"; case '_': // Check for various function names that get used for the math functions // when the header files are preprocessed with the macro @@ -1863,7 +1867,6 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, break; case LibFunc_log: case LibFunc_logf: - case LibFunc_log_finite: case LibFunc_logf_finite: if (V > 0.0 && TLI->has(Func)) @@ -1877,6 +1880,15 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, // TODO: What about hosts that lack a C99 library? return ConstantFoldFP(log10, V, Ty); break; + case LibFunc_nearbyint: + case LibFunc_nearbyintf: + case LibFunc_rint: + case LibFunc_rintf: + if (TLI->has(Func)) { + U.roundToIntegral(APFloat::rmNearestTiesToEven); + return ConstantFP::get(Ty->getContext(), U); + } + break; case LibFunc_round: case LibFunc_roundf: if (TLI->has(Func)) { @@ -1911,6 +1923,13 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, if (TLI->has(Func)) return ConstantFoldFP(tanh, V, Ty); break; + case LibFunc_trunc: + case LibFunc_truncf: + if (TLI->has(Func)) { + U.roundToIntegral(APFloat::rmTowardZero); + return ConstantFP::get(Ty->getContext(), U); + } + break; } return nullptr; } diff --git a/llvm/test/Analysis/ConstantFolding/rint.ll b/llvm/test/Analysis/ConstantFolding/rint.ll new file mode 100644 index 0000000..9ad794d --- /dev/null +++ b/llvm/test/Analysis/ConstantFolding/rint.ll @@ -0,0 +1,109 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -early-cse < %s | FileCheck %s + +declare float @nearbyintf(float) #0 +declare float @llvm.nearbyint.f32(float) #0 +declare double @nearbyint(double) #0 +declare double @llvm.nearbyint.f64(double) #0 +declare float @rintf(float) #0 +declare float @llvm.rint.f32(float) #0 +declare double @rint(double) #0 +declare double @llvm.rint.f64(double) #0 + +define float @constant_fold_rint_f32_01() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_01( +; CHECK-NEXT: ret float 1.000000e+00 +; + %x = call float @nearbyintf(float 1.25) #0 + ret float %x +} + +define float @constant_fold_rint_f32_02() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_02( +; CHECK-NEXT: ret float -1.000000e+00 +; + %x = call float @llvm.nearbyint.f32(float -1.25) #0 + ret float %x +} + +define float @constant_fold_rint_f32_03() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_03( +; CHECK-NEXT: ret float 2.000000e+00 +; + %x = call float @rintf(float 1.5) #0 + ret float %x +} + +define float @constant_fold_rint_f32_04() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_04( +; CHECK-NEXT: ret float -2.000000e+00 +; + %x = call float @llvm.rint.f32(float -1.5) #0 + ret float %x +} + +define float @constant_fold_rint_f32_05() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_05( +; CHECK-NEXT: ret float 3.000000e+00 +; + %x = call float @nearbyintf(float 2.75) #0 + ret float %x +} + +define float @constant_fold_rint_f32_06() #0 { +; CHECK-LABEL: @constant_fold_rint_f32_06( +; CHECK-NEXT: ret float -3.000000e+00 +; + %x = call float @llvm.nearbyint.f32(float -2.75) #0 + ret float %x +} + +define double @constant_fold_rint_f64_01() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_01( +; CHECK-NEXT: ret double 1.000000e+00 +; + %x = call double @rint(double 1.3) #0 + ret double %x +} + +define double @constant_fold_rint_f64_02() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_02( +; CHECK-NEXT: ret double -1.000000e+00 +; + %x = call double @llvm.rint.f64(double -1.3) #0 + ret double %x +} + +define double @constant_fold_rint_f64_03() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_03( +; CHECK-NEXT: ret double 2.000000e+00 +; + %x = call double @nearbyint(double 1.5) #0 + ret double %x +} + +define double @constant_fold_rint_f64_04() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_04( +; CHECK-NEXT: ret double -2.000000e+00 +; + %x = call double @llvm.nearbyint.f64(double -1.5) #0 + ret double %x +} + +define double @constant_fold_rint_f64_05() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_05( +; CHECK-NEXT: ret double 3.000000e+00 +; + %x = call double @rint(double 2.7) #0 + ret double %x +} + +define double @constant_fold_rint_f64_06() #0 { +; CHECK-LABEL: @constant_fold_rint_f64_06( +; CHECK-NEXT: ret double -3.000000e+00 +; + %x = call double @llvm.rint.f64(double -2.7) #0 + ret double %x +} + +attributes #0 = { nounwind readnone } diff --git a/llvm/test/Transforms/InstCombine/round.ll b/llvm/test/Analysis/ConstantFolding/round.ll similarity index 86% rename from llvm/test/Transforms/InstCombine/round.ll rename to llvm/test/Analysis/ConstantFolding/round.ll index ecc62dd..d5b8478 100644 --- a/llvm/test/Transforms/InstCombine/round.ll +++ b/llvm/test/Analysis/ConstantFolding/round.ll @@ -1,12 +1,14 @@ -; RUN: opt -S -instcombine < %s | FileCheck %s +; RUN: opt -S -early-cse < %s | FileCheck %s +declare float @roundf(float) #0 declare float @llvm.round.f32(float) #0 +declare double @round(double) #0 declare double @llvm.round.f64(double) #0 ; CHECK-LABEL: @constant_fold_round_f32_01 ; CHECK-NEXT: ret float 1.000000e+00 define float @constant_fold_round_f32_01() #0 { - %x = call float @llvm.round.f32(float 1.25) #0 + %x = call float @roundf(float 1.25) #0 ret float %x } @@ -20,7 +22,7 @@ define float @constant_fold_round_f32_02() #0 { ; CHECK-LABEL: @constant_fold_round_f32_03 ; CHECK-NEXT: ret float 2.000000e+00 define float @constant_fold_round_f32_03() #0 { - %x = call float @llvm.round.f32(float 1.5) #0 + %x = call float @roundf(float 1.5) #0 ret float %x } @@ -34,7 +36,7 @@ define float @constant_fold_round_f32_04() #0 { ; CHECK-LABEL: @constant_fold_round_f32_05 ; CHECK-NEXT: ret float 3.000000e+00 define float @constant_fold_round_f32_05() #0 { - %x = call float @llvm.round.f32(float 2.75) #0 + %x = call float @roundf(float 2.75) #0 ret float %x } @@ -48,7 +50,7 @@ define float @constant_fold_round_f32_06() #0 { ; CHECK-LABEL: @constant_fold_round_f64_01 ; CHECK-NEXT: ret double 1.000000e+00 define double @constant_fold_round_f64_01() #0 { - %x = call double @llvm.round.f64(double 1.3) #0 + %x = call double @round(double 1.3) #0 ret double %x } @@ -62,7 +64,7 @@ define double @constant_fold_round_f64_02() #0 { ; CHECK-LABEL: @constant_fold_round_f64_03 ; CHECK-NEXT: ret double 2.000000e+00 define double @constant_fold_round_f64_03() #0 { - %x = call double @llvm.round.f64(double 1.5) #0 + %x = call double @round(double 1.5) #0 ret double %x } @@ -76,7 +78,7 @@ define double @constant_fold_round_f64_04() #0 { ; CHECK-LABEL: @constant_fold_round_f64_05 ; CHECK-NEXT: ret double 3.000000e+00 define double @constant_fold_round_f64_05() #0 { - %x = call double @llvm.round.f64(double 2.7) #0 + %x = call double @round(double 2.7) #0 ret double %x } diff --git a/llvm/test/Analysis/ConstantFolding/trunc.ll b/llvm/test/Analysis/ConstantFolding/trunc.ll new file mode 100644 index 0000000..df13809 --- /dev/null +++ b/llvm/test/Analysis/ConstantFolding/trunc.ll @@ -0,0 +1,105 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -early-cse < %s | FileCheck %s + +declare float @truncf(float) #0 +declare float @llvm.trunc.f32(float) #0 +declare double @trunc(double) #0 +declare double @llvm.trunc.f64(double) #0 + +define float @constant_fold_trunc_f32_01() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_01( +; CHECK-NEXT: ret float 1.000000e+00 +; + %x = call float @truncf(float 1.25) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_02() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_02( +; CHECK-NEXT: ret float -1.000000e+00 +; + %x = call float @llvm.trunc.f32(float -1.25) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_03() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_03( +; CHECK-NEXT: ret float 1.000000e+00 +; + %x = call float @truncf(float 1.5) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_04() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_04( +; CHECK-NEXT: ret float -1.000000e+00 +; + %x = call float @llvm.trunc.f32(float -1.5) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_05() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_05( +; CHECK-NEXT: ret float 2.000000e+00 +; + %x = call float @truncf(float 2.75) #0 + ret float %x +} + +define float @constant_fold_trunc_f32_06() #0 { +; CHECK-LABEL: @constant_fold_trunc_f32_06( +; CHECK-NEXT: ret float -2.000000e+00 +; + %x = call float @llvm.trunc.f32(float -2.75) #0 + ret float %x +} + +define double @constant_fold_trunc_f64_01() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_01( +; CHECK-NEXT: ret double 1.000000e+00 +; + %x = call double @trunc(double 1.3) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_02() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_02( +; CHECK-NEXT: ret double -1.000000e+00 +; + %x = call double @llvm.trunc.f64(double -1.3) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_03() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_03( +; CHECK-NEXT: ret double 1.000000e+00 +; + %x = call double @trunc(double 1.5) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_04() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_04( +; CHECK-NEXT: ret double -1.000000e+00 +; + %x = call double @llvm.trunc.f64(double -1.5) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_05() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_05( +; CHECK-NEXT: ret double 2.000000e+00 +; + %x = call double @trunc(double 2.7) #0 + ret double %x +} + +define double @constant_fold_trunc_f64_06() #0 { +; CHECK-LABEL: @constant_fold_trunc_f64_06( +; CHECK-NEXT: ret double -2.000000e+00 +; + %x = call double @llvm.trunc.f64(double -2.7) #0 + ret double %x +} + +attributes #0 = { nounwind readnone } -- 2.7.4