https://github.com/Serosh-commits updated 
https://github.com/llvm/llvm-project/pull/194327

>From 3bb020cd4fc050fb27fb043bc113beb002176a02 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Mon, 27 Apr 2026 01:55:47 +0530
Subject: [PATCH 1/6] [Clang] Add constexpr eval for cmath builtins

Enable compile-time evaluation of math builtins like ceil, floor,
fmod, fma, frexp, ilogb, nextafter, scalbn, etc. in both the AST
evaluator and the bytecode interpreter.
---
 clang/include/clang/Basic/Builtins.td         |  77 ++-
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      | 469 ++++++++++++++++++
 clang/lib/AST/ExprConstant.cpp                | 327 ++++++++++++
 .../test/SemaCXX/constexpr-cmath-builtins.cpp | 187 +++++++
 4 files changed, 1033 insertions(+), 27 deletions(-)
 create mode 100644 clang/test/SemaCXX/constexpr-cmath-builtins.cpp

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index b8bbc544595e2..c0e37ab77220e 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -133,7 +133,7 @@ def CbrtF128 : Builtin {
 
 def CeilF16F128 : Builtin, F16F128MathTemplate {
   let Spellings = ["__builtin_ceil"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
   let Prototype = "T(T)";
 }
 
@@ -187,19 +187,19 @@ def Expm1F128 : Builtin {
 
 def FdimF128 : Builtin {
   let Spellings = ["__builtin_fdimf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "__float128(__float128, __float128)";
 }
 
 def FloorF16F128 : Builtin, F16F128MathTemplate {
   let Spellings = ["__builtin_floor"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
   let Prototype = "T(T)";
 }
 
 def FmaF16F128 : Builtin, F16F128MathTemplate {
   let Spellings = ["__builtin_fma"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "T(T, T, T)";
 }
 
@@ -259,13 +259,13 @@ def FabsF128 : Builtin {
 
 def FmodF16F128 : F16F128MathTemplate, Builtin {
   let Spellings = ["__builtin_fmod"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "T(T, T)";
 }
 
 def FrexpF16F128 : F16F128MathTemplate, Builtin {
   let Spellings = ["__builtin_frexp"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "T(T, int*)";
 }
 
@@ -295,13 +295,13 @@ def InfF16 : Builtin {
 
 def LdexpF16F128 : F16F128MathTemplate, Builtin {
   let Spellings = ["__builtin_ldexp"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "T(T, int)";
 }
 
 def ModfF128 : Builtin {
   let Spellings = ["__builtin_modff128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Constexpr];
   let Prototype = "__float128(__float128, __float128*)";
 }
 
@@ -347,7 +347,7 @@ def HypotF128 : Builtin {
 
 def ILogbF128 : Builtin {
   let Spellings = ["__builtin_ilogbf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "int(__float128)";
 }
 
@@ -359,13 +359,13 @@ def LgammaF128 : Builtin {
 
 def LLrintF128 : Builtin {
   let Spellings = ["__builtin_llrintf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "long long int(__float128)";
 }
 
 def LLroundF128 : Builtin {
   let Spellings = ["__builtin_llroundf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "long long int(__float128)";
 }
 
@@ -401,55 +401,55 @@ def LogF16F128 : Builtin, F16F128MathTemplate {
 
 def LrintF128 : Builtin {
   let Spellings = ["__builtin_lrintf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "long int(__float128)";
 }
 
 def LroundF128 : Builtin {
   let Spellings = ["__builtin_lroundf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "long int(__float128)";
 }
 
-def NearbyintF128 : Builtin {
-  let Spellings = ["__builtin_nearbyintf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
-  let Prototype = "__float128(__float128)";
+def NearbyintF16F128 : Builtin, F16F128MathTemplate {
+  let Spellings = ["__builtin_nearbyint"];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
+  let Prototype = "T(T)";
 }
 
 def NextafterF128 : Builtin {
   let Spellings = ["__builtin_nextafterf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "__float128(__float128, __float128)";
 }
 
 def NexttowardF128 : Builtin {
   let Spellings = ["__builtin_nexttowardf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "__float128(__float128, __float128)";
 }
 
 def RemainderF128 : Builtin {
   let Spellings = ["__builtin_remainderf128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, 
ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "__float128(__float128, __float128)";
 }
 
 def RemquoF128 : Builtin {
   let Spellings = ["__builtin_remquof128"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Constexpr];
   let Prototype = "__float128(__float128, __float128, int*)";
 }
 
 def RintF16F128 : Builtin, F16F128MathTemplate {
   let Spellings = ["__builtin_rint"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
   let Prototype = "T(T)";
 }
 
 def RoundF16F128 : Builtin, F16F128MathTemplate {
   let Spellings = ["__builtin_round"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
   let Prototype = "T(T)";
 }
 
@@ -462,14 +462,14 @@ def RoundevenF16F128 : Builtin, F16F128MathTemplate {
 def ScanlblnF128 : Builtin {
   let Spellings = ["__builtin_scalblnf128"];
   let Attributes = [FunctionWithBuiltinPrefix, NoThrow,
-                    ConstIgnoringErrnoAndExceptions];
+                    ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "__float128(__float128, long int)";
 }
 
 def ScanlbnF128 : Builtin {
   let Spellings = ["__builtin_scalbnf128"];
   let Attributes = [FunctionWithBuiltinPrefix, NoThrow,
-                    ConstIgnoringErrnoAndExceptions];
+                    ConstIgnoringErrnoAndExceptions, Constexpr];
   let Prototype = "__float128(__float128, int)";
 }
 
@@ -517,7 +517,7 @@ def TgammaF128 : Builtin {
 
 def TruncF16F128 : Builtin, F16F128MathTemplate {
   let Spellings = ["__builtin_trunc"];
-  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
   let Prototype = "T(T)";
 }
 
@@ -3796,6 +3796,7 @@ def Fmod : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Frexp : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -3803,6 +3804,7 @@ def Frexp : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow];
   let Prototype = "T(T, int*)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Sincos : FPMathTemplate, GNULibBuiltin<"math.h"> {
@@ -3823,6 +3825,7 @@ def Ldexp : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, int)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Modf : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -3830,6 +3833,7 @@ def Modf : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow];
   let Prototype = "T(T, T*)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Nan : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -3901,6 +3905,7 @@ def Ceil : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, Const];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Cos : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -3965,6 +3970,7 @@ def Fdim : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Floor : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -3972,6 +3978,7 @@ def Floor : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, Const];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Fma : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -3979,6 +3986,7 @@ def Fma : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, T, T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Fmax : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4025,6 +4033,7 @@ def Ilogb : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "int(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Lgamma : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4039,6 +4048,7 @@ def Llrint : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "long long int(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Llround : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4046,6 +4056,7 @@ def Llround : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "long long int(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Log : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4088,6 +4099,7 @@ def Lrint : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "long int(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Lround : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4095,13 +4107,15 @@ def Lround : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "long int(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Nearbyint : FPMathTemplate, LibBuiltin<"math.h"> {
   let Spellings = ["nearbyint"];
-  let Attributes = [NoThrow, Const];
+  let Attributes = [NoThrow, Const, Constexpr];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Nextafter : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4109,6 +4123,7 @@ def Nextafter : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Nexttoward : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4116,6 +4131,7 @@ def Nexttoward : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, long double)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Remainder : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4123,6 +4139,7 @@ def Remainder : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Remquo : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4130,6 +4147,7 @@ def Remquo : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow];
   let Prototype = "T(T, T, int*)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Rint : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4137,6 +4155,7 @@ def Rint : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringExceptions];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Round : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4144,6 +4163,7 @@ def Round : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, Const];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def RoundEven : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4158,6 +4178,7 @@ def Scalbln : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, long int)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Scalbn : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4165,6 +4186,7 @@ def Scalbn : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
   let Prototype = "T(T, int)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Sin : FPMathTemplate, LibBuiltin<"math.h"> {
@@ -4214,6 +4236,7 @@ def Trunc : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, Const];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Cabs : FPMathTemplate, LibBuiltin<"complex.h"> {
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index e7b3ef6ce1510..bce535cc6f0f5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -707,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()) {
+    Floating Fraction = S.allocFloat(Val.getAPFloat().getSemantics());
+    Fraction.copy(APFloat::getZero(Val.getAPFloat().getSemantics(), 
Val.getAPFloat().isNegative()));
+    S.Stk.push<Floating>(Fraction);
+    return true;
+  }
+
+  APFloat Fraction = Val.getAPFloat();
+  Fraction.subtract(Integral, APFloat::rmNearestTiesToEven);
+
+  Floating Result = S.allocFloat(Fraction.getSemantics());
+  Result.copy(Fraction);
+  S.Stk.push<Floating>(Result);
+  return true;
+}
+
+static bool interp__builtin_fmod(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();
+  unsigned BuiltinOp = Call->getBuiltinCallee();
+
+  if (BuiltinOp == Builtin::BI__builtin_remainder ||
+      BuiltinOp == Builtin::BI__builtin_remainderf ||
+      BuiltinOp == Builtin::BI__builtin_remainderl ||
+      BuiltinOp == Builtin::BI__builtin_remainderf128)
+    L.remainder(RHS.getAPFloat());
+  else
+    L.mod(RHS.getAPFloat());
+
+  Floating F = S.allocFloat(L.getSemantics());
+  F.copy(L);
+  S.Stk.push<Floating>(F);
+  return true;
+}
+
+static bool interp__builtin_nextafter(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();
+
+  if (L.isNaN()) {
+    S.Stk.push<Floating>(LHS);
+    return true;
+  }
+
+  if (R.isNaN()) {
+    bool LoseInfo = false;
+    L = R;
+    L.convert(LHS.getSemantics(), APFloat::rmNearestTiesToEven, &LoseInfo);
+    Floating Result = S.allocFloat(L.getSemantics());
+    Result.copy(L);
+    S.Stk.push<Floating>(Result);
+    return true;
+  }
+
+  APFloat LCopy = L;
+  bool LoseInfo = false;
+  LCopy.convert(R.getSemantics(), APFloat::rmNearestTiesToEven, &LoseInfo);
+  APFloat::cmpResult Res = LCopy.compare(R);
+
+  if (Res != APFloat::cmpEqual)
+    L.next(Res == APFloat::cmpGreaterThan);
+
+  Floating Result = S.allocFloat(L.getSemantics());
+  Result.copy(L);
+  S.Stk.push<Floating>(Result);
+  return true;
+}
+
+static bool interp__builtin_scalbn(InterpState &S, CodePtr OpPC,
+                                   const InterpFrame *Frame,
+                                   const CallExpr *Call) {
+  PrimType ExpT = *S.getContext().classify(Call->getArg(1)->getType());
+  APSInt Exp = popToAPSInt(S.Stk, ExpT);
+  const Floating &Val = S.Stk.pop<Floating>();
+
+  const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
+  llvm::RoundingMode RM = FPO.getRoundingMode();
+  if (RM == llvm::RoundingMode::Dynamic)
+    RM = llvm::RoundingMode::NearestTiesToEven;
+
+  Floating Result = S.allocFloat(Val.getSemantics());
+  Result.copy(scalbn(Val.getAPFloat(), (int)Exp.getExtValue(), RM));
+  S.Stk.push<Floating>(Result);
+  return true;
+}
+
+static bool interp__builtin_ilogb(InterpState &S, CodePtr OpPC,
+                                  const InterpFrame *Frame,
+                                  const CallExpr *Call) {
+  const Floating &Val = S.Stk.pop<Floating>();
+  if (Val.getAPFloat().isZero() || Val.getAPFloat().isNaN()) {
+    pushInteger(S, -2147483648LL, Call->getType());
+    return true;
+  }
+  pushInteger(S, ilogb(Val.getAPFloat()), Call->getType());
+  return true;
+}
+
+static bool interp__builtin_remquo(InterpState &S, CodePtr OpPC,
+                                   const InterpFrame *Frame,
+                                   const CallExpr *Call) {
+  const Pointer &Ptr = S.Stk.pop<Pointer>();
+  const Floating &RHS = S.Stk.pop<Floating>();
+  const Floating &LHS = S.Stk.pop<Floating>();
+
+  APFloat Q = LHS.getAPFloat();
+  if (Q.divide(RHS.getAPFloat(), APFloat::rmNearestTiesToEven) & 
APFloat::opInvalidOp)
+    Q = APFloat::getZero(Q.getSemantics());
+  else
+    Q.roundToIntegral(APFloat::rmNearestTiesToEven);
+
+  if (!Ptr.isDummy()) {
+    QualType QuoType = Call->getArg(2)->getType()->getPointeeType();
+    APSInt QuoInt(S.getASTContext().getTypeSize(QuoType), false);
+    bool IsExact = false;
+    Q.convertToInteger(QuoInt, APFloat::rmTowardZero, &IsExact);
+
+    PrimType QuoT = *S.getContext().classify(QuoType);
+    assignInteger(S, Ptr, QuoT, QuoInt);
+    Ptr.initialize();
+  }
+
+  APFloat R = LHS.getAPFloat();
+  R.remainder(RHS.getAPFloat());
+  Floating Result = S.allocFloat(R.getSemantics());
+  Result.copy(R);
+  S.Stk.push<Floating>(Result);
+  return true;
+}
+
+static bool interp__builtin_round(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();
+
+  F.roundToIntegral(llvm::RoundingMode::NearestTiesToAway);
+  Result.copy(F);
+  S.Stk.push<Floating>(Result);
+  return true;
+}
+
+static bool interp__builtin_lrint(InterpState &S, CodePtr OpPC,
+                                  const InterpFrame *Frame,
+                                  const CallExpr *Call) {
+  const Floating &Val = S.Stk.pop<Floating>();
+  APFloat F = Val.getAPFloat();
+  unsigned BuiltinOp = Call->getBuiltinCallee();
+
+  llvm::RoundingMode RM;
+  switch (BuiltinOp) {
+  case Builtin::BI__builtin_lround:
+  case Builtin::BI__builtin_lroundf:
+  case Builtin::BI__builtin_lroundl:
+  case Builtin::BI__builtin_lroundf128:
+  case Builtin::BI__builtin_llround:
+  case Builtin::BI__builtin_llroundf:
+  case Builtin::BI__builtin_llroundl:
+  case Builtin::BI__builtin_llroundf128:
+    RM = llvm::RoundingMode::NearestTiesToAway;
+    break;
+  default: {
+    const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
+    RM = FPO.getRoundingMode();
+    if (RM == llvm::RoundingMode::Dynamic)
+      RM = llvm::RoundingMode::NearestTiesToEven;
+    break;
+  }
+  }
+
+  F.roundToIntegral(RM);
+
+  APSInt IntVal(S.getASTContext().getTypeSize(Call->getType()),
+               Call->getType()->isUnsignedIntegerOrEnumerationType());
+  bool IsExact = false;
+  APFloat::opStatus Status = F.convertToInteger(IntVal, RM, &IsExact);
+
+  if (Status & APFloat::opInvalidOp) {
+    if (S.diagnosing()) {
+      auto Loc = S.Current->getSource(OpPC);
+      S.CCEDiag(Loc, diag::note_constexpr_float_arithmetic)
+          << (F.isNaN() ? 1 : 0);
+    }
+  }
+
+  pushInteger(S, IntVal, Call->getType());
+  return true;
+}
+
+static bool interp__builtin_nearbyint(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();
+
+  const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
+  llvm::RoundingMode RM = FPO.getRoundingMode();
+  if (RM == llvm::RoundingMode::Dynamic)
+    RM = llvm::RoundingMode::NearestTiesToEven;
+
+  F.roundToIntegral(RM);
+  Result.copy(F);
+  S.Stk.push<Floating>(Result);
+  return true;
+}
+
 // The C standard says "fabs raises no floating-point exceptions,
 // even if x is a signaling NaN. The returned value is independent of
 // the current rounding direction mode."  Therefore constant folding can
@@ -4300,6 +4642,133 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const CallExpr *Call,
   case Builtin::BI__builtin_issubnormal:
     return interp__builtin_issubnormal(S, OpPC, Frame, Call);
 
+  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:
+    return interp__builtin_nearbyint(S, OpPC, Frame, Call);
+
+  case Builtin::BI__builtin_lrint:
+  case Builtin::BI__builtin_lrintf:
+  case Builtin::BI__builtin_lrintl:
+  case Builtin::BI__builtin_lrintf128:
+  case Builtin::BI__builtin_llrint:
+  case Builtin::BI__builtin_llrintf:
+  case Builtin::BI__builtin_llrintl:
+  case Builtin::BI__builtin_llrintf128:
+  case Builtin::BI__builtin_lround:
+  case Builtin::BI__builtin_lroundf:
+  case Builtin::BI__builtin_lroundl:
+  case Builtin::BI__builtin_lroundf128:
+  case Builtin::BI__builtin_llround:
+  case Builtin::BI__builtin_llroundf:
+  case Builtin::BI__builtin_llroundl:
+  case Builtin::BI__builtin_llroundf128:
+    return interp__builtin_lrint(S, OpPC, Frame, Call);
+
+  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:
+    return interp__builtin_ceil(S, OpPC, Frame, Call);
+
+  case Builtin::BI__builtin_fdim:
+  case Builtin::BI__builtin_fdimf:
+  case Builtin::BI__builtin_fdiml:
+  case Builtin::BI__builtin_fdimf128:
+    return interp__builtin_fdim(S, OpPC, Frame, Call);
+
+  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:
+    return interp__builtin_frexp(S, OpPC, Frame, Call);
+
+  case Builtin::BI__builtin_modf:
+  case Builtin::BI__builtin_modff:
+  case Builtin::BI__builtin_modfl:
+  case Builtin::BI__builtin_modff128:
+    return interp__builtin_modf(S, OpPC, Frame, Call);
+
+  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:
+    return interp__builtin_fma(S, OpPC, Frame, Call);
+
+  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:
+  case Builtin::BI__builtin_remainder:
+  case Builtin::BI__builtin_remainderf:
+  case Builtin::BI__builtin_remainderf128:
+    return interp__builtin_fmod(S, OpPC, Frame, Call);
+
+  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:
+    return interp__builtin_nextafter(S, OpPC, Frame, Call);
+
+  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:
+    return interp__builtin_scalbn(S, OpPC, Frame, Call);
+
+  case Builtin::BI__builtin_ilogb:
+  case Builtin::BI__builtin_ilogbf:
+  case Builtin::BI__builtin_ilogbl:
+  case Builtin::BI__builtin_ilogbf128:
+    return interp__builtin_ilogb(S, OpPC, Frame, Call);
+
+  case Builtin::BI__builtin_remquo:
+  case Builtin::BI__builtin_remquof:
+  case Builtin::BI__builtin_remquol:
+  case Builtin::BI__builtin_remquof128:
+    return interp__builtin_remquo(S, OpPC, Frame, Call);
+
+  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:
+    return interp__builtin_round(S, OpPC, Frame, Call);
+
   case Builtin::BI__builtin_iszero:
     return interp__builtin_iszero(S, OpPC, Frame, Call);
 
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4f45fa728c605..9b89f7997b133 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16275,6 +16275,57 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
   };
 
   switch (BuiltinOp) {
+  case Builtin::BI__builtin_lrint:
+  case Builtin::BI__builtin_lrintf:
+  case Builtin::BI__builtin_lrintl:
+  case Builtin::BI__builtin_lrintf128:
+  case Builtin::BI__builtin_llrint:
+  case Builtin::BI__builtin_llrintf:
+  case Builtin::BI__builtin_llrintl:
+  case Builtin::BI__builtin_llrintf128:
+  case Builtin::BI__builtin_lround:
+  case Builtin::BI__builtin_lroundf:
+  case Builtin::BI__builtin_lroundl:
+  case Builtin::BI__builtin_lroundf128:
+  case Builtin::BI__builtin_llround:
+  case Builtin::BI__builtin_llroundf:
+  case Builtin::BI__builtin_llroundl:
+  case Builtin::BI__builtin_llroundf128: {
+    APFloat FloatVal(0.0);
+    if (!EvaluateFloat(E->getArg(0), FloatVal, Info))
+      return false;
+
+    llvm::RoundingMode RM;
+    switch (BuiltinOp) {
+    case Builtin::BI__builtin_lround:
+    case Builtin::BI__builtin_lroundf:
+    case Builtin::BI__builtin_lroundl:
+    case Builtin::BI__builtin_lroundf128:
+    case Builtin::BI__builtin_llround:
+    case Builtin::BI__builtin_llroundf:
+    case Builtin::BI__builtin_llroundl:
+    case Builtin::BI__builtin_llroundf128:
+      RM = llvm::RoundingMode::NearestTiesToAway;
+      break;
+    default:
+      RM = getActiveRoundingMode(Info, E);
+      break;
+    }
+
+    FloatVal.roundToIntegral(RM);
+
+    APSInt IntVal(Info.Ctx.getTypeSize(E->getType()),
+                 E->getType()->isUnsignedIntegerOrEnumerationType());
+    bool IsExact = false;
+    APFloat::opStatus Status = FloatVal.convertToInteger(IntVal, RM, &IsExact);
+
+    if (Status & APFloat::opInvalidOp)
+      Info.CCEDiag(E, diag::note_constexpr_float_arithmetic)
+          << (FloatVal.isNaN() ? 1 : 0);
+
+    return Success(IntVal, E);
+  }
+
   default:
     return false;
 
@@ -16744,6 +16795,19 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
     return Success(Val.popcount() % 2, E);
   }
 
+  case Builtin::BI__builtin_ilogb:
+  case Builtin::BI__builtin_ilogbf:
+  case Builtin::BI__builtin_ilogbl:
+  case Builtin::BI__builtin_ilogbf128: {
+    APFloat FloatVal(0.0);
+    if (!EvaluateFloat(E->getArg(0), FloatVal, Info))
+      return false;
+
+    if (FloatVal.isZero() || FloatVal.isNaN())
+      return Success(-2147483648LL, E);
+    return Success(ilogb(FloatVal), E);
+  }
+
   case Builtin::BI__builtin_abs:
   case Builtin::BI__builtin_labs:
   case Builtin::BI__builtin_llabs: {
@@ -19634,6 +19698,269 @@ 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)
+      Q = APFloat::getZero(Q.getSemantics());
+    else
+      Q.roundToIntegral(APFloat::rmNearestTiesToEven);
+
+    APSInt 
QuoInt(Info.Ctx.getTypeSize(E->getArg(2)->getType()->getPointeeType()), false);
+    bool IsExact = false;
+    Q.convertToInteger(QuoInt, APFloat::rmTowardZero, &IsExact);
+
+    APValue APV{QuoInt};
+    if (!handleAssignment(Info, E, QuoLVal, 
E->getArg(2)->getType()->getPointeeType(), APV))
+      return false;
+
+    Result.remainder(RHS);
+    return true;
+  }
+
   case Builtin::BI__builtin_elementwise_fma: {
     if (!E->getArg(0)->isPRValue() || !E->getArg(1)->isPRValue() ||
         !E->getArg(2)->isPRValue()) {
diff --git a/clang/test/SemaCXX/constexpr-cmath-builtins.cpp 
b/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
new file mode 100644
index 0000000000000..368617b27b863
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
@@ -0,0 +1,187 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify -std=c++20 
%s
+// RUN: %clang_cc1 -verify -std=c++20 %s
+
+// expected-no-diagnostics
+
+static_assert(__builtin_nearbyint(1.1) == 1.0);
+static_assert(__builtin_nearbyint(1.9) == 2.0);
+static_assert(__builtin_nearbyint(-1.1) == -1.0);
+static_assert(__builtin_nearbyint(-1.9) == -2.0);
+
+static_assert(__builtin_nearbyintf(1.1f) == 1.0f);
+static_assert(__builtin_nearbyintl(1.1l) == 1.0l);
+
+// Test ties to even (default rounding mode)
+static_assert(__builtin_nearbyint(1.5) == 2.0);
+static_assert(__builtin_nearbyint(2.5) == 2.0);
+
+// rint tests
+static_assert(__builtin_rint(1.1) == 1.0);
+static_assert(__builtin_rint(1.9) == 2.0);
+static_assert(__builtin_rintf(1.1f) == 1.0f);
+static_assert(__builtin_rintl(1.1l) == 1.0l);
+static_assert(__builtin_rintf16(1.1f16) == 1.0f16);
+static_assert(__builtin_rintf128(1.1) == 1.0);
+
+// lrint tests
+static_assert(__builtin_lrint(1.1) == 1);
+static_assert(__builtin_lrint(1.9) == 2);
+static_assert(__builtin_lrintf(1.1f) == 1);
+static_assert(__builtin_lrintl(1.1l) == 1);
+static_assert(__builtin_lrintf128(1.1) == 1);
+
+// llrint tests
+static_assert(__builtin_llrint(1.1) == 1LL);
+static_assert(__builtin_llrint(1.9) == 2LL);
+static_assert(__builtin_llrintf(1.1f) == 1LL);
+static_assert(__builtin_llrintl(1.1l) == 1LL);
+static_assert(__builtin_llrintf128(1.1) == 1LL);
+
+// round tests
+static_assert(__builtin_round(1.1) == 1.0);
+static_assert(__builtin_round(1.5) == 2.0);
+static_assert(__builtin_round(1.9) == 2.0);
+static_assert(__builtin_round(-1.5) == -2.0);
+
+// lround tests
+static_assert(__builtin_lround(1.1) == 1);
+static_assert(__builtin_lround(1.5) == 2);
+static_assert(__builtin_lround(-1.5) == -2);
+
+// llround tests
+static_assert(__builtin_llround(1.1) == 1LL);
+static_assert(__builtin_llround(1.5) == 2LL);
+static_assert(__builtin_llround(-1.5) == -2LL);
+
+// ceil tests
+static_assert(__builtin_ceil(1.1) == 2.0);
+static_assert(__builtin_ceil(-1.1) == -1.0);
+static_assert(__builtin_ceilf(1.1f) == 2.0f);
+
+// floor tests
+static_assert(__builtin_floor(1.1) == 1.0);
+static_assert(__builtin_floor(-1.1) == -2.0);
+static_assert(__builtin_floorf(1.1f) == 1.0f);
+
+// trunc tests
+static_assert(__builtin_trunc(1.1) == 1.0);
+static_assert(__builtin_trunc(-1.1) == -1.0);
+static_assert(__builtin_truncf(1.1f) == 1.0f);
+
+// fdim tests
+static_assert(__builtin_fdim(3.0, 1.0) == 2.0);
+static_assert(__builtin_fdim(1.0, 3.0) == 0.0);
+static_assert(__builtin_fdimf(3.0f, 1.0f) == 2.0f);
+
+// fma tests
+static_assert(__builtin_fma(2.0, 3.0, 4.0) == 10.0);
+static_assert(__builtin_fmaf(2.0f, 3.0f, 4.0f) == 10.0f);
+
+// fmod tests
+static_assert(__builtin_fmod(5.5, 3.0) == 2.5);
+static_assert(__builtin_fmodf(5.5f, 3.0f) == 2.5f);
+
+// remainder tests
+static_assert(__builtin_remainder(5.5, 3.0) == -0.5);
+static_assert(__builtin_remainderf(5.5f, 3.0f) == -0.5f);
+
+// nextafter tests
+static_assert(__builtin_nextafter(1.0, 2.0) > 1.0);
+static_assert(__builtin_nextafter(1.0, 0.0) < 1.0);
+static_assert(__builtin_nextafter(1.0, 1.0) == 1.0);
+static_assert(__builtin_nextafter(0.0, 1.0) > 0.0);
+static_assert(__builtin_nextafter(0.0, -1.0) < 0.0);
+
+// nexttoward tests
+static_assert(__builtin_nexttoward(1.0, 2.0L) > 1.0);
+static_assert(__builtin_nexttoward(1.0, 1.0L) == 1.0);
+
+// scalbn tests
+static_assert(__builtin_scalbn(1.0, 2) == 4.0);
+static_assert(__builtin_scalbnf(1.0f, -1) == 0.5f);
+
+// scalbln tests
+static_assert(__builtin_scalbln(1.0, 2L) == 4.0);
+
+// ldexp tests
+static_assert(__builtin_ldexp(1.0, 3) == 8.0);
+
+// ilogb tests
+static_assert(__builtin_ilogb(1.0) == 0);
+static_assert(__builtin_ilogb(2.0) == 1);
+static_assert(__builtin_ilogb(0.5) == -1);
+static_assert(__builtin_ilogbf(8.0f) == 3);
+
+// remquo tests
+constexpr double test_remquo(double x, double y) {
+  int quo = 0;
+  double rem = __builtin_remquo(x, y, &quo);
+  return rem;
+}
+static_assert(test_remquo(10.0, 3.0) == 1.0);
+
+constexpr int test_remquo_quo(double x, double y) {
+  int quo = 0;
+  __builtin_remquo(x, y, &quo);
+  return quo;
+}
+static_assert(test_remquo_quo(10.0, 3.0) == 3);
+static_assert(test_remquo_quo(10.0, -3.0) == -3);
+
+// frexp tests
+constexpr double test_frexp_val(double x) {
+  int exp = 0;
+  return __builtin_frexp(x, &exp);
+}
+static_assert(test_frexp_val(8.0) == 0.5);
+
+constexpr int test_frexp_exp(double x) {
+  int exp = 0;
+  __builtin_frexp(x, &exp);
+  return exp;
+}
+static_assert(test_frexp_exp(8.0) == 4);
+
+// modf tests
+constexpr double test_modf_val(double x) {
+  double iptr = 0;
+  return __builtin_modf(x, &iptr);
+}
+static_assert(test_modf_val(3.14) > 0.139 && test_modf_val(3.14) < 0.141);
+
+constexpr double test_modf_iptr(double x) {
+  double iptr = 0;
+  __builtin_modf(x, &iptr);
+  return iptr;
+}
+static_assert(test_modf_iptr(3.14) == 3.0);
+
+// ilogb special values
+static_assert(__builtin_ilogb(0.0) == -2147483648);
+static_assert(__builtin_ilogb(__builtin_nan("")) == -2147483648);
+static_assert(__builtin_ilogb(__builtin_inf()) == 2147483647);
+
+// modf special values
+constexpr double test_modf_inf_val() {
+  double iptr = 0;
+  return __builtin_modf(__builtin_inf(), &iptr);
+}
+static_assert(test_modf_inf_val() == 0.0);
+
+constexpr double test_modf_inf_iptr() {
+  double iptr = 0;
+  __builtin_modf(__builtin_inf(), &iptr);
+  return iptr;
+}
+static_assert(__builtin_isinf(test_modf_inf_iptr()));
+
+// fdim special values
+static_assert(__builtin_fdim(__builtin_inf(), __builtin_inf()) == 0.0);
+
+// remquo special values (returns NaN for y=0)
+constexpr bool test_remquo_nan() {
+  int quo = 0;
+  double rem = __builtin_remquo(1.0, 0.0, &quo);
+  return __builtin_isnan(rem);
+}
+static_assert(test_remquo_nan());

>From 42524697f1cc329384f8a2f426dc1e45ea5c11e4 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Mon, 27 Apr 2026 18:33:39 +0530
Subject: [PATCH 2/6] address feedback

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 93 ++++++++++--------------
 clang/lib/AST/ExprConstant.cpp           |  2 -
 2 files changed, 37 insertions(+), 58 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index bce535cc6f0f5..535ebc4914917 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -709,11 +709,10 @@ static inline Floating abs(InterpState &S, const Floating 
&In) {
 
 static bool interp__builtin_ceil(InterpState &S, CodePtr OpPC,
                                  const InterpFrame *Frame,
-                                 const CallExpr *Call) {
+                                 const CallExpr *Call, unsigned BuiltinOp) {
   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) {
@@ -781,10 +780,7 @@ static bool interp__builtin_fma(InterpState &S, CodePtr 
OpPC,
   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;
+  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   Result.fusedMultiplyAdd(Y.getAPFloat(), Z.getAPFloat(), RM);
   Floating F = S.allocFloat(Result.getSemantics());
@@ -800,17 +796,14 @@ static bool interp__builtin_frexp(InterpState &S, CodePtr 
OpPC,
   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;
+  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   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));
+    assignIntegral(S, Ptr, ExpT, APSInt::get(Exp));
     Ptr.initialize();
   }
 
@@ -825,8 +818,9 @@ static bool interp__builtin_modf(InterpState &S, CodePtr 
OpPC,
                                  const CallExpr *Call) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
   const Floating &Val = S.Stk.pop<Floating>();
+  const APFloat &F = Val.getAPFloat();
 
-  APFloat Integral = Val.getAPFloat();
+  APFloat Integral = F;
   Integral.roundToIntegral(APFloat::rmTowardZero);
 
   if (!Ptr.isDummy()) {
@@ -834,14 +828,14 @@ static bool interp__builtin_modf(InterpState &S, CodePtr 
OpPC,
     Ptr.initialize();
   }
 
-  if (Val.getAPFloat().isInfinity()) {
-    Floating Fraction = S.allocFloat(Val.getAPFloat().getSemantics());
-    Fraction.copy(APFloat::getZero(Val.getAPFloat().getSemantics(), 
Val.getAPFloat().isNegative()));
+  if (F.isInfinity()) {
+    Floating Fraction = S.allocFloat(F.getSemantics());
+    Fraction.copy(APFloat::getZero(F.getSemantics(), F.isNegative()));
     S.Stk.push<Floating>(Fraction);
     return true;
   }
 
-  APFloat Fraction = Val.getAPFloat();
+  APFloat Fraction = F;
   Fraction.subtract(Integral, APFloat::rmNearestTiesToEven);
 
   Floating Result = S.allocFloat(Fraction.getSemantics());
@@ -852,22 +846,23 @@ static bool interp__builtin_modf(InterpState &S, CodePtr 
OpPC,
 
 static bool interp__builtin_fmod(InterpState &S, CodePtr OpPC,
                                  const InterpFrame *Frame,
-                                 const CallExpr *Call) {
+                                 const CallExpr *Call, unsigned BuiltinOp) {
   const Floating &RHS = S.Stk.pop<Floating>();
   const Floating &LHS = S.Stk.pop<Floating>();
-  APFloat L = LHS.getAPFloat();
-  unsigned BuiltinOp = Call->getBuiltinCallee();
+  const APFloat &L = LHS.getAPFloat();
+  const APFloat &R = RHS.getAPFloat();
+  APFloat ResF = L;
 
   if (BuiltinOp == Builtin::BI__builtin_remainder ||
       BuiltinOp == Builtin::BI__builtin_remainderf ||
       BuiltinOp == Builtin::BI__builtin_remainderl ||
       BuiltinOp == Builtin::BI__builtin_remainderf128)
-    L.remainder(RHS.getAPFloat());
+    ResF.remainder(R);
   else
-    L.mod(RHS.getAPFloat());
+    ResF.mod(R);
 
-  Floating F = S.allocFloat(L.getSemantics());
-  F.copy(L);
+  Floating F = S.allocFloat(ResF.getSemantics());
+  F.copy(ResF);
   S.Stk.push<Floating>(F);
   return true;
 }
@@ -877,8 +872,8 @@ static bool interp__builtin_nextafter(InterpState &S, 
CodePtr OpPC,
                                       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();
+  const APFloat &L = LHS.getAPFloat();
+  const APFloat &R = RHS.getAPFloat();
 
   if (L.isNaN()) {
     S.Stk.push<Floating>(LHS);
@@ -887,10 +882,10 @@ static bool interp__builtin_nextafter(InterpState &S, 
CodePtr OpPC,
 
   if (R.isNaN()) {
     bool LoseInfo = false;
-    L = R;
-    L.convert(LHS.getSemantics(), APFloat::rmNearestTiesToEven, &LoseInfo);
-    Floating Result = S.allocFloat(L.getSemantics());
-    Result.copy(L);
+    APFloat NaN = R;
+    NaN.convert(L.getSemantics(), APFloat::rmNearestTiesToEven, &LoseInfo);
+    Floating Result = S.allocFloat(NaN.getSemantics());
+    Result.copy(NaN);
     S.Stk.push<Floating>(Result);
     return true;
   }
@@ -900,11 +895,12 @@ static bool interp__builtin_nextafter(InterpState &S, 
CodePtr OpPC,
   LCopy.convert(R.getSemantics(), APFloat::rmNearestTiesToEven, &LoseInfo);
   APFloat::cmpResult Res = LCopy.compare(R);
 
+  APFloat Next = L;
   if (Res != APFloat::cmpEqual)
-    L.next(Res == APFloat::cmpGreaterThan);
+    Next.next(Res == APFloat::cmpGreaterThan);
 
-  Floating Result = S.allocFloat(L.getSemantics());
-  Result.copy(L);
+  Floating Result = S.allocFloat(Next.getSemantics());
+  Result.copy(Next);
   S.Stk.push<Floating>(Result);
   return true;
 }
@@ -916,10 +912,7 @@ static bool interp__builtin_scalbn(InterpState &S, CodePtr 
OpPC,
   APSInt Exp = popToAPSInt(S.Stk, ExpT);
   const Floating &Val = S.Stk.pop<Floating>();
 
-  const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
-  llvm::RoundingMode RM = FPO.getRoundingMode();
-  if (RM == llvm::RoundingMode::Dynamic)
-    RM = llvm::RoundingMode::NearestTiesToEven;
+  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   Floating Result = S.allocFloat(Val.getSemantics());
   Result.copy(scalbn(Val.getAPFloat(), (int)Exp.getExtValue(), RM));
@@ -931,10 +924,6 @@ static bool interp__builtin_ilogb(InterpState &S, CodePtr 
OpPC,
                                   const InterpFrame *Frame,
                                   const CallExpr *Call) {
   const Floating &Val = S.Stk.pop<Floating>();
-  if (Val.getAPFloat().isZero() || Val.getAPFloat().isNaN()) {
-    pushInteger(S, -2147483648LL, Call->getType());
-    return true;
-  }
   pushInteger(S, ilogb(Val.getAPFloat()), Call->getType());
   return true;
 }
@@ -959,7 +948,7 @@ static bool interp__builtin_remquo(InterpState &S, CodePtr 
OpPC,
     Q.convertToInteger(QuoInt, APFloat::rmTowardZero, &IsExact);
 
     PrimType QuoT = *S.getContext().classify(QuoType);
-    assignInteger(S, Ptr, QuoT, QuoInt);
+    assignIntegral(S, Ptr, QuoT, QuoInt);
     Ptr.initialize();
   }
 
@@ -986,10 +975,9 @@ static bool interp__builtin_round(InterpState &S, CodePtr 
OpPC,
 
 static bool interp__builtin_lrint(InterpState &S, CodePtr OpPC,
                                   const InterpFrame *Frame,
-                                  const CallExpr *Call) {
+                                  const CallExpr *Call, unsigned BuiltinOp) {
   const Floating &Val = S.Stk.pop<Floating>();
   APFloat F = Val.getAPFloat();
-  unsigned BuiltinOp = Call->getBuiltinCallee();
 
   llvm::RoundingMode RM;
   switch (BuiltinOp) {
@@ -1003,14 +991,10 @@ static bool interp__builtin_lrint(InterpState &S, 
CodePtr OpPC,
   case Builtin::BI__builtin_llroundf128:
     RM = llvm::RoundingMode::NearestTiesToAway;
     break;
-  default: {
-    const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
-    RM = FPO.getRoundingMode();
-    if (RM == llvm::RoundingMode::Dynamic)
-      RM = llvm::RoundingMode::NearestTiesToEven;
+  default:
+    RM = getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
     break;
   }
-  }
 
   F.roundToIntegral(RM);
 
@@ -1038,10 +1022,7 @@ static bool interp__builtin_nearbyint(InterpState &S, 
CodePtr OpPC,
   Floating Result = S.allocFloat(Val.getSemantics());
   APFloat F = Val.getAPFloat();
 
-  const FPOptions FPO = Call->getFPFeaturesInEffect(S.getLangOpts());
-  llvm::RoundingMode RM = FPO.getRoundingMode();
-  if (RM == llvm::RoundingMode::Dynamic)
-    RM = llvm::RoundingMode::NearestTiesToEven;
+  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   F.roundToIntegral(RM);
   Result.copy(F);
@@ -4670,7 +4651,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
CallExpr *Call,
   case Builtin::BI__builtin_llroundf:
   case Builtin::BI__builtin_llroundl:
   case Builtin::BI__builtin_llroundf128:
-    return interp__builtin_lrint(S, OpPC, Frame, Call);
+    return interp__builtin_lrint(S, OpPC, Frame, Call, ID);
 
   case Builtin::BI__builtin_ceil:
   case Builtin::BI__builtin_ceilf:
@@ -4687,7 +4668,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
CallExpr *Call,
   case Builtin::BI__builtin_truncl:
   case Builtin::BI__builtin_truncf16:
   case Builtin::BI__builtin_truncf128:
-    return interp__builtin_ceil(S, OpPC, Frame, Call);
+    return interp__builtin_ceil(S, OpPC, Frame, Call, ID);
 
   case Builtin::BI__builtin_fdim:
   case Builtin::BI__builtin_fdimf:
@@ -4723,7 +4704,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
CallExpr *Call,
   case Builtin::BI__builtin_remainder:
   case Builtin::BI__builtin_remainderf:
   case Builtin::BI__builtin_remainderf128:
-    return interp__builtin_fmod(S, OpPC, Frame, Call);
+    return interp__builtin_fmod(S, OpPC, Frame, Call, ID);
 
   case Builtin::BI__builtin_nextafter:
   case Builtin::BI__builtin_nextafterf:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 9b89f7997b133..c1449cf33f002 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16803,8 +16803,6 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
     if (!EvaluateFloat(E->getArg(0), FloatVal, Info))
       return false;
 
-    if (FloatVal.isZero() || FloatVal.isNaN())
-      return Success(-2147483648LL, E);
     return Success(ilogb(FloatVal), E);
   }
 

>From a8b9e7329d31c0904ccf4c4c2d5c6ea5e74fad16 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Mon, 27 Apr 2026 19:17:31 +0530
Subject: [PATCH 3/6] ci fixes

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      | 56 ++++++++++++++-----
 clang/lib/AST/ExprConstant.cpp                | 11 ++--
 clang/test/CodeGen/logb_scalbn.c              |  6 +-
 .../test/SemaCXX/constexpr-cmath-builtins.cpp |  6 +-
 4 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 535ebc4914917..5967869bf227c 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -57,13 +57,29 @@ static APSInt popToAPSInt(InterpStack &Stk, PrimType T) {
   INT_TYPE_SWITCH(T, return Stk.pop<T>().toAPSInt());
 }
 
+static bool popToAPSInt(InterpStack &Stk, PrimType T, APSInt &Out) {
+  Out = popToAPSInt(Stk, T);
+  return true;
+}
+
 static APSInt popToAPSInt(InterpState &S, const Expr *E) {
   return popToAPSInt(S.Stk, *S.getContext().classify(E->getType()));
 }
+
+static bool popToAPSInt(InterpState &S, const Expr *E, APSInt &Out) {
+  Out = popToAPSInt(S, E);
+  return true;
+}
+
 static APSInt popToAPSInt(InterpState &S, QualType T) {
   return popToAPSInt(S.Stk, *S.getContext().classify(T));
 }
 
+static bool popToAPSInt(InterpState &S, QualType T, APSInt &Out) {
+  Out = popToAPSInt(S, T);
+  return true;
+}
+
 /// Check for common reasons a pointer can't be read from, which
 /// are usually not diagnosed in a builtin function.
 static bool isReadable(const Pointer &P) {
@@ -141,6 +157,11 @@ static void assignInteger(InterpState &S, const Pointer 
&Dest, PrimType ValueT,
   }
 }
 
+static void assignIntegral(InterpState &S, const Pointer &Dest, PrimType 
ValueT,
+                           const APSInt &Value) {
+  assignInteger(S, Dest, ValueT, Value);
+}
+
 static QualType getElemType(const Pointer &P) {
   const Descriptor *Desc = P.getFieldDesc();
   QualType T = Desc->getType();
@@ -708,8 +729,8 @@ static inline Floating abs(InterpState &S, const Floating 
&In) {
 }
 
 static bool interp__builtin_ceil(InterpState &S, CodePtr OpPC,
-                                 const InterpFrame *Frame,
-                                 const CallExpr *Call, unsigned BuiltinOp) {
+                                 const InterpFrame *Frame, const CallExpr 
*Call,
+                                 unsigned BuiltinOp) {
   const Floating &Val = S.Stk.pop<Floating>();
   Floating Result = S.allocFloat(Val.getSemantics());
   APFloat F = Val.getAPFloat();
@@ -780,7 +801,8 @@ static bool interp__builtin_fma(InterpState &S, CodePtr 
OpPC,
   const Floating &X = S.Stk.pop<Floating>();
   APFloat Result = X.getAPFloat();
 
-  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
+  llvm::RoundingMode RM =
+      getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   Result.fusedMultiplyAdd(Y.getAPFloat(), Z.getAPFloat(), RM);
   Floating F = S.allocFloat(Result.getSemantics());
@@ -796,7 +818,8 @@ static bool interp__builtin_frexp(InterpState &S, CodePtr 
OpPC,
   const Floating &Val = S.Stk.pop<Floating>();
 
   int Exp = 0;
-  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
+  llvm::RoundingMode RM =
+      getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   APFloat F = frexp(Val.getAPFloat(), Exp, RM);
 
@@ -845,8 +868,8 @@ static bool interp__builtin_modf(InterpState &S, CodePtr 
OpPC,
 }
 
 static bool interp__builtin_fmod(InterpState &S, CodePtr OpPC,
-                                 const InterpFrame *Frame,
-                                 const CallExpr *Call, unsigned BuiltinOp) {
+                                 const InterpFrame *Frame, const CallExpr 
*Call,
+                                 unsigned BuiltinOp) {
   const Floating &RHS = S.Stk.pop<Floating>();
   const Floating &LHS = S.Stk.pop<Floating>();
   const APFloat &L = LHS.getAPFloat();
@@ -909,10 +932,13 @@ static bool interp__builtin_scalbn(InterpState &S, 
CodePtr OpPC,
                                    const InterpFrame *Frame,
                                    const CallExpr *Call) {
   PrimType ExpT = *S.getContext().classify(Call->getArg(1)->getType());
-  APSInt Exp = popToAPSInt(S.Stk, ExpT);
+  APSInt Exp;
+  if (!popToAPSInt(S.Stk, ExpT, Exp))
+    return false;
   const Floating &Val = S.Stk.pop<Floating>();
 
-  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
+  llvm::RoundingMode RM =
+      getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   Floating Result = S.allocFloat(Val.getSemantics());
   Result.copy(scalbn(Val.getAPFloat(), (int)Exp.getExtValue(), RM));
@@ -936,7 +962,8 @@ static bool interp__builtin_remquo(InterpState &S, CodePtr 
OpPC,
   const Floating &LHS = S.Stk.pop<Floating>();
 
   APFloat Q = LHS.getAPFloat();
-  if (Q.divide(RHS.getAPFloat(), APFloat::rmNearestTiesToEven) & 
APFloat::opInvalidOp)
+  if (Q.divide(RHS.getAPFloat(), APFloat::rmNearestTiesToEven) &
+      APFloat::opInvalidOp)
     Q = APFloat::getZero(Q.getSemantics());
   else
     Q.roundToIntegral(APFloat::rmNearestTiesToEven);
@@ -999,7 +1026,7 @@ static bool interp__builtin_lrint(InterpState &S, CodePtr 
OpPC,
   F.roundToIntegral(RM);
 
   APSInt IntVal(S.getASTContext().getTypeSize(Call->getType()),
-               Call->getType()->isUnsignedIntegerOrEnumerationType());
+                Call->getType()->isUnsignedIntegerOrEnumerationType());
   bool IsExact = false;
   APFloat::opStatus Status = F.convertToInteger(IntVal, RM, &IsExact);
 
@@ -1022,7 +1049,8 @@ static bool interp__builtin_nearbyint(InterpState &S, 
CodePtr OpPC,
   Floating Result = S.allocFloat(Val.getSemantics());
   APFloat F = Val.getAPFloat();
 
-  llvm::RoundingMode RM = 
getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
+  llvm::RoundingMode RM =
+      getRoundingMode(Call->getFPFeaturesInEffect(S.getLangOpts()));
 
   F.roundToIntegral(RM);
   Result.copy(F);
@@ -4651,7 +4679,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
CallExpr *Call,
   case Builtin::BI__builtin_llroundf:
   case Builtin::BI__builtin_llroundl:
   case Builtin::BI__builtin_llroundf128:
-    return interp__builtin_lrint(S, OpPC, Frame, Call, ID);
+    return interp__builtin_lrint(S, OpPC, Frame, Call, BuiltinID);
 
   case Builtin::BI__builtin_ceil:
   case Builtin::BI__builtin_ceilf:
@@ -4668,7 +4696,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
CallExpr *Call,
   case Builtin::BI__builtin_truncl:
   case Builtin::BI__builtin_truncf16:
   case Builtin::BI__builtin_truncf128:
-    return interp__builtin_ceil(S, OpPC, Frame, Call, ID);
+    return interp__builtin_ceil(S, OpPC, Frame, Call, BuiltinID);
 
   case Builtin::BI__builtin_fdim:
   case Builtin::BI__builtin_fdimf:
@@ -4704,7 +4732,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
CallExpr *Call,
   case Builtin::BI__builtin_remainder:
   case Builtin::BI__builtin_remainderf:
   case Builtin::BI__builtin_remainderf128:
-    return interp__builtin_fmod(S, OpPC, Frame, Call, ID);
+    return interp__builtin_fmod(S, OpPC, Frame, Call, BuiltinID);
 
   case Builtin::BI__builtin_nextafter:
   case Builtin::BI__builtin_nextafterf:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c1449cf33f002..1e333758a4eb2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16315,7 +16315,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
     FloatVal.roundToIntegral(RM);
 
     APSInt IntVal(Info.Ctx.getTypeSize(E->getType()),
-                 E->getType()->isUnsignedIntegerOrEnumerationType());
+                  E->getType()->isUnsignedIntegerOrEnumerationType());
     bool IsExact = false;
     APFloat::opStatus Status = FloatVal.convertToInteger(IntVal, RM, &IsExact);
 
@@ -19850,7 +19850,8 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
 
     APFloat ResultCopy = Result;
     bool LoseInfo = false;
-    ResultCopy.convert(RHS.getSemantics(), APFloat::rmNearestTiesToEven, 
&LoseInfo);
+    ResultCopy.convert(RHS.getSemantics(), APFloat::rmNearestTiesToEven,
+                       &LoseInfo);
     APFloat::cmpResult Res = ResultCopy.compare(RHS);
 
     if (Res == APFloat::cmpEqual)
@@ -19947,12 +19948,14 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
     else
       Q.roundToIntegral(APFloat::rmNearestTiesToEven);
 
-    APSInt 
QuoInt(Info.Ctx.getTypeSize(E->getArg(2)->getType()->getPointeeType()), false);
+    APSInt QuoInt(
+        Info.Ctx.getTypeSize(E->getArg(2)->getType()->getPointeeType()), 
false);
     bool IsExact = false;
     Q.convertToInteger(QuoInt, APFloat::rmTowardZero, &IsExact);
 
     APValue APV{QuoInt};
-    if (!handleAssignment(Info, E, QuoLVal, 
E->getArg(2)->getType()->getPointeeType(), APV))
+    if (!handleAssignment(Info, E, QuoLVal,
+                          E->getArg(2)->getType()->getPointeeType(), APV))
       return false;
 
     Result.remainder(RHS);
diff --git a/clang/test/CodeGen/logb_scalbn.c b/clang/test/CodeGen/logb_scalbn.c
index 52c52bcb292be..d4d58f5c773de 100644
--- a/clang/test/CodeGen/logb_scalbn.c
+++ b/clang/test/CodeGen/logb_scalbn.c
@@ -777,8 +777,7 @@ void test_logb_var(double a) {
 // IGNORE-NEXT:  [[ENTRY:.*:]]
 // IGNORE-NEXT:    [[D1:%.*]] = alloca float, align 4, addrspace(5)
 // IGNORE-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// IGNORE-NEXT:    [[TMP0:%.*]] = call float @llvm.ldexp.f32.i32(float 
0x4030B33340000000, i32 10)
-// IGNORE-NEXT:    store float [[TMP0]], ptr [[D1_ASCAST]], align 4
+// IGNORE-NEXT:    store float 0x40D0B33340000000, ptr [[D1_ASCAST]], align 4
 // IGNORE-NEXT:    ret void
 //
 // STRICT-LABEL: define dso_local void @test_scalbnf(
@@ -1358,8 +1357,7 @@ void test_scalbnf_var3(float a, int b) {
 // IGNORE-NEXT:  [[ENTRY:.*:]]
 // IGNORE-NEXT:    [[D1:%.*]] = alloca double, align 8, addrspace(5)
 // IGNORE-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// IGNORE-NEXT:    [[TMP0:%.*]] = call double @llvm.ldexp.f64.i32(double 
1.720000e+01, i32 10)
-// IGNORE-NEXT:    store double [[TMP0]], ptr [[D1_ASCAST]], align 8
+// IGNORE-NEXT:    store double 1.761280e+04, ptr [[D1_ASCAST]], align 8
 // IGNORE-NEXT:    ret void
 //
 // STRICT-LABEL: define dso_local void @test_scalbn(
diff --git a/clang/test/SemaCXX/constexpr-cmath-builtins.cpp 
b/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
index 368617b27b863..79f28d795e179 100644
--- a/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
+++ b/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
@@ -157,9 +157,9 @@ constexpr double test_modf_iptr(double x) {
 static_assert(test_modf_iptr(3.14) == 3.0);
 
 // ilogb special values
-static_assert(__builtin_ilogb(0.0) == -2147483648);
-static_assert(__builtin_ilogb(__builtin_nan("")) == -2147483648);
-static_assert(__builtin_ilogb(__builtin_inf()) == 2147483647);
+static_assert(__builtin_ilogb(0.) == -2147483647L);
+static_assert(__builtin_ilogb(__builtin_nan("")) == -2147483648L);
+static_assert(__builtin_ilogb(__builtin_inf()) == 2147483647L);
 
 // modf special values
 constexpr double test_modf_inf_val() {

>From 9d4a22f66540c248f9e3a7b80d83f4169b0b92a5 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Wed, 29 Apr 2026 02:58:46 +0530
Subject: [PATCH 4/6] solve issues caused due to resolve conflicts

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp |  2 --
 clang/test/CodeGen/aix-builtin-mapping.c |  2 +-
 clang/test/CodeGen/logb_scalbn.c         | 12 ++++--------
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index c72a746b6464d..08fca6df485b8 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -76,7 +76,6 @@ static bool popToAPSInt(InterpState &S, QualType T, APSInt 
&Out) {
   return popToAPSInt(S.Stk, *S.getContext().classify(T), Out);
 }
 
-
 /// Check for common reasons a pointer can't be read from, which
 /// are usually not diagnosed in a builtin function.
 static bool isReadable(const Pointer &P) {
@@ -156,7 +155,6 @@ static void assignIntegral(InterpState &S, const Pointer 
&Dest, PrimType ValueT,
   }
 }
 
-
 static QualType getElemType(const Pointer &P) {
   const Descriptor *Desc = P.getFieldDesc();
   QualType T = Desc->getType();
diff --git a/clang/test/CodeGen/aix-builtin-mapping.c 
b/clang/test/CodeGen/aix-builtin-mapping.c
index cc1cc1a44f32c..f72b7bdca89fb 100644
--- a/clang/test/CodeGen/aix-builtin-mapping.c
+++ b/clang/test/CodeGen/aix-builtin-mapping.c
@@ -19,4 +19,4 @@ int main()
 
 // CHECK: %{{.+}} = call { double, double } @llvm.modf.f64(double 1.000000e+00)
 // CHECK: %{{.+}} = call { double, i32 } @llvm.frexp.f64.i32(double 
0.000000e+00)
-// CHECK: %{{.+}} = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 1)
+// CHECK: store double 2.000000e+00, ptr %returnValue, align 8
diff --git a/clang/test/CodeGen/logb_scalbn.c b/clang/test/CodeGen/logb_scalbn.c
index d4d58f5c773de..28afcaf0d55ce 100644
--- a/clang/test/CodeGen/logb_scalbn.c
+++ b/clang/test/CodeGen/logb_scalbn.c
@@ -1340,16 +1340,14 @@ void test_scalbnf_var3(float a, int b) {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[D1:%.*]] = alloca double, align 8, addrspace(5)
 // CHECK-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] to 
ptr
-// CHECK-NEXT:    [[TMP0:%.*]] = call double @llvm.ldexp.f64.i32(double 
1.720000e+01, i32 10)
-// CHECK-NEXT:    store double [[TMP0]], ptr [[D1_ASCAST]], align 8
+// CHECK-NEXT:    store double 1.761280e+04, ptr [[D1_ASCAST]], align 8
 // CHECK-NEXT:    ret void
 // DEFAULT-LABEL: define dso_local void @test_scalbn(
 // DEFAULT-SAME: ) #[[ATTR0]] {
 // DEFAULT-NEXT:  [[ENTRY:.*:]]
 // DEFAULT-NEXT:    [[D1:%.*]] = alloca double, align 8, addrspace(5)
 // DEFAULT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// DEFAULT-NEXT:    [[TMP0:%.*]] = call double @llvm.ldexp.f64.i32(double 
1.720000e+01, i32 10)
-// DEFAULT-NEXT:    store double [[TMP0]], ptr [[D1_ASCAST]], align 8
+// DEFAULT-NEXT:    store double 1.761280e+04, ptr [[D1_ASCAST]], align 8
 // DEFAULT-NEXT:    ret void
 //
 // IGNORE-LABEL: define dso_local void @test_scalbn(
@@ -1365,8 +1363,7 @@ void test_scalbnf_var3(float a, int b) {
 // STRICT-NEXT:  [[ENTRY:.*:]]
 // STRICT-NEXT:    [[D1:%.*]] = alloca double, align 8, addrspace(5)
 // STRICT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// STRICT-NEXT:    [[TMP0:%.*]] = call double @llvm.ldexp.f64.i32(double 
1.720000e+01, i32 10)
-// STRICT-NEXT:    store double [[TMP0]], ptr [[D1_ASCAST]], align 8
+// STRICT-NEXT:    store double 1.761280e+04, ptr [[D1_ASCAST]], align 8
 // STRICT-NEXT:    ret void
 //
 // MAYTRAP-LABEL: define dso_local void @test_scalbn(
@@ -1392,8 +1389,7 @@ void test_scalbnf_var3(float a, int b) {
 // AMDGCNSPIRV-DEFAULT-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-DEFAULT-NEXT:    [[D1:%.*]] = alloca double, align 8
 // AMDGCNSPIRV-DEFAULT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] 
to ptr addrspace(4)
-// AMDGCNSPIRV-DEFAULT-NEXT:    [[TMP0:%.*]] = call addrspace(4) double 
@llvm.ldexp.f64.i32(double 1.720000e+01, i32 10)
-// AMDGCNSPIRV-DEFAULT-NEXT:    store double [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 8
+// AMDGCNSPIRV-DEFAULT-NEXT:    store double 1.761280e+04, ptr addrspace(4) 
[[D1_ASCAST]], align 8
 // AMDGCNSPIRV-DEFAULT-NEXT:    ret void
 //
 // AMDGCNSPIRV-IGNORE-LABEL: define spir_func void @test_scalbn(

>From 92068b61f2554a59229130102ff16f08e0899b52 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Wed, 29 Apr 2026 04:26:15 +0530
Subject: [PATCH 5/6] update test(folding)

---
 clang/test/CodeGen/logb_scalbn.c | 48 +++++++++++---------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/clang/test/CodeGen/logb_scalbn.c b/clang/test/CodeGen/logb_scalbn.c
index 28afcaf0d55ce..143fd54adba98 100644
--- a/clang/test/CodeGen/logb_scalbn.c
+++ b/clang/test/CodeGen/logb_scalbn.c
@@ -760,16 +760,14 @@ void test_logb_var(double a) {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[D1:%.*]] = alloca float, align 4, addrspace(5)
 // CHECK-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] to 
ptr
-// CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.ldexp.f32.i32(float 
0x4030B33340000000, i32 10)
-// CHECK-NEXT:    store float [[TMP0]], ptr [[D1_ASCAST]], align 4
+// CHECK-NEXT:    store float 0x40D0B33340000000, ptr [[D1_ASCAST]], align 4
 // CHECK-NEXT:    ret void
 // DEFAULT-LABEL: define dso_local void @test_scalbnf(
 // DEFAULT-SAME: ) #[[ATTR0]] {
 // DEFAULT-NEXT:  [[ENTRY:.*:]]
 // DEFAULT-NEXT:    [[D1:%.*]] = alloca float, align 4, addrspace(5)
 // DEFAULT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// DEFAULT-NEXT:    [[TMP0:%.*]] = call float @llvm.ldexp.f32.i32(float 
0x4030B33340000000, i32 10)
-// DEFAULT-NEXT:    store float [[TMP0]], ptr [[D1_ASCAST]], align 4
+// DEFAULT-NEXT:    store float 0x40D0B33340000000, ptr [[D1_ASCAST]], align 4
 // DEFAULT-NEXT:    ret void
 //
 // IGNORE-LABEL: define dso_local void @test_scalbnf(
@@ -785,8 +783,7 @@ void test_logb_var(double a) {
 // STRICT-NEXT:  [[ENTRY:.*:]]
 // STRICT-NEXT:    [[D1:%.*]] = alloca float, align 4, addrspace(5)
 // STRICT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// STRICT-NEXT:    [[TMP0:%.*]] = call float @llvm.ldexp.f32.i32(float 
0x4030B33340000000, i32 10)
-// STRICT-NEXT:    store float [[TMP0]], ptr [[D1_ASCAST]], align 4
+// STRICT-NEXT:    store float 0x40D0B33340000000, ptr [[D1_ASCAST]], align 4
 // STRICT-NEXT:    ret void
 //
 // MAYTRAP-LABEL: define dso_local void @test_scalbnf(
@@ -794,8 +791,7 @@ void test_logb_var(double a) {
 // MAYTRAP-NEXT:  [[ENTRY:.*:]]
 // MAYTRAP-NEXT:    [[D1:%.*]] = alloca float, align 4, addrspace(5)
 // MAYTRAP-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// MAYTRAP-NEXT:    [[TMP0:%.*]] = call float @llvm.ldexp.f32.i32(float 
0x4030B33340000000, i32 10)
-// MAYTRAP-NEXT:    store float [[TMP0]], ptr [[D1_ASCAST]], align 4
+// MAYTRAP-NEXT:    store float 0x40D0B33340000000, ptr [[D1_ASCAST]], align 4
 // MAYTRAP-NEXT:    ret void
 //
 // ERRNO-LABEL: define dso_local void @test_scalbnf(
@@ -803,8 +799,7 @@ void test_logb_var(double a) {
 // ERRNO-NEXT:  [[ENTRY:.*:]]
 // ERRNO-NEXT:    [[D1:%.*]] = alloca float, align 4, addrspace(5)
 // ERRNO-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] to 
ptr
-// ERRNO-NEXT:    [[CALL:%.*]] = call float @scalbnf(float noundef 
0x4030B33340000000, i32 noundef 10) #[[ATTR2]]
-// ERRNO-NEXT:    store float [[CALL]], ptr [[D1_ASCAST]], align 4
+// ERRNO-NEXT:    store float 0x40D0B33340000000, ptr [[D1_ASCAST]], align 4
 // ERRNO-NEXT:    ret void
 //
 // AMDGCNSPIRV-DEFAULT-LABEL: define spir_func void @test_scalbnf(
@@ -812,8 +807,7 @@ void test_logb_var(double a) {
 // AMDGCNSPIRV-DEFAULT-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-DEFAULT-NEXT:    [[D1:%.*]] = alloca float, align 4
 // AMDGCNSPIRV-DEFAULT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] 
to ptr addrspace(4)
-// AMDGCNSPIRV-DEFAULT-NEXT:    [[TMP0:%.*]] = call addrspace(4) float 
@llvm.ldexp.f32.i32(float 0x4030B33340000000, i32 10)
-// AMDGCNSPIRV-DEFAULT-NEXT:    store float [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 4
+// AMDGCNSPIRV-DEFAULT-NEXT:    store float 0x40D0B33340000000, ptr 
addrspace(4) [[D1_ASCAST]], align 4
 // AMDGCNSPIRV-DEFAULT-NEXT:    ret void
 //
 // AMDGCNSPIRV-IGNORE-LABEL: define spir_func void @test_scalbnf(
@@ -821,8 +815,7 @@ void test_logb_var(double a) {
 // AMDGCNSPIRV-IGNORE-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-IGNORE-NEXT:    [[D1:%.*]] = alloca float, align 4
 // AMDGCNSPIRV-IGNORE-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] to 
ptr addrspace(4)
-// AMDGCNSPIRV-IGNORE-NEXT:    [[TMP0:%.*]] = call addrspace(4) float 
@llvm.ldexp.f32.i32(float 0x4030B33340000000, i32 10)
-// AMDGCNSPIRV-IGNORE-NEXT:    store float [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 4
+// AMDGCNSPIRV-IGNORE-NEXT:    store float 0x40D0B33340000000, ptr 
addrspace(4) [[D1_ASCAST]], align 4
 // AMDGCNSPIRV-IGNORE-NEXT:    ret void
 //
 // AMDGCNSPIRV-STRICT-LABEL: define spir_func void @test_scalbnf(
@@ -830,8 +823,7 @@ void test_logb_var(double a) {
 // AMDGCNSPIRV-STRICT-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-STRICT-NEXT:    [[D1:%.*]] = alloca float, align 4
 // AMDGCNSPIRV-STRICT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] to 
ptr addrspace(4)
-// AMDGCNSPIRV-STRICT-NEXT:    [[TMP0:%.*]] = call addrspace(4) float 
@llvm.ldexp.f32.i32(float 0x4030B33340000000, i32 10)
-// AMDGCNSPIRV-STRICT-NEXT:    store float [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 4
+// AMDGCNSPIRV-STRICT-NEXT:    store float 0x40D0B33340000000, ptr 
addrspace(4) [[D1_ASCAST]], align 4
 // AMDGCNSPIRV-STRICT-NEXT:    ret void
 //
 // AMDGCNSPIRV-MAYTRAP-LABEL: define spir_func void @test_scalbnf(
@@ -839,8 +831,7 @@ void test_logb_var(double a) {
 // AMDGCNSPIRV-MAYTRAP-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-MAYTRAP-NEXT:    [[D1:%.*]] = alloca float, align 4
 // AMDGCNSPIRV-MAYTRAP-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] 
to ptr addrspace(4)
-// AMDGCNSPIRV-MAYTRAP-NEXT:    [[TMP0:%.*]] = call addrspace(4) float 
@llvm.ldexp.f32.i32(float 0x4030B33340000000, i32 10)
-// AMDGCNSPIRV-MAYTRAP-NEXT:    store float [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 4
+// AMDGCNSPIRV-MAYTRAP-NEXT:    store float 0x40D0B33340000000, ptr 
addrspace(4) [[D1_ASCAST]], align 4
 // AMDGCNSPIRV-MAYTRAP-NEXT:    ret void
 //
 // AMDGCNSPIRV-ERRNO-LABEL: define spir_func void @test_scalbnf(
@@ -848,8 +839,7 @@ void test_logb_var(double a) {
 // AMDGCNSPIRV-ERRNO-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-ERRNO-NEXT:    [[D1:%.*]] = alloca float, align 4
 // AMDGCNSPIRV-ERRNO-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] to 
ptr addrspace(4)
-// AMDGCNSPIRV-ERRNO-NEXT:    [[CALL:%.*]] = call spir_func addrspace(4) float 
@scalbnf(float noundef 0x4030B33340000000, i32 noundef 10) #[[ATTR2]]
-// AMDGCNSPIRV-ERRNO-NEXT:    store float [[CALL]], ptr addrspace(4) 
[[D1_ASCAST]], align 4
+// AMDGCNSPIRV-ERRNO-NEXT:    store float 0x40D0B33340000000, ptr addrspace(4) 
[[D1_ASCAST]], align 4
 // AMDGCNSPIRV-ERRNO-NEXT:    ret void
 //
 void test_scalbnf() {
@@ -1371,8 +1361,7 @@ void test_scalbnf_var3(float a, int b) {
 // MAYTRAP-NEXT:  [[ENTRY:.*:]]
 // MAYTRAP-NEXT:    [[D1:%.*]] = alloca double, align 8, addrspace(5)
 // MAYTRAP-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] 
to ptr
-// MAYTRAP-NEXT:    [[TMP0:%.*]] = call double @llvm.ldexp.f64.i32(double 
1.720000e+01, i32 10)
-// MAYTRAP-NEXT:    store double [[TMP0]], ptr [[D1_ASCAST]], align 8
+// MAYTRAP-NEXT:    store double 1.761280e+04, ptr [[D1_ASCAST]], align 8
 // MAYTRAP-NEXT:    ret void
 //
 // ERRNO-LABEL: define dso_local void @test_scalbn(
@@ -1380,8 +1369,7 @@ void test_scalbnf_var3(float a, int b) {
 // ERRNO-NEXT:  [[ENTRY:.*:]]
 // ERRNO-NEXT:    [[D1:%.*]] = alloca double, align 8, addrspace(5)
 // ERRNO-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[D1]] to 
ptr
-// ERRNO-NEXT:    [[CALL:%.*]] = call double @scalbn(double noundef 
1.720000e+01, i32 noundef 10) #[[ATTR2]]
-// ERRNO-NEXT:    store double [[CALL]], ptr [[D1_ASCAST]], align 8
+// ERRNO-NEXT:    store double 1.761280e+04, ptr [[D1_ASCAST]], align 8
 // ERRNO-NEXT:    ret void
 //
 // AMDGCNSPIRV-DEFAULT-LABEL: define spir_func void @test_scalbn(
@@ -1397,8 +1385,7 @@ void test_scalbnf_var3(float a, int b) {
 // AMDGCNSPIRV-IGNORE-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-IGNORE-NEXT:    [[D1:%.*]] = alloca double, align 8
 // AMDGCNSPIRV-IGNORE-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] to 
ptr addrspace(4)
-// AMDGCNSPIRV-IGNORE-NEXT:    [[TMP0:%.*]] = call addrspace(4) double 
@llvm.ldexp.f64.i32(double 1.720000e+01, i32 10)
-// AMDGCNSPIRV-IGNORE-NEXT:    store double [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 8
+// AMDGCNSPIRV-IGNORE-NEXT:    store double 1.761280e+04, ptr addrspace(4) 
[[D1_ASCAST]], align 8
 // AMDGCNSPIRV-IGNORE-NEXT:    ret void
 //
 // AMDGCNSPIRV-STRICT-LABEL: define spir_func void @test_scalbn(
@@ -1406,8 +1393,7 @@ void test_scalbnf_var3(float a, int b) {
 // AMDGCNSPIRV-STRICT-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-STRICT-NEXT:    [[D1:%.*]] = alloca double, align 8
 // AMDGCNSPIRV-STRICT-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] to 
ptr addrspace(4)
-// AMDGCNSPIRV-STRICT-NEXT:    [[TMP0:%.*]] = call addrspace(4) double 
@llvm.ldexp.f64.i32(double 1.720000e+01, i32 10)
-// AMDGCNSPIRV-STRICT-NEXT:    store double [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 8
+// AMDGCNSPIRV-STRICT-NEXT:    store double 1.761280e+04, ptr addrspace(4) 
[[D1_ASCAST]], align 8
 // AMDGCNSPIRV-STRICT-NEXT:    ret void
 //
 // AMDGCNSPIRV-MAYTRAP-LABEL: define spir_func void @test_scalbn(
@@ -1415,8 +1401,7 @@ void test_scalbnf_var3(float a, int b) {
 // AMDGCNSPIRV-MAYTRAP-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-MAYTRAP-NEXT:    [[D1:%.*]] = alloca double, align 8
 // AMDGCNSPIRV-MAYTRAP-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] 
to ptr addrspace(4)
-// AMDGCNSPIRV-MAYTRAP-NEXT:    [[TMP0:%.*]] = call addrspace(4) double 
@llvm.ldexp.f64.i32(double 1.720000e+01, i32 10)
-// AMDGCNSPIRV-MAYTRAP-NEXT:    store double [[TMP0]], ptr addrspace(4) 
[[D1_ASCAST]], align 8
+// AMDGCNSPIRV-MAYTRAP-NEXT:    store double 1.761280e+04, ptr addrspace(4) 
[[D1_ASCAST]], align 8
 // AMDGCNSPIRV-MAYTRAP-NEXT:    ret void
 //
 // AMDGCNSPIRV-ERRNO-LABEL: define spir_func void @test_scalbn(
@@ -1424,8 +1409,7 @@ void test_scalbnf_var3(float a, int b) {
 // AMDGCNSPIRV-ERRNO-NEXT:  [[ENTRY:.*:]]
 // AMDGCNSPIRV-ERRNO-NEXT:    [[D1:%.*]] = alloca double, align 8
 // AMDGCNSPIRV-ERRNO-NEXT:    [[D1_ASCAST:%.*]] = addrspacecast ptr [[D1]] to 
ptr addrspace(4)
-// AMDGCNSPIRV-ERRNO-NEXT:    [[CALL:%.*]] = call spir_func addrspace(4) 
double @scalbn(double noundef 1.720000e+01, i32 noundef 10) #[[ATTR2]]
-// AMDGCNSPIRV-ERRNO-NEXT:    store double [[CALL]], ptr addrspace(4) 
[[D1_ASCAST]], align 8
+// AMDGCNSPIRV-ERRNO-NEXT:    store double 1.761280e+04, ptr addrspace(4) 
[[D1_ASCAST]], align 8
 // AMDGCNSPIRV-ERRNO-NEXT:    ret void
 //
 void test_scalbn() {

>From 6075ee97b695a6fac951f218da3fc6a8fe943475 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Wed, 29 Apr 2026 21:53:42 +0530
Subject: [PATCH 6/6] address feedback

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      | 48 +++++++++----------
 .../test/SemaCXX/constexpr-cmath-builtins.cpp |  6 ++-
 2 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 08fca6df485b8..967afb5fd71e0 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -812,12 +812,13 @@ static bool interp__builtin_frexp(InterpState &S, CodePtr 
OpPC,
 
   APFloat F = frexp(Val.getAPFloat(), Exp, RM);
 
-  if (!Ptr.isDummy()) {
-    QualType ExpType = Call->getArg(1)->getType()->getPointeeType();
-    PrimType ExpT = *S.getContext().classify(ExpType);
-    assignIntegral(S, Ptr, ExpT, APSInt::get(Exp));
-    Ptr.initialize();
-  }
+  if (Ptr.isDummy())
+    return false;
+
+  QualType ExpType = Call->getArg(1)->getType()->getPointeeType();
+  PrimType ExpT = *S.getContext().classify(ExpType);
+  assignIntegral(S, Ptr, ExpT, APSInt::get(Exp));
+  Ptr.initialize();
 
   Floating Result = S.allocFloat(F.getSemantics());
   Result.copy(F);
@@ -835,10 +836,11 @@ static bool interp__builtin_modf(InterpState &S, CodePtr 
OpPC,
   APFloat Integral = F;
   Integral.roundToIntegral(APFloat::rmTowardZero);
 
-  if (!Ptr.isDummy()) {
-    Ptr.deref<Floating>().copy(Integral);
-    Ptr.initialize();
-  }
+  if (Ptr.isDummy())
+    return false;
+
+  Ptr.deref<Floating>().copy(Integral);
+  Ptr.initialize();
 
   if (F.isInfinity()) {
     Floating Fraction = S.allocFloat(F.getSemantics());
@@ -957,16 +959,17 @@ static bool interp__builtin_remquo(InterpState &S, 
CodePtr OpPC,
   else
     Q.roundToIntegral(APFloat::rmNearestTiesToEven);
 
-  if (!Ptr.isDummy()) {
-    QualType QuoType = Call->getArg(2)->getType()->getPointeeType();
-    APSInt QuoInt(S.getASTContext().getTypeSize(QuoType), false);
-    bool IsExact = false;
-    Q.convertToInteger(QuoInt, APFloat::rmTowardZero, &IsExact);
+  if (Ptr.isDummy())
+    return false;
 
-    PrimType QuoT = *S.getContext().classify(QuoType);
-    assignIntegral(S, Ptr, QuoT, QuoInt);
-    Ptr.initialize();
-  }
+  QualType QuoType = Call->getArg(2)->getType()->getPointeeType();
+  APSInt QuoInt(S.getASTContext().getTypeSize(QuoType), /*IsUnsigned=*/false);
+  bool IsExact = false;
+  Q.convertToInteger(QuoInt, APFloat::rmTowardZero, &IsExact);
+
+  PrimType QuoT = *S.getContext().classify(QuoType);
+  assignIntegral(S, Ptr, QuoT, QuoInt);
+  Ptr.initialize();
 
   APFloat R = LHS.getAPFloat();
   R.remainder(RHS.getAPFloat());
@@ -1020,11 +1023,8 @@ static bool interp__builtin_lrint(InterpState &S, 
CodePtr OpPC,
   APFloat::opStatus Status = F.convertToInteger(IntVal, RM, &IsExact);
 
   if (Status & APFloat::opInvalidOp) {
-    if (S.diagnosing()) {
-      auto Loc = S.Current->getSource(OpPC);
-      S.CCEDiag(Loc, diag::note_constexpr_float_arithmetic)
-          << (F.isNaN() ? 1 : 0);
-    }
+    auto Loc = S.Current->getSource(OpPC);
+    S.CCEDiag(Loc, diag::note_constexpr_float_arithmetic) << F.isNaN();
   }
 
   pushInteger(S, IntVal, Call->getType());
diff --git a/clang/test/SemaCXX/constexpr-cmath-builtins.cpp 
b/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
index 79f28d795e179..0c64659da79ef 100644
--- a/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
+++ b/clang/test/SemaCXX/constexpr-cmath-builtins.cpp
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify -std=c++20 
%s
 // RUN: %clang_cc1 -verify -std=c++20 %s
 
-// expected-no-diagnostics
 
 static_assert(__builtin_nearbyint(1.1) == 1.0);
 static_assert(__builtin_nearbyint(1.9) == 2.0);
@@ -185,3 +184,8 @@ constexpr bool test_remquo_nan() {
   return __builtin_isnan(rem);
 }
 static_assert(test_remquo_nan());
+
+namespace LRoundDiagnostic {
+  constexpr int i = __builtin_lround(1e30); // expected-error {{constexpr 
variable 'i' must be initialized by a constant expression}} \
+                                            // expected-note {{floating point 
arithmetic produces an infinity}}
+}

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

Reply via email to