[Mlir-commits] [mlir] [mlir][SPIR-V] Add SPIRVToLLVM conversions for CL.s_abs and CL.rsqrt (PR #237740)

Arseniy Obolenskiy llvmlistbot at llvm.org
Mon Nov 2 01:29:44 PST 2026


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

>From dcaf95bf1fb9515290eb56b9519fb2c3e66c3b4a Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Sun, 1 Nov 2026 16:18:22 +0100
Subject: [PATCH] [mlir][SPIR-V] Add SPIRVToLLVM conversions for CL.s_abs and
 CL.rsqrt

Reuse the GL.SAbs and GL.InverseSqrt patterns by templating them on the source op
---
 .../Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp    | 34 ++++++++++---------
 .../SPIRVToLLVM/cl-ops-to-llvm.mlir           | 26 ++++++++++++++
 2 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
index 4b34bc722b8ee7..601c9dc71f3883 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
@@ -1064,23 +1064,23 @@ class FPClassPattern : public SPIRVToLLVMConversion<SPIRVOp> {
   }
 };
 
-class InverseSqrtPattern
-    : public SPIRVToLLVMConversion<spirv::GLInverseSqrtOp> {
+template <typename SPIRVOp>
+class InverseSqrtPattern : public SPIRVToLLVMConversion<SPIRVOp> {
 public:
-  using SPIRVToLLVMConversion<spirv::GLInverseSqrtOp>::SPIRVToLLVMConversion;
+  using SPIRVToLLVMConversion<SPIRVOp>::SPIRVToLLVMConversion;
 
   LogicalResult
-  matchAndRewrite(spirv::GLInverseSqrtOp op, OpAdaptor adaptor,
+  matchAndRewrite(SPIRVOp op, typename SPIRVOp::Adaptor adaptor,
                   ConversionPatternRewriter &rewriter) const override {
     auto srcType = op.getType();
-    auto dstType = getTypeConverter()->convertType(srcType);
+    auto dstType = this->getTypeConverter()->convertType(srcType);
     if (!dstType)
       return rewriter.notifyMatchFailure(op, "type conversion failed");
 
     Location loc = op.getLoc();
     Value one = createFPConstant(loc, srcType, dstType, rewriter, 1.0);
     Value sqrt = LLVM::SqrtOp::create(rewriter, loc, dstType, op.getOperand());
-    rewriter.replaceOpWithNewOp<LLVM::FDivOp>(op, dstType, one, sqrt);
+    rewriter.template replaceOpWithNewOp<LLVM::FDivOp>(op, dstType, one, sqrt);
     return success();
   }
 };
@@ -1921,21 +1921,22 @@ class ShiftPattern : public SPIRVToLLVMConversion<SPIRVOp> {
 };
 
 // `llvm.intr.abs` requires an `is_int_min_poison` immarg that `spirv.GL.SAbs`
-// does not carry; default to `false` to preserve SPIR-V's well-defined
-// behavior on INT_MIN.
-class SAbsPattern : public SPIRVToLLVMConversion<spirv::GLSAbsOp> {
+// and `spirv.CL.s_abs` do not carry; default to `false` to preserve SPIR-V's
+// well-defined behavior on INT_MIN.
+template <typename SPIRVOp>
+class SAbsPattern : public SPIRVToLLVMConversion<SPIRVOp> {
 public:
-  using SPIRVToLLVMConversion<spirv::GLSAbsOp>::SPIRVToLLVMConversion;
+  using SPIRVToLLVMConversion<SPIRVOp>::SPIRVToLLVMConversion;
 
   LogicalResult
-  matchAndRewrite(spirv::GLSAbsOp op, OpAdaptor adaptor,
+  matchAndRewrite(SPIRVOp op, typename SPIRVOp::Adaptor adaptor,
                   ConversionPatternRewriter &rewriter) const override {
-    Type dstType = getTypeConverter()->convertType(op.getType());
+    Type dstType = this->getTypeConverter()->convertType(op.getType());
     if (!dstType)
       return rewriter.notifyMatchFailure(op, "type conversion failed");
 
-    rewriter.replaceOpWithNewOp<LLVM::AbsOp>(op, dstType, adaptor.getOperand(),
-                                             /*is_int_min_poison=*/false);
+    rewriter.template replaceOpWithNewOp<LLVM::AbsOp>(
+        op, dstType, adaptor.getOperand(), /*is_int_min_poison=*/false);
     return success();
   }
 };
@@ -2464,8 +2465,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
       DirectConversionPattern<spirv::GLAtanOp, LLVM::ATanOp>,
       DirectConversionPattern<spirv::GLTanOp, LLVM::TanOp>,
       DirectConversionPattern<spirv::GLTanhOp, LLVM::TanhOp>,
-      InverseSqrtPattern, SAbsPattern, FractPattern,
-      SignPattern<spirv::GLFSignOp, /*isFloat=*/true>,
+      InverseSqrtPattern<spirv::GLInverseSqrtOp>, SAbsPattern<spirv::GLSAbsOp>,
+      FractPattern, SignPattern<spirv::GLFSignOp, /*isFloat=*/true>,
       SignPattern<spirv::GLSSignOp, /*isFloat=*/false>, GLFMixPattern,
 
       // OpenCL extended instruction set ops
@@ -2502,6 +2503,7 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
       DirectConversionPattern<spirv::CLSMinOp, LLVM::SMinOp>,
       DirectConversionPattern<spirv::CLUMaxOp, LLVM::UMaxOp>,
       DirectConversionPattern<spirv::CLUMinOp, LLVM::UMinOp>, CLMixPattern,
+      InverseSqrtPattern<spirv::CLRsqrtOp>, SAbsPattern<spirv::CLSAbsOp>,
 
       // Logical ops
       DirectConversionPattern<spirv::LogicalAndOp, LLVM::AndOp>,
diff --git a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
index e6fed930268d47..5f52fc7a4db68a 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
@@ -101,6 +101,32 @@ spirv.func @cl_integer(%arg0: i32, %arg1: i32) "None" {
   %2 = spirv.CL.u_max %arg0, %arg1 : i32
   // CHECK: llvm.intr.umin(%{{.*}}, %{{.*}}) : (i32, i32) -> i32
   %3 = spirv.CL.u_min %arg0, %arg1 : i32
+  // CHECK: "llvm.intr.abs"(%{{.*}}) <{is_int_min_poison = false}> : (i32) -> i32
+  %4 = spirv.CL.s_abs %arg0 : i32
+  spirv.Return
+}
+
+// CHECK-LABEL: @cl_s_abs_vector
+spirv.func @cl_s_abs_vector(%arg0: vector<3xi16>) "None" {
+  // CHECK: "llvm.intr.abs"(%{{.*}}) <{is_int_min_poison = false}> : (vector<3xi16>) -> vector<3xi16>
+  %0 = spirv.CL.s_abs %arg0 : vector<3xi16>
+  spirv.Return
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.CL.rsqrt
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @rsqrt
+spirv.func @rsqrt(%arg0: f32, %arg1: vector<3xf16>) "None" {
+  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
+  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%{{.*}}) : (f32) -> f32
+  // CHECK: llvm.fdiv %[[ONE]], %[[SQRT]] : f32
+  %0 = spirv.CL.rsqrt %arg0 : f32
+  // CHECK: %[[VONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<3xf16>) : vector<3xf16>
+  // CHECK: %[[VSQRT:.*]] = llvm.intr.sqrt(%{{.*}}) : (vector<3xf16>) -> vector<3xf16>
+  // CHECK: llvm.fdiv %[[VONE]], %[[VSQRT]] : vector<3xf16>
+  %1 = spirv.CL.rsqrt %arg1 : vector<3xf16>
   spirv.Return
 }
 



More information about the Mlir-commits mailing list