Author: Arseniy Obolenskiy
Date: 2026-11-02T10:23:12+01:00
New Revision: c7afb2bb15a40697b8f394830f112458891cd12f
URL: https://github.com/llvm/llvm-project/commit/c7afb2bb15a40697b8f394830f112458891cd12f
DIFF: https://github.com/llvm/llvm-project/commit/c7afb2bb15a40697b8f394830f112458891cd12f.diff
LOG: [mlir][SPIR-V] Add SPIRVToLLVM conversion for CL.clz and CL.ctz (#237851)
Added:
Modified:
mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
index 4b34bc722b8ee7..cfcc608025848e 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
@@ -1940,6 +1940,27 @@ class SAbsPattern : public SPIRVToLLVMConversion<spirv::GLSAbsOp> {
}
};
+/// Converts `spirv.CL.clz` and `spirv.CL.ctz` to `llvm.intr.ctlz` and
+/// `llvm.intr.cttz`.
+template <typename SPIRVOp, typename LLVMOp>
+class CountZerosPattern : public SPIRVToLLVMConversion<SPIRVOp> {
+public:
+ using SPIRVToLLVMConversion<SPIRVOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(SPIRVOp op, typename SPIRVOp::Adaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Type dstType = this->getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return rewriter.notifyMatchFailure(op, "type conversion failed");
+
+ rewriter.template replaceOpWithNewOp<LLVMOp>(op, dstType,
+ adaptor.getOperand(),
+ /*is_zero_poison=*/false);
+ return success();
+ }
+};
+
/// Converts `spirv.GL.Fract` to `x - floor(x)`.
class FractPattern : public SPIRVToLLVMConversion<spirv::GLFractOp> {
public:
@@ -2502,6 +2523,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
DirectConversionPattern<spirv::CLSMinOp, LLVM::SMinOp>,
DirectConversionPattern<spirv::CLUMaxOp, LLVM::UMaxOp>,
DirectConversionPattern<spirv::CLUMinOp, LLVM::UMinOp>, CLMixPattern,
+ CountZerosPattern<spirv::CLClzOp, LLVM::CountLeadingZerosOp>,
+ CountZerosPattern<spirv::CLCtzOp, LLVM::CountTrailingZerosOp>,
// 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..0fc6935260ff3f 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
@@ -104,6 +104,15 @@ spirv.func @cl_integer(%arg0: i32, %arg1: i32) "None" {
spirv.Return
}
+// CHECK-LABEL: @cl_count_zeros
+spirv.func @cl_count_zeros(%arg0: i32, %arg1: vector<3xi16>) "None" {
+ // CHECK: "llvm.intr.ctlz"(%{{.*}}) <{is_zero_poison = false}> : (i32) -> i32
+ %0 = spirv.CL.clz %arg0 : i32
+ // CHECK: "llvm.intr.cttz"(%{{.*}}) <{is_zero_poison = false}> : (vector<3xi16>) -> vector<3xi16>
+ %1 = spirv.CL.ctz %arg1 : vector<3xi16>
+ spirv.Return
+}
+
//===----------------------------------------------------------------------===//
// spirv.CL.mix
//===----------------------------------------------------------------------===//