[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