[Mlir-commits] [mlir] [mlir][SPIR-V] Add SPIRVToLLVM conversions for FMod and SMod (PR #206933)
Igor Wodiany
llvmlistbot at llvm.org
Thu Jul 30 01:31:12 PDT 2026
================
@@ -1032,6 +1032,83 @@ class ClampPattern : public SPIRVToLLVMConversion<SPIRVOp> {
}
};
+/// Converts `spirv.FMod` to `x - y * floor(x / y)`. The SPIR-V op requires the
+/// result to take the sign of the divisor, whereas `llvm.frem` keeps the sign
+/// of the dividend, so `frem` cannot be used directly.
+class FModPattern : public SPIRVToLLVMConversion<spirv::FModOp> {
+public:
+ using SPIRVToLLVMConversion<spirv::FModOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(spirv::FModOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ auto dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return rewriter.notifyMatchFailure(op, "type conversion failed");
+
+ Location loc = op.getLoc();
+ Value lhs = adaptor.getOperand1();
+ Value rhs = adaptor.getOperand2();
+ Value div = LLVM::FDivOp::create(rewriter, loc, dstType, lhs, rhs);
+ Value floored = LLVM::FFloorOp::create(rewriter, loc, dstType, div);
+ Value scaled = LLVM::FMulOp::create(rewriter, loc, dstType, rhs, floored);
+ rewriter.replaceOpWithNewOp<LLVM::FSubOp>(op, dstType, lhs, scaled);
+ return success();
+ }
+};
+
+/// Converts `spirv.SMod` to a signed remainder corrected to take the sign of
+/// the divisor. `llvm.srem` keeps the sign of the dividend, so the result is
+/// adjusted by adding the divisor when the remainder is non-zero and its sign
+/// differs from the divisor's.
+class SModPattern : public SPIRVToLLVMConversion<spirv::SModOp> {
+public:
+ using SPIRVToLLVMConversion<spirv::SModOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(spirv::SModOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ auto srcType = op.getType();
+ auto dstType = getTypeConverter()->convertType(srcType);
+ if (!dstType)
+ return rewriter.notifyMatchFailure(op, "type conversion failed");
+
+ Location loc = op.getLoc();
+ Value lhs = adaptor.getOperand1();
+ Value rhs = adaptor.getOperand2();
+ Type i1Type = rewriter.getI1Type();
+ auto vecSrcType = dyn_cast<VectorType>(srcType);
+ Type cmpType =
+ vecSrcType ? VectorType::get(vecSrcType.getShape(), i1Type) : i1Type;
+
+ Value rem = LLVM::SRemOp::create(rewriter, loc, dstType, lhs, rhs);
+ IntegerAttr zeroAttr = rewriter.getIntegerAttr(
+ cast<IntegerType>(getElementTypeOrSelf(srcType)), 0);
+ Value zero;
+ if (vecSrcType)
+ zero = LLVM::ConstantOp::create(
+ rewriter, loc, dstType, SplatElementsAttr::get(vecSrcType, zeroAttr));
+ else
+ zero = LLVM::ConstantOp::create(rewriter, loc, dstType, zeroAttr);
----------------
IgWod wrote:
Can it use the helper as in the other PR?
https://github.com/llvm/llvm-project/pull/206933
More information about the Mlir-commits
mailing list