1212// ===----------------------------------------------------------------------===//
1313
1414#include " llvm/Transforms/Scalar/InferAlignment.h"
15+ #include " llvm/ADT/DenseMap.h"
1516#include " llvm/Analysis/AssumptionCache.h"
1617#include " llvm/Analysis/ValueTracking.h"
1718#include " llvm/IR/Instructions.h"
2223
2324using namespace llvm ;
2425
26+ DenseMap<Value *, Value *> ValueToBasePtr;
27+
2528static bool tryToImproveAlign (
2629 const DataLayout &DL, Instruction *I,
2730 function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) {
@@ -36,10 +39,31 @@ static bool tryToImproveAlign(
3639 return true ;
3740 }
3841 }
42+
3943 // TODO: Also handle memory intrinsics.
4044 return false ;
4145}
4246
47+ static bool needEnforceAlignment (Value *PtrOp, Instruction *I, Align PrefAlign,
48+ const DataLayout &DL) {
49+ auto it = ValueToBasePtr.find (PtrOp);
50+ if (it != ValueToBasePtr.end ()) {
51+ Value *V = it->second ;
52+ Align CurrentAlign;
53+ if (auto Alloca = dyn_cast<AllocaInst>(V))
54+ CurrentAlign = Alloca->getAlign ();
55+ if (auto GO = dyn_cast<GlobalObject>(V))
56+ CurrentAlign = GO->getPointerAlignment (DL);
57+
58+ if (PrefAlign <= CurrentAlign) {
59+ setLoadStoreAlignment (I, CurrentAlign);
60+ return false ;
61+ }
62+ }
63+
64+ return true ;
65+ }
66+
4367bool inferAlignment (Function &F, AssumptionCache &AC, DominatorTree &DT) {
4468 const DataLayout &DL = F.getDataLayout ();
4569 bool Changed = false ;
@@ -50,9 +74,15 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
5074 for (Instruction &I : BB) {
5175 Changed |= tryToImproveAlign (
5276 DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
53- if (PrefAlign > OldAlign)
54- return std::max (OldAlign,
55- tryEnforceAlignment (PtrOp, PrefAlign, DL));
77+ if (needEnforceAlignment (PtrOp, &I, PrefAlign, DL) &&
78+ PrefAlign > OldAlign) {
79+ Align NewAlign = tryEnforceAlignment (PtrOp, PrefAlign, DL);
80+ if (NewAlign > OldAlign) {
81+ ValueToBasePtr[PtrOp] = PtrOp->stripPointerCasts ();
82+ return NewAlign;
83+ }
84+ }
85+
5686 return OldAlign;
5787 });
5888 }
0 commit comments