summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Instruction.h7
-rw-r--r--llvm/include/llvm/IR/PatternMatch.h41
-rw-r--r--llvm/lib/Analysis/AssumptionCache.cpp11
3 files changed, 49 insertions, 10 deletions
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 00c431834e3..d8db29e1588 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -152,9 +152,14 @@ public:
return getOpcode() == AShr;
}
+ /// Determine if the Opcode is and/or/xor.
+ static inline bool isBitwiseLogicOp(unsigned Opcode) {
+ return Opcode == And || Opcode == Or || Opcode == Xor;
+ }
+
/// Return true if this is and/or/xor.
inline bool isBitwiseLogicOp() const {
- return getOpcode() == And || getOpcode() == Or || getOpcode() == Xor;
+ return isBitwiseLogicOp(getOpcode());
}
/// Determine if the OpCode is one of the CastInst instructions.
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 015a17e8e7c..84dc2a1fa48 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -704,6 +704,47 @@ m_IDiv(const LHS &L, const RHS &R) {
}
//===----------------------------------------------------------------------===//
+// Class that matches a group of binary opcodes.
+//
+template <typename LHS_t, typename RHS_t, typename Predicate>
+struct BinOpPred_match : Predicate {
+ LHS_t L;
+ RHS_t R;
+
+ BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *I = dyn_cast<Instruction>(V))
+ return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+ if (auto *CE = dyn_cast<ConstantExpr>(V))
+ return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+struct is_shift_op {
+ bool isOpType(unsigned Opcode) { return Instruction::isShift(Opcode); }
+};
+
+struct is_bitwiselogic_op {
+ bool isOpType(unsigned Opcode) { return Instruction::isBitwiseLogicOp(Opcode); }
+};
+
+/// \brief Matches shift operations.
+template <typename LHS, typename RHS>
+inline BinOpPred_match<LHS, RHS, is_shift_op>
+m_Shift(const LHS &L, const RHS &R) {
+ return BinOpPred_match<LHS, RHS, is_shift_op>(L, R);
+}
+
+/// \brief Matches bitwise logic operations.
+template <typename LHS, typename RHS>
+inline BinOpPred_match<LHS, RHS, is_bitwiselogic_op>
+m_BitwiseLogic(const LHS &L, const RHS &R) {
+ return BinOpPred_match<LHS, RHS, is_bitwiselogic_op>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
// Class that matches exact binary ops.
//
template <typename SubPattern_t> struct Exact_match {
diff --git a/llvm/lib/Analysis/AssumptionCache.cpp b/llvm/lib/Analysis/AssumptionCache.cpp
index 0468c794e81..3ff27890dc3 100644
--- a/llvm/lib/Analysis/AssumptionCache.cpp
+++ b/llvm/lib/Analysis/AssumptionCache.cpp
@@ -84,18 +84,11 @@ void AssumptionCache::updateAffectedValues(CallInst *CI) {
Value *B;
ConstantInt *C;
// (A & B) or (A | B) or (A ^ B).
- if (match(V,
- m_CombineOr(m_And(m_Value(A), m_Value(B)),
- m_CombineOr(m_Or(m_Value(A), m_Value(B)),
- m_Xor(m_Value(A), m_Value(B)))))) {
+ if (match(V, m_BitwiseLogic(m_Value(A), m_Value(B)))) {
AddAffected(A);
AddAffected(B);
// (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
- } else if (match(V,
- m_CombineOr(m_Shl(m_Value(A), m_ConstantInt(C)),
- m_CombineOr(m_LShr(m_Value(A), m_ConstantInt(C)),
- m_AShr(m_Value(A),
- m_ConstantInt(C)))))) {
+ } else if (match(V, m_Shift(m_Value(A), m_ConstantInt(C)))) {
AddAffected(A);
}
};
OpenPOWER on IntegriCloud