[clang] [Clang] Add constexpr eval for cmath builtins (PR #194327)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 01:22:47 PDT 2026
================
@@ -700,6 +707,348 @@ static inline Floating abs(InterpState &S, const Floating &In) {
return Output;
}
+static bool interp__builtin_ceil(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const CallExpr *Call) {
+ const Floating &Val = S.Stk.pop<Floating>();
+ Floating Result = S.allocFloat(Val.getSemantics());
+ APFloat F = Val.getAPFloat();
+ unsigned BuiltinOp = Call->getBuiltinCallee();
+
+ llvm::RoundingMode RM;
+ switch (BuiltinOp) {
+ 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;
+ 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:
+ RM = llvm::RoundingMode::TowardZero;
+ break;
+ default:
+ llvm_unreachable("invalid builtin ID");
+ }
+
+ F.roundToIntegral(RM);
+ Result.copy(F);
+ S.Stk.push<Floating>(Result);
+ return true;
+}
+
+static bool interp__builtin_fdim(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const CallExpr *Call) {
+ const Floating &RHS = S.Stk.pop<Floating>();
+ const Floating &LHS = S.Stk.pop<Floating>();
+ APFloat L = LHS.getAPFloat();
+ APFloat R = RHS.getAPFloat();
+ APFloat Result(L.getSemantics());
+
+ if (L.compare(R) == APFloat::cmpGreaterThan) {
+ L.subtract(R, APFloat::rmNearestTiesToEven);
+ Result = L;
+ } else if (L.isNaN() || R.isNaN()) {
+ L.add(R, APFloat::rmNearestTiesToEven);
+ Result = L;
+ } else {
+ Result = APFloat::getZero(L.getSemantics());
+ }
+
+ Floating F = S.allocFloat(Result.getSemantics());
+ F.copy(Result);
+ S.Stk.push<Floating>(F);
+ return true;
+}
+
+static bool interp__builtin_fma(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const CallExpr *Call) {
+ const Floating &Z = S.Stk.pop<Floating>();
+ const Floating &Y = S.Stk.pop<Floating>();
+ const Floating &X = S.Stk.pop<Floating>();
+ APFloat Result = X.getAPFloat();
+
+ const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
+ llvm::RoundingMode RM = FPO.getRoundingMode();
+ if (RM == llvm::RoundingMode::Dynamic)
+ RM = llvm::RoundingMode::NearestTiesToEven;
+
+ Result.fusedMultiplyAdd(Y.getAPFloat(), Z.getAPFloat(), RM);
+ Floating F = S.allocFloat(Result.getSemantics());
+ F.copy(Result);
+ S.Stk.push<Floating>(F);
+ return true;
+}
+
+static bool interp__builtin_frexp(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const CallExpr *Call) {
+ const Pointer &Ptr = S.Stk.pop<Pointer>();
+ const Floating &Val = S.Stk.pop<Floating>();
+
+ int Exp = 0;
+ const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
+ llvm::RoundingMode RM = FPO.getRoundingMode();
+ if (RM == llvm::RoundingMode::Dynamic)
+ RM = llvm::RoundingMode::NearestTiesToEven;
+
+ APFloat F = frexp(Val.getAPFloat(), Exp, RM);
+
+ if (!Ptr.isDummy()) {
+ QualType ExpType = Call->getArg(1)->getType()->getPointeeType();
+ PrimType ExpT = *S.getContext().classify(ExpType);
+ assignInteger(S, Ptr, ExpT, APSInt::get(Exp));
+ Ptr.initialize();
+ }
+
+ Floating Result = S.allocFloat(F.getSemantics());
+ Result.copy(F);
+ S.Stk.push<Floating>(Result);
+ return true;
+}
+
+static bool interp__builtin_modf(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const CallExpr *Call) {
+ const Pointer &Ptr = S.Stk.pop<Pointer>();
+ const Floating &Val = S.Stk.pop<Floating>();
+
+ APFloat Integral = Val.getAPFloat();
+ Integral.roundToIntegral(APFloat::rmTowardZero);
+
+ if (!Ptr.isDummy()) {
+ Ptr.deref<Floating>().copy(Integral);
+ Ptr.initialize();
+ }
+
+ if (Val.getAPFloat().isInfinity()) {
----------------
Serosh-commits wrote:
done!!!
https://github.com/llvm/llvm-project/pull/194327
More information about the cfe-commits
mailing list