[llvm-branch-commits] [libc] [libc][cmake] Add LIBC_INCLUDE_SIZE_CHECKS and object size checks (PR #233197)

Prabhu Rajasekaran via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Oct 17 23:45:10 PDT 2026


https://github.com/Prabhuk created https://github.com/llvm/llvm-project/pull/233197

Add the LIBC_INCLUDE_SIZE_CHECKS option (default OFF) and the
check-libc-size target, which runs libc/utils/size_check/
libc_size_check.py over every math entrypoint object of the build.

The option is independent of LLVM_INCLUDE_TESTS because the baremetal
caches turn tests off, and the checks only build and inspect objects,
so they also work for cross builds without an emulator. When tests are
enabled, check-libc depends on check-libc-size.

LLVMLibCSizeCheckRules.cmake finds llvm-nm and llvm-size next to the
compiler, writes a manifest of the entrypoint objects (following
entrypoint aliases), and dumps the predefined macros of the compiler
once per distinct set of compile options, because some entrypoints are
built with extra target options (e.g. -mfma on x86-64).

rules/math.json starts with generic rules:

  * skip-accurate-no-multiprecision: with LIBC_MATH_SKIP_ACCURATE_PASS,
    no DyadicFloat<128+>, BigInt, *_f128 or *accurate* helpers, except
    for correctly rounded basic operations (fma, narrowing arithmetic)
    and f128/long double variants.
  * small-tables-max-object: with LIBC_MATH_SMALL_TABLES, no named data
    object above 512 bytes, with ratcheting per-function ceilings for
    the tables that remain today.
  * no-writable-data(-round-nearest): no .data/.bss, except for the
    rounding mode probes of fputil::generic, which must also be gone
    with LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY.
  * float-comp-no-soft-double: with LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT,
    logf, log2f, log10f, expf, exp2f, exp10f, atanf and powf must not
    call double precision soft-float helpers on targets without a
    hardware double precision FPU. logf, log2f and log10f are known
    exceptions until their float-only implementation lands.

The rules pass on x86-64 (default and optimized configurations, with
and without -march=native) and on the armv6m, armv7m, armv7em,
armv8m.main, armv8m.main-eabihf and armv8.1m.main baremetal caches.

Assisted-by: Gemini

---

<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

>From aaed13c22d61c7476d01f8d9b9c8f23c7c0df662 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Sat, 17 Oct 2026 17:12:38 +0000
Subject: [PATCH] [libc][cmake] Add LIBC_INCLUDE_SIZE_CHECKS and object size
 checks

Add the LIBC_INCLUDE_SIZE_CHECKS option (default OFF) and the
check-libc-size target, which runs libc/utils/size_check/
libc_size_check.py over every math entrypoint object of the build.

The option is independent of LLVM_INCLUDE_TESTS because the baremetal
caches turn tests off, and the checks only build and inspect objects,
so they also work for cross builds without an emulator. When tests are
enabled, check-libc depends on check-libc-size.

LLVMLibCSizeCheckRules.cmake finds llvm-nm and llvm-size next to the
compiler, writes a manifest of the entrypoint objects (following
entrypoint aliases), and dumps the predefined macros of the compiler
once per distinct set of compile options, because some entrypoints are
built with extra target options (e.g. -mfma on x86-64).

rules/math.json starts with generic rules:

  * skip-accurate-no-multiprecision: with LIBC_MATH_SKIP_ACCURATE_PASS,
    no DyadicFloat<128+>, BigInt, *_f128 or *accurate* helpers, except
    for correctly rounded basic operations (fma, narrowing arithmetic)
    and f128/long double variants.
  * small-tables-max-object: with LIBC_MATH_SMALL_TABLES, no named data
    object above 512 bytes, with ratcheting per-function ceilings for
    the tables that remain today.
  * no-writable-data(-round-nearest): no .data/.bss, except for the
    rounding mode probes of fputil::generic, which must also be gone
    with LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY.
  * float-comp-no-soft-double: with LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT,
    logf, log2f, log10f, expf, exp2f, exp10f, atanf and powf must not
    call double precision soft-float helpers on targets without a
    hardware double precision FPU. logf, log2f and log10f are known
    exceptions until their float-only implementation lands.

The rules pass on x86-64 (default and optimized configurations, with
and without -march=native) and on the armv6m, armv7m, armv7em,
armv8m.main, armv8m.main-eabihf and armv8.1m.main baremetal caches.

Assisted-by: Gemini
---
 libc/CMakeLists.txt                           |   8 +
 .../modules/LLVMLibCSizeCheckRules.cmake      | 161 ++++++++++++++++++
 libc/utils/CMakeLists.txt                     |   4 +
 libc/utils/size_check/CMakeLists.txt          |  38 +++++
 libc/utils/size_check/README.md               |  42 +++++
 libc/utils/size_check/rules/math.json         |  74 ++++++++
 6 files changed, 327 insertions(+)
 create mode 100644 libc/cmake/modules/LLVMLibCSizeCheckRules.cmake
 create mode 100644 libc/utils/size_check/CMakeLists.txt
 create mode 100644 libc/utils/size_check/rules/math.json

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index b6c6b0aa546e2d..465c01befbaeeb 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -523,10 +523,15 @@ if(LLVM_LIBC_INCLUDE_SCUDO)
 endif()
 
 option(LIBC_INCLUDE_DOCS "Build the libc documentation." ${LLVM_INCLUDE_DOCS})
+option(LIBC_INCLUDE_SIZE_CHECKS
+  "Add the check-libc-size target that checks the binary size of libc objects" OFF)
 
 include(LLVMLibCCheckCpuFeatures)
 include(CheckCompilerFeatures)
 include(LLVMLibCRules)
+if(LIBC_INCLUDE_SIZE_CHECKS)
+  include(LLVMLibCSizeCheckRules)
+endif()
 
 set(TARGET_LLVMLIBC_ENTRYPOINTS "")
 set(TARGET_LIBC_ENTRYPOINTS "")
@@ -603,6 +608,9 @@ add_subdirectory(lib)
 if(LLVM_INCLUDE_TESTS)
   add_subdirectory(test)
   add_subdirectory(fuzzing)
+  if(TARGET check-libc AND TARGET check-libc-size)
+    add_dependencies(check-libc check-libc-size)
+  endif()
 endif()
 
 add_subdirectory(benchmarks)
diff --git a/libc/cmake/modules/LLVMLibCSizeCheckRules.cmake b/libc/cmake/modules/LLVMLibCSizeCheckRules.cmake
new file mode 100644
index 00000000000000..d1b5b4ed927802
--- /dev/null
+++ b/libc/cmake/modules/LLVMLibCSizeCheckRules.cmake
@@ -0,0 +1,161 @@
+# Rules for checking the binary size of LLVM libc entrypoints.
+#
+# These checks only build and inspect objects; they never execute target code,
+# so they work for cross and baremetal builds. They are enabled with
+# LIBC_INCLUDE_SIZE_CHECKS, independently of LLVM_INCLUDE_TESTS. See
+# libc/utils/size_check/README.md for details.
+
+# Finds an LLVM binary utility, preferring the one next to the compiler.
+function(_libc_size_check_find_tool output_var tool)
+  if(${output_var})
+    return()
+  endif()
+  set(candidate "")
+  execute_process(
+    COMMAND ${CMAKE_CXX_COMPILER} -print-prog-name=${tool}
+    OUTPUT_VARIABLE candidate
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    RESULT_VARIABLE result
+    ERROR_QUIET
+  )
+  if(result EQUAL 0 AND IS_ABSOLUTE "${candidate}" AND EXISTS "${candidate}")
+    set(${output_var} "${candidate}" CACHE FILEPATH "Path to ${tool}")
+    return()
+  endif()
+  get_filename_component(compiler_dir ${CMAKE_CXX_COMPILER} DIRECTORY)
+  find_program(
+    ${output_var}
+    NAMES ${tool} ${tool}-${LLVM_VERSION_MAJOR}
+    HINTS ${compiler_dir} ${LLVM_TOOLS_DIR}
+  )
+endfunction()
+
+# Writes the predefined macros of the compiler for the given compile options to
+# `output_file`. The size checker uses them to select target specific rules.
+function(_libc_size_check_dump_macros output_file)
+  set(cmd ${CMAKE_CXX_COMPILER})
+  if(CMAKE_CXX_COMPILER_TARGET)
+    list(APPEND cmd "--target=${CMAKE_CXX_COMPILER_TARGET}")
+  endif()
+  separate_arguments(cxx_flags NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
+  list(APPEND cmd ${cxx_flags})
+  foreach(opt IN LISTS ARGN)
+    if(opt MATCHES "^SHELL:(.*)$")
+      separate_arguments(shell_opts NATIVE_COMMAND "${CMAKE_MATCH_1}")
+      list(APPEND cmd ${shell_opts})
+    else()
+      list(APPEND cmd ${opt})
+    endif()
+  endforeach()
+  list(APPEND cmd -dM -E -x c++ /dev/null)
+  get_filename_component(output_dir ${output_file} DIRECTORY)
+  file(MAKE_DIRECTORY ${output_dir})
+  execute_process(
+    COMMAND ${cmd}
+    OUTPUT_FILE ${output_file}
+    RESULT_VARIABLE result
+    ERROR_VARIABLE error
+  )
+  if(NOT result EQUAL 0)
+    message(WARNING "libc size checks: failed to dump the predefined macros "
+      "(${error}); target specific rules will be inactive.")
+    file(WRITE ${output_file} "")
+  endif()
+endfunction()
+
+# Follows entrypoint aliases (e.g. libc.src.math.logf ->
+# libc.src.math.generic.logf) to the target that builds the object.
+function(_libc_size_check_resolve_entrypoint output_var target)
+  set(${output_var} "" PARENT_SCOPE)
+  set(current ${target})
+  while(TRUE)
+    if(NOT TARGET ${current})
+      return()
+    endif()
+    get_target_property(skipped ${current} "SKIPPED")
+    if(skipped)
+      return()
+    endif()
+    get_target_property(is_alias ${current} "IS_ALIAS")
+    if(NOT is_alias)
+      break()
+    endif()
+    get_target_property(current ${current} "DEPS")
+  endwhile()
+  set(${output_var} ${current} PARENT_SCOPE)
+endfunction()
+
+# Adds a check of the entrypoint objects whose target names match
+# `ENTRYPOINT_REGEX` against the rules in `RULES`.
+#
+# Usage:
+#   add_libc_object_size_check(
+#     <name>
+#     ENTRYPOINT_REGEX <regex matching fully qualified entrypoint targets>
+#     RULES <rules JSON file>
+#   )
+#
+# This creates the target `<name>` that writes `<name>.json` and `<name>.md`
+# reports to the current binary directory and fails if a rule is violated.
+function(add_libc_object_size_check name)
+  cmake_parse_arguments(
+    "SIZE_CHECK"
+    "" # Optional arguments
+    "ENTRYPOINT_REGEX;RULES" # Single value arguments
+    "" # Multi value arguments
+    ${ARGN}
+  )
+  set(manifest_lines "")
+  set(object_targets "")
+  set(macro_files "")
+  foreach(entrypoint IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
+    if(NOT entrypoint MATCHES "${SIZE_CHECK_ENTRYPOINT_REGEX}")
+      continue()
+    endif()
+    _libc_size_check_resolve_entrypoint(object_target ${entrypoint})
+    if(NOT object_target)
+      continue()
+    endif()
+    get_target_property(entrypoint_name ${object_target} "ENTRYPOINT_NAME")
+    get_target_property(flags ${object_target} "FLAGS")
+    if(NOT flags)
+      set(flags "")
+    endif()
+    # Entrypoints can be compiled with different target options depending on
+    # their flags (e.g. -mfma for FMA_OPT on x86-64), so dump the macros once
+    # per distinct set of compile options.
+    _get_common_compile_options(compile_options "${flags}")
+    string(MD5 options_hash "${compile_options}")
+    string(SUBSTRING ${options_hash} 0 12 options_hash)
+    set(macro_file ${CMAKE_CURRENT_BINARY_DIR}/macros/${options_hash}.txt)
+    if(NOT macro_file IN_LIST macro_files)
+      _libc_size_check_dump_macros(${macro_file} ${compile_options})
+      list(APPEND macro_files ${macro_file})
+    endif()
+    string(APPEND manifest_lines
+      "${entrypoint_name}\t${macro_file}\t$<TARGET_OBJECTS:${object_target}>\n")
+    list(APPEND object_targets ${object_target})
+  endforeach()
+
+  set(manifest ${CMAKE_CURRENT_BINARY_DIR}/${name}.manifest)
+  file(GENERATE OUTPUT ${manifest} CONTENT "${manifest_lines}")
+  add_custom_target(
+    ${name}
+    COMMAND
+      ${Python3_EXECUTABLE} ${LIBC_SIZE_CHECK_SCRIPT} objects
+      --manifest ${manifest}
+      --rules ${SIZE_CHECK_RULES}
+      "--math-optimizations=${LIBC_CONF_MATH_OPTIMIZATIONS}"
+      --nm ${LIBC_SIZE_CHECK_NM}
+      --size ${LIBC_SIZE_CHECK_SIZE}
+      --json ${CMAKE_CURRENT_BINARY_DIR}/${name}.json
+      --markdown ${CMAKE_CURRENT_BINARY_DIR}/${name}.md
+    DEPENDS ${manifest} ${SIZE_CHECK_RULES} ${LIBC_SIZE_CHECK_SCRIPT}
+    COMMENT "Checking the binary size of libc objects against ${SIZE_CHECK_RULES}"
+    USES_TERMINAL
+    VERBATIM
+  )
+  if(object_targets)
+    add_dependencies(${name} ${object_targets})
+  endif()
+endfunction()
diff --git a/libc/utils/CMakeLists.txt b/libc/utils/CMakeLists.txt
index b85136f2d420f4..9dd06f2e1451ba 100644
--- a/libc/utils/CMakeLists.txt
+++ b/libc/utils/CMakeLists.txt
@@ -1,5 +1,9 @@
 add_subdirectory(hdrgen)
 
+if(LIBC_INCLUDE_SIZE_CHECKS)
+  add_subdirectory(size_check)
+endif()
+
 if(LLVM_INCLUDE_TESTS)
   add_subdirectory(MPFRWrapper)
   add_subdirectory(MPCWrapper)
diff --git a/libc/utils/size_check/CMakeLists.txt b/libc/utils/size_check/CMakeLists.txt
new file mode 100644
index 00000000000000..c73f1ac279c3db
--- /dev/null
+++ b/libc/utils/size_check/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Binary size checks for libc entrypoints. See README.md.
+
+if(LIBC_TARGET_OS_IS_DARWIN OR LIBC_TARGET_OS_IS_WINDOWS OR
+  LIBC_TARGET_OS_IS_GPU OR LIBC_TARGET_OS_IS_UEFI)
+  message(STATUS "libc size checks are only supported for ELF targets; "
+    "skipping them for ${LIBC_TARGET_TRIPLE}.")
+  return()
+endif()
+
+_libc_size_check_find_tool(LIBC_SIZE_CHECK_NM llvm-nm)
+_libc_size_check_find_tool(LIBC_SIZE_CHECK_SIZE llvm-size)
+if(NOT LIBC_SIZE_CHECK_NM OR NOT LIBC_SIZE_CHECK_SIZE)
+  message(WARNING "libc size checks need llvm-nm and llvm-size; set "
+    "LIBC_SIZE_CHECK_NM and LIBC_SIZE_CHECK_SIZE to enable them.")
+  return()
+endif()
+
+set(LIBC_SIZE_CHECK_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/libc_size_check.py)
+
+add_custom_target(
+  check-libc-size-unittests
+  COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/libc_size_check_test.py
+  COMMENT "Running the libc size checker unit tests"
+  USES_TERMINAL
+)
+
+add_libc_object_size_check(
+  libc-size-check-math-objects
+  ENTRYPOINT_REGEX "^libc\\.src\\.math\\."
+  RULES ${CMAKE_CURRENT_SOURCE_DIR}/rules/math.json
+)
+
+add_custom_target(check-libc-size)
+add_dependencies(
+  check-libc-size
+  check-libc-size-unittests
+  libc-size-check-math-objects
+)
diff --git a/libc/utils/size_check/README.md b/libc/utils/size_check/README.md
index f5fb04bf0efa1f..37f30f2ae132a6 100644
--- a/libc/utils/size_check/README.md
+++ b/libc/utils/size_check/README.md
@@ -10,6 +10,48 @@ The checks never execute target code. They only inspect objects with
 `llvm-nm` and `llvm-size`, so they work the same way for host, cross and
 baremetal builds.
 
+## Running the checks
+
+Configure libc with `-DLIBC_INCLUDE_SIZE_CHECKS=ON` and build the
+`check-libc-size` target:
+
+```
+cmake -S runtimes -B build -G Ninja -DLLVM_ENABLE_RUNTIMES=libc \
+    -DLIBC_INCLUDE_SIZE_CHECKS=ON \
+    "-DLIBC_CONF_MATH_OPTIMIZATIONS=(LIBC_MATH_SKIP_ACCURATE_PASS|LIBC_MATH_SMALL_TABLES)"
+ninja -C build check-libc-size
+```
+
+The option is independent of `LLVM_INCLUDE_TESTS`, which is off in the
+baremetal caches, e.g.:
+
+```
+cmake -S runtimes -B build -G Ninja -DCMAKE_C_COMPILER=clang \
+    -DCMAKE_CXX_COMPILER=clang++ -DLLVM_USE_LINKER=lld \
+    -DLIBC_INCLUDE_SIZE_CHECKS=ON -C libc/cmake/caches/armv7em-none-eabi.cmake
+ninja -C build check-libc-size
+```
+
+`check-libc-size` runs the unit tests of the checker and checks every math
+entrypoint object against `rules/math.json`. The reports are written to
+`<build>/libc/utils/size_check/libc-size-check-math-objects.{json,md}`. When
+tests are enabled, `check-libc` depends on `check-libc-size`.
+
+The checks support ELF targets only and need `llvm-nm` and `llvm-size`. They
+are looked up next to the compiler, then on `PATH` and in `LLVM_TOOLS_DIR`;
+set `LIBC_SIZE_CHECK_NM` and `LIBC_SIZE_CHECK_SIZE` to override them.
+
+Some entrypoints are compiled with extra target options (for example `-mfma`
+on x86-64 when the host supports it), so the predefined macros used by
+`when_macros` are dumped once per distinct set of compile options.
+
+## Updating the rules
+
+When a change legitimately grows a function, update `rules/math.json` in the
+same change so reviewers see it. When a change shrinks a function, the
+checker's notes (`--verbose`, or the reports) point out exceptions and limits
+that can be tightened.
+
 ## The checker
 
 `libc_size_check.py objects` reads a manifest of entrypoint objects, runs
diff --git a/libc/utils/size_check/rules/math.json b/libc/utils/size_check/rules/math.json
new file mode 100644
index 00000000000000..e359b86fa1e20b
--- /dev/null
+++ b/libc/utils/size_check/rules/math.json
@@ -0,0 +1,74 @@
+{
+  "version": 1,
+  "symbol_prefix_regex": "^__llvm_libc[0-9A-Za-z_]*::",
+  "regex_aliases": {
+    "soft_double_helpers": "__aeabi_(dadd|dsub|drsub|dmul|ddiv|dneg|dcmp[a-z]+|cdcmp[a-z]+|cdrcmp[a-z]+|f2d|d2f|i2d|ui2d|l2d|ul2d|d2iz|d2uiz|d2lz|d2ulz)|__(add|sub|mul|div|neg)df3|__extendsfdf2|__truncdfsf2|__float(un)?(si|di|ti)df|__fix(uns)?df(si|di|ti)|__(eq|ne|lt|le|gt|ge|un|cmp)df2"
+  },
+  "rules": [
+    {
+      "id": "skip-accurate-no-multiprecision",
+      "comment": "With LIBC_MATH_SKIP_ACCURATE_PASS, functions must not contain the multi-precision helpers used by the accurate pass. The exceptions are correctly rounded basic operations (fused multiply-add and narrowing arithmetic) that use DyadicFloat as their main algorithm rather than as an accurate pass. f128 and long double variants inherently need wide arithmetic.",
+      "when_flags": ["LIBC_MATH_SKIP_ACCURATE_PASS"],
+      "exclude_variants": ["f128", "long_double"],
+      "exceptions": ["bf16fma", "bf16mul", "daddl", "ddivl", "dfmal", "dmull", "dsqrtl", "dsubl", "f16fma", "f16mul", "ffma", "fma", "fmul"],
+      "forbid_defined_regex": ["DyadicFloat<(128|192|256)u?l?>", "BigInt<", "_f128\\(", "_f256\\(", "accurate"]
+    },
+    {
+      "id": "small-tables-max-object",
+      "comment": "With LIBC_MATH_SMALL_TABLES, no named data object may exceed 512 bytes. The exceptions are ceilings for the current tables; lower or remove them as tables shrink.",
+      "when_flags": ["LIBC_MATH_SMALL_TABLES"],
+      "max_named_data_object_bytes": 512,
+      "max_named_data_object_exceptions": {
+        "atan": {"bytes": 1040, "note": "atan_internal::ATAN_I; a smaller table is pending"},
+        "atan2": {"bytes": 1040, "note": "atan_internal::ATAN_I; a smaller table is pending"},
+        "atan2f128": 1560,
+        "atan2f16": 1224,
+        "atan2l": 1560,
+        "cbrtbf16": 896,
+        "cbrtf": 896,
+        "cos": 2048,
+        "erff": 2048,
+        "exp": {"bytes": 1536, "note": "EXP2_MID1/EXP2_MID2; smaller tables are pending"},
+        "exp10": {"bytes": 1536, "note": "EXP2_MID1/EXP2_MID2; smaller tables are pending"},
+        "expm1": 1536,
+        "expm1f": 1560,
+        "lgammaf": 2048,
+        "log": 2048,
+        "log10": 2048,
+        "log10f": {"bytes": 1024, "note": "128-entry log tables; smaller tables are pending"},
+        "log1p": 2064,
+        "log2": {"bytes": 2048, "note": "log2_internal::LOG_R1; smaller tables are pending"},
+        "log2f": {"bytes": 1024, "note": "128-entry log tables; smaller tables are pending"},
+        "logf": {"bytes": 1024, "note": "128-entry log tables; smaller tables are pending"},
+        "pow": {"bytes": 2048, "note": "pow_internal::LOG2_R_DD; smaller tables are pending"},
+        "sin": 2048,
+        "sincos": 2048,
+        "tan": 2048
+      }
+    },
+    {
+      "id": "no-writable-data",
+      "comment": "Math functions must not have writable data. The only exceptions are the static volatile variables that the functions in fputil::generic (FPUtil/rounding_mode.h) use to probe the rounding mode, which are not used with LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY (see no-writable-data-round-nearest).",
+      "max_writable_data_bytes": 0,
+      "allow_writable_sections": ["^\\.data\\._ZZN[0-9]+__llvm_libc[0-9A-Za-z_]*6fputil7generic[0-9]+(quick_get_round|fenv_is_round_(up|down|to_nearest|to_zero))EvE1x$"]
+    },
+    {
+      "id": "no-writable-data-round-nearest",
+      "when_flags": ["LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY"],
+      "max_writable_data_bytes": 0
+    },
+    {
+      "id": "float-comp-no-soft-double",
+      "comment": "With LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT, these single precision functions must not call double precision soft-float helpers on targets without a hardware double precision FPU.",
+      "when_flags": ["LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT"],
+      "when_macros": ["__arm__ || __riscv", "!__ARM_FP&0x8", "!__riscv_flen&64"],
+      "functions": ["logf", "log2f", "log10f", "expf", "exp2f", "exp10f", "atanf", "powf"],
+      "forbid_undefined": ["@soft_double_helpers"],
+      "known_exceptions": {
+        "logf": {"symbols": ["@soft_double_helpers"], "note": "a float-only implementation is pending"},
+        "log2f": {"symbols": ["@soft_double_helpers"], "note": "a float-only implementation is pending"},
+        "log10f": {"symbols": ["@soft_double_helpers"], "note": "a float-only implementation is pending"}
+      }
+    }
+  ]
+}



More information about the llvm-branch-commits mailing list