Skip to content

Commit d6a88e7

Browse files
author
Jessica Paquette
committed
[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
1 parent 6e09818 commit d6a88e7

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,13 @@ inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
6868
return SpecificConstantMatch(RequestedValue);
6969
}
7070

71-
/// Matches an integer 0.
71+
///{
72+
/// Convenience matchers for specific integer values.
7273
inline SpecificConstantMatch m_ZeroInt() { return SpecificConstantMatch(0); }
74+
inline SpecificConstantMatch m_AllOnesInt() {
75+
return SpecificConstantMatch(-1);
76+
}
77+
///}
7378

7479
// TODO: Rework this for different kinds of MachineOperand.
7580
// Currently assumes the Src for a match is a register.
@@ -451,6 +456,14 @@ m_Neg(const SrcTy &&Src) {
451456
return m_GSub(m_ZeroInt(), Src);
452457
}
453458

459+
/// Matches a register not-ed by a G_XOR.
460+
/// G_XOR %not_reg, -1
461+
template <typename SrcTy>
462+
inline BinaryOp_match<SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true>
463+
m_Not(const SrcTy &&Src) {
464+
return m_GXor(Src, m_AllOnesInt());
465+
}
466+
454467
} // namespace GMIPatternMatch
455468
} // namespace llvm
456469

llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,17 @@ TEST_F(AArch64GISelMITest, MatchZeroInt) {
426426
EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_ZeroInt()));
427427
}
428428

429+
TEST_F(AArch64GISelMITest, MatchAllOnesInt) {
430+
setUp();
431+
if (!TM)
432+
return;
433+
auto AllOnes = B.buildConstant(LLT::scalar(64), -1);
434+
EXPECT_TRUE(mi_match(AllOnes.getReg(0), *MRI, m_AllOnesInt()));
435+
436+
auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
437+
EXPECT_FALSE(mi_match(FortyTwo.getReg(0), *MRI, m_AllOnesInt()));
438+
}
439+
429440
TEST_F(AArch64GISelMITest, MatchNeg) {
430441
setUp();
431442
if (!TM)
@@ -457,6 +468,39 @@ TEST_F(AArch64GISelMITest, MatchNeg) {
457468
EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Neg(m_Reg(NegatedReg))));
458469
EXPECT_EQ(NegatedReg, Copies[0]);
459470
}
471+
472+
TEST_F(AArch64GISelMITest, MatchNot) {
473+
setUp();
474+
if (!TM)
475+
return;
476+
477+
LLT s64 = LLT::scalar(64);
478+
auto AllOnes = B.buildConstant(LLT::scalar(64), -1);
479+
auto NotInst1 = B.buildXor(s64, Copies[0], AllOnes);
480+
Register NotReg;
481+
482+
// Match: G_XOR %NotReg, -1
483+
EXPECT_TRUE(mi_match(NotInst1.getReg(0), *MRI, m_Not(m_Reg(NotReg))));
484+
EXPECT_EQ(NotReg, Copies[0]);
485+
486+
// Match: G_XOR -1, %NotReg
487+
auto NotInst2 = B.buildXor(s64, AllOnes, Copies[1]);
488+
EXPECT_TRUE(mi_match(NotInst2.getReg(0), *MRI, m_Not(m_Reg(NotReg))));
489+
EXPECT_EQ(NotReg, Copies[1]);
490+
491+
// Don't match: G_XOR %NotReg, 42
492+
auto FortyTwo = B.buildConstant(LLT::scalar(64), 42);
493+
auto WrongCst = B.buildXor(s64, Copies[0], FortyTwo);
494+
EXPECT_FALSE(mi_match(WrongCst.getReg(0), *MRI, m_Not(m_Reg(NotReg))));
495+
496+
// Complex testcase.
497+
// %xor = G_XOR %NotReg, -1
498+
// %add = G_ADD %x, %xor
499+
auto AddInst = B.buildAdd(s64, Copies[1], NotInst1);
500+
NotReg = Register();
501+
EXPECT_TRUE(mi_match(AddInst.getReg(2), *MRI, m_Not(m_Reg(NotReg))));
502+
EXPECT_EQ(NotReg, Copies[0]);
503+
}
460504
} // namespace
461505

462506
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)