Izaron updated this revision to Diff 461312. Izaron added a comment. Removed whitespaces in comments.
P.S. I wonder if smaller review requests will make things better? Say a review request for `fmax`+`fmin`, then a new one for `ilogb`+`logb`, then for `scalbn`. This may lead to a more understandable and robust review process =) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134136/new/ https://reviews.llvm.org/D134136 Files: clang/docs/LanguageExtensions.rst clang/lib/AST/ExprConstant.cpp clang/test/Sema/constant-builtins-math.cpp llvm/include/llvm/ADT/APFloat.h llvm/lib/Support/APFloat.cpp
Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -4198,6 +4198,19 @@ return Normalized.exponent - SignificandBits; } +IEEEFloat logb(const IEEEFloat &Arg) { + IEEEFloat Result(Arg.getSemantics()); + if (Arg.isNaN()) + Result.makeNaN(); + else if (Arg.isZero()) + Result.makeInf(/*Negative=*/true); + else if (Arg.isInfinity()) + Result.makeInf(/*Negative=*/false); + else + Result = IEEEFloat(static_cast<double>(ilogb(Arg))); + return Result; +} + IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) { auto MaxExp = X.getSemantics().maxExponent; auto MinExp = X.getSemantics().minExponent; Index: llvm/include/llvm/ADT/APFloat.h =================================================================== --- llvm/include/llvm/ADT/APFloat.h +++ llvm/include/llvm/ADT/APFloat.h @@ -592,6 +592,7 @@ hash_code hash_value(const IEEEFloat &Arg); int ilogb(const IEEEFloat &Arg); +IEEEFloat logb(const IEEEFloat &Arg); IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode); IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM); @@ -1248,6 +1249,9 @@ friend hash_code hash_value(const APFloat &Arg); friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); } + friend APFloat logb(const APFloat &Arg) { + return APFloat(logb(Arg.getIEEE()), Arg.getSemantics()); + } friend APFloat scalbn(APFloat X, int Exp, roundingMode RM); friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM); friend IEEEFloat; Index: clang/test/Sema/constant-builtins-math.cpp =================================================================== --- /dev/null +++ clang/test/Sema/constant-builtins-math.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(__builtin_fmax(12.34, 56.78) == 56.78); +static_assert(__builtin_fmaxf(12.34f, 56.78f) == 56.78f); +static_assert(__builtin_fmaxl(12.34, 56.78) == 56.78); +static_assert(__builtin_fmaxf16(12.0, 56.0) == 56.0); +static_assert(__builtin_fmaxf128(12.34, 56.78) == 56.78); + +static_assert(__builtin_fmin(12.34, 56.78) == 12.34); +static_assert(__builtin_fminf(12.34f, 56.78f) == 12.34f); +static_assert(__builtin_fminl(12.34, 56.78) == 12.34); +static_assert(__builtin_fminf16(12.0, 56.0) == 12.0); +static_assert(__builtin_fminf128(12.34, 56.78) == 12.34); + +// TODO: investigate why this is `INT_MIN + 1` instead of `INT_MIN` +static_assert(__builtin_ilogb(0.0) == -2147483647); +static_assert(__builtin_ilogb(__builtin_inf()) == 2147483647); +static_assert(__builtin_ilogb(__builtin_nan("")) == -2147483648); +static_assert(__builtin_ilogb(1.0) == 0); +static_assert(__builtin_ilogb(32.0) == 5); +static_assert(__builtin_ilogb(1024.0) == 10); +static_assert(__builtin_ilogb(-1024.0) == 10); +static_assert(__builtin_ilogb(0.1) == -4); +static_assert(__builtin_ilogb(0.0000000000001) == -44); + +static_assert(__builtin_logb(0.0) == -__builtin_inf()); +static_assert(__builtin_logb(__builtin_inf()) == __builtin_inf()); +static_assert(__builtin_isnan(__builtin_logb(__builtin_nan("")))); +static_assert(__builtin_logb(1.0) == 0.0); +static_assert(__builtin_logb(32.0) == 5.0); +static_assert(__builtin_logb(1024.0) == 10.0); +static_assert(__builtin_logb(-1024.0) == 10.0); +static_assert(__builtin_logb(0.1) == -4.0); +static_assert(__builtin_logb(0.0000000000001) == -44.0); + +static_assert(__builtin_scalbn(12.5, 0) == 12.5); +static_assert(__builtin_scalbn(12.5, 1) == 25); +static_assert(__builtin_scalbn(12.5, 3) == 100.0); +static_assert(__builtin_scalbn(0.0, 100) == 0); +static_assert(__builtin_scalbn(__builtin_inf(), 100) == __builtin_inf()); +static_assert(__builtin_isnan(__builtin_scalbn(__builtin_nan(""), 100))); Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -12410,6 +12410,19 @@ return false; return Success(DidOverflow, E); } + + case Builtin::BI__builtin_ilogb: + case Builtin::BI__builtin_ilogbf: + case Builtin::BI__builtin_ilogbl: + case Builtin::BI__builtin_ilogbf128: { + APFloat F(0.0); + if (!EvaluateFloat(E->getArg(0), F, Info)) + return false; + APSInt Logb(llvm::APInt(32, ilogb(F), /*isSigned=*/true), + /*isUnsigned=*/false); + Result = APValue(std::move(Logb)); + return true; + } } } @@ -14021,6 +14034,58 @@ Result.copySign(RHS); return true; } + + case Builtin::BI__builtin_fmax: + case Builtin::BI__builtin_fmaxf: + case Builtin::BI__builtin_fmaxl: + case Builtin::BI__builtin_fmaxf16: + case Builtin::BI__builtin_fmaxf128: { + APFloat RHS(0.); + if (!EvaluateFloat(E->getArg(0), Result, Info) || + !EvaluateFloat(E->getArg(1), RHS, Info)) + return false; + if (RHS > Result) + Result = RHS; + return true; + } + + case Builtin::BI__builtin_fmin: + case Builtin::BI__builtin_fminf: + case Builtin::BI__builtin_fminl: + case Builtin::BI__builtin_fminf16: + case Builtin::BI__builtin_fminf128: { + APFloat RHS(0.); + if (!EvaluateFloat(E->getArg(0), Result, Info) || + !EvaluateFloat(E->getArg(1), RHS, Info)) + return false; + if (RHS < Result) + Result = RHS; + return true; + } + + case Builtin::BI__builtin_logb: + case Builtin::BI__builtin_logbf: + case Builtin::BI__builtin_logbl: + case Builtin::BI__builtin_logbf128: { + APFloat F(0.0); + if (!EvaluateFloat(E->getArg(0), F, Info)) + return false; + Result = logb(F); + return true; + } + + case Builtin::BI__builtin_scalbn: + case Builtin::BI__builtin_scalbnf: + case Builtin::BI__builtin_scalbnl: + case Builtin::BI__builtin_scalbnf128: { + APFloat X(0.0); + APSInt Exp; + if (!EvaluateFloat(E->getArg(0), X, Info) || + !EvaluateInteger(E->getArg(1), Exp, Info)) + return false; + Result = scalbn(X, Exp.getExtValue(), APFloat::rmNearestTiesToEven); + return true; + } } } Index: clang/docs/LanguageExtensions.rst =================================================================== --- clang/docs/LanguageExtensions.rst +++ clang/docs/LanguageExtensions.rst @@ -4659,13 +4659,17 @@ * ``__builtin_ffs`` * ``__builtin_ffsl`` * ``__builtin_ffsll`` +* ``__builtin_fmax`` +* ``__builtin_fmin`` * ``__builtin_fpclassify`` +* ``__builtin_ilogb`` * ``__builtin_inf`` * ``__builtin_isinf`` * ``__builtin_isinf_sign`` * ``__builtin_isfinite`` * ``__builtin_isnan`` * ``__builtin_isnormal`` +* ``__builtin_logb`` * ``__builtin_nan`` * ``__builtin_nans`` * ``__builtin_parity`` @@ -4682,6 +4686,7 @@ * ``__builtin_rotateright16`` * ``__builtin_rotateright32`` * ``__builtin_rotateright64`` +* ``__builtin_scalbn`` The following x86-specific intrinsics can be used in constant expressions:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits