[llvm] [GlobalISel] Add integer combines from SelectionDAG (PR #181126)

Osman Yasar via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 12 04:06:33 PST 2026


https://github.com/osmanyasar05 created https://github.com/llvm/llvm-project/pull/181126

This PR adds the patterns` // fold (A - (0 - B)) to (A + B)` and `// fold A - (A - B) -> B` from SelectionDAG: https://github.com/llvm/llvm-project/blob/838be78e44cd1f70006eb508bfc925e3e56aac03/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp#L4312

These rewrites should not need HasOneUse checks, since even with multiple uses, they cannot increase the instruction count.

>From 33d270951fd06391042733d0d892b793bb4074df Mon Sep 17 00:00:00 2001
From: osmanyasar05 <osmanyas05 at gmail.com>
Date: Wed, 11 Feb 2026 21:24:07 +0000
Subject: [PATCH 1/3] first commit

---
 .../AArch64/GlobalISel/combine-integer.mir    | 85 +++++++++++++++++++
 llvm/test/CodeGen/RISCV/GlobalISel/test.mir   | 22 +++++
 2 files changed, 107 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/test.mir

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index c9b24ad75ce27..dba3b46991887 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -413,3 +413,88 @@ body:             |
     $x0 = COPY %add
     RET_ReallyLR implicit $x0
 
+...
+---
+name:   AMinusZeroMinusBTestLine10
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: AMinusZeroMinusBTestLine10
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %b:_(s64) = COPY $x1
+    ; CHECK-NEXT: %add:_(s64) = G_SUB %a, %b
+    ; CHECK-NEXT: $x0 = COPY %add(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %b:_(s64) = COPY $x1
+    %c1:_(s64) = G_CONSTANT i64 0
+    %sub:_(s64) = G_SUB %c1, %b
+    %add:_(s64) = G_ADD %a, %sub
+    $x0 = COPY %add
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   APlusBMinusBTestLine11
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: APlusBMinusBTestLine11
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %b:_(s64) = COPY $x1
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB %a, %b
+    ; CHECK-NEXT: %add:_(s64) = G_SUB %a, %sub
+    ; CHECK-NEXT: $x0 = COPY %add(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %b:_(s64) = COPY $x1
+    %sub:_(s64) = G_SUB %a, %b
+    %add:_(s64) = G_SUB %a, %sub
+    $x0 = COPY %add
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   APlusBMinusALine12
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: APlusBMinusALine12
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %b:_(s64) = COPY $x1
+    ; CHECK-NEXT: $x0 = COPY %b(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %b:_(s64) = COPY $x1
+    %add:_(s64) = G_ADD %a, %b
+    %sub:_(s64) = G_SUB %add, %a
+    $x0 = COPY %sub
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   APlusBMinusALine13
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: APlusBMinusALine12
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %b:_(s64) = COPY $x1
+    ; CHECK-NEXT: $x0 = COPY %b(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %b:_(s64) = COPY $x1
+    %add:_(s64) = G_ADD %a, %b
+    %sub:_(s64) = G_SUB %add, %a
+    $x0 = COPY %sub
+    RET_ReallyLR implicit $x0
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/test.mir b/llvm/test/CodeGen/RISCV/GlobalISel/test.mir
new file mode 100644
index 0000000000000..27be0942b5aae
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/test.mir
@@ -0,0 +1,22 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -run-pass=riscv-prelegalizer-combiner -mtriple riscv64 %s -o - | FileCheck %s --check-prefix=RV64
+
+---
+name:            nneg_zext
+body:             |
+  bb.0:
+
+    ; RV64-LABEL: name: nneg_zext
+    ; RV64: [[COPY:%[0-9]+]]:_(s64) = COPY $x11
+    ; RV64-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x12
+    ; RV64-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[COPY1]], [[COPY]]
+    ; RV64-NEXT: $x10 = COPY [[SUB]](s64)
+    ; RV64-NEXT: PseudoRET implicit $x10
+    %0:_(s64) = COPY $x10
+    %1:_(s64) = COPY $x11
+    %2:_(s64) = COPY $x12
+    %3:_(s64) = G_SUB %0, %1
+    %4:_(s64) = G_SUB %2, %0
+    %5:_(s64) = G_ADD %3, %4
+    $x10 = COPY %5(s64)
+    PseudoRET implicit $x10

>From 8a4ba932d9a4eeb442dd6793d945d757ed27cbee Mon Sep 17 00:00:00 2001
From: osmanyasar05 <osmanyas05 at gmail.com>
Date: Thu, 12 Feb 2026 11:53:01 +0000
Subject: [PATCH 2/3] add irc rewrites

---
 .../include/llvm/Target/GlobalISel/Combine.td | 16 +++++
 .../AArch64/GlobalISel/combine-integer.mir    | 64 ++++---------------
 2 files changed, 27 insertions(+), 53 deletions(-)

diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index f5c940bffc8fb..a90790afa8dfb 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1946,6 +1946,20 @@ def APlusBMinusCPlusA : GICombineRule<
           (G_SUB $sub1, $B, $add1),
           (G_ADD $root, $A, $sub1)),
    (apply (G_SUB $root, $B, $C))>;
+  
+// fold (A - (0 - B)) to (A + B)
+def AMinusZeroMinusB : GICombineRule<
+   (defs root:$root),
+   (match (G_SUB $sub1, 0, $B),
+          (G_SUB $root, $A, $sub1)),
+   (apply (G_ADD $root, $A, $B))>;
+
+// fold A - (A - B) -> B
+def AMinusBMinusA: GICombineRule<
+   (defs root:$root),
+   (match (G_SUB $add, $A, $B),
+          (G_SUB $root, $A, $add)),
+   (apply (GIReplaceReg $root, $B))>;
 
 // fold (A+C1)-C2 -> A+(C1-C2)
 def APlusC1MinusC2: GICombineRule<
@@ -2008,6 +2022,8 @@ def integer_reassoc_combines: GICombineGroup<[
   AMinusBPlusBMinusC,
   APlusBMinusAplusC,
   APlusBMinusCPlusA,
+  AMinusZeroMinusB,
+  AMinusBMinusA,
   APlusC1MinusC2,
   C2MinusAPlusC1,
   AMinusC1MinusC2,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index dba3b46991887..0f7efc9df34bb 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -415,42 +415,40 @@ body:             |
 
 ...
 ---
-name:   AMinusZeroMinusBTestLine10
+name:   AMinusZeroMinusB
 body:             |
   bb.0:
     liveins: $w0, $w1
 
-    ; CHECK-LABEL: name: AMinusZeroMinusBTestLine10
+
+    ; CHECK-LABEL: name: AMinusZeroMinusB
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
-    ; CHECK-NEXT: %add:_(s64) = G_SUB %a, %b
-    ; CHECK-NEXT: $x0 = COPY %add(s64)
+    ; CHECK-NEXT: %sub2:_(s64) = G_ADD %a, %b
+    ; CHECK-NEXT: $x0 = COPY %sub2(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
     %b:_(s64) = COPY $x1
     %c1:_(s64) = G_CONSTANT i64 0
-    %sub:_(s64) = G_SUB %c1, %b
-    %add:_(s64) = G_ADD %a, %sub
-    $x0 = COPY %add
+    %sub1:_(s64) = G_SUB %c1, %b
+    %sub2:_(s64) = G_SUB %a, %sub1
+    $x0 = COPY %sub2
     RET_ReallyLR implicit $x0
 
 ...
 ---
-name:   APlusBMinusBTestLine11
+name:   AMinusBMinusA
 body:             |
   bb.0:
     liveins: $w0, $w1
 
-    ; CHECK-LABEL: name: APlusBMinusBTestLine11
+    ; CHECK-LABEL: name: AMinusBMinusA
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
-    ; CHECK-NEXT: %sub:_(s64) = G_SUB %a, %b
-    ; CHECK-NEXT: %add:_(s64) = G_SUB %a, %sub
-    ; CHECK-NEXT: $x0 = COPY %add(s64)
+    ; CHECK-NEXT: $x0 = COPY %b(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
     %b:_(s64) = COPY $x1
@@ -458,43 +456,3 @@ body:             |
     %add:_(s64) = G_SUB %a, %sub
     $x0 = COPY %add
     RET_ReallyLR implicit $x0
-
-...
----
-name:   APlusBMinusALine12
-body:             |
-  bb.0:
-    liveins: $w0, $w1
-
-    ; CHECK-LABEL: name: APlusBMinusALine12
-    ; CHECK: liveins: $w0, $w1
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %b:_(s64) = COPY $x1
-    ; CHECK-NEXT: $x0 = COPY %b(s64)
-    ; CHECK-NEXT: RET_ReallyLR implicit $x0
-    %a:_(s64) = COPY $x0
-    %b:_(s64) = COPY $x1
-    %add:_(s64) = G_ADD %a, %b
-    %sub:_(s64) = G_SUB %add, %a
-    $x0 = COPY %sub
-    RET_ReallyLR implicit $x0
-
-...
----
-name:   APlusBMinusALine13
-body:             |
-  bb.0:
-    liveins: $w0, $w1
-
-    ; CHECK-LABEL: name: APlusBMinusALine12
-    ; CHECK: liveins: $w0, $w1
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %b:_(s64) = COPY $x1
-    ; CHECK-NEXT: $x0 = COPY %b(s64)
-    ; CHECK-NEXT: RET_ReallyLR implicit $x0
-    %a:_(s64) = COPY $x0
-    %b:_(s64) = COPY $x1
-    %add:_(s64) = G_ADD %a, %b
-    %sub:_(s64) = G_SUB %add, %a
-    $x0 = COPY %sub
-    RET_ReallyLR implicit $x0

>From f06c5a99ddbc140d04e104f4797332cbaf39074a Mon Sep 17 00:00:00 2001
From: osmanyasar05 <osmanyas05 at gmail.com>
Date: Thu, 12 Feb 2026 12:04:51 +0000
Subject: [PATCH 3/3] modify tests

---
 llvm/test/CodeGen/RISCV/GlobalISel/test.mir | 22 ---------------------
 1 file changed, 22 deletions(-)
 delete mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/test.mir

diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/test.mir b/llvm/test/CodeGen/RISCV/GlobalISel/test.mir
deleted file mode 100644
index 27be0942b5aae..0000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/test.mir
+++ /dev/null
@@ -1,22 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -run-pass=riscv-prelegalizer-combiner -mtriple riscv64 %s -o - | FileCheck %s --check-prefix=RV64
-
----
-name:            nneg_zext
-body:             |
-  bb.0:
-
-    ; RV64-LABEL: name: nneg_zext
-    ; RV64: [[COPY:%[0-9]+]]:_(s64) = COPY $x11
-    ; RV64-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x12
-    ; RV64-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[COPY1]], [[COPY]]
-    ; RV64-NEXT: $x10 = COPY [[SUB]](s64)
-    ; RV64-NEXT: PseudoRET implicit $x10
-    %0:_(s64) = COPY $x10
-    %1:_(s64) = COPY $x11
-    %2:_(s64) = COPY $x12
-    %3:_(s64) = G_SUB %0, %1
-    %4:_(s64) = G_SUB %2, %0
-    %5:_(s64) = G_ADD %3, %4
-    $x10 = COPY %5(s64)
-    PseudoRET implicit $x10



More information about the llvm-commits mailing list