Index: llvm/include/llvm/Analysis/TargetLibraryInfo.def =================================================================== --- llvm/include/llvm/Analysis/TargetLibraryInfo.def +++ llvm/include/llvm/Analysis/TargetLibraryInfo.def @@ -1119,6 +1119,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") Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -1515,7 +1515,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" || @@ -2095,6 +2096,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: @@ -2624,6 +2633,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()); Index: llvm/lib/Analysis/TargetLibraryInfo.cpp =================================================================== --- llvm/lib/Analysis/TargetLibraryInfo.cpp +++ llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -209,6 +209,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); @@ -238,6 +239,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); @@ -1375,6 +1377,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: Index: llvm/test/Analysis/ConstantFolding/math-2.ll =================================================================== --- llvm/test/Analysis/ConstantFolding/math-2.ll +++ llvm/test/Analysis/ConstantFolding/math-2.ll @@ -20,6 +20,15 @@ ret float %res } +declare float @remainderf(float, float) +define float @f_remainderf() { +; CHECK-LABEL: @f_remainderf( +; CHECK-NEXT: ret float 1.000000e+00 +; + %res = tail call fast float @remainderf(float 1.0, float 2.0) + ret float %res +} + declare double @pow(double, double) define double @f_pow() { ; CHECK-LABEL: @f_pow(