[llvm] becceca - [SLP]Fix PR98838: do no replace condition of select-based logical op by poison.
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 15 07:28:11 PDT 2024
Author: Alexey Bataev
Date: 2024-07-15T07:27:54-07:00
New Revision: beccecaacde405a3b50891c67594eccbcd1c8b08
URL: https://github.com/llvm/llvm-project/commit/beccecaacde405a3b50891c67594eccbcd1c8b08
DIFF: https://github.com/llvm/llvm-project/commit/beccecaacde405a3b50891c67594eccbcd1c8b08.diff
LOG: [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 https://github.com/llvm/llvm-project/issues/98838
Added:
llvm/test/Transforms/SLPVectorizer/X86/select-reduction-op.ll
Modified:
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 5c2fc0b9320e8..74a16d3fbcad6 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -14201,9 +14201,23 @@ Value *BoUpSLP::vectorizeTree(
for (Instruction *I : RemovedInsts) {
if (getTreeEntry(I)->Idx != 0)
continue;
+ SmallVector<SelectInst *> LogicalOpSelects;
I->replaceUsesWithIf(PoisonValue::get(I->getType()), [&](Use &U) {
+ // Do not replace condition of the logical op in form select <cond>.
+ bool IsPoisoningLogicalOp = isa<SelectInst>(U.getUser()) &&
+ (match(U.getUser(), m_LogicalAnd()) ||
+ match(U.getUser(), m_LogicalOr())) &&
+ U.getOperandNo() == 0;
+ if (IsPoisoningLogicalOp) {
+ LogicalOpSelects.push_back(cast<SelectInst>(U.getUser()));
+ return false;
+ }
return UserIgnoreList->contains(U.getUser());
});
+ // Replace conditions of the poisoning logical ops with the non-poison
+ // constant value.
+ for (SelectInst *SI : LogicalOpSelects)
+ SI->setCondition(Constant::getNullValue(SI->getCondition()->getType()));
}
}
// Retain to-be-deleted instructions for some debug-info bookkeeping and alias
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/select-reduction-op.ll b/llvm/test/Transforms/SLPVectorizer/X86/select-reduction-op.ll
new file mode 100644
index 0000000000000..5f62def150d8f
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/select-reduction-op.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux < %s | FileCheck %s
+
+define i1 @src(i1 %cmp4.118.i) {
+; CHECK-LABEL: define i1 @src(
+; CHECK-SAME: i1 [[CMP4_118_I:%.*]]) {
+; CHECK-NEXT: [[CMP4_118_I_NOT:%.*]] = xor i1 [[CMP4_118_I]], true
+; CHECK-NEXT: [[TMP1:%.*]] = freeze <4 x i1> poison
+; CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
+; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[CMP4_118_I_NOT]], i1 true, i1 [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[OP_RDX]]
+; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[TMP3]], i1 true, i1 poison
+; CHECK-NEXT: ret i1 [[OP_RDX1]]
+;
+ %cmp4.118.i.not = xor i1 %cmp4.118.i, true
+ %brmerge = select i1 %cmp4.118.i.not, i1 true, i1 poison
+ %.not = xor i1 poison, true
+ %brmerge2 = select i1 %brmerge, i1 true, i1 %.not
+ %.not3 = xor i1 poison, true
+ %brmerge4 = select i1 %brmerge2, i1 true, i1 %.not3
+ %.not5 = xor i1 poison, true
+ %brmerge6 = select i1 %brmerge4, i1 true, i1 %.not5
+ %.not7 = xor i1 poison, true
+ %brmerge8 = select i1 %brmerge6, i1 true, i1 %.not7
+ ret i1 %brmerge8
+}
More information about the llvm-commits
mailing list