Index: include/llvm/IR/PatternMatch.h =================================================================== --- include/llvm/IR/PatternMatch.h +++ include/llvm/IR/PatternMatch.h @@ -402,6 +402,18 @@ 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 m_NegatedPower2() { + return cst_pred_ty(); +} +inline api_pred_ty m_NegatedPower2(const APInt *&V) { + return V; +} + struct is_power2_or_zero { bool isValue(const APInt &C) { return !C || C.isPowerOf2(); } }; Index: unittests/IR/PatternMatch.cpp =================================================================== --- unittests/IR/PatternMatch.cpp +++ unittests/IR/PatternMatch.cpp @@ -101,6 +101,17 @@ EXPECT_FALSE(m_Unless(m_c_Add(m_Zero(), m_One())).match(One)); } +TEST_F(PatternMatchTest, Power2) { + Value *One = IRB.getInt32(128); + Value *NegOne = ConstantExpr::getNeg(cast(One)); + + EXPECT_TRUE(m_Power2().match(One)); + EXPECT_FALSE(m_Power2().match(NegOne)); + + EXPECT_FALSE(m_NegatedPower2().match(One)); + EXPECT_TRUE(m_NegatedPower2().match(NegOne)); +} + TEST_F(PatternMatchTest, CommutativeDeferredValue) { Value *X = IRB.getInt32(1); Value *Y = IRB.getInt32(2);