[Mlir-commits] [mlir] ee1fe94 - [mlir][arith] Use subui_extended in wide integer emulation of subi (#197762)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Jun 4 00:06:06 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-06-04T09:06:00+02:00
New Revision: ee1fe9431baedb216674a1452eb39aca9d3a78d9
URL: https://github.com/llvm/llvm-project/commit/ee1fe9431baedb216674a1452eb39aca9d3a78d9
DIFF: https://github.com/llvm/llvm-project/commit/ee1fe9431baedb216674a1452eb39aca9d3a78d9.diff
LOG: [mlir][arith] Use subui_extended in wide integer emulation of subi (#197762)
Added:
Modified:
mlir/lib/Dialect/Arith/Transforms/EmulateWideInt.cpp
mlir/test/Dialect/Arith/emulate-wide-int.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/Arith/Transforms/EmulateWideInt.cpp b/mlir/lib/Dialect/Arith/Transforms/EmulateWideInt.cpp
index 36765d7b27418..ec1e1851d8a84 100644
--- a/mlir/lib/Dialect/Arith/Transforms/EmulateWideInt.cpp
+++ b/mlir/lib/Dialect/Arith/Transforms/EmulateWideInt.cpp
@@ -890,18 +890,18 @@ struct ConvertSubI final : OpConversionPattern<arith::SubIOp> {
auto [rhsElem0, rhsElem1] =
extractLastDimHalves(rewriter, loc, adaptor.getRhs());
- // Emulates LHS - RHS by [LHS0 - RHS0, LHS1 - RHS1 - CARRY] where
- // CARRY is 1 or 0.
- Value low = arith::SubIOp::create(rewriter, loc, lhsElem0, rhsElem0);
- // We have a carry if lhsElem0 < rhsElem0.
- Value carry0 = arith::CmpIOp::create(
- rewriter, loc, arith::CmpIPredicate::ult, lhsElem0, rhsElem0);
- Value carryVal = arith::ExtUIOp::create(rewriter, loc, newElemTy, carry0);
-
- Value high0 = arith::SubIOp::create(rewriter, loc, lhsElem1, carryVal);
+ // Emulates LHS - RHS by [LHS0 - RHS0, LHS1 - RHS1 - BORROW] where
+ // BORROW is 1 or 0.
+ auto lowDiff =
+ arith::SubUIExtendedOp::create(rewriter, loc, lhsElem0, rhsElem0);
+ Value borrowVal =
+ arith::ExtUIOp::create(rewriter, loc, newElemTy, lowDiff.getBorrow());
+
+ Value high0 = arith::SubIOp::create(rewriter, loc, lhsElem1, borrowVal);
Value high = arith::SubIOp::create(rewriter, loc, high0, rhsElem1);
- Value resultVec = constructResultVector(rewriter, loc, newTy, {low, high});
+ Value resultVec =
+ constructResultVector(rewriter, loc, newTy, {lowDiff.getDiff(), high});
rewriter.replaceOp(op, resultVec);
return success();
}
diff --git a/mlir/test/Dialect/Arith/emulate-wide-int.mlir b/mlir/test/Dialect/Arith/emulate-wide-int.mlir
index 936050cddb676..695d8fd453fd7 100644
--- a/mlir/test/Dialect/Arith/emulate-wide-int.mlir
+++ b/mlir/test/Dialect/Arith/emulate-wide-int.mlir
@@ -136,10 +136,9 @@ func.func @addi_vector_a_b(%a : vector<4xi64>, %b : vector<4xi64>) -> vector<4xi
// CHECK-NEXT: [[HIGH0:%.+]] = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
// CHECK-NEXT: [[LOW1:%.+]] = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
// CHECK-NEXT: [[HIGH1:%.+]] = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
-// CHECK-NEXT: [[SUB_L:%.+]] = arith.subi [[LOW0]], [[LOW1]] : i32
-// CHECK-NEXT: [[ULT:%.+]] = arith.cmpi ult, [[LOW0]], [[LOW1]] : i32
-// CHECK-NEXT: [[CARRY:%.+]] = arith.extui [[ULT]] : i1 to i32
-// CHECK-NEXT: [[SUB_H0:%.+]] = arith.subi [[HIGH0]], [[CARRY]] : i32
+// CHECK-NEXT: [[SUB_L:%.+]], [[BB:%.+]] = arith.subui_extended [[LOW0]], [[LOW1]] : i32, i1
+// CHECK-NEXT: [[BORROW:%.+]] = arith.extui [[BB]] : i1 to i32
+// CHECK-NEXT: [[SUB_H0:%.+]] = arith.subi [[HIGH0]], [[BORROW]] : i32
// CHECK-NEXT: [[SUB_H1:%.+]] = arith.subi [[SUB_H0]], [[HIGH1]] : i32
// CHECK: [[INS0:%.+]] = vector.insert [[SUB_L]], {{%.+}} [0] : i32 into vector<2xi32>
// CHECK-NEXT: [[INS1:%.+]] = vector.insert [[SUB_H1]], [[INS0]] [1] : i32 into vector<2xi32>
@@ -155,10 +154,9 @@ func.func @subi_scalar(%a : i64, %b : i64) -> i64 {
// CHECK-NEXT: [[HIGH0:%.+]] = vector.extract_strided_slice [[ARG0]] {offsets = [0, 1], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
// CHECK-NEXT: [[LOW1:%.+]] = vector.extract_strided_slice [[ARG1]] {offsets = [0, 0], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
// CHECK-NEXT: [[HIGH1:%.+]] = vector.extract_strided_slice [[ARG1]] {offsets = [0, 1], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
-// CHECK-NEXT: [[SUB_L:%.+]] = arith.subi [[LOW0]], [[LOW1]] : vector<4x1xi32>
-// CHECK-NEXT: [[ULT:%.+]] = arith.cmpi ult, [[LOW0]], [[LOW1]] : vector<4x1xi32>
-// CHECK-NEXT: [[CARRY:%.+]] = arith.extui [[ULT]] : vector<4x1xi1> to vector<4x1xi32>
-// CHECK-NEXT: [[SUB_H0:%.+]] = arith.subi [[HIGH0]], [[CARRY]] : vector<4x1xi32>
+// CHECK-NEXT: [[SUB_L:%.+]], [[BB:%.+]] = arith.subui_extended [[LOW0]], [[LOW1]] : vector<4x1xi32>, vector<4x1xi1>
+// CHECK-NEXT: [[BORROW:%.+]] = arith.extui [[BB]] : vector<4x1xi1> to vector<4x1xi32>
+// CHECK-NEXT: [[SUB_H0:%.+]] = arith.subi [[HIGH0]], [[BORROW]] : vector<4x1xi32>
// CHECK-NEXT: [[SUB_H1:%.+]] = arith.subi [[SUB_H0]], [[HIGH1]] : vector<4x1xi32>
// CHECK: [[INS0:%.+]] = vector.insert_strided_slice [[SUB_L]], {{%.+}} {offsets = [0, 0], strides = [1, 1]} : vector<4x1xi32> into vector<4x2xi32>
// CHECK-NEXT: [[INS1:%.+]] = vector.insert_strided_slice [[SUB_H1]], [[INS0]] {offsets = [0, 1], strides = [1, 1]} : vector<4x1xi32> into vector<4x2xi32>
@@ -1009,7 +1007,7 @@ func.func @uitofp_i64_f16(%a : i64) -> f16 {
// CHECK: vector.extract [[VZERO]][0] : i32 from vector<2xi32>
// CHECK: [[ZERO1:%.+]] = vector.extract [[VZERO]][0] : i32 from vector<2xi32>
// CHECK-NEXT: [[ZERO2:%.+]] = vector.extract [[VZERO]][1] : i32 from vector<2xi32>
-// CHECK: arith.subi [[ZERO1]], {{%.+}} : i32
+// CHECK: arith.subui_extended [[ZERO1]], {{%.+}} : i32, i1
// CHECK: arith.subi [[ZERO2]], {{%.+}} : i32
// CHECK: [[CST0:%.+]] = arith.constant 0 : i32
// CHECK: [[HIEQ0:%.+]] = arith.cmpi eq, [[HI:%.+]], [[CST0]] : i32
@@ -1030,7 +1028,7 @@ func.func @sitofp_i64_f64(%a : i64) -> f64 {
// CHECK-LABEL: func @sitofp_i64_f64_vector
// CHECK-SAME: ([[ARG:%.+]]: vector<3x2xi32>) -> vector<3xf64>
// CHECK: [[VZERO:%.+]] = arith.constant dense<0> : vector<3x2xi32>
-// CHECK: arith.subi
+// CHECK: arith.subui_extended
// CHECK: arith.subi
// CHECK: [[HIEQ0:%.+]] = arith.cmpi eq, [[HI:%.+]], [[CST0:%.+]] : vector<3xi32>
// CHECK-NEXT: [[LOWFP:%.+]] = arith.uitofp [[LOW:%.+]] : vector<3xi32> to vector<3xf64>
@@ -1096,8 +1094,7 @@ func.func @fptoui_i64_f64_vector(%a : vector<3xf64>) -> vector<3xi64> {
// CHECK: vector.insert [[LOWHALF]], %{{.+}} [0] : i32 into vector<2xi32>
// CHECK-NEXT: [[FPTOUIRESVEC:%.+]] = vector.insert [[HIGHHALF]]
// CHECK: [[ZEROCSTINTHALF:%.+]] = vector.extract [[ZEROCSTINT]][0] : i32 from vector<2xi32>
-// CHECK: [[SUB:%.+]] = arith.subi [[ZEROCSTINTHALF]], %{{.+}} : i32
-// CHECK-NEXT: arith.cmpi ult, [[ZEROCSTINTHALF]], %{{.+}} : i32
+// CHECK: [[SUB:%.+]], %{{.+}} = arith.subui_extended [[ZEROCSTINTHALF]], %{{.+}} : i32, i1
// CHECK-NEXT: arith.extui
// CHECK-NEXT: arith.subi
// CHECK-NEXT: arith.subi
@@ -1134,8 +1131,7 @@ func.func @fptosi_i64_f64(%a : f64) -> i64 {
// CHECK-NEXT: [[FPTOUIRESVEC:%.+]] = vector.insert_strided_slice [[HIGHHALFX1]]
// CHECK: [[ZEROCSTINTHALF:%.+]] = vector.extract_strided_slice [[ZEROCSTINT]]
// CHECK-SAME: {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
-// CHECK: [[SUB:%.+]] = arith.subi [[ZEROCSTINTHALF]], %{{.+}} : vector<3x1xi32>
-// CHECK-NEXT: arith.cmpi ult, [[ZEROCSTINTHALF]], %{{.+}} : vector<3x1xi32>
+// CHECK: [[SUB:%.+]], %{{.+}} = arith.subui_extended [[ZEROCSTINTHALF]], %{{.+}} : vector<3x1xi32>, vector<3x1xi1>
// CHECK-NEXT: arith.extui
// CHECK-NEXT: arith.subi
// CHECK-NEXT: arith.subi
More information about the Mlir-commits
mailing list