Skip to content

[C23] Add *_NORM_MAX macros to <float.h> #96643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 10, 2024

Conversation

AaronBallman
Copy link
Collaborator

This adds the *_NORM_MAX macros to <float.h> for freestanding mode in Clang; the values were chosen based on the behavior seen coming from GCC and the values already produced for the *_MAX macros by Clang.

This adds the *_NORM_MAX macros to <float.h> for freestanding mode in
Clang; the values were chosen based on the behavior seen coming from
GCC and the values already produced for the *_MAX macros by Clang.
@AaronBallman AaronBallman added c23 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:headers Headers provided by Clang, e.g. for intrinsics floating-point Floating-point math labels Jun 25, 2024
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:X86 labels Jun 25, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 25, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-x86

Author: Aaron Ballman (AaronBallman)

Changes

This adds the *_NORM_MAX macros to <float.h> for freestanding mode in Clang; the values were chosen based on the behavior seen coming from GCC and the values already produced for the *_MAX macros by Clang.


Full diff: https://github.com/llvm/llvm-project/pull/96643.diff

4 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+3)
  • (modified) clang/lib/Frontend/InitPreprocessor.cpp (+6-1)
  • (modified) clang/lib/Headers/float.h (+13)
  • (modified) clang/test/Headers/float.c (+27)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index df579ae398c5e..8879a77ba4dd9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -336,6 +336,9 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Added the ``FLT_NORM_MAX``, ``DBL_NORM_MAX``, and ``LDBL_NORM_MAX`` to the
+  freestanding implementation of ``<float.h>`` that ships with Clang.
+
 Non-comprehensive list of changes in this release
 -------------------------------------------------
 
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..afc4c16ab685b 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -113,7 +113,11 @@ static T PickFP(const llvm::fltSemantics *Sem, T IEEEHalfVal, T IEEESingleVal,
 
 static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
                               const llvm::fltSemantics *Sem, StringRef Ext) {
-  const char *DenormMin, *Epsilon, *Max, *Min;
+  const char *DenormMin, *NormMax, *Epsilon, *Max, *Min;
+  NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38",
+                   "1.7976931348623157e+308", "1.18973149535723176502e+4932",
+                   "1.79769313486231580793728971405301e+308",
+                   "1.18973149535723176508575932662800702e+4932");
   DenormMin = PickFP(Sem, "5.9604644775390625e-8", "1.40129846e-45",
                      "4.9406564584124654e-324", "3.64519953188247460253e-4951",
                      "4.94065645841246544176568792868221e-324",
@@ -144,6 +148,7 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
   DefPrefix += "_";
 
   Builder.defineMacro(DefPrefix + "DENORM_MIN__", Twine(DenormMin)+Ext);
+  Builder.defineMacro(DefPrefix + "NORM_MAX__", Twine(NormMax)+Ext);
   Builder.defineMacro(DefPrefix + "HAS_DENORM__");
   Builder.defineMacro(DefPrefix + "DIG__", Twine(Digits));
   Builder.defineMacro(DefPrefix + "DECIMAL_DIG__", Twine(DecimalDigits));
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index 642c8f06cc938..61f65dad8debc 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -86,6 +86,12 @@
 #    undef DBL_HAS_SUBNORM
 #    undef LDBL_HAS_SUBNORM
 #  endif
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||              \
+    !defined(__STRICT_ANSI__)
+#    undef FLT_NORM_MAX
+#    undef DBL_NORM_MAX
+#    undef LDBL_NORM_MAX
+#endif
 #endif
 
 /* Characteristics of floating point types, C99 5.2.4.2.2 */
@@ -155,6 +161,13 @@
 #  define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
 #endif
 
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||              \
+    !defined(__STRICT_ANSI__)
+#  define FLT_NORM_MAX __FLT_NORM_MAX__
+#  define DBL_NORM_MAX __DBL_NORM_MAX__
+#  define LDBL_NORM_MAX __LDBL_NORM_MAX__
+#endif
+
 #ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
 #  define FLT16_MANT_DIG    __FLT16_MANT_DIG__
 #  define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__
diff --git a/clang/test/Headers/float.c b/clang/test/Headers/float.c
index 70c11b0537537..59cc0faa074db 100644
--- a/clang/test/Headers/float.c
+++ b/clang/test/Headers/float.c
@@ -1,17 +1,21 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++23 -ffreestanding %s
 // expected-no-diagnostics
 
 /* Basic floating point conformance checks against:
+    - C23 Final Std.
     - N1570 draft of C11 Std.
     - N1256 draft of C99 Std.
     - http://port70.net/~nsz/c/c89/c89-draft.html draft of C89/C90 Std.
 */
 /*
+    C23,    5.2.5.3.3p21,   pp. 25
     C11,    5.2.4.2.2p11,   pp. 30
     C99,    5.2.4.2.2p9,    pp. 25
     C89,    2.2.4.2
@@ -207,6 +211,23 @@
     #error "Mandatory macros {FLT,DBL,LDBL}_MAX_10_EXP are invalid."
 #endif
 
+#if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
+#ifndef FLT_NORM_MAX
+  #error "Mandatory macro FLT_NORM_MAX is missing."
+#else
+  _Static_assert(FLT_NORM_MAX >= 1.0E+37F, "Mandatory macro FLT_NORM_MAX is invalid.");
+#endif
+#ifndef DBL_NORM_MAX
+  #error "Mandatory macro DBL_NORM_MAX is missing."
+#else
+  _Static_assert(DBL_NORM_MAX >= 1.0E+37F, "Mandatory macro DBL_NORM_MAX is invalid.");
+#endif
+#ifndef LDBL_NORM_MAX
+  #error "Mandatory macro LDBL_NORM_MAX is missing."
+#else
+  _Static_assert(LDBL_NORM_MAX >= 1.0E+37F, "Mandatory macro LDBL_NORM_MAX is invalid.");
+#endif
+#endif
 
 /* Internal consistency checks */
 _Static_assert(FLT_RADIX == __FLT_RADIX__, "");
@@ -244,3 +265,9 @@ _Static_assert(LDBL_MAX_EXP == __LDBL_MAX_EXP__, "");
 _Static_assert(FLT_MAX_10_EXP == __FLT_MAX_10_EXP__, "");
 _Static_assert(DBL_MAX_10_EXP == __DBL_MAX_10_EXP__, "");
 _Static_assert(LDBL_MAX_10_EXP == __LDBL_MAX_10_EXP__, "");
+
+#if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
+_Static_assert(FLT_NORM_MAX == __FLT_NORM_MAX__, "");
+_Static_assert(DBL_NORM_MAX == __DBL_NORM_MAX__, "");
+_Static_assert(LDBL_NORM_MAX == __LDBL_NORM_MAX__, "");
+#endif

Copy link

github-actions bot commented Jun 25, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 748a6ad68ba31d242e3f86eddd5b0fd7b2a02ff9 aee0da9de46bfadae00774ec9206f22bf0254d05 -- clang/lib/Frontend/InitPreprocessor.cpp clang/lib/Headers/float.h clang/test/Headers/float.c clang/test/Preprocessor/init-aarch64.c clang/test/Preprocessor/init.c
View the diff from clang-format here.
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index d40d78a385..4ab1e30e5e 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -148,7 +148,7 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
   DefPrefix += "_";
 
   Builder.defineMacro(DefPrefix + "DENORM_MIN__", Twine(DenormMin)+Ext);
-  Builder.defineMacro(DefPrefix + "NORM_MAX__", Twine(NormMax)+Ext);
+  Builder.defineMacro(DefPrefix + "NORM_MAX__", Twine(NormMax) + Ext);
   Builder.defineMacro(DefPrefix + "HAS_DENORM__");
   Builder.defineMacro(DefPrefix + "DIG__", Twine(Digits));
   Builder.defineMacro(DefPrefix + "DECIMAL_DIG__", Twine(DecimalDigits));
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index e5c439a9d4..356c2cab78 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -88,9 +88,9 @@
 #  endif
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||              \
     !defined(__STRICT_ANSI__)
-#    undef FLT_NORM_MAX
-#    undef DBL_NORM_MAX
-#    undef LDBL_NORM_MAX
+#undef FLT_NORM_MAX
+#undef DBL_NORM_MAX
+#undef LDBL_NORM_MAX
 #endif
 #endif
 
@@ -172,10 +172,10 @@
    /* C23 5.2.5.3.3p29-30 */
 #  define INFINITY (__builtin_inff())
 #  define NAN (__builtin_nanf(""))
-   /* C23 5.2.5.3.3p32 */
-#  define FLT_NORM_MAX __FLT_NORM_MAX__
-#  define DBL_NORM_MAX __DBL_NORM_MAX__
-#  define LDBL_NORM_MAX __LDBL_NORM_MAX__
+/* C23 5.2.5.3.3p32 */
+#define FLT_NORM_MAX __FLT_NORM_MAX__
+#define DBL_NORM_MAX __DBL_NORM_MAX__
+#define LDBL_NORM_MAX __LDBL_NORM_MAX__
 #endif
 
 #ifdef __STDC_WANT_IEC_60559_TYPES_EXT__

const char *DenormMin, *NormMax, *Epsilon, *Max, *Min;
NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38",
"1.7976931348623157e+308", "1.18973149535723176502e+4932",
"1.79769313486231580793728971405301e+308",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the correct value for ppc double-double, since double-double is supposed to give a different result for NORM_MAX than MAX (indeed, that's explicitly the point of the new macros!)

Copy link
Collaborator Author

@AaronBallman AaronBallman Jun 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thank you! I see now that GCC uses the following values for long double:

#define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L
#define __LDBL_NORM_MAX__ 8.98846567431157953864652595394501e+307L

https://godbolt.org/z/M1zjxx7K5

so I should probably go with 8.98846567431157953864652595394501e+307 as the value? CC @hubert-reinterpretcast

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping -- I think I've corrected the value (at least, I'm using the same value as GCC in this case).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure this is correct, but I'd rather prefer someone who knows PPC to confirm this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping @hubert-reinterpretcast @chenzheng1030 -- hoping to get this landed for Clang 19, just need verification that the value is correct here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the value is correct for an interpretation where the LDBL_MANT_DIG is 106.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you Hubert!

@AaronBallman AaronBallman merged commit 0e7590a into llvm:main Jul 10, 2024
5 of 7 checks passed
@AaronBallman AaronBallman deleted the aballman/norm_max branch July 10, 2024 13:49
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
This adds the *_NORM_MAX macros to <float.h> for freestanding mode in
Clang; the values were chosen based on the behavior seen coming from GCC
and the values already produced for the *_MAX macros by Clang.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 c23 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:headers Headers provided by Clang, e.g. for intrinsics clang Clang issues not falling into any other category floating-point Floating-point math
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants