[llvm] ae35188 - [GISel] Fix match tree emitter.
Kai Nacke via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 17 17:04:16 PDT 2022
Author: Kai Nacke
Date: 2022-09-18T00:00:15Z
New Revision: ae35188f973eb77f5fb22e55d0b8bdac0d15e89b
URL: https://github.com/llvm/llvm-project/commit/ae35188f973eb77f5fb22e55d0b8bdac0d15e89b
DIFF: https://github.com/llvm/llvm-project/commit/ae35188f973eb77f5fb22e55d0b8bdac0d15e89b.diff
LOG: [GISel] Fix match tree emitter.
The following changes are necessasy to get the generated tree
matcher to compile:
- In CodeExpansions::declare(), the assert() prevents connecting
two instructions. E.g. the match code
(match (MUL $t, $s1, $s2),
(SUB $d, $t, $s3)),
results in two declarations of $t, one for the def and one for
the use. Removing the assertion allows this construct.
If $t is later used, it is one of the operands, which should be
perfectly fine.
- The code emitted in GIMatchTreeVRegDefPartitioner::generatePartitionSelectorCode()
is not compilable:
- The value of NewInstrID should be emitted, not the name
- Both calls involving getOperand() end with one parenthesis too many
- Swaps generated condition for the partition code in the latter function
It also changes the rules i2p_to_p2i, fabs_fabs_fold, and fneg_fneg_fold
to use the tree matcher for a linear match. These rules are tested by:
CodeGen/AArch64/GlobalISel/combine-fabs.mir
CodeGen/AArch64/GlobalISel/combine-fneg.mir
CodeGen/AArch64/GlobalISel/combine-ptrtoint.mir
CodeGen/AMDGPU/GlobalISel/combine-add-nullptr.mir
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D133257
Added:
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/test/TableGen/GICombinerEmitter/match-tree.td
llvm/utils/TableGen/GlobalISel/CodeExpansions.h
llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index d5e323523024e..fe1585e4600d6 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -362,7 +362,6 @@ class CombinerHelper {
void applyCombineI2PToP2I(MachineInstr &MI, Register &Reg);
/// Transform PtrToInt(IntToPtr(x)) to x.
- bool matchCombineP2IToI2P(MachineInstr &MI, Register &Reg);
void applyCombineP2IToI2P(MachineInstr &MI, Register &Reg);
/// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
@@ -389,11 +388,7 @@ class CombinerHelper {
void applyCombineExtOfExt(MachineInstr &MI,
std::tuple<Register, unsigned> &MatchInfo);
- /// Transform fneg(fneg(x)) to x.
- bool matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg);
-
- /// Match fabs(fabs(x)) to fabs(x).
- bool matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
+ /// Transform fabs(fabs(x)) to fabs(x).
void applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
/// Transform fabs(fneg(x)) to fabs(x).
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 5ec829f29869e..26726787e659f 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -416,10 +416,11 @@ def p2i_to_i2p: GICombineRule<
// Fold ptr2int(int2ptr(x)) -> x
def i2p_to_p2i: GICombineRule<
- (defs root:$root, register_matchinfo:$info),
- (match (wip_match_opcode G_PTRTOINT):$root,
- [{ return Helper.matchCombineP2IToI2P(*${root}, ${info}); }]),
- (apply [{ Helper.applyCombineP2IToI2P(*${root}, ${info}); }])
+ (defs root:$dst, register_matchinfo:$info),
+ (match (G_INTTOPTR $t, $ptr),
+ (G_PTRTOINT $dst, $t):$mi,
+ [{ ${info} = ${ptr}.getReg(); }]),
+ (apply [{ Helper.applyCombineP2IToI2P(*${mi}, ${info}); }])
>;
// Fold add ptrtoint(x), y -> ptrtoint (ptr_add x), y
@@ -529,10 +530,11 @@ def not_cmp_fold : GICombineRule<
// Fold (fneg (fneg x)) -> x.
def fneg_fneg_fold: GICombineRule <
- (defs root:$root, register_matchinfo:$matchinfo),
- (match (wip_match_opcode G_FNEG):$root,
- [{ return Helper.matchCombineFNegOfFNeg(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (defs root:$dst, register_matchinfo:$matchinfo),
+ (match (G_FNEG $t, $src),
+ (G_FNEG $dst, $t):$mi,
+ [{ ${matchinfo} = ${src}.getReg(); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithReg(*${mi}, ${matchinfo}); }])
>;
// Fold (unmerge(merge x, y, z)) -> z, y, z.
@@ -554,10 +556,11 @@ def merge_unmerge : GICombineRule<
// Fold (fabs (fabs x)) -> (fabs x).
def fabs_fabs_fold: GICombineRule<
- (defs root:$root, register_matchinfo:$matchinfo),
- (match (wip_match_opcode G_FABS):$root,
- [{ return Helper.matchCombineFAbsOfFAbs(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (defs root:$dst, register_matchinfo:$matchinfo),
+ (match (G_FABS $abs, $src),
+ (G_FABS $dst, $abs):$mi,
+ [{ ${matchinfo} = ${abs}.getReg(); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithReg(*${mi}, ${matchinfo}); }])
>;
// Fold (fabs (fneg x)) -> (fabs x).
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 070a70aeb9285..5ba8bfefe1a40 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2019,12 +2019,6 @@ void CombinerHelper::applyCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
MI.eraseFromParent();
}
-bool CombinerHelper::matchCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT");
- Register SrcReg = MI.getOperand(1).getReg();
- return mi_match(SrcReg, MRI, m_GIntToPtr(m_Reg(Reg)));
-}
-
void CombinerHelper::applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT");
Register DstReg = MI.getOperand(0).getReg();
@@ -2195,19 +2189,6 @@ void CombinerHelper::applyCombineMulByNegativeOne(MachineInstr &MI) {
MI.eraseFromParent();
}
-bool CombinerHelper::matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_FNEG && "Expected a G_FNEG");
- Register SrcReg = MI.getOperand(1).getReg();
- return mi_match(SrcReg, MRI, m_GFNeg(m_Reg(Reg)));
-}
-
-bool CombinerHelper::matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src) {
- assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
- Src = MI.getOperand(1).getReg();
- Register AbsSrc;
- return mi_match(Src, MRI, m_GFabs(m_Reg(AbsSrc)));
-}
-
bool CombinerHelper::matchCombineFAbsOfFNeg(MachineInstr &MI,
BuildFnTy &MatchInfo) {
assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
diff --git a/llvm/test/TableGen/GICombinerEmitter/match-tree.td b/llvm/test/TableGen/GICombinerEmitter/match-tree.td
index fc911fb2f29c5..64ab4350878af 100644
--- a/llvm/test/TableGen/GICombinerEmitter/match-tree.td
+++ b/llvm/test/TableGen/GICombinerEmitter/match-tree.td
@@ -1,6 +1,10 @@
// RUN: llvm-tblgen -I %p/../../../include -gen-global-isel-combiner \
// RUN: -combiners=MyCombinerHelper -gicombiner-stop-after-build %s \
// RUN: -o %t.inc | FileCheck %s
+//
+// RUN: llvm-tblgen -I %p/../../../include -gen-global-isel-combiner \
+// RUN: -combiners=MyCombinerHelper %s | \
+// RUN: FileCheck --check-prefix=CODE %s
include "llvm/Target/Target.td"
include "llvm/Target/GlobalISel/Combine.td"
@@ -140,3 +144,88 @@ def MyCombinerHelper: GICombinerHelper<"GenMyCombinerHelper", [
// CHECK-DAG: Node[[N17]] -> Node[[N18]] [label="#0 MyTarget::SEXT"]
// CHECK-DAG: Node[[N17]] -> Node[[N19]] [label="#1 MyTarget::ZEXT"]
// CHECK-LABEL: {{^}$}}
+
+
+// Check the generated source code.
+
+// CODE-LABEL: GenMyCombinerHelper::tryCombineAll
+
+// Check the first partition. The numbers correspond to the labels above.
+// CODE: switch (MIs[0]->getOpcode()) {
+// CODE-NEXT: case MyTarget::SUB: Partition = 0; break;
+// CODE-NEXT: case MyTarget::MOV: Partition = 1; break;
+// CODE-NEXT: case MyTarget::ADD: Partition = 2; break;
+// CODE-NEXT: case MyTarget::TRUNC: Partition = 3; break;
+// CODE-NEXT: }
+
+// Check that the correct partition is choosen if operand 1 is a register.
+
+// CODE: if (Partition == 0 /* MyTarget::SUB */) {
+// CODE-NEXT: Partition = -1;
+// CODE-NEXT: if (MIs.size() <= 1) MIs.resize(2);
+// CODE-NEXT: MIs[1] = nullptr;
+// CODE-NEXT: if (MIs[0]->getOperand(1).isReg())
+// CODE-NEXT: MIs[1] = MRI.getVRegDef(MIs[0]->getOperand(1).getReg());
+// CODE-NEXT: if (MIs[1] == nullptr) Partition = 1;
+// CODE-NEXT: if (MIs[1] != nullptr) Partition = 0;
+
+
+// Check that the MUL opcode is tested.
+
+// CODE: if (Partition == 0 /* true */) {
+// CODE-NEXT: Partition = -1;
+// CODE-NEXT: switch (MIs[1]->getOpcode()) {
+// CODE-NEXT: case MyTarget::MUL: Partition = 0; break;
+// CODE-NEXT: default: Partition = 1; break;
+// CODE-NEXT: }
+
+// Check that action for MUL is executed.
+
+// CODE: if (Partition == 0 /* MyTarget::MUL */) {
+// CODE-NEXT: // Leaf name: Rule0
+// CODE-NEXT: // Rule: Rule0
+// CODE-NEXT: if (!RuleConfig->isRuleDisabled(0)) {
+// CODE-NEXT: if (1
+// CODE-NEXT:) {
+// CODE-NEXT: APPLY
+// CODE-NEXT: return true;
+// CODE-NEXT: }
+// CODE-NEXT: }
+// CODE-NEXT: llvm_unreachable("Combine rule elision was incorrect");
+// CODE-NEXT: return false;
+// CODE-NEXT: }
+
+// Check that the other rule involving SUB (Rule5) is run otherwise.
+
+// CODE-NEXT: if (Partition == 1 /* * or nullptr */) {
+// CODE-NEXT: // Leaf name: Rule5
+// CODE-NEXT: // Rule: Rule5
+// CODE-NEXT: if (!RuleConfig->isRuleDisabled(5)) {
+// CODE-NEXT: if (1
+// CODE-NEXT:) {
+// CODE-NEXT: APPLY
+// CODE-NEXT: return true;
+// CODE-NEXT: }
+// CODE-NEXT: }
+// CODE-NEXT: llvm_unreachable("Combine rule elision was incorrect");
+// CODE-NEXT: return false;
+// CODE-NEXT: }
+// CODE-NEXT: }
+
+// Check that Rule5 is run if operand 1 is not MUL.
+
+// CODE-NEXT: if (Partition == 1 /* false */) {
+// CODE-NEXT: // Leaf name: Rule5
+// CODE-NEXT: // Rule: Rule5
+// CODE-NEXT: if (!RuleConfig->isRuleDisabled(5)) {
+// CODE-NEXT: if (1
+// CODE-NEXT:) {
+// CODE-NEXT: APPLY
+// CODE-NEXT: return true;
+// CODE-NEXT: }
+// CODE-NEXT: }
+// CODE-NEXT: llvm_unreachable("Combine rule elision was incorrect");
+// CODE-NEXT: return false;
+// CODE-NEXT: }
+// CODE-NEXT: }
+
diff --git a/llvm/utils/TableGen/GlobalISel/CodeExpansions.h b/llvm/utils/TableGen/GlobalISel/CodeExpansions.h
index bb890ec8f57ef..f536e801b27f3 100644
--- a/llvm/utils/TableGen/GlobalISel/CodeExpansions.h
+++ b/llvm/utils/TableGen/GlobalISel/CodeExpansions.h
@@ -24,9 +24,9 @@ class CodeExpansions {
public:
void declare(StringRef Name, StringRef Expansion) {
- bool Inserted = Expansions.try_emplace(Name, Expansion).second;
- assert(Inserted && "Declared variable twice");
- (void)Inserted;
+ // Duplicates are not inserted. The expansion refers to
diff erent
+ // MachineOperands using the same virtual register.
+ Expansions.try_emplace(Name, Expansion);
}
std::string lookup(StringRef Variable) const {
diff --git a/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp b/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
index 42055ad4f608e..f797e042e6a05 100644
--- a/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
+++ b/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
@@ -762,17 +762,18 @@ void GIMatchTreeVRegDefPartitioner::emitPartitionResults(
void GIMatchTreeVRegDefPartitioner::generatePartitionSelectorCode(
raw_ostream &OS, StringRef Indent) const {
- OS << Indent << "Partition = -1\n"
- << Indent << "if (MIs.size() <= NewInstrID) MIs.resize(NewInstrID + 1);\n"
+ OS << Indent << "Partition = -1;\n"
+ << Indent << "if (MIs.size() <= " << NewInstrID << ") MIs.resize("
+ << (NewInstrID + 1) << ");\n"
<< Indent << "MIs[" << NewInstrID << "] = nullptr;\n"
- << Indent << "if (MIs[" << InstrID << "].getOperand(" << OpIdx
- << ").isReg()))\n"
+ << Indent << "if (MIs[" << InstrID << "]->getOperand(" << OpIdx
+ << ").isReg())\n"
<< Indent << " MIs[" << NewInstrID << "] = MRI.getVRegDef(MIs[" << InstrID
- << "].getOperand(" << OpIdx << ").getReg()));\n";
+ << "]->getOperand(" << OpIdx << ").getReg());\n";
for (const auto &Pair : ResultToPartition)
OS << Indent << "if (MIs[" << NewInstrID << "] "
- << (Pair.first ? "==" : "!=")
+ << (Pair.first ? "!=" : "==")
<< " nullptr) Partition = " << Pair.second << ";\n";
OS << Indent << "if (Partition == -1) return false;\n";
More information about the llvm-commits
mailing list