https://github.com/xakep8 updated 
https://github.com/llvm/llvm-project/pull/224899

>From 8289cb4434b394bb654573c10f04a717b108bd9a Mon Sep 17 00:00:00 2001
From: Kunal Dubey <[email protected]>
Date: Sun, 20 Sep 2026 14:31:07 +0530
Subject: [PATCH 1/3] [CIR] Added fast-math flags to LLVM intrinsic calls

Added fast-math flags attribute to CIR which cir.call_llvm_intrinsic now
carries through DirectToLLVM lowering. CIR now preserves fast-math flags
such as reassoc when lowering to llvm.call_intrinsic.

Added test for the same.
---
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  | 28 +++++++++++++++++++
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  9 ++++--
 clang/lib/CIR/CodeGen/CIRGenBuilder.h         |  9 ++++++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 26 ++++++++++++++++-
 .../test/CIR/Lowering/call-llvm-intrinsic.cir | 11 ++++++++
 5 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 57a6237138ac70..840d03e99a11e2 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -947,6 +947,34 @@ def CIR_FenvAttr : CIR_Attr<"Fenv", "fenv"> {
   let canHaveIllegalCXXABIType = 0;
 }
 
+//===----------------------------------------------------------------------===//
+// FastMathFlagsAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_FMFnone     : I32BitEnumAttrCaseNone<"none">;
+def CIR_FMFnnan     : I32BitEnumAttrCaseBit<"nnan", 0>;
+def CIR_FMFninf     : I32BitEnumAttrCaseBit<"ninf", 1>;
+def CIR_FMFnsz      : I32BitEnumAttrCaseBit<"nsz", 2>;
+def CIR_FMFarcp     : I32BitEnumAttrCaseBit<"arcp", 3>;
+def CIR_FMFcontract : I32BitEnumAttrCaseBit<"contract", 4>;
+def CIR_FMFafn      : I32BitEnumAttrCaseBit<"afn", 5>;
+def CIR_FMFreassoc  : I32BitEnumAttrCaseBit<"reassoc", 6>;
+def CIR_FMFfast     : I32BitEnumAttrCaseGroup<"fast", [
+  CIR_FMFnnan, CIR_FMFninf, CIR_FMFnsz, CIR_FMFarcp, CIR_FMFcontract,
+  CIR_FMFafn, CIR_FMFreassoc
+]>;
+
+def CIR_FastMathFlags : CIR_I32BitEnum<
+    "FastMathFlags", "fast-math flags", [
+  CIR_FMFnone, CIR_FMFnnan, CIR_FMFninf, CIR_FMFnsz, CIR_FMFarcp,
+  CIR_FMFcontract, CIR_FMFafn, CIR_FMFreassoc, CIR_FMFfast
+]> {
+  let separator = ", ";
+  let printBitEnumPrimaryGroups = 1;
+}
+
+def CIR_FastMathFlagsAttr : CIR_EnumAttr<CIR_FastMathFlags, "fastmath">;
+
 
//===----------------------------------------------------------------------===//
 // GlobalViewAttr
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index f6b524176a6559..ce858823c994a9 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4509,7 +4509,9 @@ def CIR_LLVMIntrinsicCallOp : 
CIR_Op<"call_llvm_intrinsic"> {
 
   let results = (outs Optional<CIR_AnyType>:$result);
   let arguments = (ins
-                   StrAttr:$intrinsic_name, Variadic<CIR_AnyType>:$arg_ops);
+                   StrAttr:$intrinsic_name,
+                   OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath_flags,
+                   Variadic<CIR_AnyType>:$arg_ops);
 
   let skipDefaultBuilders = 1;
 
@@ -4519,8 +4521,11 @@ def CIR_LLVMIntrinsicCallOp : 
CIR_Op<"call_llvm_intrinsic"> {
 
   let builders = [
     OpBuilder<(ins "mlir::StringAttr":$intrinsic_name, "mlir::Type":$resType,
-              CArg<"mlir::ValueRange", "{}">:$operands), [{
+              CArg<"mlir::ValueRange", "{}">:$operands,
+              CArg<"cir::FastMathFlagsAttr", "{}">:$fastmath), [{
       $_state.addAttribute("intrinsic_name", intrinsic_name);
+      if (fastmath)
+        $_state.addAttribute("fastmath_flags", fastmath);
       $_state.addOperands(operands);
       if (resType)
         $_state.addTypes(resType);
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 91e3b18a6b3155..2f82c1d2494346 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -830,6 +830,15 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
                                             std::forward<Operands>(op)...)
         .getResult();
   }
+
+  mlir::Value emitIntrinsicCallOp(mlir::Location loc, const llvm::StringRef 
str,
+                                  const mlir::Type &resTy,
+                                  mlir::ValueRange operands,
+                                  cir::FastMathFlagsAttr fastmath) {
+    return cir::LLVMIntrinsicCallOp::create(
+               *this, loc, this->getStringAttr(str), resTy, operands, fastmath)
+        .getResult();
+  }
 };
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 1b1423862ba7bb..770f89c8552868 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -582,6 +582,27 @@ mlir::LogicalResult lowerConstrainableFPOp(
                                        constrainedMnemonic, hasRoundingMode);
 }
 
+static mlir::LLVM::FastmathFlags
+convertFastMathFlags(cir::FastMathFlags cirFlags) {
+  mlir::LLVM::FastmathFlags llvmFlags{};
+  const std::pair<cir::FastMathFlags, mlir::LLVM::FastmathFlags> flags[] = {
+      {cir::FastMathFlags::nnan, mlir::LLVM::FastmathFlags::nnan},
+      {cir::FastMathFlags::ninf, mlir::LLVM::FastmathFlags::ninf},
+      {cir::FastMathFlags::nsz, mlir::LLVM::FastmathFlags::nsz},
+      {cir::FastMathFlags::arcp, mlir::LLVM::FastmathFlags::arcp},
+      {cir::FastMathFlags::contract, mlir::LLVM::FastmathFlags::contract},
+      {cir::FastMathFlags::afn, mlir::LLVM::FastmathFlags::afn},
+      {cir::FastMathFlags::reassoc, mlir::LLVM::FastmathFlags::reassoc},
+  };
+
+  for (auto [cirFlag, llvmFlag] : flags) {
+    if (bitEnumContainsAny(cirFlags, cirFlag))
+      llvmFlags = llvmFlags | llvmFlag;
+  }
+
+  return llvmFlags;
+}
+
 mlir::LogicalResult CIRToLLVMLLVMIntrinsicCallOpLowering::matchAndRewrite(
     cir::LLVMIntrinsicCallOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
@@ -594,6 +615,9 @@ mlir::LogicalResult 
CIRToLLVMLLVMIntrinsicCallOpLowering::matchAndRewrite(
       return op.emitError("expected LLVM result type");
   }
   StringRef name = op.getIntrinsicName();
+  mlir::LLVM::FastmathFlags fastmathFlags = {};
+  if (std::optional<cir::FastMathFlags> fastmath = op.getFastmathFlags())
+    fastmathFlags = convertFastMathFlags(*fastmath);
 
   // Some LLVM intrinsics require ElementType attribute to be attached to
   // the argument of pointer type. That prevents us from generating LLVM IR
@@ -606,7 +630,7 @@ mlir::LogicalResult 
CIRToLLVMLLVMIntrinsicCallOpLowering::matchAndRewrite(
   // to set LLVM IR attribute.
   assert(!cir::MissingFeatures::intrinsicElementTypeSupport());
   replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm." + name, llvmResTy,
-                                   adaptor.getOperands());
+                                   adaptor.getOperands(), fastmathFlags);
   return mlir::success();
 }
 
diff --git a/clang/test/CIR/Lowering/call-llvm-intrinsic.cir 
b/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
index edd492aa7477ca..643e4db0d7d0c4 100644
--- a/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
+++ b/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
@@ -5,6 +5,8 @@
 // 0-result (void) calls in addition to the single-result case.
 
 !s32i = !cir.int<s, 32>
+!f32 = !cir.float
+!v4f32 = !cir.vector<4 x !f32>
 
 module {
   // 0-result, 0-operand.
@@ -24,4 +26,13 @@ module {
     cir.call_llvm_intrinsic "amdgcn.s.sleep" %arg0 : (!s32i) -> ()
     cir.return
   }
+
+  // Fast-math flags are preserved on the lowered LLVM intrinsic call.
+  // CHECK-LABEL: llvm.func @fastmath_flags
+  // CHECK:         llvm.call_intrinsic "llvm.vector.reduce.fadd"(%{{.*}}, 
%{{.*}}) {fastmathFlags = #llvm.fastmath<reassoc>} : (f32, vector<4xf32>) -> f32
+  // CHECK:         llvm.return
+  cir.func @fastmath_flags(%arg0: !f32, %arg1: !v4f32) -> !f32 {
+    %0 = cir.call_llvm_intrinsic "vector.reduce.fadd" %arg0, %arg1 : (!f32, 
!v4f32) -> !f32 {fastmath_flags = #cir.fastmath<reassoc>}
+    cir.return %0 : !f32
+  }
 }

>From 1f8b250a8e9062bb6261c366f8a8013d812280d9 Mon Sep 17 00:00:00 2001
From: Kunal Dubey <[email protected]>
Date: Tue, 22 Sep 2026 00:34:55 +0530
Subject: [PATCH 2/3] [CIR] Added fast-math attr description and tests

---
 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td  | 6 ++++++
 clang/test/CIR/IR/enum-attrs.cir                | 8 ++++++++
 clang/test/CIR/Lowering/call-llvm-intrinsic.cir | 8 ++++++++
 3 files changed, 22 insertions(+)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 840d03e99a11e2..04dc8bb178cb87 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -969,6 +969,12 @@ def CIR_FastMathFlags : CIR_I32BitEnum<
   CIR_FMFnone, CIR_FMFnnan, CIR_FMFninf, CIR_FMFnsz, CIR_FMFarcp,
   CIR_FMFcontract, CIR_FMFafn, CIR_FMFreassoc, CIR_FMFfast
 ]> {
+  let description = [{
+    Describes fast-math flags for CIR operations. This attribute is shared by
+    operations with floating-point semantics and is not specific to LLVM 
intrinsic
+    calls.
+  }];
+
   let separator = ", ";
   let printBitEnumPrimaryGroups = 1;
 }
diff --git a/clang/test/CIR/IR/enum-attrs.cir b/clang/test/CIR/IR/enum-attrs.cir
index 6455564cab7937..e4c4e76a292c75 100644
--- a/clang/test/CIR/IR/enum-attrs.cir
+++ b/clang/test/CIR/IR/enum-attrs.cir
@@ -131,6 +131,14 @@ cir.func @fp_class_attr() {
                           #cir.fp_class<fcSNan|fcNegInf>]}
 }
 
+// CHECK-LABEL: cir.func @fastmath_attr() {
+cir.func @fastmath_attr() {
+  // CHECK: cir.return {cir.test = [#cir.fastmath<reassoc>, 
#cir.fastmath<nnan, ninf>, #cir.fastmath<fast>]}
+  cir.return {cir.test = [#cir.fastmath<reassoc>,
+                          #cir.fastmath<nnan, ninf>,
+                          #cir.fastmath<fast>]}
+}
+
 // The operations themselves keep printing a bare keyword.
 
 // CHECK-LABEL: cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) {
diff --git a/clang/test/CIR/Lowering/call-llvm-intrinsic.cir 
b/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
index 643e4db0d7d0c4..cbc2c469697983 100644
--- a/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
+++ b/clang/test/CIR/Lowering/call-llvm-intrinsic.cir
@@ -35,4 +35,12 @@ module {
     %0 = cir.call_llvm_intrinsic "vector.reduce.fadd" %arg0, %arg1 : (!f32, 
!v4f32) -> !f32 {fastmath_flags = #cir.fastmath<reassoc>}
     cir.return %0 : !f32
   }
+
+  // CHECK-LABEL: llvm.func @fastmath_fast_group
+  // CHECK:         llvm.call_intrinsic "llvm.vector.reduce.fadd"(%{{.*}}, 
%{{.*}}) {fastmathFlags = #llvm.fastmath<fast>} : (f32, vector<4xf32>) -> f32
+  // CHECK:         llvm.return
+  cir.func @fastmath_fast_group(%arg0: !f32, %arg1: !v4f32) -> !f32 {
+    %0 = cir.call_llvm_intrinsic "vector.reduce.fadd" %arg0, %arg1 : (!f32, 
!v4f32) -> !f32 {fastmath_flags = #cir.fastmath<fast>}
+    cir.return %0 : !f32
+  }
 }

>From aa3c7cc9e474c38fd8a831394e42802e81d6ac31 Mon Sep 17 00:00:00 2001
From: Kunal Dubey <[email protected]>
Date: Tue, 22 Sep 2026 13:27:30 +0530
Subject: [PATCH 3/3] [CIR] Updated IntrinsicCallOp helper shape

Changed mlir::Value range to template Operands &&...ops and moved flags before
the operands to improve the overall design.
---
 clang/lib/CIR/CodeGen/CIRGenBuilder.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 2f82c1d2494346..e93bda42a903e9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -831,12 +831,14 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
         .getResult();
   }
 
+  template <typename... Operands>
   mlir::Value emitIntrinsicCallOp(mlir::Location loc, const llvm::StringRef 
str,
                                   const mlir::Type &resTy,
-                                  mlir::ValueRange operands,
-                                  cir::FastMathFlagsAttr fastmath) {
+                                  cir::FastMathFlagsAttr fastmath,
+                                  Operands &&...op) {
     return cir::LLVMIntrinsicCallOp::create(
-               *this, loc, this->getStringAttr(str), resTy, operands, fastmath)
+               *this, loc, this->getStringAttr(str), resTy,
+               std::forward<Operands>(op)..., fastmath)
         .getResult();
   }
 };

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

Reply via email to