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());