[llvm] [GlobalISel] Drop poison flags by default in combiners (PR #218306)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 25 07:20:18 PDT 2026
https://github.com/Michael-Chen-NJU updated https://github.com/llvm/llvm-project/pull/218306
>From e42d2c2f51f9ed4aed8108f755d188f5285ef07c Mon Sep 17 00:00:00 2001
From: Michael-Chen-NJU <2802328816 at qq.com>
Date: Mon, 24 Aug 2026 10:21:50 +0800
Subject: [PATCH 1/2] [GlobalISel] Drop poison flags by default in combiners
---
.../llvm/CodeGen/GlobalISel/Combiner.h | 2 +
.../CodeGen/GlobalISel/GIMatchTableExecutor.h | 5 +
.../GlobalISel/GIMatchTableExecutorImpl.h | 5 +-
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 12 +-
.../AArch64/GlobalISel/combine-add.mir | 28 +++
.../AArch64/GlobalISel/combine-integer.mir | 197 ++++++++++++++++++
6 files changed, 245 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
index bd9a526eae606..bb4c7be459753 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
@@ -67,6 +67,8 @@ class LLVM_ABI Combiner : public GIMatchTableExecutor {
protected:
virtual bool canMatchOpcode(unsigned Opc) const { return true; }
+ bool shouldDropRootPoisonGeneratingFlags() const override { return true; }
+
const CombinerInfo &CInfo;
GISelChangeObserver &Observer;
MachineIRBuilder &B;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 6e3ccf1923c40..ccce4b79f4419 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -739,6 +739,11 @@ class GIMatchTableExecutor {
llvm_unreachable("Subclass does not implement runCustomAction!");
}
+ /// Return true to drop root poison-generating flags from the implicit flag
+ /// propagation performed for newly-built instructions. Explicit MIFlags
+ /// actions in the match table still apply to the output instruction.
+ virtual bool shouldDropRootPoisonGeneratingFlags() const { return false; }
+
LLVM_ABI bool isOperandImmEqual(const MachineOperand &MO, int64_t Value,
const MachineRegisterInfo &MRI,
bool Splat = false) const;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index e0720928c6526..1eb6715c4a249 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -58,7 +59,9 @@ bool GIMatchTableExecutor::executeMatchTable(
// Bypass the flag check on the instruction, and only look at the MCInstrDesc.
bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
- const uint32_t Flags = State.MIs[0]->getFlags();
+ uint32_t Flags = State.MIs[0]->getFlags();
+ if (shouldDropRootPoisonGeneratingFlags())
+ Flags &= ~GenericMachineInstr::getPoisonGeneratingFlags();
bool BuilderInitialized = false;
const auto initializeBuilder = [&]() {
if (BuilderInitialized)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 6daa7f3808f43..1a24434bb388f 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -26,7 +26,7 @@ namespace llvm {
/// A base class for all GenericMachineInstrs.
class GenericMachineInstr : public MachineInstr {
- constexpr static unsigned PoisonFlags =
+ constexpr static unsigned PoisonGeneratingFlags =
NoUWrap | NoSWrap | NoUSWrap | IsExact | Disjoint | NonNeg | FmNoNans |
FmNoInfs | SameSign | InBounds;
@@ -41,10 +41,16 @@ class GenericMachineInstr : public MachineInstr {
return isPreISelGenericOpcode(MI->getOpcode());
}
- bool hasPoisonGeneratingFlags() const { return getFlags() & PoisonFlags; }
+ static constexpr unsigned getPoisonGeneratingFlags() {
+ return PoisonGeneratingFlags;
+ }
+
+ bool hasPoisonGeneratingFlags() const {
+ return getFlags() & PoisonGeneratingFlags;
+ }
void dropPoisonGeneratingFlags() {
- clearFlags(PoisonFlags);
+ clearFlags(PoisonGeneratingFlags);
assert(!hasPoisonGeneratingFlags());
}
};
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir
index 1bf856cd6f704..2c06724978f05 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir
@@ -359,6 +359,34 @@ body: |
RET_ReallyLR implicit $w0
...
+---
+name: add_shl_neg_nuw
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1, $w2
+
+ ; CHECK-LABEL: name: add_shl_neg_nuw
+ ; CHECK: liveins: $w0, $w1, $w2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $w1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(i32) = COPY $w2
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[COPY1]], [[COPY2]](i32)
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(i32) = G_SUB [[COPY]], [[SHL]]
+ ; CHECK-NEXT: $w0 = COPY [[SUB]](i32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(i32) = COPY $w0
+ %1:_(i32) = COPY $w1
+ %2:_(i32) = COPY $w2
+ %3:_(i32) = G_CONSTANT i32 0
+ %4:_(i32) = G_SUB %3, %1
+ %5:_(i32) = G_SHL %4, %2
+ %6:_(i32) = nuw G_ADD %0, %5
+ $w0 = COPY %6
+ RET_ReallyLR implicit $w0
+...
+
---
name: add_shl_neg_commuted
tracksRegLiveness: true
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index 3de9527bb3584..3f57fb256873d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -24,6 +24,29 @@ body: |
$x0 = COPY %sub
RET_ReallyLR implicit $x0
+...
+---
+name: APlusBMinusCMinusB_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+ ; CHECK-LABEL: name: APlusBMinusCMinusB_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(i64) = COPY $x0
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: %sub:_(i64) = G_SUB %a, %c
+ ; CHECK-NEXT: $x0 = COPY %sub(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %sub1:_(i64) = G_SUB %b, %c
+ %add1:_(i64) = G_ADD %a, %sub1
+ %sub:_(i64) = nuw G_SUB %add1, %b
+ $x0 = COPY %sub
+ RET_ReallyLR implicit $x0
+
...
---
name: AMinusBMinusCMinusC
@@ -47,6 +70,29 @@ body: |
$x0 = COPY %sub
RET_ReallyLR implicit $x0
+...
+---
+name: AMinusBMinusCMinusC_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+ ; CHECK-LABEL: name: AMinusBMinusCMinusC_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(i64) = COPY $x0
+ ; CHECK-NEXT: %b:_(i64) = COPY $x1
+ ; CHECK-NEXT: %sub:_(i64) = G_SUB %a, %b
+ ; CHECK-NEXT: $x0 = COPY %sub(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %sub1:_(i64) = G_SUB %b, %c
+ %sub2:_(i64) = G_SUB %a, %sub1
+ %sub:_(i64) = nuw G_SUB %sub2, %c
+ $x0 = COPY %sub
+ RET_ReallyLR implicit $x0
+
...
---
name: ZeroMinusAPlusB
@@ -190,6 +236,31 @@ body: |
$x0 = COPY %add
RET_ReallyLR implicit $x0
+...
+---
+name: AMinusBPlusCMinusA_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; CHECK-LABEL: name: AMinusBPlusCMinusA_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %b:_(i64) = COPY $x1
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: %add:_(i64) = G_SUB %c, %b
+ ; CHECK-NEXT: $x0 = COPY %add(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %zero:_(i64) = G_CONSTANT i64 0
+ %sub2:_(i64) = G_SUB %c, %a
+ %sub1:_(i64) = G_SUB %a, %b
+ %add:_(i64) = nuw G_ADD %sub1, %sub2
+ $x0 = COPY %add
+ RET_ReallyLR implicit $x0
+
...
---
name: AMinusBPlusBMinusC
@@ -216,6 +287,32 @@ body: |
RET_ReallyLR implicit $x0
+...
+---
+name: AMinusBPlusBMinusC_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; CHECK-LABEL: name: AMinusBPlusBMinusC_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(i64) = COPY $x0
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: %add:_(i64) = G_SUB %a, %c
+ ; CHECK-NEXT: $x0 = COPY %add(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %zero:_(i64) = G_CONSTANT i64 0
+ %sub2:_(i64) = G_SUB %b, %c
+ %sub1:_(i64) = G_SUB %a, %b
+ %add:_(i64) = nuw G_ADD %sub1, %sub2
+ $x0 = COPY %add
+ RET_ReallyLR implicit $x0
+
+
...
---
name: APlusBMinusAplusC
@@ -241,6 +338,31 @@ body: |
$x0 = COPY %add
RET_ReallyLR implicit $x0
+...
+---
+name: APlusBMinusAplusC_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; CHECK-LABEL: name: APlusBMinusAplusC_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %b:_(i64) = COPY $x1
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: %add:_(i64) = G_SUB %b, %c
+ ; CHECK-NEXT: $x0 = COPY %add(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %zero:_(i64) = G_CONSTANT i64 0
+ %add1:_(i64) = G_ADD %a, %c
+ %sub1:_(i64) = G_SUB %b, %add1
+ %add:_(i64) = nuw G_ADD %a, %sub1
+ $x0 = COPY %add
+ RET_ReallyLR implicit $x0
+
...
---
name: APlusBMinusCPlusA
@@ -266,6 +388,31 @@ body: |
$x0 = COPY %add
RET_ReallyLR implicit $x0
+...
+---
+name: APlusBMinusCPlusA_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; CHECK-LABEL: name: APlusBMinusCPlusA_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %b:_(i64) = COPY $x1
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: %add:_(i64) = G_SUB %b, %c
+ ; CHECK-NEXT: $x0 = COPY %add(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %zero:_(i64) = G_CONSTANT i64 0
+ %add1:_(i64) = G_ADD %c, %a
+ %sub1:_(i64) = G_SUB %b, %add1
+ %add:_(i64) = nuw G_ADD %a, %sub1
+ $x0 = COPY %add
+ RET_ReallyLR implicit $x0
+
...
---
name: APlusBMinusCPlusA_BV
@@ -496,6 +643,56 @@ body: |
$x0 = COPY %sub2
RET_ReallyLR implicit $x0
+...
+---
+name: AMinusBMinusC_nuw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; CHECK-LABEL: name: AMinusBMinusC_nuw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(i64) = COPY $x0
+ ; CHECK-NEXT: %b:_(i64) = COPY $x1
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(i64) = G_SUB %c, %b
+ ; CHECK-NEXT: %sub2:_(i64) = G_ADD %a, [[SUB]]
+ ; CHECK-NEXT: $x0 = COPY %sub2(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %sub1:_(i64) = G_SUB %b, %c
+ %sub2:_(i64) = nuw G_SUB %a, %sub1
+ $x0 = COPY %sub2
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: AMinusBMinusC_nsw
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; CHECK-LABEL: name: AMinusBMinusC_nsw
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(i64) = COPY $x0
+ ; CHECK-NEXT: %b:_(i64) = COPY $x1
+ ; CHECK-NEXT: %c:_(i64) = COPY $x2
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(i64) = G_SUB %c, %b
+ ; CHECK-NEXT: %sub2:_(i64) = G_ADD %a, [[SUB]]
+ ; CHECK-NEXT: $x0 = COPY %sub2(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(i64) = COPY $x0
+ %b:_(i64) = COPY $x1
+ %c:_(i64) = COPY $x2
+ %sub1:_(i64) = G_SUB %b, %c
+ %sub2:_(i64) = nsw G_SUB %a, %sub1
+ $x0 = COPY %sub2
+ RET_ReallyLR implicit $x0
+
...
---
name: AMinusZeroMinusB
>From 0e564fbd1ffb0491fd4929a019e83cbbaf741ada Mon Sep 17 00:00:00 2001
From: Michael-Chen-NJU <2802328816 at qq.com>
Date: Tue, 25 Aug 2026 16:12:51 +0800
Subject: [PATCH 2/2] [GlobalISel] Encode combiner flag drops in match tables
---
.../llvm/CodeGen/GlobalISel/Combiner.h | 2 -
.../CodeGen/GlobalISel/GIMatchTableExecutor.h | 10 +-
.../GlobalISel/GIMatchTableExecutorImpl.h | 28 +++-
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 12 +-
.../include/llvm/Target/GlobalISel/Combine.td | 3 +
.../builtins/match-table-replacerreg.td | 1 +
.../match-table-cxx.td | 10 +-
.../match-table-hoisting-cxx.td | 96 +++++------
.../match-table-hoisting.td | 70 ++++----
.../match-table-imms.td | 3 +
.../match-table-intrinsics.td | 6 +-
.../match-table-miflags.td | 5 +-
.../match-table-operand-types.td | 8 +-
.../match-table-patfrag-root.td | 3 +
.../match-table-permutations.td | 54 +++----
.../match-table-typeof.td | 8 +-
.../match-table-variadics.td | 13 +-
.../GlobalISelCombinerEmitter/match-table.td | 13 +-
.../pattern-parsing.td | 4 +-
.../GlobalISel/GIMatchTableExecutorTest.cpp | 149 ++++++++++++++++++
.../Common/GlobalISel/MatchTable/Matchers.cpp | 9 ++
.../Common/GlobalISel/MatchTable/Matchers.h | 8 +
.../TableGen/GlobalISelCombinerEmitter.cpp | 16 ++
23 files changed, 375 insertions(+), 156 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
index bb4c7be459753..bd9a526eae606 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Combiner.h
@@ -67,8 +67,6 @@ class LLVM_ABI Combiner : public GIMatchTableExecutor {
protected:
virtual bool canMatchOpcode(unsigned Opc) const { return true; }
- bool shouldDropRootPoisonGeneratingFlags() const override { return true; }
-
const CombinerInfo &CInfo;
GISelChangeObserver &Observer;
MachineIRBuilder &B;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index ccce4b79f4419..7fb9891ac4b6f 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -515,7 +515,12 @@ enum {
/// Calls a C++ function that concludes the current match.
/// The C++ function is free to return false and reject the match, or
/// return true and mutate the instruction(s) (or do nothing, even).
+ /// Any instructions added to OutMIs should be newly-created outputs. Custom
+ /// actions that set flags on those instructions before returning explicitly
+ /// opt in to preserving those flags.
/// - FnID(2) - The function to call.
+ /// - InitialUnsetFlags(4) - Flags to clear from implicit root flag
+ /// propagation for instructions added to OutMIs by the function.
GIR_DoneWithCustomAction,
/// Render operands to the specified instruction using a custom function,
@@ -739,11 +744,6 @@ class GIMatchTableExecutor {
llvm_unreachable("Subclass does not implement runCustomAction!");
}
- /// Return true to drop root poison-generating flags from the implicit flag
- /// propagation performed for newly-built instructions. Explicit MIFlags
- /// actions in the match table still apply to the output instruction.
- virtual bool shouldDropRootPoisonGeneratingFlags() const { return false; }
-
LLVM_ABI bool isOperandImmEqual(const MachineOperand &MO, int64_t Value,
const MachineRegisterInfo &MRI,
bool Splat = false) const;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 1eb6715c4a249..82abb1d7cbd08 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -18,7 +18,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
-#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -59,9 +58,8 @@ bool GIMatchTableExecutor::executeMatchTable(
// Bypass the flag check on the instruction, and only look at the MCInstrDesc.
bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
- uint32_t Flags = State.MIs[0]->getFlags();
- if (shouldDropRootPoisonGeneratingFlags())
- Flags &= ~GenericMachineInstr::getPoisonGeneratingFlags();
+ const uint32_t Flags = State.MIs[0]->getFlags();
+ SmallVector<uint32_t, 4> OutMIUnsetFlags;
bool BuilderInitialized = false;
const auto initializeBuilder = [&]() {
if (BuilderInitialized)
@@ -86,10 +84,13 @@ bool GIMatchTableExecutor::executeMatchTable(
};
const auto propagateFlags = [&]() {
- for (auto MIB : OutMIs) {
+ OutMIUnsetFlags.resize(OutMIs.size());
+ for (unsigned I = 0, E = OutMIs.size(); I != E; ++I) {
+ MachineInstrBuilder MIB = OutMIs[I];
// Set the NoFPExcept flag when no original matched instruction could
// raise an FP exception, but the new instruction potentially might.
uint32_t MIBFlags = Flags | MIB.getInstr()->getFlags();
+ MIBFlags &= ~OutMIUnsetFlags[I];
if (NoFPException && MIB->mayRaiseFPException())
MIBFlags |= MachineInstr::NoFPExcept;
if (Observer)
@@ -1085,6 +1086,8 @@ bool GIMatchTableExecutor::executeMatchTable(
uint32_t NewOpcode = readU16();
if (NewInsnID >= OutMIs.size())
OutMIs.resize(NewInsnID + 1);
+ if (NewInsnID >= OutMIUnsetFlags.size())
+ OutMIUnsetFlags.resize(NewInsnID + 1);
MachineInstr *OldMI = State.MIs[OldInsnID];
if (Observer)
@@ -1106,6 +1109,8 @@ bool GIMatchTableExecutor::executeMatchTable(
uint32_t Opcode = readU16();
if (NewInsnID >= OutMIs.size())
OutMIs.resize(NewInsnID + 1);
+ if (NewInsnID >= OutMIUnsetFlags.size())
+ OutMIUnsetFlags.resize(NewInsnID + 1);
initializeBuilder();
OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
@@ -1258,6 +1263,8 @@ bool GIMatchTableExecutor::executeMatchTable(
<< InsnID << "], " << Flags << ")\n");
MachineInstr *MI = OutMIs[InsnID];
MI->setFlags(MI->getFlags() | Flags);
+ OutMIUnsetFlags.resize(OutMIs.size());
+ OutMIUnsetFlags[InsnID] &= ~Flags;
break;
}
case GIR_UnsetMIFlags: {
@@ -1269,6 +1276,8 @@ bool GIMatchTableExecutor::executeMatchTable(
<< InsnID << "], " << Flags << ")\n");
MachineInstr *MI = OutMIs[InsnID];
MI->setFlags(MI->getFlags() & ~Flags);
+ OutMIUnsetFlags.resize(OutMIs.size());
+ OutMIUnsetFlags[InsnID] |= Flags;
break;
}
case GIR_CopyMIFlags: {
@@ -1279,7 +1288,10 @@ bool GIMatchTableExecutor::executeMatchTable(
dbgs() << CurrentIdx << ": GIR_CopyMIFlags(OutMIs["
<< InsnID << "], MIs[" << OldInsnID << "])\n");
MachineInstr *MI = OutMIs[InsnID];
- MI->setFlags(MI->getFlags() | State.MIs[OldInsnID]->getFlags());
+ uint32_t Flags = State.MIs[OldInsnID]->getFlags();
+ MI->setFlags(MI->getFlags() | Flags);
+ OutMIUnsetFlags.resize(OutMIs.size());
+ OutMIUnsetFlags[InsnID] &= ~Flags;
break;
}
case GIR_AddSimpleTempRegister:
@@ -1432,11 +1444,15 @@ bool GIMatchTableExecutor::executeMatchTable(
}
case GIR_DoneWithCustomAction: {
uint16_t FnID = readU16();
+ uint32_t InitialUnsetFlags = readU32();
DEBUG_WITH_TYPE(TgtExecutor::getName(),
dbgs() << CurrentIdx << ": GIR_DoneWithCustomAction(FnID="
<< FnID << ")\n");
assert(FnID > GICXXCustomAction_Invalid && "Expected a valid FnID");
if (runCustomAction(FnID, State, OutMIs)) {
+ OutMIUnsetFlags.resize(OutMIs.size());
+ for (unsigned I = 0, E = OutMIs.size(); I != E; ++I)
+ OutMIUnsetFlags[I] |= InitialUnsetFlags & ~OutMIs[I]->getFlags();
propagateFlags();
return true;
}
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 1a24434bb388f..6daa7f3808f43 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -26,7 +26,7 @@ namespace llvm {
/// A base class for all GenericMachineInstrs.
class GenericMachineInstr : public MachineInstr {
- constexpr static unsigned PoisonGeneratingFlags =
+ constexpr static unsigned PoisonFlags =
NoUWrap | NoSWrap | NoUSWrap | IsExact | Disjoint | NonNeg | FmNoNans |
FmNoInfs | SameSign | InBounds;
@@ -41,16 +41,10 @@ class GenericMachineInstr : public MachineInstr {
return isPreISelGenericOpcode(MI->getOpcode());
}
- static constexpr unsigned getPoisonGeneratingFlags() {
- return PoisonGeneratingFlags;
- }
-
- bool hasPoisonGeneratingFlags() const {
- return getFlags() & PoisonGeneratingFlags;
- }
+ bool hasPoisonGeneratingFlags() const { return getFlags() & PoisonFlags; }
void dropPoisonGeneratingFlags() {
- clearFlags(PoisonGeneratingFlags);
+ clearFlags(PoisonFlags);
assert(!hasPoisonGeneratingFlags());
}
};
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index e0f665e85c2cc..a7f2c305b788e 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -193,7 +193,10 @@ def FmReassoc : MIFlagEnum<"FmReassoc">;
def IsExact : MIFlagEnum<"IsExact">;
def NoSWrap : MIFlagEnum<"NoSWrap">;
def NoUWrap : MIFlagEnum<"NoUWrap">;
+def NoUSWrap : MIFlagEnum<"NoUSWrap">;
+def Disjoint : MIFlagEnum<"Disjoint">;
def NonNeg : MIFlagEnum<"NonNeg">;
+def SameSign : MIFlagEnum<"SameSign">;
def InBounds : MIFlagEnum<"InBounds">;
def MIFlags;
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/match-table-replacerreg.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/match-table-replacerreg.td
index 850c04130b865..28d135e8af3dc 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/match-table-replacerreg.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/match-table-replacerreg.td
@@ -54,6 +54,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // y
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_ReplaceRegWithTempReg, /*OldInsnID*/0, /*OldOpIdx*/1, /*TempRegID*/0,
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 3: @[[L529]]
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
index b226071598056..c5823a8942c5d 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
@@ -123,7 +123,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] y
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #3: NoMatchTwoApply
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 7: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 2: @{{[0-9]+}}
@@ -134,7 +134,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] y
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #4: CombineCXXOrder
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner3),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner3), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 8: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 3: @{{[0-9]+}}
@@ -145,7 +145,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #1: TwoMatchTwoApply
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 9: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 4: @{{[0-9]+}}
@@ -156,11 +156,11 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #0: OneMatchOneApply
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 10: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 5: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: }; // Size: 537 bytes
+// CHECK-NEXT: }; // Size: 553 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting-cxx.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting-cxx.td
index a7e0360921803..220dc232973a4 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting-cxx.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting-cxx.td
@@ -39,9 +39,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: /* 0 */ GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(198),
+// CHECK-NEXT: /* 0 */ GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(222),
// CHECK-NEXT: /* 5 */ GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SUB),
-// CHECK-NEXT: /* 9 */ GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4(103), // Rule ID 1 //
+// CHECK-NEXT: /* 9 */ GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4(115), // Rule ID 1 //
// CHECK-NEXT: /* 14 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
// CHECK-NEXT: /* 17 */ // MIs[0] root
// CHECK-NEXT: /* 17 */ GIM_RecordRegType, /*MI*/0, /*Op*/0, /*TempTypeIdx*/255,
@@ -69,49 +69,53 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: /* 75 */ GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
// CHECK-NEXT: /* 80 */ GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/1,
// CHECK-NEXT: /* 83 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // A
-// CHECK-NEXT: /* 87 */ GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SMIN),
-// CHECK-NEXT: /* 91 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // root
-// CHECK-NEXT: /* 95 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // A
-// CHECK-NEXT: /* 99 */ GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
-// CHECK-NEXT: /* 102 */ GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: /* 103 */ // Label 1: @103
-// CHECK-NEXT: /* 103 */ GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4(197), // Rule ID 0 //
-// CHECK-NEXT: /* 108 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
-// CHECK-NEXT: /* 111 */ // MIs[0] root
-// CHECK-NEXT: /* 111 */ GIM_RecordRegType, /*MI*/0, /*Op*/0, /*TempTypeIdx*/255,
-// CHECK-NEXT: /* 115 */ // MIs[0] Operand 1
-// CHECK-NEXT: /* 115 */ GIM_CheckConstantInt8, /*MI*/0, /*Op*/1, 0,
-// CHECK-NEXT: /* 119 */ // MIs[0] max
-// CHECK-NEXT: /* 119 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, // MIs[1]
-// CHECK-NEXT: /* 123 */ GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_UMAX),
-// CHECK-NEXT: /* 127 */ // MIs[1] A
-// CHECK-NEXT: /* 127 */ // No operand predicates
-// CHECK-NEXT: /* 127 */ // MIs[1] sub
-// CHECK-NEXT: /* 127 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/2, /*MI*/1, /*OpIdx*/2, // MIs[2]
-// CHECK-NEXT: /* 131 */ GIM_CheckOpcode, /*MI*/2, GIMT_Encode2(TargetOpcode::G_SUB),
-// CHECK-NEXT: /* 135 */ // MIs[2] Operand 1
-// CHECK-NEXT: /* 135 */ GIM_CheckConstantInt8, /*MI*/2, /*Op*/1, 0,
-// CHECK-NEXT: /* 139 */ // MIs[2] A
-// CHECK-NEXT: /* 139 */ GIM_CheckIsSameOperandIgnoreCopies, /*MI*/2, /*OpIdx*/2, /*OtherMI*/1, /*OtherOpIdx*/1,
-// CHECK-NEXT: /* 144 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
-// CHECK-NEXT: /* 148 */ GIM_CheckIsSafeToFold, /*NumInsns*/2,
-// CHECK-NEXT: /* 150 */ GIR_MakeTempReg, /*TempRegID*/1, /*TypeID*/255,
-// CHECK-NEXT: /* 153 */ GIR_BuildConstant, /*TempRegID*/1, /*Val*/GIMT_Encode8(0),
-// CHECK-NEXT: /* 163 */ GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/255,
-// CHECK-NEXT: /* 166 */ // Combiner Rule #0: SharedCXXPred0
-// CHECK-NEXT: /* 166 */ GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SUB),
-// CHECK-NEXT: /* 169 */ GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
-// CHECK-NEXT: /* 174 */ GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/1,
-// CHECK-NEXT: /* 177 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // A
-// CHECK-NEXT: /* 181 */ GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_UMIN),
-// CHECK-NEXT: /* 185 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // root
-// CHECK-NEXT: /* 189 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // A
-// CHECK-NEXT: /* 193 */ GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
-// CHECK-NEXT: /* 196 */ GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: /* 197 */ // Label 2: @197
-// CHECK-NEXT: /* 197 */ GIM_Reject,
-// CHECK-NEXT: /* 198 */ // Label 0: @198
-// CHECK-NEXT: /* 198 */ GIM_Reject,
-// CHECK-NEXT: /* 199 */ }; // Size: 199 bytes
+// CHECK-NEXT: /* 87 */ GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: /* 93 */ GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SMIN),
+// CHECK-NEXT: /* 97 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // root
+// CHECK-NEXT: /* 101 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // A
+// CHECK-NEXT: /* 105 */ GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
+// CHECK-NEXT: /* 108 */ GIR_UnsetMIFlags, /*InsnID*/1, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: /* 114 */ GIR_EraseRootFromParent_Done,
+// CHECK-NEXT: /* 115 */ // Label 1: @115
+// CHECK-NEXT: /* 115 */ GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4(221), // Rule ID 0 //
+// CHECK-NEXT: /* 120 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
+// CHECK-NEXT: /* 123 */ // MIs[0] root
+// CHECK-NEXT: /* 123 */ GIM_RecordRegType, /*MI*/0, /*Op*/0, /*TempTypeIdx*/255,
+// CHECK-NEXT: /* 127 */ // MIs[0] Operand 1
+// CHECK-NEXT: /* 127 */ GIM_CheckConstantInt8, /*MI*/0, /*Op*/1, 0,
+// CHECK-NEXT: /* 131 */ // MIs[0] max
+// CHECK-NEXT: /* 131 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, // MIs[1]
+// CHECK-NEXT: /* 135 */ GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_UMAX),
+// CHECK-NEXT: /* 139 */ // MIs[1] A
+// CHECK-NEXT: /* 139 */ // No operand predicates
+// CHECK-NEXT: /* 139 */ // MIs[1] sub
+// CHECK-NEXT: /* 139 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/2, /*MI*/1, /*OpIdx*/2, // MIs[2]
+// CHECK-NEXT: /* 143 */ GIM_CheckOpcode, /*MI*/2, GIMT_Encode2(TargetOpcode::G_SUB),
+// CHECK-NEXT: /* 147 */ // MIs[2] Operand 1
+// CHECK-NEXT: /* 147 */ GIM_CheckConstantInt8, /*MI*/2, /*Op*/1, 0,
+// CHECK-NEXT: /* 151 */ // MIs[2] A
+// CHECK-NEXT: /* 151 */ GIM_CheckIsSameOperandIgnoreCopies, /*MI*/2, /*OpIdx*/2, /*OtherMI*/1, /*OtherOpIdx*/1,
+// CHECK-NEXT: /* 156 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
+// CHECK-NEXT: /* 160 */ GIM_CheckIsSafeToFold, /*NumInsns*/2,
+// CHECK-NEXT: /* 162 */ GIR_MakeTempReg, /*TempRegID*/1, /*TypeID*/255,
+// CHECK-NEXT: /* 165 */ GIR_BuildConstant, /*TempRegID*/1, /*Val*/GIMT_Encode8(0),
+// CHECK-NEXT: /* 175 */ GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/255,
+// CHECK-NEXT: /* 178 */ // Combiner Rule #0: SharedCXXPred0
+// CHECK-NEXT: /* 178 */ GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SUB),
+// CHECK-NEXT: /* 181 */ GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
+// CHECK-NEXT: /* 186 */ GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/1,
+// CHECK-NEXT: /* 189 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // A
+// CHECK-NEXT: /* 193 */ GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: /* 199 */ GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_UMIN),
+// CHECK-NEXT: /* 203 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // root
+// CHECK-NEXT: /* 207 */ GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // A
+// CHECK-NEXT: /* 211 */ GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
+// CHECK-NEXT: /* 214 */ GIR_UnsetMIFlags, /*InsnID*/1, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: /* 220 */ GIR_EraseRootFromParent_Done,
+// CHECK-NEXT: /* 221 */ // Label 2: @221
+// CHECK-NEXT: /* 221 */ GIM_Reject,
+// CHECK-NEXT: /* 222 */ // Label 0: @222
+// CHECK-NEXT: /* 222 */ GIM_Reject,
+// CHECK-NEXT: /* 223 */ }; // Size: 223 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting.td
index ebad6f7ac86bf..55a01de6a4800 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-hoisting.td
@@ -35,9 +35,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: /* 0 */ GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(100),
+// CHECK-NEXT: /* 0 */ GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(112),
// CHECK-NEXT: /* 5 */ GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SUB),
-// CHECK-NEXT: /* 9 */ GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4(54), // Rule ID 1 //
+// CHECK-NEXT: /* 9 */ GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4(60), // Rule ID 1 //
// CHECK-NEXT: /* 14 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
// CHECK-NEXT: /* 17 */ // MIs[0] root
// CHECK-NEXT: /* 17 */ // No operand predicates
@@ -61,37 +61,39 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: /* 43 */ GIR_RootToRootCopy, /*OpIdx*/0, // root
// CHECK-NEXT: /* 45 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // A
// CHECK-NEXT: /* 49 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // C
-// CHECK-NEXT: /* 53 */ GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: /* 54 */ // Label 1: @54
-// CHECK-NEXT: /* 54 */ GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4(99), // Rule ID 0 //
-// CHECK-NEXT: /* 59 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
-// CHECK-NEXT: /* 62 */ // MIs[0] root
-// CHECK-NEXT: /* 62 */ // No operand predicates
-// CHECK-NEXT: /* 62 */ // MIs[0] add1
-// CHECK-NEXT: /* 62 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
-// CHECK-NEXT: /* 66 */ GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_ADD),
-// CHECK-NEXT: /* 70 */ // MIs[1] A
-// CHECK-NEXT: /* 70 */ // No operand predicates
-// CHECK-NEXT: /* 70 */ // MIs[1] sub1
-// CHECK-NEXT: /* 70 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/2, /*MI*/1, /*OpIdx*/2, // MIs[2]
-// CHECK-NEXT: /* 74 */ GIM_CheckOpcode, /*MI*/2, GIMT_Encode2(TargetOpcode::G_SUB),
-// CHECK-NEXT: /* 78 */ // MIs[2] B
-// CHECK-NEXT: /* 78 */ // No operand predicates
-// CHECK-NEXT: /* 78 */ // MIs[2] C
-// CHECK-NEXT: /* 78 */ // No operand predicates
-// CHECK-NEXT: /* 78 */ // MIs[0] B
-// CHECK-NEXT: /* 78 */ GIM_CheckIsSameOperandIgnoreCopies, /*MI*/0, /*OpIdx*/2, /*OtherMI*/2, /*OtherOpIdx*/1,
-// CHECK-NEXT: /* 83 */ GIM_CheckIsSafeToFold, /*NumInsns*/2,
-// CHECK-NEXT: /* 85 */ // Combiner Rule #0: SharedPreds0
-// CHECK-NEXT: /* 85 */ GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SUB),
-// CHECK-NEXT: /* 88 */ GIR_RootToRootCopy, /*OpIdx*/0, // root
-// CHECK-NEXT: /* 90 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // A
-// CHECK-NEXT: /* 94 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // C
-// CHECK-NEXT: /* 98 */ GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: /* 99 */ // Label 2: @99
-// CHECK-NEXT: /* 99 */ GIM_Reject,
-// CHECK-NEXT: /* 100 */ // Label 0: @100
-// CHECK-NEXT: /* 100 */ GIM_Reject,
-// CHECK-NEXT: /* 101 */ }; // Size: 101 bytes
+// CHECK-NEXT: /* 53 */ GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: /* 59 */ GIR_EraseRootFromParent_Done,
+// CHECK-NEXT: /* 60 */ // Label 1: @60
+// CHECK-NEXT: /* 60 */ GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4(111), // Rule ID 0 //
+// CHECK-NEXT: /* 65 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
+// CHECK-NEXT: /* 68 */ // MIs[0] root
+// CHECK-NEXT: /* 68 */ // No operand predicates
+// CHECK-NEXT: /* 68 */ // MIs[0] add1
+// CHECK-NEXT: /* 68 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
+// CHECK-NEXT: /* 72 */ GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_ADD),
+// CHECK-NEXT: /* 76 */ // MIs[1] A
+// CHECK-NEXT: /* 76 */ // No operand predicates
+// CHECK-NEXT: /* 76 */ // MIs[1] sub1
+// CHECK-NEXT: /* 76 */ GIM_RecordInsnIgnoreCopies, /*DefineMI*/2, /*MI*/1, /*OpIdx*/2, // MIs[2]
+// CHECK-NEXT: /* 80 */ GIM_CheckOpcode, /*MI*/2, GIMT_Encode2(TargetOpcode::G_SUB),
+// CHECK-NEXT: /* 84 */ // MIs[2] B
+// CHECK-NEXT: /* 84 */ // No operand predicates
+// CHECK-NEXT: /* 84 */ // MIs[2] C
+// CHECK-NEXT: /* 84 */ // No operand predicates
+// CHECK-NEXT: /* 84 */ // MIs[0] B
+// CHECK-NEXT: /* 84 */ GIM_CheckIsSameOperandIgnoreCopies, /*MI*/0, /*OpIdx*/2, /*OtherMI*/2, /*OtherOpIdx*/1,
+// CHECK-NEXT: /* 89 */ GIM_CheckIsSafeToFold, /*NumInsns*/2,
+// CHECK-NEXT: /* 91 */ // Combiner Rule #0: SharedPreds0
+// CHECK-NEXT: /* 91 */ GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SUB),
+// CHECK-NEXT: /* 94 */ GIR_RootToRootCopy, /*OpIdx*/0, // root
+// CHECK-NEXT: /* 96 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // A
+// CHECK-NEXT: /* 100 */ GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // C
+// CHECK-NEXT: /* 104 */ GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: /* 110 */ GIR_EraseRootFromParent_Done,
+// CHECK-NEXT: /* 111 */ // Label 2: @111
+// CHECK-NEXT: /* 111 */ GIM_Reject,
+// CHECK-NEXT: /* 112 */ // Label 0: @112
+// CHECK-NEXT: /* 112 */ GIM_Reject,
+// CHECK-NEXT: /* 113 */ }; // Size: 113 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td
index e0b802447ea2a..dcc8d92c42ef3 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td
@@ -49,6 +49,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 4: @[[L492]]
// CHECK-NEXT: GIM_Reject,
@@ -63,6 +64,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_CONSTANT),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_AddCImm, /*InsnID*/0, /*Type*/GILLT_s32, /*Imm*/GIMT_Encode8(42),
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 5: @[[L538]]
// CHECK-NEXT: GIM_Reject,
@@ -79,6 +81,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 6: @[[L578]]
// CHECK-NEXT: GIM_Reject,
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td
index 22cb105355ab1..24c8232ac5306 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td
@@ -46,10 +46,12 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_INTRINSIC),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
// CHECK-NEXT: GIR_AddIntrinsicID, /*MI*/0, GIMT_Encode2(Intrinsic::0in_1out),
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_INTRINSIC),
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_AddIntrinsicID, /*MI*/1, GIMT_Encode2(Intrinsic::1in_1out),
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/1, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 3: @[[L72]]
// CHECK-NEXT: GIM_Reject,
@@ -68,16 +70,18 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
// CHECK-NEXT: GIR_AddIntrinsicID, /*MI*/0, GIMT_Encode2(Intrinsic::convergent_1in_1out),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/2, // b
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS),
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_AddIntrinsicID, /*MI*/1, GIMT_Encode2(Intrinsic::convergent_sideeffects_1in_1out),
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/1, /*NumInsns*/1, /*MergeInsnID's*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/1, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 4: @[[L131]]
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 2: @[[L132]]
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: }; // Size: 125 bytes
+// CHECK-NEXT: }; // Size: 149 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-miflags.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-miflags.td
index 24864e8aef456..b5edf5c27f3f2 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-miflags.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-miflags.td
@@ -17,7 +17,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [MIFlagsTest]>;
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(63), // Rule ID 0 //
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(69), // Rule ID 0 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SEXT),
// CHECK-NEXT: // MIs[0] dst
@@ -35,11 +35,12 @@ def MyCombiner: GICombiner<"GenMyCombiner", [MIFlagsTest]>;
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // dst
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_CopyMIFlags, /*InsnID*/0, /*OldInsnID*/1,
// CHECK-NEXT: GIR_SetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::FmReassoc),
// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::FmNsz | MachineInstr::FmArcp),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: // Label 0: @63
+// CHECK-NEXT: // Label 0: @69
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: };
// CHECK-NEXT: return MatchTable0;
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-operand-types.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-operand-types.td
index e359ddf73cd8a..4874b0eb0bca8 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-operand-types.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-operand-types.td
@@ -21,7 +21,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(73), // Rule ID 0 //
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(85), // Rule ID 0 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s8,
@@ -39,13 +39,15 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // b
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // c
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_ADD),
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/1, // b
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/1, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: // Label 0: @73
+// CHECK-NEXT: // Label 0: @85
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: }; // Size: 74 bytes
+// CHECK-NEXT: }; // Size: 86 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-patfrag-root.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-patfrag-root.td
index 5a8b51dfc8324..26d010cffceea 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-patfrag-root.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-patfrag-root.td
@@ -45,6 +45,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // root
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 4: @[[L297]]
// CHECK-NEXT: GIM_Reject,
@@ -65,6 +66,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // root
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 5: @[[L343]]
// CHECK-NEXT: GIM_Reject,
@@ -81,6 +83,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // root
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 6: @[[L379]]
// CHECK-NEXT: GIM_Reject,
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-permutations.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-permutations.td
index 4a908e7823484..2a41be5fea811 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-permutations.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-permutations.td
@@ -159,9 +159,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(562),
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(594),
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_AND),
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4(66), // Rule ID 7 //
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4(70), // Rule ID 7 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -188,9 +188,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner23),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/4,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[1], b[1], c[1]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 1: @66
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4(131), // Rule ID 6 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 1: @70
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4(139), // Rule ID 6 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -220,9 +220,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner20),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/5,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[1], b[1], c[0]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 2: @131
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 3*/ GIMT_Encode4(196), // Rule ID 5 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 2: @139
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 3*/ GIMT_Encode4(208), // Rule ID 5 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -252,9 +252,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner17),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/5,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[1], b[0], c[1]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 3: @196
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 4*/ GIMT_Encode4(269), // Rule ID 4 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 3: @208
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 4*/ GIMT_Encode4(285), // Rule ID 4 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -287,9 +287,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner14),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/6,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[1], b[0], c[0]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 4: @269
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 5*/ GIMT_Encode4(334), // Rule ID 3 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 4: @285
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 5*/ GIMT_Encode4(354), // Rule ID 3 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -319,9 +319,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner11),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/5,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[0], b[1], c[1]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 5: @334
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4(407), // Rule ID 2 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 5: @354
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4(431), // Rule ID 2 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -354,9 +354,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner8),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/6,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[0], b[1], c[0]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 6: @407
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4(480), // Rule ID 1 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 6: @431
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4(508), // Rule ID 1 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -389,9 +389,9 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner5),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/6,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[0], b[0], c[1]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 7: @480
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4(561), // Rule ID 0 //
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 7: @508
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4(593), // Rule ID 0 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // MIs[0] dst
// CHECK-NEXT: // No operand predicates
@@ -427,11 +427,11 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner2),
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/7,
// CHECK-NEXT: // Combiner Rule #0: Test0 @ [a[0], b[0], c[0]]
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: // Label 8: @561
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
+// CHECK-NEXT: // Label 8: @593
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: // Label 0: @562
+// CHECK-NEXT: // Label 0: @594
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: }; // Size: 563 bytes
+// CHECK-NEXT: }; // Size: 595 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-typeof.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-typeof.td
index aca7e5ef42fd0..49897a69081ce 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-typeof.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-typeof.td
@@ -16,7 +16,7 @@ def Test0 : GICombineRule<
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(74), // Rule ID 0 //
+// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(86), // Rule ID 0 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),
// CHECK-NEXT: // MIs[0] dst
@@ -32,14 +32,16 @@ def Test0 : GICombineRule<
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_CONSTANT),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(static_cast<uint16_t>(RegState::Define)),
// CHECK-NEXT: GIR_AddCImm, /*InsnID*/0, /*Type*/254, /*Imm*/GIMT_Encode8(42),
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SUB),
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // dst
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/1,
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/1, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: // Label 0: @74
+// CHECK-NEXT: // Label 0: @86
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: }; // Size: 75 bytes
+// CHECK-NEXT: }; // Size: 87 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-variadics.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-variadics.td
index 98456983c085b..276df294dee98 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-variadics.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-variadics.td
@@ -78,7 +78,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #2: InstTest2
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 3: @{{[0-9]+}}
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 4*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 3 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule3Enabled),
@@ -92,7 +92,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] d
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #3: InstTest3
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 4: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 1: @{{[0-9]+}}
@@ -105,7 +105,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #4: VariadicTypeTestCxx
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 5: @{{[0-9]+}}
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 1 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
@@ -115,7 +115,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #1: InstTest1
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 6: @{{[0-9]+}}
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 5 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule5Enabled),
@@ -132,6 +132,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a
// CHECK-NEXT: GIR_CopyRemaining, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // b
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // c
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 7: @{{[0-9]+}}
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 0 //
@@ -146,11 +147,11 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] d
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #0: InstTest0
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 8: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 2: @{{[0-9]+}}
// CHECK-NEXT: GIM_Reject,
-// CHECK-NEXT: }; // Size: 128 bytes
+// CHECK-NEXT: }; // Size: 154 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
index 58c25ab925b85..545c1a4d074b0 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td
@@ -171,7 +171,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
// CHECK-NEXT: // Combiner Rule #3: InstTest1
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 7: @[[L7]]
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4([[L8:[0-9]+]]), // Rule ID 3 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule2Enabled),
@@ -180,7 +180,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // MIs[0] b
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // Combiner Rule #2: InstTest0
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 8: @[[L8]]
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 1: @[[L1]]
@@ -200,6 +200,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_TRUNC),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // dst
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // z
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 9: @[[L9]]
// CHECK-NEXT: GIM_Reject,
@@ -219,6 +220,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // ext
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // ptr
// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*NumInsns*/2, /*MergeInsnID's*/0, 1,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 10: @[[L10]]
// CHECK-NEXT: GIM_Reject,
@@ -226,19 +228,19 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 11*/ GIMT_Encode4([[L11:[0-9]+]]), // Rule ID 0 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: // Combiner Rule #0: WipOpcodeTest0; wip_match_opcode 'G_TRUNC'
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 11: @[[L11]]
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 12*/ GIMT_Encode4([[L12:[0-9]+]]), // Rule ID 1 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
// CHECK-NEXT: // Combiner Rule #1: WipOpcodeTest1; wip_match_opcode 'G_TRUNC'
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 12: @[[L12]]
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 4: @[[L4]]
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 13*/ GIMT_Encode4([[L13:[0-9]+]]), // Rule ID 2 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
// CHECK-NEXT: // Combiner Rule #1: WipOpcodeTest1; wip_match_opcode 'G_SEXT'
-// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0), /*InitialUnsetFlags*/GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: // Label 13: @[[L13]]
// CHECK-NEXT: GIM_Reject,
// CHECK-NEXT: // Label 5: @[[L5]]
@@ -255,6 +257,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // dst
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,
+// CHECK-NEXT: GIR_UnsetMIFlags, /*InsnID*/0, GIMT_Encode4(MachineInstr::NoUWrap | MachineInstr::NoSWrap | MachineInstr::NoUSWrap | MachineInstr::IsExact | MachineInstr::Disjoint | MachineInstr::NonNeg | MachineInstr::FmNoNans | MachineInstr::FmNoInfs | MachineInstr::SameSign | MachineInstr::InBounds),
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
// CHECK-NEXT: // Label 14: @[[L14]]
// CHECK-NEXT: GIM_Reject,
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/pattern-parsing.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/pattern-parsing.td
index 7541639480fc5..335c96f184d51 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/pattern-parsing.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/pattern-parsing.td
@@ -325,7 +325,7 @@ def TypeOfTest : GICombineRule<
// CHECK-NEXT: <match_root>mi:(CodeGenInstructionPattern G_ZEXT operands:[<def>$dst, $src] (MIFlags (set MachineInstr::FmReassoc) (unset MachineInstr::FmNoNans, MachineInstr::FmArcp)))
// CHECK-NEXT: )
// CHECK-NEXT: (ApplyPats
-// CHECK-NEXT: <apply_root>__MIFlagsTest_apply_0:(CodeGenInstructionPattern G_MUL operands:[<def>$dst, $src, $src] (MIFlags (set MachineInstr::FmReassoc) (unset MachineInstr::FmNsz, MachineInstr::FmArcp) (copy mi)))
+// CHECK-NEXT: <apply_root>__MIFlagsTest_apply_0:(CodeGenInstructionPattern G_MUL operands:[<def>$dst, $src, $src] (MIFlags (set MachineInstr::FmReassoc, MachineInstr::SameSign) (unset MachineInstr::FmNsz, MachineInstr::FmArcp) (copy mi)))
// CHECK-NEXT: )
// CHECK-NEXT: (OperandTable MatchPats
// CHECK-NEXT: dst -> mi
@@ -339,7 +339,7 @@ def TypeOfTest : GICombineRule<
def MIFlagsTest : GICombineRule<
(defs root:$dst),
(match (G_ZEXT $dst, $src, (MIFlags FmReassoc, (not FmNoNans, FmArcp))):$mi),
- (apply (G_MUL $dst, $src, $src, (MIFlags $mi, FmReassoc, (not FmNsz, FmArcp))))>;
+ (apply (G_MUL $dst, $src, $src, (MIFlags $mi, FmReassoc, SameSign, (not FmNsz, FmArcp))))>;
// CHECK-NEXT: (CombineRule name:IntrinTest0 id:12 root:a
// CHECK-NEXT: (MatchPats
diff --git a/llvm/unittests/CodeGen/GlobalISel/GIMatchTableExecutorTest.cpp b/llvm/unittests/CodeGen/GlobalISel/GIMatchTableExecutorTest.cpp
index 5a811d7959288..ea6cfa16eda94 100644
--- a/llvm/unittests/CodeGen/GlobalISel/GIMatchTableExecutorTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/GIMatchTableExecutorTest.cpp
@@ -7,10 +7,73 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
+#include "GISelMITest.h"
+#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetMachine.h"
#include "gtest/gtest.h"
using namespace llvm;
+namespace {
+
+class TestGIMatchTableExecutor : public GIMatchTableExecutor {
+public:
+ static const char *getName() { return "test-gimatchtable-executor"; }
+
+ void setupGeneratedPerFunctionState(MachineFunction &MF) override {}
+
+ bool runCustomAction(unsigned FnID, const MatcherState &State,
+ NewMIVector &OutMIs) const override {
+ assert(FnID == 1);
+ MachineInstr &Root = *State.MIs[0];
+ MachineBasicBlock &MBB = *Root.getParent();
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, Root.getIterator(), Root.getDebugLoc(),
+ MF->getSubtarget().getInstrInfo()->get(TargetOpcode::G_SUB))
+ .addDef(Root.getOperand(0).getReg())
+ .addUse(Root.getOperand(1).getReg())
+ .addUse(Root.getOperand(2).getReg());
+ MIB.setMIFlags(MachineInstr::NoSWrap);
+ OutMIs.push_back(MIB);
+ return true;
+ }
+
+ bool run(MachineInstr &Root, MachineIRBuilder &Builder,
+ const uint8_t *MatchTable, const TargetInstrInfo &TII,
+ MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+ const RegisterBankInfo &RBI) const {
+ MatcherState State(/*MaxRenderers=*/0);
+ State.MIs.push_back(&Root);
+ using PredicateBitset = Bitset<1>;
+ using ComplexMatcherMemFn =
+ ComplexRendererFns (TestGIMatchTableExecutor::*)(MachineOperand &)
+ const;
+ using CustomRendererFn = void (TestGIMatchTableExecutor::*)(
+ MachineInstrBuilder &, const MachineInstr &, int64_t) const;
+ const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
+ ExecInfo(nullptr, 0, nullptr, nullptr, nullptr);
+ PredicateBitset AvailableFeatures;
+ return executeMatchTable(*const_cast<TestGIMatchTableExecutor *>(this),
+ State, ExecInfo, Builder, MatchTable, TII, MRI,
+ TRI, RBI, AvailableFeatures, nullptr);
+ }
+};
+
+static void appendU16(SmallVectorImpl<uint8_t> &Table, uint16_t Value) {
+ Table.push_back(Value & 0xff);
+ Table.push_back((Value >> 8) & 0xff);
+}
+
+static void appendU32(SmallVectorImpl<uint8_t> &Table, uint32_t Value) {
+ Table.push_back(Value & 0xff);
+ Table.push_back((Value >> 8) & 0xff);
+ Table.push_back((Value >> 16) & 0xff);
+ Table.push_back((Value >> 24) & 0xff);
+}
+
+} // namespace
+
TEST(GlobalISelLEB128Test, fastDecodeULEB128) {
#define EXPECT_DECODE_ULEB128_EQ(EXPECTED, VALUE) \
do { \
@@ -47,3 +110,89 @@ TEST(GlobalISelLEB128Test, fastDecodeULEB128) {
#undef EXPECT_DECODE_ULEB128_EQ
}
+
+TEST_F(AArch64GISelMITest, MatchTableExplicitMIFlagsOverrideInitialUnset) {
+ setUp("");
+ if (!TM)
+ GTEST_SKIP();
+
+ Register RootReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
+ auto Root =
+ B.buildInstr(TargetOpcode::G_ADD, {RootReg}, {Copies[1], Copies[2]});
+ Root->setFlags(MachineInstr::NoUWrap | MachineInstr::NoSWrap);
+
+ TestGIMatchTableExecutor Executor;
+ Executor.setupMF(*MF, nullptr);
+
+ SmallVector<uint8_t, 32> MatchTable;
+ MatchTable.push_back(GIR_BuildMI);
+ MatchTable.push_back(0); // InsnID
+ appendU16(MatchTable, TargetOpcode::G_SUB);
+ MatchTable.push_back(GIR_BuildMI);
+ MatchTable.push_back(1); // InsnID
+ appendU16(MatchTable, TargetOpcode::G_SUB);
+ MatchTable.push_back(GIR_UnsetMIFlags);
+ MatchTable.push_back(0); // InsnID
+ appendU32(MatchTable, MachineInstr::NoUWrap | MachineInstr::NoSWrap);
+ MatchTable.push_back(GIR_SetMIFlags);
+ MatchTable.push_back(0); // InsnID
+ appendU32(MatchTable, MachineInstr::NoSWrap);
+ MatchTable.push_back(GIR_UnsetMIFlags);
+ MatchTable.push_back(1); // InsnID
+ appendU32(MatchTable, MachineInstr::NoUWrap | MachineInstr::NoSWrap);
+ MatchTable.push_back(GIR_CopyMIFlags);
+ MatchTable.push_back(1); // InsnID
+ MatchTable.push_back(0); // OldInsnID
+ MatchTable.push_back(GIR_Done);
+
+ const TargetSubtargetInfo &STI = MF->getSubtarget();
+ EXPECT_TRUE(Executor.run(*Root, B, MatchTable.data(), *STI.getInstrInfo(),
+ *MRI, *STI.getRegisterInfo(),
+ *STI.getRegBankInfo()));
+
+ SmallVector<MachineInstr *, 2> BuiltMIs;
+ for (MachineInstr &MI : *EntryMBB) {
+ if (MI.getOpcode() == TargetOpcode::G_SUB)
+ BuiltMIs.push_back(&MI);
+ }
+ ASSERT_EQ(BuiltMIs.size(), 2u);
+ EXPECT_FALSE(BuiltMIs[0]->getFlag(MachineInstr::NoUWrap));
+ EXPECT_TRUE(BuiltMIs[0]->getFlag(MachineInstr::NoSWrap));
+ EXPECT_TRUE(BuiltMIs[1]->getFlag(MachineInstr::NoUWrap));
+ EXPECT_TRUE(BuiltMIs[1]->getFlag(MachineInstr::NoSWrap));
+}
+
+TEST_F(AArch64GISelMITest, MatchTableCustomActionDropsRootMIFlags) {
+ setUp("");
+ if (!TM)
+ GTEST_SKIP();
+
+ Register RootReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
+ auto Root =
+ B.buildInstr(TargetOpcode::G_ADD, {RootReg}, {Copies[1], Copies[2]});
+ Root->setFlags(MachineInstr::NoUWrap | MachineInstr::NoSWrap);
+
+ TestGIMatchTableExecutor Executor;
+ Executor.setupMF(*MF, nullptr);
+
+ SmallVector<uint8_t, 16> MatchTable;
+ MatchTable.push_back(GIR_DoneWithCustomAction);
+ appendU16(MatchTable, 1); // FnID
+ appendU32(MatchTable, MachineInstr::NoUWrap | MachineInstr::NoSWrap);
+
+ const TargetSubtargetInfo &STI = MF->getSubtarget();
+ EXPECT_TRUE(Executor.run(*Root, B, MatchTable.data(), *STI.getInstrInfo(),
+ *MRI, *STI.getRegisterInfo(),
+ *STI.getRegBankInfo()));
+
+ MachineInstr *BuiltMI = nullptr;
+ for (MachineInstr &MI : *EntryMBB) {
+ if (MI.getOpcode() == TargetOpcode::G_SUB) {
+ BuiltMI = &MI;
+ break;
+ }
+ }
+ ASSERT_NE(BuiltMI, nullptr);
+ EXPECT_FALSE(BuiltMI->getFlag(MachineInstr::NoUWrap));
+ EXPECT_TRUE(BuiltMI->getFlag(MachineInstr::NoSWrap));
+}
diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
index cc1089fc316c7..85afde6c7fcd3 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
@@ -830,6 +830,8 @@ void RuleMatcher::emit(MatchTable &Table) {
Table << MatchTable::Opcode("GIR_DoneWithCustomAction", -1)
<< MatchTable::Comment("Fn")
<< MatchTable::NamedValue(2, CustomCXXAction)
+ << MatchTable::Comment("InitialUnsetFlags")
+ << MatchTable::NamedValue(4, CustomCXXActionInitialUnsetFlags)
<< MatchTable::LineBreak;
} else {
// Emit all actions except the last one, then emit coverage and emit the
@@ -1956,6 +1958,13 @@ void BuildMIAction::chooseInsnToMutate(RuleMatcher &Rule) {
void BuildMIAction::emitActionOpcodes(MatchTable &Table) const {
const auto AddMIFlags = [&]() {
+ if (!InitialUnsetFlags.empty()) {
+ Table << MatchTable::Opcode("GIR_UnsetMIFlags")
+ << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID)
+ << MatchTable::NamedValue(4, join(InitialUnsetFlags, " | "))
+ << MatchTable::LineBreak;
+ }
+
for (const InstructionMatcher *IM : CopiedFlags) {
Table << MatchTable::Opcode("GIR_CopyMIFlags")
<< MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID)
diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
index b7ea01279eea9..720a60f0e1347 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
@@ -305,6 +305,7 @@ class RuleMatcher : public Matcher {
/// Combiners can sometimes just run C++ code to finish matching a rule &
/// mutate instructions instead of relying on MatchActions. Empty if unused.
std::string CustomCXXAction;
+ std::string CustomCXXActionInitialUnsetFlags = "0";
using MutatableInsnSet = SmallPtrSet<InstructionMatcher *, 4>;
@@ -410,6 +411,9 @@ class RuleMatcher : public Matcher {
void setCustomCXXAction(StringRef FnEnumName) {
CustomCXXAction = FnEnumName.str();
}
+ void setCustomCXXActionInitialUnsetFlags(StringRef Flags) {
+ CustomCXXActionInitialUnsetFlags = Flags.str();
+ }
// Emplaces an action of the specified Kind at the end of the action list.
//
@@ -2251,6 +2255,7 @@ class BuildMIAction : public MatchAction {
SmallPtrSet<const Record *, 4> DeadImplicitDefs;
std::vector<const InstructionMatcher *> CopiedFlags;
+ std::vector<StringRef> InitialUnsetFlags;
std::vector<StringRef> SetFlags;
std::vector<StringRef> UnsetFlags;
std::vector<unsigned> MergeInsnIDs;
@@ -2283,6 +2288,9 @@ class BuildMIAction : public MatchAction {
unsigned getInsnID() const { return InsnID; }
const CodeGenInstruction *getCGI() const { return I; }
+ void addInitialUnsetMIFlags(StringRef Flag) {
+ InitialUnsetFlags.push_back(Flag);
+ }
void addSetMIFlags(StringRef Flag) { SetFlags.push_back(Flag); }
void addUnsetMIFlags(StringRef Flag) { UnsetFlags.push_back(Flag); }
void addCopiedMIFlags(const InstructionMatcher &IM) {
diff --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index bb93d0248e55f..df037d5d504d7 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -83,6 +83,17 @@ constexpr StringLiteral CXXCustomActionPrefix = "GICXXCustomAction_";
constexpr StringLiteral CXXPredPrefix = "GICXXPred_MI_Predicate_";
constexpr StringLiteral MatchDataClassName = "GIDefMatchData";
+static constexpr StringLiteral PoisonGeneratingMIFlags[] = {
+ "MachineInstr::NoUWrap", "MachineInstr::NoSWrap",
+ "MachineInstr::NoUSWrap", "MachineInstr::IsExact",
+ "MachineInstr::Disjoint", "MachineInstr::NonNeg",
+ "MachineInstr::FmNoNans", "MachineInstr::FmNoInfs",
+ "MachineInstr::SameSign", "MachineInstr::InBounds"};
+
+static std::string getPoisonGeneratingMIFlags() {
+ return join(ArrayRef(PoisonGeneratingMIFlags), " | ");
+}
+
//===- CodeExpansions Helpers --------------------------------------------===//
static void declareInstExpansion(CodeExpansions &CE,
@@ -1951,6 +1962,7 @@ bool CombineRuleBuilder::emitCXXMatchApply(CodeExpansions &CE, RuleMatcher &M,
const auto &Code = CXXPredicateCode::getCustomActionCode(CodeStr);
M.setCustomCXXAction(Code.getEnumNameWithPrefix(CXXCustomActionPrefix));
+ M.setCustomCXXActionInitialUnsetFlags(getPoisonGeneratingMIFlags());
return true;
}
@@ -2104,6 +2116,10 @@ bool CombineRuleBuilder::emitInstructionApplyPattern(
if (CGIP.isIntrinsic() && !HasEmittedIntrinsicID)
EmitIntrinsicID();
+ // Poison-generating flags need to be explicitly preserved by the pattern.
+ for (StringRef F : PoisonGeneratingMIFlags)
+ DstMI.addInitialUnsetMIFlags(F);
+
// Render MIFlags
if (const auto *FI = CGIP.getMIFlagsInfo()) {
for (StringRef InstName : FI->copy_flags())
More information about the llvm-commits
mailing list