@@ -43,10 +43,6 @@ AllowStridedPointerIVs("lv-strided-pointer-ivs", cl::init(false), cl::Hidden,
43
43
cl::desc(" Enable recognition of non-constant strided "
44
44
" pointer induction variables." ));
45
45
46
- static cl::opt<bool >
47
- EnableEarlyExitVectorization (" enable-early-exit-vectorization" ,
48
- cl::init (false ), cl::Hidden, cl::desc(" " ));
49
-
50
46
namespace llvm {
51
47
cl::opt<bool >
52
48
HintsAllowReordering (" hints-allow-reordering" , cl::init(true ), cl::Hidden,
@@ -87,6 +83,12 @@ static cl::opt<bool> EnableHistogramVectorization(
87
83
" enable-histogram-loop-vectorization" , cl::init(false ), cl::Hidden,
88
84
cl::desc(" Enables autovectorization of some loops containing histograms" ));
89
85
86
+ static cl::opt<bool > AssumeNoMemFault (
87
+ " vectorizer-no-mem-fault" , cl::init(false ), cl::Hidden,
88
+ cl::desc(" Assume vectorized loops will not have memory faults, which is "
89
+ " potentially unsafe but can be useful for testing vectorization "
90
+ " of early exit loops." ));
91
+
90
92
// / Maximum vectorization interleave count.
91
93
static const unsigned MaxInterleaveFactor = 16 ;
92
94
@@ -1379,10 +1381,14 @@ bool LoopVectorizationLegality::isFixedOrderRecurrence(
1379
1381
}
1380
1382
1381
1383
bool LoopVectorizationLegality::blockNeedsPredication (BasicBlock *BB) const {
1382
- // When vectorizing early exits, create predicates for all blocks, except the
1383
- // header.
1384
- if (canVectorizeEarlyExit () && BB != TheLoop->getHeader ())
1384
+ // The only block currently permitted after the early exiting block is the
1385
+ // loop latch, so only that blocks needs predication.
1386
+ // FIXME: Once we support instructions in the loop that cannot be executed
1387
+ // speculatively, such as stores, we will also need to predicate all blocks
1388
+ // leading up to the early exit too.
1389
+ if (hasUncountableEarlyExit () && BB == TheLoop->getLoopLatch ())
1385
1390
return true ;
1391
+
1386
1392
return LoopAccessInfo::blockNeedsPredication (BB, TheLoop, DT);
1387
1393
}
1388
1394
@@ -1519,27 +1525,6 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
1519
1525
return true ;
1520
1526
}
1521
1527
1522
- bool LoopVectorizationLegality::canVectorizeEarlyExit () const {
1523
- // Currently only allow vectorizing loops with early exits, if early-exit
1524
- // vectorization is explicitly enabled and the loop has metadata to force
1525
- // vectorization.
1526
- if (!EnableEarlyExitVectorization)
1527
- return false ;
1528
-
1529
- SmallVector<BasicBlock *> Exiting;
1530
- TheLoop->getExitingBlocks (Exiting);
1531
- if (Exiting.size () == 1 )
1532
- return false ;
1533
-
1534
- LoopVectorizeHints Hints (TheLoop, true , *ORE);
1535
- if (Hints.getForce () == LoopVectorizeHints::FK_Undefined)
1536
- return false ;
1537
-
1538
- Function *Fn = TheLoop->getHeader ()->getParent ();
1539
- return Hints.allowVectorization (Fn, TheLoop,
1540
- true /* VectorizeOnlyWhenForced*/ );
1541
- }
1542
-
1543
1528
// Helper function to canVectorizeLoopNestCFG.
1544
1529
bool LoopVectorizationLegality::canVectorizeLoopCFG (Loop *Lp,
1545
1530
bool UseVPlanNativePath) {
@@ -1662,6 +1647,15 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1662
1647
// PSE.getSymbolicMaxBackedgeTakenCount() below.
1663
1648
Predicates.clear ();
1664
1649
1650
+ unsigned NumUncountableExits = getUncountableExitingBlocks ().size ();
1651
+ if (NumUncountableExits > 0 ) {
1652
+ LoopVectorizeHints Hints (TheLoop, true , *ORE);
1653
+ if (Hints.getForce () != LoopVectorizeHints::FK_Undefined &&
1654
+ Hints.allowVectorization (TheLoop->getHeader ()->getParent (), TheLoop,
1655
+ true /* VectorizeOnlyWhenForced*/ ))
1656
+ return true ;
1657
+ }
1658
+
1665
1659
// We only support one uncountable early exit.
1666
1660
if (getUncountableExitingBlocks ().size () != 1 ) {
1667
1661
reportVectorizationFailure (
@@ -1736,11 +1730,15 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1736
1730
Predicates.clear ();
1737
1731
if (!isDereferenceableReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC,
1738
1732
&Predicates)) {
1739
- reportVectorizationFailure (
1740
- " Loop may fault" ,
1741
- " Cannot vectorize potentially faulting early exit loop" ,
1742
- " PotentiallyFaultingEarlyExitLoop" , ORE, TheLoop);
1743
- return false ;
1733
+ if (!AssumeNoMemFault) {
1734
+ reportVectorizationFailure (
1735
+ " Loop may fault" ,
1736
+ " Cannot vectorize potentially faulting early exit loop" ,
1737
+ " PotentiallyFaultingEarlyExitLoop" , ORE, TheLoop);
1738
+ return false ;
1739
+ } else
1740
+ LLVM_DEBUG (dbgs () << " LV: Assuming early exit vector loop will not "
1741
+ << " fault\n " );
1744
1742
}
1745
1743
1746
1744
[[maybe_unused]] const SCEV *SymbolicMaxBTC =
0 commit comments