[clang] 5821351 - [clang][Interp] Implement __builtin_fpclassify
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 1 07:15:30 PDT 2023
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)];
+}
More information about the cfe-commits
mailing list