Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions llvm/include/llvm/IR/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,45 @@ inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
}

template <typename LHS_t, unsigned Opcode> struct ShiftLike_match {
LHS_t L;
uint64_t &R;

ShiftLike_match(const LHS_t &LHS, uint64_t &RHS) : L(LHS), R(RHS) {}

template <typename OpTy> bool match(OpTy *V) const {
if (auto *Op = dyn_cast<BinaryOperator>(V)) {
if (Op->getOpcode() == Opcode)
return m_ConstantInt(R).match(Op->getOperand(1)) &&
L.match(Op->getOperand(0));
}
// Interpreted as shiftop V, 0
R = 0;
return L.match(V);
}
};

/// Matches shl L, ConstShAmt or L itself (R will be set to zero in this case).
template <typename LHS>
inline ShiftLike_match<LHS, Instruction::Shl> m_ShlOrSelf(const LHS &L,
uint64_t &R) {
return ShiftLike_match<LHS, Instruction::Shl>(L, R);
}

/// Matches lshr L, ConstShAmt or L itself (R will be set to zero in this case).
template <typename LHS>
inline ShiftLike_match<LHS, Instruction::LShr> m_LShrOrSelf(const LHS &L,
uint64_t &R) {
return ShiftLike_match<LHS, Instruction::LShr>(L, R);
}

/// Matches ashr L, ConstShAmt or L itself (R will be set to zero in this case).
template <typename LHS>
inline ShiftLike_match<LHS, Instruction::AShr> m_AShrOrSelf(const LHS &L,
uint64_t &R) {
return ShiftLike_match<LHS, Instruction::AShr>(L, R);
}

template <typename LHS_t, typename RHS_t, unsigned Opcode,
unsigned WrapFlags = 0, bool Commutable = false>
struct OverflowingBinaryOp_match {
Expand Down
11 changes: 3 additions & 8 deletions llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3640,16 +3640,11 @@ static bool matchSubIntegerPackFromVector(Value *V, Value *&Vec,
int64_t &VecOffset,
SmallBitVector &Mask,
const DataLayout &DL) {
static const auto m_ConstShlOrSelf = [](const auto &Base, uint64_t &ShlAmt) {
ShlAmt = 0;
return m_CombineOr(m_Shl(Base, m_ConstantInt(ShlAmt)), Base);
};

// First try to match extractelement -> zext -> shl
uint64_t VecIdx, ShlAmt;
if (match(V, m_ConstShlOrSelf(m_ZExtOrSelf(m_ExtractElt(
m_Value(Vec), m_ConstantInt(VecIdx))),
ShlAmt))) {
if (match(V, m_ShlOrSelf(m_ZExtOrSelf(m_ExtractElt(m_Value(Vec),
m_ConstantInt(VecIdx))),
ShlAmt))) {
auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
if (!VecTy)
return false;
Expand Down
36 changes: 36 additions & 0 deletions llvm/unittests/IR/PatternMatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2621,4 +2621,40 @@ TEST_F(PatternMatchTest, PtrAdd) {
EXPECT_FALSE(match(OtherGEP, m_PtrAdd(m_Value(A), m_Value(B))));
}

TEST_F(PatternMatchTest, ShiftOrSelf) {
Type *I64Ty = Type::getInt64Ty(Ctx);
Constant *LHS = ConstantInt::get(I64Ty, 7);
Constant *ShAmt = ConstantInt::get(I64Ty, 16);
Value *Shl = IRB.CreateShl(LHS, ShAmt);
Value *LShr = IRB.CreateLShr(LHS, ShAmt);
Value *AShr = IRB.CreateAShr(LHS, ShAmt);
Value *Add = IRB.CreateAdd(LHS, LHS);

uint64_t ShAmtC;
Value *A;
EXPECT_TRUE(match(Shl, m_ShlOrSelf(m_Value(A), ShAmtC)));
EXPECT_EQ(A, LHS);
EXPECT_EQ(ShAmtC, 16U);

EXPECT_TRUE(match(Add, m_ShlOrSelf(m_Value(A), ShAmtC)));
EXPECT_EQ(A, Add);
EXPECT_EQ(ShAmtC, 0U);

EXPECT_TRUE(match(LShr, m_LShrOrSelf(m_Value(A), ShAmtC)));
EXPECT_EQ(A, LHS);
EXPECT_EQ(ShAmtC, 16U);

EXPECT_TRUE(match(Add, m_LShrOrSelf(m_Value(A), ShAmtC)));
EXPECT_EQ(A, Add);
EXPECT_EQ(ShAmtC, 0U);

EXPECT_TRUE(match(AShr, m_AShrOrSelf(m_Value(A), ShAmtC)));
EXPECT_EQ(A, LHS);
EXPECT_EQ(ShAmtC, 16U);

EXPECT_TRUE(match(Add, m_AShrOrSelf(m_Value(A), ShAmtC)));
EXPECT_EQ(A, Add);
EXPECT_EQ(ShAmtC, 0U);
}

} // anonymous namespace.
Loading