1212// ===----------------------------------------------------------------------===//
1313
1414#include " llvm/Transforms/Scalar/InferAlignment.h"
15+ #include " llvm/ADT/STLFunctionalExtras.h"
1516#include " llvm/Analysis/AssumptionCache.h"
1617#include " llvm/Analysis/ValueTracking.h"
18+ #include " llvm/IR/Instruction.h"
1719#include " llvm/IR/Instructions.h"
1820#include " llvm/IR/IntrinsicInst.h"
21+ #include " llvm/IR/PatternMatch.h"
22+ #include " llvm/IR/Value.h"
23+ #include " llvm/Support/Alignment.h"
1924#include " llvm/Support/KnownBits.h"
2025#include " llvm/Transforms/Scalar.h"
2126#include " llvm/Transforms/Utils/Local.h"
2227
2328using namespace llvm ;
29+ using namespace llvm ::PatternMatch;
2430
2531static bool tryToImproveAlign (
2632 const DataLayout &DL, Instruction *I,
27- function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) {
33+ function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn,
34+ function_ref<Align(Instruction &I, Value *PtrOp)> ActualAlignFn) {
2835
2936 if (auto *PtrOp = getLoadStorePointerOperand (I)) {
3037 Align OldAlign = getLoadStoreAlignment (I);
@@ -37,6 +44,17 @@ static bool tryToImproveAlign(
3744 }
3845 }
3946
47+ Value *PtrOp;
48+ ConstantInt *Const;
49+ if (match (I,
50+ m_c_And (m_PtrToIntOrAddr (m_Value (PtrOp)), m_ConstantInt (Const)))) {
51+ Align ActualAlign = ActualAlignFn (*I, PtrOp);
52+ if (Const->getValue ().ult (ActualAlign.value ())) {
53+ I->replaceAllUsesWith (Constant::getNullValue (I->getType ()));
54+ return true ;
55+ }
56+ }
57+
4058 IntrinsicInst *II = dyn_cast<IntrinsicInst>(I);
4159 if (!II)
4260 return false ;
@@ -75,11 +93,15 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
7593 for (BasicBlock &BB : F) {
7694 for (Instruction &I : BB) {
7795 Changed |= tryToImproveAlign (
78- DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
96+ DL, &I,
97+ [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
7998 if (PrefAlign > OldAlign)
8099 return std::max (OldAlign,
81100 tryEnforceAlignment (PtrOp, PrefAlign, DL));
82101 return OldAlign;
102+ },
103+ [&](Instruction &, Value *PtrOp) {
104+ return PtrOp->getPointerAlignment (DL);
83105 });
84106 }
85107 }
@@ -120,6 +142,17 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
120142 return LoadStoreAlign;
121143 };
122144
145+ auto ActualAlginFn = [&](Instruction &I, Value *PtrOp) {
146+ Align KnownAlign = InferFromKnownBits (I, PtrOp);
147+ Align BaseAlign = PtrOp->getPointerAlignment (DL);
148+ if (auto It = BestBasePointerAligns.find (PtrOp);
149+ It != BestBasePointerAligns.end ()) {
150+ BaseAlign = std::max (BaseAlign, It->second );
151+ }
152+ Align ActualAlign = std::max (KnownAlign, BaseAlign);
153+ return ActualAlign;
154+ };
155+
123156 for (BasicBlock &BB : F) {
124157 // We need to reset the map for each block because alignment information
125158 // can only be propagated from instruction A to B if A dominates B.
@@ -131,10 +164,12 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
131164
132165 for (Instruction &I : BB) {
133166 Changed |= tryToImproveAlign (
134- DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
167+ DL, &I,
168+ [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
135169 return std::max (InferFromKnownBits (I, PtrOp),
136170 InferFromBasePointer (PtrOp, OldAlign));
137- });
171+ },
172+ ActualAlginFn);
138173 }
139174 }
140175
0 commit comments