tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, shafik, cor3ntin.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155394

Files:
  clang/lib/AST/Interp/Floating.h
  clang/lib/AST/Interp/InterpBuiltin.cpp
  clang/test/AST/Interp/builtin-functions.cpp


Index: clang/test/AST/Interp/builtin-functions.cpp
===================================================================
--- clang/test/AST/Interp/builtin-functions.cpp
+++ clang/test/AST/Interp/builtin-functions.cpp
@@ -116,3 +116,16 @@
   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)];
+}
Index: clang/lib/AST/Interp/InterpBuiltin.cpp
===================================================================
--- clang/lib/AST/Interp/InterpBuiltin.cpp
+++ clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -234,6 +234,37 @@
   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;
@@ -316,6 +347,10 @@
     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;
Index: clang/lib/AST/Interp/Floating.h
===================================================================
--- clang/lib/AST/Interp/Floating.h
+++ clang/lib/AST/Interp/Floating.h
@@ -97,7 +97,9 @@
   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 {
     return Compare(F, RHS.F);


Index: clang/test/AST/Interp/builtin-functions.cpp
===================================================================
--- clang/test/AST/Interp/builtin-functions.cpp
+++ clang/test/AST/Interp/builtin-functions.cpp
@@ -116,3 +116,16 @@
   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)];
+}
Index: clang/lib/AST/Interp/InterpBuiltin.cpp
===================================================================
--- clang/lib/AST/Interp/InterpBuiltin.cpp
+++ clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -234,6 +234,37 @@
   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;
@@ -316,6 +347,10 @@
     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;
Index: clang/lib/AST/Interp/Floating.h
===================================================================
--- clang/lib/AST/Interp/Floating.h
+++ clang/lib/AST/Interp/Floating.h
@@ -97,7 +97,9 @@
   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 {
     return Compare(F, RHS.F);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to