Skip to content

Commit 6cc3953

Browse files
committed
!fixup address latest comments, thanks
1 parent 918f079 commit 6cc3953

File tree

1 file changed

+57
-17
lines changed

1 file changed

+57
-17
lines changed

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,18 +1014,27 @@ bool VPlanTransforms::handleMultiUseReductions(VPlan &Plan) {
10141014
if (!MinMaxPhiR || !MinMaxPhiR->hasLoopUsesOutsideReductionChain())
10151015
continue;
10161016

1017+
// MinMaxPhiR has users outside the reduction cycle in the loop. Check if
1018+
// the only other user is a FindLastIV reduction. MinMaxPhiR must have
1019+
// exactly 3 users: 1) the min/max operation, the compare of a FindLastIV
1020+
// reduction and ComputeReductionResult. The comparisom must compare
1021+
// MinMaxPhiR against the min/max operand used for the min/max reduction
1022+
// and only be used by the select of the FindLastIV reduction.
10171023
RecurKind RdxKind = MinMaxPhiR->getRecurrenceKind();
10181024
assert(
10191025
RecurrenceDescriptor::isIntMinMaxRecurrenceKind(RdxKind) &&
10201026
"only min/max recurrences support users outside the reduction chain");
10211027

1022-
// One user of MinMaxPhiR is MinMaxOp, the other user must be a compare
1023-
// that's part of a FindLastIV chain.
10241028
auto *MinMaxOp =
10251029
dyn_cast<VPRecipeWithIRFlags>(MinMaxPhiR->getBackedgeValue());
1026-
if (!MinMaxOp || MinMaxOp->getNumUsers() != 2)
1030+
if (!MinMaxOp)
10271031
return false;
10281032

1033+
// MinMaxOp must have 2 users: 1) MinMaxPhiR and 2) ComputeReductionResult
1034+
// (asserted below).
1035+
assert(MinMaxOp->getNumUsers() == 2 &&
1036+
"MinMaxOp must have exactly 2 users");
1037+
10291038
assert((isa<VPWidenIntrinsicRecipe>(MinMaxOp) ||
10301039
(isa<VPReplicateRecipe>(MinMaxOp) &&
10311040
isa<IntrinsicInst>(
@@ -1035,8 +1044,8 @@ bool VPlanTransforms::handleMultiUseReductions(VPlan &Plan) {
10351044
VPValue *MinMaxOpB = MinMaxOp->getOperand(1);
10361045
if (MinMaxOpA != MinMaxPhiR)
10371046
std::swap(MinMaxOpA, MinMaxOpB);
1038-
if (MinMaxOpA != MinMaxPhiR)
1039-
return false;
1047+
assert(MinMaxOpA == MinMaxPhiR &&
1048+
"one of MinMaxOp's operands must be the phi");
10401049

10411050
VPValue *CmpOpA;
10421051
VPValue *CmpOpB;
@@ -1047,16 +1056,31 @@ bool VPlanTransforms::handleMultiUseReductions(VPlan &Plan) {
10471056
(CmpOpA != MinMaxOpB && CmpOpB != MinMaxOpB))
10481057
return false;
10491058

1059+
// MinMaxPhiR must have exactly 3 users:
1060+
// * MinMaxOp,
1061+
// * Cmp (that's part of a FindLastIV chain),
1062+
// * ComputeReductionResult.
1063+
if (MinMaxPhiR->getNumUsers() != 3)
1064+
return false;
1065+
1066+
VPInstruction *MinMaxResult =
1067+
findUserOf<VPInstruction::ComputeReductionResult>(MinMaxPhiR);
1068+
assert(is_contained(MinMaxPhiR->users(), MinMaxOp) &&
1069+
"one user must be MinMaxOp");
1070+
assert(is_contained(MinMaxPhiR->users(), Cmp) && "one user must be Cmp");
1071+
assert(is_contained(MinMaxPhiR->users(), MinMaxResult) &&
1072+
"one user must be MinMaxResult");
1073+
assert(is_contained(MinMaxOp->users(), MinMaxPhiR) &&
1074+
"one user must be MinMaxPhiR");
1075+
assert(is_contained(MinMaxOp->users(), MinMaxResult) &&
1076+
"one user must be MinMaxResult");
1077+
10501078
// TODO: Strict predicates need to find the first IV value for which the
10511079
// predicate holds, not the last.
10521080
if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE ||
10531081
ICmpInst::isLT(Pred) || ICmpInst::isGT(Pred))
10541082
return false;
10551083

1056-
// Normalize the predicate so MinMaxPhiR is on the right side.
1057-
if (CmpOpA == MinMaxPhiR)
1058-
Pred = CmpInst::getSwappedPredicate(Pred);
1059-
10601084
// Cmp must be used by the select of a FindLastIV chain.
10611085
VPValue *Sel = dyn_cast<VPSingleDefRecipe>(Cmp->getSingleUser());
10621086
VPValue *IVOp, *FindIV;
@@ -1079,23 +1103,39 @@ bool VPlanTransforms::handleMultiUseReductions(VPlan &Plan) {
10791103
// The reduction using MinMaxPhiR needs adjusting to compute the correct
10801104
// result:
10811105
// 1. We need to find the last IV for which the condition based on the
1082-
// min/max recurrence is true,
1106+
// min/max recurrence is true,
10831107
// 2. Compare the partial min/max reduction result to its final value and,
10841108
// 3. Select the lanes of the partial FindLastIV reductions which
1085-
// correspond to the lanes matching the min/max reduction result.
1109+
// correspond to the lanes matching the min/max reduction result.
1110+
//
1111+
// For example, this transforms
1112+
// vp<%min.result> = compute-reduction-result ir<%min.val>,
1113+
// ir<%min.val.next>
1114+
// vp<%find.iv.result = compute-find-iv-result ir<%min.idx>, ir<0>,
1115+
// SENTINEL, vp<%min.idx.next>
1116+
//
1117+
// into:
1118+
//
1119+
// vp<min.result> = compute-reduction-result ir<%min.val>, ir<%min.val.next>
1120+
// vp<%final.min.cmp> = icmp eq ir<%min.val.next>, vp<min.result>
1121+
// vp<%final.iv> = select vp<%final.min.cmp>, ir<%min.idx.next>, SENTINEL
1122+
// vp<%find.iv.result> = compute-find-iv-result ir<%min.idx>, ir<0>,
1123+
// SENTINEL, vp<%final.iv>
10861124
VPInstruction *FindIVResult =
10871125
findUserOf<VPInstruction::ComputeFindIVResult>(FindIVPhiR);
1088-
VPInstruction *MinMaxResult =
1089-
findUserOf<VPInstruction::ComputeReductionResult>(MinMaxPhiR);
1126+
assert(FindIVResult->getParent() == MinMaxResult->getParent() &&
1127+
"both results must be computed in the same block");
10901128
MinMaxResult->moveBefore(*FindIVResult->getParent(),
10911129
FindIVResult->getIterator());
10921130

10931131
VPBuilder B(FindIVResult);
1094-
auto *FinalMinMaxCmp = B.createICmp(
1095-
CmpInst::ICMP_EQ, MinMaxResult->getOperand(1), MinMaxResult);
1132+
VPValue *MinMaxExiting = MinMaxResult->getOperand(1);
1133+
auto *FinalMinMaxCmp =
1134+
B.createICmp(CmpInst::ICMP_EQ, MinMaxExiting, MinMaxResult);
1135+
VPValue *Sentinel = FindIVResult->getOperand(2);
1136+
VPValue *LastIVExiting = FindIVResult->getOperand(3);
10961137
auto *FinalIVSelect =
1097-
B.createSelect(FinalMinMaxCmp, FindIVResult->getOperand(3),
1098-
FindIVResult->getOperand(2));
1138+
B.createSelect(FinalMinMaxCmp, LastIVExiting, Sentinel);
10991139
FindIVResult->setOperand(3, FinalIVSelect);
11001140
}
11011141
return true;

0 commit comments

Comments
 (0)