[libc-commits] [libc] [libc][math] Extend iscanonical macro to _Float16 and float128 (PR #204981)

via libc-commits libc-commits at lists.llvm.org
Sun Jun 21 08:23:09 PDT 2026


https://github.com/jofrn created https://github.com/llvm/llvm-project/pull/204981

iscanonical is a C23 type-generic macro, so the f16/f128 variants are surfaced through it rather than as functions in the generated math.h. float128 is only listed when distinct from long double (LDBL_MANT_DIG != 113) to avoid two _Generic associations with compatible types.

>From 5be649dfe54d68f32fcdfb6a67dd3c73b07e60f4 Mon Sep 17 00:00:00 2001
From: jofrn <jo7frn1 at gmail.com>
Date: Sat, 20 Jun 2026 05:26:10 -0700
Subject: [PATCH] [libc][math] Extend iscanonical macro to _Float16 and
 float128

iscanonical is a C23 type-generic macro, so the f16/f128 variants are
surfaced through it rather than as functions in the generated math.h.
float128 is only listed when distinct from long double (LDBL_MANT_DIG !=
113) to avoid two _Generic associations with compatible types.
---
 .../llvm-libc-macros/math-function-macros.h   | 19 +++++++++++++++++++
 libc/test/include/CMakeLists.txt              |  2 ++
 libc/test/include/iscanonical_test.c          | 16 ++++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/libc/include/llvm-libc-macros/math-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
index 21d09f1f5e1a4..5de923dcb0f3c 100644
--- a/libc/include/llvm-libc-macros/math-function-macros.h
+++ b/libc/include/llvm-libc-macros/math-function-macros.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
 #define LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
 
+#include "float16-macros.h" // LIBC_TYPES_HAS_FLOAT16, LIBC_TYPES_HAS_FLOAT128
 #include "math-macros.h"
 
 #ifndef __cplusplus
@@ -17,8 +18,26 @@
       float: issignalingf,                                                     \
       double: issignaling,                                                     \
       long double: issignalingl)(x)
+
+// 'iscanonical' is a C23 type-generic macro (7.12.3.1).  The '_Float16' and
+// 'float128' associations are only added when those types exist, and 'float128'
+// only when it is distinct from 'long double' (otherwise _Generic would have
+// two associations with compatible types).  The 'float128' guard mirrors
+// LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE in
+// src/__support/macros/properties/types.h, which public headers cannot include.
+#ifdef LIBC_TYPES_HAS_FLOAT16
+#define __LIBC_MATH_ISCANONICAL_F16 _Float16 : iscanonicalf16,
+#else
+#define __LIBC_MATH_ISCANONICAL_F16
+#endif
+#if defined(LIBC_TYPES_HAS_FLOAT128) && (LDBL_MANT_DIG != 113)
+#define __LIBC_MATH_ISCANONICAL_F128 float128 : iscanonicalf128,
+#else
+#define __LIBC_MATH_ISCANONICAL_F128
+#endif
 #define iscanonical(x)                                                         \
   _Generic((x),                                                                \
+      __LIBC_MATH_ISCANONICAL_F16 __LIBC_MATH_ISCANONICAL_F128                 \
       float: iscanonicalf,                                                     \
       double: iscanonical,                                                     \
       long double: iscanonicall)(x)
diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index 094a95bab6f53..231dd658be46e 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -437,6 +437,8 @@ add_libc_test(
 #     libc.src.math.iscanonical
 #     libc.src.math.iscanonicalf
 #     libc.src.math.iscanonicall
+#     libc.src.math.iscanonicalf16
+#     libc.src.math.iscanonicalf128
 # )
 
 add_libc_test(
diff --git a/libc/test/include/iscanonical_test.c b/libc/test/include/iscanonical_test.c
index 670b48b0008e3..4fbf0a42e3495 100644
--- a/libc/test/include/iscanonical_test.c
+++ b/libc/test/include/iscanonical_test.c
@@ -5,9 +5,17 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+#include "include/llvm-libc-macros/float16-macros.h"
+
 int iscanonical(double);
 int iscanonicalf(float);
 int iscanonicall(long double);
+#ifdef LIBC_TYPES_HAS_FLOAT16
+int iscanonicalf16(_Float16);
+#endif
+#if defined(LIBC_TYPES_HAS_FLOAT128) && (LDBL_MANT_DIG != 113)
+int iscanonicalf128(float128);
+#endif
 
 #include "include/llvm-libc-macros/math-function-macros.h"
 
@@ -24,6 +32,14 @@ int main(void) {
   assert(iscanonical(1.819f) == 1);
   assert(iscanonical(-1.726) == 1);
   assert(iscanonical(1.426L) == 1);
+#ifdef LIBC_TYPES_HAS_FLOAT16
+  assert(iscanonical(__builtin_nansf16("")) == 0);
+  assert(iscanonical((_Float16)1.0) == 1);
+#endif
+#if defined(LIBC_TYPES_HAS_FLOAT128) && (LDBL_MANT_DIG != 113)
+  assert(iscanonical(__builtin_nansf128("")) == 0);
+  assert(iscanonical((float128)1.0) == 1);
+#endif
   return 0;
 }
 #endif



More information about the libc-commits mailing list