[Mlir-commits] [mlir] [mlir][SPIR-V] Convert math.sincos to SPIR-V sin/cos ops (PR #201926)
Arseniy Obolenskiy
llvmlistbot at llvm.org
Fri Jun 5 13:02:57 PDT 2026
https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/201926
None
>From 7d3b0371cdb143497ad11f5cbe28892512f4d327 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 5 Jun 2026 21:54:34 +0200
Subject: [PATCH] [mlir][SPIR-V] Convert math.sincos to SPIR-V sin/cos ops
---
.../Conversion/MathToSPIRV/MathToSPIRV.cpp | 31 ++++++++++++++++++-
.../MathToSPIRV/math-to-gl-spirv.mlir | 24 ++++++++++++++
.../MathToSPIRV/math-to-opencl-spirv.mlir | 22 +++++++++++++
3 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp b/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp
index 5353fb64fb443..85cb16b350f0a 100644
--- a/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp
+++ b/mlir/lib/Conversion/MathToSPIRV/MathToSPIRV.cpp
@@ -544,6 +544,34 @@ struct PowIOpGLPattern final : public OpConversionPattern<math::FPowIOp> {
}
};
+/// Converts math.sincos to SPIR-V ops.
+///
+/// SPIR-V has no fused sincos instruction, so emit separate sin and cos ops
+/// sharing the same operand.
+template <typename SinOp, typename CosOp>
+struct SincosOpPattern final : public OpConversionPattern<math::SincosOp> {
+ using Base::Base;
+
+ LogicalResult
+ matchAndRewrite(math::SincosOp operation, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ if (LogicalResult res = checkSourceOpTypes(rewriter, operation);
+ failed(res))
+ return res;
+
+ Type type =
+ getTypeConverter()->convertType(operation.getOperand().getType());
+ if (!type)
+ return failure();
+
+ Location loc = operation.getLoc();
+ Value sin = SinOp::create(rewriter, loc, type, adaptor.getOperand());
+ Value cos = CosOp::create(rewriter, loc, type, adaptor.getOperand());
+ rewriter.replaceOp(operation, {sin, cos});
+ return success();
+ }
+};
+
/// Converts math.round to GLSL SPIRV extended ops.
struct RoundOpPattern final : public OpConversionPattern<math::RoundOp> {
using Base::Base;
@@ -615,7 +643,7 @@ void populateMathToSPIRVPatterns(const SPIRVTypeConverter &typeConverter,
.add<CountLeadingZerosPattern, CountTrailingZerosPattern,
Log1pOpPattern<spirv::GLLogOp>, Log10OpPattern,
ExpM1OpPattern<spirv::GLExpOp>, PowFOpPattern, PowIOpGLPattern,
- RoundOpPattern,
+ RoundOpPattern, SincosOpPattern<spirv::GLSinOp, spirv::GLCosOp>,
CheckedElementwiseOpPattern<math::AbsFOp, spirv::GLFAbsOp>,
CheckedElementwiseOpPattern<math::AbsIOp, spirv::GLSAbsOp>,
CheckedElementwiseOpPattern<math::AtanOp, spirv::GLAtanOp>,
@@ -647,6 +675,7 @@ void populateMathToSPIRVPatterns(const SPIRVTypeConverter &typeConverter,
// OpenCL patterns
patterns.add<
Log1pOpPattern<spirv::CLLogOp>, ExpM1OpPattern<spirv::CLExpOp>,
+ SincosOpPattern<spirv::CLSinOp, spirv::CLCosOp>,
CheckedElementwiseOpPattern<math::AbsFOp, spirv::CLFAbsOp>,
CheckedElementwiseOpPattern<math::AbsIOp, spirv::CLSAbsOp>,
CheckedElementwiseOpPattern<math::CountLeadingZerosOp, spirv::CLClzOp>,
diff --git a/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir b/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir
index e7d7dec521999..a8b2975ecb3c7 100644
--- a/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir
+++ b/mlir/test/Conversion/MathToSPIRV/math-to-gl-spirv.mlir
@@ -481,3 +481,27 @@ func.func @tensor_1d(%arg0: tensor<2xf32>) {
}
} // end module
+
+// -----
+
+module attributes {
+ spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Shader], []>, #spirv.resource_limits<>>
+} {
+
+// CHECK-LABEL: @sincos_scalar
+func.func @sincos_scalar(%arg0: f32) {
+ // CHECK: %[[SIN:.+]] = spirv.GL.Sin %{{.*}}: f32
+ // CHECK: %[[COS:.+]] = spirv.GL.Cos %{{.*}}: f32
+ %sin, %cos = math.sincos %arg0 : f32
+ return
+}
+
+// CHECK-LABEL: @sincos_vector
+func.func @sincos_vector(%arg0: vector<3xf32>) {
+ // CHECK: %[[SIN:.+]] = spirv.GL.Sin %{{.*}}: vector<3xf32>
+ // CHECK: %[[COS:.+]] = spirv.GL.Cos %{{.*}}: vector<3xf32>
+ %sin, %cos = math.sincos %arg0 : vector<3xf32>
+ return
+}
+
+} // end module
diff --git a/mlir/test/Conversion/MathToSPIRV/math-to-opencl-spirv.mlir b/mlir/test/Conversion/MathToSPIRV/math-to-opencl-spirv.mlir
index fd040f1646661..d58ac740d2565 100644
--- a/mlir/test/Conversion/MathToSPIRV/math-to-opencl-spirv.mlir
+++ b/mlir/test/Conversion/MathToSPIRV/math-to-opencl-spirv.mlir
@@ -238,3 +238,25 @@ func.func @tensor_1d(%arg0: tensor<2xf32>) {
}
} // end module
+
+// -----
+
+module attributes { spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Kernel], []>, #spirv.resource_limits<>> } {
+
+// CHECK-LABEL: @sincos_scalar
+func.func @sincos_scalar(%arg0: f32) {
+ // CHECK: %[[SIN:.+]] = spirv.CL.sin %{{.*}}: f32
+ // CHECK: %[[COS:.+]] = spirv.CL.cos %{{.*}}: f32
+ %sin, %cos = math.sincos %arg0 : f32
+ return
+}
+
+// CHECK-LABEL: @sincos_vector
+func.func @sincos_vector(%arg0: vector<3xf32>) {
+ // CHECK: %[[SIN:.+]] = spirv.CL.sin %{{.*}}: vector<3xf32>
+ // CHECK: %[[COS:.+]] = spirv.CL.cos %{{.*}}: vector<3xf32>
+ %sin, %cos = math.sincos %arg0 : vector<3xf32>
+ return
+}
+
+} // end module
More information about the Mlir-commits
mailing list