Commit 2470d298 authored by Ehud Katz's avatar Ehud Katz
Browse files

[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
parent e9900b1f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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")
+13 −1
Original line number Diff line number Diff line
@@ -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());

+5 −0
Original line number Diff line number Diff line
@@ -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:
+52 −0
Original line number Diff line number Diff line
@@ -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(