[Mlir-commits] [mlir] ed2fda6 - [mlir][spirv] Convert arith.subui_extended to spirv.ISubBorrow (#197736)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri May 15 05:43:34 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-05-15T14:43:30+02:00
New Revision: ed2fda64ac2246968ab21fdab4d795fe25e276cd
URL: https://github.com/llvm/llvm-project/commit/ed2fda64ac2246968ab21fdab4d795fe25e276cd
DIFF: https://github.com/llvm/llvm-project/commit/ed2fda64ac2246968ab21fdab4d795fe25e276cd.diff
LOG: [mlir][spirv] Convert arith.subui_extended to spirv.ISubBorrow (#197736)
Added:
Modified:
mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
mlir/test/Target/SPIRV/arithmetic-ops.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp b/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
index 1b5a8728dd3f8..63f84bc1ceb60 100644
--- a/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
+++ b/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
@@ -1318,32 +1318,34 @@ class CmpFOpNanNonePattern final : public OpConversionPattern<arith::CmpFOp> {
};
//===----------------------------------------------------------------------===//
-// AddUIExtendedOp
+// AddUIExtendedOp/SubUIExtendedOp
//===----------------------------------------------------------------------===//
-/// Converts arith.addui_extended to spirv.IAddCarry.
-class AddUIExtendedOpPattern final
- : public OpConversionPattern<arith::AddUIExtendedOp> {
+/// Converts arith.addui_extended/arith.subui_extended to spirv.IAddCarry/
+/// spirv.ISubBorrow.
+template <typename ArithExtendedOp, typename SPIRVExtendedOp>
+class BinaryExtendedOpPattern final
+ : public OpConversionPattern<ArithExtendedOp> {
public:
- using Base::Base;
+ using OpConversionPattern<ArithExtendedOp>::OpConversionPattern;
LogicalResult
- matchAndRewrite(arith::AddUIExtendedOp op, OpAdaptor adaptor,
+ matchAndRewrite(ArithExtendedOp op, typename ArithExtendedOp::Adaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
Type dstElemTy = adaptor.getLhs().getType();
Location loc = op->getLoc();
- Value result = spirv::IAddCarryOp::create(rewriter, loc, adaptor.getLhs(),
- adaptor.getRhs());
+ Value result = SPIRVExtendedOp::create(rewriter, loc, adaptor.getLhs(),
+ adaptor.getRhs());
- Value sumResult = spirv::CompositeExtractOp::create(rewriter, loc, result,
- llvm::ArrayRef(0));
- Value carryValue = spirv::CompositeExtractOp::create(rewriter, loc, result,
- llvm::ArrayRef(1));
+ Value valueResult = spirv::CompositeExtractOp::create(rewriter, loc, result,
+ llvm::ArrayRef(0));
+ Value flagValue = spirv::CompositeExtractOp::create(rewriter, loc, result,
+ llvm::ArrayRef(1));
- // Convert the carry value to boolean.
+ // Convert the carry/borrow value to boolean.
Value one = spirv::ConstantOp::getOne(dstElemTy, loc, rewriter);
- Value carryResult = spirv::IEqualOp::create(rewriter, loc, carryValue, one);
+ Value flagResult = spirv::IEqualOp::create(rewriter, loc, flagValue, one);
- rewriter.replaceOp(op, {sumResult, carryResult});
+ rewriter.replaceOp(op, {valueResult, flagResult});
return success();
}
};
@@ -1552,7 +1554,8 @@ void mlir::arith::populateArithToSPIRVPatterns(
TypeCastingOpPattern<arith::BitcastOp, spirv::BitcastOp>,
CmpIOpBooleanPattern, CmpIOpPattern,
CmpFOpNanNonePattern, CmpFOpPattern,
- AddUIExtendedOpPattern,
+ BinaryExtendedOpPattern<arith::AddUIExtendedOp, spirv::IAddCarryOp>,
+ BinaryExtendedOpPattern<arith::SubUIExtendedOp, spirv::ISubBorrowOp>,
MulIExtendedOpPattern<arith::MulSIExtendedOp, spirv::SMulExtendedOp>,
MulIExtendedOpPattern<arith::MulUIExtendedOp, spirv::UMulExtendedOp>,
SelectOpPattern,
diff --git a/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir b/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
index 31b70177a0d19..b6a488f0dad73 100644
--- a/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
+++ b/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
@@ -99,6 +99,33 @@ func.func @int32_vector_addui_extended(%lhs: vector<4xi32>, %rhs: vector<4xi32>)
return %sum, %overflow : vector<4xi32>, vector<4xi1>
}
+// Check integer subtract-with-borrow conversions.
+// CHECK-LABEL: @int32_scalar_subui_extended
+// CHECK-SAME: (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32)
+func.func @int32_scalar_subui_extended(%lhs: i32, %rhs: i32) -> (i32, i1) {
+ // CHECK-NEXT: %[[ISB:.+]] = spirv.ISubBorrow %[[LHS]], %[[RHS]] : !spirv.struct<(i32, i32)>
+ // CHECK-DAG: %[[DIFF:.+]] = spirv.CompositeExtract %[[ISB]][0 : i32] : !spirv.struct<(i32, i32)>
+ // CHECK-DAG: %[[B0:.+]] = spirv.CompositeExtract %[[ISB]][1 : i32] : !spirv.struct<(i32, i32)>
+ // CHECK-DAG: %[[ONE:.+]] = spirv.Constant 1 : i32
+ // CHECK-NEXT: %[[B1:.+]] = spirv.IEqual %[[B0]], %[[ONE]] : i32
+ // CHECK-NEXT: return %[[DIFF]], %[[B1]] : i32, i1
+ %
diff , %borrow = arith.subui_extended %lhs, %rhs: i32, i1
+ return %
diff , %borrow : i32, i1
+}
+
+// CHECK-LABEL: @int32_vector_subui_extended
+// CHECK-SAME: (%[[LHS:.+]]: vector<4xi32>, %[[RHS:.+]]: vector<4xi32>)
+func.func @int32_vector_subui_extended(%lhs: vector<4xi32>, %rhs: vector<4xi32>) -> (vector<4xi32>, vector<4xi1>) {
+ // CHECK-NEXT: %[[ISB:.+]] = spirv.ISubBorrow %[[LHS]], %[[RHS]] : !spirv.struct<(vector<4xi32>, vector<4xi32>)>
+ // CHECK-DAG: %[[DIFF:.+]] = spirv.CompositeExtract %[[ISB]][0 : i32] : !spirv.struct<(vector<4xi32>, vector<4xi32>)>
+ // CHECK-DAG: %[[B0:.+]] = spirv.CompositeExtract %[[ISB]][1 : i32] : !spirv.struct<(vector<4xi32>, vector<4xi32>)>
+ // CHECK-DAG: %[[ONE:.+]] = spirv.Constant dense<1> : vector<4xi32>
+ // CHECK-NEXT: %[[B1:.+]] = spirv.IEqual %[[B0]], %[[ONE]] : vector<4xi32>
+ // CHECK-NEXT: return %[[DIFF]], %[[B1]] : vector<4xi32>, vector<4xi1>
+ %
diff , %borrow = arith.subui_extended %lhs, %rhs: vector<4xi32>, vector<4xi1>
+ return %
diff , %borrow : vector<4xi32>, vector<4xi1>
+}
+
// Check extended signed integer multiplication conversions.
// CHECK-LABEL: @int32_scalar_mulsi_extended
// CHECK-SAME: (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32)
diff --git a/mlir/test/Target/SPIRV/arithmetic-ops.mlir b/mlir/test/Target/SPIRV/arithmetic-ops.mlir
index ec47035d088b7..3b4c48f8b7b98 100644
--- a/mlir/test/Target/SPIRV/arithmetic-ops.mlir
+++ b/mlir/test/Target/SPIRV/arithmetic-ops.mlir
@@ -56,6 +56,16 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, Linkage, BFloat1
%0 = spirv.IMul %arg0, %arg1 : vector<4xi32>
spirv.Return
}
+ spirv.func @isub_borrow(%arg0 : i32, %arg1 : i32) "None" {
+ // CHECK: {{%.*}} = spirv.ISubBorrow {{%.*}}, {{%.*}} : !spirv.struct<(i32, i32)>
+ %0 = spirv.ISubBorrow %arg0, %arg1 : !spirv.struct<(i32, i32)>
+ spirv.Return
+ }
+ spirv.func @isub_borrow_vector(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) "None" {
+ // CHECK: {{%.*}} = spirv.ISubBorrow {{%.*}}, {{%.*}} : !spirv.struct<(vector<4xi32>, vector<4xi32>)>
+ %0 = spirv.ISubBorrow %arg0, %arg1 : !spirv.struct<(vector<4xi32>, vector<4xi32>)>
+ spirv.Return
+ }
spirv.func @udiv(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) "None" {
// CHECK: {{%.*}} = spirv.UDiv {{%.*}}, {{%.*}} : vector<4xi32>
%0 = spirv.UDiv %arg0, %arg1 : vector<4xi32>
More information about the Mlir-commits
mailing list