[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