[CIR] Implement __builtin_flt_rounds and __builtin_set_flt_rounds (#190706)

This adds CIR handling for the __builtin_flt_rounds and
__builtin_set_flt_rounds builtin functions. Because the LLVM dialect
does not have dedicated operations for these, I have chosen not to
implement them as operations in CIR either. Instead, we just call the
LLVM intrinsic.
This commit is contained in:
Andy Kaylor 2026-04-06 17:11:49 -07:00 committed by GitHub
parent 511a7aacee
commit fa70ee45be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 3 deletions

View File

@ -1580,9 +1580,23 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
mlir::Value result = builder.createSelect(loc, isInf, signResult, zero); mlir::Value result = builder.createSelect(loc, isInf, signResult, zero);
return RValue::get(result); return RValue::get(result);
} }
case Builtin::BI__builtin_flt_rounds: case Builtin::BI__builtin_flt_rounds: {
case Builtin::BI__builtin_set_flt_rounds: mlir::Location loc = getLoc(e->getExprLoc());
return errorBuiltinNYI(*this, e, builtinID); 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: { case Builtin::BI__builtin_fpclassify: {
CIRGenFunction::CIRGenFPOptionsRAII fPOptsRAII(*this, e); CIRGenFunction::CIRGenFPOptionsRAII fPOptsRAII(*this, e);
mlir::Location loc = getLoc(e->getBeginLoc()); mlir::Location loc = getLoc(e->getBeginLoc());

View File

@ -2210,3 +2210,29 @@ double my_roundeven(double x) {
// OGCG: define{{.*}}@my_roundeven( // OGCG: define{{.*}}@my_roundeven(
// OGCG: call double @llvm.roundeven.f64( // 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 %{{.+}})
}