[Mlir-commits] [mlir] [mlir][SPIR-V] Support floating-point atomic_rmw addf in MemRefToSPIRV (PR #202330)

Arseniy Obolenskiy llvmlistbot at llvm.org
Mon Jun 8 06:19:44 PDT 2026


https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/202330

>From c3e92123e5ff12535621865c680f4d806e7917fe Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 8 Jun 2026 14:40:46 +0200
Subject: [PATCH] [mlir][SPIR-V] Support floating-point atomic_rmw addf in
 MemRefToSPIRV

---
 .../Conversion/MemRefToSPIRV/MemRefToSPIRV.cpp | 15 +++++++--------
 mlir/test/Conversion/MemRefToSPIRV/atomic.mlir | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/mlir/lib/Conversion/MemRefToSPIRV/MemRefToSPIRV.cpp b/mlir/lib/Conversion/MemRefToSPIRV/MemRefToSPIRV.cpp
index fe9f9c59e6ede..4674aa351315f 100644
--- a/mlir/lib/Conversion/MemRefToSPIRV/MemRefToSPIRV.cpp
+++ b/mlir/lib/Conversion/MemRefToSPIRV/MemRefToSPIRV.cpp
@@ -454,10 +454,6 @@ LogicalResult
 AtomicRMWOpPattern::matchAndRewrite(memref::AtomicRMWOp atomicOp,
                                     OpAdaptor adaptor,
                                     ConversionPatternRewriter &rewriter) const {
-  if (isa<FloatType>(atomicOp.getType()))
-    return rewriter.notifyMatchFailure(atomicOp,
-                                       "unimplemented floating-point case");
-
   auto memrefType = cast<MemRefType>(atomicOp.getMemref().getType());
   std::optional<spirv::Scope> scope = getAtomicOpScope(memrefType);
   if (!scope)
@@ -488,13 +484,13 @@ AtomicRMWOpPattern::matchAndRewrite(memref::AtomicRMWOp atomicOp,
                                        "failed to convert memref type");
 
   Type pointeeType = pointerType.getPointeeType();
-  auto dstType = dyn_cast<IntegerType>(
-      getElementTypeForStoragePointer(pointeeType, typeConverter));
-  if (!dstType)
+  Type storageElemType =
+      getElementTypeForStoragePointer(pointeeType, typeConverter);
+  if (!storageElemType || !storageElemType.isIntOrFloat())
     return rewriter.notifyMatchFailure(
         atomicOp, "failed to determine destination element type");
 
-  int dstBits = static_cast<int>(dstType.getWidth());
+  int dstBits = static_cast<int>(storageElemType.getIntOrFloatBitWidth());
   assert(dstBits % srcBits == 0);
 
   spirv::MemorySemantics memSem = getAtomicAcqRelMemorySemantics(memrefType);
@@ -509,6 +505,7 @@ AtomicRMWOpPattern::matchAndRewrite(memref::AtomicRMWOp atomicOp,
     break
 
     switch (atomicOp.getKind()) {
+      ATOMIC_CASE(addf, EXTAtomicFAddOp);
       ATOMIC_CASE(addi, AtomicIAddOp);
       ATOMIC_CASE(maxs, AtomicSMaxOp);
       ATOMIC_CASE(maxu, AtomicUMaxOp);
@@ -546,6 +543,8 @@ AtomicRMWOpPattern::matchAndRewrite(memref::AtomicRMWOp atomicOp,
         atomicOp,
         "sub-element-width atomic ops unsupported with Kernel capability");
 
+  auto dstType = cast<IntegerType>(storageElemType);
+
   auto accessChainOp = ptr.getDefiningOp<spirv::AccessChainOp>();
   if (!accessChainOp)
     return failure();
diff --git a/mlir/test/Conversion/MemRefToSPIRV/atomic.mlir b/mlir/test/Conversion/MemRefToSPIRV/atomic.mlir
index b5815a73ee8b2..fa416512aa144 100644
--- a/mlir/test/Conversion/MemRefToSPIRV/atomic.mlir
+++ b/mlir/test/Conversion/MemRefToSPIRV/atomic.mlir
@@ -146,3 +146,21 @@ func.func @atomic_andi_i8_storage_buffer(%value: i8, %memref: memref<16xi8, #spi
 }
 
 }
+
+// -----
+
+// Floating-point atomic add requires the shader_atomic_float_add extension.
+
+module attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.3, [Shader, AtomicFloat32AddEXT], [SPV_EXT_shader_atomic_float_add]>, #spirv.resource_limits<>>} {
+
+//      CHECK: func.func @atomic_addf_storage_buffer
+// CHECK-SAME: (%[[VAL:.+]]: f32,
+func.func @atomic_addf_storage_buffer(%value: f32, %memref: memref<2x3x4xf32, #spirv.storage_class<StorageBuffer>>, %i0: index, %i1: index, %i2: index) -> f32 {
+  // CHECK: %[[AC:.+]] = spirv.AccessChain
+  // CHECK: %[[ATOMIC:.+]] = spirv.EXT.AtomicFAdd <Device> <AcquireRelease|UniformMemory> %[[AC]], %[[VAL]] : !spirv.ptr<f32, StorageBuffer>
+  // CHECK: return %[[ATOMIC]]
+  %0 = memref.atomic_rmw "addf" %value, %memref[%i0, %i1, %i2] : (f32, memref<2x3x4xf32, #spirv.storage_class<StorageBuffer>>) -> f32
+  return %0: f32
+}
+
+}



More information about the Mlir-commits mailing list