Skip to content

Commit becceca

Browse files
committed
[SLP]Fix PR98838: do no replace condition of select-based logical op by poison.
If the reduction operation is a select-based logical op, the condition should be replaced by the poison, better to replace by the non-poisoning constant to prevent poison propagation in the vector code. Fixes #98838
1 parent 9ba9e48 commit becceca

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14201,9 +14201,23 @@ Value *BoUpSLP::vectorizeTree(
1420114201
for (Instruction *I : RemovedInsts) {
1420214202
if (getTreeEntry(I)->Idx != 0)
1420314203
continue;
14204+
SmallVector<SelectInst *> LogicalOpSelects;
1420414205
I->replaceUsesWithIf(PoisonValue::get(I->getType()), [&](Use &U) {
14206+
// Do not replace condition of the logical op in form select <cond>.
14207+
bool IsPoisoningLogicalOp = isa<SelectInst>(U.getUser()) &&
14208+
(match(U.getUser(), m_LogicalAnd()) ||
14209+
match(U.getUser(), m_LogicalOr())) &&
14210+
U.getOperandNo() == 0;
14211+
if (IsPoisoningLogicalOp) {
14212+
LogicalOpSelects.push_back(cast<SelectInst>(U.getUser()));
14213+
return false;
14214+
}
1420514215
return UserIgnoreList->contains(U.getUser());
1420614216
});
14217+
// Replace conditions of the poisoning logical ops with the non-poison
14218+
// constant value.
14219+
for (SelectInst *SI : LogicalOpSelects)
14220+
SI->setCondition(Constant::getNullValue(SI->getCondition()->getType()));
1420714221
}
1420814222
}
1420914223
// Retain to-be-deleted instructions for some debug-info bookkeeping and alias
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux < %s | FileCheck %s
3+
4+
define i1 @src(i1 %cmp4.118.i) {
5+
; CHECK-LABEL: define i1 @src(
6+
; CHECK-SAME: i1 [[CMP4_118_I:%.*]]) {
7+
; CHECK-NEXT: [[CMP4_118_I_NOT:%.*]] = xor i1 [[CMP4_118_I]], true
8+
; CHECK-NEXT: [[TMP1:%.*]] = freeze <4 x i1> poison
9+
; CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
10+
; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[CMP4_118_I_NOT]], i1 true, i1 [[TMP2]]
11+
; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[OP_RDX]]
12+
; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[TMP3]], i1 true, i1 poison
13+
; CHECK-NEXT: ret i1 [[OP_RDX1]]
14+
;
15+
%cmp4.118.i.not = xor i1 %cmp4.118.i, true
16+
%brmerge = select i1 %cmp4.118.i.not, i1 true, i1 poison
17+
%.not = xor i1 poison, true
18+
%brmerge2 = select i1 %brmerge, i1 true, i1 %.not
19+
%.not3 = xor i1 poison, true
20+
%brmerge4 = select i1 %brmerge2, i1 true, i1 %.not3
21+
%.not5 = xor i1 poison, true
22+
%brmerge6 = select i1 %brmerge4, i1 true, i1 %.not5
23+
%.not7 = xor i1 poison, true
24+
%brmerge8 = select i1 %brmerge6, i1 true, i1 %.not7
25+
ret i1 %brmerge8
26+
}

0 commit comments

Comments
 (0)