@@ -345,7 +345,7 @@ class Vectorizer {
345345 std::vector<Chain> gatherChains (ArrayRef<Instruction *> Instrs);
346346
347347 // / Propagates the best alignment in a chain of contiguous accesses
348- void propagateBestAlignmentsInChain (ArrayRef<ChainElem> C) const ;
348+ void propagateBestAlignmentInChain (ArrayRef<ChainElem> C) const ;
349349};
350350
351351class LoadStoreVectorizerLegacyPass : public FunctionPass {
@@ -721,7 +721,7 @@ std::vector<Chain> Vectorizer::splitChainByAlignment(Chain &C) {
721721
722722 // We know that the accesses are contiguous. Propagate alignment
723723 // information so that slices of the chain can still be vectorized.
724- propagateBestAlignmentsInChain (C);
724+ propagateBestAlignmentInChain (C);
725725 LLVM_DEBUG ({
726726 dbgs () << " LSV: Chain after alignment propagation:\n " ;
727727 dumpChain (C);
@@ -1639,31 +1639,23 @@ std::optional<APInt> Vectorizer::getConstantOffset(Value *PtrA, Value *PtrB,
16391639 return std::nullopt ;
16401640}
16411641
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 ;
16631651 }
1664- };
1652+ }
16651653
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+ }
16691661}
0 commit comments