diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def @@ -1122,6 +1122,15 @@ /// char *realpath(const char *file_name, char *resolved_name); TLI_DEFINE_ENUM_INTERNAL(realpath) TLI_DEFINE_STRING_INTERNAL("realpath") +/// double remainder(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(remainder) +TLI_DEFINE_STRING_INTERNAL("remainder") +/// float remainderf(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(remainderf) +TLI_DEFINE_STRING_INTERNAL("remainderf") +/// long double remainderl(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(remainderl) +TLI_DEFINE_STRING_INTERNAL("remainderl") /// int remove(const char *path); TLI_DEFINE_ENUM_INTERNAL(remove) TLI_DEFINE_STRING_INTERNAL("remove") diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1518,7 +1518,8 @@ case 'p': return Name == "pow" || Name == "powf"; case 'r': - return Name == "rint" || Name == "rintf" || + return Name == "remainder" || Name == "remainderf" || + Name == "rint" || Name == "rintf" || Name == "round" || Name == "roundf"; case 's': return Name == "sin" || Name == "sinf" || @@ -2098,6 +2099,14 @@ return ConstantFP::get(Ty->getContext(), V); } break; + case LibFunc_remainder: + case LibFunc_remainderf: + if (TLI->has(Func)) { + APFloat V = Op1->getValueAPF(); + if (APFloat::opStatus::opOK == V.remainder(Op2->getValueAPF())) + return ConstantFP::get(Ty->getContext(), V); + } + break; case LibFunc_atan2: case LibFunc_atan2f: case LibFunc_atan2_finite: @@ -2632,6 +2641,9 @@ case LibFunc_fmodl: case LibFunc_fmod: case LibFunc_fmodf: + case LibFunc_remainderl: + case LibFunc_remainder: + case LibFunc_remainderf: return Op0.isNaN() || Op1.isNaN() || (!Op0.isInfinity() && !Op1.isZero()); diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -210,6 +210,7 @@ TLI.setUnavailable(LibFunc_logf); TLI.setUnavailable(LibFunc_modff); TLI.setUnavailable(LibFunc_powf); + TLI.setUnavailable(LibFunc_remainderf); TLI.setUnavailable(LibFunc_sinf); TLI.setUnavailable(LibFunc_sinhf); TLI.setUnavailable(LibFunc_sqrtf); @@ -239,6 +240,7 @@ TLI.setUnavailable(LibFunc_logl); TLI.setUnavailable(LibFunc_modfl); TLI.setUnavailable(LibFunc_powl); + TLI.setUnavailable(LibFunc_remainderl); TLI.setUnavailable(LibFunc_sinl); TLI.setUnavailable(LibFunc_sinhl); TLI.setUnavailable(LibFunc_sqrtl); @@ -1379,6 +1381,9 @@ case LibFunc_fmod: case LibFunc_fmodf: case LibFunc_fmodl: + case LibFunc_remainder: + case LibFunc_remainderf: + case LibFunc_remainderl: case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: diff --git a/llvm/test/Analysis/ConstantFolding/math-2.ll b/llvm/test/Analysis/ConstantFolding/math-2.ll --- a/llvm/test/Analysis/ConstantFolding/math-2.ll +++ b/llvm/test/Analysis/ConstantFolding/math-2.ll @@ -20,6 +20,58 @@ ret float %res } +declare float @remainderf(float, float) +define float @f_remainderf_fold1() { +; CHECK-LABEL: @f_remainderf_fold1( +; CHECK-NEXT: ret float 1.000000e+00 +; + %res = tail call fast float @remainderf(float 1.0, float 2.0) + ret float %res +} + +define float @f_remainderf_fold2() { +; CHECK-LABEL: @f_remainderf_fold2( +; CHECK-NEXT: ret float -5.000000e-01 +; + %res = tail call fast float @remainderf(float 1.5, float 1.0) + ret float %res +} + +define float @f_remainderf_nofold() { +; CHECK-LABEL: @f_remainderf_nofold( +; CHECK-NEXT: [[RES:%.*]] = tail call fast float @remainderf(float 1.000000e+00, float 0.000000e+00) +; CHECK-NEXT: ret float [[RES]] +; + %res = tail call fast float @remainderf(float 1.0, float 0.0) + ret float %res +} + +declare double @remainder(double, double) +define double @f_remainder_fold1() { +; CHECK-LABEL: @f_remainder_fold1( +; CHECK-NEXT: ret double 1.000000e+00 +; + %res = tail call fast double @remainder(double 1.0, double 2.0) + ret double %res +} + +define double @f_remainder_fold2() { +; CHECK-LABEL: @f_remainder_fold2( +; CHECK-NEXT: ret double -5.000000e-01 +; + %res = tail call fast double @remainder(double 1.5, double 1.0) + ret double %res +} + +define double @f_remainder_nofold() { +; CHECK-LABEL: @f_remainder_nofold( +; CHECK-NEXT: [[RES:%.*]] = tail call fast double @remainder(double 1.000000e+00, double 0.000000e+00) +; CHECK-NEXT: ret double [[RES]] +; + %res = tail call fast double @remainder(double 1.0, double 0.0) + ret double %res +} + declare double @pow(double, double) define double @f_pow() { ; CHECK-LABEL: @f_pow(