[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 10:54:15 PDT 2026
https://github.com/jofrn updated https://github.com/llvm/llvm-project/pull/204981
>From 0e135699c927f73a7b50ef26a481d65b83af147d 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 | 23 ++++++++++++++++++-
libc/test/include/CMakeLists.txt | 2 ++
libc/test/include/iscanonical_test.c | 16 +++++++++++++
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/libc/include/llvm-libc-macros/math-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
index 21d09f1f5e1a4..3a2574161e3e3 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,9 +18,29 @@
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), \
- float: iscanonicalf, \
+ __LIBC_MATH_ISCANONICAL_F16 \
+ __LIBC_MATH_ISCANONICAL_F128 float: iscanonicalf, \
double: iscanonical, \
long double: iscanonicall)(x)
#endif
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