[llvm-branch-commits] [llvm] CodeGen: Add SUCC_ARGS pseudo-instruction (PR #218893)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Aug 26 06:50:14 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/218893
>From 90e8e17c5e899ffb3c094358b55232684952d2a0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 14 Aug 2026 00:19:43 +0200
Subject: [PATCH] CodeGen: Add SUCC_ARGS pseudo-instruction
The sender half of a block-argument representation for Machine IR: a
"reverse PHI" that forwards values from a predecessor's bottom to a
successor block's arguments along one CFG edge. Operand 0 is the successor
block; the rest are the forwarded value registers, mapped positionally.
Like PHI, SUCC_ARGS is edge-specific: it must stay in its block, so it is
excluded from CSE and hoisting, and it defines no register but is not dead.
SUCC_ARGS are clustered contiguously immediately before the terminators,
mirroring how PHIs are clustered at the top of a block; the verifier
enforces this and the succ_args() range and getBlockEndInsertPt() let
consumers work with the cluster. Inert; no producer emits it yet.
Co-Authored-By: Claude <noreply at anthropic.com> (Claude Opus 4.8)
---
llvm/include/llvm/CodeGen/MachineBasicBlock.h | 26 ++++++++++++
llvm/include/llvm/CodeGen/MachineInstr.h | 1 +
llvm/include/llvm/Support/TargetOpcodes.def | 7 ++++
llvm/include/llvm/Target/Target.td | 6 +++
llvm/lib/CodeGen/MachineBasicBlock.cpp | 13 ++++++
llvm/lib/CodeGen/MachineCSE.cpp | 6 +--
llvm/lib/CodeGen/MachineInstr.cpp | 5 ++-
llvm/lib/CodeGen/MachineVerifier.cpp | 22 ++++++++++
llvm/test/CodeGen/MIR/X86/succ-args.mir | 40 +++++++++++++++++++
.../CodeGen/X86/machine-cse-succ-args.mir | 34 ++++++++++++++++
.../CodeGen/X86/machinelicm-succ-args.mir | 29 ++++++++++++++
llvm/test/CodeGen/X86/succ-args-not-dead.mir | 20 ++++++++++
llvm/test/MachineVerifier/X86/lit.local.cfg | 2 +
.../X86/succ-args-clustered.mir | 19 +++++++++
.../X86/succ-args-debug-in-cluster.mir | 21 ++++++++++
.../MachineVerifier/X86/succ-args-empty.mir | 33 +++++++++++++++
.../match-table-imms.td | 4 +-
llvm/test/TableGen/get-named-operand-idx.td | 4 +-
18 files changed, 284 insertions(+), 8 deletions(-)
create mode 100644 llvm/test/CodeGen/MIR/X86/succ-args.mir
create mode 100644 llvm/test/CodeGen/X86/machine-cse-succ-args.mir
create mode 100644 llvm/test/CodeGen/X86/machinelicm-succ-args.mir
create mode 100644 llvm/test/CodeGen/X86/succ-args-not-dead.mir
create mode 100644 llvm/test/MachineVerifier/X86/lit.local.cfg
create mode 100644 llvm/test/MachineVerifier/X86/succ-args-clustered.mir
create mode 100644 llvm/test/MachineVerifier/X86/succ-args-debug-in-cluster.mir
create mode 100644 llvm/test/MachineVerifier/X86/succ-args-empty.mir
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index d5c31c4b7281b..fd5fc8fe8c1e5 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -403,6 +403,15 @@ class MachineBasicBlock
return make_range(getFirstTerminator(), end());
}
+ /// Returns a range that iterates over the SUCC_ARGS instructions clustered
+ /// immediately before the terminators of this block.
+ inline iterator_range<iterator> succ_args() {
+ return make_range(getFirstSuccArgs(), getFirstTerminator());
+ }
+ inline iterator_range<const_iterator> succ_args() const {
+ return const_cast<MachineBasicBlock *>(this)->succ_args();
+ }
+
/// Returns a range that iterates over the phis in the basic block.
inline iterator_range<iterator> phis() {
return make_range(begin(), getFirstNonPHI());
@@ -925,6 +934,23 @@ class MachineBasicBlock
return const_cast<MachineBasicBlock *>(this)->getFirstTerminator();
}
+ /// Returns an iterator to the first SUCC_ARGS instruction of this basic
+ /// block. SUCC_ARGS instructions are clustered immediately before the
+ /// terminators, mirroring how PHIs are clustered at the top of a block. If
+ /// there are none, this returns getFirstTerminator().
+ LLVM_ABI iterator getFirstSuccArgs();
+ const_iterator getFirstSuccArgs() const {
+ return const_cast<MachineBasicBlock *>(this)->getFirstSuccArgs();
+ }
+
+ /// Returns the insertion point for instructions that must go at the end of
+ /// this block, before the SUCC_ARGS cluster and terminators. This is the
+ /// end-of-block analogue of SkipPHIsAndLabels: anything spliced or built
+ /// here stays clear of the SUCC_ARGS cluster, which must remain adjacent to
+ /// the terminators. Equivalent to getFirstSuccArgs().
+ iterator getBlockEndInsertPt() { return getFirstSuccArgs(); }
+ const_iterator getBlockEndInsertPt() const { return getFirstSuccArgs(); }
+
/// Same getFirstTerminator but it ignores bundles and return an
/// instr_iterator instead.
LLVM_ABI instr_iterator getFirstInstrTerminator();
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index b04018e43bbe0..50d82ee0cd46a 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1425,6 +1425,7 @@ class MachineInstr
return getOpcode() == TargetOpcode::PHI ||
getOpcode() == TargetOpcode::G_PHI;
}
+ bool isSuccArgs() const { return getOpcode() == TargetOpcode::SUCC_ARGS; }
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const {
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index 549a93b7bec3a..b3d7b8ea1883f 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -27,6 +27,13 @@
/// Every instruction defined here must also appear in Target.td.
///
HANDLE_TARGET_OPCODE(PHI)
+
+/// SUCC_ARGS - Forwards values along one CFG edge to a successor block's
+/// arguments. Operand 0 is the successor MachineBasicBlock; the rest are the
+/// forwarded value registers, mapped positionally onto that successor's block
+/// arguments.
+HANDLE_TARGET_OPCODE(SUCC_ARGS)
+
HANDLE_TARGET_OPCODE(INLINEASM)
HANDLE_TARGET_OPCODE(INLINEASM_BR)
HANDLE_TARGET_OPCODE(CFI_INSTRUCTION)
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 3acb2531a5466..79c5c25282af2 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -1332,6 +1332,12 @@ def PHI : StandardPseudoInstruction {
let AsmString = "PHINODE";
let hasSideEffects = false;
}
+def SUCC_ARGS : StandardPseudoInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins unknown:$succ, unknown:$val0, variable_ops);
+ let AsmString = "SUCC_ARGS";
+ let hasSideEffects = false;
+}
def INLINEASM : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 08a67935b52f5..977bec06a547a 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -251,6 +251,19 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
return I;
}
+MachineBasicBlock::iterator MachineBasicBlock::getFirstSuccArgs() {
+ // SUCC_ARGS are clustered contiguously immediately before the terminators,
+ // mirroring how PHIs are clustered at the top of a block. Walk backward from
+ // the first terminator over that cluster; the result is the first SUCC_ARGS,
+ // or the first terminator if there are none. Nothing (not even a debug
+ // instruction) may be interspersed in the cluster, so the succ_args() range
+ // yields only SUCC_ARGS.
+ iterator B = begin(), I = getFirstTerminator();
+ while (I != B && std::prev(I)->isSuccArgs())
+ --I;
+ return I;
+}
+
MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() {
instr_iterator B = instr_begin(), E = instr_end(), I = E;
while (I != B && ((--I)->isTerminator() || I->isDebugInstr()))
diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp
index 75a6ad8d6f3c2..2ac740856c439 100644
--- a/llvm/lib/CodeGen/MachineCSE.cpp
+++ b/llvm/lib/CodeGen/MachineCSE.cpp
@@ -394,9 +394,9 @@ bool MachineCSEImpl::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
}
bool MachineCSEImpl::isCSECandidate(MachineInstr *MI) {
- if (MI->isPosition() || MI->isPHI() || MI->isImplicitDef() || MI->isKill() ||
- MI->isInlineAsm() || MI->isDebugInstr() || MI->isJumpTableDebugInfo() ||
- MI->isFakeUse())
+ if (MI->isPosition() || MI->isPHI() || MI->isSuccArgs() ||
+ MI->isImplicitDef() || MI->isKill() || MI->isInlineAsm() ||
+ MI->isDebugInstr() || MI->isJumpTableDebugInfo() || MI->isFakeUse())
return false;
// Ignore copies.
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 1067f186208c4..48248af9ca1f0 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -1360,7 +1360,7 @@ bool MachineInstr::isSafeToMove(bool &SawStore) const {
// Don't touch instructions that have non-trivial invariants. For example,
// terminators have to be at the end of a basic block.
if (isPosition() || isDebugInstr() || isTerminator() ||
- isJumpTableDebugInfo() || isLifetimeMarker())
+ isJumpTableDebugInfo() || isLifetimeMarker() || isSuccArgs())
return false;
// Don't touch instructions which can have non-load/store effects.
@@ -1403,6 +1403,9 @@ bool MachineInstr::wouldBeTriviallyDead() const {
if (isFakeUse())
return false;
+ if (isSuccArgs())
+ return false;
+
// If we can move an instruction, we can remove it. Otherwise, it has
// a side-effect of some sort.
bool SawStore = false;
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 0d3015e098cf2..dd034d7e5cb73 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -159,6 +159,7 @@ struct MachineVerifier {
const MachineInstr *FirstNonPHI = nullptr;
const MachineInstr *FirstTerminator = nullptr;
+ const MachineInstr *FirstSuccArgs = nullptr;
BlockSet FunctionBlocks;
BitVector regsReserved;
@@ -742,6 +743,7 @@ void
MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
FirstTerminator = nullptr;
FirstNonPHI = nullptr;
+ FirstSuccArgs = nullptr;
if (MRI->tracksLiveness() && hasPHIs(*MF)) {
// If this block has allocatable physical registers live-in, check that
@@ -957,6 +959,19 @@ void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) {
OS << "First terminator was:\t" << *FirstTerminator;
}
}
+
+ // SUCC_ARGS instructions must be clustered contiguously immediately before
+ // the terminators, mirroring how PHIs are clustered at the top of a block.
+ // Once a SUCC_ARGS has been seen, only more SUCC_ARGS or terminators may
+ // follow - not even debug instructions, so that the succ_args() range (which
+ // spans getFirstSuccArgs()..getFirstTerminator()) yields only SUCC_ARGS.
+ if (MI->isSuccArgs()) {
+ if (!FirstSuccArgs)
+ FirstSuccArgs = MI;
+ } else if (FirstSuccArgs && !MI->isTerminator()) {
+ report("Non-terminator instruction after SUCC_ARGS", MI);
+ OS << "First SUCC_ARGS was:\t" << *FirstSuccArgs;
+ }
}
// The operands on an INLINEASM instruction must follow a template.
@@ -2360,6 +2375,13 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
} else if (FirstNonPHI == nullptr)
FirstNonPHI = MI;
+ if (MI->isSuccArgs()) {
+ if (MI->getNumOperands() < 1 || !MI->getOperand(0).isMBB())
+ report("SUCC_ARGS must have a successor block operand", MI);
+ else if (MI->getNumOperands() < 2)
+ report("SUCC_ARGS must forward at least one value", MI);
+ }
+
// Check the tied operands.
if (MI->isInlineAsm())
verifyInlineAsm(MI);
diff --git a/llvm/test/CodeGen/MIR/X86/succ-args.mir b/llvm/test/CodeGen/MIR/X86/succ-args.mir
new file mode 100644
index 0000000000000..5f1faca662ba6
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/succ-args.mir
@@ -0,0 +1,40 @@
+# RUN: llc -mtriple=x86_64-- -run-pass=none -o - %s | FileCheck %s
+# Round-trip test for the SUCC_ARGS pseudo-instruction.
+
+# A single forwarded value.
+---
+name: one_value
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: one_value
+ ; CHECK: SUCC_ARGS %bb.1, %0
+ bb.0:
+ successors: %bb.1
+ %0:gr32 = MOV32ri 7
+ SUCC_ARGS %bb.1, %0
+ JMP_1 %bb.1
+
+ bb.1:
+ %1:gr32 = COPY %0
+ RET64
+...
+
+# Multiple forwarded values on one edge.
+---
+name: many_values
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: many_values
+ ; CHECK: SUCC_ARGS %bb.1, %0, %1, %2
+ bb.0:
+ successors: %bb.1
+ %0:gr32 = MOV32ri 1
+ %1:gr32 = MOV32ri 2
+ %2:gr32 = MOV32ri 3
+ SUCC_ARGS %bb.1, %0, %1, %2
+ JMP_1 %bb.1
+
+ bb.1:
+ %3:gr32 = COPY %0
+ RET64
+...
diff --git a/llvm/test/CodeGen/X86/machine-cse-succ-args.mir b/llvm/test/CodeGen/X86/machine-cse-succ-args.mir
new file mode 100644
index 0000000000000..ed89e3c2e4e1e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/machine-cse-succ-args.mir
@@ -0,0 +1,34 @@
+# RUN: llc -mtriple=x86_64-- -run-pass=machine-cse -o - %s | FileCheck %s
+# SUCC_ARGS is edge-specific and must not be common-subexpression-eliminated,
+# even when a dominating block forwards the same register to the same successor
+# along a different edge. Each predecessor must retain its own SUCC_ARGS.
+
+---
+name: no_cse_succ_args
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: no_cse_succ_args
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $edi, $esi
+ %0:gr32 = COPY $edi
+ %1:gr32 = COPY $esi
+ TEST32rr %0, %0, implicit-def $eflags
+ ; CHECK: SUCC_ARGS %bb.2, %1
+ SUCC_ARGS %bb.2, %1
+ JCC_1 %bb.2, 5, implicit $eflags
+ JMP_1 %bb.1
+
+ ; bb.1 is dominated by bb.0. Its SUCC_ARGS is identical to bb.0's but feeds a
+ ; different edge, so it must not be CSE'd away.
+ ; CHECK: bb.1:
+ ; CHECK: SUCC_ARGS %bb.2, %1
+ bb.1:
+ successors: %bb.2
+ SUCC_ARGS %bb.2, %1
+ JMP_1 %bb.2
+
+ bb.2:
+ $eax = COPY %1
+ RET64 implicit $eax
+...
diff --git a/llvm/test/CodeGen/X86/machinelicm-succ-args.mir b/llvm/test/CodeGen/X86/machinelicm-succ-args.mir
new file mode 100644
index 0000000000000..c1a0360248efc
--- /dev/null
+++ b/llvm/test/CodeGen/X86/machinelicm-succ-args.mir
@@ -0,0 +1,29 @@
+# RUN: llc -mtriple=x86_64-- -run-pass=early-machinelicm -o - %s | FileCheck %s
+# SUCC_ARGS is edge-specific and must not be hoisted out of a loop by
+# MachineLICM, even when its forwarded operands are loop-invariant.
+
+---
+name: no_hoist_succ_args
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: no_hoist_succ_args
+ bb.0:
+ successors: %bb.1
+ liveins: $edi
+ %0:gr32 = COPY $edi
+ %1:gr32 = MOV32ri 7
+ JMP_1 %bb.1
+
+ ; The SUCC_ARGS must remain in the loop body, not be hoisted into bb.0.
+ ; CHECK: bb.1:
+ ; CHECK: SUCC_ARGS %bb.1, %1
+ bb.1:
+ successors: %bb.1, %bb.2
+ TEST32rr %0, %0, implicit-def $eflags
+ SUCC_ARGS %bb.1, %1
+ JCC_1 %bb.1, 5, implicit $eflags
+ JMP_1 %bb.2
+
+ bb.2:
+ RET64
+...
diff --git a/llvm/test/CodeGen/X86/succ-args-not-dead.mir b/llvm/test/CodeGen/X86/succ-args-not-dead.mir
new file mode 100644
index 0000000000000..bf2c83baf2758
--- /dev/null
+++ b/llvm/test/CodeGen/X86/succ-args-not-dead.mir
@@ -0,0 +1,20 @@
+# RUN: llc -mtriple=x86_64-- -run-pass=dead-mi-elimination -o - %s | FileCheck %s
+# A SUCC_ARGS defines no register but is not dead: dead-MI elimination must
+# preserve it.
+
+---
+name: f
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: f
+ bb.0:
+ successors: %bb.1
+ %0:gr32 = MOV32ri 7
+ ; CHECK: SUCC_ARGS %bb.1, %0
+ SUCC_ARGS %bb.1, %0
+ JMP_1 %bb.1
+
+ bb.1:
+ %1:gr32 = COPY %0
+ RET64
+...
diff --git a/llvm/test/MachineVerifier/X86/lit.local.cfg b/llvm/test/MachineVerifier/X86/lit.local.cfg
new file mode 100644
index 0000000000000..42bf50dcc13c3
--- /dev/null
+++ b/llvm/test/MachineVerifier/X86/lit.local.cfg
@@ -0,0 +1,2 @@
+if not "X86" in config.root.targets:
+ config.unsupported = True
diff --git a/llvm/test/MachineVerifier/X86/succ-args-clustered.mir b/llvm/test/MachineVerifier/X86/succ-args-clustered.mir
new file mode 100644
index 0000000000000..fb18c54cd8df8
--- /dev/null
+++ b/llvm/test/MachineVerifier/X86/succ-args-clustered.mir
@@ -0,0 +1,19 @@
+# RUN: not --crash llc %s -mtriple=x86_64-- -run-pass=none -filetype=null 2>&1 | FileCheck %s
+
+# SUCC_ARGS instructions must be clustered contiguously immediately before the
+# terminators. A non-terminator instruction after a SUCC_ARGS is malformed.
+# CHECK: *** Bad machine code: Non-terminator instruction after SUCC_ARGS ***
+---
+name: succ_args_not_clustered
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1
+ %0:gr32 = MOV32ri 7
+ SUCC_ARGS %bb.1, %0
+ %1:gr32 = MOV32ri 8
+ JMP_1 %bb.1
+
+ bb.1:
+ RET64
+...
diff --git a/llvm/test/MachineVerifier/X86/succ-args-debug-in-cluster.mir b/llvm/test/MachineVerifier/X86/succ-args-debug-in-cluster.mir
new file mode 100644
index 0000000000000..04f598a3a874b
--- /dev/null
+++ b/llvm/test/MachineVerifier/X86/succ-args-debug-in-cluster.mir
@@ -0,0 +1,21 @@
+# RUN: not --crash llc %s -mtriple=x86_64-- -run-pass=none -filetype=null 2>&1 | FileCheck %s
+
+# The SUCC_ARGS cluster must be contiguous: not even a debug instruction may sit
+# between a SUCC_ARGS and the terminators, so that the succ_args() range
+# (spanning getFirstSuccArgs()..getFirstTerminator()) yields only SUCC_ARGS and
+# no consumer misreads a debug instruction's operand 0 as a block.
+# CHECK: *** Bad machine code: Non-terminator instruction after SUCC_ARGS ***
+---
+name: succ_args_debug_in_cluster
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1
+ %0:gr32 = MOV32ri 7
+ SUCC_ARGS %bb.1, %0
+ DBG_VALUE %0, $noreg
+ JMP_1 %bb.1
+
+ bb.1:
+ RET64
+...
diff --git a/llvm/test/MachineVerifier/X86/succ-args-empty.mir b/llvm/test/MachineVerifier/X86/succ-args-empty.mir
new file mode 100644
index 0000000000000..8723cb58972b0
--- /dev/null
+++ b/llvm/test/MachineVerifier/X86/succ-args-empty.mir
@@ -0,0 +1,33 @@
+# RUN: split-file %s %t
+
+# A SUCC_ARGS must forward at least one value; the bare successor form and the
+# operand-less form are both malformed.
+
+;--- no-values.mir
+# RUN: not --crash llc %t/no-values.mir -mtriple=x86_64-- -run-pass=none -filetype=null 2>&1 | FileCheck %t/no-values.mir
+# CHECK: *** Bad machine code: SUCC_ARGS must forward at least one value ***
+---
+name: no_values
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1
+ SUCC_ARGS %bb.1
+ JMP_1 %bb.1
+
+ bb.1:
+ RET64
+...
+
+;--- no-successor.mir
+# RUN: not --crash llc %t/no-successor.mir -mtriple=x86_64-- -run-pass=none -filetype=null 2>&1 | FileCheck %t/no-successor.mir
+# CHECK: *** Bad machine code: SUCC_ARGS must have a successor block operand ***
+---
+name: no_successor
+tracksRegLiveness: true
+body: |
+ bb.0:
+ %0:gr32 = MOV32ri 7
+ SUCC_ARGS %0
+ RET64
+...
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td
index e0b802447ea2a..981ba0c8633c5 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-imms.td
@@ -34,8 +34,8 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(20), GIMT_Encode2({{[0-9]+}}), /*)*//*default:*//*Label 3*/ GIMT_Encode4([[L579:[0-9]+]]),
-// CHECK-NEXT: /*TargetOpcode::COPY*//*Label 0*/ GIMT_Encode4([[L462:[0-9]+]]), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(21), GIMT_Encode2({{[0-9]+}}), /*)*//*default:*//*Label 3*/ GIMT_Encode4([[L579:[0-9]+]]),
+// CHECK-NEXT: /*TargetOpcode::COPY*//*Label 0*/ GIMT_Encode4([[L462:[0-9]+]]), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
// CHECK-NEXT: /*TargetOpcode::G_CONSTANT*//*Label 1*/ GIMT_Encode4([[L493:[0-9]+]]), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
// CHECK-NEXT: /*TargetOpcode::G_ZEXT*//*Label 2*/ GIMT_Encode4({{[0-9]+}}),
// CHECK-NEXT: // Label 0: @[[L462]]
diff --git a/llvm/test/TableGen/get-named-operand-idx.td b/llvm/test/TableGen/get-named-operand-idx.td
index 31de6faec0da4..fab74e2b6447e 100644
--- a/llvm/test/TableGen/get-named-operand-idx.td
+++ b/llvm/test/TableGen/get-named-operand-idx.td
@@ -98,8 +98,8 @@ defm : RemapAllTargetPseudoPointerOperands<RegClass>;
// CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-// CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2,
-// CHECK-NEXT: 0,
+// CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
+// CHECK-NEXT: 2, 0,
// CHECK-NEXT: };
// CHECK-NEXT: return InstructionIndex[Opcode];
// CHECK-NEXT: }
More information about the llvm-branch-commits
mailing list