@@ -345,7 +345,7 @@ class Vectorizer {
345
345
std::vector<Chain> gatherChains (ArrayRef<Instruction *> Instrs);
346
346
347
347
// / Propagates the best alignment in a chain of contiguous accesses
348
- void propagateBestAlignmentsInChain (ArrayRef<ChainElem> C) const ;
348
+ void propagateBestAlignmentInChain (ArrayRef<ChainElem> C) const ;
349
349
};
350
350
351
351
class LoadStoreVectorizerLegacyPass : public FunctionPass {
@@ -721,7 +721,7 @@ std::vector<Chain> Vectorizer::splitChainByAlignment(Chain &C) {
721
721
722
722
// We know that the accesses are contiguous. Propagate alignment
723
723
// information so that slices of the chain can still be vectorized.
724
- propagateBestAlignmentsInChain (C);
724
+ propagateBestAlignmentInChain (C);
725
725
LLVM_DEBUG ({
726
726
dbgs () << " LSV: Chain after alignment propagation:\n " ;
727
727
dumpChain (C);
@@ -1639,31 +1639,23 @@ std::optional<APInt> Vectorizer::getConstantOffset(Value *PtrA, Value *PtrB,
1639
1639
return std::nullopt;
1640
1640
}
1641
1641
1642
- void Vectorizer::propagateBestAlignmentsInChain (ArrayRef<ChainElem> C) const {
1643
- auto PropagateAlignments = [](auto ChainIt) {
1644
- ChainElem BestAlignedElem = *ChainIt.begin ();
1645
- Align BestAlignSoFar = getLoadStoreAlignment (BestAlignedElem.Inst );
1646
-
1647
- for (const ChainElem &E : ChainIt) {
1648
- Align OrigAlign = getLoadStoreAlignment (E.Inst );
1649
- if (OrigAlign > BestAlignSoFar) {
1650
- BestAlignedElem = E;
1651
- BestAlignSoFar = OrigAlign;
1652
- continue ;
1653
- }
1654
-
1655
- APInt DeltaFromBestAlignedElem =
1656
- APIntOps::abdu (E.OffsetFromLeader , BestAlignedElem.OffsetFromLeader );
1657
- // commonAlignment is equivalent to a greatest common power-of-two
1658
- // divisor; it returns the largest power of 2 that divides both A and B.
1659
- Align NewAlign = commonAlignment (
1660
- BestAlignSoFar, DeltaFromBestAlignedElem.getLimitedValue ());
1661
- if (NewAlign > OrigAlign)
1662
- setLoadStoreAlignment (E.Inst , NewAlign);
1642
+ void Vectorizer::propagateBestAlignmentInChain (ArrayRef<ChainElem> C) const {
1643
+ // Find the element in the chain with the best alignment and its offset.
1644
+ Align BestAlign = getLoadStoreAlignment (C[0 ].Inst );
1645
+ APInt BestAlignOffset = C[0 ].OffsetFromLeader ;
1646
+ for (const ChainElem &Elem : C) {
1647
+ Align ElemAlign = getLoadStoreAlignment (Elem.Inst );
1648
+ if (ElemAlign > BestAlign) {
1649
+ BestAlign = ElemAlign;
1650
+ BestAlignOffset = Elem.OffsetFromLeader ;
1663
1651
}
1664
- };
1652
+ }
1665
1653
1666
- // Propagate forwards and backwards.
1667
- PropagateAlignments (C);
1668
- PropagateAlignments (reverse (C));
1654
+ // Propagate the best alignment to other elements in the chain, if possible.
1655
+ for (const ChainElem &Elem : C) {
1656
+ APInt OffsetDelta = APIntOps::abdu (Elem.OffsetFromLeader , BestAlignOffset);
1657
+ Align NewAlign = commonAlignment (BestAlign, OffsetDelta.getLimitedValue ());
1658
+ if (NewAlign > getLoadStoreAlignment (Elem.Inst ))
1659
+ setLoadStoreAlignment (Elem.Inst , NewAlign);
1660
+ }
1669
1661
}
0 commit comments