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,16 @@ static bool tryToImproveAlign(
3744 }
3845 }
3946
47+ Value *PtrOp;
48+ ConstantInt *Const;
49+ if (match (I, m_c_And (m_PtrToIntOrAddr (m_Value (PtrOp)), m_ConstantInt (Const)))) {
50+ Align ActualAlign = ActualAlignFn (*I, PtrOp);
51+ if (Const->getValue ().ult (ActualAlign.value ())) {
52+ I->replaceAllUsesWith (Constant::getNullValue (I->getType ()));
53+ return true ;
54+ }
55+ }
56+
4057 IntrinsicInst *II = dyn_cast<IntrinsicInst>(I);
4158 if (!II)
4259 return false ;
@@ -80,6 +97,8 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
8097 return std::max (OldAlign,
8198 tryEnforceAlignment (PtrOp, PrefAlign, DL));
8299 return OldAlign;
100+ }, [&](Instruction&, Value *PtrOp) {
101+ return PtrOp->getPointerAlignment (DL);
83102 });
84103 }
85104 }
@@ -120,6 +139,17 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
120139 return LoadStoreAlign;
121140 };
122141
142+ auto ActualAlginFn = [&](Instruction &I, Value *PtrOp) {
143+ Align KnownAlign = InferFromKnownBits (I, PtrOp);
144+ Align BaseAlign = PtrOp->getPointerAlignment (DL);
145+ if (auto It = BestBasePointerAligns.find (PtrOp);
146+ It != BestBasePointerAligns.end ()) {
147+ BaseAlign = std::max (BaseAlign, It->second );
148+ }
149+ Align ActualAlign = std::max (KnownAlign, BaseAlign);
150+ return ActualAlign;
151+ };
152+
123153 for (BasicBlock &BB : F) {
124154 // We need to reset the map for each block because alignment information
125155 // can only be propagated from instruction A to B if A dominates B.
@@ -134,7 +164,7 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
134164 DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
135165 return std::max (InferFromKnownBits (I, PtrOp),
136166 InferFromBasePointer (PtrOp, OldAlign));
137- });
167+ }, ActualAlginFn );
138168 }
139169 }
140170
0 commit comments