[Clang] constexpr builtin floating point classification / comparison functions by MitalAshok · Pull Request #94118 · llvm/llvm-project (original) (raw)

@llvm/pr-subscribers-clang

Author: Mital Ashok (MitalAshok)

Changes

As per P0533R9, the corresponding C++ [c.math.fpclass] standard library functions for the C macros are now constexpr.

The only classification function that wasn't already constexpr was __builtin_signbit.
The floating point comparison functions __builtin_isgreater, __builtin_isgreaterequal, __builtin_isless, __builtin_islessequal, __builtin_islessgreater and __builtin_isunordered are now constexpr.
The C23 macro iseqsig is not currently supported because __bulitin_iseqsig doesn't exist yet (and C++26 is still currently based on C18).

This also allows them to be constant folded in C, matching the behaviour of GCC.


Full diff: https://github.com/llvm/llvm-project/pull/94118.diff

4 Files Affected:

diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 11982af3fa609..7b335e43f8c0e 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -533,42 +533,42 @@ def BuiltinComplex : Builtin { def IsGreater : Builtin { let Spellings = ["__builtin_isgreater"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

def IsGreaterEqual : Builtin { let Spellings = ["__builtin_isgreaterequal"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

def IsLess : Builtin { let Spellings = ["__builtin_isless"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

def IsLessEqual : Builtin { let Spellings = ["__builtin_islessequal"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

def IsLessGreater : Builtin { let Spellings = ["__builtin_islessgreater"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

def IsUnordered : Builtin { let Spellings = ["__builtin_isunordered"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

@@ -646,19 +646,21 @@ def IsFPClass : Builtin { def Signbit : Builtin { let Spellings = ["__builtin_signbit"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,

def SignbitF : Builtin { let Spellings = ["__builtin_signbitf"];

def SignbitL : Builtin { let Spellings = ["__builtin_signbitl"];

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f1aa19e4409e1..cf715857f1370 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12650,6 +12650,73 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, Success(Val.isZero() ? 1 : 0, E); }

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 00206d09c113d..69e2960269c48 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -430,6 +430,78 @@ static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, return true; }

+static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC,

case Builtin::BI__builtin_isfpclass: if (!interp__builtin_isfpclass(S, OpPC, Frame, F, Call)) return false; diff --git a/clang/test/Sema/constant-builtins-2.c b/clang/test/Sema/constant-builtins-2.c index a60a1f16a4587..59afdf056ae9f 100644 --- a/clang/test/Sema/constant-builtins-2.c +++ b/clang/test/Sema/constant-builtins-2.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -fexperimental-new-constant-interpreter -verify %s

// Math stuff

@@ -204,6 +205,53 @@ char isfpclass_snan_1 [!__builtin_isfpclass(__builtin_nans(""), 0x0002) ? 1 : char isfpclass_snan_2 [__builtin_isfpclass(__builtin_nansl(""), 0x0207) ? 1 : -1]; // ~fcFinite char isfpclass_snan_3 [!__builtin_isfpclass(__builtin_nans(""), 0x01F8) ? 1 : -1]; // fcFinite

+extension _Static_assert(