[llvm] b184a2e - [GlobalISel] Add matchers for specific constants and a matcher for negations
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 13 09:25:32 PST 2020
Author: Jessica Paquette
Date: 2020-11-13T09:24:54-08:00
New Revision: b184a2eccf3b80eb3ab741e983d4637111942815
URL: https://github.com/llvm/llvm-project/commit/b184a2eccf3b80eb3ab741e983d4637111942815
DIFF: https://github.com/llvm/llvm-project/commit/b184a2eccf3b80eb3ab741e983d4637111942815.diff
LOG: [GlobalISel] Add matchers for specific constants and a matcher for negations
It's fairly common to need matchers for a specific constant value, or for
common idioms like finding a negated register.
Add
- `m_SpecificICst`, which returns true when matching a specific value..
- `m_ZeroInt`, which returns true when an integer 0 is matched.
- `m_Neg`, which returns when a register is negated.
Also update a few places which use idioms related to the new matchers.
Differential Revision: https://reviews.llvm.org/D91397
Added:
Modified:
llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/lib/CodeGen/GlobalISel/Utils.cpp
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index e337a835b4fa..8f1cd1a1408a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -53,6 +53,24 @@ struct ConstantMatch {
inline ConstantMatch m_ICst(int64_t &Cst) { return ConstantMatch(Cst); }
+/// Matcher for a specific constant value.
+struct SpecificConstantMatch {
+ int64_t RequestedVal;
+ SpecificConstantMatch(int64_t RequestedVal) : RequestedVal(RequestedVal) {}
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
+ int64_t MatchedVal;
+ return mi_match(Reg, MRI, m_ICst(MatchedVal)) && MatchedVal == RequestedVal;
+ }
+};
+
+/// Matches a constant equal to \p RequestedValue.
+inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
+ return SpecificConstantMatch(RequestedValue);
+}
+
+/// Matches an integer 0.
+inline SpecificConstantMatch m_ZeroInt() { return SpecificConstantMatch(0); }
+
// TODO: Rework this for
diff erent kinds of MachineOperand.
// Currently assumes the Src for a match is a register.
// We might want to support taking in some MachineOperands and call getReg on
@@ -425,6 +443,14 @@ m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
TargetOpcode::G_INSERT_VECTOR_ELT>(Src0, Src1, Src2);
}
+/// Matches a register negated by a G_SUB.
+/// G_SUB 0, %negated_reg
+template <typename SrcTy>
+inline BinaryOp_match<SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB>
+m_Neg(const SrcTy &&Src) {
+ return m_GSub(m_ZeroInt(), Src);
+}
+
} // namespace GMIPatternMatch
} // namespace llvm
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 32bdba442b56..79f74a47d83c 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2614,9 +2614,7 @@ bool CombinerHelper::matchSimplifyAddToSub(
// ((0-A) + B) -> B - A
// (A + (0-B)) -> A - B
auto CheckFold = [&](Register &MaybeSub, Register &MaybeNewLHS) {
- int64_t Cst;
- if (!mi_match(MaybeSub, MRI, m_GSub(m_ICst(Cst), m_Reg(NewRHS))) ||
- Cst != 0)
+ if (!mi_match(MaybeSub, MRI, m_Neg(m_Reg(NewRHS))))
return false;
NewLHS = MaybeNewLHS;
return true;
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index a72f9f66560c..4d9580de3b7b 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -682,9 +682,7 @@ static bool isBuildVectorConstantSplat(const MachineInstr &MI,
const unsigned NumOps = MI.getNumOperands();
for (unsigned I = 1; I != NumOps; ++I) {
Register Element = MI.getOperand(I).getReg();
- int64_t ElementValue;
- if (!mi_match(Element, MRI, m_ICst(ElementValue)) ||
- ElementValue != SplatValue)
+ if (!mi_match(Element, MRI, m_SpecificICst(SplatValue)))
return false;
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 218aa19d548e..4584308a1002 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -1837,10 +1837,7 @@ bool AArch64InstructionSelector::convertPtrAddToAdd(
// Also take the opportunity here to try to do some optimization.
// Try to convert this into a G_SUB if the offset is a 0-x negate idiom.
Register NegatedReg;
- int64_t Cst;
- if (!mi_match(I.getOperand(2).getReg(), MRI,
- m_GSub(m_ICst(Cst), m_Reg(NegatedReg))) ||
- Cst != 0)
+ if (!mi_match(I.getOperand(2).getReg(), MRI, m_Neg(m_Reg(NegatedReg))))
return true;
I.getOperand(2).setReg(NegatedReg);
I.setDesc(TII.get(TargetOpcode::G_SUB));
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 645e85388490..43f28729baa1 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -291,8 +291,7 @@ static bool matchDupFromInsertVectorElt(int Lane, MachineInstr &MI,
return false;
// Match the index constant 0.
- int64_t Index = 0;
- if (!mi_match(InsMI->getOperand(3).getReg(), MRI, m_ICst(Index)) || Index)
+ if (!mi_match(InsMI->getOperand(3).getReg(), MRI, m_ZeroInt()))
return false;
MatchInfo = ShuffleVectorPseudo(AArch64::G_DUP, MI.getOperand(0).getReg(),
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index 638ec0e7ce06..e5cbcb3ccdb7 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -633,7 +633,6 @@ bool AMDGPUInstructionSelector::selectG_BUILD_VECTOR_TRUNC(
Register ShiftSrc0;
Register ShiftSrc1;
- int64_t ShiftAmt;
// With multiple uses of the shift, this will duplicate the shift and
// increase register pressure.
@@ -645,14 +644,11 @@ bool AMDGPUInstructionSelector::selectG_BUILD_VECTOR_TRUNC(
// (build_vector_trunc $src0, $src1)
// => (S_PACK_LL_B32_B16 $src0, $src1)
- // FIXME: This is an inconvenient way to check a specific value
bool Shift0 = mi_match(
- Src0, *MRI, m_OneUse(m_GLShr(m_Reg(ShiftSrc0), m_ICst(ShiftAmt)))) &&
- ShiftAmt == 16;
+ Src0, *MRI, m_OneUse(m_GLShr(m_Reg(ShiftSrc0), m_SpecificICst(16))));
bool Shift1 = mi_match(
- Src1, *MRI, m_OneUse(m_GLShr(m_Reg(ShiftSrc1), m_ICst(ShiftAmt)))) &&
- ShiftAmt == 16;
+ Src1, *MRI, m_OneUse(m_GLShr(m_Reg(ShiftSrc1), m_SpecificICst(16))));
unsigned Opc = AMDGPU::S_PACK_LL_B32_B16;
if (Shift0 && Shift1) {
@@ -3474,9 +3470,7 @@ static Register matchZeroExtendFromS32(MachineRegisterInfo &MRI, Register Reg) {
if (Def->getOpcode() != AMDGPU::G_MERGE_VALUES)
return false;
- int64_t MergeRHS;
- if (mi_match(Def->getOperand(2).getReg(), MRI, m_ICst(MergeRHS)) &&
- MergeRHS == 0) {
+ if (mi_match(Def->getOperand(2).getReg(), MRI, m_ZeroInt())) {
return Def->getOperand(1).getReg();
}
diff --git a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
index 6a54084cacaf..c6a7f8e87bb0 100644
--- a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
@@ -392,6 +392,71 @@ TEST_F(AArch64GISelMITest, MatchMiscellaneous) {
match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
EXPECT_FALSE(match);
}
+
+TEST_F(AArch64GISelMITest, MatchSpecificConstant) {
+ setUp();
+ if (!TM)
+ return;
+
+ // Basic case: Can we match a G_CONSTANT with a specific value?
+ auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
+ EXPECT_TRUE(mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICst(42)));
+ EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_SpecificICst(123)));
+
+ // Test that this works inside of a more complex pattern.
+ LLT s64 = LLT::scalar(64);
+ auto MIBAdd = B.buildAdd(s64, Copies[0], FortyTwo);
+ EXPECT_TRUE(mi_match(MIBAdd.getReg(2), *MRI, m_SpecificICst(42)));
+
+ // Wrong constant.
+ EXPECT_FALSE(mi_match(MIBAdd.getReg(2), *MRI, m_SpecificICst(123)));
+
+ // No constant on the LHS.
+ EXPECT_FALSE(mi_match(MIBAdd.getReg(1), *MRI, m_SpecificICst(42)));
+}
+
+TEST_F(AArch64GISelMITest, MatchZeroInt) {
+ setUp();
+ if (!TM)
+ return;
+ auto Zero = B.buildConstant(LLT::scalar(64), 0);
+ EXPECT_TRUE(mi_match(Zero.getReg(0), *MRI, m_ZeroInt()));
+
+ auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
+ EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_ZeroInt()));
+}
+
+TEST_F(AArch64GISelMITest, MatchNeg) {
+ setUp();
+ if (!TM)
+ return;
+
+ LLT s64 = LLT::scalar(64);
+ auto Zero = B.buildConstant(LLT::scalar(64), 0);
+ auto NegInst = B.buildSub(s64, Zero, Copies[0]);
+ Register NegatedReg;
+
+ // Match: G_SUB = 0, %Reg
+ EXPECT_TRUE(mi_match(NegInst.getReg(0), *MRI, m_Neg(m_Reg(NegatedReg))));
+ EXPECT_EQ(NegatedReg, Copies[0]);
+
+ // Don't match: G_SUB = %Reg, 0
+ auto NotNegInst1 = B.buildSub(s64, Copies[0], Zero);
+ EXPECT_FALSE(mi_match(NotNegInst1.getReg(0), *MRI, m_Neg(m_Reg(NegatedReg))));
+
+ // Don't match: G_SUB = 42, %Reg
+ auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
+ auto NotNegInst2 = B.buildSub(s64, FortyTwo, Copies[0]);
+ EXPECT_FALSE(mi_match(NotNegInst2.getReg(0), *MRI, m_Neg(m_Reg(NegatedReg))));
+
+ // Complex testcase.
+ // %sub = G_SUB = 0, %negated_reg
+ // %add = G_ADD = %x, %sub
+ auto AddInst = B.buildAdd(s64, Copies[1], NegInst);
+ NegatedReg = Register();
+ EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Neg(m_Reg(NegatedReg))));
+ EXPECT_EQ(NegatedReg, Copies[0]);
+}
} // namespace
int main(int argc, char **argv) {
More information about the llvm-commits
mailing list