================
@@ -19966,6 +20024,272 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
     return true;
   }
 
+  case Builtin::BI__builtin_nearbyint:
+  case Builtin::BI__builtin_nearbyintf:
+  case Builtin::BI__builtin_nearbyintl:
+  case Builtin::BI__builtin_nearbyintf16:
+  case Builtin::BI__builtin_nearbyintf128:
+  case Builtin::BI__builtin_rint:
+  case Builtin::BI__builtin_rintf:
+  case Builtin::BI__builtin_rintl:
+  case Builtin::BI__builtin_rintf16:
+  case Builtin::BI__builtin_rintf128: {
+    if (!EvaluateFloat(E->getArg(0), Result, Info))
+      return false;
+    llvm::RoundingMode RM = getActiveRoundingMode(getEvalInfo(), E);
+    Result.roundToIntegral(RM);
+    return true;
+  }
+
+  case Builtin::BI__builtin_round:
+  case Builtin::BI__builtin_roundf:
+  case Builtin::BI__builtin_roundl:
+  case Builtin::BI__builtin_roundf16:
+  case Builtin::BI__builtin_roundf128: {
+    if (!EvaluateFloat(E->getArg(0), Result, Info))
+      return false;
+    Result.roundToIntegral(llvm::RoundingMode::NearestTiesToAway);
+    return true;
+  }
+
+  case Builtin::BI__builtin_ceil:
+  case Builtin::BI__builtin_ceilf:
+  case Builtin::BI__builtin_ceill:
+  case Builtin::BI__builtin_ceilf16:
+  case Builtin::BI__builtin_ceilf128:
+  case Builtin::BI__builtin_floor:
+  case Builtin::BI__builtin_floorf:
+  case Builtin::BI__builtin_floorl:
+  case Builtin::BI__builtin_floorf16:
+  case Builtin::BI__builtin_floorf128:
+  case Builtin::BI__builtin_trunc:
+  case Builtin::BI__builtin_truncf:
+  case Builtin::BI__builtin_truncl:
+  case Builtin::BI__builtin_truncf16:
+  case Builtin::BI__builtin_truncf128: {
+    if (!EvaluateFloat(E->getArg(0), Result, Info))
+      return false;
+    llvm::RoundingMode RM;
+    switch (E->getBuiltinCallee()) {
+    case Builtin::BI__builtin_ceil:
+    case Builtin::BI__builtin_ceilf:
+    case Builtin::BI__builtin_ceill:
+    case Builtin::BI__builtin_ceilf16:
+    case Builtin::BI__builtin_ceilf128:
+      RM = llvm::RoundingMode::TowardPositive;
+      break;
+    case Builtin::BI__builtin_floor:
+    case Builtin::BI__builtin_floorf:
+    case Builtin::BI__builtin_floorl:
+    case Builtin::BI__builtin_floorf16:
+    case Builtin::BI__builtin_floorf128:
+      RM = llvm::RoundingMode::TowardNegative;
+      break;
+    default:
+      RM = llvm::RoundingMode::TowardZero;
+      break;
+    }
+    Result.roundToIntegral(RM);
+    return true;
+  }
+
+  case Builtin::BI__builtin_fdim:
+  case Builtin::BI__builtin_fdimf:
+  case Builtin::BI__builtin_fdiml:
+  case Builtin::BI__builtin_fdimf128: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+    if (Result.compare(RHS) == APFloat::cmpGreaterThan) {
+      Result.subtract(RHS, APFloat::rmNearestTiesToEven);
+    } else if (Result.isNaN() || RHS.isNaN()) {
+      Result.add(RHS, APFloat::rmNearestTiesToEven);
+    } else {
+      Result = APFloat::getZero(Result.getSemantics());
+    }
+    return true;
+  }
+
+  case Builtin::BI__builtin_fma:
+  case Builtin::BI__builtin_fmaf:
+  case Builtin::BI__builtin_fmal:
+  case Builtin::BI__builtin_fmaf16:
+  case Builtin::BI__builtin_fmaf128: {
+    APFloat RHS(0.), Third(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info) ||
+        !EvaluateFloat(E->getArg(2), Third, Info))
+      return false;
+
+    llvm::RoundingMode RM = getActiveRoundingMode(getEvalInfo(), E);
+    Result.fusedMultiplyAdd(RHS, Third, RM);
+    return true;
+  }
+
+  case Builtin::BI__builtin_fmod:
+  case Builtin::BI__builtin_fmodf:
+  case Builtin::BI__builtin_fmodl:
+  case Builtin::BI__builtin_fmodf16:
+  case Builtin::BI__builtin_fmodf128: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+    Result.mod(RHS);
+    return true;
+  }
+
+  case Builtin::BI__builtin_remainder:
+  case Builtin::BI__builtin_remainderf:
+  case Builtin::BI__builtin_remainderl:
+  case Builtin::BI__builtin_remainderf128: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+    Result.remainder(RHS);
+    return true;
+  }
+
+  case Builtin::BI__builtin_nextafter:
+  case Builtin::BI__builtin_nextafterf:
+  case Builtin::BI__builtin_nextafterl:
+  case Builtin::BI__builtin_nextafterf128:
+  case Builtin::BI__builtin_nexttoward:
+  case Builtin::BI__builtin_nexttowardf:
+  case Builtin::BI__builtin_nexttowardl:
+  case Builtin::BI__builtin_nexttowardf128: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+
+    if (Result.isNaN())
+      return true;
+
+    if (RHS.isNaN()) {
+      bool LoseInfo = false;
+      Result = RHS;
+      Result.convert(Info.Ctx.getFloatTypeSemantics(E->getType()),
+                     APFloat::rmNearestTiesToEven, &LoseInfo);
+      return true;
+    }
+
+    APFloat ResultCopy = Result;
+    bool LoseInfo = false;
+    ResultCopy.convert(RHS.getSemantics(), APFloat::rmNearestTiesToEven,
+                       &LoseInfo);
+    APFloat::cmpResult Res = ResultCopy.compare(RHS);
+
+    if (Res == APFloat::cmpEqual)
+      return true;
+
+    Result.next(Res == APFloat::cmpGreaterThan);
+    return true;
+  }
+
+  case Builtin::BI__builtin_scalbn:
+  case Builtin::BI__builtin_scalbnf:
+  case Builtin::BI__builtin_scalbnl:
+  case Builtin::BI__builtin_scalbnf128:
+  case Builtin::BI__builtin_scalbln:
+  case Builtin::BI__builtin_scalblnf:
+  case Builtin::BI__builtin_scalblnl:
+  case Builtin::BI__builtin_scalblnf128:
+  case Builtin::BI__builtin_ldexp:
+  case Builtin::BI__builtin_ldexpf:
+  case Builtin::BI__builtin_ldexpl:
+  case Builtin::BI__builtin_ldexpf16:
+  case Builtin::BI__builtin_ldexpf128: {
+    APSInt Exp;
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateInteger(E->getArg(1), Exp, Info))
+      return false;
+
+    llvm::RoundingMode RM = getActiveRoundingMode(getEvalInfo(), E);
+    Result = scalbn(Result, Exp.getExtValue(), RM);
+    return true;
+  }
+
+  case Builtin::BI__builtin_frexp:
+  case Builtin::BI__builtin_frexpf:
+  case Builtin::BI__builtin_frexpl:
+  case Builtin::BI__builtin_frexpf16:
+  case Builtin::BI__builtin_frexpf128: {
+    LValue ExpLVal;
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluatePointer(E->getArg(1), ExpLVal, Info))
+      return false;
+
+    int Exp = 0;
+    llvm::RoundingMode RM = getActiveRoundingMode(getEvalInfo(), E);
+    Result = frexp(Result, Exp, RM);
+
+    QualType PointeeType = E->getArg(1)->getType()->getPointeeType();
+    APValue APV{APSInt(Info.Ctx.getTypeSize(PointeeType), false)};
+    APV.getInt() = Exp;
+    if (!handleAssignment(Info, E, ExpLVal, PointeeType, APV))
+      return false;
+    return true;
+  }
+
+  case Builtin::BI__builtin_modf:
+  case Builtin::BI__builtin_modff:
+  case Builtin::BI__builtin_modfl:
+  case Builtin::BI__builtin_modff128: {
+    LValue IptrLVal;
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluatePointer(E->getArg(1), IptrLVal, Info))
+      return false;
+
+    APFloat Integral = Result;
+    Integral.roundToIntegral(APFloat::rmTowardZero);
+
+    QualType PointeeType = E->getArg(1)->getType()->getPointeeType();
+    APValue APV{Integral};
+    if (!handleAssignment(Info, E, IptrLVal, PointeeType, APV))
+      return false;
+
+    if (Result.isInfinity()) {
+      Result = APFloat::getZero(Result.getSemantics(), Result.isNegative());
+    } else {
+      Result.subtract(Integral, APFloat::rmNearestTiesToEven);
+    }
+    return true;
+  }
+
+  case Builtin::BI__builtin_remquo:
+  case Builtin::BI__builtin_remquof:
+  case Builtin::BI__builtin_remquol:
+  case Builtin::BI__builtin_remquof128: {
+    APFloat RHS(0.);
+    LValue QuoLVal;
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info) ||
+        !EvaluatePointer(E->getArg(2), QuoLVal, Info))
+      return false;
+
+    APFloat Q = Result;
+    if (Q.divide(RHS, APFloat::rmNearestTiesToEven) & APFloat::opInvalidOp)
----------------
zahiraam wrote:

The divide check is incomplete. If you're going to rely on `remainder(`) to 
produce the correct result  for all error cases, why bother checking the divide 
status at all?

https://github.com/llvm/llvm-project/pull/194327
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to