summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2014-01-05 03:28:29 +0000
committerChandler Carruth <chandlerc@gmail.com>2014-01-05 03:28:29 +0000
commit272690897ed88b0a53538aefafd7d084b3a7243c (patch)
tree6e8366fed7759721a622f36ba0adb47754b4a647 /include
parentb54a0ac20ac76f845026eab8fca112d1d40927de (diff)
downloadllvm-272690897ed88b0a53538aefafd7d084b3a7243c.tar.gz
llvm-272690897ed88b0a53538aefafd7d084b3a7243c.tar.bz2
llvm-272690897ed88b0a53538aefafd7d084b3a7243c.tar.xz
Add support to the pattern match library for matching NSW and NUW
instructions. I needed this for a quick experiment I was making, and while I've no idea if that will ever get committed, I didn't want to throw away the pattern match code and for anyone else to have to write it again. I've added unittests to make sure this works correctly. In fun news, this also uncovered the IRBuilder bug. Doh! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198541 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Support/PatternMatch.h90
1 files changed, 90 insertions, 0 deletions
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 240bb81d31..97739b0869 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -498,6 +498,96 @@ m_AShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
}
+template<typename LHS_t, typename RHS_t, unsigned Opcode, unsigned WrapFlags = 0>
+struct OverflowingBinaryOp_match {
+ LHS_t L;
+ RHS_t R;
+
+ OverflowingBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (OverflowingBinaryOperator *Op = dyn_cast<OverflowingBinaryOperator>(V)) {
+ if (Op->getOpcode() != Opcode)
+ return false;
+ if (WrapFlags & OverflowingBinaryOperator::NoUnsignedWrap &&
+ !Op->hasNoUnsignedWrap())
+ return false;
+ if (WrapFlags & OverflowingBinaryOperator::NoSignedWrap &&
+ !Op->hasNoSignedWrap())
+ return false;
+ return L.match(Op->getOperand(0)) && R.match(Op->getOperand(1));
+ }
+ return false;
+ }
+};
+
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWAdd(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWSub(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWMul(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWShl(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWAdd(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWSub(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWMul(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWShl(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+
//===----------------------------------------------------------------------===//
// Class that matches two different binary ops.
//