15
15
//
16
16
17
17
#include " llvm/Transforms/Vectorize/LoopVectorizationLegality.h"
18
+ #include " llvm/Analysis/AliasAnalysis.h"
18
19
#include " llvm/Analysis/Loads.h"
19
20
#include " llvm/Analysis/LoopInfo.h"
21
+ #include " llvm/Analysis/MustExecute.h"
20
22
#include " llvm/Analysis/OptimizationRemarkEmitter.h"
21
23
#include " llvm/Analysis/ScalarEvolutionExpressions.h"
22
24
#include " llvm/Analysis/TargetLibraryInfo.h"
@@ -1223,8 +1225,18 @@ bool LoopVectorizationLegality::canVectorizeMemory() {
1223
1225
});
1224
1226
}
1225
1227
1226
- if (!LAI->canVectorizeMemory ())
1228
+ if (!LAI->canVectorizeMemory ()) {
1229
+ if (hasUncountableExitWithSideEffects ()) {
1230
+ reportVectorizationFailure (
1231
+ " Cannot vectorize unsafe dependencies in uncountable exit loop with "
1232
+ " side effects" ,
1233
+ " CantVectorizeUnsafeDependencyForEELoopWithSideEffects" , ORE,
1234
+ TheLoop);
1235
+ return false ;
1236
+ }
1237
+
1227
1238
return canVectorizeIndirectUnsafeDependences ();
1239
+ }
1228
1240
1229
1241
if (LAI->hasLoadStoreDependenceInvolvingLoopInvariantAddress ()) {
1230
1242
reportVectorizationFailure (" We don't allow storing to uniform addresses" ,
@@ -1755,16 +1767,24 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1755
1767
}
1756
1768
};
1757
1769
1770
+ bool HasSideEffects = false ;
1758
1771
for (auto *BB : TheLoop->blocks ())
1759
1772
for (auto &I : *BB) {
1760
1773
if (I.mayWriteToMemory ()) {
1761
- // We don't support writes to memory.
1774
+ if (isa<StoreInst>(&I) && cast<StoreInst>(&I)->isSimple ()) {
1775
+ HasSideEffects = true ;
1776
+ continue ;
1777
+ }
1778
+
1779
+ // We don't support complex writes to memory.
1762
1780
reportVectorizationFailure (
1763
- " Writes to memory unsupported in early exit loops" ,
1764
- " Cannot vectorize early exit loop with writes to memory" ,
1781
+ " Complex writes to memory unsupported in early exit loops" ,
1782
+ " Cannot vectorize early exit loop with complex writes to memory" ,
1765
1783
" WritesInEarlyExitLoop" , ORE, TheLoop);
1766
1784
return false ;
1767
- } else if (!IsSafeOperation (&I)) {
1785
+ }
1786
+
1787
+ if (!IsSafeOperation (&I)) {
1768
1788
reportVectorizationFailure (" Early exit loop contains operations that "
1769
1789
" cannot be speculatively executed" ,
1770
1790
" UnsafeOperationsEarlyExitLoop" , ORE,
@@ -1777,15 +1797,22 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1777
1797
assert (LatchBB->getUniquePredecessor () == SingleUncountableExitingBlock &&
1778
1798
" Expected latch predecessor to be the early exiting block" );
1779
1799
1780
- Predicates.clear ();
1781
1800
SmallVector<LoadInst *, 4 > NonDerefLoads;
1782
- if (!isReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC, NonDerefLoads,
1783
- &Predicates)) {
1784
- reportVectorizationFailure (" Loop may fault" ,
1785
- " Cannot vectorize non-read-only early exit loop" ,
1786
- " NonReadOnlyEarlyExitLoop" , ORE, TheLoop);
1801
+ // TODO: Handle loops that may fault.
1802
+ if (!HasSideEffects) {
1803
+ // Read-only loop.
1804
+ Predicates.clear ();
1805
+ if (!isReadOnlyLoop (TheLoop, PSE.getSE (), DT, AC, NonDerefLoads,
1806
+ &Predicates)) {
1807
+ reportVectorizationFailure (
1808
+ " Loop may fault" , " Cannot vectorize non-read-only early exit loop" ,
1809
+ " NonReadOnlyEarlyExitLoop" , ORE, TheLoop);
1810
+ return false ;
1811
+ }
1812
+ } else if (!canUncountableExitConditionLoadBeMoved (
1813
+ SingleUncountableExitingBlock))
1787
1814
return false ;
1788
- }
1815
+
1789
1816
// Check non-dereferenceable loads if any.
1790
1817
for (LoadInst *LI : NonDerefLoads) {
1791
1818
// Only support unit-stride access for now.
@@ -1813,6 +1840,99 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
1813
1840
" backedge taken count: "
1814
1841
<< *SymbolicMaxBTC << ' \n ' );
1815
1842
UncountableExitingBB = SingleUncountableExitingBlock;
1843
+ UncountableExitWithSideEffects = HasSideEffects;
1844
+ return true ;
1845
+ }
1846
+
1847
+ bool LoopVectorizationLegality::canUncountableExitConditionLoadBeMoved (
1848
+ BasicBlock *ExitingBlock) {
1849
+ // Try to find a load in the critical path for the uncountable exit condition.
1850
+ // This is currently matching about the simplest form we can, expecting
1851
+ // only one in-loop load, the result of which is directly compared against
1852
+ // a loop-invariant value.
1853
+ // FIXME: We're insisting on a single use for now, because otherwise we will
1854
+ // need to make PHI nodes for other users. That can be done once the initial
1855
+ // transform code lands.
1856
+ auto *Br = cast<BranchInst>(ExitingBlock->getTerminator ());
1857
+
1858
+ using namespace llvm ::PatternMatch;
1859
+ Instruction *L = nullptr ;
1860
+ Value *Ptr = nullptr ;
1861
+ Value *R = nullptr ;
1862
+ if (!match (Br->getCondition (),
1863
+ m_OneUse (m_ICmp (m_OneUse (m_Instruction (L, m_Load (m_Value (Ptr)))),
1864
+ m_Value (R))))) {
1865
+ reportVectorizationFailure (
1866
+ " Early exit loop with store but no supported condition load" ,
1867
+ " NoConditionLoadForEarlyExitLoop" , ORE, TheLoop);
1868
+ return false ;
1869
+ }
1870
+
1871
+ // FIXME: Don't rely on operand ordering for the comparison.
1872
+ if (!TheLoop->isLoopInvariant (R)) {
1873
+ reportVectorizationFailure (
1874
+ " Early exit loop with store but no supported condition load" ,
1875
+ " NoConditionLoadForEarlyExitLoop" , ORE, TheLoop);
1876
+ return false ;
1877
+ }
1878
+
1879
+ // Make sure that the load address is not loop invariant; we want an
1880
+ // address calculation that we can rotate to the next vector iteration.
1881
+ const SCEV *PtrScev = PSE.getSE ()->getSCEV (Ptr);
1882
+ if (!isa<SCEVAddRecExpr>(PtrScev)) {
1883
+ reportVectorizationFailure (
1884
+ " Uncountable exit condition depends on load with an address that is "
1885
+ " not an add recurrence" ,
1886
+ " EarlyExitLoadInvariantAddress" , ORE, TheLoop);
1887
+ return false ;
1888
+ }
1889
+
1890
+ // FIXME: Support gathers after first-faulting load support lands.
1891
+ SmallVector<const SCEVPredicate *, 4 > Predicates;
1892
+ LoadInst *Load = cast<LoadInst>(L);
1893
+ if (!isDereferenceableAndAlignedInLoop (Load, TheLoop, *PSE.getSE (), *DT, AC,
1894
+ &Predicates)) {
1895
+ reportVectorizationFailure (
1896
+ " Loop may fault" ,
1897
+ " Cannot vectorize potentially faulting early exit loop" ,
1898
+ " PotentiallyFaultingEarlyExitLoop" , ORE, TheLoop);
1899
+ return false ;
1900
+ }
1901
+
1902
+ ICFLoopSafetyInfo SafetyInfo;
1903
+ SafetyInfo.computeLoopSafetyInfo (TheLoop);
1904
+ // We need to know that load will be executed before we can hoist a
1905
+ // copy out to run just before the first iteration.
1906
+ // FIXME: Currently, other restrictions prevent us from reaching this point
1907
+ // with a loop where the uncountable exit condition is determined
1908
+ // by a conditional load.
1909
+ assert (SafetyInfo.isGuaranteedToExecute (*Load, DT, TheLoop) &&
1910
+ " Unhandled control flow in uncountable exit loop with side effects" );
1911
+
1912
+ // Prohibit any potential aliasing with any instruction in the loop which
1913
+ // might store to memory.
1914
+ // FIXME: Relax this constraint where possible.
1915
+ for (auto *BB : TheLoop->blocks ()) {
1916
+ for (auto &I : *BB) {
1917
+ if (&I == Load)
1918
+ continue ;
1919
+
1920
+ if (I.mayWriteToMemory ()) {
1921
+ if (auto *SI = dyn_cast<StoreInst>(&I)) {
1922
+ AliasResult AR = AA->alias (Ptr, SI->getPointerOperand ());
1923
+ if (AR == AliasResult::NoAlias)
1924
+ continue ;
1925
+ }
1926
+
1927
+ reportVectorizationFailure (
1928
+ " Cannot determine whether critical uncountable exit load address "
1929
+ " does not alias with a memory write" ,
1930
+ " CantVectorizeAliasWithCriticalUncountableExitLoad" , ORE, TheLoop);
1931
+ return false ;
1932
+ }
1933
+ }
1934
+ }
1935
+
1816
1936
return true ;
1817
1937
}
1818
1938
@@ -1885,6 +2005,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
1885
2005
} else {
1886
2006
if (!isVectorizableEarlyExitLoop ()) {
1887
2007
assert (!hasUncountableEarlyExit () &&
2008
+ !hasUncountableExitWithSideEffects () &&
1888
2009
" Must be false without vectorizable early-exit loop" );
1889
2010
if (DoExtraAnalysis)
1890
2011
Result = false ;
@@ -1903,6 +2024,15 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
1903
2024
return false ;
1904
2025
}
1905
2026
2027
+ // Bail out for state-changing loops with uncountable exits for now.
2028
+ if (UncountableExitWithSideEffects) {
2029
+ reportVectorizationFailure (
2030
+ " Writes to memory unsupported in early exit loops" ,
2031
+ " Cannot vectorize early exit loop with writes to memory" ,
2032
+ " WritesInEarlyExitLoop" , ORE, TheLoop);
2033
+ return false ;
2034
+ }
2035
+
1906
2036
if (Result) {
1907
2037
LLVM_DEBUG (dbgs () << " LV: We can vectorize this loop"
1908
2038
<< (LAI->getRuntimePointerChecking ()->Need
0 commit comments