[llvm] [GIsel] import min/max rewrites (PR #188267)

Luisa Cicolini via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 10 03:53:14 PDT 2026


https://github.com/luisacicolini updated https://github.com/llvm/llvm-project/pull/188267

>From 5209235f7b8721011452de4348e361b7e78903b5 Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Tue, 24 Mar 2026 15:16:34 +0000
Subject: [PATCH 1/9] chore: smax

---
 .../include/llvm/Target/GlobalISel/Combine.td | 14 ++++-
 .../AArch64/GlobalISel/combine-integer.mir    | 56 +++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 959cd8b083d52..4c1879e82c9cf 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -2044,6 +2044,17 @@ def AMinusC1PlusC2: GICombineRule<
    [{ return Helper.matchFoldAMinusC1PlusC2(*${root}, ${matchinfo}); }]),
    (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
 
+// (sub 0, (max X, (sub 0, X))) --> (min X, (sub 0, X))
+def SubSmaxSub: GICombineRule<
+   (defs root:$root),
+   (match (G_SUB $sub, 0, $A),
+          (G_SMAX $max, $A, $sub),
+          (G_SUB $root, 0, $max):$root, 
+          [{ return MRI.hasOneNonDBGUse(${sub}.getReg()) 
+              && MRI.hasOneNonDBGUse(${max}.getReg()); }]),
+   (apply (G_SUB $sub1, 0, $A), 
+          (G_SMIN $root, $A, $sub1))>;
+   
 def integer_reassoc_combines: GICombineGroup<[
   APlusBMinusCMinusB,
   AMinusBMinusCMinusC,
@@ -2061,7 +2072,8 @@ def integer_reassoc_combines: GICombineGroup<[
   C2MinusAPlusC1,
   AMinusC1MinusC2,
   C1Minus2MinusC2,
-  AMinusC1PlusC2
+  AMinusC1PlusC2,
+  SubSmaxSub
 ]>;
 
 // fold (A+(shl (0-B), C)) -> (A-(shl B, C))
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index 1100997321a09..8afdb96a0c97a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -7,6 +7,7 @@ name:   APlusBMinusCMinusB
 body:             |
   bb.0:
     liveins: $x0, $x1, $x2
+
     ; CHECK-LABEL: name: APlusBMinusCMinusB
     ; CHECK: liveins: $x0, $x1, $x2
     ; CHECK-NEXT: {{  $}}
@@ -496,3 +497,58 @@ body:             |
     $x0 = COPY %sub2
     RET_ReallyLR implicit $x0
 
+
+...
+---
+name:   ASubMax
+body:             |
+  bb.0:
+    liveins: $x0
+
+
+    ; CHECK-LABEL: name: ASubMax
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %sub2:_(s64) = G_SMIN %a, [[SUB]]
+    ; CHECK-NEXT: $x0 = COPY %sub2(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+
+    %zero:_(s64) = G_CONSTANT i64 0
+    %sub1:_(s64) = G_SUB %zero, %a
+    %max:_(s64) = G_SMAX %a, %sub1
+    %sub2:_(s64) = G_SUB %zero, %max
+    $x0 = COPY %sub2
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   ASubMaxOneUse
+body:             |
+  bb.0:
+    liveins: $x0
+
+
+    ; CHECK-LABEL: name: ASubMaxOneUse
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %max:_(s64) = G_SMAX %a, %sub1
+    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %zero, %max
+    ; CHECK-NEXT: %mul:_(s64) = G_MUL %max, %sub2
+    ; CHECK-NEXT: $x0 = COPY %mul(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+
+    %zero:_(s64) = G_CONSTANT i64 0
+    %sub1:_(s64) = G_SUB %zero, %a
+    %max:_(s64) = G_SMAX %a, %sub1
+    %sub2:_(s64) = G_SUB %zero, %max
+    %mul:_(s64) = G_MUL %max, %sub2
+    $x0 = COPY %mul
+    RET_ReallyLR implicit $x0

>From 49a1378906d55b0444a75c811346e1112567b730 Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Tue, 24 Mar 2026 15:31:04 +0000
Subject: [PATCH 2/9] umax conflicts with smax

---
 llvm/include/llvm/Target/GlobalISel/Combine.td     | 14 +++++++++++++-
 .../CodeGen/AArch64/GlobalISel/combine-integer.mir |  1 +
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 4c1879e82c9cf..998828a936ef3 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -2054,6 +2054,17 @@ def SubSmaxSub: GICombineRule<
               && MRI.hasOneNonDBGUse(${max}.getReg()); }]),
    (apply (G_SUB $sub1, 0, $A), 
           (G_SMIN $root, $A, $sub1))>;
+          
+// (sub 0, (max X, (sub 0, X))) --> (min X, (sub 0, X))
+def SubUmaxSub: GICombineRule<
+   (defs root:$root),
+   (match (G_SUB $sub, 0, $A),
+          (G_UMAX $max, $A, $sub),
+          (G_SUB $root, 0, $max):$root, 
+          [{ return MRI.hasOneNonDBGUse(${sub}.getReg()) 
+              && MRI.hasOneNonDBGUse(${max}.getReg()); }]),
+   (apply (G_SUB $sub1, 0, $A), 
+          (G_UMIN $root, $A, $sub1))>;
    
 def integer_reassoc_combines: GICombineGroup<[
   APlusBMinusCMinusB,
@@ -2073,7 +2084,8 @@ def integer_reassoc_combines: GICombineGroup<[
   AMinusC1MinusC2,
   C1Minus2MinusC2,
   AMinusC1PlusC2,
-  SubSmaxSub
+  SubSmaxSub, 
+  SubUmaxSub
 ]>;
 
 // fold (A+(shl (0-B), C)) -> (A-(shl B, C))
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index 8afdb96a0c97a..d74c289aea4c9 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -552,3 +552,4 @@ body:             |
     %mul:_(s64) = G_MUL %max, %sub2
     $x0 = COPY %mul
     RET_ReallyLR implicit $x0
+

>From 652afe34cde3d9d21afd6f08e792109360424be8 Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Thu, 9 Apr 2026 12:39:42 +0100
Subject: [PATCH 3/9] still breaks

---
 llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index c63ae08456172..cdc3afc3cd7e8 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -573,7 +573,9 @@ body:             |
     %mul:_(s64) = G_MUL %max, %sub2
     $x0 = COPY %mul
     RET_ReallyLR implicit $x0
-
+    
+...
+---
 name:   AMinusZeroMinusB_BV
 body:             |
   bb.0:

>From aa3f57d04cc5e840457d33ddcc7308e263342e1a Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Fri, 10 Apr 2026 09:59:14 +0100
Subject: [PATCH 4/9] remove tests to figure out what is wrong

---
 .../AArch64/GlobalISel/combine-integer.mir    | 54 -------------------
 1 file changed, 54 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index cdc3afc3cd7e8..f77ab013e20f2 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -7,7 +7,6 @@ name:   APlusBMinusCMinusB
 body:             |
   bb.0:
     liveins: $x0, $x1, $x2
-
     ; CHECK-LABEL: name: APlusBMinusCMinusB
     ; CHECK: liveins: $x0, $x1, $x2
     ; CHECK-NEXT: {{  $}}
@@ -497,30 +496,6 @@ body:             |
     $x0 = COPY %sub2
     RET_ReallyLR implicit $x0
 
-
-...
----
-name:   ASubMax
-body:             |
-  bb.0:
-    liveins: $x0
-
-
-    ; CHECK-LABEL: name: ASubMax
-    ; CHECK: liveins: $x0
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
-    ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB %zero, %a
-    ; CHECK-NEXT: %sub2:_(s64) = G_SMIN %a, [[SUB]]
-    ; CHECK-NEXT: $x0 = COPY %sub2(s64)
-    ; CHECK-NEXT: RET_ReallyLR implicit $x0
-    %a:_(s64) = COPY $x0
-
-    %zero:_(s64) = G_CONSTANT i64 0
-    %sub1:_(s64) = G_SUB %zero, %a
-    %max:_(s64) = G_SMAX %a, %sub1
-    %sub2:_(s64) = G_SUB %zero, %max
 ...
 ---
 name:   AMinusZeroMinusB
@@ -545,35 +520,6 @@ body:             |
     $x0 = COPY %sub2
     RET_ReallyLR implicit $x0
 
-...
----
-name:   ASubMaxOneUse
-body:             |
-  bb.0:
-    liveins: $x0
-
-
-    ; CHECK-LABEL: name: ASubMaxOneUse
-    ; CHECK: liveins: $x0
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
-    ; CHECK-NEXT: %max:_(s64) = G_SMAX %a, %sub1
-    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %zero, %max
-    ; CHECK-NEXT: %mul:_(s64) = G_MUL %max, %sub2
-    ; CHECK-NEXT: $x0 = COPY %mul(s64)
-    ; CHECK-NEXT: RET_ReallyLR implicit $x0
-    %a:_(s64) = COPY $x0
-
-    %zero:_(s64) = G_CONSTANT i64 0
-    %sub1:_(s64) = G_SUB %zero, %a
-    %max:_(s64) = G_SMAX %a, %sub1
-    %sub2:_(s64) = G_SUB %zero, %max
-    %mul:_(s64) = G_MUL %max, %sub2
-    $x0 = COPY %mul
-    RET_ReallyLR implicit $x0
-    
 ...
 ---
 name:   AMinusZeroMinusB_BV

>From f9a520722652ca95d5af0bc9f23f9de66cdee1de Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Fri, 10 Apr 2026 11:29:21 +0100
Subject: [PATCH 5/9] test

---
 .../llvm/CodeGen/GlobalISel/CombinerHelper.h  |  3 ++
 .../include/llvm/Target/GlobalISel/Combine.td | 15 ++++---
 .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 43 +++++++++++++++++++
 .../AArch64/GlobalISel/combine-integer.mir    | 22 ++++++++++
 4 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 365bbaacfe055..29abb162d1834 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -1021,6 +1021,9 @@ class CombinerHelper {
   bool matchFoldAMinusC1PlusC2(const MachineInstr &MI,
                                BuildFnTy &MatchInfo) const;
 
+  bool matchFoldSubSmaxSub(const MachineInstr &MI,
+                               BuildFnTy &MatchInfo) const;
+                               
   bool matchExtOfExt(const MachineInstr &FirstMI, const MachineInstr &SecondMI,
                      BuildFnTy &MatchInfo) const;
 
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 9717763e30a7a..16fdc926102b7 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -2074,14 +2074,12 @@ def AMinusC1PlusC2: GICombineRule<
 
 // (sub 0, (max X, (sub 0, X))) --> (min X, (sub 0, X))
 def SubSmaxSub: GICombineRule<
-   (defs root:$root),
+   (defs root:$root, build_fn_matchinfo:$matchinfo),
    (match (G_SUB $sub, 0, $A),
           (G_SMAX $max, $A, $sub),
           (G_SUB $root, 0, $max):$root, 
-          [{ return MRI.hasOneNonDBGUse(${sub}.getReg()) 
-              && MRI.hasOneNonDBGUse(${max}.getReg()); }]),
-   (apply (G_SUB $sub1, 0, $A), 
-          (G_SMIN $root, $A, $sub1))>;
+          [{ return Helper.matchFoldSubSmaxSub(*${root}, ${matchinfo}); }]),
+   (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
           
 // (sub 0, (max X, (sub 0, X))) --> (min X, (sub 0, X))
 def SubUmaxSub: GICombineRule<
@@ -2114,8 +2112,11 @@ def integer_reassoc_combines: GICombineGroup<[
   AMinusC1MinusC2,
   C1Minus2MinusC2,
   AMinusC1PlusC2,
+]>;
+
+def max_min_combines: GICombineGroup<[
   SubSmaxSub, 
-  SubUmaxSub
+  // SubUmaxSub
 ]>;
 
 // fold (A+(shl (0-B), C)) -> (A-(shl B, C))
@@ -2400,7 +2401,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
     sext_trunc, zext_trunc, prefer_sign_combines, shuffle_combines,
     combine_use_vector_truncate, merge_combines, overflow_combines,
     truncsat_combines, lshr_of_trunc_of_lshr, ctls_combines, add_shift, sub_one_from_sub,
-    binop_with_neg, sub_minus_one]>;
+    binop_with_neg, sub_minus_one, max_min_combines]>;
 
 // A combine group used to for prelegalizer combiners at -O0. The combines in
 // this group have been selected based on experiments to balance code size and
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 177170575fe07..db99b972eea34 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -8374,6 +8374,49 @@ bool CombinerHelper::matchFoldAMinusC1PlusC2(const MachineInstr &MI,
   return true;
 }
 
+bool CombinerHelper::matchFoldSubSmaxSub(const MachineInstr &MI,
+                                         BuildFnTy &MatchInfo) const {
+  // fold (sub 0, (smax X, (sub 0, X))) --> (smin X, (sub 0, X))
+  const GSub *Sub1 = cast<GSub>(&MI);
+
+  MachineInstr *MaxMI = MRI.getVRegDef(Sub1->getRHSReg());
+  if (!MaxMI || MaxMI->getOpcode() != TargetOpcode::G_SMAX)
+    return false;
+
+  MachineInstr *Sub2MI = MRI.getVRegDef(MaxMI->getOperand(2).getReg());
+  if (!Sub2MI || Sub2MI->getOpcode() != TargetOpcode::G_SUB)
+    return false;
+
+  // Verify Sub1 LHS == 0
+  auto MaybeCst1 = getIConstantVRegValWithLookThrough(Sub1->getLHSReg(), MRI);
+  if (!MaybeCst1 || !MaybeCst1->Value.isZero())
+    return false;
+
+  // Verify Sub2 LHS == 0
+  auto MaybeCst2 = getIConstantVRegValWithLookThrough(
+      Sub2MI->getOperand(1).getReg(), MRI);
+  if (!MaybeCst2 || !MaybeCst2->Value.isZero())
+    return false;
+
+  // Verify X is the same register in both smax and the inner sub
+  Register X = MaxMI->getOperand(1).getReg();
+  if (X != Sub2MI->getOperand(2).getReg())
+    return false;
+
+  if (!MRI.hasOneNonDBGUse(Sub2MI->getOperand(0).getReg()))
+    return false;
+  if (!MRI.hasOneNonDBGUse(MaxMI->getOperand(0).getReg()))
+    return false;
+
+  Register Dst = Sub1->getReg(0);
+  Register Sub2Result = Sub2MI->getOperand(0).getReg();
+
+  MatchInfo = [=](MachineIRBuilder &B) {
+    B.buildSMin(Dst, X, Sub2Result);
+  };
+  return true;
+}
+
 bool CombinerHelper::matchUnmergeValuesAnyExtBuildVector(
     const MachineInstr &MI, BuildFnTy &MatchInfo) const {
   const GUnmerge *Unmerge = cast<GUnmerge>(&MI);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index f77ab013e20f2..fd64e54e0773d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -585,3 +585,25 @@ body:             |
     RET_ReallyLR implicit $q0
 
 ...
+---
+name:   ASubMax
+body:             |
+  bb.0:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: ASubMax
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %sub2:_(s64) = G_SMIN %a, %sub1
+    ; CHECK-NEXT: $x0 = COPY %sub2(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %zero:_(s64) = G_CONSTANT i64 0
+    %sub1:_(s64) = G_SUB %zero, %a
+    %max:_(s64) = G_SMAX %a, %sub1
+    %sub2:_(s64) = G_SUB %zero, %max
+    $x0 = COPY %sub2
+    RET_ReallyLR implicit $x0

>From 4be9d442df6a8ef23af037093d30aa4d7f2317df Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Fri, 10 Apr 2026 11:29:46 +0100
Subject: [PATCH 6/9] test

---
 .../AArch64/GlobalISel/combine-integer.mir    | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index fd64e54e0773d..23dd6a7f3ed50 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -607,3 +607,33 @@ body:             |
     %sub2:_(s64) = G_SUB %zero, %max
     $x0 = COPY %sub2
     RET_ReallyLR implicit $x0
+
+...
+---
+name:   ASubMaxOneUse
+body:             |
+  bb.0:
+    liveins: $x0
+
+
+    ; CHECK-LABEL: name: ASubMaxOneUse
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %max:_(s64) = G_SMAX %a, %sub1
+    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %zero, %max
+    ; CHECK-NEXT: %mul:_(s64) = G_MUL %max, %sub2
+    ; CHECK-NEXT: $x0 = COPY %mul(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+
+    %zero:_(s64) = G_CONSTANT i64 0
+    %sub1:_(s64) = G_SUB %zero, %a
+    %max:_(s64) = G_SMAX %a, %sub1
+    %sub2:_(s64) = G_SUB %zero, %max
+    %mul:_(s64) = G_MUL %max, %sub2
+    $x0 = COPY %mul
+    RET_ReallyLR implicit $x0
+    
\ No newline at end of file

>From 784f8c887ca27adb9d3d3dce84dbf94f6c029cf4 Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Fri, 10 Apr 2026 11:31:00 +0100
Subject: [PATCH 7/9] wip

---
 llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index 23dd6a7f3ed50..10f41853ad9c5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -615,7 +615,6 @@ body:             |
   bb.0:
     liveins: $x0
 
-
     ; CHECK-LABEL: name: ASubMaxOneUse
     ; CHECK: liveins: $x0
     ; CHECK-NEXT: {{  $}}
@@ -628,7 +627,6 @@ body:             |
     ; CHECK-NEXT: $x0 = COPY %mul(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
-
     %zero:_(s64) = G_CONSTANT i64 0
     %sub1:_(s64) = G_SUB %zero, %a
     %max:_(s64) = G_SMAX %a, %sub1
@@ -636,4 +634,4 @@ body:             |
     %mul:_(s64) = G_MUL %max, %sub2
     $x0 = COPY %mul
     RET_ReallyLR implicit $x0
-    
\ No newline at end of file
+

>From b2e4a8a7b861500dc5d71fae45de3e7f9efb9f85 Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Fri, 10 Apr 2026 11:31:35 +0100
Subject: [PATCH 8/9] wip

---
 .../AArch64/GlobalISel/combine-integer.mir    | 57 ++++++++++++++++++-
 1 file changed, 54 insertions(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index 10f41853ad9c5..91f5961160b53 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -586,12 +586,12 @@ body:             |
 
 ...
 ---
-name:   ASubMax
+name:   ASubSMax
 body:             |
   bb.0:
     liveins: $x0
 
-    ; CHECK-LABEL: name: ASubMax
+    ; CHECK-LABEL: name: ASubSMax
     ; CHECK: liveins: $x0
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
@@ -610,7 +610,7 @@ body:             |
 
 ...
 ---
-name:   ASubMaxOneUse
+name:   ASubSMaxOneUse
 body:             |
   bb.0:
     liveins: $x0
@@ -635,3 +635,54 @@ body:             |
     $x0 = COPY %mul
     RET_ReallyLR implicit $x0
 
+...
+---
+name:   ASubUMax
+body:             |
+  bb.0:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: ASubMax
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %sub2:_(s64) = G_SMIN %a, %sub1
+    ; CHECK-NEXT: $x0 = COPY %sub2(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %zero:_(s64) = G_CONSTANT i64 0
+    %sub1:_(s64) = G_SUB %zero, %a
+    %max:_(s64) = G_UMAX %a, %sub1
+    %sub2:_(s64) = G_SUB %zero, %max
+    $x0 = COPY %sub2
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   ASubUMaxOneUse
+body:             |
+  bb.0:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: ASubMaxOneUse
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %max:_(s64) = G_SMAX %a, %sub1
+    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %zero, %max
+    ; CHECK-NEXT: %mul:_(s64) = G_MUL %max, %sub2
+    ; CHECK-NEXT: $x0 = COPY %mul(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %zero:_(s64) = G_CONSTANT i64 0
+    %sub1:_(s64) = G_SUB %zero, %a
+    %max:_(s64) = G_UMAX %a, %sub1
+    %sub2:_(s64) = G_SUB %zero, %max
+    %mul:_(s64) = G_MUL %max, %sub2
+    $x0 = COPY %mul
+    RET_ReallyLR implicit $x0
+

>From 87755bdd108ea9af9c6232d5eb20ed073c332b7f Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Fri, 10 Apr 2026 11:52:57 +0100
Subject: [PATCH 9/9] no sense

---
 .../include/llvm/Target/GlobalISel/Combine.td |  6 +--
 .../AArch64/GlobalISel/combine-integer.mir    | 37 +++----------------
 2 files changed, 7 insertions(+), 36 deletions(-)

diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 16fdc926102b7..3c236c78ad6b7 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -2086,9 +2086,7 @@ def SubUmaxSub: GICombineRule<
    (defs root:$root),
    (match (G_SUB $sub, 0, $A),
           (G_UMAX $max, $A, $sub),
-          (G_SUB $root, 0, $max):$root, 
-          [{ return MRI.hasOneNonDBGUse(${sub}.getReg()) 
-              && MRI.hasOneNonDBGUse(${max}.getReg()); }]),
+          (G_SUB $root, 0, $max):$root),
    (apply (G_SUB $sub1, 0, $A), 
           (G_UMIN $root, $A, $sub1))>;
    
@@ -2116,7 +2114,7 @@ def integer_reassoc_combines: GICombineGroup<[
 
 def max_min_combines: GICombineGroup<[
   SubSmaxSub, 
-  // SubUmaxSub
+  SubUmaxSub
 ]>;
 
 // fold (A+(shl (0-B), C)) -> (A-(shl B, C))
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index 91f5961160b53..8740c44ab0ec9 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -615,7 +615,7 @@ body:             |
   bb.0:
     liveins: $x0
 
-    ; CHECK-LABEL: name: ASubMaxOneUse
+    ; CHECK-LABEL: name: ASubSMaxOneUse
     ; CHECK: liveins: $x0
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
@@ -642,13 +642,14 @@ body:             |
   bb.0:
     liveins: $x0
 
-    ; CHECK-LABEL: name: ASubMax
+
+    ; CHECK-LABEL: name: ASubUMax
     ; CHECK: liveins: $x0
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
-    ; CHECK-NEXT: %sub2:_(s64) = G_SMIN %a, %sub1
+    ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB %zero, %a
+    ; CHECK-NEXT: %sub2:_(s64) = G_UMIN %a, [[SUB]]
     ; CHECK-NEXT: $x0 = COPY %sub2(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -658,31 +659,3 @@ body:             |
     %sub2:_(s64) = G_SUB %zero, %max
     $x0 = COPY %sub2
     RET_ReallyLR implicit $x0
-
-...
----
-name:   ASubUMaxOneUse
-body:             |
-  bb.0:
-    liveins: $x0
-
-    ; CHECK-LABEL: name: ASubMaxOneUse
-    ; CHECK: liveins: $x0
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %zero, %a
-    ; CHECK-NEXT: %max:_(s64) = G_SMAX %a, %sub1
-    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %zero, %max
-    ; CHECK-NEXT: %mul:_(s64) = G_MUL %max, %sub2
-    ; CHECK-NEXT: $x0 = COPY %mul(s64)
-    ; CHECK-NEXT: RET_ReallyLR implicit $x0
-    %a:_(s64) = COPY $x0
-    %zero:_(s64) = G_CONSTANT i64 0
-    %sub1:_(s64) = G_SUB %zero, %a
-    %max:_(s64) = G_UMAX %a, %sub1
-    %sub2:_(s64) = G_SUB %zero, %max
-    %mul:_(s64) = G_MUL %max, %sub2
-    $x0 = COPY %mul
-    RET_ReallyLR implicit $x0
-



More information about the llvm-commits mailing list