Skip to content

[VPlan] Implement VPlan-based cost model for VPReduction, VPExtendedReduction and VPMulAccumulateReduction. #113903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 61 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
33b1f60
[VPlan] Impl VPlan-based pattern match for ExtendedRed and MulAccRed.…
ElvisWang123 Oct 28, 2024
68fbd70
Partially support Extended-reduction.
ElvisWang123 Nov 4, 2024
c8c9d56
Support MulAccRecipe
ElvisWang123 Nov 5, 2024
d29a118
Fix servel errors and update tests.
ElvisWang123 Nov 6, 2024
e5b50f7
Refactors
ElvisWang123 Nov 6, 2024
cc004ff
Fix typos and update printing test
ElvisWang123 Nov 7, 2024
b5445ca
Fold reduce.add(zext(mul(sext(A), sext(B)))) into MulAccRecipe when A…
ElvisWang123 Nov 11, 2024
1df91d4
Refactor! Reuse functions from VPReductionRecipe.
ElvisWang123 Nov 11, 2024
a0b2f30
Refactor! Add comments and refine new recipes.
ElvisWang123 Nov 12, 2024
46928bd
Remove underying instruction dependency.
ElvisWang123 Nov 14, 2024
35abf19
Revert "Remove underying instruction dependency."
ElvisWang123 Nov 14, 2024
453997e
Remove extended instruction after mul in MulAccRecipe.
ElvisWang123 Nov 15, 2024
fa4f476
Refactor.
ElvisWang123 Nov 15, 2024
86ad2d8
Clamp the range when the ExtendedReduction or MulAcc cost is invalid.
ElvisWang123 Nov 15, 2024
594f9e4
Try to not depend on underlying ext/mul instructions and preserve fla…
ElvisWang123 Nov 18, 2024
52369d0
Update testcase and fix reduction cost.
ElvisWang123 Nov 25, 2024
abc08f3
!fixup. Rebase to upstream `prepareToExecute()` implementation.
ElvisWang123 Dec 5, 2024
729a70e
Move VPReductionRecipe inherite from VPRecipeWithIRFlags.
ElvisWang123 Dec 11, 2024
ea58282
Only create VPMulAcc/VPExtendedReduction recipe when beneficial. NFC
ElvisWang123 Dec 11, 2024
1c22ce2
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Dec 11, 2024
a987456
!fixup use `auto`
ElvisWang123 Dec 12, 2024
6c434c7
!fixup VPReductionRecipe unit tests.
ElvisWang123 Dec 12, 2024
f4b1b78
!fixup migrate tryTo* to VPlanTransforms
ElvisWang123 Dec 23, 2024
bffcac5
Implement clone() and add some docs.
ElvisWang123 Dec 23, 2024
da705f1
Update comments.
ElvisWang123 Dec 23, 2024
1dc279e
fix-ReductionEVLRecipe query underlyingInstr().
ElvisWang123 Dec 23, 2024
20ea82e
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Dec 23, 2024
90f9ffa
Update after merge.
ElvisWang123 Dec 23, 2024
99512fe
Address comments and split off abstract recipes creation from adjustR…
ElvisWang123 Dec 26, 2024
2e4014a
!fixup using foldTailWithEVL.
ElvisWang123 Dec 27, 2024
38dd924
!fixup, remove extra debugLoc and move check of EVL out of transforms.
ElvisWang123 Jan 21, 2025
602a5e4
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Jan 21, 2025
1939d44
Update after merge main.
ElvisWang123 Jan 22, 2025
2ee6e76
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Feb 17, 2025
d584fc1
Update after merge. Using runPass::().
ElvisWang123 Feb 18, 2025
21b33e6
!fixup, Remove unused check and functions.
ElvisWang123 Feb 26, 2025
ae371e5
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Mar 4, 2025
0d7b7f3
!fixup; Address comments.
ElvisWang123 Mar 4, 2025
e12bd04
!fixup, Add Mul cost to prevent FMuladd Reduction cost misaligned.
ElvisWang123 Mar 7, 2025
4906637
!Fixup, typo.
ElvisWang123 Mar 10, 2025
ca5db10
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Mar 18, 2025
2fbdc7c
!fixup, Address comments and fix VPReductionRecipe::computeCost
ElvisWang123 Mar 19, 2025
38d83bf
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Mar 19, 2025
3e2acad
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Mar 19, 2025
d2a5a43
!fixup, Update after merge, using std::array.
ElvisWang123 Mar 19, 2025
484f9cc
fixup, formatting.
ElvisWang123 Mar 19, 2025
cd86af4
!fixup, address comments.
ElvisWang123 Mar 20, 2025
84f8a46
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Mar 25, 2025
36e1032
!fixup, formatting and address comments.
ElvisWang123 Mar 25, 2025
2483a29
!fixup, Update inferScalarType and not clear the VF of plan.
ElvisWang123 Apr 7, 2025
56dcd90
!fixup, address comments.
ElvisWang123 Apr 10, 2025
26d938a
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 Apr 18, 2025
b32538f
!fixup, address comments.
ElvisWang123 Apr 18, 2025
fd539f8
!fixup, address comments and using `transferFlags()` to copy nneg.
ElvisWang123 Apr 23, 2025
71c7401
!fixup, address comments.
ElvisWang123 Apr 23, 2025
7da7983
!fixup, Add new recipes to mayReadWriteMemory.
ElvisWang123 Apr 24, 2025
f4afc2c
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 May 16, 2025
7b25767
Fixup after merge.
ElvisWang123 May 16, 2025
685f217
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 May 28, 2025
710df44
Address comments.
ElvisWang123 May 28, 2025
829cb2a
Merge branch 'main' into vp-arm-mve-transform
ElvisWang123 May 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Address comments and split off abstract recipes creation from adjustR…
…ecipesForReduction.
  • Loading branch information
ElvisWang123 committed Dec 26, 2024
commit 99512fedb0cf7b7b684386cc41624b1036aa8bff
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ class LoopVectorizationPlanner {
// between the phi and users outside the vector region when folding the tail.
void adjustRecipesForReductions(VPlanPtr &Plan,
VPRecipeBuilder &RecipeBuilder,
VFRange &Range);
ElementCount MinVF);

#ifndef NDEBUG
/// \return The most profitable vectorization factor for the available VPlans
Expand Down
39 changes: 11 additions & 28 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static cl::opt<PreferPredicateTy::Option> PreferPredicateOverEpilogue(
"prefers tail-folding, don't attempt vectorization if "
"tail-folding fails.")));

static cl::opt<TailFoldingStyle> ForceTailFoldingStyle(
cl::opt<TailFoldingStyle> ForceTailFoldingStyle(
"force-tail-folding-style", cl::desc("Force the tail folding style"),
cl::init(TailFoldingStyle::None),
cl::values(
Expand Down Expand Up @@ -9313,7 +9313,12 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
// ---------------------------------------------------------------------------

// Adjust the recipes for any inloop reductions.
adjustRecipesForReductions(Plan, RecipeBuilder, Range);
adjustRecipesForReductions(Plan, RecipeBuilder, Range.Start);

// Transform recipes to abstract recipes if it is beneficial and clamp
// the range.
VPCostContext CostCtx(CM.TTI, *CM.TLI, Legal->getWidestInductionType(), CM);
VPlanTransforms::convertToAbstractRecipes(*Plan, CostCtx, Range);

// Interleave memory: for each Interleave Group we marked earlier as relevant
// for this VPlan, replace the Recipes widening its memory instructions with a
Expand Down Expand Up @@ -9435,9 +9440,8 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
// with a boolean reduction phi node to check if the condition is true in any
// iteration. The final value is selected by the final ComputeReductionResult.
void LoopVectorizationPlanner::adjustRecipesForReductions(
VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder, VFRange &Range) {
VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder, ElementCount MinVF) {
using namespace VPlanPatternMatch;
ElementCount MinVF = Range.Start;
VPRegionBlock *VectorLoopRegion = Plan->getVectorLoopRegion();
VPBasicBlock *Header = VectorLoopRegion->getEntryBasicBlock();
VPBasicBlock *MiddleVPBB = Plan->getMiddleBlock();
Expand Down Expand Up @@ -9555,30 +9559,9 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
if (CM.blockNeedsPredicationForAnyReason(BB))
CondOp = RecipeBuilder.getBlockInMask(BB);

VPReductionRecipe *RedRecipe;
VPCostContext CostCtx(CM.TTI, *CM.TLI, Legal->getWidestInductionType(),
CM);
bool IsOrderedRed = CM.useOrderedReductions(RdxDesc);
// TODO: Remove EVL check when we support EVL version of
// VPExtendedReductionRecipe and VPMulAccumulateReductionRecipe.
if (ForceTailFoldingStyle == TailFoldingStyle::DataWithEVL) {
RedRecipe = new VPReductionRecipe(RdxDesc, CurrentLinkI, PreviousLink,
VecOp, CondOp, IsOrderedRed);
} else {
if (auto *MulAcc =
VPlanTransforms::tryToMatchAndCreateMulAccumulateReduction(
RdxDesc, CurrentLinkI, PreviousLink, VecOp, CondOp,
IsOrderedRed, CostCtx, Range))
RedRecipe = MulAcc;
else if (auto *ExtRed =
VPlanTransforms::tryToMatchAndCreateExtendedReduction(
RdxDesc, CurrentLinkI, PreviousLink, VecOp, CondOp,
IsOrderedRed, CostCtx, Range))
RedRecipe = ExtRed;
else
RedRecipe = new VPReductionRecipe(RdxDesc, CurrentLinkI, PreviousLink,
VecOp, CondOp, IsOrderedRed);
}
VPReductionRecipe *RedRecipe =
new VPReductionRecipe(RdxDesc, CurrentLinkI, PreviousLink, VecOp,
CondOp, CM.useOrderedReductions(RdxDesc));
// Append the recipe to the end of the VPBasicBlock because we need to
// ensure that it comes after all of it's inputs, including CondOp.
// Note that this transformation may leave over dead recipes (including
Expand Down
94 changes: 43 additions & 51 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -1578,7 +1578,7 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags {
ResultTy(ResultTy) {}

VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy,
bool IsNonNeg, DebugLoc DL)
bool IsNonNeg, DebugLoc DL = {})
: VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, NonNegFlagsTy(IsNonNeg),
DL),
Opcode(Opcode), ResultTy(ResultTy) {}
Expand Down Expand Up @@ -2643,8 +2643,8 @@ class VPReductionRecipe : public VPRecipeWithIRFlags {
}
}

// For VPExtendedReductionRecipe.
// Note that IsNonNeg flag and the debug location are for extend instruction.
/// For VPExtendedReductionRecipe.
/// Note that IsNonNeg flag and the debug location are for extend instruction.
VPReductionRecipe(const unsigned char SC, const RecurrenceDescriptor &R,
ArrayRef<VPValue *> Operands, VPValue *CondOp,
bool IsOrdered, bool IsNonNeg, DebugLoc DL)
Expand All @@ -2656,8 +2656,8 @@ class VPReductionRecipe : public VPRecipeWithIRFlags {
}
}

// For VPMulAccRecipe.
// Note that the NUW/NSW and DL are for mul instruction.
/// For VPMulAccumulateReductionRecipe.
/// Note that the NUW/NSW and DL are for mul instruction.
VPReductionRecipe(const unsigned char SC, const RecurrenceDescriptor &R,
ArrayRef<VPValue *> Operands, VPValue *CondOp,
bool IsOrdered, bool NUW, bool NSW, DebugLoc DL)
Expand Down Expand Up @@ -2797,22 +2797,19 @@ class VPExtendedReductionRecipe : public VPReductionRecipe {
DebugLoc RedDL;

public:
VPExtendedReductionRecipe(const RecurrenceDescriptor &R, Instruction *RedI,
VPValue *ChainOp, VPWidenCastRecipe *Ext,
VPValue *CondOp, bool IsOrdered)
: VPReductionRecipe(VPDef::VPExtendedReductionSC, R,
ArrayRef<VPValue *>({ChainOp, Ext->getOperand(0)}),
CondOp, IsOrdered, Ext->isNonNeg(),
Ext->getDebugLoc()),
ExtOp(Ext->getOpcode()), RedDL(RedI->getDebugLoc()) {}

/// Contructor for cloning VPExtendedReductionRecipe.
VPExtendedReductionRecipe(VPReductionRecipe *R, VPWidenCastRecipe *Ext)
: VPReductionRecipe(VPDef::VPExtendedReductionSC,
R->getRecurrenceDescriptor(),
{R->getChainOp(), Ext->getOperand(0)}, R->getCondOp(),
R->isOrdered(), Ext->isNonNeg(), Ext->getDebugLoc()),
ExtOp(Ext->getOpcode()), RedDL(R->getDebugLoc()) {}

/// For cloning VPExtendedReductionRecipe.
VPExtendedReductionRecipe(VPExtendedReductionRecipe *ExtRed)
: VPReductionRecipe(
VPDef::VPExtendedReductionSC, ExtRed->getRecurrenceDescriptor(),
ArrayRef<VPValue *>({ExtRed->getChainOp(), ExtRed->getVecOp()}),
ExtRed->getCondOp(), ExtRed->isOrdered(), ExtRed->isNonNeg(),
ExtRed->getExtDebugLoc()),
{ExtRed->getChainOp(), ExtRed->getVecOp()}, ExtRed->getCondOp(),
ExtRed->isOrdered(), ExtRed->isNonNeg(), ExtRed->getExtDebugLoc()),
ExtOp(ExtRed->getExtOpcode()), RedDL(ExtRed->getRedDebugLoc()) {}

~VPExtendedReductionRecipe() override = default;
Expand Down Expand Up @@ -2843,15 +2840,16 @@ class VPExtendedReductionRecipe : public VPReductionRecipe {
return getRecurrenceDescriptor().getRecurrenceType();
}

/// Is the extend ZExt?
bool isZExt() const { return getExtOpcode() == Instruction::ZExt; }

/// The Opcode of extend instruction.
/// The Opcode of extend recipe.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The Opcode of extend recipe.
/// The opcode of extend recipe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Instruction::CastOps getExtOpcode() const { return ExtOp; }

/// Return the debug location of the extend instruction.
/// Return the debug location of the extend recipe.
DebugLoc getExtDebugLoc() const { return getDebugLoc(); }

/// Return the debug location of the reduction instruction.
/// Return the debug location of the reduction recipe.
DebugLoc getRedDebugLoc() const { return RedDL; }
};

Expand All @@ -2865,7 +2863,7 @@ class VPMulAccumulateReductionRecipe : public VPReductionRecipe {
Instruction::CastOps ExtOp;

/// Non-neg flag of the extend recipe.
bool IsNonNeg;
bool IsNonNeg = false;

/// Debug location of extend recipes will be lowered to.
DebugLoc Ext0DL;
Expand All @@ -2878,47 +2876,41 @@ class VPMulAccumulateReductionRecipe : public VPReductionRecipe {
bool IsExtended = false;

public:
VPMulAccumulateReductionRecipe(const RecurrenceDescriptor &R,
Instruction *RedI, VPValue *ChainOp,
VPValue *CondOp, bool IsOrdered,
VPWidenRecipe *Mul, VPWidenCastRecipe *Ext0,
VPMulAccumulateReductionRecipe(VPReductionRecipe *R, VPWidenRecipe *Mul,
VPWidenCastRecipe *Ext0,
VPWidenCastRecipe *Ext1)
: VPReductionRecipe(VPDef::VPMulAccumulateReductionSC, R,
ArrayRef<VPValue *>({ChainOp, Ext0->getOperand(0),
Ext1->getOperand(0)}),
CondOp, IsOrdered, Mul->hasNoUnsignedWrap(),
Mul->hasNoSignedWrap(), Mul->getDebugLoc()),
: VPReductionRecipe(
VPDef::VPMulAccumulateReductionSC, R->getRecurrenceDescriptor(),
{R->getChainOp(), Ext0->getOperand(0), Ext1->getOperand(0)},
R->getCondOp(), R->isOrdered(), Mul->hasNoUnsignedWrap(),
Mul->hasNoSignedWrap(), Mul->getDebugLoc()),
ExtOp(Ext0->getOpcode()), IsNonNeg(Ext0->isNonNeg()),
Ext0DL(Ext0->getDebugLoc()), Ext1DL(Ext1->getDebugLoc()),
RedDL(RedI->getDebugLoc()) {
assert(R.getOpcode() == Instruction::Add &&
RedDL(R->getDebugLoc()) {
assert(getRecurrenceDescriptor().getOpcode() == Instruction::Add &&
"The reduction instruction in MulAccumulateteReductionRecipe must "
"be Add");
IsExtended = true;
}

VPMulAccumulateReductionRecipe(const RecurrenceDescriptor &R,
Instruction *RedI, VPValue *ChainOp,
VPValue *CondOp, bool IsOrdered,
VPWidenRecipe *Mul)
: VPReductionRecipe(VPDef::VPMulAccumulateReductionSC, R,
ArrayRef<VPValue *>({ChainOp, Mul->getOperand(0),
Mul->getOperand(1)}),
CondOp, IsOrdered, Mul->hasNoUnsignedWrap(),
Mul->hasNoSignedWrap(), Mul->getDebugLoc()),
RedDL(RedI->getDebugLoc()) {
assert(R.getOpcode() == Instruction::Add &&
VPMulAccumulateReductionRecipe(VPReductionRecipe *R, VPWidenRecipe *Mul)
: VPReductionRecipe(
VPDef::VPMulAccumulateReductionSC, R->getRecurrenceDescriptor(),
{R->getChainOp(), Mul->getOperand(0), Mul->getOperand(1)},
R->getCondOp(), R->isOrdered(), Mul->hasNoUnsignedWrap(),
Mul->hasNoSignedWrap(), Mul->getDebugLoc()),
RedDL(R->getDebugLoc()) {
assert(getRecurrenceDescriptor().getOpcode() == Instruction::Add &&
"The reduction instruction in MulAccumulateReductionRecipe must be "
"Add");
}

/// Constructor for cloning VPMulAccumulateReductionRecipe.
/// For cloning VPMulAccumulateReductionRecipe.
VPMulAccumulateReductionRecipe(VPMulAccumulateReductionRecipe *MulAcc)
: VPReductionRecipe(
VPDef::VPMulAccumulateReductionSC,
MulAcc->getRecurrenceDescriptor(),
ArrayRef<VPValue *>({MulAcc->getChainOp(), MulAcc->getVecOp0(),
MulAcc->getVecOp1()}),
{MulAcc->getChainOp(), MulAcc->getVecOp0(), MulAcc->getVecOp1()},
MulAcc->getCondOp(), MulAcc->isOrdered(),
MulAcc->hasNoUnsignedWrap(), MulAcc->hasNoSignedWrap(),
MulAcc->getMulDebugLoc()),
Expand Down Expand Up @@ -2970,7 +2962,7 @@ class VPMulAccumulateReductionRecipe : public VPReductionRecipe {
return ExtOp == Instruction::CastOps::ZExt;
}

/// Return the non negative flag for the ext instruction.
/// Return the non negative flag of the ext recipe.
bool isNonNeg() const { return IsNonNeg; }

/// Drop flags in this recipe.
Expand All @@ -2980,14 +2972,14 @@ class VPMulAccumulateReductionRecipe : public VPReductionRecipe {
this->IsNonNeg = false;
}

/// Return debug location of mul instruction.
/// Return debug location of mul recipe.
DebugLoc getMulDebugLoc() const { return getDebugLoc(); }

/// Return debug location of extend instructions.
/// Return debug location of extend recipe.
DebugLoc getExt0DebugLoc() const { return Ext0DL; }
DebugLoc getExt1DebugLoc() const { return Ext1DL; }

/// Return the debug location of reduction instruction.
/// Return the debug location of reduction recipe.
DebugLoc getRedDebugLoc() const { return RedDL; }
};

Expand Down
45 changes: 22 additions & 23 deletions llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1523,50 +1523,49 @@ void VPWidenCastRecipe::execute(VPTransformState &State) {
setFlags(CastOp);
}

/// Computes the CastContextHint for a recipe.
static TTI::CastContextHint computeCCH(const VPRecipeBase *R, ElementCount VF) {
if (VF.isScalar())
return TTI::CastContextHint::Normal;
if (isa<VPInterleaveRecipe>(R))
return TTI::CastContextHint::Interleave;
if (const auto *ReplicateRecipe = dyn_cast<VPReplicateRecipe>(R))
return ReplicateRecipe->isPredicated() ? TTI::CastContextHint::Masked
: TTI::CastContextHint::Normal;
const auto *WidenMemoryRecipe = dyn_cast<VPWidenMemoryRecipe>(R);
if (WidenMemoryRecipe == nullptr)
return TTI::CastContextHint::None;
if (!WidenMemoryRecipe->isConsecutive())
return TTI::CastContextHint::GatherScatter;
if (WidenMemoryRecipe->isReverse())
return TTI::CastContextHint::Reversed;
if (WidenMemoryRecipe->isMasked())
return TTI::CastContextHint::Masked;
return TTI::CastContextHint::Normal;
}

InstructionCost VPWidenCastRecipe::computeCost(ElementCount VF,
VPCostContext &Ctx) const {
// TODO: In some cases, VPWidenCastRecipes are created but not considered in
// the legacy cost model, including truncates/extends when evaluating a
// reduction in a smaller type.
if (!getUnderlyingValue())
return 0;
// Computes the CastContextHint from a recipes that may access memory.
auto ComputeCCH = [&](const VPRecipeBase *R) -> TTI::CastContextHint {
if (VF.isScalar())
return TTI::CastContextHint::Normal;
if (isa<VPInterleaveRecipe>(R))
return TTI::CastContextHint::Interleave;
if (const auto *ReplicateRecipe = dyn_cast<VPReplicateRecipe>(R))
return ReplicateRecipe->isPredicated() ? TTI::CastContextHint::Masked
: TTI::CastContextHint::Normal;
const auto *WidenMemoryRecipe = dyn_cast<VPWidenMemoryRecipe>(R);
if (WidenMemoryRecipe == nullptr)
return TTI::CastContextHint::None;
if (!WidenMemoryRecipe->isConsecutive())
return TTI::CastContextHint::GatherScatter;
if (WidenMemoryRecipe->isReverse())
return TTI::CastContextHint::Reversed;
if (WidenMemoryRecipe->isMasked())
return TTI::CastContextHint::Masked;
return TTI::CastContextHint::Normal;
};

VPValue *Operand = getOperand(0);
TTI::CastContextHint CCH = TTI::CastContextHint::None;
// For Trunc/FPTrunc, get the context from the only user.
if ((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) &&
!hasMoreThanOneUniqueUser() && getNumUsers() > 0) {
if (auto *StoreRecipe = dyn_cast<VPRecipeBase>(*user_begin()))
CCH = computeCCH(StoreRecipe, VF);
CCH = ComputeCCH(StoreRecipe);
}
// For Z/Sext, get the context from the operand.
else if (Opcode == Instruction::ZExt || Opcode == Instruction::SExt ||
Opcode == Instruction::FPExt) {
if (Operand->isLiveIn())
CCH = TTI::CastContextHint::Normal;
else if (Operand->getDefiningRecipe())
CCH = computeCCH(Operand->getDefiningRecipe(), VF);
CCH = ComputeCCH(Operand->getDefiningRecipe());
}

auto *SrcTy =
Expand Down
Loading