sepavloff updated this revision to Diff 529243.
sepavloff added a comment.

Add check for test bit mask value


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152351/new/

https://reviews.llvm.org/D152351

Files:
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins.c
  clang/test/CodeGen/isfpclass.c
  clang/test/Sema/builtins.c
  llvm/include/llvm/IR/IRBuilder.h
  llvm/lib/IR/IRBuilder.cpp

Index: llvm/lib/IR/IRBuilder.cpp
===================================================================
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -1375,6 +1375,14 @@
   return Fn;
 }
 
+Value *IRBuilderBase::createIsFPClass(Value *FPNum, unsigned Test) {
+  auto TestV = llvm::ConstantInt::get(Type::getInt32Ty(Context), Test);
+  Module *M = BB->getParent()->getParent();
+  Function *FnIsFPClass =
+      Intrinsic::getDeclaration(M, Intrinsic::is_fpclass, {FPNum->getType()});
+  return CreateCall(FnIsFPClass, {FPNum, TestV});
+}
+
 CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
                                                          Value *PtrValue,
                                                          Value *AlignValue,
Index: llvm/include/llvm/IR/IRBuilder.h
===================================================================
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -2518,6 +2518,8 @@
                                          unsigned Index, unsigned FieldIndex,
                                          MDNode *DbgInfo);
 
+  Value *createIsFPClass(Value *FPNum, unsigned Test);
+
 private:
   /// Helper function that creates an assume intrinsic call that
   /// represents an alignment assumption on the provided pointer \p PtrValue
Index: clang/test/Sema/builtins.c
===================================================================
--- clang/test/Sema/builtins.c
+++ clang/test/Sema/builtins.c
@@ -378,3 +378,7 @@
 }
 
 _Complex double builtin_complex_static_init = __builtin_complex(1.0, 2.0);
+
+int test_is_fpclass(float x) {
+  return __builtin_isfpclass(1024, x); // expected-error {{argument value 1024 is outside the valid range [0, 1023]}}
+}
Index: clang/test/CodeGen/isfpclass.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/isfpclass.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -O1 -emit-llvm %s -o - | FileCheck %s
+
+_Bool check_isfpclass_finite(float x) {
+  return __builtin_isfpclass(504 /*Finite*/, x);
+}
+// CHECK-LABEL: define {{.*}} i1 @check_isfpclass_finite(
+// CHECK:         call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 504)
+
+_Bool check_isfpclass_finite_strict(float x) {
+#pragma STDC FENV_ACCESS ON
+  return __builtin_isfpclass(504 /*Finite*/, x);
+}
+// CHECK-LABEL: define {{.*}} i1 @check_isfpclass_finite_strict(
+// CHECK:         call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 504)
+
+_Bool check_isfpclass_nan_f32(float x) {
+#pragma STDC FENV_ACCESS ON
+  return __builtin_isfpclass(3 /*NaN*/, x);
+}
+// CHECK-LABEL: define {{.*}} i1 @check_isfpclass_nan_f32(
+// CHECK:         call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 3)
+
+_Bool check_isfpclass_nan_f64(double x) {
+#pragma STDC FENV_ACCESS ON
+  return __builtin_isfpclass(3 /*NaN*/, x);
+}
+// CHECK-LABEL: define {{.*}} i1 @check_isfpclass_nan_f64(
+// CHECK:         call i1 @llvm.is.fpclass.f64(double {{.*}}, i32 3)
Index: clang/test/CodeGen/builtins.c
===================================================================
--- clang/test/CodeGen/builtins.c
+++ clang/test/CodeGen/builtins.c
@@ -63,6 +63,7 @@
   P(isinf, (1.));
   P(isinf_sign, (1.));
   P(isnan, (1.));
+  P(isfpclass, (1, 1.));
 
   // Bitwise & Numeric Functions
 
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -2770,7 +2770,13 @@
            diag::err_hip_invalid_args_builtin_mangled_name);
       return ExprError();
     }
+    break;
   }
+
+  case Builtin::BI__builtin_isfpclass:
+    if (SemaBuiltinConstantArgRange(TheCall, 0, 0, llvm::fcAllFlags))
+      return ExprError();
+    break;
   }
 
   // Since the target specific builtins for each arch overlap, only check those
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3143,6 +3143,17 @@
     return RValue::get(V);
   }
 
+  case Builtin::BI__builtin_isfpclass: {
+    Expr::EvalResult Result;
+    if (!E->getArg(0)->EvaluateAsInt(Result, CGM.getContext()))
+      break;
+    uint64_t Test = Result.Val.getInt().getLimitedValue();
+    CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+    Value *V = EmitScalarExpr(E->getArg(1));
+    return RValue::get(Builder.CreateZExt(Builder.createIsFPClass(V, Test),
+                                          ConvertType(E->getType())));
+  }
+
   case Builtin::BI__builtin_nondeterministic_value: {
     llvm::Type *Ty = ConvertType(E->getArg(0)->getType());
 
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -488,6 +488,7 @@
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,      "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_isfpclass,  "iCi.", "nctE")
 
 // FP signbit builtins
 BUILTIN(__builtin_signbit, "i.", "Fnct")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to