Skip to content

Commit

Permalink
[PatternMatch] Allow poison in api_pred_ty matchers (llvm#89188)
Browse files Browse the repository at this point in the history
This allows vector splats containing poison for matchers using
api_pred_ty, making the behavior consistent with cst_pred_ty. In other
words, previously `m_NonNegative()` allowed splats with poison, while
`m_NonNegative(C)` did not. Now both allow them.

The affected matchers are m_MaxSignedValue, m_Negative, m_NonNegative,
m_StrictlyPositive, m_NonPositive, m_Power2, m_Power2OrZero,
m_NegatedPower2, m_NegatedPower2OrZero, m_LowBitMask and
m_LowBitMaskOrZero when passing in APInt.

I briefly went through the uses of these matchers and didn't spot any
places where allowing poison would be obviously wrong (I initially
thought foldSelectICmpAndBinOp is problematic, but because it does not
reuse the original constants, it's fine).

A problem here is that, despite these matchers appearing in a decent
number of places, we have very little pre-existing test coverage for
these folds with poison vectors, so we don't benefit from alive2
verification.
  • Loading branch information
nikic authored Apr 19, 2024
1 parent 949e66b commit 396cdab
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 31 deletions.
3 changes: 2 additions & 1 deletion llvm/include/llvm/IR/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
}
if (V->getType()->isVectorTy())
if (const auto *C = dyn_cast<Constant>(V))
if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
if (auto *CI = dyn_cast_or_null<ConstantInt>(
C->getSplatValue(/*AllowPoison=*/true)))
if (this->isValue(CI->getValue())) {
Res = &CI->getValue();
return true;
Expand Down
42 changes: 42 additions & 0 deletions llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,48 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec(<2 x i32> %x, <2 x i32> %y) {
ret <2 x i32> %select
}

define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison1(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison1(
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 1, i32 poison>
; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw <2 x i32> [[AND]], <i32 1, i32 1>
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
;
%and = and <2 x i32> %x, <i32 1, i32 poison>
%cmp = icmp eq <2 x i32> %and, zeroinitializer
%or = or <2 x i32> %y, <i32 2, i32 2>
%select = select <2 x i1> %cmp, <2 x i32> %y, <2 x i32> %or
ret <2 x i32> %select
}

define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison2(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison2(
; CHECK-NEXT: [[AND:%.*]] = shl <2 x i32> [[X:%.*]], <i32 1, i32 1>
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[AND]], <i32 2, i32 2>
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
;
%and = and <2 x i32> %x, <i32 1, i32 1>
%cmp = icmp eq <2 x i32> %and, <i32 0, i32 poison>
%or = or <2 x i32> %y, <i32 2, i32 2>
%select = select <2 x i1> %cmp, <2 x i32> %y, <2 x i32> %or
ret <2 x i32> %select
}

define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison3(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison3(
; CHECK-NEXT: [[AND:%.*]] = shl <2 x i32> [[X:%.*]], <i32 1, i32 1>
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[AND]], <i32 2, i32 2>
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
;
%and = and <2 x i32> %x, <i32 1, i32 1>
%cmp = icmp eq <2 x i32> %and, zeroinitializer
%or = or <2 x i32> %y, <i32 2, i32 poison>
%select = select <2 x i1> %cmp, <2 x i32> %y, <2 x i32> %or
ret <2 x i32> %select
}

define i32 @select_icmp_eq_and_1_0_xor_2(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_xor_2(
; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1
Expand Down
42 changes: 12 additions & 30 deletions llvm/test/Transforms/InstCombine/signed-truncation-check.ll
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,8 @@ define <3 x i1> @positive_vec_poison0(<3 x i32> %arg) {

define <3 x i1> @positive_vec_poison1(<3 x i32> %arg) {
; CHECK-LABEL: @positive_vec_poison1(
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
; CHECK-NEXT: ret <3 x i1> [[T4]]
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
;
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
Expand All @@ -227,11 +224,8 @@ define <3 x i1> @positive_vec_poison1(<3 x i32> %arg) {

define <3 x i1> @positive_vec_poison2(<3 x i32> %arg) {
; CHECK-LABEL: @positive_vec_poison2(
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
; CHECK-NEXT: ret <3 x i1> [[T4]]
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
;
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
%t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
Expand All @@ -242,11 +236,8 @@ define <3 x i1> @positive_vec_poison2(<3 x i32> %arg) {

define <3 x i1> @positive_vec_poison3(<3 x i32> %arg) {
; CHECK-LABEL: @positive_vec_poison3(
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 poison, i32 -1>
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
; CHECK-NEXT: ret <3 x i1> [[T4]]
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
;
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
Expand All @@ -257,11 +248,8 @@ define <3 x i1> @positive_vec_poison3(<3 x i32> %arg) {

define <3 x i1> @positive_vec_poison4(<3 x i32> %arg) {
; CHECK-LABEL: @positive_vec_poison4(
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 poison, i32 -1>
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
; CHECK-NEXT: ret <3 x i1> [[T4]]
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
;
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
%t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
Expand All @@ -272,11 +260,8 @@ define <3 x i1> @positive_vec_poison4(<3 x i32> %arg) {

define <3 x i1> @positive_vec_poison5(<3 x i32> %arg) {
; CHECK-LABEL: @positive_vec_poison5(
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
; CHECK-NEXT: ret <3 x i1> [[T4]]
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
;
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
Expand All @@ -287,11 +272,8 @@ define <3 x i1> @positive_vec_poison5(<3 x i32> %arg) {

define <3 x i1> @positive_vec_poison6(<3 x i32> %arg) {
; CHECK-LABEL: @positive_vec_poison6(
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 poison, i32 -1>
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
; CHECK-NEXT: ret <3 x i1> [[T4]]
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
;
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
Expand Down

0 comments on commit 396cdab

Please sign in to comment.