https://github.com/ayokunle321 updated 
https://github.com/llvm/llvm-project/pull/179121

>From 2d0750305d206ef1e63e4ed46b039240441dd9a3 Mon Sep 17 00:00:00 2001
From: Ayokunle Amodu <[email protected]>
Date: Sun, 1 Feb 2026 10:20:54 -0700
Subject: [PATCH 1/2] add support for cgFPOptionsRAII

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      |  1 +
 clang/include/clang/CIR/Dialect/IR/FPEnv.h    | 50 +++++++++++++
 clang/include/clang/CIR/MissingFeatures.h     |  7 ++
 clang/lib/CIR/CodeGen/CIRGenBuilder.h         | 56 +++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp      | 70 +++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenFunction.h        | 15 ++++
 clang/lib/CIR/Dialect/IR/CMakeLists.txt       |  1 +
 clang/lib/CIR/Dialect/IR/FPEnv.cpp            | 64 +++++++++++++++++
 8 files changed, 264 insertions(+)
 create mode 100644 clang/include/clang/CIR/Dialect/IR/FPEnv.h
 create mode 100644 clang/lib/CIR/Dialect/IR/FPEnv.cpp

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index c35c42c8c506b..770a6337626c4 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -14,6 +14,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/Dialect/IR/FPEnv.h"
 #include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
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 cdd9fb950b8b2..c8e61fd217411 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -278,7 +278,14 @@ struct MissingFeatures {
   static bool emitNullabilityCheck() { return false; }
   static bool emitTypeCheck() { return false; }
   static bool emitTypeMetadataCodeForVCall() { return false; }
+  
+  // Fast math.
+  static bool fastMathGuard() { return false; }
+  // Should be implemented with a moduleOp level attribute and directly
+  // mapped to LLVM - those can be set directly for every relevant LLVM IR
+  // dialect operation (log10, ...).
   static bool fastMathFlags() { return false; }
+  static bool fastMathFuncAttributes() { return false; }
 
   static bool fpConstraints() { return false; }
   static bool generateDebugInfo() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index dedb369bf3f67..812d9b9c39acf 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"
@@ -27,6 +28,10 @@ namespace clang::CIRGen {
 
 class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   const CIRGenTypeCache &typeCache;
+  bool isFPConstrained = false;
+  cir::fp::ExceptionBehavior defaultConstrainedExcept = cir::fp::ebStrict;
+  llvm::RoundingMode defaultConstrainedRounding = llvm::RoundingMode::Dynamic;
+
   llvm::StringMap<unsigned> recordNames;
   llvm::StringMap<unsigned> globalsVersioning;
 
@@ -106,6 +111,57 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
     return baseName + "." + std::to_string(recordNames[baseName]++);
   }
 
+  //
+  // 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;
+  }
+
   cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const {
     if (&format == &llvm::APFloat::IEEEdouble())
       return cir::LongDoubleType::get(getContext(), typeCache.doubleTy);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp 
b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index f2d73720a9c2b..3f7a73115b886 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/GlobalDecl.h"
+#include "clang/CIR/Dialect/IR/FPEnv.h"
 #include "clang/CIR/MissingFeatures.h"
 
 #include <cassert>
@@ -956,6 +957,22 @@ LValue 
CIRGenFunction::makeNaturalAlignAddrLValue(mlir::Value val,
   return makeAddrLValue(addr, ty, baseInfo);
 }
 
+// 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");
+  }
+}
+
 clang::QualType CIRGenFunction::buildFunctionArgList(clang::GlobalDecl gd,
                                                      FunctionArgList &args) {
   const auto *fd = cast<FunctionDecl>(gd.getDecl());
@@ -1119,6 +1136,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 adcf4d56e3892..01a36fca6c272 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -185,6 +185,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, and the function arguments are
   /// added to the mapping. When the processing of a function is terminated,
diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt 
b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
index 98575941035f2..de3c7d7a1c3b9 100644
--- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
@@ -4,6 +4,7 @@ add_clang_library(MLIRCIR
   CIRMemorySlot.cpp
   CIRTypes.cpp
   CIRDataLayout.cpp
+  FPEnv.cpp
 
   DEPENDS
   MLIRCIROpsIncGen
diff --git a/clang/lib/CIR/Dialect/IR/FPEnv.cpp 
b/clang/lib/CIR/Dialect/IR/FPEnv.cpp
new file mode 100644
index 0000000000000..501268ce57f47
--- /dev/null
+++ b/clang/lib/CIR/Dialect/IR/FPEnv.cpp
@@ -0,0 +1,64 @@
+//===-- FPEnv.cpp ---- FP Environment 
-------------------------------------===//
+//
+// 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 implementations of entities that describe floating
+/// point environment.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/IR/FPEnv.h"
+
+namespace cir {
+
+std::optional<llvm::StringRef>
+convertRoundingModeToStr(llvm::RoundingMode useRounding) {
+  std::optional<llvm::StringRef> roundingStr;
+  switch (useRounding) {
+  case llvm::RoundingMode::Dynamic:
+    roundingStr = "round.dynamic";
+    break;
+  case llvm::RoundingMode::NearestTiesToEven:
+    roundingStr = "round.tonearest";
+    break;
+  case llvm::RoundingMode::NearestTiesToAway:
+    roundingStr = "round.tonearestaway";
+    break;
+  case llvm::RoundingMode::TowardNegative:
+    roundingStr = "round.downward";
+    break;
+  case llvm::RoundingMode::TowardPositive:
+    roundingStr = "round.upward";
+    break;
+  case llvm::RoundingMode::TowardZero:
+    roundingStr = "round.towardZero";
+    break;
+  default:
+    break;
+  }
+  return roundingStr;
+}
+
+std::optional<llvm::StringRef>
+convertExceptionBehaviorToStr(fp::ExceptionBehavior useExcept) {
+  std::optional<llvm::StringRef> exceptStr;
+  switch (useExcept) {
+  case fp::ebStrict:
+    exceptStr = "fpexcept.strict";
+    break;
+  case fp::ebIgnore:
+    exceptStr = "fpexcept.ignore";
+    break;
+  case fp::ebMayTrap:
+    exceptStr = "fpexcept.maytrap";
+    break;
+  }
+  return exceptStr;
+}
+
+} // namespace cir
\ No newline at end of file

>From 1a0af4e5982b8116b6679c4dddbd0e865c0e21de Mon Sep 17 00:00:00 2001
From: Ayokunle Amodu <[email protected]>
Date: Sun, 1 Feb 2026 10:44:30 -0700
Subject: [PATCH 2/2] fix code format

---
 clang/include/clang/CIR/MissingFeatures.h | 2 +-
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index c8e61fd217411..19cc7a88d1040 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -278,7 +278,7 @@ struct MissingFeatures {
   static bool emitNullabilityCheck() { return false; }
   static bool emitTypeCheck() { return false; }
   static bool emitTypeMetadataCodeForVCall() { return false; }
-  
+
   // Fast math.
   static bool fastMathGuard() { return false; }
   // Should be implemented with a moduleOp level attribute and directly
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp 
b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 3f7a73115b886..e9e6ac74720f0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -1154,7 +1154,7 @@ void 
CIRGenFunction::CIRGenFPOptionsRAII::ConstructorHelper(
   cgf.curFPFeatures = fpFeatures;
 
   oldExcept = cgf.builder.getDefaultConstrainedExcept();
-  oldRounding =cgf.builder.getDefaultConstrainedRounding();
+  oldRounding = cgf.builder.getDefaultConstrainedRounding();
 
   if (oldFPFeatures == fpFeatures)
     return;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to