@@ -57,53 +57,57 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
5757 }
5858 }
5959
60+ // Compute alignment from known bits.
61+ auto InferFromKnownBits = [&](Instruction &I, Value *PtrOp) {
62+ KnownBits Known = computeKnownBits (PtrOp, DL, &AC, &I, &DT);
63+ unsigned TrailZ =
64+ std::min (Known.countMinTrailingZeros (), +Value::MaxAlignmentExponent);
65+ return Align (1ull << std::min (Known.getBitWidth () - 1 , TrailZ));
66+ };
67+
68+ // Propagate alignment between loads and stores that originate from the
69+ // same base pointer.
70+ DenseMap<Value *, Align> BestBasePointerAligns;
71+ auto InferFromBasePointer = [&](Value *PtrOp, Align LoadStoreAlign) {
72+ APInt OffsetFromBase =
73+ APInt (DL.getIndexTypeSizeInBits (PtrOp->getType ()), 0 );
74+ PtrOp = PtrOp->stripAndAccumulateConstantOffsets (DL, OffsetFromBase, true );
75+ // Derive the base pointer alignment from the load/store alignment
76+ // and the offset from the base pointer.
77+ Align BasePointerAlign =
78+ commonAlignment (LoadStoreAlign, OffsetFromBase.getLimitedValue ());
79+
80+ auto [It, Inserted] =
81+ BestBasePointerAligns.try_emplace (PtrOp, BasePointerAlign);
82+ if (!Inserted) {
83+ // If the stored base pointer alignment is better than the
84+ // base pointer alignment we derived, we may be able to use it
85+ // to improve the load/store alignment. If not, store the
86+ // improved base pointer alignment for future iterations.
87+ if (It->second > BasePointerAlign) {
88+ Align BetterLoadStoreAlign =
89+ commonAlignment (It->second , OffsetFromBase.getLimitedValue ());
90+ return BetterLoadStoreAlign;
91+ }
92+ It->second = BasePointerAlign;
93+ }
94+ return LoadStoreAlign;
95+ };
96+
6097 for (BasicBlock &BB : F) {
6198 // We need to reset the map for each block because alignment information
6299 // can't be propagated across blocks. This is because control flow could
63100 // be dependent on the address at runtime, making an alignment assumption
64101 // within one block not true in another. Some sort of dominator tree
65102 // approach could be better, but restricting within a basic block is correct
66103 // too.
67- DenseMap<Value *, Align> BestBasePointerAligns;
104+ BestBasePointerAligns. clear () ;
68105
69106 for (Instruction &I : BB) {
70- // Compute alignment from known bits.
71107 Changed |= tryToImproveAlign (
72108 DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
73- KnownBits Known = computeKnownBits (PtrOp, DL, &AC, &I, &DT);
74- unsigned TrailZ = std::min (Known.countMinTrailingZeros (),
75- +Value::MaxAlignmentExponent);
76- return Align (1ull << std::min (Known.getBitWidth () - 1 , TrailZ));
77- });
78-
79- // Propagate alignment between loads and stores that originate from the
80- // same base pointer.
81- Changed |= tryToImproveAlign (
82- DL, &I, [&](Value *PtrOp, Align LoadStoreAlign, Align PrefAlign) {
83- APInt OffsetFromBase =
84- APInt (DL.getIndexTypeSizeInBits (PtrOp->getType ()), 0 );
85- PtrOp = PtrOp->stripAndAccumulateConstantOffsets (DL, OffsetFromBase,
86- true );
87- // Derive the base pointer alignment from the load/store alignment
88- // and the offset from the base pointer.
89- Align BasePointerAlign = commonAlignment (
90- LoadStoreAlign, OffsetFromBase.getLimitedValue ());
91-
92- auto [It, Inserted] =
93- BestBasePointerAligns.try_emplace (PtrOp, BasePointerAlign);
94- if (!Inserted) {
95- // If the stored base pointer alignment is better than the
96- // base pointer alignment we derived, we may be able to use it
97- // to improve the load/store alignment. If not, store the
98- // improved base pointer alignment for future iterations.
99- if (It->second > BasePointerAlign) {
100- Align BetterLoadStoreAlign = commonAlignment (
101- It->second , OffsetFromBase.getLimitedValue ());
102- return BetterLoadStoreAlign;
103- }
104- It->second = BasePointerAlign;
105- }
106- return LoadStoreAlign;
109+ return std::max (InferFromKnownBits (I, PtrOp),
110+ InferFromBasePointer (PtrOp, OldAlign));
107111 });
108112 }
109113 }
0 commit comments