Skip to content

Commit 444ac34

Browse files
committed
[APInt][PatternMatch] Add 'is non-positive' predicate
It will be useful for implementing the fold mentioned in https://bugs.llvm.org/show_bug.cgi?id=44100#c4
1 parent 898df29 commit 444ac34

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

llvm/include/llvm/ADT/APInt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ class LLVM_NODISCARD APInt {
389389
/// \returns true if this APInt is positive.
390390
bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
391391

392+
/// Determine if this APInt Value is non-positive (<= 0).
393+
///
394+
/// \returns true if this APInt is non-positive.
395+
bool isNonPositive() const { return !isStrictlyPositive(); }
396+
392397
/// Determine if all bits are set
393398
///
394399
/// This checks to see if the value has all bits of the APInt are set or not.

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ inline api_pred_ty<is_negative> m_Negative(const APInt *&V) {
366366
struct is_nonnegative {
367367
bool isValue(const APInt &C) { return C.isNonNegative(); }
368368
};
369-
/// Match an integer or vector of nonnegative values.
369+
/// Match an integer or vector of non-negative values.
370370
/// For vectors, this includes constants with undefined elements.
371371
inline cst_pred_ty<is_nonnegative> m_NonNegative() {
372372
return cst_pred_ty<is_nonnegative>();
@@ -375,6 +375,28 @@ inline api_pred_ty<is_nonnegative> m_NonNegative(const APInt *&V) {
375375
return V;
376376
}
377377

378+
struct is_strictlypositive {
379+
bool isValue(const APInt &C) { return C.isStrictlyPositive(); }
380+
};
381+
/// Match an integer or vector of strictly positive values.
382+
/// For vectors, this includes constants with undefined elements.
383+
inline cst_pred_ty<is_strictlypositive> m_StrictlyPositive() {
384+
return cst_pred_ty<is_strictlypositive>();
385+
}
386+
inline api_pred_ty<is_strictlypositive> m_StrictlyPositive(const APInt *&V) {
387+
return V;
388+
}
389+
390+
struct is_nonpositive {
391+
bool isValue(const APInt &C) { return C.isNonPositive(); }
392+
};
393+
/// Match an integer or vector of non-positive values.
394+
/// For vectors, this includes constants with undefined elements.
395+
inline cst_pred_ty<is_nonpositive> m_NonPositive() {
396+
return cst_pred_ty<is_nonpositive>();
397+
}
398+
inline api_pred_ty<is_nonpositive> m_NonPositive(const APInt *&V) { return V; }
399+
378400
struct is_one {
379401
bool isValue(const APInt &C) { return C.isOneValue(); }
380402
};

llvm/unittests/ADT/APIntTest.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,4 +2845,21 @@ TEST(APIntTest, GetMostSignificantDifferentBitExaustive) {
28452845
}
28462846
}
28472847

2848+
TEST(APIntTest, SignbitZeroChecks) {
2849+
EXPECT_TRUE(APInt(8, -1).isNegative());
2850+
EXPECT_FALSE(APInt(8, -1).isNonNegative());
2851+
EXPECT_FALSE(APInt(8, -1).isStrictlyPositive());
2852+
EXPECT_TRUE(APInt(8, -1).isNonPositive());
2853+
2854+
EXPECT_FALSE(APInt(8, 0).isNegative());
2855+
EXPECT_TRUE(APInt(8, 0).isNonNegative());
2856+
EXPECT_FALSE(APInt(8, 0).isStrictlyPositive());
2857+
EXPECT_TRUE(APInt(8, 0).isNonPositive());
2858+
2859+
EXPECT_FALSE(APInt(8, 1).isNegative());
2860+
EXPECT_TRUE(APInt(8, 1).isNonNegative());
2861+
EXPECT_TRUE(APInt(8, 1).isStrictlyPositive());
2862+
EXPECT_FALSE(APInt(8, 1).isNonPositive());
2863+
}
2864+
28482865
} // end anonymous namespace

llvm/unittests/IR/PatternMatch.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,30 @@ TEST_F(PatternMatchTest, SpecificIntUGT) {
182182
.match(NegOne));
183183
}
184184

185+
TEST_F(PatternMatchTest, SignbitZeroChecks) {
186+
Type *IntTy = IRB.getInt32Ty();
187+
unsigned BitWidth = IntTy->getScalarSizeInBits();
188+
189+
Value *Zero = ConstantInt::get(IntTy, 0);
190+
Value *One = ConstantInt::get(IntTy, 1);
191+
Value *NegOne = ConstantInt::get(IntTy, -1);
192+
193+
EXPECT_TRUE(m_Negative().match(NegOne));
194+
EXPECT_FALSE(m_NonNegative().match(NegOne));
195+
EXPECT_FALSE(m_StrictlyPositive().match(NegOne));
196+
EXPECT_TRUE(m_NonPositive().match(NegOne));
197+
198+
EXPECT_FALSE(m_Negative().match(Zero));
199+
EXPECT_TRUE(m_NonNegative().match(Zero));
200+
EXPECT_FALSE(m_StrictlyPositive().match(Zero));
201+
EXPECT_TRUE(m_NonPositive().match(Zero));
202+
203+
EXPECT_FALSE(m_Negative().match(One));
204+
EXPECT_TRUE(m_NonNegative().match(One));
205+
EXPECT_TRUE(m_StrictlyPositive().match(One));
206+
EXPECT_FALSE(m_NonPositive().match(One));
207+
}
208+
185209
TEST_F(PatternMatchTest, SpecificIntUGE) {
186210
Type *IntTy = IRB.getInt32Ty();
187211
unsigned BitWidth = IntTy->getScalarSizeInBits();

0 commit comments

Comments
 (0)