diff options
-rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 12 | ||||
-rw-r--r-- | llvm/unittests/IR/PatternMatch.cpp | 21 |
2 files changed, 33 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index f39678347d3..9d51bcd5d71 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -411,6 +411,18 @@ inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; } +struct is_negated_power2 { + bool isValue(const APInt &C) { return (-C).isPowerOf2(); } +}; +/// Match a integer or vector negated power-of-2. +/// For vectors, this includes constants with undefined elements. +inline cst_pred_ty<is_negated_power2> m_NegatedPower2() { + return cst_pred_ty<is_negated_power2>(); +} +inline api_pred_ty<is_negated_power2> m_NegatedPower2(const APInt *&V) { + return V; +} + struct is_power2_or_zero { bool isValue(const APInt &C) { return !C || C.isPowerOf2(); } }; diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index 8263acb59a0..fe8c518fa82 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/PatternMatch.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" @@ -470,6 +471,26 @@ TEST_F(PatternMatchTest, Unless) { EXPECT_FALSE(m_Unless(m_c_Add(m_Zero(), m_One())).match(X)); } +TEST_F(PatternMatchTest, Power2) { + Value *C128 = IRB.getInt32(128); + Value *CNeg128 = ConstantExpr::getNeg(cast<Constant>(C128)); + + EXPECT_TRUE(m_Power2().match(C128)); + EXPECT_FALSE(m_Power2().match(CNeg128)); + + EXPECT_FALSE(m_NegatedPower2().match(C128)); + EXPECT_TRUE(m_NegatedPower2().match(CNeg128)); + + Value *CIntMin = IRB.getInt64(APSInt::getSignedMinValue(64).getSExtValue()); + Value *CNegIntMin = ConstantExpr::getNeg(cast<Constant>(CIntMin)); + + EXPECT_TRUE(m_Power2().match(CIntMin)); + EXPECT_TRUE(m_Power2().match(CNegIntMin)); + + EXPECT_TRUE(m_NegatedPower2().match(CIntMin)); + EXPECT_TRUE(m_NegatedPower2().match(CNegIntMin)); +} + TEST_F(PatternMatchTest, CommutativeDeferredValue) { Value *X = IRB.getInt32(1); Value *Y = IRB.getInt32(2); |