[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