Author: Timm Bäder Date: 2023-08-01T16:02:15+02:00 New Revision: 5821351343eba18b39ef97cf1866f57a967a5fd0
URL: https://github.com/llvm/llvm-project/commit/5821351343eba18b39ef97cf1866f57a967a5fd0 DIFF: https://github.com/llvm/llvm-project/commit/5821351343eba18b39ef97cf1866f57a967a5fd0.diff LOG: [clang][Interp] Implement __builtin_fpclassify Differential Revision: https://reviews.llvm.org/D155394 Added: Modified: clang/lib/AST/Interp/Floating.h clang/lib/AST/Interp/InterpBuiltin.cpp clang/test/AST/Interp/builtin-functions.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index d8e0108cb082f7..60e7ce2461aadc 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -90,7 +90,9 @@ class Floating final { bool isInf() const { return F.isInfinity(); } bool isFinite() const { return F.isFinite(); } bool isNormal() const { return F.isNormal(); } + bool isDenormal() const { return F.isDenormal(); } llvm::FPClassTest classify() const { return F.classify(); } + APFloat::fltCategory getCategory() const { return F.getCategory(); } ComparisonCategoryResult compare(const Floating &RHS) const { llvm::APFloatBase::cmpResult CmpRes = F.compare(RHS.F); diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 146f047d7ee8ff..714fa9ee02ce13 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -235,6 +235,37 @@ static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, return true; } +/// Five int32 values followed by one floating value. +static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func) { + const Floating &Val = S.Stk.peek<Floating>(); + + unsigned Index; + switch (Val.getCategory()) { + case APFloat::fcNaN: + Index = 0; + break; + case APFloat::fcInfinity: + Index = 1; + break; + case APFloat::fcNormal: + Index = Val.isDenormal() ? 3 : 2; + break; + case APFloat::fcZero: + Index = 4; + break; + } + + // The last argument is first on the stack. + unsigned Offset = align(primSize(PT_Float)) + + ((1 + (4 - Index)) * align(primSize(PT_Sint32))); + + const Integral<32, true> &I = S.Stk.peek<Integral<32, true>>(Offset); + S.Stk.push<Integral<32, true>>(I); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) { InterpFrame *Frame = S.Current; APValue Dummy; @@ -323,6 +354,10 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) { if (interp__builtin_isfpclass(S, OpPC, Frame, F)) return Ret<PT_Sint32>(S, OpPC, Dummy); break; + case Builtin::BI__builtin_fpclassify: + if (interp__builtin_fpclassify(S, OpPC, Frame, F)) + return Ret<PT_Sint32>(S, OpPC, Dummy); + break; default: return false; diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp index a7e55bd0e159e7..e3fabecf8c9378 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -126,3 +126,17 @@ namespace isfpclass { char isfpclass_snan_2 [__builtin_isfpclass(__builtin_nansl(""), 0x0207) ? 1 : -1]; // ~fcFinite char isfpclass_snan_3 [!__builtin_isfpclass(__builtin_nans(""), 0x01F8) ? 1 : -1]; // fcFinite } + +namespace fpclassify { + char classify_nan [__builtin_fpclassify(+1, -1, -1, -1, -1, __builtin_nan(""))]; + char classify_snan [__builtin_fpclassify(+1, -1, -1, -1, -1, __builtin_nans(""))]; + char classify_inf [__builtin_fpclassify(-1, +1, -1, -1, -1, __builtin_inf())]; + char classify_neg_inf [__builtin_fpclassify(-1, +1, -1, -1, -1, -__builtin_inf())]; + char classify_normal [__builtin_fpclassify(-1, -1, +1, -1, -1, 1.539)]; + char classify_normal2 [__builtin_fpclassify(-1, -1, +1, -1, -1, 1e-307)]; + char classify_denorm [__builtin_fpclassify(-1, -1, -1, +1, -1, 1e-308)]; + char classify_denorm2 [__builtin_fpclassify(-1, -1, -1, +1, -1, -1e-308)]; + char classify_zero [__builtin_fpclassify(-1, -1, -1, -1, +1, 0.0)]; + char classify_neg_zero[__builtin_fpclassify(-1, -1, -1, -1, +1, -0.0)]; + char classify_subnorm [__builtin_fpclassify(-1, -1, -1, +1, -1, 1.0e-38f)]; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits