[Mlir-commits] [mlir] 334eb77 - [mlir][SPIR-V] Add SPIRVToLLVM conversions for GL.FMix and CL.mix (#206935)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Jul 6 02:40:48 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-07-06T11:40:44+02:00
New Revision: 334eb772a25d700feb1f6c64b872cc693731b0b3
URL: https://github.com/llvm/llvm-project/commit/334eb772a25d700feb1f6c64b872cc693731b0b3
DIFF: https://github.com/llvm/llvm-project/commit/334eb772a25d700feb1f6c64b872cc693731b0b3.diff
LOG: [mlir][SPIR-V] Add SPIRVToLLVM conversions for GL.FMix and CL.mix (#206935)
Added:
Modified:
mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
index 1cd3d79c13e20..d1c8822bf0f05 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
@@ -1584,6 +1584,55 @@ class FractPattern : public SPIRVToLLVMConversion<spirv::GLFractOp> {
}
};
+/// Converts `spirv.GL.FMix` to `x * (1 - a) + y * a` as specified by
+/// GL.std.450.
+class GLFMixPattern : public SPIRVToLLVMConversion<spirv::GLFMixOp> {
+public:
+ using SPIRVToLLVMConversion<spirv::GLFMixOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(spirv::GLFMixOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Type dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return rewriter.notifyMatchFailure(op, "type conversion failed");
+
+ Location loc = op.getLoc();
+ Value x = adaptor.getX();
+ Value y = adaptor.getY();
+ Value a = adaptor.getA();
+ Value one = createFPConstant(loc, op.getType(), dstType, rewriter, 1.0);
+ Value oneMinusA = LLVM::FSubOp::create(rewriter, loc, dstType, one, a);
+ Value lhs = LLVM::FMulOp::create(rewriter, loc, dstType, x, oneMinusA);
+ Value rhs = LLVM::FMulOp::create(rewriter, loc, dstType, y, a);
+ rewriter.replaceOpWithNewOp<LLVM::FAddOp>(op, dstType, lhs, rhs);
+ return success();
+ }
+};
+
+/// Converts `spirv.CL.mix` to `fma(a, y - x, x)`. The OpenCL spec defines
+/// mix as `x + (y - x) * a` and explicitly permits FMA contractions.
+class CLMixPattern : public SPIRVToLLVMConversion<spirv::CLMixOp> {
+public:
+ using SPIRVToLLVMConversion<spirv::CLMixOp>::SPIRVToLLVMConversion;
+
+ LogicalResult
+ matchAndRewrite(spirv::CLMixOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Type dstType = getTypeConverter()->convertType(op.getType());
+ if (!dstType)
+ return rewriter.notifyMatchFailure(op, "type conversion failed");
+
+ Location loc = op.getLoc();
+ Value x = adaptor.getX();
+ Value y = adaptor.getY();
+ Value a = adaptor.getZ();
+ Value
diff = LLVM::FSubOp::create(rewriter, loc, dstType, y, x);
+ rewriter.replaceOpWithNewOp<LLVM::FMAOp>(op, dstType, a,
diff , x);
+ return success();
+ }
+};
+
// Converts spirv.GL.Radians (scale = pi/180) and spirv.GL.Degrees
// (scale = 180/pi) by multiplying the operand by a compile-time constant.
template <typename SPIRVOp>
@@ -1966,6 +2015,7 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
DirectConversionPattern<spirv::GLAcosOp, LLVM::ACosOp>,
DirectConversionPattern<spirv::GLAtanOp, LLVM::ATanOp>,
InverseSqrtPattern, SAbsPattern, TanPattern, TanhPattern, FractPattern,
+ GLFMixPattern,
// OpenCL extended instruction set ops
DirectConversionPattern<spirv::CLCeilOp, LLVM::FCeilOp>,
@@ -1998,7 +2048,7 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
DirectConversionPattern<spirv::CLSMaxOp, LLVM::SMaxOp>,
DirectConversionPattern<spirv::CLSMinOp, LLVM::SMinOp>,
DirectConversionPattern<spirv::CLUMaxOp, LLVM::UMaxOp>,
- DirectConversionPattern<spirv::CLUMinOp, LLVM::UMinOp>,
+ DirectConversionPattern<spirv::CLUMinOp, LLVM::UMinOp>, CLMixPattern,
// Logical ops
DirectConversionPattern<spirv::LogicalAndOp, LLVM::AndOp>,
diff --git a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
index f0568e1035cd9..a986be42a5437 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir
@@ -99,3 +99,23 @@ spirv.func @cl_integer(%arg0: i32, %arg1: i32) "None" {
%3 = spirv.CL.u_min %arg0, %arg1 : i32
spirv.Return
}
+
+//===----------------------------------------------------------------------===//
+// spirv.CL.mix
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @mix_scalar
+spirv.func @mix_scalar(%x: f32, %y: f32, %a: f32) "None" {
+ // CHECK: %[[DIFF:.*]] = llvm.fsub %{{.*}}, %{{.*}} : f32
+ // CHECK: llvm.intr.fma(%{{.*}}, %[[DIFF]], %{{.*}}) : (f32, f32, f32) -> f32
+ %0 = spirv.CL.mix %x, %y, %a : f32
+ spirv.Return
+}
+
+// CHECK-LABEL: @mix_vector
+spirv.func @mix_vector(%x: vector<4xf32>, %y: vector<4xf32>, %a: vector<4xf32>) "None" {
+ // CHECK: %[[DIFF:.*]] = llvm.fsub %{{.*}}, %{{.*}} : vector<4xf32>
+ // CHECK: llvm.intr.fma(%{{.*}}, %[[DIFF]], %{{.*}}) : (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32>
+ %0 = spirv.CL.mix %x, %y, %a : vector<4xf32>
+ spirv.Return
+}
diff --git a/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir
index 24f16602e4147..caecf1f9f8d32 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir
@@ -406,3 +406,29 @@ spirv.func @fract(%arg0: f32, %arg1: vector<3xf16>) "None" {
%1 = spirv.GL.Fract %arg1 : vector<3xf16>
spirv.Return
}
+
+//===----------------------------------------------------------------------===//
+// spirv.GL.FMix
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @fmix_scalar
+spirv.func @fmix_scalar(%x: f32, %y: f32, %a: f32) "None" {
+ // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
+ // CHECK: %[[ONE_MINUS_A:.*]] = llvm.fsub %[[ONE]], %{{.*}} : f32
+ // CHECK: %[[LHS:.*]] = llvm.fmul %{{.*}}, %[[ONE_MINUS_A]] : f32
+ // CHECK: %[[RHS:.*]] = llvm.fmul %{{.*}}, %{{.*}} : f32
+ // CHECK: llvm.fadd %[[LHS]], %[[RHS]] : f32
+ %0 = spirv.GL.FMix %x : f32, %y : f32, %a : f32 -> f32
+ spirv.Return
+}
+
+// CHECK-LABEL: @fmix_vector
+spirv.func @fmix_vector(%x: vector<4xf32>, %y: vector<4xf32>, %a: vector<4xf32>) "None" {
+ // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<4xf32>) : vector<4xf32>
+ // CHECK: %[[ONE_MINUS_A:.*]] = llvm.fsub %[[ONE]], %{{.*}} : vector<4xf32>
+ // CHECK: %[[LHS:.*]] = llvm.fmul %{{.*}}, %[[ONE_MINUS_A]] : vector<4xf32>
+ // CHECK: %[[RHS:.*]] = llvm.fmul %{{.*}}, %{{.*}} : vector<4xf32>
+ // CHECK: llvm.fadd %[[LHS]], %[[RHS]] : vector<4xf32>
+ %0 = spirv.GL.FMix %x : vector<4xf32>, %y : vector<4xf32>, %a : vector<4xf32> -> vector<4xf32>
+ spirv.Return
+}
More information about the Mlir-commits
mailing list