================
@@ -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

Reply via email to