-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[CIR] Upstream isfpclass op #166037
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Upstream isfpclass op #166037
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
caa62bc to
058f43b
Compare
058f43b to
3ab831e
Compare
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clangir Author: Jasmine Tang (badumbatish) ChangesRef commit in incubator: ee17ff6 There is a minor change in the assumption for emitting a direct callee. In incubator, Fixes #163892 Patch is 33.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/166037.diff 14 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 3288f5b12c77e..a680ac58cc904 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -442,6 +442,22 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return createCast(cir::CastKind::ptr_to_bool, v, getBoolTy());
}
+ // TODO(cir): the following function was introduced to keep in sync with LLVM
+ // codegen. CIR does not have "zext" operations. It should eventually be
+ // renamed or removed. For now, we just add whatever cast is required here.
+ mlir::Value createZExtOrBitCast(mlir::Location loc, mlir::Value src,
+ mlir::Type newTy) {
+ auto srcTy = src.getType();
+
+ if (srcTy == newTy)
+ return src;
+
+ if (mlir::isa<cir::BoolType>(srcTy) && mlir::isa<cir::IntType>(newTy))
+ return createBoolToInt(src, newTy);
+
+ llvm_unreachable("unhandled extension cast");
+ }
+
mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
return createCast(cir::CastKind::bool_to_int, src, newTy);
}
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 86d09d72fe6ca..a6ee8c668efec 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3921,6 +3921,39 @@ def CIR_RotateOp : CIR_Op<"rotate", [Pure, SameOperandsAndResultType]> {
let hasFolder = 1;
}
+def CIR_IsFPClassOp : CIR_Op<"is_fp_class"> {
+ let summary = "Corresponding to the `__builtin_fpclassify` builtin function in clang";
+
+ let description = [{
+ The `cir.is_fp_class` operation takes a floating-point value as its first
+ argument and a bitfield of flags as its second argument. The operation
+ returns a boolean value indicating whether the floating-point value
+ satisfies the given flags.
+
+ The flags must be a compile time constant and the values are:
+
+ | Bit # | floating-point class |
+ | -------- | ------- |
+ | 0 | Signaling NaN |
+ | 1 | Quiet NaN |
+ | 2 | Negative infinity |
+ | 3 | Negative normal |
+ | 4 | Negative subnormal |
+ | 5 | Negative zero |
+ | 6 | Positive zero |
+ | 7 | Positive subnormal |
+ | 8 | Positive normal |
+ | 9 | Positive infinity |
+ }];
+
+ let arguments = (ins CIR_AnyFloatType:$src,
+ I32Attr:$flags);
+ let results = (outs CIR_BoolType:$result);
+ let assemblyFormat = [{
+ $src `,` $flags `:` functional-type($src, $result) attr-dict
+ }];
+}
+
//===----------------------------------------------------------------------===//
// Assume Operations
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/FPEnv.h b/clang/include/clang/CIR/Dialect/IR/FPEnv.h
new file mode 100644
index 0000000000000..aceba9ee57d05
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/FPEnv.h
@@ -0,0 +1,50 @@
+//===- FPEnv.h ---- FP Environment ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains the declarations of entities that describe floating
+/// point environment and related functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_IR_FPENV_H
+#define CLANG_CIR_DIALECT_IR_FPENV_H
+
+#include "llvm/ADT/FloatingPointMode.h"
+
+#include <optional>
+
+namespace cir {
+
+namespace fp {
+
+/// Exception behavior used for floating point operations.
+///
+/// Each of these values corresponds to some LLVMIR metadata argument value of a
+/// constrained floating point intrinsic. See the LLVM Language Reference Manual
+/// for details.
+enum ExceptionBehavior : uint8_t {
+ ebIgnore, ///< This corresponds to "fpexcept.ignore".
+ ebMayTrap, ///< This corresponds to "fpexcept.maytrap".
+ ebStrict, ///< This corresponds to "fpexcept.strict".
+};
+
+} // namespace fp
+
+/// For any RoundingMode enumerator, returns a string valid as input in
+/// constrained intrinsic rounding mode metadata.
+std::optional<llvm::StringRef> convertRoundingModeToStr(llvm::RoundingMode);
+
+/// For any ExceptionBehavior enumerator, returns a string valid as input in
+/// constrained intrinsic exception behavior metadata.
+std::optional<llvm::StringRef>
+ convertExceptionBehaviorToStr(fp::ExceptionBehavior);
+
+} // namespace cir
+
+#endif
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 598e826a473a6..d9bbd64d029a1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -256,7 +256,10 @@ struct MissingFeatures {
static bool emitNullabilityCheck() { return false; }
static bool emitTypeCheck() { return false; }
static bool emitTypeMetadataCodeForVCall() { return false; }
+ static bool fastMathGuard() { return false; }
static bool fastMathFlags() { return false; }
+ static bool fastMathFuncAttributes() { return false; }
+
static bool fpConstraints() { return false; }
static bool generateDebugInfo() { return false; }
static bool globalViewIndices() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 50d585dca3b8c..f525f24918cb6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -16,6 +16,7 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/Support/LLVM.h"
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
+#include "clang/CIR/Dialect/IR/FPEnv.h"
#include "clang/CIR/MissingFeatures.h"
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
@@ -29,6 +30,9 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
const CIRGenTypeCache &typeCache;
llvm::StringMap<unsigned> recordNames;
llvm::StringMap<unsigned> globalsVersioning;
+ bool isFpConstrained = false;
+ cir::fp::ExceptionBehavior defaultConstrainedExcept = cir::fp::ebStrict;
+ llvm::RoundingMode defaultConstrainedRounding = llvm::RoundingMode::Dynamic;
public:
CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
@@ -66,6 +70,56 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
cir::ArrayType arrayTy) const {
return cir::ConstArrayAttr::get(arrayTy, attrs);
}
+ //
+ // Floating point specific helpers
+ // -------------------------------
+ //
+
+ /// Enable/Disable use of constrained floating point math. When enabled the
+ /// CreateF<op>() calls instead create constrained floating point intrinsic
+ /// calls. Fast math flags are unaffected by this setting.
+ void setIsFPConstrained(bool isCon) {
+ if (isCon)
+ llvm_unreachable("Constrained FP NYI");
+ isFpConstrained = isCon;
+ }
+
+ /// Query for the use of constrained floating point math
+ bool getIsFPConstrained() {
+ if (isFpConstrained)
+ llvm_unreachable("Constrained FP NYI");
+ return isFpConstrained;
+ }
+ ///
+ /// Set the exception handling to be used with constrained floating point
+ void setDefaultConstrainedExcept(cir::fp::ExceptionBehavior newExcept) {
+#ifndef NDEBUG
+ std::optional<llvm::StringRef> exceptStr =
+ cir::convertExceptionBehaviorToStr(newExcept);
+ assert(exceptStr && "Garbage strict exception behavior!");
+#endif
+ defaultConstrainedExcept = newExcept;
+ }
+
+ /// Set the rounding mode handling to be used with constrained floating point
+ void setDefaultConstrainedRounding(llvm::RoundingMode newRounding) {
+#ifndef NDEBUG
+ std::optional<llvm::StringRef> roundingStr =
+ cir::convertRoundingModeToStr(newRounding);
+ assert(roundingStr && "Garbage strict rounding mode!");
+#endif
+ defaultConstrainedRounding = newRounding;
+ }
+
+ /// Get the exception handling used with constrained floating point
+ cir::fp::ExceptionBehavior getDefaultConstrainedExcept() {
+ return defaultConstrainedExcept;
+ }
+
+ /// Get the rounding mode handling used with constrained floating point
+ llvm::RoundingMode getDefaultConstrainedRounding() {
+ return defaultConstrainedRounding;
+ }
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr,
bool packed = false,
@@ -332,6 +386,11 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
llvm_unreachable("negation for the given type is NYI");
}
+ cir::IsFPClassOp createIsFPClass(mlir::Location loc, mlir::Value src,
+ unsigned flags) {
+ return cir::IsFPClassOp::create(*this, loc, src, flags);
+ }
+
// TODO: split this to createFPExt/createFPTrunc when we have dedicated cast
// operations.
mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 798e9d9fbb99e..4088018738d57 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -29,6 +29,16 @@ using namespace clang;
using namespace clang::CIRGen;
using namespace llvm;
+static mlir::Value tryUseTestFPKind(CIRGenFunction &cgf, unsigned BuiltinID,
+ mlir::Value V) {
+ if (cgf.getBuilder().getIsFPConstrained() &&
+ cgf.getBuilder().getDefaultConstrainedExcept() != cir::fp::ebIgnore) {
+ if (mlir::Value Result = cgf.getTargetHooks().testFPKind(
+ V, BuiltinID, cgf.getBuilder(), cgf.cgm))
+ return Result;
+ }
+ return nullptr;
+}
static RValue emitLibraryCall(CIRGenFunction &cgf, const FunctionDecl *fd,
const CallExpr *e, mlir::Operation *calleeValue) {
CIRGenCallee callee = CIRGenCallee::forDirect(calleeValue, GlobalDecl(fd));
@@ -454,14 +464,117 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
assert(!cir::MissingFeatures::coroSizeBuiltinCall());
return getUndefRValue(e->getType());
}
+ // From https://clang.llvm.org/docs/LanguageExtensions.html#builtin-isfpclass
+ // :
+ //
+ // The `__builtin_isfpclass()` builtin is a generalization of functions
+ // isnan, isinf, isfinite and some others defined by the C standard. It tests
+ // if the floating-point value, specified by the first argument, falls into
+ // any of data classes, specified by the second argument.
+ case Builtin::BI__builtin_isnan: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ if (mlir::Value result = tryUseTestFPKind(*this, builtinID, v))
+ return RValue::get(result);
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcNan),
+ convertType(e->getType())));
+ }
+
+ case Builtin::BI__builtin_issignaling: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcSNan),
+ convertType(e->getType())));
+ }
+
+ case Builtin::BI__builtin_isinf: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ if (mlir::Value result = tryUseTestFPKind(*this, builtinID, v))
+ return RValue::get(result);
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcInf),
+ convertType(e->getType())));
+ }
+
+ case Builtin::BIfinite:
+ case Builtin::BI__finite:
+ case Builtin::BIfinitef:
+ case Builtin::BI__finitef:
+ case Builtin::BIfinitel:
+ case Builtin::BI__finitel:
+ case Builtin::BI__builtin_isfinite: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ if (mlir::Value result = tryUseTestFPKind(*this, builtinID, v))
+ return RValue::get(result);
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcFinite),
+ convertType(e->getType())));
+ }
+
+ case Builtin::BI__builtin_isnormal: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcNormal),
+ convertType(e->getType())));
+ }
+
+ case Builtin::BI__builtin_issubnormal: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcSubnormal),
+ convertType(e->getType())));
+ }
+
+ case Builtin::BI__builtin_iszero: {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, FPClassTest::fcZero),
+ convertType(e->getType())));
+ }
+ case Builtin::BI__builtin_isfpclass: {
+ Expr::EvalResult result;
+ if (!e->getArg(1)->EvaluateAsInt(result, cgm.getASTContext()))
+ break;
+
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRaii(*this, e);
+ mlir::Value v = emitScalarExpr(e->getArg(0));
+ uint64_t test = result.Val.getInt().getLimitedValue();
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ //
+ // // FIXME: We should use builder.createZExt once createZExt is available.
+ return RValue::get(builder.createZExtOrBitCast(
+ loc, builder.createIsFPClass(loc, v, test), convertType(e->getType())));
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
// the call using the normal call path, but using the unmangled
// version of the function name.
- if (getContext().BuiltinInfo.isLibFunction(builtinID))
+ if (getContext().BuiltinInfo.isLibFunction(builtinID)) {
return emitLibraryCall(*this, fd, e,
cgm.getBuiltinLibFunction(fd, builtinID));
+ }
// Some target-specific builtins can have aggregate return values, e.g.
// __builtin_arm_mve_vld2q_u32. So if the result is an aggregate, force
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index d3c0d9f109317..8b1856da22130 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -805,6 +805,22 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
cgm.errorNYI(dtor->getSourceRange(), "function-try-block destructor");
}
+// Map the LangOption for exception behavior into the corresponding enum in
+// the IR.
+static cir::fp::ExceptionBehavior
+toConstrainedExceptMd(LangOptions::FPExceptionModeKind kind) {
+ switch (kind) {
+ case LangOptions::FPE_Ignore:
+ return cir::fp::ebIgnore;
+ case LangOptions::FPE_MayTrap:
+ return cir::fp::ebMayTrap;
+ case LangOptions::FPE_Strict:
+ return cir::fp::ebStrict;
+ default:
+ llvm_unreachable("Unsupported FP Exception Behavior");
+ }
+}
+
/// Given a value of type T* that may not be to a complete object, construct
/// an l-vlaue withi the natural pointee alignment of T.
LValue CIRGenFunction::makeNaturalAlignPointeeAddrLValue(mlir::Value val,
@@ -975,6 +991,59 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
builder.createStore(loc, zeroValue, destPtr);
}
+CIRGenFunction::CIRGenFPOptionsRAII::CIRGenFPOptionsRAII(CIRGenFunction &cgf,
+ const clang::Expr *e)
+ : cgf(cgf) {
+ constructorHelper(e->getFPFeaturesInEffect(cgf.getLangOpts()));
+}
+
+CIRGenFunction::CIRGenFPOptionsRAII::CIRGenFPOptionsRAII(CIRGenFunction &cgf,
+ FPOptions fpFeatures)
+ : cgf(cgf) {
+ constructorHelper(fpFeatures);
+}
+
+void CIRGenFunction::CIRGenFPOptionsRAII::constructorHelper(
+ FPOptions fpFeatures) {
+ oldFpFeatures = cgf.curFpFeatures;
+ cgf.curFpFeatures = fpFeatures;
+
+ oldExcept = cgf.builder.getDefaultConstrainedExcept();
+ oldRounding = cgf.builder.getDefaultConstrainedRounding();
+
+ if (oldFpFeatures == fpFeatures)
+ return;
+
+ // TODO(cir): create guard to restore fast math configurations.
+ assert(!cir::MissingFeatures::fastMathGuard());
+
+ llvm::RoundingMode newRoundingBehavior = fpFeatures.getRoundingMode();
+ // TODO(cir): override rounding behaviour once FM configs are guarded.
+ auto newExceptionBehavior =
+ toConstrainedExceptMd(static_cast<LangOptions::FPExceptionModeKind>(
+ fpFeatures.getExceptionMode()));
+ // TODO(cir): override exception behaviour once FM configs are guarded.
+
+ // TODO(cir): override FP flags once FM configs are guarded.
+ assert(!cir::MissingFeatures::fastMathFlags());
+
+ assert((cgf.curFuncDecl == nullptr || cgf.builder.getIsFPConstrained() ||
+ isa<CXXConstructorDecl>(cgf.curFuncDecl) ||
+ isa<CXXDestructorDecl>(cgf.curFuncDecl) ||
+ (newExceptionBehavior == cir::fp::ebIgnore &&
+ newRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
+ "FPConstrained should be enabled on entire function");
+
+ // TODO(cir): mark CIR function with fast math attributes.
+ assert(!cir::MissingFeatures::fastMathFuncAttributes());
+}
+
+CIRGenFunction::CIRGenFPOptionsRAII::~CIRGenFPOptionsRAII() {
+ cgf.curFpFeatures = oldFpFeatures;
+ cgf.builder.setDefaultConstrainedExcept(oldExcept);
+ cgf.builder.setDefaultConstrainedRounding(oldRounding);
+}
+
// TODO(cir): should be shared with LLVM codegen.
bool CIRGenFunction::shouldNullCheckClassCastValue(const CastExpr *ce) {
const Expr *e = ce->getSubExpr();
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index e3b9b6a8180d9..7d9a93bde4894 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -31,6 +31,7 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/IR/FPEnv.h"
#include "clang/CIR/MissingFeatures.h"
#include "clang/CIR/TypeEvaluationKind.h"
#include "llvm/ADT/ScopedHashTable.h"
@@ -174,6 +175,21 @@ class CIRGenFunction : public CIRGenTypeCache {
/// Sanitizers enabled for this function.
clang::SanitizerSet sanOpts;
+ class CIRGenFPOptionsRAII {
+ public:
+ CIRGenFPOptionsRAII(CIRGenFunction &cgf, FPOptions fpFeatures);
+ CIRGenFPOptionsRAII(CIRGenFunction &cgf, const clang::Expr *e);
+ ~CIRGenFPOptionsRAII();
+
+ private:
+ void constructorHelper(clang::FPOptions fpFeatures);
+ CIRGenFunction &cgf;
+ clang::FPOptions oldFpFeatures;
+ cir::fp::ExceptionBehavior oldExcept;
+ llvm::RoundingMode oldRounding;
+ };
+ clang::FPOptions curFpFeatures;
+
/// The symbol table maps a variable name to a value in the current scope.
/// Entering a function creates a new scope, ...
[truncated]
|
3ab831e to
b18467a
Compare
andykaylor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good except for some leftover FPEnv artifacts.
andykaylor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
| }]; | ||
|
|
||
| let arguments = (ins CIR_AnyFloatType:$src, | ||
| I32Attr:$flags); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The $flags could use I32BitEnumAttr so that we get some nice printing of the fp class.
|
@badumbatish Can you rebase this PR and possibly implement Bruno's suggestion? |
|
Yep, im on it |
Add lowering test
… OGCG and LLVM test
fcf436e to
e54de58
Compare
🐧 Linux x64 Test Results
|
Ref commit in incubator: ee17ff6
There is a minor change in the assumption for emitting a direct callee. In incubator,
bool hasAttributeNoBuiltin = false(llvm-project/clang/lib/CIR/CodeGen/CIRGenExpr.cpp:1671), while in upstream, it's true, therefore, the call to finite(...) is not converted to a builtin anymore.Fixes #163892