forked from OSchip/llvm-project
[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:
parent
6e098189db
commit
d6a88e7e19
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue