@@ -1760,16 +1760,41 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
17601760 assert (LatchBB->getUniquePredecessor () == SingleUncountableExitingBlock &&
17611761 " Expected latch predecessor to be the early exiting block" );
17621762
1763- // TODO: Handle loops that may fault.
17641763 Predicates.clear ();
1765- if (!isDereferenceableReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC,
1766- &Predicates)) {
1764+ SmallVector<LoadInst *, 4 > NonDerefLoads;
1765+ bool HasSafeAccess =
1766+ TTI->supportsSpeculativeLoads ()
1767+ ? isReadOnlyLoopWithSafeOrSpeculativeLoads (
1768+ TheLoop, PSE.getSE (), DT, AC, &NonDerefLoads, &Predicates)
1769+ : isDereferenceableReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC,
1770+ &Predicates);
1771+ if (!HasSafeAccess) {
17671772 reportVectorizationFailure (
17681773 " Loop may fault" ,
17691774 " Cannot vectorize potentially faulting early exit loop" ,
17701775 " PotentiallyFaultingEarlyExitLoop" , ORE, TheLoop);
17711776 return false ;
17721777 }
1778+ // Speculative loads need to be unit-stride.
1779+ for (LoadInst *LI : NonDerefLoads) {
1780+ if (LI->getParent () != TheLoop->getHeader ()) {
1781+ reportVectorizationFailure (" Cannot vectorize predicated speculative load" ,
1782+ " SpeculativeLoadNeedsPredication" , ORE,
1783+ TheLoop);
1784+ return false ;
1785+ }
1786+ int Stride = isConsecutivePtr (LI->getType (), LI->getPointerOperand ());
1787+ if (Stride != 1 ) {
1788+ reportVectorizationFailure (" Loop contains non-unit-stride load" ,
1789+ " Cannot vectorize early exit loop with "
1790+ " speculative non-unit-stride load" ,
1791+ " SpeculativeNonUnitStrideLoadEarlyExitLoop" ,
1792+ ORE, TheLoop);
1793+ return false ;
1794+ }
1795+ SpeculativeLoads.insert (LI);
1796+ LLVM_DEBUG (dbgs () << " LV: Found speculative load: " << *LI << " \n " );
1797+ }
17731798
17741799 [[maybe_unused]] const SCEV *SymbolicMaxBTC =
17751800 PSE.getSymbolicMaxBackedgeTakenCount ();
0 commit comments