diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index c03858ba8da5..523348a95277 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1580,9 +1580,23 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, mlir::Value result = builder.createSelect(loc, isInf, signResult, zero); return RValue::get(result); } - case Builtin::BI__builtin_flt_rounds: - case Builtin::BI__builtin_set_flt_rounds: - return errorBuiltinNYI(*this, e, builtinID); + case Builtin::BI__builtin_flt_rounds: { + mlir::Location loc = getLoc(e->getExprLoc()); + mlir::Type resultType = convertType(e->getType()); + mlir::Value result = + builder.emitIntrinsicCallOp(loc, "get.rounding", resultType); + if (result.getType() != resultType) + result = + builder.createCast(loc, cir::CastKind::integral, result, resultType); + return RValue::get(result); + } + case Builtin::BI__builtin_set_flt_rounds: { + mlir::Location loc = getLoc(e->getExprLoc()); + mlir::Value v = emitScalarExpr(e->getArg(0)); + builder.emitIntrinsicCallOp(loc, "set.rounding", builder.getVoidTy(), + mlir::ValueRange{v}); + return RValue::get(nullptr); + } case Builtin::BI__builtin_fpclassify: { CIRGenFunction::CIRGenFPOptionsRAII fPOptsRAII(*this, e); mlir::Location loc = getLoc(e->getBeginLoc()); diff --git a/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c b/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c index be82137427ea..c3306ccbada0 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c +++ b/clang/test/CIR/CodeGenBuiltins/builtins-floating-point.c @@ -2210,3 +2210,29 @@ double my_roundeven(double x) { // OGCG: define{{.*}}@my_roundeven( // OGCG: call double @llvm.roundeven.f64( } + +int my_flt_rounds(void) { + return __builtin_flt_rounds(); + // CIR: cir.func no_inline dso_local @my_flt_rounds + // CIR: cir.call_llvm_intrinsic "get.rounding" : () -> !s32i + + // LLVM: define{{.*}} i32 @my_flt_rounds + // LLVM: call i32 @llvm.get.rounding() + // LLVM: } + + // OGCG: define{{.*}}@my_flt_rounds + // OGCG: call i32 @llvm.get.rounding() +} + +void my_set_flt_rounds(int rounding) { + __builtin_set_flt_rounds(rounding); + // CIR: cir.func no_inline dso_local @my_set_flt_rounds + // CIR: cir.call_llvm_intrinsic "set.rounding" %{{.*}} : (!s32i) + + // LLVM: define{{.*}} void @my_set_flt_rounds + // LLVM: call void @llvm.set.rounding(i32 %{{.+}}) + // LLVM: } + + // OGCG: define{{.*}}@my_set_flt_rounds + // OGCG: call void @llvm.set.rounding(i32 %{{.+}}) +}