[compiler-rt][builtins] libc-backed single-float comparison builtins

This commit is contained in:
hulxv 2026-07-29 01:24:14 +03:00
parent e2564f080a
commit 63d6e8d99e
No known key found for this signature in database
12 changed files with 280 additions and 0 deletions

View file

@ -288,6 +288,7 @@ if(COMPILER_RT_USE_LIBC_MATH)
use_libc_builtin(GENERIC_SOURCES adddf3)
use_libc_builtin(GENERIC_SOURCES addsf3)
use_libc_builtin(GENERIC_TF_SOURCES addtf3)
use_libc_builtin(GENERIC_SOURCES comparesf2)
use_libc_builtin(GENERIC_SOURCES divdf3)
use_libc_builtin(GENERIC_SOURCES divsf3)
use_libc_builtin(GENERIC_TF_SOURCES divtf3)

View file

@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's float comparison routines
/// (__lesf2/__gesf2/__unordsf2 and their aliases) on top of LLVM-libc's shared
/// comparison builtins.
///
//===----------------------------------------------------------------------===//
#define SINGLE_PRECISION
#include "fp_lib.h"
#include "fp_compare_impl.inc"
#include "fp_libc_config.h"
#include "shared/builtins/gesf2.h"
#include "shared/builtins/lesf2.h"
#include "shared/builtins/unordsf2.h"
extern "C" {
COMPILER_RT_ABI CMP_RESULT __lesf2(fp_t a, fp_t b) {
return LIBC_NAMESPACE::shared::lesf2(a, b);
}
#if defined(__ELF__)
COMPILER_RT_ALIAS(__lesf2, __cmpsf2)
#endif
COMPILER_RT_ALIAS(__lesf2, __eqsf2)
COMPILER_RT_ALIAS(__lesf2, __ltsf2)
COMPILER_RT_ALIAS(__lesf2, __nesf2)
COMPILER_RT_ABI CMP_RESULT __gesf2(fp_t a, fp_t b) {
return LIBC_NAMESPACE::shared::gesf2(a, b);
}
COMPILER_RT_ALIAS(__gesf2, __gtsf2)
COMPILER_RT_ABI CMP_RESULT __unordsf2(fp_t a, fp_t b) {
return LIBC_NAMESPACE::shared::unordsf2(a, b);
}
#if defined(__ARM_EABI__)
#if defined(COMPILER_RT_ARMHF_TARGET)
AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) { return __unordsf2(a, b); }
#else
COMPILER_RT_ALIAS(__unordsf2, __aeabi_fcmpun)
#endif
#endif
} // extern "C"

View file

@ -27,6 +27,8 @@
#include "builtins/extendsfdf2.h"
#include "builtins/extendsftf2.h"
#include "builtins/extendxftf2.h"
#include "builtins/gesf2.h"
#include "builtins/lesf2.h"
#include "builtins/muldf3.h"
#include "builtins/mulsf3.h"
#include "builtins/multf3.h"
@ -39,5 +41,6 @@
#include "builtins/trunctfdf2.h"
#include "builtins/trunctfsf2.h"
#include "builtins/trunctfxf2.h"
#include "builtins/unordsf2.h"
#endif // LLVM_LIBC_SHARED_BUILTINS_H

View file

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __gesf2 implementation as shared::gesf2 so
/// that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_GESF2_H
#define LLVM_LIBC_SHARED_BUILTINS_GESF2_H
#include "shared/libc_common.h"
#include "src/__support/builtins/gesf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::gesf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SHARED_BUILTINS_GESF2_H

View file

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __lesf2 implementation as shared::lesf2 so
/// that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_LESF2_H
#define LLVM_LIBC_SHARED_BUILTINS_LESF2_H
#include "shared/libc_common.h"
#include "src/__support/builtins/lesf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::lesf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SHARED_BUILTINS_LESF2_H

View file

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __unordsf2 implementation as
/// shared::unordsf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_UNORDSF2_H
#define LLVM_LIBC_SHARED_BUILTINS_UNORDSF2_H
#include "shared/libc_common.h"
#include "src/__support/builtins/unordsf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::unordsf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SHARED_BUILTINS_UNORDSF2_H

View file

@ -230,3 +230,30 @@ add_header_library(
libc.src.__support.macros.attributes
libc.src.__support.macros.config
)
add_header_library(
lesf2
HDRS
lesf2.h
DEPENDS
libc.src.__support.builtins.cmp_helper
libc.src.__support.macros.config
)
add_header_library(
gesf2
HDRS
gesf2.h
DEPENDS
libc.src.__support.builtins.cmp_helper
libc.src.__support.macros.config
)
add_header_library(
unordsf2
HDRS
unordsf2.h
DEPENDS
libc.src.__support.builtins.cmp_helper
libc.src.__support.macros.config
)

View file

@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __gesf2 implementation as builtins::gesf2 so
/// that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_GESF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_GESF2_H
#include "src/__support/builtins/cmp_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Greater-equal comparison of float; mirrors compiler-rt's __gesf2.
LIBC_INLINE int gesf2(float a, float b) { return cmp_ge(a, b); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_GESF2_H

View file

@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __lesf2 implementation as builtins::lesf2 so
/// that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_LESF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_LESF2_H
#include "src/__support/builtins/cmp_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Less-equal comparison of float; mirrors compiler-rt's __lesf2.
LIBC_INLINE int lesf2(float a, float b) { return cmp_le(a, b); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_LESF2_H

View file

@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __unordsf2 implementation as
/// builtins::unordsf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_UNORDSF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_UNORDSF2_H
#include "src/__support/builtins/cmp_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Unordered comparison of float; mirrors compiler-rt's __unordsf2.
LIBC_INLINE int unordsf2(float a, float b) { return cmp_unord(a, b); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_UNORDSF2_H

View file

@ -838,6 +838,8 @@ add_fp_unittest(
libc.src.__support.builtins.extendsfdf2
libc.src.__support.builtins.extendsftf2
libc.src.__support.builtins.extendxftf2
libc.src.__support.builtins.gesf2
libc.src.__support.builtins.lesf2
libc.src.__support.builtins.muldf3
libc.src.__support.builtins.mulsf3
libc.src.__support.builtins.multf3
@ -850,6 +852,7 @@ add_fp_unittest(
libc.src.__support.builtins.trunctfdf2
libc.src.__support.builtins.trunctfsf2
libc.src.__support.builtins.trunctfxf2
libc.src.__support.builtins.unordsf2
)
add_fp_unittest(

View file

@ -60,3 +60,18 @@ TEST(LlvmLibcSharedBuiltinsTest, TruncateConversion) {
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LIBC_TYPES_HAS_FLOAT128
}
TEST(LlvmLibcSharedBuiltinsTest, SingleCompare) {
const float aNaN =
LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
EXPECT_EQ(-1, shared::gesf2(1.0f, 2.0f));
EXPECT_EQ(0, shared::gesf2(1.0f, 1.0f));
EXPECT_EQ(1, shared::gesf2(2.0f, 1.0f));
EXPECT_EQ(-1, shared::gesf2(aNaN, 1.0f));
EXPECT_EQ(-1, shared::lesf2(1.0f, 2.0f));
EXPECT_EQ(0, shared::lesf2(1.0f, 1.0f));
EXPECT_EQ(1, shared::lesf2(2.0f, 1.0f));
EXPECT_EQ(1, shared::lesf2(aNaN, 1.0f));
EXPECT_EQ(0, shared::unordsf2(1.0f, 2.0f));
EXPECT_EQ(1, shared::unordsf2(aNaN, 1.0f));
}