@@ -1051,7 +1051,7 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
1051
1051
return true ;
1052
1052
}
1053
1053
1054
- bool LoopVectorizationLegality::canVectorizeMemory () {
1054
+ bool LoopVectorizationLegality::canVectorizeMemory (bool IsEarlyExitLoop ) {
1055
1055
LAI = &LAIs.getInfo (*TheLoop);
1056
1056
const OptimizationRemarkAnalysis *LAR = LAI->getReport ();
1057
1057
if (LAR) {
@@ -1073,6 +1073,50 @@ bool LoopVectorizationLegality::canVectorizeMemory() {
1073
1073
return false ;
1074
1074
}
1075
1075
1076
+ // For loops with uncountable early exiting blocks that are not the latch
1077
+ // it's necessary to perform extra checks, since the vectoriser is currently
1078
+ // only capable of handling simple search loops.
1079
+ if (IsEarlyExitLoop) {
1080
+ // We don't support calls or any memory accesses that write to memory.
1081
+ if (LAI->getNumStores ()) {
1082
+ reportVectorizationFailure (
1083
+ " Writes to memory unsupported in early exit loops" ,
1084
+ " Cannot vectorize early exit loop with writes to memory" ,
1085
+ " WritesInEarlyExitLoop" , ORE, TheLoop);
1086
+ return false ;
1087
+ }
1088
+
1089
+ if (LAI->getNumCalls ()) {
1090
+ reportVectorizationFailure (
1091
+ " Calls unsupported in early exit loops" ,
1092
+ " Cannot vectorize early exit loop with function calls" ,
1093
+ " CallsInEarlyExitLoop" , ORE, TheLoop);
1094
+ return false ;
1095
+ }
1096
+
1097
+ // The vectoriser cannot handle loads that occur after the early exit block.
1098
+ BasicBlock *LatchBB = TheLoop->getLoopLatch ();
1099
+ for (Instruction &I : *LatchBB) {
1100
+ if (I.mayReadFromMemory ()) {
1101
+ reportVectorizationFailure (
1102
+ " Loads not permitted after early exit" ,
1103
+ " Cannot vectorize early exit loop with loads after early exit" ,
1104
+ " LoadsAfterEarlyExit" , ORE, TheLoop);
1105
+ return false ;
1106
+ }
1107
+ }
1108
+
1109
+ // The vectoriser does not yet handle loops that may fault, but this will
1110
+ // be improved in a follow-on patch.
1111
+ if (!isDereferenceableReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC)) {
1112
+ reportVectorizationFailure (
1113
+ " Loop may fault" ,
1114
+ " Cannot vectorize potentially faulting early exit loop" ,
1115
+ " PotentiallyFaultingEarlyExitLoop" , ORE, TheLoop);
1116
+ return false ;
1117
+ }
1118
+ }
1119
+
1076
1120
// We can vectorize stores to invariant address when final reduction value is
1077
1121
// guaranteed to be stored at the end of the loop. Also, if decision to
1078
1122
// vectorize loop is made, runtime checks are added so as to make sure that
@@ -1445,6 +1489,95 @@ bool LoopVectorizationLegality::canVectorizeLoopNestCFG(
1445
1489
return Result;
1446
1490
}
1447
1491
1492
+ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop () {
1493
+ // At least one of the exiting blocks must be the latch.
1494
+ BasicBlock *LatchBB = TheLoop->getLoopLatch ();
1495
+ if (!LatchBB) {
1496
+ reportVectorizationFailure (" Loop does not have a latch" ,
1497
+ " Cannot vectorize early exit loop" ,
1498
+ " NoLatchEarlyExit" , ORE, TheLoop);
1499
+ return false ;
1500
+ }
1501
+
1502
+ SmallVector<BasicBlock *, 8 > ExitingBlocks;
1503
+ TheLoop->getExitingBlocks (ExitingBlocks);
1504
+
1505
+ // Keep a record of all the exiting blocks with exact exit counts, as well as
1506
+ // those with inexact counts.
1507
+ SmallVector<const SCEVPredicate *, 4 > Predicates;
1508
+ for (BasicBlock *BB1 : ExitingBlocks) {
1509
+ const SCEV *EC =
1510
+ PSE.getSE ()->getPredicatedExitCount (TheLoop, BB1, &Predicates);
1511
+ if (isa<SCEVCouldNotCompute>(EC)) {
1512
+ UncountableExitingBlocks.push_back (BB1);
1513
+
1514
+ unsigned NumExitBlocks = 0 ;
1515
+ for (BasicBlock *BB2 : successors (BB1)) {
1516
+ if (!TheLoop->contains (BB2)) {
1517
+ UncountableExitBlocks.push_back (BB2);
1518
+ NumExitBlocks++;
1519
+ }
1520
+ }
1521
+ if (NumExitBlocks > 1 ) {
1522
+ reportVectorizationFailure (
1523
+ " Early exiting block has more than one successor outside of loop" ,
1524
+ " Too many successors from early exiting block" ,
1525
+ " EarlyExitTooManySuccessors" , ORE, TheLoop);
1526
+ return false ;
1527
+ }
1528
+ } else
1529
+ CountableExitingBlocks.push_back (BB1);
1530
+ }
1531
+ Predicates.clear ();
1532
+
1533
+ // We only support one uncountable early exit.
1534
+ if (getUncountableExitingBlocks ().size () != 1 ) {
1535
+ reportVectorizationFailure (
1536
+ " Loop has too many uncountable exits" ,
1537
+ " Cannot vectorize early exit loop with more than one early exit" ,
1538
+ " TooManyUncountableEarlyExits" , ORE, TheLoop);
1539
+ return false ;
1540
+ }
1541
+
1542
+ // The only supported early exit loops so far are ones where the early
1543
+ // exiting block is a unique predecessor of the latch block.
1544
+ BasicBlock *LatchPredBB = LatchBB->getUniquePredecessor ();
1545
+ if (!LatchPredBB || LatchPredBB != getUncountableExitingBlocks ()[0 ]) {
1546
+ reportVectorizationFailure (" Early exit is not the latch predecessor" ,
1547
+ " Cannot vectorize early exit loop" ,
1548
+ " EarlyExitNotLatchPredecessor" , ORE, TheLoop);
1549
+ return false ;
1550
+ }
1551
+
1552
+ if (Reductions.size () || FixedOrderRecurrences.size ()) {
1553
+ reportVectorizationFailure (
1554
+ " Found reductions or recurrences in early-exit loop" ,
1555
+ " Cannot vectorize early exit loop with reductions or recurrences" ,
1556
+ " RecurrencesInEarlyExitLoop" , ORE, TheLoop);
1557
+ return false ;
1558
+ }
1559
+
1560
+ LLVM_DEBUG (
1561
+ dbgs ()
1562
+ << " LV: Found an early exit. Retrying with speculative exit count.\n " );
1563
+ if (isa<SCEVCouldNotCompute>(
1564
+ PSE.getSE ()->getPredicatedExitCount (TheLoop, LatchBB, &Predicates))) {
1565
+ reportVectorizationFailure (
1566
+ " Cannot determine exact exit count for latch block" ,
1567
+ " Cannot vectorize early exit loop" ,
1568
+ " UnknownLatchExitCountEarlyExitLoop" , ORE, TheLoop);
1569
+ return false ;
1570
+ }
1571
+
1572
+ const SCEV *SpecExitCount = PSE.getSymbolicMaxBackedgeTakenCount ();
1573
+ assert (!isa<SCEVCouldNotCompute>(SpecExitCount) &&
1574
+ " Failed to get symbolic expression for backedge taken count" );
1575
+
1576
+ LLVM_DEBUG (dbgs () << " LV: Found speculative backedge taken count: "
1577
+ << *SpecExitCount << ' \n ' );
1578
+ return true ;
1579
+ }
1580
+
1448
1581
bool LoopVectorizationLegality::canVectorize (bool UseVPlanNativePath) {
1449
1582
// Store the result and return it at the end instead of exiting early, in case
1450
1583
// allowExtraAnalysis is used to report multiple reasons for not vectorizing.
@@ -1505,19 +1638,20 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
1505
1638
return false ;
1506
1639
}
1507
1640
1508
- // Go over each instruction and look at memory deps.
1509
- if (!canVectorizeMemory ()) {
1510
- LLVM_DEBUG (dbgs () << " LV: Can't vectorize due to memory conflicts\n " );
1511
- if (DoExtraAnalysis)
1512
- Result = false ;
1513
- else
1514
- return false ;
1641
+ HasSpeculativeEarlyExit = false ;
1642
+ if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount ())) {
1643
+ if (!isVectorizableEarlyExitLoop ()) {
1644
+ if (DoExtraAnalysis)
1645
+ Result = false ;
1646
+ else
1647
+ return false ;
1648
+ } else
1649
+ HasSpeculativeEarlyExit = true ;
1515
1650
}
1516
1651
1517
- if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount ())) {
1518
- reportVectorizationFailure (" could not determine number of loop iterations" ,
1519
- " could not determine number of loop iterations" ,
1520
- " CantComputeNumberOfIterations" , ORE, TheLoop);
1652
+ // Go over each instruction and look at memory deps.
1653
+ if (!canVectorizeMemory (HasSpeculativeEarlyExit)) {
1654
+ LLVM_DEBUG (dbgs () << " LV: Can't vectorize due to memory conflicts\n " );
1521
1655
if (DoExtraAnalysis)
1522
1656
Result = false ;
1523
1657
else
0 commit comments