[Mlir-commits] [mlir] [mlir][SPIR-V] Add ComplexToSPIRV lowering for complex.angle (PR #214172)
Arseniy Obolenskiy
llvmlistbot at llvm.org
Wed Aug 5 02:48:32 PDT 2026
https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/214172
Lower complex.angle to spirv.GL.Atan2/spirv.CL.Atan2 on the real and imaginary components, following the existing complex.abs pattern
>From 340cfe2602a5db2a27a5a7d2e3855fbf1c0011d4 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 5 Aug 2026 11:45:00 +0200
Subject: [PATCH] [mlir][SPIR-V] Add ComplexToSPIRV lowering for complex.angle
Lowers complex.angle to spirv.GL.Atan2/spirv.CL.Atan2 on the real
and imaginary components, following the existing complex.abs pattern.
---
.../ComplexToSPIRV/ComplexToSPIRV.cpp | 51 ++++++++++++++-----
.../ComplexToSPIRV/complex-to-spirv.mlir | 31 +++++++++++
2 files changed, 70 insertions(+), 12 deletions(-)
diff --git a/mlir/lib/Conversion/ComplexToSPIRV/ComplexToSPIRV.cpp b/mlir/lib/Conversion/ComplexToSPIRV/ComplexToSPIRV.cpp
index eb0f81dfecf30..884df06a4e705 100644
--- a/mlir/lib/Conversion/ComplexToSPIRV/ComplexToSPIRV.cpp
+++ b/mlir/lib/Conversion/ComplexToSPIRV/ComplexToSPIRV.cpp
@@ -284,6 +284,31 @@ struct DivOpPattern final : OpConversionPattern<complex::DivOp> {
}
};
+template <typename Atan2Op>
+struct AngleOpPattern final : OpConversionPattern<complex::AngleOp> {
+ using OpConversionPattern<complex::AngleOp>::OpConversionPattern;
+
+ LogicalResult
+ matchAndRewrite(complex::AngleOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Type spirvType =
+ this->getTypeConverter()->convertType(op.getResult().getType());
+ if (!spirvType)
+ return rewriter.notifyMatchFailure(op, "unable to convert result type");
+
+ Location loc = op.getLoc();
+ Value complexVal = adaptor.getComplex();
+
+ Value re =
+ spirv::CompositeExtractOp::create(rewriter, loc, complexVal, {0});
+ Value im =
+ spirv::CompositeExtractOp::create(rewriter, loc, complexVal, {1});
+
+ rewriter.replaceOpWithNewOp<Atan2Op>(op, im, re);
+ return success();
+ }
+};
+
} // namespace
//===----------------------------------------------------------------------===//
@@ -294,16 +319,18 @@ void mlir::populateComplexToSPIRVPatterns(
const SPIRVTypeConverter &typeConverter, RewritePatternSet &patterns) {
MLIRContext *context = patterns.getContext();
- patterns.add<ConstantOpPattern, CreateOpPattern, ReOpPattern, ImOpPattern,
- ElementwiseBinaryOpPattern<complex::AddOp, spirv::FAddOp>,
- ElementwiseBinaryOpPattern<complex::SubOp, spirv::FSubOp>,
- ComparisonOpPattern<complex::EqualOp, spirv::FOrdEqualOp,
- spirv::LogicalAndOp>,
- ComparisonOpPattern<complex::NotEqualOp, spirv::FUnordNotEqualOp,
- spirv::LogicalOrOp>,
- MulOpPattern, DivOpPattern,
- NegationOpPattern<complex::NegOp, /*NegateReal=*/true>,
- NegationOpPattern<complex::ConjOp, /*NegateReal=*/false>,
- AbsOpPattern<spirv::GLSqrtOp>, AbsOpPattern<spirv::CLSqrtOp>>(
- typeConverter, context);
+ patterns
+ .add<ConstantOpPattern, CreateOpPattern, ReOpPattern, ImOpPattern,
+ ElementwiseBinaryOpPattern<complex::AddOp, spirv::FAddOp>,
+ ElementwiseBinaryOpPattern<complex::SubOp, spirv::FSubOp>,
+ ComparisonOpPattern<complex::EqualOp, spirv::FOrdEqualOp,
+ spirv::LogicalAndOp>,
+ ComparisonOpPattern<complex::NotEqualOp, spirv::FUnordNotEqualOp,
+ spirv::LogicalOrOp>,
+ MulOpPattern, DivOpPattern,
+ NegationOpPattern<complex::NegOp, /*NegateReal=*/true>,
+ NegationOpPattern<complex::ConjOp, /*NegateReal=*/false>,
+ AbsOpPattern<spirv::GLSqrtOp>, AbsOpPattern<spirv::CLSqrtOp>,
+ AngleOpPattern<spirv::GLAtan2Op>, AngleOpPattern<spirv::CLAtan2Op>>(
+ typeConverter, context);
}
diff --git a/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir b/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir
index deb4eb6d9d08c..e060c1c0ad44a 100644
--- a/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir
+++ b/mlir/test/Conversion/ComplexToSPIRV/complex-to-spirv.mlir
@@ -237,3 +237,34 @@ func.func @complex_abs_opencl(%arg: complex<f32>) -> f32 {
// CHECK: spirv.CL.sqrt %[[SUM]] : f32
}
+
+// -----
+
+func.func @complex_angle(%arg: complex<f32>) -> f32 {
+ %angle = complex.angle %arg : complex<f32>
+ return %angle : f32
+}
+
+// CHECK-LABEL: func.func @complex_angle
+// CHECK-SAME: %[[ARG:.+]]: complex<f32>
+// CHECK: %[[V:.+]] = builtin.unrealized_conversion_cast %[[ARG]] : complex<f32> to vector<2xf32>
+// CHECK: %[[RE:.+]] = spirv.CompositeExtract %[[V]][0 : i32] : vector<2xf32>
+// CHECK: %[[IM:.+]] = spirv.CompositeExtract %[[V]][1 : i32] : vector<2xf32>
+// CHECK: %[[ANGLE:.+]] = spirv.GL.Atan2 %[[IM]], %[[RE]] : f32
+// CHECK: return %[[ANGLE]] : f32
+
+// -----
+
+module attributes {
+ spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Kernel], []>, #spirv.resource_limits<>>
+} {
+
+func.func @complex_angle_opencl(%arg: complex<f32>) -> f32 {
+ %angle = complex.angle %arg : complex<f32>
+ return %angle : f32
+}
+
+// CHECK-LABEL: func.func @complex_angle_opencl
+// CHECK: spirv.CL.atan2
+
+}
More information about the Mlir-commits
mailing list