================
@@ -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());
----------------
andykaylor wrote:
For CIR, rather than explicitly creating blocks and branches, you should create
a series of cir.ternary operations. Basically, you need to produce this:
```
%is_zero = cir.is_fp_class %val, 96 : (!cir.float) -> !cir.bool // 96 =
fcZero
%result = cir.ternary(%is_zero, true {
%fp_zero = cir.const #cir.int<2> : !s32i
cir.yield %fp_zero : !s32i
}, false {
%is_nan = cir.is_fp_class %val, 3 : (!cir.float) -> !cir.bool // 3 - fcNan
%temp = cir.ternary(%is_nan, true {
%fp_nan = cir.const #cir.int<0> : !s32i
cir.yield %fp_nan : !s32i
}, false {
%is_infinity = cir.is_fp_class %val, 516 : (!cir.float) -> !cir.bool //
516 = fcInfinity
%temp2 = cir.ternary(%is_infinity, true {
%fp_infinite = cir.const #cir.int<1> : !s32i
cir.yield %fp_infinite : !s32i
}, false {
%is_normal = cir.is_fp_class %val, 264 : (!cir.float) -> !cir.bool //
264 = fcNormal
%fp_normal = cir.const #cir.int<4> : !s32i
%fp_subnormal = cir.const #cir.int<3> : !s32i
%temp3 = cir.select if %is_normal then %fp_normal else %fp_subnormal
: (!cir.bool, !s32i, !s32i) -> !s32i
cir.yield %temp3 : !s32i
}) : (!cir.bool) -> !s32i
cir.yield %temp2 : !s32i
}) : (!cir.bool) -> !s32i
cir.yield %temp : !s32i
}) : (!cir.bool) -> !s32i
```
Though you'll want to double-check my constants and logic there because I hand
edited that.
https://github.com/llvm/llvm-project/pull/183893
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits