@@ -79,6 +79,10 @@ static cl::opt<LoopVectorizeHints::ScalableForceKind>
7979 " Scalable vectorization is available and favored when the "
8080 " cost is inconclusive." )));
8181
82+ static cl::opt<bool >
83+ EnableCSA (" enable-csa-vectorization" , cl::init(false ), cl::Hidden,
84+ cl::desc(" Control whether CSA loop vectorization is enabled" ));
85+
8286// / Maximum vectorization interleave count.
8387static const unsigned MaxInterleaveFactor = 16 ;
8488
@@ -749,6 +753,15 @@ bool LoopVectorizationLegality::setupOuterLoopInductions() {
749753 return llvm::all_of (Header->phis (), IsSupportedPhi);
750754}
751755
756+ void LoopVectorizationLegality::addCSAPhi (
757+ PHINode *Phi, const CSADescriptor &CSADesc,
758+ SmallPtrSetImpl<Value *> &AllowedExit) {
759+ assert (CSADesc.isValid () && " Expected Valid CSADescriptor" );
760+ LLVM_DEBUG (dbgs () << " LV: found legal CSA opportunity" << *Phi << " \n " );
761+ AllowedExit.insert (Phi);
762+ CSAs.insert ({Phi, CSADesc});
763+ }
764+
752765// / Checks if a function is scalarizable according to the TLI, in
753766// / the sense that it should be vectorized and then expanded in
754767// / multiple scalar calls. This is represented in the
@@ -866,14 +879,23 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
866879 continue ;
867880 }
868881
869- // As a last resort, coerce the PHI to a AddRec expression
870- // and re-try classifying it a an induction PHI.
882+ // Try to coerce the PHI to a AddRec expression and re-try classifying
883+ // it a an induction PHI.
871884 if (InductionDescriptor::isInductionPHI (Phi, TheLoop, PSE, ID, true ) &&
872885 !IsDisallowedStridedPointerInduction (ID)) {
873886 addInductionPhi (Phi, ID, AllowedExit);
874887 continue ;
875888 }
876889
890+ // Check if the PHI can be classified as a CSA PHI.
891+ if (EnableCSA || (TTI->enableCSAVectorization () &&
892+ EnableCSA.getNumOccurrences () == 0 )) {
893+ if (auto CSADesc = CSADescriptor::isCSAPhi (Phi, TheLoop)) {
894+ addCSAPhi (Phi, CSADesc, AllowedExit);
895+ continue ;
896+ }
897+ }
898+
877899 reportVectorizationFailure (" Found an unidentified PHI" ,
878900 " value that could not be identified as "
879901 " reduction is used outside the loop" ,
@@ -1555,11 +1577,15 @@ bool LoopVectorizationLegality::canFoldTailByMasking() const {
15551577 for (const auto &Reduction : getReductionVars ())
15561578 ReductionLiveOuts.insert (Reduction.second .getLoopExitInstr ());
15571579
1580+ SmallPtrSet<const Value *, 8 > CSALiveOuts;
1581+ for (const auto &CSA: getCSAs ())
1582+ CSALiveOuts.insert (CSA.second .getAssignment ());
1583+
15581584 // TODO: handle non-reduction outside users when tail is folded by masking.
15591585 for (auto *AE : AllowedExit) {
15601586 // Check that all users of allowed exit values are inside the loop or
1561- // are the live-out of a reduction.
1562- if (ReductionLiveOuts.count (AE))
1587+ // are the live-out of a reduction or a CSA
1588+ if (ReductionLiveOuts.count (AE) || CSALiveOuts. count (AE) )
15631589 continue ;
15641590 for (User *U : AE->users ()) {
15651591 Instruction *UI = cast<Instruction>(U);
0 commit comments