1212// ===----------------------------------------------------------------------===//
1313
1414#include " llvm/Transforms/Scalar/InferAlignment.h"
15+ #include " llvm/ADT/APInt.h"
16+ #include " llvm/ADT/STLFunctionalExtras.h"
1517#include " llvm/Analysis/AssumptionCache.h"
1618#include " llvm/Analysis/ValueTracking.h"
19+ #include " llvm/IR/Instruction.h"
1720#include " llvm/IR/Instructions.h"
1821#include " llvm/IR/IntrinsicInst.h"
22+ #include " llvm/IR/PatternMatch.h"
1923#include " llvm/Support/KnownBits.h"
2024#include " llvm/Transforms/Scalar.h"
2125#include " llvm/Transforms/Utils/Local.h"
2226
2327using namespace llvm ;
28+ using namespace llvm ::PatternMatch;
2429
2530static bool tryToImproveAlign (
2631 const DataLayout &DL, Instruction *I,
27- function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) {
32+ function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn,
33+ function_ref<Align(Value *PtrOp)> ActualAlignFn) {
2834
2935 if (auto *PtrOp = getLoadStorePointerOperand (I)) {
3036 Align OldAlign = getLoadStoreAlignment (I);
@@ -37,6 +43,16 @@ static bool tryToImproveAlign(
3743 }
3844 }
3945
46+ Value *PtrOp;
47+ const APInt *Const;
48+ if (match (I, m_And (m_PtrToIntOrAddr (m_Value (PtrOp)), m_APInt (Const)))) {
49+ Align ActualAlign = ActualAlignFn (PtrOp);
50+ if (Const->ult (ActualAlign.value ())) {
51+ I->replaceAllUsesWith (Constant::getNullValue (I->getType ()));
52+ return true ;
53+ }
54+ }
55+
4056 IntrinsicInst *II = dyn_cast<IntrinsicInst>(I);
4157 if (!II)
4258 return false ;
@@ -75,12 +91,14 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
7591 for (BasicBlock &BB : F) {
7692 for (Instruction &I : BB) {
7793 Changed |= tryToImproveAlign (
78- DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
94+ DL, &I,
95+ [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
7996 if (PrefAlign > OldAlign)
8097 return std::max (OldAlign,
8198 tryEnforceAlignment (PtrOp, PrefAlign, DL));
8299 return OldAlign;
83- });
100+ },
101+ [&](Value *PtrOp) { return PtrOp->getPointerAlignment (DL); });
84102 }
85103 }
86104
@@ -120,6 +138,15 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
120138 return LoadStoreAlign;
121139 };
122140
141+ auto ActualAlginFn = [&](Value *PtrOp) {
142+ Align BaseAlign = PtrOp->getPointerAlignment (DL);
143+ if (auto It = BestBasePointerAligns.find (PtrOp);
144+ It != BestBasePointerAligns.end ()) {
145+ BaseAlign = std::max (BaseAlign, It->second );
146+ }
147+ return BaseAlign;
148+ };
149+
123150 for (BasicBlock &BB : F) {
124151 // We need to reset the map for each block because alignment information
125152 // can only be propagated from instruction A to B if A dominates B.
@@ -131,10 +158,12 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
131158
132159 for (Instruction &I : BB) {
133160 Changed |= tryToImproveAlign (
134- DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
161+ DL, &I,
162+ [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
135163 return std::max (InferFromKnownBits (I, PtrOp),
136164 InferFromBasePointer (PtrOp, OldAlign));
137- });
165+ },
166+ ActualAlginFn);
138167 }
139168 }
140169
0 commit comments