https://github.com/YeonguChoe created 
https://github.com/llvm/llvm-project/pull/183893

BI__builtin_fpclassify function is not implemented in ClangIR, so fpclassify 
cannot be used at the moment with ClangIR. I implemented BI__builtin_fpclassify 
so that fpclassify can use builtin_fpclassify.

>From c4a086c5ffdbdbc41d225f64621df0c99fbbd01a Mon Sep 17 00:00:00 2001
From: YeonguChoe <[email protected]>
Date: Sat, 28 Feb 2026 04:41:45 -0500
Subject: [PATCH] [CIR][CodeGen] Implement BI__builtin_fpclassify function

BI__builtin_fpclassify function is not implemented in ClangIR, so fpclassify 
cannot be used at the moment with ClangIR. I implemented BI__builtin_fpclassify 
so that fpclassify can use builtin_fpclassify.
---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       | 66 ++++++++++++++++++-
 .../CodeGenBuiltins/builtins-floating-point.c |  7 ++
 2 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 86d34be0a311c..5eee7a522331c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1544,8 +1544,70 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   case Builtin::BI__builtin_isinf_sign:
   case Builtin::BI__builtin_flt_rounds:
   case Builtin::BI__builtin_set_flt_rounds:
-  case Builtin::BI__builtin_fpclassify:
-    return errorBuiltinNYI(*this, e, builtinID);
+  case Builtin::BI__builtin_fpclassify: {
+    CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(*this, e);
+    mlir::Location Loc = getLoc(e->getBeginLoc());
+
+    mlir::Value NanLiteral = emitScalarExpr(e->getArg(0));
+    mlir::Value InfinityLiteral = emitScalarExpr(e->getArg(1));
+    mlir::Value NormalLiteral = emitScalarExpr(e->getArg(2));
+    mlir::Value SubnormalLiteral = emitScalarExpr(e->getArg(3));
+    mlir::Value ZeroLiteral = emitScalarExpr(e->getArg(4));
+    mlir::Value V = emitScalarExpr(e->getArg(5));
+
+    mlir::Type ResultTy = convertType(e->getType());
+    mlir::Block *EntryBlock = builder.getInsertionBlock();
+    mlir::Region *Region = EntryBlock->getParent();
+
+    // Create Blocks
+    mlir::Block *InfinityBlock = builder.createBlock(Region, Region->end());
+    mlir::Block *NormalBlock = builder.createBlock(Region, Region->end());
+    mlir::Block *SubnormalBlock = builder.createBlock(Region, Region->end());
+    mlir::Block *ZeroBlock = builder.createBlock(Region, Region->end());
+    mlir::Block *EndBlock = builder.createBlock(Region, Region->end());
+    EndBlock->addArgument(ResultTy, Loc);
+
+    // ^EntryBlock
+    builder.setInsertionPointToEnd(EntryBlock);
+    mlir::Value IsNan = builder.createIsFPClass(Loc, V, cir::FPClassTest::Nan);
+    cir::BrCondOp::create(builder, Loc, IsNan, EndBlock,
+                          InfinityBlock, // destTrue, destFalse
+                          mlir::ValueRange{NanLiteral},
+                          mlir::ValueRange{}); // operandsTrue, operandsFalse
+
+    // ^InfinityBlock
+    builder.setInsertionPointToEnd(InfinityBlock);
+    mlir::Value IsInfinity =
+        builder.createIsFPClass(Loc, V, cir::FPClassTest::Infinity);
+    cir::BrCondOp::create(builder, Loc, IsInfinity, EndBlock, NormalBlock,
+                          mlir::ValueRange{InfinityLiteral},
+                          mlir::ValueRange{});
+
+    // ^NormalBlock
+    builder.setInsertionPointToEnd(NormalBlock);
+    mlir::Value IsNormal =
+        builder.createIsFPClass(Loc, V, cir::FPClassTest::Normal);
+    cir::BrCondOp::create(builder, Loc, IsNormal, EndBlock, SubnormalBlock,
+                          mlir::ValueRange{NormalLiteral}, mlir::ValueRange{});
+
+    // ^SubnormalBlock
+    builder.setInsertionPointToEnd(SubnormalBlock);
+    mlir::Value IsSubnormal =
+        builder.createIsFPClass(Loc, V, cir::FPClassTest::Subnormal);
+    cir::BrCondOp::create(builder, Loc, IsSubnormal, EndBlock, ZeroBlock,
+                          mlir::ValueRange{SubnormalLiteral},
+                          mlir::ValueRange{});
+
+    // ^ZeroBlock
+    builder.setInsertionPointToEnd(ZeroBlock);
+    cir::BrOp::create(builder, Loc, EndBlock, mlir::ValueRange{ZeroLiteral});
+
+    // ^EndBlock(x)
+    builder.setInsertionPointToEnd(EndBlock);
+    mlir::Value Result = EndBlock->getArgument(0);
+
+    return RValue::get(Result);
+  }
   case Builtin::BIalloca:
   case Builtin::BI_alloca:
   case Builtin::BI__builtin_alloca_uninitialized:
diff --git a/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c 
b/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c
index be82137427ea2..f63ec9b4c76e9 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c
@@ -2210,3 +2210,10 @@ double my_roundeven(double x) {
   // OGCG: define{{.*}}@my_roundeven(
   // OGCG: call double @llvm.roundeven.f64(
 }
+
+int fpclassify(float f) {
+  return __builtin_fpclassify(0, 1, 2, 3, 4, f);
+  // CIR: %{{.*}} = cir.is_fp_class %{{.*}}, fcNan : (!cir.float) -> !cir.bool
+  // LLVM: %{{.*}} = call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 {{.*}})
+  // OGCG: %{{.*}} = fcmp uno float %{{.*}}, %{{.*}}
+}
\ No newline at end of file

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to