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
