Index: llvm/trunk/include/llvm/IR/PatternMatch.h =================================================================== --- llvm/trunk/include/llvm/IR/PatternMatch.h +++ llvm/trunk/include/llvm/IR/PatternMatch.h @@ -418,6 +418,20 @@ return cst_pred_ty(); } +struct is_unsigned_less_than { + const APInt *Thr; + bool isValue(const APInt &C) { return C.ult(*Thr); } +}; +/// Match an integer or vector with every element unsigned less than the +/// Threshold. For vectors, this includes constants with undefined elements. +/// FIXME: is it worth generalizing this to simply take ICmpInst::Predicate? +inline cst_pred_ty +m_SpecificInt_ULT(const APInt &Threshold) { + cst_pred_ty P; + P.Thr = &Threshold; + return P; +} + struct is_nan { bool isValue(const APFloat &C) { return C.isNaN(); } }; Index: llvm/trunk/unittests/IR/PatternMatch.cpp =================================================================== --- llvm/trunk/unittests/IR/PatternMatch.cpp +++ llvm/trunk/unittests/IR/PatternMatch.cpp @@ -64,6 +64,27 @@ EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf)); } +TEST_F(PatternMatchTest, SpecificIntULT) { + Type *IntTy = IRB.getInt32Ty(); + unsigned BitWidth = IntTy->getScalarSizeInBits(); + + Value *Zero = ConstantInt::get(IntTy, 0); + Value *One = ConstantInt::get(IntTy, 1); + Value *NegOne = ConstantInt::get(IntTy, -1); + + EXPECT_FALSE(m_SpecificInt_ULT(APInt(BitWidth, 0)).match(Zero)); + EXPECT_FALSE(m_SpecificInt_ULT(APInt(BitWidth, 0)).match(One)); + EXPECT_FALSE(m_SpecificInt_ULT(APInt(BitWidth, 0)).match(NegOne)); + + EXPECT_TRUE(m_SpecificInt_ULT(APInt(BitWidth, 1)).match(Zero)); + EXPECT_FALSE(m_SpecificInt_ULT(APInt(BitWidth, 1)).match(One)); + EXPECT_FALSE(m_SpecificInt_ULT(APInt(BitWidth, 1)).match(NegOne)); + + EXPECT_TRUE(m_SpecificInt_ULT(APInt(BitWidth, -1)).match(Zero)); + EXPECT_TRUE(m_SpecificInt_ULT(APInt(BitWidth, -1)).match(One)); + EXPECT_FALSE(m_SpecificInt_ULT(APInt(BitWidth, -1)).match(NegOne)); +} + TEST_F(PatternMatchTest, CommutativeDeferredValue) { Value *X = IRB.getInt32(1); Value *Y = IRB.getInt32(2);