[PATCH] D114720: [LV] Fix crash when optimized phi is feeding first-order recurrence.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 29 09:44:22 PST 2021
fhahn created this revision.
fhahn added reviewers: Ayal, gilr.
Herald added subscribers: rogfer01, hiraditya.
fhahn requested review of this revision.
Herald added a subscriber: vkmr.
Herald added a project: LLVM.
This patch fixes a crash when a phi with an optimized cast feeds a
first-order recurrence, as discussed in D113183 <https://reviews.llvm.org/D113183>.
There are 2 issues that this patch addresses:
1. The recipe for the optimized cast is not recorded.
2. fixHeaderPhis assumes the incoming def defines a single VPValue.
If the incoming value is an induction phi recipe, always use the first
defined value, which represents the phi itself.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D114720
Files:
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
llvm/test/Transforms/LoopVectorize/induction.ll
Index: llvm/test/Transforms/LoopVectorize/induction.ll
===================================================================
--- llvm/test/Transforms/LoopVectorize/induction.ll
+++ llvm/test/Transforms/LoopVectorize/induction.ll
@@ -933,3 +933,41 @@
exit:
ret void
}
+
+; Test case where %iv.2.ext and %iv.2.conv become redundant due to the SCEV
+; predicates generated for the vector loop. They should be removed in the
+; vector loop.
+define void @test_optimized_cast_induction_feeding_first_order_recurrence(i64 %n, i32 %step, i32* %ptr) {
+; CHECK-LABEL: @test_optimized_cast_induction_feeding_first_order_recurrence(
+; CHECK-LABEL: vector.body:
+; CHECK-NEXT: [[MAIN_IV:%.+]] = phi i64 [ 0, %vector.ph ], [ [[MAIN_IV_NEXT:%.+]], %vector.body ]
+; CHECK-NEXT: [[VEC_RECUR:%.+]] = phi <2 x i32> [ <i32 poison, i32 0>, %vector.ph ], [ [[VEC_IV:%.+]], %vector.body ]
+; CHECK-NEXT: [[VEC_IV]] = phi <2 x i32> [ %induction, %vector.ph ], [ [[VEC_IV_NEXT:%.+]], %vector.body ]
+; CHECK-NEXT: [[MAIN_IV_0:%.+]] = add i64 [[MAIN_IV]], 0
+; CHECK-NEXT: [[RECUR_SHUFFLE:%.+]] = shufflevector <2 x i32> [[VEC_RECUR]], <2 x i32> [[VEC_IV]], <2 x i32> <i32 1, i32 2>
+; CHECK-NEXT: [[GEP0:%.+]] = getelementptr inbounds i32, i32* %ptr, i64 [[MAIN_IV_0]]
+; CHECK-NEXT: [[GEP1:%.+]] = getelementptr inbounds i32, i32* [[GEP0]], i32 0
+; CHECK-NEXT: [[GEP_CAST:%.+]] = bitcast i32* [[GEP1]] to <2 x i32>*
+; CHECK-NEXT: store <2 x i32> [[RECUR_SHUFFLE]], <2 x i32>* [[GEP_CAST]], align 4
+; CHECK-NEXT: [[MAIN_IV_NEXT]] = add nuw i64 [[MAIN_IV]], 2
+; CHECK-NEXT: [[VEC_IV_NEXT]] = add <2 x i32> [[VEC_IV]],
+;
+entry:
+ br label %loop
+
+loop:
+ %for = phi i32 [ 0, %entry ], [ %iv.2.conv, %loop ]
+ %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
+ %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ]
+ %iv.2.ext = shl i32 %iv.2, 24
+ %iv.2.conv = ashr exact i32 %iv.2.ext, 24
+ %gep = getelementptr inbounds i32, i32* %ptr, i64 %iv.1
+ store i32 %for, i32* %gep, align 4
+ %iv.2.next = add nsw i32 %iv.2.conv, %step
+ %iv.1.next = add nuw nsw i64 %iv.1, 1
+ %exitcond = icmp eq i64 %iv.1.next, %n
+ br i1 %exitcond, label %exit, label %loop
+
+exit:
+ ret void
+}
Index: llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
===================================================================
--- llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
+++ llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
@@ -75,7 +75,7 @@
/// Check if an induction recipe should be constructed for \I. If so build and
/// return it. If not, return null.
VPWidenIntOrFpInductionRecipe *
- tryToOptimizeInductionPHI(PHINode *Phi, ArrayRef<VPValue *> Operands) const;
+ tryToOptimizeInductionPHI(PHINode *Phi, ArrayRef<VPValue *> Operands);
/// Optimize the special case where the operand of \p I is a constant integer
/// induction variable.
Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
===================================================================
--- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -8748,7 +8748,7 @@
VPWidenIntOrFpInductionRecipe *
VPRecipeBuilder::tryToOptimizeInductionPHI(PHINode *Phi,
- ArrayRef<VPValue *> Operands) const {
+ ArrayRef<VPValue *> Operands) {
// Check if this is an integer or fp induction. If so, build the recipe that
// produces its scalar and vector values.
InductionDescriptor II = Legal->getInductionVars().lookup(Phi);
@@ -8757,8 +8757,13 @@
assert(II.getStartValue() ==
Phi->getIncomingValueForBlock(OrigLoop->getLoopPreheader()));
const SmallVectorImpl<Instruction *> &Casts = II.getCastInsts();
- return new VPWidenIntOrFpInductionRecipe(
- Phi, Operands[0], Casts.empty() ? nullptr : Casts.front());
+
+ Instruction *CastI =
+ cast_or_null<Instruction>(Casts.empty() ? nullptr : Casts.front());
+ auto *R = new VPWidenIntOrFpInductionRecipe(Phi, Operands[0], CastI);
+ if (CastI)
+ setRecipe(CastI, R);
+ return R;
}
return nullptr;
@@ -8932,7 +8937,10 @@
auto *PN = cast<PHINode>(R->getUnderlyingValue());
VPRecipeBase *IncR =
getRecipe(cast<Instruction>(PN->getIncomingValueForBlock(OrigLatch)));
- R->addOperand(IncR->getVPSingleValue());
+ if (isa<VPWidenIntOrFpInductionRecipe>(IncR))
+ R->addOperand(IncR->getVPValue(0));
+ else
+ R->addOperand(IncR->getVPSingleValue());
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114720.390393.patch
Type: text/x-patch
Size: 4546 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211129/f015b629/attachment.bin>
More information about the llvm-commits
mailing list