[llvm] feat: add GlobalISel combine (PR #181486)

Luisa Cicolini via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 14 08:24:12 PST 2026


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

>From f0ba0f871ca98fe80eecf950ca2bc9231ed2b86b Mon Sep 17 00:00:00 2001
From: luisacicolini <luisacicolini at gmail.com>
Date: Sat, 14 Feb 2026 16:16:05 +0000
Subject: [PATCH 1/6] chore: test

---
 .../GlobalISel/GIMatchTableExecutorImpl.h     | 22 ++++++-
 .../include/llvm/Target/GlobalISel/Combine.td | 45 +++++++++----
 .../AArch64/GlobalISel/combine-integer.mir    | 66 ++++++++++++++++---
 3 files changed, 108 insertions(+), 25 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 8f6586e79d78a..05a312a0c0812 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -35,6 +35,7 @@
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
+#include <cstdio>
 
 namespace llvm {
 
@@ -49,6 +50,8 @@ bool GIMatchTableExecutor::executeMatchTable(
     const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
     const PredicateBitset &AvailableFeatures,
     CodeGenCoverage *CoverageInfo) const {
+  
+  printf("\nHALO\n");
 
   uint64_t CurrentIdx = 0;
   SmallVector<uint64_t, 4> OnFailResumeAt;
@@ -215,7 +218,7 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       unsigned Opcode = State.MIs[InsnID]->getOpcode();
-
+      
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
                << "], ExpectedOpcode=" << Expected0;
@@ -230,6 +233,7 @@ bool GIMatchTableExecutor::executeMatchTable(
       }
       break;
     }
+    
     case GIM_SwitchOpcode: {
       uint64_t InsnID = readULEB();
       uint16_t LowerBound = readU16();
@@ -460,6 +464,7 @@ bool GIMatchTableExecutor::executeMatchTable(
       // Note: we don't check for invalid here because this is purely a hook to
       // allow some executors (such as the combiner) to check arbitrary,
       // contextless predicates, such as whether a rule is enabled or not.
+      
       uint16_t Predicate = readU16();
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx
@@ -1151,6 +1156,9 @@ bool GIMatchTableExecutor::executeMatchTable(
     }
 
     case GIR_CopySubReg: {
+      
+      printf("\nGIR_CopySubReg\n");
+      
       uint64_t NewInsnID = readULEB();
       uint64_t OldInsnID = readULEB();
       uint64_t OpIdx = readULEB();
@@ -1259,6 +1267,9 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_AddSimpleTempRegister:
     case GIR_AddTempRegister:
     case GIR_AddTempSubRegister: {
+      
+      printf("\nGIR_AddTempSubRegister\n");
+      
       uint64_t InsnID = readULEB();
       uint64_t TempRegID = readULEB();
       RegState TempRegFlags = {};
@@ -1323,6 +1334,9 @@ bool GIMatchTableExecutor::executeMatchTable(
       break;
     }
     case GIR_ComplexSubOperandRenderer: {
+      
+      printf("\nGIR_ComplexSubOperandRenderer\n");
+      
       uint64_t InsnID = readULEB();
       uint16_t RendererID = readU16();
       uint64_t RenderOpID = readULEB();
@@ -1336,6 +1350,9 @@ bool GIMatchTableExecutor::executeMatchTable(
       break;
     }
     case GIR_ComplexSubOperandSubRegRenderer: {
+      
+      printf("\nGIR_ComplexSubOperandSubRegRenderer\n");
+      
       uint64_t InsnID = readULEB();
       uint16_t RendererID = readU16();
       uint64_t RenderOpID = readULEB();
@@ -1455,6 +1472,9 @@ bool GIMatchTableExecutor::executeMatchTable(
 
     case GIR_RootConstrainSelectedInstOperands:
     case GIR_ConstrainSelectedInstOperands: {
+      
+      printf("GIR_ConstrainSelectedInstOperands at index %lu\n", CurrentIdx);
+      
       uint64_t InsnID = (MatcherOpcode == GIR_RootConstrainSelectedInstOperands)
                             ? 0
                             : readULEB();
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index f5c940bffc8fb..697d70cfda7d1 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1879,6 +1879,22 @@ def APlusBMinusCMinusB : GICombineRule<
           (G_SUB $root, $add1, $B)),
    (apply (G_SUB $root, $A, $C))>;
 
+// fold ((A+(B+C))-B) -> A+C
+def APlusBPlusCMinusB_frags : GICombinePatFrag<
+  (outs root:$root), (ins $x, $y, $n),
+  [
+    (pattern (G_ADD $add1, $y, $n),
+              (G_ADD $add2, $x, $add1),
+              (G_SUB $root, $add2, $y),
+             [{ return MRI.hasOneNonDBGUse(${add2}.getReg()) &&
+                       MRI.hasOneNonDBGUse(${add1}.getReg()); }]),
+  ]>;
+
+def APlusBPlusCMinusB : GICombineRule<
+  (defs root:$root),
+  (match (APlusBPlusCMinusB_frags $root, $x, $y, $n)),
+  (apply (G_ADD $root, $x, $n))>;
+
 // fold ((A-(B-C))-C) -> A-B
 def AMinusBMinusCMinusC : GICombineRule<
     (defs root:$root),
@@ -1999,20 +2015,21 @@ def AMinusC1PlusC2: GICombineRule<
 
 def integer_reassoc_combines: GICombineGroup<[
   APlusBMinusCMinusB,
-  AMinusBMinusCMinusC,
-  ZeroMinusAPlusB,
-  APlusZeroMinusB,
-  APlusBMinusB,
-  BMinusAPlusA,
-  AMinusBPlusCMinusA,
-  AMinusBPlusBMinusC,
-  APlusBMinusAplusC,
-  APlusBMinusCPlusA,
-  APlusC1MinusC2,
-  C2MinusAPlusC1,
-  AMinusC1MinusC2,
-  C1Minus2MinusC2,
-  AMinusC1PlusC2
+  APlusBPlusCMinusB,
+  // AMinusBMinusCMinusC,
+  // ZeroMinusAPlusB,
+  // APlusZeroMinusB,
+  // APlusBMinusB,
+  // BMinusAPlusA,
+  // AMinusBPlusCMinusA,
+  // AMinusBPlusBMinusC,
+  // APlusBMinusAplusC,
+  // APlusBMinusCPlusA,
+  // APlusC1MinusC2,
+  // C2MinusAPlusC1,
+  // AMinusC1MinusC2,
+  // C1Minus2MinusC2,
+  // AMinusC1PlusC2
 ]>;
 
 // 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 c9b24ad75ce27..2693caad43d21 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -35,7 +35,10 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
-    ; CHECK-NEXT: %sub:_(s64) = G_SUB %a, %b
+    ; CHECK-NEXT: %c:_(s64) = COPY $x2
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %c
+    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %a, %sub1
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB %sub2, %c
     ; CHECK-NEXT: $x0 = COPY %sub(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -175,9 +178,12 @@ body:             |
     ; CHECK-LABEL: name: AMinusBPlusCMinusA
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %add:_(s64) = G_SUB %c, %b
+    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %c, %a
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %a, %b
+    ; CHECK-NEXT: %add:_(s64) = G_ADD %sub1, %sub2
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -201,8 +207,11 @@ body:             |
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %add:_(s64) = G_SUB %a, %c
+    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %b, %c
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %a, %b
+    ; CHECK-NEXT: %add:_(s64) = G_ADD %sub1, %sub2
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -226,9 +235,12 @@ body:             |
     ; CHECK-LABEL: name: APlusBMinusAplusC
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %add:_(s64) = G_SUB %b, %c
+    ; CHECK-NEXT: %add1:_(s64) = G_ADD %a, %c
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %add1
+    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, %sub1
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -251,9 +263,12 @@ body:             |
     ; CHECK-LABEL: name: APlusBMinusCPlusA
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %add:_(s64) = G_SUB %b, %c
+    ; CHECK-NEXT: %add1:_(s64) = G_ADD %c, %a
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %add1
+    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, %sub1
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -279,9 +294,12 @@ body:             |
     ; CHECK-NEXT: %a1:_(s64) = COPY $x0
     ; CHECK-NEXT: %b1:_(s64) = COPY $x1
     ; CHECK-NEXT: %c1:_(s64) = COPY $x2
+    ; CHECK-NEXT: %a:_(<2 x s64>) = G_BUILD_VECTOR %a1(s64), %b1(s64)
     ; CHECK-NEXT: %b:_(<2 x s64>) = G_BUILD_VECTOR %b1(s64), %ba:_(s64)
     ; CHECK-NEXT: %c:_(<2 x s64>) = G_BUILD_VECTOR %a1(s64), %c1(s64)
-    ; CHECK-NEXT: %add:_(<2 x s64>) = G_SUB %b, %c
+    ; CHECK-NEXT: %add1:_(<2 x s64>) = G_ADD %c, %a
+    ; CHECK-NEXT: %sub1:_(<2 x s64>) = G_SUB %b, %add1
+    ; CHECK-NEXT: %add:_(<2 x s64>) = G_ADD %a, %sub1
     ; CHECK-NEXT: $q0 = COPY %add(<2 x s64>)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a1:_(s64) = COPY $x0
@@ -331,8 +349,10 @@ body:             |
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
-    ; CHECK-NEXT: %sub:_(s64) = G_SUB [[C]], %a
+    ; CHECK-NEXT: %c1:_(s64) = G_CONSTANT i64 4
+    ; CHECK-NEXT: %c2:_(s64) = G_CONSTANT i64 9
+    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, %c1
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB %c2, %add
     ; CHECK-NEXT: $x0 = COPY %sub(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -377,8 +397,10 @@ body:             |
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -49
-    ; CHECK-NEXT: %sub:_(s64) = G_SUB [[C]], %a
+    ; CHECK-NEXT: %c1:_(s64) = G_CONSTANT i64 11
+    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %c1, %a
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -60
+    ; CHECK-NEXT: %sub:_(s64) = G_ADD %sub1, [[C]]
     ; CHECK-NEXT: $x0 = COPY %sub(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -413,3 +435,27 @@ body:             |
     $x0 = COPY %add
     RET_ReallyLR implicit $x0
 
+...
+---
+name:   APlusBPlusCMinusB
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: APlusBPlusCMinusB
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: %c:_(s64) = COPY $x2
+    ; CHECK-NEXT: %sub1:_(s64) = G_ADD %a, %c
+    ; CHECK-NEXT: $x0 = COPY %sub1(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %b:_(s64) = COPY $x1
+    %c:_(s64) = COPY $x2
+    %add1:_(s64) = G_ADD %b, %c
+    %add2:_(s64) = G_ADD %a, %add1
+    %sub1:_(s64) = G_SUB %add2, %b
+    $x0 = COPY %sub1
+    RET_ReallyLR implicit $x0
+

>From 5dba0ef850db425e870b4fed6639360f45afafcd Mon Sep 17 00:00:00 2001
From: luisacicolini <luisacicolini at gmail.com>
Date: Sat, 14 Feb 2026 16:18:46 +0000
Subject: [PATCH 2/6] chore: clean

---
 .../GlobalISel/GIMatchTableExecutorImpl.h      | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 05a312a0c0812..87c531aaed725 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -35,7 +35,6 @@
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
-#include <cstdio>
 
 namespace llvm {
 
@@ -51,8 +50,6 @@ bool GIMatchTableExecutor::executeMatchTable(
     const PredicateBitset &AvailableFeatures,
     CodeGenCoverage *CoverageInfo) const {
   
-  printf("\nHALO\n");
-
   uint64_t CurrentIdx = 0;
   SmallVector<uint64_t, 4> OnFailResumeAt;
   NewMIVector OutMIs;
@@ -233,7 +230,6 @@ bool GIMatchTableExecutor::executeMatchTable(
       }
       break;
     }
-    
     case GIM_SwitchOpcode: {
       uint64_t InsnID = readULEB();
       uint16_t LowerBound = readU16();
@@ -242,7 +238,6 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       const int64_t Opcode = State.MIs[InsnID]->getOpcode();
-
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
                << LowerBound << ", " << UpperBound << "), Default=" << Default
@@ -464,7 +459,6 @@ bool GIMatchTableExecutor::executeMatchTable(
       // Note: we don't check for invalid here because this is purely a hook to
       // allow some executors (such as the combiner) to check arbitrary,
       // contextless predicates, such as whether a rule is enabled or not.
-      
       uint16_t Predicate = readU16();
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx
@@ -1156,9 +1150,6 @@ bool GIMatchTableExecutor::executeMatchTable(
     }
 
     case GIR_CopySubReg: {
-      
-      printf("\nGIR_CopySubReg\n");
-      
       uint64_t NewInsnID = readULEB();
       uint64_t OldInsnID = readULEB();
       uint64_t OpIdx = readULEB();
@@ -1267,9 +1258,6 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_AddSimpleTempRegister:
     case GIR_AddTempRegister:
     case GIR_AddTempSubRegister: {
-      
-      printf("\nGIR_AddTempSubRegister\n");
-      
       uint64_t InsnID = readULEB();
       uint64_t TempRegID = readULEB();
       RegState TempRegFlags = {};
@@ -1334,9 +1322,6 @@ bool GIMatchTableExecutor::executeMatchTable(
       break;
     }
     case GIR_ComplexSubOperandRenderer: {
-      
-      printf("\nGIR_ComplexSubOperandRenderer\n");
-      
       uint64_t InsnID = readULEB();
       uint16_t RendererID = readU16();
       uint64_t RenderOpID = readULEB();
@@ -1350,9 +1335,6 @@ bool GIMatchTableExecutor::executeMatchTable(
       break;
     }
     case GIR_ComplexSubOperandSubRegRenderer: {
-      
-      printf("\nGIR_ComplexSubOperandSubRegRenderer\n");
-      
       uint64_t InsnID = readULEB();
       uint16_t RendererID = readU16();
       uint64_t RenderOpID = readULEB();

>From eb80ece3e7704b5da4c6038e07b7b1f5736aee42 Mon Sep 17 00:00:00 2001
From: luisacicolini <luisacicolini at gmail.com>
Date: Sat, 14 Feb 2026 16:20:24 +0000
Subject: [PATCH 3/6] chore: fix

---
 .../include/llvm/Target/GlobalISel/Combine.td | 28 ++++++-------
 .../AArch64/GlobalISel/combine-integer.mir    | 42 +++++--------------
 2 files changed, 24 insertions(+), 46 deletions(-)

diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 697d70cfda7d1..e70d90283d3be 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -2016,20 +2016,20 @@ def AMinusC1PlusC2: GICombineRule<
 def integer_reassoc_combines: GICombineGroup<[
   APlusBMinusCMinusB,
   APlusBPlusCMinusB,
-  // AMinusBMinusCMinusC,
-  // ZeroMinusAPlusB,
-  // APlusZeroMinusB,
-  // APlusBMinusB,
-  // BMinusAPlusA,
-  // AMinusBPlusCMinusA,
-  // AMinusBPlusBMinusC,
-  // APlusBMinusAplusC,
-  // APlusBMinusCPlusA,
-  // APlusC1MinusC2,
-  // C2MinusAPlusC1,
-  // AMinusC1MinusC2,
-  // C1Minus2MinusC2,
-  // AMinusC1PlusC2
+  AMinusBMinusCMinusC,
+  ZeroMinusAPlusB,
+  APlusZeroMinusB,
+  APlusBMinusB,
+  BMinusAPlusA,
+  AMinusBPlusCMinusA,
+  AMinusBPlusBMinusC,
+  APlusBMinusAplusC,
+  APlusBMinusCPlusA,
+  APlusC1MinusC2,
+  C2MinusAPlusC1,
+  AMinusC1MinusC2,
+  C1Minus2MinusC2,
+  AMinusC1PlusC2
 ]>;
 
 // 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 2693caad43d21..d972f3aad591f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -35,10 +35,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
-    ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %c
-    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %a, %sub1
-    ; CHECK-NEXT: %sub:_(s64) = G_SUB %sub2, %c
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB %a, %b
     ; CHECK-NEXT: $x0 = COPY %sub(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -178,12 +175,9 @@ body:             |
     ; CHECK-LABEL: name: AMinusBPlusCMinusA
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %c, %a
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %a, %b
-    ; CHECK-NEXT: %add:_(s64) = G_ADD %sub1, %sub2
+    ; CHECK-NEXT: %add:_(s64) = G_SUB %c, %b
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -207,11 +201,8 @@ body:             |
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %sub2:_(s64) = G_SUB %b, %c
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %a, %b
-    ; CHECK-NEXT: %add:_(s64) = G_ADD %sub1, %sub2
+    ; CHECK-NEXT: %add:_(s64) = G_SUB %a, %c
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -235,12 +226,9 @@ body:             |
     ; CHECK-LABEL: name: APlusBMinusAplusC
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %add1:_(s64) = G_ADD %a, %c
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %add1
-    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, %sub1
+    ; CHECK-NEXT: %add:_(s64) = G_SUB %b, %c
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -263,12 +251,9 @@ body:             |
     ; CHECK-LABEL: name: APlusBMinusCPlusA
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %a:_(s64) = COPY $x0
     ; CHECK-NEXT: %b:_(s64) = COPY $x1
     ; CHECK-NEXT: %c:_(s64) = COPY $x2
-    ; CHECK-NEXT: %add1:_(s64) = G_ADD %c, %a
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %add1
-    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, %sub1
+    ; CHECK-NEXT: %add:_(s64) = G_SUB %b, %c
     ; CHECK-NEXT: $x0 = COPY %add(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -294,12 +279,9 @@ body:             |
     ; CHECK-NEXT: %a1:_(s64) = COPY $x0
     ; CHECK-NEXT: %b1:_(s64) = COPY $x1
     ; CHECK-NEXT: %c1:_(s64) = COPY $x2
-    ; CHECK-NEXT: %a:_(<2 x s64>) = G_BUILD_VECTOR %a1(s64), %b1(s64)
     ; CHECK-NEXT: %b:_(<2 x s64>) = G_BUILD_VECTOR %b1(s64), %ba:_(s64)
     ; CHECK-NEXT: %c:_(<2 x s64>) = G_BUILD_VECTOR %a1(s64), %c1(s64)
-    ; CHECK-NEXT: %add1:_(<2 x s64>) = G_ADD %c, %a
-    ; CHECK-NEXT: %sub1:_(<2 x s64>) = G_SUB %b, %add1
-    ; CHECK-NEXT: %add:_(<2 x s64>) = G_ADD %a, %sub1
+    ; CHECK-NEXT: %add:_(<2 x s64>) = G_SUB %b, %c
     ; CHECK-NEXT: $q0 = COPY %add(<2 x s64>)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a1:_(s64) = COPY $x0
@@ -349,10 +331,8 @@ body:             |
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: %c1:_(s64) = G_CONSTANT i64 4
-    ; CHECK-NEXT: %c2:_(s64) = G_CONSTANT i64 9
-    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, %c1
-    ; CHECK-NEXT: %sub:_(s64) = G_SUB %c2, %add
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB [[C]], %a
     ; CHECK-NEXT: $x0 = COPY %sub(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0
@@ -397,10 +377,8 @@ body:             |
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %a:_(s64) = COPY $x0
-    ; CHECK-NEXT: %c1:_(s64) = G_CONSTANT i64 11
-    ; CHECK-NEXT: %sub1:_(s64) = G_SUB %c1, %a
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -60
-    ; CHECK-NEXT: %sub:_(s64) = G_ADD %sub1, [[C]]
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -49
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB [[C]], %a
     ; CHECK-NEXT: $x0 = COPY %sub(s64)
     ; CHECK-NEXT: RET_ReallyLR implicit $x0
     %a:_(s64) = COPY $x0

>From c1d5472e8db19abebdec5cc2cd79ce7724e97430 Mon Sep 17 00:00:00 2001
From: luisacicolini <luisacicolini at gmail.com>
Date: Sat, 14 Feb 2026 16:21:59 +0000
Subject: [PATCH 4/6] chore: things

---
 .../llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h      | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 87c531aaed725..8f720bb282206 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -49,7 +49,6 @@ bool GIMatchTableExecutor::executeMatchTable(
     const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
     const PredicateBitset &AvailableFeatures,
     CodeGenCoverage *CoverageInfo) const {
-  
   uint64_t CurrentIdx = 0;
   SmallVector<uint64_t, 4> OnFailResumeAt;
   NewMIVector OutMIs;
@@ -215,7 +214,6 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       unsigned Opcode = State.MIs[InsnID]->getOpcode();
-      
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
                << "], ExpectedOpcode=" << Expected0;
@@ -238,6 +236,7 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       const int64_t Opcode = State.MIs[InsnID]->getOpcode();
+      
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
                << LowerBound << ", " << UpperBound << "), Default=" << Default
@@ -1454,9 +1453,6 @@ bool GIMatchTableExecutor::executeMatchTable(
 
     case GIR_RootConstrainSelectedInstOperands:
     case GIR_ConstrainSelectedInstOperands: {
-      
-      printf("GIR_ConstrainSelectedInstOperands at index %lu\n", CurrentIdx);
-      
       uint64_t InsnID = (MatcherOpcode == GIR_RootConstrainSelectedInstOperands)
                             ? 0
                             : readULEB();

>From 9a9c4b895c15364fc66eafde76b60510dc40f5fd Mon Sep 17 00:00:00 2001
From: luisacicolini <luisacicolini at gmail.com>
Date: Sat, 14 Feb 2026 16:22:49 +0000
Subject: [PATCH 5/6] chore: things

---
 .../include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 8f720bb282206..1821aeb99c280 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -49,6 +49,7 @@ bool GIMatchTableExecutor::executeMatchTable(
     const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
     const PredicateBitset &AvailableFeatures,
     CodeGenCoverage *CoverageInfo) const {
+      
   uint64_t CurrentIdx = 0;
   SmallVector<uint64_t, 4> OnFailResumeAt;
   NewMIVector OutMIs;
@@ -214,6 +215,7 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       unsigned Opcode = State.MIs[InsnID]->getOpcode();
+      
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
                << "], ExpectedOpcode=" << Expected0;
@@ -236,7 +238,6 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       const int64_t Opcode = State.MIs[InsnID]->getOpcode();
-      
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
                << LowerBound << ", " << UpperBound << "), Default=" << Default

>From f56eaa1f3232c3a6c7dceed85900a08e48f48e91 Mon Sep 17 00:00:00 2001
From: luisacicolini <luisacicolini at gmail.com>
Date: Sat, 14 Feb 2026 16:23:54 +0000
Subject: [PATCH 6/6] chore: thinfs

---
 .../include/llvm/CodeGen/GlobalISel/CSEInfo.h |  9 +-
 .../llvm/CodeGen/GlobalISel/CallLowering.h    | 25 +-----
 .../llvm/CodeGen/GlobalISel/Combiner.h        |  2 +-
 .../llvm/CodeGen/GlobalISel/CombinerHelper.h  | 25 ++----
 .../GlobalISel/GIMatchTableExecutorImpl.h     | 33 ++++----
 .../CodeGen/GlobalISel/GISelValueTracking.h   | 14 +++-
 .../llvm/CodeGen/GlobalISel/IRTranslator.h    |  9 +-
 .../CodeGen/GlobalISel/InstructionSelector.h  |  5 +-
 .../GlobalISel/LegalizationArtifactCombiner.h | 47 ++++-------
 .../llvm/CodeGen/GlobalISel/Legalizer.h       | 11 ++-
 .../llvm/CodeGen/GlobalISel/LegalizerHelper.h | 83 +++++++------------
 .../llvm/CodeGen/GlobalISel/LegalizerInfo.h   | 32 ++-----
 .../llvm/CodeGen/GlobalISel/MIPatternMatch.h  | 17 ++--
 .../CodeGen/GlobalISel/MachineIRBuilder.h     | 29 +------
 .../llvm/CodeGen/GlobalISel/RegBankSelect.h   |  3 +
 llvm/include/llvm/CodeGen/GlobalISel/Utils.h  |  7 +-
 16 files changed, 123 insertions(+), 228 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
index 19de00ee65cbc..ea3f1a8375c4a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -40,14 +40,14 @@ class UniqueMachineInstr : public FoldingSetNode {
 // A CSE config for fully optimized builds.
 class LLVM_ABI CSEConfigFull : public CSEConfigBase {
 public:
-  ~CSEConfigFull() override = default;
+  virtual ~CSEConfigFull() = default;
   bool shouldCSEOpc(unsigned Opc) override;
 };
 
 // Commonly used for O0 config.
 class LLVM_ABI CSEConfigConstantOnly : public CSEConfigBase {
 public:
-  ~CSEConfigConstantOnly() override = default;
+  virtual ~CSEConfigConstantOnly() = default;
   bool shouldCSEOpc(unsigned Opc) override;
 };
 
@@ -118,7 +118,7 @@ class LLVM_ABI GISelCSEInfo : public GISelChangeObserver {
 public:
   GISelCSEInfo() = default;
 
-  ~GISelCSEInfo() override;
+  virtual ~GISelCSEInfo();
 
   void setMF(MachineFunction &MF);
 
@@ -218,7 +218,8 @@ class GISelCSEAnalysisWrapper {
   /// If CSEConfig is already set, and the CSE Analysis has been preserved,
   /// it will not use the new CSEOpt(use Recompute to force using the new
   /// CSEOpt).
-  LLVM_ABI GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt);
+  LLVM_ABI GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt,
+                             bool ReCompute = false);
   void setMF(MachineFunction &MFunc) { MF = &MFunc; }
   void setComputed(bool Computed) { AlreadyComputed = Computed; }
   void releaseMemory() { Info.releaseMemory(); }
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 391c12001a2e8..a8bde824527a5 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -19,7 +19,6 @@
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/TargetCallingConv.h"
-#include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGenTypes/LowLevelType.h"
 #include "llvm/CodeGenTypes/MachineValueType.h"
 #include "llvm/IR/CallingConv.h"
@@ -160,8 +159,6 @@ class LLVM_ABI CallLowering {
 
     /// True if this call results in convergent operations.
     bool IsConvergent = true;
-
-    GlobalValue *DeactivationSymbol = nullptr;
   };
 
   /// Argument handling is mostly uniform between the four places that
@@ -389,7 +386,7 @@ class LLVM_ABI CallLowering {
   void splitToValueTypes(const ArgInfo &OrigArgInfo,
                          SmallVectorImpl<ArgInfo> &SplitArgs,
                          const DataLayout &DL, CallingConv::ID CallConv,
-                         SmallVectorImpl<TypeSize> *Offsets = nullptr) const;
+                         SmallVectorImpl<uint64_t> *Offsets = nullptr) const;
 
   /// Analyze the argument list in \p Args, using \p Assigner to populate \p
   /// CCInfo. This will determine the types and locations to use for passed or
@@ -486,26 +483,6 @@ class LLVM_ABI CallLowering {
                                   const CallBase &CB,
                                   CallLoweringInfo &Info) const;
 
-  /// Create a sequence of instructions to combine pieces split into register
-  /// typed values to the original IR value. \p OrigRegs contains the
-  /// destination value registers of type \p LLTy, and \p Regs contains the
-  /// legalized pieces with type \p PartLLT. This is used for incoming values
-  /// (physregs to vregs).
-  static void buildCopyFromRegs(MachineIRBuilder &B,
-                                ArrayRef<Register> OrigRegs,
-                                ArrayRef<Register> Regs, LLT LLTy, LLT PartLLT,
-                                const ISD::ArgFlagsTy Flags);
-
-  /// Create a sequence of instructions to expand the value in \p SrcReg (of
-  /// type
-  /// \p SrcTy) to the types in \p DstRegs (of type \p PartTy). \p ExtendOp
-  /// should contain the type of scalar value extension if necessary.
-  ///
-  /// This is used for outgoing values (vregs to physregs)
-  static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
-                              Register SrcReg, LLT SrcTy, LLT PartTy,
-                              unsigned ExtendOp = TargetOpcode::G_ANYEXT);
-
   /// \return True if the return type described by \p Outs can be returned
   /// without performing sret demotion.
   bool checkReturn(CCState &CCInfo, SmallVectorImpl<BaseArgInfo> &Outs,
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
index 7a313f493a6d3..39ff90c2687f4 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
@@ -60,7 +60,7 @@ class Combiner : public GIMatchTableExecutor {
   Combiner(MachineFunction &MF, CombinerInfo &CInfo,
            const TargetPassConfig *TPC, GISelValueTracking *VT,
            GISelCSEInfo *CSEInfo = nullptr);
-  ~Combiner() override;
+  virtual ~Combiner();
 
   virtual bool tryCombineAll(MachineInstr &I) const = 0;
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index da53005ed801e..5a1ff3d128bfb 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -276,6 +276,7 @@ class CombinerHelper {
                                  SmallVector<Register> &Ops) const;
 
   /// Replace \p MI with a build_vector.
+  bool matchCombineShuffleToBuildVector(MachineInstr &MI) const;
   void applyCombineShuffleToBuildVector(MachineInstr &MI) const;
 
   /// Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
@@ -293,7 +294,9 @@ class CombinerHelper {
                                  SmallVectorImpl<Register> &Ops) const;
   /// Replace \p MI with a concat_vectors with \p Ops.
   void applyCombineShuffleVector(MachineInstr &MI,
-                                 ArrayRef<Register> Ops) const;
+                                 const ArrayRef<Register> Ops) const;
+  bool matchShuffleToExtract(MachineInstr &MI) const;
+  void applyShuffleToExtract(MachineInstr &MI) const;
 
   /// Optimize memcpy intrinsics et al, e.g. constant len calls.
   /// /p MaxLen if non-zero specifies the max length of a mem libcall to inline.
@@ -518,6 +521,9 @@ class CombinerHelper {
   /// Optimize (x op x) -> x
   bool matchBinOpSameVal(MachineInstr &MI) const;
 
+  /// Check if operand \p OpIdx is zero.
+  bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx) const;
+
   /// Check if operand \p OpIdx is undef.
   bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) const;
 
@@ -637,19 +643,12 @@ class CombinerHelper {
   /// This variant does not erase \p MI after calling the build function.
   void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo) const;
 
-  bool matchOrShiftToFunnelShift(MachineInstr &MI, bool AllowScalarConstants,
-                                 BuildFnTy &MatchInfo) const;
+  bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo) const;
   bool matchFunnelShiftToRotate(MachineInstr &MI) const;
   void applyFunnelShiftToRotate(MachineInstr &MI) const;
   bool matchRotateOutOfRange(MachineInstr &MI) const;
   void applyRotateOutOfRange(MachineInstr &MI) const;
 
-  bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
-                                Register &UnmergeSrc) const;
-  void applyCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
-                                MachineIRBuilder &B,
-                                Register &UnmergeSrc) const;
-
   bool matchUseVectorTruncate(MachineInstr &MI, Register &MatchInfo) const;
   void applyUseVectorTruncate(MachineInstr &MI, Register &MatchInfo) const;
 
@@ -849,10 +848,6 @@ class CombinerHelper {
 
   bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info) const;
 
-  bool matchRepeatedFPDivisor(MachineInstr &MI,
-                              SmallVector<MachineInstr *> &MatchInfo) const;
-  void applyRepeatedFPDivisor(SmallVector<MachineInstr *> &MatchInfo) const;
-
   /// Transform G_ADD(x, G_SUB(y, x)) to y.
   /// Transform G_ADD(G_SUB(y, x), x) to y.
   bool matchAddSubSameReg(MachineInstr &MI, Register &Src) const;
@@ -1043,10 +1038,6 @@ class CombinerHelper {
   bool matchRedundantSextInReg(MachineInstr &Root, MachineInstr &Other,
                                BuildFnTy &MatchInfo) const;
 
-  // (ctlz (xor x, (sra x, bitwidth-1))) -> (add (ctls x), 1) or
-  // (ctlz (or (shl (xor x, (sra x, bitwidth-1)), 1), 1) -> (ctls x)
-  bool matchCtls(MachineInstr &CtlzMI, BuildFnTy &MatchInfo) const;
-
 private:
   /// Checks for legality of an indexed variant of \p LdSt.
   bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 1821aeb99c280..591cf9c97ae49 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -25,6 +25,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/RegisterBankInfo.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
@@ -32,6 +33,8 @@
 #include "llvm/Support/CodeGenCoverage.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
@@ -49,7 +52,7 @@ bool GIMatchTableExecutor::executeMatchTable(
     const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
     const PredicateBitset &AvailableFeatures,
     CodeGenCoverage *CoverageInfo) const {
-      
+
   uint64_t CurrentIdx = 0;
   SmallVector<uint64_t, 4> OnFailResumeAt;
   NewMIVector OutMIs;
@@ -215,7 +218,7 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       unsigned Opcode = State.MIs[InsnID]->getOpcode();
-      
+
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
                << "], ExpectedOpcode=" << Expected0;
@@ -238,6 +241,7 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
       const int64_t Opcode = State.MIs[InsnID]->getOpcode();
+
       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
         dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
                << LowerBound << ", " << UpperBound << "), Default=" << Default
@@ -1057,7 +1061,7 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_MutateOpcode: {
       uint64_t OldInsnID = readULEB();
       uint64_t NewInsnID = readULEB();
-      uint32_t NewOpcode = readU16();
+      uint16_t NewOpcode = readU16();
       if (NewInsnID >= OutMIs.size())
         OutMIs.resize(NewInsnID + 1);
 
@@ -1078,7 +1082,7 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_BuildRootMI:
     case GIR_BuildMI: {
       uint64_t NewInsnID = (MatcherOpcode == GIR_BuildRootMI) ? 0 : readULEB();
-      uint32_t Opcode = readU16();
+      uint16_t Opcode = readU16();
       if (NewInsnID >= OutMIs.size())
         OutMIs.resize(NewInsnID + 1);
 
@@ -1156,7 +1160,7 @@ bool GIMatchTableExecutor::executeMatchTable(
       uint16_t SubRegIdx = readU16();
       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
       OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
-                               {}, SubRegIdx);
+                               0, SubRegIdx);
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
                              << NewInsnID << "], MIs[" << OldInsnID << "], "
@@ -1167,14 +1171,13 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_AddImplicitDef: {
       uint64_t InsnID = readULEB();
       uint16_t RegNum = readU16();
-      RegState Flags = static_cast<RegState>(readU16());
+      uint16_t Flags = readU16();
       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
       Flags |= RegState::Implicit;
       OutMIs[InsnID].addDef(RegNum, Flags);
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
                       dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
-                             << InsnID << "], " << RegNum << ", "
-                             << static_cast<uint16_t>(Flags) << ")\n");
+                             << InsnID << "], " << RegNum << ")\n");
       break;
     }
 
@@ -1192,13 +1195,13 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_AddRegister: {
       uint64_t InsnID = readULEB();
       uint16_t RegNum = readU16();
-      RegState RegFlags = static_cast<RegState>(readU16());
+      uint16_t RegFlags = readU16();
       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
       OutMIs[InsnID].addReg(RegNum, RegFlags);
       DEBUG_WITH_TYPE(TgtExecutor::getName(),
-                      dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
-                             << InsnID << "], " << RegNum << ", "
-                             << static_cast<uint16_t>(RegFlags) << ")\n");
+                      dbgs()
+                          << CurrentIdx << ": GIR_AddRegister(OutMIs[" << InsnID
+                          << "], " << RegNum << ", " << RegFlags << ")\n");
       break;
     }
     case GIR_AddIntrinsicID: {
@@ -1260,9 +1263,9 @@ bool GIMatchTableExecutor::executeMatchTable(
     case GIR_AddTempSubRegister: {
       uint64_t InsnID = readULEB();
       uint64_t TempRegID = readULEB();
-      RegState TempRegFlags = {};
+      uint16_t TempRegFlags = 0;
       if (MatcherOpcode != GIR_AddSimpleTempRegister)
-        TempRegFlags = static_cast<RegState>(readU16());
+        TempRegFlags = readU16();
       uint16_t SubReg = 0;
       if (MatcherOpcode == GIR_AddTempSubRegister)
         SubReg = readU16();
@@ -1276,7 +1279,7 @@ bool GIMatchTableExecutor::executeMatchTable(
           dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs[" << InsnID
                  << "], TempRegisters[" << TempRegID << "]";
           if (SubReg) dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
-          dbgs() << ", " << static_cast<uint16_t>(TempRegFlags) << ")\n");
+          dbgs() << ", " << TempRegFlags << ")\n");
       break;
     }
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h b/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h
index 2ce085b8da7b6..490d1a34cc846 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h
@@ -37,6 +37,8 @@ class LLVM_ABI GISelValueTracking : public GISelChangeObserver {
   const TargetLowering &TL;
   const DataLayout &DL;
   unsigned MaxDepth;
+  /// Cache maintained during a computeKnownBits request.
+  SmallDenseMap<Register, KnownBits, 16> ComputeKnownBitsCache;
 
   void computeKnownBitsMin(Register Src0, Register Src1, KnownBits &Known,
                            const APInt &DemandedElts, unsigned Depth = 0);
@@ -58,14 +60,15 @@ class LLVM_ABI GISelValueTracking : public GISelChangeObserver {
 
 public:
   GISelValueTracking(MachineFunction &MF, unsigned MaxDepth = 6);
-  ~GISelValueTracking() override = default;
+  virtual ~GISelValueTracking() = default;
 
   const MachineFunction &getMachineFunction() const { return MF; }
 
   const DataLayout &getDataLayout() const { return DL; }
 
-  void computeKnownBitsImpl(Register R, KnownBits &Known,
-                            const APInt &DemandedElts, unsigned Depth = 0);
+  virtual void computeKnownBitsImpl(Register R, KnownBits &Known,
+                                    const APInt &DemandedElts,
+                                    unsigned Depth = 0);
 
   unsigned computeNumSignBits(Register R, const APInt &DemandedElts,
                               unsigned Depth = 0);
@@ -165,7 +168,10 @@ class LLVM_ABI GISelValueTrackingAnalysisLegacy : public MachineFunctionPass {
 
 public:
   static char ID;
-  GISelValueTrackingAnalysisLegacy() : MachineFunctionPass(ID) {}
+  GISelValueTrackingAnalysisLegacy() : MachineFunctionPass(ID) {
+    initializeGISelValueTrackingAnalysisLegacyPass(
+        *PassRegistry::getPassRegistry());
+  }
   GISelValueTracking &get(MachineFunction &MF);
   void getAnalysisUsage(AnalysisUsage &AU) const override;
   bool runOnMachineFunction(MachineFunction &MF) override;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 2f3f55a58a517..3d7ccd55ee042 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -297,10 +297,6 @@ class IRTranslator : public MachineFunctionPass {
   /// \pre \p U is a call instruction.
   bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
 
-  bool translateIntrinsic(
-      const CallBase &CB, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder,
-      ArrayRef<TargetLowering::IntrinsicInfo> TgtMemIntrinsicInfos = {});
-
   /// When an invoke or a cleanupret unwinds to the next EH pad, there are
   /// many places it could ultimately go. In the IR, we have a single unwind
   /// destination, but in the machine CFG, we enumerate all the possible blocks.
@@ -317,8 +313,6 @@ class IRTranslator : public MachineFunctionPass {
   bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
 
   bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
-  bool translateCallBrIntrinsic(const CallBrInst &I,
-                                MachineIRBuilder &MIRBuilder);
 
   bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
 
@@ -635,7 +629,6 @@ class IRTranslator : public MachineFunctionPass {
   AAResults *AA = nullptr;
   AssumptionCache *AC = nullptr;
   const TargetLibraryInfo *LibInfo = nullptr;
-  const LibcallLoweringInfo *Libcalls = nullptr;
   const TargetLowering *TLI = nullptr;
   FunctionLoweringInfo FuncInfo;
 
@@ -663,7 +656,7 @@ class IRTranslator : public MachineFunctionPass {
       IRT->addSuccessorWithProb(Src, Dst, Prob);
     }
 
-    ~GISelSwitchLowering() override = default;
+    virtual ~GISelSwitchLowering() = default;
 
   private:
     IRTranslator *IRT;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 483afb426fa10..cf65f34ce805a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -21,7 +21,7 @@ class GISelObserverWrapper;
 
 class LLVM_ABI InstructionSelector : public GIMatchTableExecutor {
 public:
-  ~InstructionSelector() override;
+  virtual ~InstructionSelector();
 
   /// Select the (possibly generic) instruction \p I to only use target-specific
   /// opcodes. It is OK to insert multiple instructions, but they cannot be
@@ -35,6 +35,9 @@ class LLVM_ABI InstructionSelector : public GIMatchTableExecutor {
   ///       !isPreISelGenericOpcode(I.getOpcode())
   virtual bool select(MachineInstr &I) = 0;
 
+  // FIXME: Eliminate dependency on TargetPassConfig for NewPM transition
+  const TargetPassConfig *TPC = nullptr;
+
   MachineOptimizationRemarkEmitter *MORE = nullptr;
 
   /// Note: InstructionSelect does not track changed instructions.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index d8d7ccc0bd7a7..6dccdc2f1a403 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -356,7 +356,7 @@ class LegalizationArtifactCombiner {
     // trunc(ext x) -> x
     ArtifactValueFinder Finder(MRI, Builder, LI);
     if (Register FoundReg =
-            Finder.findValueFromDef(DstReg, 0, DstTy.getSizeInBits(), DstTy)) {
+            Finder.findValueFromDef(DstReg, 0, DstTy.getSizeInBits())) {
       LLT FoundRegTy = MRI.getType(FoundReg);
       if (DstTy == FoundRegTy) {
         LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_[S,Z,ANY]EXT/G_TRUNC...): "
@@ -641,11 +641,10 @@ class LegalizationArtifactCombiner {
       Register SrcReg = Concat.getReg(StartSrcIdx);
       if (InRegOffset == 0 && Size == SrcSize) {
         CurrentBest = SrcReg;
-        return findValueFromDefImpl(SrcReg, 0, Size, MRI.getType(SrcReg));
+        return findValueFromDefImpl(SrcReg, 0, Size);
       }
 
-      return findValueFromDefImpl(SrcReg, InRegOffset, Size,
-                                  MRI.getType(SrcReg));
+      return findValueFromDefImpl(SrcReg, InRegOffset, Size);
     }
 
     /// Given an build_vector op \p BV and a start bit and size, try to find
@@ -760,8 +759,7 @@ class LegalizationArtifactCombiner {
       if (EndBit <= InsertOffset || InsertedEndBit <= StartBit) {
         SrcRegToUse = ContainerSrcReg;
         NewStartBit = StartBit;
-        return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size,
-                                    MRI.getType(SrcRegToUse));
+        return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size);
       }
       if (InsertOffset <= StartBit && EndBit <= InsertedEndBit) {
         SrcRegToUse = InsertedReg;
@@ -769,8 +767,7 @@ class LegalizationArtifactCombiner {
         if (NewStartBit == 0 &&
             Size == MRI.getType(SrcRegToUse).getSizeInBits())
           CurrentBest = SrcRegToUse;
-        return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size,
-                                    MRI.getType(SrcRegToUse));
+        return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size);
       }
       // The bit range spans both the inserted and container regions.
       return Register();
@@ -802,7 +799,7 @@ class LegalizationArtifactCombiner {
 
       if (StartBit == 0 && SrcType.getSizeInBits() == Size)
         CurrentBest = SrcReg;
-      return findValueFromDefImpl(SrcReg, StartBit, Size, SrcType);
+      return findValueFromDefImpl(SrcReg, StartBit, Size);
     }
 
     /// Given an G_TRUNC op \p MI and a start bit and size, try to find
@@ -822,14 +819,14 @@ class LegalizationArtifactCombiner {
       if (!SrcType.isScalar())
         return CurrentBest;
 
-      return findValueFromDefImpl(SrcReg, StartBit, Size, SrcType);
+      return findValueFromDefImpl(SrcReg, StartBit, Size);
     }
 
     /// Internal implementation for findValueFromDef(). findValueFromDef()
     /// initializes some data like the CurrentBest register, which this method
     /// and its callees rely upon.
     Register findValueFromDefImpl(Register DefReg, unsigned StartBit,
-                                  unsigned Size, LLT DstTy) {
+                                  unsigned Size) {
       std::optional<DefinitionAndSourceRegister> DefSrcReg =
           getDefSrcRegIgnoringCopies(DefReg, MRI);
       MachineInstr *Def = DefSrcReg->MI;
@@ -850,7 +847,7 @@ class LegalizationArtifactCombiner {
         }
         Register SrcReg = Def->getOperand(Def->getNumOperands() - 1).getReg();
         Register SrcOriginReg =
-            findValueFromDefImpl(SrcReg, StartBit + DefStartBit, Size, DstTy);
+            findValueFromDefImpl(SrcReg, StartBit + DefStartBit, Size);
         if (SrcOriginReg)
           return SrcOriginReg;
         // Failed to find a further value. If the StartBit and Size perfectly
@@ -871,12 +868,6 @@ class LegalizationArtifactCombiner {
       case TargetOpcode::G_ZEXT:
       case TargetOpcode::G_ANYEXT:
         return findValueFromExt(*Def, StartBit, Size);
-      case TargetOpcode::G_IMPLICIT_DEF: {
-        if (MRI.getType(DefReg) == DstTy)
-          return DefReg;
-        MIB.setInstrAndDebugLoc(*Def);
-        return MIB.buildUndef(DstTy).getReg(0);
-      }
       default:
         return CurrentBest;
       }
@@ -891,10 +882,10 @@ class LegalizationArtifactCombiner {
     /// at position \p StartBit with size \p Size.
     /// \returns a register with the requested size, or an empty Register if no
     /// better value could be found.
-    Register findValueFromDef(Register DefReg, unsigned StartBit, unsigned Size,
-                              LLT DstTy) {
+    Register findValueFromDef(Register DefReg, unsigned StartBit,
+                              unsigned Size) {
       CurrentBest = Register();
-      Register FoundReg = findValueFromDefImpl(DefReg, StartBit, Size, DstTy);
+      Register FoundReg = findValueFromDefImpl(DefReg, StartBit, Size);
       return FoundReg != DefReg ? FoundReg : Register();
     }
 
@@ -913,8 +904,7 @@ class LegalizationArtifactCombiner {
           DeadDefs[DefIdx] = true;
           continue;
         }
-        Register FoundVal =
-            findValueFromDef(DefReg, 0, DestTy.getSizeInBits(), DestTy);
+        Register FoundVal = findValueFromDef(DefReg, 0, DestTy.getSizeInBits());
         if (!FoundVal)
           continue;
         if (MRI.getType(FoundVal) != DestTy)
@@ -933,7 +923,7 @@ class LegalizationArtifactCombiner {
 
     GUnmerge *findUnmergeThatDefinesReg(Register Reg, unsigned Size,
                                         unsigned &DefOperandIdx) {
-      if (Register Def = findValueFromDefImpl(Reg, 0, Size, MRI.getType(Reg))) {
+      if (Register Def = findValueFromDefImpl(Reg, 0, Size)) {
         if (auto *Unmerge = dyn_cast<GUnmerge>(MRI.getVRegDef(Def))) {
           DefOperandIdx =
               Unmerge->findRegisterDefOperandIdx(Def, /*TRI=*/nullptr);
@@ -1298,19 +1288,12 @@ class LegalizationArtifactCombiner {
     // for N >= %2.getSizeInBits() / 2
     //    %3 = G_EXTRACT %1, (N - %0.getSizeInBits()
 
-    Register DstReg = MI.getOperand(0).getReg();
     Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
     MachineInstr *MergeI = MRI.getVRegDef(SrcReg);
-    if (MergeI && MergeI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) {
-      Builder.setInstrAndDebugLoc(MI);
-      Builder.buildUndef(DstReg);
-      UpdatedDefs.push_back(DstReg);
-      markInstAndDefDead(MI, *MergeI, DeadInsts);
-      return true;
-    }
     if (!MergeI || !isa<GMergeLikeInstr>(MergeI))
       return false;
 
+    Register DstReg = MI.getOperand(0).getReg();
     LLT DstTy = MRI.getType(DstReg);
     LLT SrcTy = MRI.getType(SrcReg);
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index f8e629bc50a90..a94daa202d856 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -33,7 +33,6 @@ class LegalizerInfo;
 class MachineIRBuilder;
 class MachineInstr;
 class GISelChangeObserver;
-class LibcallLoweringInfo;
 class LostDebugLocObserver;
 
 class LLVM_ABI Legalizer : public MachineFunctionPass {
@@ -71,11 +70,11 @@ class LLVM_ABI Legalizer : public MachineFunctionPass {
 
   bool runOnMachineFunction(MachineFunction &MF) override;
 
-  static MFResult legalizeMachineFunction(
-      MachineFunction &MF, const LegalizerInfo &LI,
-      ArrayRef<GISelChangeObserver *> AuxObservers,
-      LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder,
-      const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT);
+  static MFResult
+  legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
+                          ArrayRef<GISelChangeObserver *> AuxObservers,
+                          LostDebugLocObserver &LocObserver,
+                          MachineIRBuilder &MIRBuilder, GISelValueTracking *VT);
 };
 } // End namespace llvm.
 
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 37936af6d853c..feb446291caf7 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -59,9 +59,7 @@ class LegalizerHelper {
   MachineRegisterInfo &MRI;
   const LegalizerInfo &LI;
   const TargetLowering &TLI;
-
-  const LibcallLoweringInfo *Libcalls = nullptr;
-  GISelValueTracking *VT = nullptr;
+  GISelValueTracking *VT;
 
 public:
   enum LegalizeResult {
@@ -80,16 +78,12 @@ class LegalizerHelper {
   /// Expose LegalizerInfo so the clients can re-use.
   const LegalizerInfo &getLegalizerInfo() const { return LI; }
   const TargetLowering &getTargetLowering() const { return TLI; }
-  const LibcallLoweringInfo *getLibcallLoweringInfo() { return Libcalls; }
   GISelValueTracking *getValueTracking() const { return VT; }
 
-  // FIXME: Should probably make Libcalls mandatory
   LLVM_ABI LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
-                           MachineIRBuilder &B,
-                           const LibcallLoweringInfo *Libcalls = nullptr);
+                           MachineIRBuilder &B);
   LLVM_ABI LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
                            GISelChangeObserver &Observer, MachineIRBuilder &B,
-                           const LibcallLoweringInfo *Libcalls = nullptr,
                            GISelValueTracking *VT = nullptr);
 
   /// Replace \p MI by a sequence of legal instructions that can implement the
@@ -184,38 +178,6 @@ class LegalizerHelper {
   /// def by inserting a G_BITCAST from \p CastTy
   LLVM_ABI void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
 
-  // Useful for libcalls where all operands have the same type.
-  LLVM_ABI LegalizeResult
-  simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
-                Type *OpType, LostDebugLocObserver &LocObserver) const;
-
-  /// Helper function that creates a libcall to the given \p Name using the
-  /// given calling convention \p CC.
-  LLVM_ABI LegalizeResult createLibcall(const char *Name,
-                                        const CallLowering::ArgInfo &Result,
-                                        ArrayRef<CallLowering::ArgInfo> Args,
-                                        CallingConv::ID CC,
-                                        LostDebugLocObserver &LocObserver,
-                                        MachineInstr *MI = nullptr) const;
-
-  /// Helper function that creates the given libcall.
-  LLVM_ABI LegalizeResult createLibcall(RTLIB::Libcall Libcall,
-                                        const CallLowering::ArgInfo &Result,
-                                        ArrayRef<CallLowering::ArgInfo> Args,
-                                        LostDebugLocObserver &LocObserver,
-                                        MachineInstr *MI = nullptr) const;
-
-  LLVM_ABI LegalizeResult conversionLibcall(MachineInstr &MI, Type *ToType,
-                                            Type *FromType,
-                                            LostDebugLocObserver &LocObserver,
-                                            bool IsSigned = false) const;
-  LegalizerHelper::LegalizeResult createAtomicLibcall(MachineInstr &MI) const;
-
-  /// Create a libcall to memcpy et al.
-  LLVM_ABI LegalizeResult
-  createMemLibcall(MachineRegisterInfo &MRI, MachineInstr &MI,
-                   LostDebugLocObserver &LocObserver) const;
-
 private:
   LegalizeResult
   widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
@@ -316,13 +278,17 @@ class LegalizerHelper {
                               bool IsVolatile);
 
   // Implements floating-point environment read/write via library function call.
-  LegalizeResult createGetStateLibcall(MachineInstr &MI,
+  LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder,
+                                       MachineInstr &MI,
                                        LostDebugLocObserver &LocObserver);
-  LegalizeResult createSetStateLibcall(MachineInstr &MI,
+  LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder,
+                                       MachineInstr &MI,
                                        LostDebugLocObserver &LocObserver);
-  LegalizeResult createResetStateLibcall(MachineInstr &MI,
+  LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder,
+                                         MachineInstr &MI,
                                          LostDebugLocObserver &LocObserver);
-  LegalizeResult createFCMPLibcall(MachineInstr &MI,
+  LegalizeResult createFCMPLibcall(MachineIRBuilder &MIRBuilder,
+                                   MachineInstr &MI,
                                    LostDebugLocObserver &LocObserver);
 
   MachineInstrBuilder
@@ -334,10 +300,6 @@ class LegalizerHelper {
                                    Type *OpType,
                                    LostDebugLocObserver &LocObserver);
 
-  LegalizeResult emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
-                                 unsigned Size, Type *OpType,
-                                 LostDebugLocObserver &LocObserver);
-
 public:
   /// Return the alignment to use for a stack temporary object with the given
   /// type.
@@ -477,8 +439,6 @@ class LegalizerHelper {
                                            LLT Ty);
   LLVM_ABI LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx,
                                            LLT Ty);
-  LLVM_ABI LegalizeResult narrowScalarCTLS(MachineInstr &MI, unsigned TypeIdx,
-                                           LLT Ty);
   LLVM_ABI LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx,
                                             LLT Ty);
   LLVM_ABI LegalizeResult narrowScalarFLDEXP(MachineInstr &MI, unsigned TypeIdx,
@@ -526,7 +486,6 @@ class LegalizerHelper {
   LLVM_ABI LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerFPTRUNC(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerFPOWI(MachineInstr &MI);
-  LLVM_ABI LegalizeResult lowerFMODF(MachineInstr &MI);
 
   LLVM_ABI LegalizeResult lowerISFPCLASS(MachineInstr &MI);
 
@@ -534,7 +493,6 @@ class LegalizerHelper {
   LLVM_ABI LegalizeResult lowerMinMax(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerFCopySign(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
-  LLVM_ABI LegalizeResult lowerFMinimumMaximum(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerFMad(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerIntrinsicRound(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerFFloor(MachineInstr &MI);
@@ -553,7 +511,6 @@ class LegalizerHelper {
   LLVM_ABI LegalizeResult lowerInsert(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerSADDE(MachineInstr &MI);
-  LLVM_ABI LegalizeResult lowerSSUBE(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
   LLVM_ABI LegalizeResult lowerShlSat(MachineInstr &MI);
@@ -576,6 +533,26 @@ class LegalizerHelper {
   LLVM_ABI LegalizeResult lowerVAArg(MachineInstr &MI);
 };
 
+/// Helper function that creates a libcall to the given \p Name using the given
+/// calling convention \p CC.
+LLVM_ABI LegalizerHelper::LegalizeResult
+createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
+              const CallLowering::ArgInfo &Result,
+              ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC,
+              LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
+
+/// Helper function that creates the given libcall.
+LLVM_ABI LegalizerHelper::LegalizeResult
+createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
+              const CallLowering::ArgInfo &Result,
+              ArrayRef<CallLowering::ArgInfo> Args,
+              LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr);
+
+/// Create a libcall to memcpy et al.
+LLVM_ABI LegalizerHelper::LegalizeResult
+createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+                 MachineInstr &MI, LostDebugLocObserver &LocObserver);
+
 } // End namespace llvm.
 
 #endif
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 498594f40e694..fd72a3898562e 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -115,17 +115,14 @@ struct LegalityQuery {
   struct MemDesc {
     LLT MemoryTy;
     uint64_t AlignInBits;
-    AtomicOrdering Ordering; //< For cmpxchg this is the success ordering.
-    AtomicOrdering FailureOrdering; //< For cmpxchg, otherwise NotAtomic.
+    AtomicOrdering Ordering;
 
     MemDesc() = default;
-    MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering,
-            AtomicOrdering FailureOrdering)
-        : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering),
-          FailureOrdering(FailureOrdering) {}
+    MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering)
+        : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering) {}
     MemDesc(const MachineMemOperand &MMO)
         : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8,
-                  MMO.getSuccessOrdering(), MMO.getFailureOrdering()) {}
+                  MMO.getSuccessOrdering()) {}
   };
 
   /// Operations which require memory can use this to place requirements on the
@@ -314,16 +311,6 @@ LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
 LLVM_ABI LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx,
                                                    unsigned Size);
 
-/// True iff the specified type index is a vector with a number of elements
-/// that's greater than the given size.
-LLVM_ABI LegalityPredicate vectorElementCountIsGreaterThan(unsigned TypeIdx,
-                                                           unsigned Size);
-
-/// True iff the specified type index is a vector with a number of elements
-/// that's less than or equal to the given size.
-LLVM_ABI LegalityPredicate
-vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx, unsigned Size);
-
 /// True iff the specified type index is a scalar or a vector with an element
 /// type that's wider than the given size.
 LLVM_ABI LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx,
@@ -393,8 +380,7 @@ LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx,
 
 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
 /// elements from \p Ty.
-LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx,
-                                               ElementCount EC);
+LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
 
 /// Change the scalar size or element size to have the same scalar size as type
 /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
@@ -757,14 +743,6 @@ class LegalizeRuleSet {
     return actionFor(LegalizeAction::Lower, Types);
   }
   /// The instruction is lowered when type indexes 0 and 1 is any type pair in
-  /// the given list, provided Predicate pred is true.
-  LegalizeRuleSet &lowerFor(bool Pred,
-                            std::initializer_list<std::pair<LLT, LLT>> Types) {
-    if (!Pred)
-      return *this;
-    return actionFor(LegalizeAction::Lower, Types);
-  }
-  /// The instruction is lowered when type indexes 0 and 1 is any type pair in
   /// the given list.
   LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
                             LegalizeMutation Mutation) {
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index 8db99ba4ed883..b7ccfbb27e51c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -210,8 +210,8 @@ struct SpecificConstantMatch {
 };
 
 /// Matches a constant equal to \p RequestedValue.
-inline SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue) {
-  return SpecificConstantMatch(RequestedValue);
+inline SpecificConstantMatch m_SpecificICst(APInt RequestedValue) {
+  return SpecificConstantMatch(std::move(RequestedValue));
 }
 
 inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
@@ -221,7 +221,7 @@ inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
 /// Matcher for a specific constant splat.
 struct SpecificConstantSplatMatch {
   APInt RequestedVal;
-  SpecificConstantSplatMatch(const APInt &RequestedVal)
+  SpecificConstantSplatMatch(const APInt RequestedVal)
       : RequestedVal(RequestedVal) {}
   bool match(const MachineRegisterInfo &MRI, Register Reg) {
     return isBuildVectorConstantSplat(Reg, MRI, RequestedVal,
@@ -230,9 +230,8 @@ struct SpecificConstantSplatMatch {
 };
 
 /// Matches a constant splat of \p RequestedValue.
-inline SpecificConstantSplatMatch
-m_SpecificICstSplat(const APInt &RequestedValue) {
-  return SpecificConstantSplatMatch(RequestedValue);
+inline SpecificConstantSplatMatch m_SpecificICstSplat(APInt RequestedValue) {
+  return SpecificConstantSplatMatch(std::move(RequestedValue));
 }
 
 inline SpecificConstantSplatMatch m_SpecificICstSplat(int64_t RequestedValue) {
@@ -243,7 +242,7 @@ inline SpecificConstantSplatMatch m_SpecificICstSplat(int64_t RequestedValue) {
 /// Matcher for a specific constant or constant splat.
 struct SpecificConstantOrSplatMatch {
   APInt RequestedVal;
-  SpecificConstantOrSplatMatch(const APInt &RequestedVal)
+  SpecificConstantOrSplatMatch(const APInt RequestedVal)
       : RequestedVal(RequestedVal) {}
   bool match(const MachineRegisterInfo &MRI, Register Reg) {
     APInt MatchedVal;
@@ -264,8 +263,8 @@ struct SpecificConstantOrSplatMatch {
 /// Matches a \p RequestedValue constant or a constant splat of \p
 /// RequestedValue.
 inline SpecificConstantOrSplatMatch
-m_SpecificICstOrSplat(const APInt &RequestedValue) {
-  return SpecificConstantOrSplatMatch(RequestedValue);
+m_SpecificICstOrSplat(APInt RequestedValue) {
+  return SpecificConstantOrSplatMatch(std::move(RequestedValue));
 }
 
 inline SpecificConstantOrSplatMatch
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 5114e979e58ea..99d3cd0aac85c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -56,7 +56,6 @@ struct MachineIRBuilderState {
   MDNode *PCSections = nullptr;
   /// MMRA Metadata to be set on any instruction we create.
   MDNode *MMRA = nullptr;
-  Value *DS = nullptr;
 
   /// \name Fields describing the insertion point.
   /// @{
@@ -370,7 +369,6 @@ class LLVM_ABI MachineIRBuilder {
     State.II = MI.getIterator();
     setPCSections(MI.getPCSections());
     setMMRAMetadata(MI.getMMRAMetadata());
-    setDeactivationSymbol(MI.getDeactivationSymbol());
   }
   /// @}
 
@@ -407,9 +405,6 @@ class LLVM_ABI MachineIRBuilder {
   /// Set the PC sections metadata to \p MD for all the next build instructions.
   void setMMRAMetadata(MDNode *MMRA) { State.MMRA = MMRA; }
 
-  Value *getDeactivationSymbol() { return State.DS; }
-  void setDeactivationSymbol(Value *DS) { State.DS = DS; }
-
   /// Get the current instruction's MMRA metadata.
   MDNode *getMMRAMetadata() { return State.MMRA; }
 
@@ -2063,11 +2058,6 @@ class LLVM_ABI MachineIRBuilder {
     return buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {Dst}, {Src0});
   }
 
-  /// Build and insert \p Res = G_CTLS \p Op0, \p Src0
-  MachineInstrBuilder buildCTLS(const DstOp &Dst, const SrcOp &Src0) {
-    return buildInstr(TargetOpcode::G_CTLS, {Dst}, {Src0});
-  }
-
   /// Build and insert \p Dst = G_BSWAP \p Src0
   MachineInstrBuilder buildBSwap(const DstOp &Dst, const SrcOp &Src0) {
     return buildInstr(TargetOpcode::G_BSWAP, {Dst}, {Src0});
@@ -2194,18 +2184,10 @@ class LLVM_ABI MachineIRBuilder {
     return buildInstr(TargetOpcode::G_FSINCOS, {Sin, Cos}, {Src}, Flags);
   }
 
-  /// Build and insert \p Fract, \p Int = G_FMODF \p Src
-  MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int,
-                                const SrcOp &Src,
-                                std::optional<unsigned> Flags = std::nullopt) {
-    return buildInstr(TargetOpcode::G_FMODF, {Fract, Int}, {Src}, Flags);
-  }
-
   /// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
-  MachineInstrBuilder
-  buildFCopysign(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1,
-                 std::optional<unsigned> Flags = std::nullopt) {
-    return buildInstr(TargetOpcode::G_FCOPYSIGN, {Dst}, {Src0, Src1}, Flags);
+  MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
+                                     const SrcOp &Src1) {
+    return buildInstr(TargetOpcode::G_FCOPYSIGN, {Dst}, {Src0, Src1});
   }
 
   /// Build and insert \p Res = G_UITOFP \p Src0
@@ -2481,11 +2463,6 @@ class LLVM_ABI MachineIRBuilder {
     return buildInstr(TargetOpcode::G_GET_ROUNDING, {Dst}, {});
   }
 
-  /// Build and insert G_SET_ROUNDING
-  MachineInstrBuilder buildSetRounding(const SrcOp &Src) {
-    return buildInstr(TargetOpcode::G_SET_ROUNDING, {}, {Src});
-  }
-
   virtual MachineInstrBuilder
   buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps, ArrayRef<SrcOp> SrcOps,
              std::optional<unsigned> Flags = std::nullopt);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
index 6060bb6144c62..076c70d21bbdf 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
@@ -510,6 +510,9 @@ class RegBankSelect : public MachineFunctionPass {
   /// Optimization mode of the pass.
   Mode OptMode;
 
+  /// Current target configuration. Controls how the pass handles errors.
+  const TargetPassConfig *TPC;
+
   /// Assign the register bank of each operand of \p MI.
   /// \return True on success, false otherwise.
   bool assignInstr(MachineInstr &MI);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index de6606e7ed14a..e1aa8eceefd3f 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -132,10 +132,12 @@ LLVM_ABI Register constrainOperandRegClass(
 /// generic) virtual register operands to the instruction's register class.
 /// This could involve inserting COPYs before (for uses) or after (for defs).
 /// This requires the number of operands to match the instruction description.
+/// \returns whether operand regclass constraining succeeded.
+///
 // FIXME: Not all instructions have the same number of operands. We should
 // probably expose a constrain helper per operand and let the target selector
 // constrain individual registers, like fast-isel.
-LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I,
+LLVM_ABI bool constrainSelectedInstRegOperands(MachineInstr &I,
                                                const TargetInstrInfo &TII,
                                                const TargetRegisterInfo &TRI,
                                                const RegisterBankInfo &RBI);
@@ -153,10 +155,12 @@ LLVM_ABI bool isTriviallyDead(const MachineInstr &MI,
 /// Report an ISel error as a missed optimization remark to the LLVMContext's
 /// diagnostic stream.  Set the FailedISel MachineFunction property.
 LLVM_ABI void reportGISelFailure(MachineFunction &MF,
+                                 const TargetPassConfig &TPC,
                                  MachineOptimizationRemarkEmitter &MORE,
                                  MachineOptimizationRemarkMissed &R);
 
 LLVM_ABI void reportGISelFailure(MachineFunction &MF,
+                                 const TargetPassConfig &TPC,
                                  MachineOptimizationRemarkEmitter &MORE,
                                  const char *PassName, StringRef Msg,
                                  const MachineInstr &MI);
@@ -164,6 +168,7 @@ LLVM_ABI void reportGISelFailure(MachineFunction &MF,
 /// Report an ISel warning as a missed optimization remark to the LLVMContext's
 /// diagnostic stream.
 LLVM_ABI void reportGISelWarning(MachineFunction &MF,
+                                 const TargetPassConfig &TPC,
                                  MachineOptimizationRemarkEmitter &MORE,
                                  MachineOptimizationRemarkMissed &R);
 



More information about the llvm-commits mailing list