@@ -1086,16 +1086,12 @@ bool LoopVectorizationLegality::canVectorizeMemory(bool IsEarlyExitLoop) {
1086
1086
return false ;
1087
1087
}
1088
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
1089
// The vectoriser cannot handle loads that occur after the early exit block.
1098
1090
BasicBlock *LatchBB = TheLoop->getLoopLatch ();
1091
+ assert (LatchBB->getUniquePredecessor () ==
1092
+ getUncountableExitingBlocks ()[0 ] &&
1093
+ " Expected latch predecessor to be the early exiting block" );
1094
+
1099
1095
for (Instruction &I : *LatchBB) {
1100
1096
if (I.mayReadFromMemory ()) {
1101
1097
reportVectorizationFailure (
@@ -1104,10 +1100,15 @@ bool LoopVectorizationLegality::canVectorizeMemory(bool IsEarlyExitLoop) {
1104
1100
" LoadsAfterEarlyExit" , ORE, TheLoop);
1105
1101
return false ;
1106
1102
}
1103
+ // Any other problematic instructions should have been caught earlier.
1104
+ assert (!I.mayWriteToMemory () && !I.mayThrow () &&
1105
+ !I.mayHaveSideEffects () &&
1106
+ " Unexpected instructions in latch block of early exit loop" );
1107
1107
}
1108
1108
1109
1109
// The vectoriser does not yet handle loops that may fault, but this will
1110
1110
// be improved in a follow-on patch.
1111
+ // TODO: Handle loops that may fault.
1111
1112
if (!isDereferenceableReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC)) {
1112
1113
reportVectorizationFailure (
1113
1114
" Loop may fault" ,
@@ -1499,32 +1500,42 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1499
1500
return false ;
1500
1501
}
1501
1502
1503
+ if (Reductions.size () || FixedOrderRecurrences.size ()) {
1504
+ reportVectorizationFailure (
1505
+ " Found reductions or recurrences in early-exit loop" ,
1506
+ " Cannot vectorize early exit loop with reductions or recurrences" ,
1507
+ " RecurrencesInEarlyExitLoop" , ORE, TheLoop);
1508
+ return false ;
1509
+ }
1510
+
1502
1511
SmallVector<BasicBlock *, 8 > ExitingBlocks;
1503
1512
TheLoop->getExitingBlocks (ExitingBlocks);
1504
1513
1505
- // Keep a record of all the exiting blocks with exact exit counts, as well as
1506
- // those with inexact counts.
1514
+ // Keep a record of all the exiting blocks.
1507
1515
SmallVector<const SCEVPredicate *, 4 > Predicates;
1508
1516
for (BasicBlock *BB1 : ExitingBlocks) {
1509
1517
const SCEV *EC =
1510
1518
PSE.getSE ()->getPredicatedExitCount (TheLoop, BB1, &Predicates);
1511
1519
if (isa<SCEVCouldNotCompute>(EC)) {
1512
1520
UncountableExitingBlocks.push_back (BB1);
1513
1521
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
+ SmallVector<BasicBlock *, 2 > Succs (successors (BB1));
1523
+ if (Succs.size () != 2 ) {
1522
1524
reportVectorizationFailure (
1523
- " Early exiting block has more than one successor outside of loop " ,
1524
- " Too many successors from early exiting block" ,
1525
+ " Early exiting block does not have exactly two successors " ,
1526
+ " Incorrect number of successors from early exiting block" ,
1525
1527
" EarlyExitTooManySuccessors" , ORE, TheLoop);
1526
1528
return false ;
1527
1529
}
1530
+
1531
+ BasicBlock *BB2;
1532
+ if (!TheLoop->contains (Succs[0 ]))
1533
+ BB2 = Succs[0 ];
1534
+ else {
1535
+ assert (!TheLoop->contains (Succs[1 ]));
1536
+ BB2 = Succs[1 ];
1537
+ }
1538
+ UncountableExitBlocks.push_back (BB2);
1528
1539
} else
1529
1540
CountableExitingBlocks.push_back (BB1);
1530
1541
}
@@ -1549,13 +1560,34 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1549
1560
return false ;
1550
1561
}
1551
1562
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
- }
1563
+ // Check all instructions in the loop to see if they could potentially
1564
+ // generate exceptions or have side-effects.
1565
+ auto IsSafeOperation = [](Instruction *I) -> bool {
1566
+ // Is this a divide?
1567
+ switch (I->getOpcode ()) {
1568
+ case Instruction::Load:
1569
+ case Instruction::Store:
1570
+ case Instruction::PHI:
1571
+ case Instruction::Br:
1572
+ // These are checked separately. For example, canVectorizeMemory will
1573
+ // analyze the loads and stores in the loop.
1574
+ return true ;
1575
+ default :
1576
+ return isSafeToSpeculativelyExecute (I);
1577
+ }
1578
+ };
1579
+
1580
+ for (auto *BB : TheLoop->blocks ())
1581
+ for (auto &I : *BB)
1582
+ if (!IsSafeOperation (&I)) {
1583
+ reportVectorizationFailure (" Early exit loop contains operations that "
1584
+ " cannot be speculatively executed" ,
1585
+ " Early exit loop contains operations that "
1586
+ " cannot be speculatively executed" ,
1587
+ " UnsafeOperationsEarlyExitLoop" , ORE,
1588
+ TheLoop);
1589
+ return false ;
1590
+ }
1559
1591
1560
1592
LLVM_DEBUG (
1561
1593
dbgs ()
0 commit comments