Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/compiler-rt-libc-builtins-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,62 @@
--build build \
--parallel \
--target check-builtins

# Build the libc-backed builtins against only the extracted shared subset, so
# the build fails if they ever reach into the rest of libc.
isolation:
name: builtins isolation (subset-only build)
if: github.repository_owner == 'llvm'
runs-on: ubuntu-24.04
container:
image: ghcr.io/llvm/libc-ubuntu-24.04

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hash pin?


steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Manifest matches the live header closure
shell: bash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be the default?

run: |
d="compiler-rt/lib/builtins/libc-isolation"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

More descriptive variable name?

if ! diff -u \
<(grep -v '^#' "$d/libc-shared-manifest.txt") \
<(CXX=clang++-23 bash "$d/libc-shared-closure.sh"); then
echo "::error::libc-shared-manifest.txt is stale. Regenerate it with:"
echo " CXX=clang++-23 $d/regen-manifest.sh"
exit 1
fi

- name: Extract the shared subset
run: |
d="compiler-rt/lib/builtins/libc-isolation"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A more descriptive variable name might be nice.

cmake \
-DLIBC_ROOT="$PWD/libc" \
-DDEST="$PWD/libc-shared-subset" \
-DMANIFEST="$PWD/$d/libc-shared-manifest.txt" \
-P "$d/export-libc-shared.cmake"

- name: Configure CMake against the subset only
run: |
cmake \
-B build-iso \
-S runtimes \
-DLLVM_ENABLE_RUNTIMES=compiler-rt \
-G Ninja \
-DCMAKE_C_COMPILER=clang-23 \
-DCMAKE_CXX_COMPILER=clang++-23 \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCOMPILER_RT_STANDALONE_BUILD=ON \
-DCOMPILER_RT_USE_LIBC_MATH=ON \
-DCOMPILER_RT_LIBC_SHARED_INCLUDE_ROOT="$PWD/libc-shared-subset" \
-DLLVM_EXTERNAL_LIT=$(which lit-23) \
-DCOMPILER_RT_INCLUDE_TESTS=ON

- name: Build and test builtins against the subset
run: |
cmake \
--build build-iso \
--parallel \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This probably isn't necessary to say explicitly?

--target check-builtins
26 changes: 26 additions & 0 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,15 @@ set(x86_80_BIT_SOURCES
option(COMPILER_RT_USE_LIBC_MATH
"Use LLVM libc math routines for floating-point builtins" OFF)

# libc include root; point at an isolated subset (see libc-isolation/) to prove
# the builtins build against that subset alone. Empty = the in-tree libc.
set(COMPILER_RT_LIBC_SHARED_INCLUDE_ROOT "" CACHE PATH
"Include root for the libc-backed builtins (default: the LLVM-libc source tree)")

# Where compiler-rt-export-libc-shared writes that subset (per the manifest).
set(COMPILER_RT_LIBC_SHARED_EXPORT_DIR "" CACHE PATH
"Destination for the extracted LLVM-libc shared subset (see libc-isolation/)")

# Swap the legacy soft-float <name>.c builtin in <list> for the libc-backed
# <name>.cpp implementation (which delegates to LIBC_NAMESPACE::shared::*).
macro(use_libc_builtin list_var name)
Expand All @@ -282,9 +291,26 @@ if(COMPILER_RT_USE_LIBC_MATH)

get_target_property(_libc_include_dirs llvm-libc-common-utilities
INTERFACE_INCLUDE_DIRECTORIES)
set(_libc_root ${_libc_include_dirs})

if(COMPILER_RT_LIBC_SHARED_INCLUDE_ROOT)
set(_libc_include_dirs ${COMPILER_RT_LIBC_SHARED_INCLUDE_ROOT})
endif()

include_directories(SYSTEM ${_libc_include_dirs})
add_definitions(-DCOMPILER_RT_USE_LIBC_MATH)

if(COMPILER_RT_LIBC_SHARED_EXPORT_DIR)
add_custom_target(compiler-rt-export-libc-shared
COMMAND ${CMAKE_COMMAND}
-DLIBC_ROOT=${_libc_root}
-DDEST=${COMPILER_RT_LIBC_SHARED_EXPORT_DIR}
-DMANIFEST=${CMAKE_CURRENT_SOURCE_DIR}/libc-isolation/libc-shared-manifest.txt
-P ${CMAKE_CURRENT_SOURCE_DIR}/libc-isolation/export-libc-shared.cmake
VERBATIM
COMMENT "Exporting LLVM-libc shared subset to ${COMPILER_RT_LIBC_SHARED_EXPORT_DIR}")
endif()

use_libc_builtin(GENERIC_SOURCES adddf3)
use_libc_builtin(GENERIC_SOURCES addsf3)
use_libc_builtin(GENERIC_TF_SOURCES addtf3)
Expand Down
25 changes: 25 additions & 0 deletions compiler-rt/lib/builtins/libc-isolation/export-libc-shared.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copy the manifest's libc headers into DEST, preserving their paths, so

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

libc-isolation tools (.sh) and manifests should stay inside libc/utils.

The export-libc-shared.cmake should stay in llvm-project/cmake/Modules, maybe merge it with llvm-project/cmake/Modules/FindLibcCommonUtils.cmake?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you also generate manifest for shared/math?

# compiler-rt can build the libc-backed builtins against that subset alone.
#
# cmake -DLIBC_ROOT=<libc> -DDEST=<dir> -DMANIFEST=<file> -P export-libc-shared.cmake

if(NOT LIBC_ROOT OR NOT DEST OR NOT MANIFEST)
message(FATAL_ERROR "set LIBC_ROOT, DEST and MANIFEST")
endif()

file(STRINGS "${MANIFEST}" _lines)
set(_count 0)
foreach(_rel IN LISTS _lines)
string(STRIP "${_rel}" _rel)
if(_rel STREQUAL "" OR _rel MATCHES "^#")
continue()
endif()
if(NOT EXISTS "${LIBC_ROOT}/${_rel}")
message(FATAL_ERROR "manifest lists a missing file: ${LIBC_ROOT}/${_rel}")
endif()
get_filename_component(_dstdir "${DEST}/${_rel}" DIRECTORY)
file(MAKE_DIRECTORY "${_dstdir}")
configure_file("${LIBC_ROOT}/${_rel}" "${DEST}/${_rel}" COPYONLY)
math(EXPR _count "${_count} + 1")
endforeach()
message(STATUS "export-libc-shared: copied ${_count} files into ${DEST}")
34 changes: 34 additions & 0 deletions compiler-rt/lib/builtins/libc-isolation/libc-shared-closure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Print the libc headers the compiler-rt libc-backed builtins include, one
# libc-root-relative path per line, sorted. Used to regenerate the manifest and
# to drift-check it in CI. Run from the llvm-project root; override with CXX=.
set -euo pipefail

CXX="${CXX:-clang++}"
LIBC_ROOT="${LIBC_ROOT:-libc}"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
printf '#include "shared/builtins.h"\n' > "$tmp/probe.cpp"

"$CXX" -std=c++17 \
-DLIBC_NAMESPACE=__llvm_libc_common_utils \
-DLIBC_MATH=12 \
-I "$LIBC_ROOT" -I "$LIBC_ROOT/include" \
-MM -MG "$tmp/probe.cpp" 2>/dev/null \
| tr ' \\' '\n\n' \
| grep -E "^$LIBC_ROOT/" \
| LIBC_ROOT="$LIBC_ROOT" python3 -c '
import os, sys
libc = os.path.abspath(os.environ["LIBC_ROOT"])
seen = set()
for line in sys.stdin:
p = line.strip()
if not p:
continue
rel = os.path.relpath(os.path.normpath(os.path.abspath(p)), libc)
if not rel.startswith(".."):
seen.add(rel)
for rel in sorted(seen):
print(rel)
'
227 changes: 227 additions & 0 deletions compiler-rt/lib/builtins/libc-isolation/libc-shared-manifest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
# Auto-generated by regen-manifest.sh -- do not edit by hand.
# The libc headers the compiler-rt libc-backed builtins include,
# libc-root-relative. Regenerate after changing those includes.
hdr/errno_macros.h
hdr/fenv_macros.h
hdr/float_macros.h
hdr/limits_macros.h
hdr/math_macros.h
hdr/stdint_proxy.h
hdr/types/fenv_t.h
hdr/types/size_t.h
include/llvm-libc-macros/cfloat128-macros.h
include/llvm-libc-macros/cfloat16-macros.h
include/llvm-libc-macros/float-macros.h
include/llvm-libc-macros/float16-macros.h
include/llvm-libc-macros/stdfix-macros.h
include/llvm-libc-types/cfloat128.h
include/llvm-libc-types/cfloat16.h
include/llvm-libc-types/float128.h
shared/builtins.h
shared/builtins/adddf3.h
shared/builtins/addsf3.h
shared/builtins/addtf3.h
shared/builtins/divdf3.h
shared/builtins/divsf3.h
shared/builtins/divtf3.h
shared/builtins/extenddftf2.h
shared/builtins/extendsfdf2.h
shared/builtins/extendsftf2.h
shared/builtins/extendxftf2.h
shared/builtins/fixdfdi.h
shared/builtins/fixdfsi.h
shared/builtins/fixdfti.h
shared/builtins/fixsfdi.h
shared/builtins/fixsfsi.h
shared/builtins/fixsfti.h
shared/builtins/fixunsdfdi.h
shared/builtins/fixunsdfsi.h
shared/builtins/fixunsdfti.h
shared/builtins/fixunssfdi.h
shared/builtins/fixunssfsi.h
shared/builtins/fixunssfti.h
shared/builtins/floatdidf.h
shared/builtins/floatdisf.h
shared/builtins/floatsidf.h
shared/builtins/floatsisf.h
shared/builtins/floattidf.h
shared/builtins/floattisf.h
shared/builtins/floatundidf.h
shared/builtins/floatundisf.h
shared/builtins/floatunsidf.h
shared/builtins/floatunsisf.h
shared/builtins/floatuntidf.h
shared/builtins/floatuntisf.h
shared/builtins/gesf2.h
shared/builtins/lesf2.h
shared/builtins/muldf3.h
shared/builtins/mulsf3.h
shared/builtins/multf3.h
shared/builtins/negdf2.h
shared/builtins/negsf2.h
shared/builtins/subdf3.h
shared/builtins/subsf3.h
shared/builtins/subtf3.h
shared/builtins/truncdfsf2.h
shared/builtins/trunctfdf2.h
shared/builtins/trunctfsf2.h
shared/builtins/trunctfxf2.h
shared/builtins/unordsf2.h
shared/libc_common.h
src/__support/CPP/algorithm.h
src/__support/CPP/array.h
src/__support/CPP/bit.h
src/__support/CPP/iterator.h
src/__support/CPP/limits.h
src/__support/CPP/optional.h
src/__support/CPP/type_traits.h
src/__support/CPP/type_traits/add_lvalue_reference.h
src/__support/CPP/type_traits/add_pointer.h
src/__support/CPP/type_traits/add_rvalue_reference.h
src/__support/CPP/type_traits/aligned_storage.h
src/__support/CPP/type_traits/always_false.h
src/__support/CPP/type_traits/bool_constant.h
src/__support/CPP/type_traits/conditional.h
src/__support/CPP/type_traits/decay.h
src/__support/CPP/type_traits/enable_if.h
src/__support/CPP/type_traits/false_type.h
src/__support/CPP/type_traits/has_unique_object_representations.h
src/__support/CPP/type_traits/integral_constant.h
src/__support/CPP/type_traits/invoke.h
src/__support/CPP/type_traits/invoke_result.h
src/__support/CPP/type_traits/is_arithmetic.h
src/__support/CPP/type_traits/is_array.h
src/__support/CPP/type_traits/is_assignable.h
src/__support/CPP/type_traits/is_base_of.h
src/__support/CPP/type_traits/is_class.h
src/__support/CPP/type_traits/is_complex.h
src/__support/CPP/type_traits/is_const.h
src/__support/CPP/type_traits/is_constant_evaluated.h
src/__support/CPP/type_traits/is_constructible.h
src/__support/CPP/type_traits/is_convertible.h
src/__support/CPP/type_traits/is_copy_assignable.h
src/__support/CPP/type_traits/is_copy_constructible.h
src/__support/CPP/type_traits/is_destructible.h
src/__support/CPP/type_traits/is_enum.h
src/__support/CPP/type_traits/is_fixed_point.h
src/__support/CPP/type_traits/is_floating_point.h
src/__support/CPP/type_traits/is_function.h
src/__support/CPP/type_traits/is_integral.h
src/__support/CPP/type_traits/is_lvalue_reference.h
src/__support/CPP/type_traits/is_member_pointer.h
src/__support/CPP/type_traits/is_move_assignable.h
src/__support/CPP/type_traits/is_move_constructible.h
src/__support/CPP/type_traits/is_null_pointer.h
src/__support/CPP/type_traits/is_object.h
src/__support/CPP/type_traits/is_pointer.h
src/__support/CPP/type_traits/is_reference.h
src/__support/CPP/type_traits/is_rvalue_reference.h
src/__support/CPP/type_traits/is_same.h
src/__support/CPP/type_traits/is_scalar.h
src/__support/CPP/type_traits/is_signed.h
src/__support/CPP/type_traits/is_trivially_constructible.h
src/__support/CPP/type_traits/is_trivially_copyable.h
src/__support/CPP/type_traits/is_trivially_destructible.h
src/__support/CPP/type_traits/is_union.h
src/__support/CPP/type_traits/is_unsigned.h
src/__support/CPP/type_traits/is_void.h
src/__support/CPP/type_traits/make_signed.h
src/__support/CPP/type_traits/make_unsigned.h
src/__support/CPP/type_traits/remove_all_extents.h
src/__support/CPP/type_traits/remove_cv.h
src/__support/CPP/type_traits/remove_cvref.h
src/__support/CPP/type_traits/remove_extent.h
src/__support/CPP/type_traits/remove_reference.h
src/__support/CPP/type_traits/true_type.h
src/__support/CPP/type_traits/type_identity.h
src/__support/CPP/type_traits/void_t.h
src/__support/CPP/utility.h
src/__support/CPP/utility/declval.h
src/__support/CPP/utility/forward.h
src/__support/CPP/utility/in_place.h
src/__support/CPP/utility/integer_sequence.h
src/__support/CPP/utility/move.h
src/__support/FPUtil/BasicOperations.h
src/__support/FPUtil/FEnvImpl.h
src/__support/FPUtil/FPBits.h
src/__support/FPUtil/cast.h
src/__support/FPUtil/comparison_operations.h
src/__support/FPUtil/dyadic_float.h
src/__support/FPUtil/generic/add_sub.h
src/__support/FPUtil/generic/div.h
src/__support/FPUtil/generic/mul.h
src/__support/FPUtil/multiply_add.h
src/__support/FPUtil/rounding_mode.h
src/__support/big_int.h
src/__support/builtins/adddf3.h
src/__support/builtins/addsf3.h
src/__support/builtins/addtf3.h
src/__support/builtins/cmp_helper.h
src/__support/builtins/divdf3.h
src/__support/builtins/divsf3.h
src/__support/builtins/divtf3.h
src/__support/builtins/extenddftf2.h
src/__support/builtins/extendsfdf2.h
src/__support/builtins/extendsftf2.h
src/__support/builtins/extendxftf2.h
src/__support/builtins/fixdfdi.h
src/__support/builtins/fixdfsi.h
src/__support/builtins/fixdfti.h
src/__support/builtins/fixint_helper.h
src/__support/builtins/fixsfdi.h
src/__support/builtins/fixsfsi.h
src/__support/builtins/fixsfti.h
src/__support/builtins/fixunsdfdi.h
src/__support/builtins/fixunsdfsi.h
src/__support/builtins/fixunsdfti.h
src/__support/builtins/fixunssfdi.h
src/__support/builtins/fixunssfsi.h
src/__support/builtins/fixunssfti.h
src/__support/builtins/floatdidf.h
src/__support/builtins/floatdisf.h
src/__support/builtins/floatint_helper.h
src/__support/builtins/floatsidf.h
src/__support/builtins/floatsisf.h
src/__support/builtins/floattidf.h
src/__support/builtins/floattisf.h
src/__support/builtins/floatundidf.h
src/__support/builtins/floatundisf.h
src/__support/builtins/floatunsidf.h
src/__support/builtins/floatunsisf.h
src/__support/builtins/floatuntidf.h
src/__support/builtins/floatuntisf.h
src/__support/builtins/fpconvert_helper.h
src/__support/builtins/gesf2.h
src/__support/builtins/lesf2.h
src/__support/builtins/muldf3.h
src/__support/builtins/mulsf3.h
src/__support/builtins/multf3.h
src/__support/builtins/negdf2.h
src/__support/builtins/negsf2.h
src/__support/builtins/subdf3.h
src/__support/builtins/subsf3.h
src/__support/builtins/subtf3.h
src/__support/builtins/truncdfsf2.h
src/__support/builtins/trunctfdf2.h
src/__support/builtins/trunctfsf2.h
src/__support/builtins/trunctfxf2.h
src/__support/builtins/unordsf2.h
src/__support/common.h
src/__support/libc_assert.h
src/__support/libc_errno.h
src/__support/macros/attributes.h
src/__support/macros/config.h
src/__support/macros/hardening.h
src/__support/macros/macro-utils.h
src/__support/macros/optimization.h
src/__support/macros/properties/architectures.h
src/__support/macros/properties/compiler.h
src/__support/macros/properties/complex_types.h
src/__support/macros/properties/cpu_features.h
src/__support/macros/properties/os.h
src/__support/macros/properties/types.h
src/__support/macros/sanitizer.h
src/__support/math_extras.h
src/__support/number_pair.h
src/__support/sign.h
src/__support/uint128.h
Loading
Loading