Skip to content

Commit 396cdab

Browse files
authored
[PatternMatch] Allow poison in api_pred_ty matchers (#89188)
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.
1 parent 949e66b commit 396cdab

File tree

3 files changed

+56
-31
lines changed

3 files changed

+56
-31
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,8 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
406406
}
407407
if (V->getType()->isVectorTy())
408408
if (const auto *C = dyn_cast<Constant>(V))
409-
if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
409+
if (auto *CI = dyn_cast_or_null<ConstantInt>(
410+
C->getSplatValue(/*AllowPoison=*/true)))
410411
if (this->isValue(CI->getValue())) {
411412
Res = &CI->getValue();
412413
return true;

llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {
3434
ret <2 x i32> %select
3535
}
3636

37+
define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison1(<2 x i32> %x, <2 x i32> %y) {
38+
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison1(
39+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 1, i32 poison>
40+
; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw <2 x i32> [[AND]], <i32 1, i32 1>
41+
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
42+
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
43+
;
44+
%and = and <2 x i32> %x, <i32 1, i32 poison>
45+
%cmp = icmp eq <2 x i32> %and, zeroinitializer
46+
%or = or <2 x i32> %y, <i32 2, i32 2>
47+
%select = select <2 x i1> %cmp, <2 x i32> %y, <2 x i32> %or
48+
ret <2 x i32> %select
49+
}
50+
51+
define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison2(<2 x i32> %x, <2 x i32> %y) {
52+
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison2(
53+
; CHECK-NEXT: [[AND:%.*]] = shl <2 x i32> [[X:%.*]], <i32 1, i32 1>
54+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[AND]], <i32 2, i32 2>
55+
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
56+
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
57+
;
58+
%and = and <2 x i32> %x, <i32 1, i32 1>
59+
%cmp = icmp eq <2 x i32> %and, <i32 0, i32 poison>
60+
%or = or <2 x i32> %y, <i32 2, i32 2>
61+
%select = select <2 x i1> %cmp, <2 x i32> %y, <2 x i32> %or
62+
ret <2 x i32> %select
63+
}
64+
65+
define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison3(<2 x i32> %x, <2 x i32> %y) {
66+
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison3(
67+
; CHECK-NEXT: [[AND:%.*]] = shl <2 x i32> [[X:%.*]], <i32 1, i32 1>
68+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[AND]], <i32 2, i32 2>
69+
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
70+
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
71+
;
72+
%and = and <2 x i32> %x, <i32 1, i32 1>
73+
%cmp = icmp eq <2 x i32> %and, zeroinitializer
74+
%or = or <2 x i32> %y, <i32 2, i32 poison>
75+
%select = select <2 x i1> %cmp, <2 x i32> %y, <2 x i32> %or
76+
ret <2 x i32> %select
77+
}
78+
3779
define i32 @select_icmp_eq_and_1_0_xor_2(i32 %x, i32 %y) {
3880
; CHECK-LABEL: @select_icmp_eq_and_1_0_xor_2(
3981
; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1

llvm/test/Transforms/InstCombine/signed-truncation-check.ll

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,8 @@ define <3 x i1> @positive_vec_poison0(<3 x i32> %arg) {
212212

213213
define <3 x i1> @positive_vec_poison1(<3 x i32> %arg) {
214214
; CHECK-LABEL: @positive_vec_poison1(
215-
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
216-
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
217-
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
218-
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
219-
; CHECK-NEXT: ret <3 x i1> [[T4]]
215+
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
216+
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
220217
;
221218
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
222219
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
@@ -227,11 +224,8 @@ define <3 x i1> @positive_vec_poison1(<3 x i32> %arg) {
227224

228225
define <3 x i1> @positive_vec_poison2(<3 x i32> %arg) {
229226
; CHECK-LABEL: @positive_vec_poison2(
230-
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
231-
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
232-
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
233-
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
234-
; CHECK-NEXT: ret <3 x i1> [[T4]]
227+
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
228+
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
235229
;
236230
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
237231
%t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
@@ -242,11 +236,8 @@ define <3 x i1> @positive_vec_poison2(<3 x i32> %arg) {
242236

243237
define <3 x i1> @positive_vec_poison3(<3 x i32> %arg) {
244238
; CHECK-LABEL: @positive_vec_poison3(
245-
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 poison, i32 -1>
246-
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
247-
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 256, i32 256>
248-
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
249-
; CHECK-NEXT: ret <3 x i1> [[T4]]
239+
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
240+
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
250241
;
251242
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
252243
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
@@ -257,11 +248,8 @@ define <3 x i1> @positive_vec_poison3(<3 x i32> %arg) {
257248

258249
define <3 x i1> @positive_vec_poison4(<3 x i32> %arg) {
259250
; CHECK-LABEL: @positive_vec_poison4(
260-
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 poison, i32 -1>
261-
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 128, i32 128>
262-
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
263-
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
264-
; CHECK-NEXT: ret <3 x i1> [[T4]]
251+
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
252+
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
265253
;
266254
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
267255
%t2 = add <3 x i32> %arg, <i32 128, i32 128, i32 128>
@@ -272,11 +260,8 @@ define <3 x i1> @positive_vec_poison4(<3 x i32> %arg) {
272260

273261
define <3 x i1> @positive_vec_poison5(<3 x i32> %arg) {
274262
; CHECK-LABEL: @positive_vec_poison5(
275-
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 -1, i32 -1>
276-
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
277-
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
278-
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
279-
; CHECK-NEXT: ret <3 x i1> [[T4]]
263+
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
264+
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
280265
;
281266
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 -1, i32 -1>
282267
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>
@@ -287,11 +272,8 @@ define <3 x i1> @positive_vec_poison5(<3 x i32> %arg) {
287272

288273
define <3 x i1> @positive_vec_poison6(<3 x i32> %arg) {
289274
; CHECK-LABEL: @positive_vec_poison6(
290-
; CHECK-NEXT: [[T1:%.*]] = icmp sgt <3 x i32> [[ARG:%.*]], <i32 -1, i32 poison, i32 -1>
291-
; CHECK-NEXT: [[T2:%.*]] = add <3 x i32> [[ARG]], <i32 128, i32 poison, i32 128>
292-
; CHECK-NEXT: [[T3:%.*]] = icmp ult <3 x i32> [[T2]], <i32 256, i32 poison, i32 256>
293-
; CHECK-NEXT: [[T4:%.*]] = and <3 x i1> [[T1]], [[T3]]
294-
; CHECK-NEXT: ret <3 x i1> [[T4]]
275+
; CHECK-NEXT: [[T4_SIMPLIFIED:%.*]] = icmp ult <3 x i32> [[ARG:%.*]], <i32 128, i32 128, i32 128>
276+
; CHECK-NEXT: ret <3 x i1> [[T4_SIMPLIFIED]]
295277
;
296278
%t1 = icmp sgt <3 x i32> %arg, <i32 -1, i32 poison, i32 -1>
297279
%t2 = add <3 x i32> %arg, <i32 128, i32 poison, i32 128>

0 commit comments

Comments
 (0)