[llvm] 6cfbefb - [PatternMatch] Add m_WithOverflowInst and m_ExtractValue matchers

David Green via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 05:21:56 PDT 2019


Author: David Green
Date: 2019-10-31T12:19:29Z
New Revision: 6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692

URL: https://github.com/llvm/llvm-project/commit/6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692
DIFF: https://github.com/llvm/llvm-project/commit/6cfbefbc4a7ebcf3f2ee38962ddcd8df54719692.diff

LOG: [PatternMatch] Add m_WithOverflowInst and m_ExtractValue matchers

Used in D69245, these add pattern matchers for the WithOverflowInst
(capturing the result) and the ExtractValue instructions taking a
template parameter specifying the element being extracted.

Added: 
    

Modified: 
    llvm/include/llvm/IR/PatternMatch.h
    llvm/unittests/IR/PatternMatch.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 2851b24c05ae..37a2fe52ec11 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -35,6 +35,7 @@
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/Value.h"
@@ -558,6 +559,8 @@ inline bind_ty<const Value> m_Value(const Value *&V) { return V; }
 inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
 /// Match a binary operator, capturing it if we match.
 inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
+/// Match a with overflow intrinsic, capturing it if we match.
+inline bind_ty<WithOverflowInst> m_WithOverflowInst(WithOverflowInst *&I) { return I; }
 
 /// Match a ConstantInt, capturing the value if we match.
 inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
@@ -1937,6 +1940,25 @@ template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) {
   return Signum_match<Val_t>(V);
 }
 
+template <int Ind, typename Opnd_t> struct ExtractValue_match {
+  Opnd_t Val;
+  ExtractValue_match(const Opnd_t &V) : Val(V) {}
+
+  template <typename OpTy> bool match(OpTy *V) {
+    if (auto *I = dyn_cast<ExtractValueInst>(V))
+      return I->getNumIndices() == 1 && I->getIndices()[0] == Ind &&
+             Val.match(I->getAggregateOperand());
+    return false;
+  }
+};
+
+/// Match a single index ExtractValue instruction.
+/// For example m_ExtractValue<1>(...)
+template <int Ind, typename Val_t>
+inline ExtractValue_match<Ind, Val_t> m_ExtractValue(const Val_t &V) {
+  return ExtractValue_match<Ind, Val_t>(V);
+}
+
 } // end namespace PatternMatch
 } // end namespace llvm
 

diff  --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index c2c38b73a278..f624024d584c 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -1109,6 +1109,30 @@ TEST_F(PatternMatchTest, CondBranchTest) {
   EXPECT_TRUE(match(Br2, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A))));
 }
 
+TEST_F(PatternMatchTest, WithOverflowInst) {
+  Value *Add = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow,
+                                         IRB.getInt32(0), IRB.getInt32(0));
+  Value *Add0 = IRB.CreateExtractValue(Add, 0);
+  Value *Add1 = IRB.CreateExtractValue(Add, 1);
+
+  EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_Value())));
+  EXPECT_FALSE(match(Add0, m_ExtractValue<1>(m_Value())));
+  EXPECT_FALSE(match(Add1, m_ExtractValue<0>(m_Value())));
+  EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_Value())));
+  EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value())));
+  EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value())));
+
+  WithOverflowInst *WOI;
+  EXPECT_FALSE(match(Add0, m_WithOverflowInst(WOI)));
+  EXPECT_FALSE(match(Add1, m_WithOverflowInst(WOI)));
+  EXPECT_TRUE(match(Add, m_WithOverflowInst(WOI)));
+
+  EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_WithOverflowInst(WOI))));
+  EXPECT_EQ(Add, WOI);
+  EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_WithOverflowInst(WOI))));
+  EXPECT_EQ(Add, WOI);
+}
+
 template <typename T> struct MutableConstTest : PatternMatchTest { };
 
 typedef ::testing::Types<std::tuple<Value*, Instruction*>,


        


More information about the llvm-commits mailing list