Skip to content

Commit f0f8dab

Browse files
committed
[SLP]Check if the first reduced value requires freeze/swap, if it may be too poisonous
If several reduced values are combined and the first reduced value is just the original reduced value of the bool logical op, need to freeze it to prevent the propagation of the poison value. Fixes #114905
1 parent 6bafbc9 commit f0f8dab

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19679,20 +19679,35 @@ class HorizontalReduction {
1967919679
return cast<Instruction>(ScalarCond);
1968019680
};
1968119681

19682+
bool AnyBoolLogicOp = any_of(ReductionOps.back(), [](Value *V) {
19683+
return isBoolLogicOp(cast<Instruction>(V));
19684+
});
1968219685
// Return new VectorizedTree, based on previous value.
1968319686
auto GetNewVectorizedTree = [&](Value *VectorizedTree, Value *Res) {
1968419687
if (VectorizedTree) {
1968519688
// Update the final value in the reduction.
1968619689
Builder.SetCurrentDebugLocation(
1968719690
cast<Instruction>(ReductionOps.front().front())->getDebugLoc());
19688-
if ((isa<PoisonValue>(VectorizedTree) && !isa<PoisonValue>(Res)) ||
19689-
(isGuaranteedNotToBePoison(Res) &&
19690-
!isGuaranteedNotToBePoison(VectorizedTree))) {
19691-
auto It = ReducedValsToOps.find(Res);
19692-
if (It != ReducedValsToOps.end() &&
19693-
any_of(It->getSecond(),
19694-
[](Instruction *I) { return isBoolLogicOp(I); }))
19691+
if (AnyBoolLogicOp) {
19692+
19693+
if (auto It = ReducedValsToOps.find(VectorizedTree);
19694+
It == ReducedValsToOps.end() ||
19695+
isGuaranteedNotToBePoison(VectorizedTree) ||
19696+
any_of(It->getSecond(), [&](Instruction *I) {
19697+
return isBoolLogicOp(I) &&
19698+
getRdxOperand(I, 0) == VectorizedTree;
19699+
})) {
19700+
;
19701+
} else if (auto It = ReducedValsToOps.find(Res);
19702+
It == ReducedValsToOps.end() ||
19703+
isGuaranteedNotToBePoison(Res) ||
19704+
any_of(It->getSecond(), [&](Instruction *I) {
19705+
return isBoolLogicOp(I) && getRdxOperand(I, 0) == Res;
19706+
})) {
1969519707
std::swap(VectorizedTree, Res);
19708+
} else {
19709+
VectorizedTree = Builder.CreateFreeze(VectorizedTree);
19710+
}
1969619711
}
1969719712

1969819713
return createOp(Builder, RdxKind, VectorizedTree, Res, "op.rdx",
@@ -19701,9 +19716,6 @@ class HorizontalReduction {
1970119716
// Initialize the final value in the reduction.
1970219717
return Res;
1970319718
};
19704-
bool AnyBoolLogicOp = any_of(ReductionOps.back(), [](Value *V) {
19705-
return isBoolLogicOp(cast<Instruction>(V));
19706-
});
1970719719
SmallDenseSet<Value *> IgnoreList(ReductionOps.size() *
1970819720
ReductionOps.front().size());
1970919721
for (ReductionOpsType &RdxOps : ReductionOps)

llvm/test/Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ define i1 @test(<4 x i32> %x) {
1212
; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[X1]], 0
1313
; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[X2]], 0
1414
; CHECK-NEXT: [[C3:%.*]] = icmp slt i32 [[X3]], 0
15-
; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[C3]], i1 [[C1]], i1 false
15+
; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[C3]]
16+
; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP2]], i1 [[C1]], i1 false
1617
; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i1 [[TMP1]], i1 false
1718
; CHECK-NEXT: ret i1 [[OP_RDX1]]
1819
;

0 commit comments

Comments
 (0)