[Mlir-commits] [mlir] [mlir][SPIR-V] Add OpenCL ctz, ilogb, and sincos operations (PR #231713)

Alexander Shaposhnikov llvmlistbot at llvm.org
Tue Oct 13 22:19:56 PDT 2026


================
@@ -292,6 +294,47 @@ struct CountTrailingZerosPattern final
   }
 };
 
+/// Converts math.cttz to OpenCL.std ctz, preserving the source bit width when
+/// narrow integers are emulated using wider integers.
+struct CountTrailingZerosOpenCLPattern final
+    : public OpConversionPattern<math::CountTrailingZerosOp> {
+  using Base::Base;
+
+  LogicalResult
+  matchAndRewrite(math::CountTrailingZerosOp op, OpAdaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    if (failed(checkSourceOpTypes(rewriter, op)))
+      return failure();
+
+    auto &typeConverter = *getTypeConverter<SPIRVTypeConverter>();
+    if (!typeConverter.getTargetEnv().allows(spirv::Capability::Kernel))
+      return rewriter.notifyMatchFailure(op, "requires Kernel capability");
+    Type type = typeConverter.convertType(op.getType());
+    if (!type)
+      return failure();
+
+    Type elementType = getElementTypeOrSelf(type);
+    unsigned sourceWidth =
+        getElementTypeOrSelf(op.getType()).getIntOrFloatBitWidth();
+    unsigned targetWidth = elementType.getIntOrFloatBitWidth();
+    Value input = adaptor.getOperand();
+    if (sourceWidth < targetWidth) {
+      // Set the bit immediately above the original value. This bounds the
+      // count by sourceWidth, even when the emulated value has nonzero high
+      // bits, and gives the correct result for a zero source value.
+      Attribute sentinel = IntegerAttr::get(
+          elementType, APInt::getOneBitSet(targetWidth, sourceWidth));
+      if (auto vectorType = dyn_cast<VectorType>(type))
+        sentinel = SplatElementsAttr::get(vectorType, sentinel);
+      Value mask =
+          spirv::ConstantOp::create(rewriter, op.getLoc(), type, sentinel);
+      input = spirv::BitwiseOrOp::create(rewriter, op.getLoc(), input, mask);
+    }
+    rewriter.replaceOpWithNewOp<spirv::CLCtzOp>(op, type, input);
----------------
alexander-shaposhnikov wrote:

Yeah, fixed, also added a test

https://github.com/llvm/llvm-project/pull/231713


More information about the Mlir-commits mailing list