[ConstantFolding] Fold calls to FP remainder function

With the fixed implementation of the "remainder" operation in
rG9d0956ebd471, we can now add support to folding calls to it.

Differential Revision: https://reviews.llvm.org/D69777
This commit is contained in:
Ehud Katz 2020-02-12 13:14:09 +02:00
parent e9900b1fbf
commit 2470d2988a
4 changed files with 79 additions and 1 deletions

View File

@ -1122,6 +1122,15 @@ TLI_DEFINE_STRING_INTERNAL("reallocf")
/// 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")

View File

@ -1518,7 +1518,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
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 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
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 @@ bool llvm::isMathLibCallNoop(const CallBase *Call,
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());

View File

@ -210,6 +210,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
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 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
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 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
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:

View File

@ -20,6 +20,58 @@ define float @f_fmodf() {
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(