From 8c39d016705e04be7dcfddae8997a36fcd0ee30d Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 27 Sep 2019 21:53:04 +0000 Subject: [PATCH] [PatternMatch] Add m_SExtOrSelf(), m_ZExtOrSExtOrSelf() matchers + unittests m_SExtOrSelf() is for consistency. m_ZExtOrSExtOrSelf() is motivated by the D68103/r373106 : sometimes it is useful to look past any extensions of the shift amount, and m_ZExtOrSExtOrSelf() may be exactly the tool to do that. llvm-svn: 373128 --- llvm/include/llvm/IR/PatternMatch.h | 15 +++++++++++++++ llvm/unittests/IR/PatternMatch.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 82e7d0a..73b182c 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1320,12 +1320,27 @@ m_ZExtOrSelf(const OpTy &Op) { } template +inline match_combine_or, OpTy> +m_SExtOrSelf(const OpTy &Op) { + return m_CombineOr(m_SExt(Op), Op); +} + +template inline match_combine_or, CastClass_match> m_ZExtOrSExt(const OpTy &Op) { return m_CombineOr(m_ZExt(Op), m_SExt(Op)); } +template +inline match_combine_or< + match_combine_or, + CastClass_match>, + OpTy> +m_ZExtOrSExtOrSelf(const OpTy &Op) { + return m_CombineOr(m_ZExtOrSExt(Op), Op); +} + /// Matches UIToFP. template inline CastClass_match m_UIToFP(const OpTy &Op) { diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index d52d4fe..c2c38b7 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -471,6 +471,42 @@ TEST_F(PatternMatchTest, Unless) { EXPECT_FALSE(m_Unless(m_c_Add(m_Zero(), m_One())).match(X)); } +TEST_F(PatternMatchTest, ZExtSExtSelf) { + LLVMContext &Ctx = IRB.getContext(); + + Value *One32 = IRB.getInt32(1); + Value *One64Z = IRB.CreateZExt(One32, IntegerType::getInt64Ty(Ctx)); + Value *One64S = IRB.CreateSExt(One32, IntegerType::getInt64Ty(Ctx)); + + EXPECT_TRUE(m_One().match(One32)); + EXPECT_FALSE(m_One().match(One64Z)); + EXPECT_FALSE(m_One().match(One64S)); + + EXPECT_FALSE(m_ZExt(m_One()).match(One32)); + EXPECT_TRUE(m_ZExt(m_One()).match(One64Z)); + EXPECT_FALSE(m_ZExt(m_One()).match(One64S)); + + EXPECT_FALSE(m_SExt(m_One()).match(One32)); + EXPECT_FALSE(m_SExt(m_One()).match(One64Z)); + EXPECT_TRUE(m_SExt(m_One()).match(One64S)); + + EXPECT_TRUE(m_ZExtOrSelf(m_One()).match(One32)); + EXPECT_TRUE(m_ZExtOrSelf(m_One()).match(One64Z)); + EXPECT_FALSE(m_ZExtOrSelf(m_One()).match(One64S)); + + EXPECT_TRUE(m_SExtOrSelf(m_One()).match(One32)); + EXPECT_FALSE(m_SExtOrSelf(m_One()).match(One64Z)); + EXPECT_TRUE(m_SExtOrSelf(m_One()).match(One64S)); + + EXPECT_FALSE(m_ZExtOrSExt(m_One()).match(One32)); + EXPECT_TRUE(m_ZExtOrSExt(m_One()).match(One64Z)); + EXPECT_TRUE(m_ZExtOrSExt(m_One()).match(One64S)); + + EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One32)); + EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One64Z)); + EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One64S)); +} + TEST_F(PatternMatchTest, Power2) { Value *C128 = IRB.getInt32(128); Value *CNeg128 = ConstantExpr::getNeg(cast(C128)); -- 2.7.4