[Mlir-commits] [mlir] [mlir][SPIR-V] Add ComplexToSPIRV lowering for complex.sin/cos (PR #231873)

Arseniy Obolenskiy llvmlistbot at llvm.org
Wed Oct 14 21:09:12 PDT 2026


================
@@ -369,6 +369,89 @@ struct SignOpPattern final : OpConversionPattern<complex::SignOp> {
     return success();
   }
 };
+
+/// Common building blocks for complex.sin/cos, following the identities
+/// sin(x + iy) = sin(x) * (0.5*exp(y) + 0.5/exp(y))
+///              + i * cos(x) * (0.5*exp(y) - 0.5/exp(y))
+/// cos(x + iy) = cos(x) * (0.5/exp(y) + 0.5*exp(y))
+///              + i * sin(x) * (0.5/exp(y) - 0.5*exp(y))
+template <typename ComplexOp, typename SinOp, typename CosOp, typename ExpOp>
+struct TrigonometricOpPattern : OpConversionPattern<ComplexOp> {
+  using OpConversionPattern<ComplexOp>::OpConversionPattern;
+  using OpAdaptor = typename ComplexOp::Adaptor;
+
+  LogicalResult
+  matchAndRewrite(ComplexOp 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});
+
+    Value half = createFPConstant(rewriter, loc, re.getType(), 0.5);
+    Value exp = ExpOp::create(rewriter, loc, im);
+    Value scaledExp = spirv::FMulOp::create(rewriter, loc, half, exp);
+    Value reciprocalExp = spirv::FDivOp::create(rewriter, loc, half, exp);
+    Value sin = SinOp::create(rewriter, loc, re);
+    Value cos = CosOp::create(rewriter, loc, re);
+
+    auto [resultRe, resultIm] =
+        combine(rewriter, loc, scaledExp, reciprocalExp, sin, cos);
+
+    rewriter.replaceOpWithNewOp<spirv::CompositeConstructOp>(
+        op, spirvType, llvm::ArrayRef<Value>{resultRe, resultIm});
+    return success();
+  }
+
+  virtual std::pair<Value, Value> combine(ConversionPatternRewriter &rewriter,
----------------
aobolensk wrote:

That seems better and more concise, applied, thanks

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


More information about the Mlir-commits mailing list