[GlobalISel] Add convenience matchers for nots and all-ones constants

Add a convenience matcher which handles

```
G_XOR %not_reg, -1
```

And a convenience matcher which returns true if an integer constant is
all-ones.

Differential Revision: https://reviews.llvm.org/D91459
This commit is contained in:
Jessica Paquette 2020-11-13 11:28:55 -08:00
parent 6e098189db
commit d6a88e7e19
2 changed files with 58 additions and 1 deletions

View File

@ -68,8 +68,13 @@ inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
return SpecificConstantMatch(RequestedValue);
}
/// Matches an integer 0.
///{
/// Convenience matchers for specific integer values.
inline SpecificConstantMatch m_ZeroInt() { return SpecificConstantMatch(0); }
inline SpecificConstantMatch m_AllOnesInt() {
return SpecificConstantMatch(-1);
}
///}
// TODO: Rework this for different kinds of MachineOperand.
// Currently assumes the Src for a match is a register.
@ -451,6 +456,14 @@ m_Neg(const SrcTy &&Src) {
return m_GSub(m_ZeroInt(), Src);
}
/// Matches a register not-ed by a G_XOR.
/// G_XOR %not_reg, -1
template <typename SrcTy>
inline BinaryOp_match<SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true>
m_Not(const SrcTy &&Src) {
return m_GXor(Src, m_AllOnesInt());
}
} // namespace GMIPatternMatch
} // namespace llvm

View File

@ -426,6 +426,17 @@ TEST_F(AArch64GISelMITest, MatchZeroInt) {
EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_ZeroInt()));
}
TEST_F(AArch64GISelMITest, MatchAllOnesInt) {
setUp();
if (!TM)
return;
auto AllOnes = B.buildConstant(LLT::scalar(64), -1);
EXPECT_TRUE(mi_match(AllOnes.getReg(0), *MRI, m_AllOnesInt()));
auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_AllOnesInt()));
}
TEST_F(AArch64GISelMITest, MatchNeg) {
setUp();
if (!TM)
@ -457,6 +468,39 @@ TEST_F(AArch64GISelMITest, MatchNeg) {
EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Neg(m_Reg(NegatedReg))));
EXPECT_EQ(NegatedReg, Copies[0]);
}
TEST_F(AArch64GISelMITest, MatchNot) {
setUp();
if (!TM)
return;
LLT s64 = LLT::scalar(64);
auto AllOnes = B.buildConstant(LLT::scalar(64), -1);
auto NotInst1 = B.buildXor(s64, Copies[0], AllOnes);
Register NotReg;
// Match: G_XOR %NotReg, -1
EXPECT_TRUE(mi_match(NotInst1.getReg(0), *MRI, m_Not(m_Reg(NotReg))));
EXPECT_EQ(NotReg, Copies[0]);
// Match: G_XOR -1, %NotReg
auto NotInst2 = B.buildXor(s64, AllOnes, Copies[1]);
EXPECT_TRUE(mi_match(NotInst2.getReg(0), *MRI, m_Not(m_Reg(NotReg))));
EXPECT_EQ(NotReg, Copies[1]);
// Don't match: G_XOR %NotReg, 42
auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
auto WrongCst = B.buildXor(s64, Copies[0], FortyTwo);
EXPECT_FALSE(mi_match(WrongCst.getReg(0), *MRI, m_Not(m_Reg(NotReg))));
// Complex testcase.
// %xor = G_XOR %NotReg, -1
// %add = G_ADD %x, %xor
auto AddInst = B.buildAdd(s64, Copies[1], NotInst1);
NotReg = Register();
EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Not(m_Reg(NotReg))));
EXPECT_EQ(NotReg, Copies[0]);
}
} // namespace
int main(int argc, char **argv) {