llvm.org GIT mirror llvm / 16fd27b
Add scoped-noalias metadata This commit adds scoped noalias metadata. The primary motivations for this feature are: 1. To preserve noalias function attribute information when inlining 2. To provide the ability to model block-scope C99 restrict pointers Neither of these two abilities are added here, only the necessary infrastructure. In fact, there should be no change to existing functionality, only the addition of new features. The logic that converts noalias function parameters into this metadata during inlining will come in a follow-up commit. What is added here is the ability to generally specify noalias memory-access sets. Regarding the metadata, alias-analysis scopes are defined similar to TBAA nodes: !scope0 = metadata !{ metadata !"scope of foo()" } !scope1 = metadata !{ metadata !"scope 1", metadata !scope0 } !scope2 = metadata !{ metadata !"scope 2", metadata !scope0 } !scope3 = metadata !{ metadata !"scope 2.1", metadata !scope2 } !scope4 = metadata !{ metadata !"scope 2.2", metadata !scope2 } Loads and stores can be tagged with an alias-analysis scope, and also, with a noalias tag for a specific scope: ... = load %ptr1, !alias.scope !{ !scope1 } ... = load %ptr2, !alias.scope !{ !scope1, !scope2 }, !noalias !{ !scope1 } When evaluating an aliasing query, if one of the instructions is associated with an alias.scope id that is identical to the noalias scope associated with the other instruction, or is a descendant (in the scope hierarchy) of the noalias scope associated with the other instruction, then the two memory accesses are assumed not to alias. Note that is the first element of the scope metadata is a string, then it can be combined accross functions and translation units. The string can be replaced by a self-reference to create globally unqiue scope identifiers. [Note: This overview is slightly stylized, since the metadata nodes really need to just be numbers (!0 instead of !scope0), and the scope lists are also global unnamed metadata.] Existing noalias metadata in a callee is "cloned" for use by the inlined code. This is necessary because the aliasing scopes are unique to each call site (because of possible control dependencies on the aliasing properties). For example, consider a function: foo(noalias a, noalias b) { *a = *b; } that gets inlined into bar() { ... if (...) foo(a1, b1); ... if (...) foo(a2, b2); } -- now just because we know that a1 does not alias with b1 at the first call site, and a2 does not alias with b2 at the second call site, we cannot let inlining these functons have the metadata imply that a1 does not alias with b2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213864 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 6 years ago
31 changed file(s) with 836 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
28282828 4 byte gap between the two fields. This gap represents padding which
28292829 does not carry useful data and need not be preserved.
28302830
2831 '``noalias``' and '``alias.scope``' Metadata
2832 ^^^^^^^^^^^^^^^^^^^^^^^^^^
2833
2834 ``noalias`` and ``alias.scope`` metadata provide the ability to specify generic
2835 noalias memory-access sets. This means that some collection of memory access
2836 instructions (loads, stores, memory-accessing calls, etc.) that carry
2837 ``noalias`` metadata can specifically be specified not to alias with some other
2838 collection of memory access instructions that carry ``alias.scope`` metadata.
2839 Each type of metadata specifies a list of scopes, and when evaluating an
2840 aliasing query, if one of the instructions has a scope in its ``alias.scope``
2841 list that is identical to a scope in the other instruction's ``noalias`` list,
2842 or is a descendant (in the scope hierarchy) of a scope in the other
2843 instruction's ``noalias`` list , then the two memory accesses are assumed not
2844 to alias.
2845
2846 The metadata identifying each scope is itself a list containing one or two
2847 entries. The first entry is the name of the scope. Note that if the name is a
2848 string then it can be combined accross functions and translation units. A
2849 self-reference can be used to create globally unique scope names.
2850 Optionally, a metadata reference to a parent scope can be provided as a second
2851 entry in the list.
2852
2853 For example,
2854
2855 .. code-block:: llvm
2856
2857 ; A root scope (which doubles as a list of itself):
2858 !0 = metadata !{metadata !0}
2859
2860 ; Two child scopes (which must be self-referential to avoid being "uniqued"):
2861 !1 = metadata !{metadata !2} ; A list containing only scope !2
2862 !2 = metadata !{metadata !2, metadata !0} ; Scope !2 is a descendant of scope !0
2863
2864 !3 = metadata !{metadata !4} ; A list containing only scope !4
2865 !4 = metadata !{metadata !4, metadata !0} ; Scope !4 is a descendant of scope !0
2866
2867 ; These two instructions don't alias:
2868 %0 = load float* %c, align 4, !alias.scope !0
2869 store float %0, float* %arrayidx.i, align 4, !noalias !0
2870
2871 ; These two instructions may alias (scope !2 and scope !4 are peers):
2872 %2 = load float* %c, align 4, !alias.scope !1
2873 store float %2, float* %arrayidx.i2, align 4, !noalias !3
2874
2875 ; These two instructions don't alias (scope !2 is a descendant of scope !0
2876 ; and the store does not alias with anything in scope !0 or any of its descendants):
2877 %2 = load float* %c, align 4, !alias.scope !1
2878 store float %0, float* %arrayidx.i, align 4, !noalias !0
2879
2880 ; These two instructions may alias:
2881 %2 = load float* %c, align 4, !alias.scope !0
2882 store float %0, float* %arrayidx.i, align 4, !noalias !1
2883
28312884 '``fpmath``' Metadata
28322885 ^^^^^^^^^^^^^^^^^^^^^
28332886
8787
8888 //===--------------------------------------------------------------------===//
8989 //
90 // createScopedNoAliasAAPass - This pass implements metadata-based
91 // scoped noalias analysis.
92 //
93 ImmutablePass *createScopedNoAliasAAPass();
94
95 //===--------------------------------------------------------------------===//
96 //
9097 // createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based
9198 // alias analysis.
9299 //
363363 /// \brief Create and insert a memset to the specified pointer and the
364364 /// specified value.
365365 ///
366 /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is
367 /// specified, it will be added to the instruction.
366 /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is
367 /// specified, it will be added to the instruction. Likewise with alias.scope
368 /// and noalias tags.
368369 CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
369 bool isVolatile = false, MDNode *TBAATag = nullptr) {
370 return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
370 bool isVolatile = false, MDNode *TBAATag = nullptr,
371 MDNode *ScopeTag = nullptr,
372 MDNode *NoAliasTag = nullptr) {
373 return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile,
374 TBAATag, ScopeTag, NoAliasTag);
371375 }
372376
373377 CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
374 bool isVolatile = false, MDNode *TBAATag = nullptr);
378 bool isVolatile = false, MDNode *TBAATag = nullptr,
379 MDNode *ScopeTag = nullptr,
380 MDNode *NoAliasTag = nullptr);
375381
376382 /// \brief Create and insert a memcpy between the specified pointers.
377383 ///
378384 /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
379 /// specified, it will be added to the instruction.
385 /// specified, it will be added to the instruction. Likewise with alias.scope
386 /// and noalias tags.
380387 CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
381388 bool isVolatile = false, MDNode *TBAATag = nullptr,
382 MDNode *TBAAStructTag = nullptr) {
389 MDNode *TBAAStructTag = nullptr,
390 MDNode *ScopeTag = nullptr,
391 MDNode *NoAliasTag = nullptr) {
383392 return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,
384 TBAAStructTag);
393 TBAAStructTag, ScopeTag, NoAliasTag);
385394 }
386395
387396 CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
388397 bool isVolatile = false, MDNode *TBAATag = nullptr,
389 MDNode *TBAAStructTag = nullptr);
398 MDNode *TBAAStructTag = nullptr,
399 MDNode *ScopeTag = nullptr,
400 MDNode *NoAliasTag = nullptr);
390401
391402 /// \brief Create and insert a memmove between the specified
392403 /// pointers.
393404 ///
394405 /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
395 /// specified, it will be added to the instruction.
406 /// specified, it will be added to the instruction. Likewise with alias.scope
407 /// and noalias tags.
396408 CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
397 bool isVolatile = false, MDNode *TBAATag = nullptr) {
398 return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
409 bool isVolatile = false, MDNode *TBAATag = nullptr,
410 MDNode *ScopeTag = nullptr,
411 MDNode *NoAliasTag = nullptr) {
412 return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile,
413 TBAATag, ScopeTag, NoAliasTag);
399414 }
400415
401416 CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
402 bool isVolatile = false, MDNode *TBAATag = nullptr);
417 bool isVolatile = false, MDNode *TBAATag = nullptr,
418 MDNode *ScopeTag = nullptr,
419 MDNode *NoAliasTag = nullptr);
403420
404421 /// \brief Create a lifetime.start intrinsic.
405422 ///
5151 MD_fpmath = 3, // "fpmath"
5252 MD_range = 4, // "range"
5353 MD_tbaa_struct = 5, // "tbaa.struct"
54 MD_invariant_load = 6 // "invariant.load"
54 MD_invariant_load = 6, // "invariant.load"
55 MD_alias_scope = 7, // "alias.scope"
56 MD_noalias = 8 // "noalias"
5557 };
5658
5759 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
6262 MDNode *createRange(const APInt &Lo, const APInt &Hi);
6363
6464 //===------------------------------------------------------------------===//
65 // TBAA metadata.
65 // AA metadata.
6666 //===------------------------------------------------------------------===//
6767
68 /// \brief Return metadata appropriate for a TBAA root node. Each returned
68 protected:
69 /// \brief Return metadata appropriate for a AA root node (scope or TBAA).
70 /// Each returned node is distinct from all other metadata and will never
71 /// be identified (uniqued) with anything else.
72 MDNode *createAnonymousAARoot(StringRef Name = StringRef());
73
74 public:
75 /// \brief Return metadata appropriate for a TBAA root node. Each returned
6976 /// node is distinct from all other metadata and will never be identified
7077 /// (uniqued) with anything else.
71 MDNode *createAnonymousTBAARoot();
78 MDNode *createAnonymousTBAARoot() {
79 return createAnonymousAARoot();
80 }
81
82 /// \brief Return metadata appropriate for an alias scope root node.
83 /// Each returned node is distinct from all other metadata and will never
84 /// be identified (uniqued) with anything else.
85 MDNode *createAnonymousAliasScopeRoot(StringRef Name = StringRef()) {
86 return createAnonymousAARoot(Name);
87 }
7288
7389 /// \brief Return metadata appropriate for a TBAA root node with the given
7490 /// name. This may be identified (uniqued) with other roots with the same
7591 /// name.
7692 MDNode *createTBAARoot(StringRef Name);
7793
94 /// \brief Return metadata appropriate for an alias scope root node with
95 /// the given name. This may be identified (uniqued) with other roots with
96 /// the same name.
97 MDNode *createAliasScopeRoot(StringRef Name);
98
7899 /// \brief Return metadata for a non-root TBAA node with the given name,
79100 /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
80101 MDNode *createTBAANode(StringRef Name, MDNode *Parent,
81102 bool isConstant = false);
103
104 /// \brief Return metadata for a non-root alias scope node with the given
105 /// name and parent in the scope tree.
106 MDNode *createAliasScopeNode(StringRef Name, MDNode *Parent);
82107
83108 struct TBAAStructField {
84109 uint64_t Offset;
6969 /// AAMDNodes - A collection of metadata nodes that might be associated with a
7070 /// memory access used by the alias-analysis infrastructure.
7171 struct AAMDNodes {
72 AAMDNodes(MDNode *T = nullptr)
73 : TBAA(T) {}
72 AAMDNodes(MDNode *T = nullptr, MDNode *S = nullptr, MDNode *N = nullptr)
73 : TBAA(T), Scope(S), NoAlias(N) {}
7474
7575 bool operator == (const AAMDNodes &A) const {
7676 return equals(A);
8181 }
8282
8383 operator bool() const {
84 return TBAA;
84 return TBAA || Scope || NoAlias;
8585 }
8686
8787 /// TBAA - The tag for type-based alias analysis.
8888 MDNode *TBAA;
8989
90 /// Scope - The tag for alias scope specification (used with noalias).
91 MDNode *Scope;
92
93 /// NoAlias - The tag specifying the noalias scope.
94 MDNode *NoAlias;
95
9096 protected:
9197 bool equals(const AAMDNodes &A) const {
92 return TBAA == A.TBAA;
98 return TBAA == A.TBAA && Scope == A.Scope && NoAlias == A.NoAlias;
9399 }
94100 };
95101
97103 template<>
98104 struct DenseMapInfo {
99105 static inline AAMDNodes getEmptyKey() {
100 return AAMDNodes(DenseMapInfo::getEmptyKey());
106 return AAMDNodes(DenseMapInfo::getEmptyKey(), 0, 0);
101107 }
102108 static inline AAMDNodes getTombstoneKey() {
103 return AAMDNodes(DenseMapInfo::getTombstoneKey());
109 return AAMDNodes(DenseMapInfo::getTombstoneKey(), 0, 0);
104110 }
105111 static unsigned getHashValue(const AAMDNodes &Val) {
106 return DenseMapInfo::getHashValue(Val.TBAA);
112 return DenseMapInfo::getHashValue(Val.TBAA) ^
113 DenseMapInfo::getHashValue(Val.Scope) ^
114 DenseMapInfo::getHashValue(Val.NoAlias);
107115 }
108116 static bool isEqual(const AAMDNodes &LHS, const AAMDNodes &RHS) {
109117 return LHS == RHS;
213221 bool isTBAAVtableAccess() const;
214222
215223 /// Methods for metadata merging.
224 static MDNode *concatenate(MDNode *A, MDNode *B);
225 static MDNode *intersect(MDNode *A, MDNode *B);
216226 static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B);
217227 static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);
218228 static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
262262 void initializeTargetLibraryInfoPass(PassRegistry&);
263263 void initializeTwoAddressInstructionPassPass(PassRegistry&);
264264 void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
265 void initializeScopedNoAliasAAPass(PassRegistry&);
265266 void initializeUnifyFunctionExitNodesPass(PassRegistry&);
266267 void initializeUnreachableBlockElimPass(PassRegistry&);
267268 void initializeUnreachableMachineBlockElimPass(PassRegistry&);
5555 (void) llvm::createLibCallAliasAnalysisPass(nullptr);
5656 (void) llvm::createScalarEvolutionAliasAnalysisPass();
5757 (void) llvm::createTypeBasedAliasAnalysisPass();
58 (void) llvm::createScopedNoAliasAAPass();
5859 (void) llvm::createBoundsCheckingPass();
5960 (void) llvm::createBreakCriticalEdgesPass();
6061 (void) llvm::createCallGraphPrinterPass();
131131 /** See llvm::createTypeBasedAliasAnalysisPass function */
132132 void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);
133133
134 /** See llvm::createScopedNoAliasAAPass function */
135 void LLVMAddScopedNoAliasAAPass(LLVMPassManagerRef PM);
136
134137 /** See llvm::createBasicAliasAnalysisPass function */
135138 void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
136139
6565 initializeScalarEvolutionAliasAnalysisPass(Registry);
6666 initializeTargetTransformInfoAnalysisGroup(Registry);
6767 initializeTypeBasedAliasAnalysisPass(Registry);
68 initializeScopedNoAliasAAPass(Registry);
6869 }
6970
7071 void LLVMInitializeAnalysis(LLVMPassRegistryRef R) {
5252 TargetTransformInfo.cpp
5353 Trace.cpp
5454 TypeBasedAliasAnalysis.cpp
55 ScopedNoAliasAA.cpp
5556 ValueTracking.cpp
5657 )
5758
0 //===- ScopedNoAliasAA.cpp - Scoped No-Alias Alias Analysis ---------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the ScopedNoAlias alias-analysis pass, which implements
10 // metadata-based scoped no-alias support.
11 //
12 // Alias-analysis scopes are defined similar to TBAA nodes:
13 //
14 // !scope0 = metadata !{ metadata !"scope of foo()" }
15 // !scope1 = metadata !{ metadata !"scope 1", metadata !scope0 }
16 // !scope2 = metadata !{ metadata !"scope 2", metadata !scope0 }
17 // !scope3 = metadata !{ metadata !"scope 2.1", metadata !scope2 }
18 // !scope4 = metadata !{ metadata !"scope 2.2", metadata !scope2 }
19 //
20 // Loads and stores can be tagged with an alias-analysis scope, and also, with
21 // a noalias tag for a specific scope:
22 //
23 // ... = load %ptr1, !alias.scope !{ !scope1 }
24 // ... = load %ptr2, !alias.scope !{ !scope1, !scope2 }, !noalias !{ !scope1 }
25 //
26 // When evaluating an aliasing query, if one of the instructions is associated
27 // with an alias.scope id that is identical to the noalias scope associated
28 // with the other instruction, or is a descendant (in the scope hierarchy) of
29 // the noalias scope associated with the other instruction, then the two memory
30 // accesses are assumed not to alias.
31 //
32 // Note that if the first element of the scope metadata is a string, then it
33 // can be combined accross functions and translation units. The string can be
34 // replaced by a self-reference to create globally unqiue scope identifiers.
35 //
36 //===----------------------------------------------------------------------===//
37
38 #include "llvm/Analysis/Passes.h"
39 #include "llvm/Analysis/AliasAnalysis.h"
40 #include "llvm/IR/Constants.h"
41 #include "llvm/IR/LLVMContext.h"
42 #include "llvm/IR/Metadata.h"
43 #include "llvm/IR/Module.h"
44 #include "llvm/Pass.h"
45 #include "llvm/Support/CommandLine.h"
46 using namespace llvm;
47
48 // A handy option for disabling scoped no-alias functionality. The same effect
49 // can also be achieved by stripping the associated metadata tags from IR, but
50 // this option is sometimes more convenient.
51 static cl::opt
52 EnableScopedNoAlias("enable-scoped-noalias", cl::init(true));
53
54 namespace {
55 /// AliasScopeNode - This is a simple wrapper around an MDNode which provides
56 /// a higher-level interface by hiding the details of how alias analysis
57 /// information is encoded in its operands.
58 class AliasScopeNode {
59 const MDNode *Node;
60
61 public:
62 AliasScopeNode() : Node(0) {}
63 explicit AliasScopeNode(const MDNode *N) : Node(N) {}
64
65 /// getNode - Get the MDNode for this AliasScopeNode.
66 const MDNode *getNode() const { return Node; }
67
68 /// getParent - Get this AliasScopeNode's Alias tree parent.
69 AliasScopeNode getParent() const {
70 if (Node->getNumOperands() < 2)
71 return AliasScopeNode();
72 MDNode *P = dyn_cast_or_null(Node->getOperand(1));
73 if (!P)
74 return AliasScopeNode();
75 // Ok, this node has a valid parent. Return it.
76 return AliasScopeNode(P);
77 }
78 };
79
80 /// ScopedNoAliasAA - This is a simple alias analysis
81 /// implementation that uses scoped-noalias metadata to answer queries.
82 class ScopedNoAliasAA : public ImmutablePass, public AliasAnalysis {
83 public:
84 static char ID; // Class identification, replacement for typeinfo
85 ScopedNoAliasAA() : ImmutablePass(ID) {
86 initializeScopedNoAliasAAPass(*PassRegistry::getPassRegistry());
87 }
88
89 virtual void initializePass() {
90 InitializeAliasAnalysis(this);
91 }
92
93 /// getAdjustedAnalysisPointer - This method is used when a pass implements
94 /// an analysis interface through multiple inheritance. If needed, it
95 /// should override this to adjust the this pointer as needed for the
96 /// specified pass info.
97 virtual void *getAdjustedAnalysisPointer(const void *PI) {
98 if (PI == &AliasAnalysis::ID)
99 return (AliasAnalysis*)this;
100 return this;
101 }
102
103 protected:
104 bool mayAlias(const MDNode *A, const MDNode *B) const;
105 bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const;
106
107 private:
108 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
109 virtual AliasResult alias(const Location &LocA, const Location &LocB);
110 virtual bool pointsToConstantMemory(const Location &Loc, bool OrLocal);
111 virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
112 virtual ModRefBehavior getModRefBehavior(const Function *F);
113 virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
114 const Location &Loc);
115 virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
116 ImmutableCallSite CS2);
117 };
118 } // End of anonymous namespace
119
120 // Register this pass...
121 char ScopedNoAliasAA::ID = 0;
122 INITIALIZE_AG_PASS(ScopedNoAliasAA, AliasAnalysis, "scoped-noalias",
123 "Scoped NoAlias Alias Analysis", false, true, false)
124
125 ImmutablePass *llvm::createScopedNoAliasAAPass() {
126 return new ScopedNoAliasAA();
127 }
128
129 void
130 ScopedNoAliasAA::getAnalysisUsage(AnalysisUsage &AU) const {
131 AU.setPreservesAll();
132 AliasAnalysis::getAnalysisUsage(AU);
133 }
134
135 /// mayAlias - Test whether the scope represented by A may alias the
136 /// scope represented by B. Specifically, A is the target scope, and B is the
137 /// noalias scope.
138 bool
139 ScopedNoAliasAA::mayAlias(const MDNode *A,
140 const MDNode *B) const {
141 // Climb the tree from A to see if we reach B.
142 for (AliasScopeNode T(A); ; ) {
143 if (T.getNode() == B)
144 // B is an ancestor of A.
145 return false;
146
147 T = T.getParent();
148 if (!T.getNode())
149 break;
150 }
151
152 return true;
153 }
154
155 bool
156 ScopedNoAliasAA::mayAliasInScopes(const MDNode *Scopes,
157 const MDNode *NoAlias) const {
158 if (!Scopes || !NoAlias)
159 return true;
160
161 for (unsigned i = 0, ie = Scopes->getNumOperands(); i != ie; ++i)
162 if (const MDNode *SMD = dyn_cast(Scopes->getOperand(i)))
163 for (unsigned j = 0, je = NoAlias->getNumOperands(); j != je; ++j)
164 if (const MDNode *NAMD = dyn_cast(NoAlias->getOperand(j)))
165 if (!mayAlias(SMD, NAMD))
166 return false;
167
168 return true;
169 }
170
171 AliasAnalysis::AliasResult
172 ScopedNoAliasAA::alias(const Location &LocA, const Location &LocB) {
173 if (!EnableScopedNoAlias)
174 return AliasAnalysis::alias(LocA, LocB);
175
176 // Get the attached MDNodes.
177 const MDNode *AScopes = LocA.AATags.Scope,
178 *BScopes = LocB.AATags.Scope;
179
180 const MDNode *ANoAlias = LocA.AATags.NoAlias,
181 *BNoAlias = LocB.AATags.NoAlias;
182
183 if (!mayAliasInScopes(AScopes, BNoAlias))
184 return NoAlias;
185
186 if (!mayAliasInScopes(BScopes, ANoAlias))
187 return NoAlias;
188
189 // If they may alias, chain to the next AliasAnalysis.
190 return AliasAnalysis::alias(LocA, LocB);
191 }
192
193 bool ScopedNoAliasAA::pointsToConstantMemory(const Location &Loc,
194 bool OrLocal) {
195 return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
196 }
197
198 AliasAnalysis::ModRefBehavior
199 ScopedNoAliasAA::getModRefBehavior(ImmutableCallSite CS) {
200 return AliasAnalysis::getModRefBehavior(CS);
201 }
202
203 AliasAnalysis::ModRefBehavior
204 ScopedNoAliasAA::getModRefBehavior(const Function *F) {
205 return AliasAnalysis::getModRefBehavior(F);
206 }
207
208 AliasAnalysis::ModRefResult
209 ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
210 if (!EnableScopedNoAlias)
211 return AliasAnalysis::getModRefInfo(CS, Loc);
212
213 if (!mayAliasInScopes(Loc.AATags.Scope,
214 CS.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
215 return NoModRef;
216
217 if (!mayAliasInScopes(
218 CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
219 Loc.AATags.NoAlias))
220 return NoModRef;
221
222 return AliasAnalysis::getModRefInfo(CS, Loc);
223 }
224
225 AliasAnalysis::ModRefResult
226 ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
227 if (!EnableScopedNoAlias)
228 return AliasAnalysis::getModRefInfo(CS1, CS2);
229
230 if (!mayAliasInScopes(
231 CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
232 CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
233 return NoModRef;
234
235 if (!mayAliasInScopes(
236 CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
237 CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
238 return NoModRef;
239
240 return AliasAnalysis::getModRefInfo(CS1, CS2);
241 }
242
617617 getMetadata(LLVMContext::MD_tbaa));
618618 else
619619 N.TBAA = getMetadata(LLVMContext::MD_tbaa);
620 }
621
620
621 if (Merge)
622 N.Scope = MDNode::intersect(N.Scope,
623 getMetadata(LLVMContext::MD_alias_scope));
624 else
625 N.Scope = getMetadata(LLVMContext::MD_alias_scope);
626
627 if (Merge)
628 N.NoAlias = MDNode::intersect(N.NoAlias,
629 getMetadata(LLVMContext::MD_noalias));
630 else
631 N.NoAlias = getMetadata(LLVMContext::MD_noalias);
632 }
633
522522 OS << ")";
523523 }
524524
525 // Print AA scope info.
526 if (const MDNode *ScopeInfo = MMO.getAAInfo().Scope) {
527 OS << "(alias.scope=";
528 if (ScopeInfo->getNumOperands() > 0)
529 for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) {
530 ScopeInfo->getOperand(i)->printAsOperand(OS, /*PrintType=*/false);
531 if (i != ie-1)
532 OS << ",";
533 }
534 else
535 OS << "";
536 OS << ")";
537 }
538
539 // Print AA noalias scope info.
540 if (const MDNode *NoAliasInfo = MMO.getAAInfo().NoAlias) {
541 OS << "(noalias=";
542 if (NoAliasInfo->getNumOperands() > 0)
543 for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) {
544 NoAliasInfo->getOperand(i)->printAsOperand(OS, /*PrintType=*/false);
545 if (i != ie-1)
546 OS << ",";
547 }
548 else
549 OS << "";
550 OS << ")";
551 }
552
525553 // Print nontemporal info.
526554 if (MMO.isNonTemporal())
527555 OS << "(nontemporal)";
376376 // BasicAliasAnalysis wins if they disagree. This is intended to help
377377 // support "obvious" type-punning idioms.
378378 addPass(createTypeBasedAliasAnalysisPass());
379 addPass(createScopedNoAliasAAPass());
379380 addPass(createBasicAliasAnalysisPass());
380381
381382 // Before running any passes, run the verifier to determine if the input
6161
6262 CallInst *IRBuilderBase::
6363 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
64 bool isVolatile, MDNode *TBAATag) {
64 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
65 MDNode *NoAliasTag) {
6566 Ptr = getCastedInt8PtrValue(Ptr);
6667 Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };
6768 Type *Tys[] = { Ptr->getType(), Size->getType() };
7374 // Set the TBAA info if present.
7475 if (TBAATag)
7576 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
76
77
78 if (ScopeTag)
79 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
80
81 if (NoAliasTag)
82 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
83
7784 return CI;
7885 }
7986
8087 CallInst *IRBuilderBase::
8188 CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
82 bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag) {
89 bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,
90 MDNode *ScopeTag, MDNode *NoAliasTag) {
8391 Dst = getCastedInt8PtrValue(Dst);
8492 Src = getCastedInt8PtrValue(Src);
8593
97105 // Set the TBAA Struct info if present.
98106 if (TBAAStructTag)
99107 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
100
108
109 if (ScopeTag)
110 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
111
112 if (NoAliasTag)
113 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
114
101115 return CI;
102116 }
103117
104118 CallInst *IRBuilderBase::
105119 CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
106 bool isVolatile, MDNode *TBAATag) {
120 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
121 MDNode *NoAliasTag) {
107122 Dst = getCastedInt8PtrValue(Dst);
108123 Src = getCastedInt8PtrValue(Src);
109124
117132 // Set the TBAA info if present.
118133 if (TBAATag)
119134 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
120
135
136 if (ScopeTag)
137 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
138
139 if (NoAliasTag)
140 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
141
121142 return CI;
122143 }
123144
6565 unsigned InvariantLdId = getMDKindID("invariant.load");
6666 assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
6767 (void)InvariantLdId;
68
69 // Create the 'alias.scope' metadata kind.
70 unsigned AliasScopeID = getMDKindID("alias.scope");
71 assert(AliasScopeID == MD_alias_scope && "alias.scope kind id drifted");
72 (void)AliasScopeID;
73
74 // Create the 'noalias' metadata kind.
75 unsigned NoAliasID = getMDKindID("noalias");
76 assert(NoAliasID == MD_noalias && "noalias kind id drifted");
77 (void)NoAliasID;
6878 }
6979 LLVMContext::~LLVMContext() { delete pImpl; }
7080
5959 return MDNode::get(Context, Range);
6060 }
6161
62 MDNode *MDBuilder::createAnonymousTBAARoot() {
62 MDNode *MDBuilder::createAnonymousAARoot(StringRef Name) {
6363 // To ensure uniqueness the root node is self-referential.
64 MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef());
65 MDNode *Root = MDNode::get(Context, Dummy);
64 MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef());
65
66 SmallVector Args(1, Dummy);
67 if (!Name.empty())
68 Args.push_back(createString(Name));
69 MDNode *Root = MDNode::get(Context, Args);
70
6671 // At this point we have
6772 // !0 = metadata !{} <- dummy
6873 // !1 = metadata !{metadata !0} <- root
9095 Value *Ops[2] = {createString(Name), Parent};
9196 return MDNode::get(Context, Ops);
9297 }
98 }
99
100 MDNode *MDBuilder::createAliasScopeRoot(StringRef Name) {
101 return MDNode::get(Context, createString(Name));
102 }
103
104 MDNode *MDBuilder::createAliasScopeNode(StringRef Name, MDNode *Parent) {
105 Value *Ops[2] = { createString(Name), Parent };
106 return MDNode::get(Context, Ops);
93107 }
94108
95109 /// \brief Return metadata for a tbaa.struct node with the given
405405 }
406406 }
407407
408 MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
409 if (!A)
410 return B;
411 if (!B)
412 return A;
413
414 SmallVector Vals(A->getNumOperands() +
415 B->getNumOperands());
416
417 unsigned j = 0;
418 for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i)
419 Vals[j++] = A->getOperand(i);
420 for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++i)
421 Vals[j++] = B->getOperand(i);
422
423 return MDNode::get(A->getContext(), Vals);
424 }
425
426 MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
427 if (!A || !B)
428 return nullptr;
429
430 SmallVector Vals;
431 for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) {
432 Value *V = A->getOperand(i);
433 for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j)
434 if (V == B->getOperand(j)) {
435 Vals.push_back(V);
436 break;
437 }
438 }
439
440 return MDNode::get(A->getContext(), Vals);
441 }
442
408443 MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
409444 if (!A || !B)
410445 return nullptr;
688723
689724 void Instruction::setAAMetadata(const AAMDNodes &N) {
690725 setMetadata(LLVMContext::MD_tbaa, N.TBAA);
726 setMetadata(LLVMContext::MD_alias_scope, N.Scope);
727 setMetadata(LLVMContext::MD_noalias, N.NoAlias);
691728 }
692729
693730 MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
106106 // BasicAliasAnalysis wins if they disagree. This is intended to help
107107 // support "obvious" type-punning idioms.
108108 PM.add(createTypeBasedAliasAnalysisPass());
109 PM.add(createScopedNoAliasAAPass());
109110 PM.add(createBasicAliasAnalysisPass());
110111 }
111112
17901790 case LLVMContext::MD_tbaa:
17911791 ReplInst->setMetadata(Kind, MDNode::getMostGenericTBAA(IMD, ReplMD));
17921792 break;
1793 case LLVMContext::MD_alias_scope:
1794 case LLVMContext::MD_noalias:
1795 // FIXME: If both the original and replacement value are part of the
1796 // same control-flow region (meaning that the execution of one
1797 // guarentees the executation of the other), then we can combine the
1798 // noalias scopes here and do better than the general conservative
1799 // answer.
1800
1801 // In general, GVN unifies expressions over different control-flow
1802 // regions, and so we need a conservative combination of the noalias
1803 // scopes.
1804 ReplInst->setMetadata(Kind, MDNode::intersect(IMD, ReplMD));
1805 break;
17931806 case LLVMContext::MD_range:
17941807 ReplInst->setMetadata(Kind, MDNode::getMostGenericRange(IMD, ReplMD));
17951808 break;
202202 unwrap(PM)->add(createTypeBasedAliasAnalysisPass());
203203 }
204204
205 void LLVMAddScopedNoAliasAAPass(LLVMPassManagerRef PM) {
206 unwrap(PM)->add(createScopedNoAliasAAPass());
207 }
208
205209 void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM) {
206210 unwrap(PM)->add(createBasicAliasAnalysisPass());
207211 }
311311 || Tag == LLVMContext::MD_fpmath
312312 || Tag == LLVMContext::MD_tbaa_struct
313313 || Tag == LLVMContext::MD_invariant_load
314 || Tag == LLVMContext::MD_alias_scope
315 || Tag == LLVMContext::MD_noalias
314316 || Tag == ParallelLoopAccessMDKind);
315317 }
316318
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "llvm/Transforms/Utils/Cloning.h"
15 #include "llvm/ADT/SmallSet.h"
1516 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/SetVector.h"
1618 #include "llvm/ADT/StringExtras.h"
1719 #include "llvm/Analysis/CallGraph.h"
1820 #include "llvm/Analysis/InstructionSimplify.h"
21 #include "llvm/Analysis/ValueTracking.h"
1922 #include "llvm/IR/Attributes.h"
2023 #include "llvm/IR/CallSite.h"
2124 #include "llvm/IR/CFG.h"
2730 #include "llvm/IR/Instructions.h"
2831 #include "llvm/IR/IntrinsicInst.h"
2932 #include "llvm/IR/Intrinsics.h"
33 #include "llvm/IR/MDBuilder.h"
3034 #include "llvm/IR/Module.h"
3135 #include "llvm/Transforms/Utils/Local.h"
3236 using namespace llvm;
257261 // invoke instruction. Eliminate these entries (which might even delete the
258262 // PHI node) now.
259263 InvokeDest->removePredecessor(II->getParent());
264 }
265
266 /// CloneAliasScopeMetadata - When inlining a function that contains noalias
267 /// scope metadata, this metadata needs to be cloned so that the inlined blocks
268 /// have different "unqiue scopes" at every call site. Were this not done, then
269 /// aliasing scopes from a function inlined into a caller multiple times could
270 /// not be differentiated (and this would lead to miscompiles because the
271 /// non-aliasing property communicated by the metadata could have
272 /// call-site-specific control dependencies).
273 static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) {
274 const Function *CalledFunc = CS.getCalledFunction();
275 SetVector MD;
276
277 // Note: We could only clone the metadata if it is already used in the
278 // caller. I'm omitting that check here because it might confuse
279 // inter-procedural alias analysis passes. We can revisit this if it becomes
280 // an efficiency or overhead problem.
281
282 for (Function::const_iterator I = CalledFunc->begin(), IE = CalledFunc->end();
283 I != IE; ++I)
284 for (BasicBlock::const_iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
285 if (const MDNode *M = J->getMetadata(LLVMContext::MD_alias_scope))
286 MD.insert(M);
287 if (const MDNode *M = J->getMetadata(LLVMContext::MD_noalias))
288 MD.insert(M);
289 }
290
291 if (MD.empty())
292 return;
293
294 // Walk the existing metadata, adding the complete (perhaps cyclic) chain to
295 // the set.
296 SmallVector Queue(MD.begin(), MD.end());
297 while (!Queue.empty()) {
298 const MDNode *M = cast(Queue.pop_back_val());
299 for (unsigned i = 0, ie = M->getNumOperands(); i != ie; ++i)
300 if (const MDNode *M1 = dyn_cast(M->getOperand(i)))
301 if (MD.insert(M1))
302 Queue.push_back(M1);
303 }
304
305 // Now we have a complete set of all metadata in the chains used to specify
306 // the noalias scopes and the lists of those scopes.
307 SmallVector DummyNodes;
308 DenseMap > MDMap;
309 for (SetVector::iterator I = MD.begin(), IE = MD.end();
310 I != IE; ++I) {
311 MDNode *Dummy = MDNode::getTemporary(CalledFunc->getContext(),
312 ArrayRef());
313 DummyNodes.push_back(Dummy);
314 MDMap[*I] = Dummy;
315 }
316
317 // Create new metadata nodes to replace the dummy nodes, replacing old
318 // metadata references with either a dummy node or an already-created new
319 // node.
320 for (SetVector::iterator I = MD.begin(), IE = MD.end();
321 I != IE; ++I) {
322 SmallVector NewOps;
323 for (unsigned i = 0, ie = (*I)->getNumOperands(); i != ie; ++i) {
324 const Value *V = (*I)->getOperand(i);
325 if (const MDNode *M = dyn_cast(V))
326 NewOps.push_back(MDMap[M]);
327 else
328 NewOps.push_back(const_cast(V));
329 }
330
331 MDNode *NewM = MDNode::get(CalledFunc->getContext(), NewOps),
332 *TempM = MDMap[*I];
333
334 TempM->replaceAllUsesWith(NewM);
335 }
336
337 // Now replace the metadata in the new inlined instructions with the
338 // repacements from the map.
339 for (ValueToValueMapTy::iterator VMI = VMap.begin(), VMIE = VMap.end();
340 VMI != VMIE; ++VMI) {
341 if (!VMI->second)
342 continue;
343
344 Instruction *NI = dyn_cast(VMI->second);
345 if (!NI)
346 continue;
347
348 if (MDNode *M = NI->getMetadata(LLVMContext::MD_alias_scope))
349 NI->setMetadata(LLVMContext::MD_alias_scope, MDMap[M]);
350
351 if (MDNode *M = NI->getMetadata(LLVMContext::MD_noalias))
352 NI->setMetadata(LLVMContext::MD_noalias, MDMap[M]);
353 }
354
355 // Now that everything has been replaced, delete the dummy nodes.
356 for (unsigned i = 0, ie = DummyNodes.size(); i != ie; ++i)
357 MDNode::deleteTemporary(DummyNodes[i]);
260358 }
261359
262360 /// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee
647745
648746 // Update inlined instructions' line number information.
649747 fixupLineNumbers(Caller, FirstNewBlock, TheCall);
748
749 // Clone existing noalias metadata if necessary.
750 CloneAliasScopeMetadata(CS, VMap);
650751 }
651752
652753 // If there are any alloca instructions in the block that used to be the entry
29812981 case LLVMContext::MD_tbaa:
29822982 K->setMetadata(Kind, MDNode::getMostGenericTBAA(JMD, KMD));
29832983 break;
2984 case LLVMContext::MD_alias_scope:
2985 case LLVMContext::MD_noalias:
2986 K->setMetadata(Kind, MDNode::intersect(JMD, KMD));
2987 break;
29842988 case LLVMContext::MD_fpmath:
29852989 K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD));
29862990 break;
534534 // non-speculated memory access when the condition was false, this would be
535535 // caught by the runtime overlap checks).
536536 if (Kind != LLVMContext::MD_tbaa &&
537 Kind != LLVMContext::MD_alias_scope &&
538 Kind != LLVMContext::MD_noalias &&
537539 Kind != LLVMContext::MD_fpmath)
538540 continue;
539541
229229 case LLVMContext::MD_tbaa:
230230 MD = MDNode::getMostGenericTBAA(MD, IMD);
231231 break;
232 case LLVMContext::MD_alias_scope:
233 case LLVMContext::MD_noalias:
234 MD = MDNode::intersect(MD, IMD);
235 break;
232236 case LLVMContext::MD_fpmath:
233237 MD = MDNode::getMostGenericFPMath(MD, IMD);
234238 break;
0 ; RUN: opt < %s -basicaa -scoped-noalias -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
1 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 define void @foo1(float* nocapture %a, float* nocapture readonly %c) #0 {
5 entry:
6 ; CHECK-LABEL: Function: foo1
7 %0 = load float* %c, align 4, !alias.scope !0
8 %arrayidx.i = getelementptr inbounds float* %a, i64 5
9 store float %0, float* %arrayidx.i, align 4, !noalias !0
10
11 %1 = load float* %c, align 4
12 %arrayidx = getelementptr inbounds float* %a, i64 7
13 store float %1, float* %arrayidx, align 4
14
15 %2 = load float* %c, align 4, !alias.scope !1
16 %arrayidx.i2 = getelementptr inbounds float* %a, i64 15
17 store float %2, float* %arrayidx.i2, align 4, !noalias !3
18
19 %3 = load float* %c, align 4, !alias.scope !3
20 %arrayidx.i3 = getelementptr inbounds float* %a, i64 16
21 store float %3, float* %arrayidx.i3, align 4, !noalias !0
22
23 %4 = load float* %c, align 4, !alias.scope !5
24 %arrayidx.i4 = getelementptr inbounds float* %a, i64 17
25 store float %4, float* %arrayidx.i4, align 4, !noalias !3
26 ret void
27 }
28
29 attributes #0 = { nounwind uwtable }
30
31 ; A root scope (which doubles as a list of itself):
32 !0 = metadata !{metadata !0}
33
34 ; Two child scopes (which must be self-referential to avoid being "uniqued"):
35 !1 = metadata !{metadata !2}
36 !2 = metadata !{metadata !2, metadata !0}
37
38 !3 = metadata !{metadata !4}
39 !4 = metadata !{metadata !4, metadata !0}
40
41 ; A list of the two children:
42 !5 = metadata !{metadata !2, metadata !4}
43
44 ; CHECK: NoAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
45 ; CHECK: MayAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %1, float* %arrayidx, align 4
46 ; CHECK: MayAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
47 ; CHECK: NoAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %3, float* %arrayidx.i3, align 4, !noalias !0
48 ; CHECK: MayAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %4, float* %arrayidx.i4, align 4, !noalias !3
49 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
50 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %1, float* %arrayidx, align 4
51 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
52 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %3, float* %arrayidx.i3, align 4, !noalias !0
53 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %4, float* %arrayidx.i4, align 4, !noalias !3
54 ; CHECK: NoAlias: %2 = load float* %c, align 4, !alias.scope !1 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
55 ; CHECK: MayAlias: %2 = load float* %c, align 4, !alias.scope !1 <-> store float %1, float* %arrayidx, align 4
56 ; CHECK: MayAlias: %2 = load float* %c, align 4, !alias.scope !1 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
57 ; CHECK: NoAlias: %2 = load float* %c, align 4, !alias.scope !1 <-> store float %3, float* %arrayidx.i3, align 4, !noalias !0
58 ; CHECK: MayAlias: %2 = load float* %c, align 4, !alias.scope !1 <-> store float %4, float* %arrayidx.i4, align 4, !noalias !3
59 ; CHECK: NoAlias: %3 = load float* %c, align 4, !alias.scope !3 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
60 ; CHECK: MayAlias: %3 = load float* %c, align 4, !alias.scope !3 <-> store float %1, float* %arrayidx, align 4
61 ; CHECK: NoAlias: %3 = load float* %c, align 4, !alias.scope !3 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
62 ; CHECK: NoAlias: %3 = load float* %c, align 4, !alias.scope !3 <-> store float %3, float* %arrayidx.i3, align 4, !noalias !0
63 ; CHECK: NoAlias: %3 = load float* %c, align 4, !alias.scope !3 <-> store float %4, float* %arrayidx.i4, align 4, !noalias !3
64 ; CHECK: NoAlias: %4 = load float* %c, align 4, !alias.scope !5 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
65 ; CHECK: MayAlias: %4 = load float* %c, align 4, !alias.scope !5 <-> store float %1, float* %arrayidx, align 4
66 ; CHECK: NoAlias: %4 = load float* %c, align 4, !alias.scope !5 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
67 ; CHECK: NoAlias: %4 = load float* %c, align 4, !alias.scope !5 <-> store float %3, float* %arrayidx.i3, align 4, !noalias !0
68 ; CHECK: NoAlias: %4 = load float* %c, align 4, !alias.scope !5 <-> store float %4, float* %arrayidx.i4, align 4, !noalias !3
69 ; CHECK: NoAlias: store float %1, float* %arrayidx, align 4 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
70 ; CHECK: NoAlias: store float %2, float* %arrayidx.i2, align 4, !noalias !3 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
71 ; CHECK: NoAlias: store float %2, float* %arrayidx.i2, align 4, !noalias !3 <-> store float %1, float* %arrayidx, align 4
72 ; CHECK: NoAlias: store float %3, float* %arrayidx.i3, align 4, !noalias !0 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
73 ; CHECK: NoAlias: store float %3, float* %arrayidx.i3, align 4, !noalias !0 <-> store float %1, float* %arrayidx, align 4
74 ; CHECK: NoAlias: store float %3, float* %arrayidx.i3, align 4, !noalias !0 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
75 ; CHECK: NoAlias: store float %4, float* %arrayidx.i4, align 4, !noalias !3 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
76 ; CHECK: NoAlias: store float %4, float* %arrayidx.i4, align 4, !noalias !3 <-> store float %1, float* %arrayidx, align 4
77 ; CHECK: NoAlias: store float %4, float* %arrayidx.i4, align 4, !noalias !3 <-> store float %2, float* %arrayidx.i2, align 4, !noalias !3
78 ; CHECK: NoAlias: store float %4, float* %arrayidx.i4, align 4, !noalias !3 <-> store float %3, float* %arrayidx.i3, align 4, !noalias !0
79
0 ; RUN: opt < %s -basicaa -scoped-noalias -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
1 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 define void @foo1(float* nocapture %a, float* nocapture readonly %c) #0 {
5 entry:
6 ; CHECK-LABEL: Function: foo1
7 %0 = load float* %c, align 4, !alias.scope !0
8 %arrayidx.i = getelementptr inbounds float* %a, i64 5
9 store float %0, float* %arrayidx.i, align 4, !noalias !0
10 %1 = load float* %c, align 4
11 %arrayidx = getelementptr inbounds float* %a, i64 7
12 store float %1, float* %arrayidx, align 4
13 ret void
14
15 ; CHECK: NoAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
16 ; CHECK: MayAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %1, float* %arrayidx, align 4
17 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
18 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %1, float* %arrayidx, align 4
19 ; CHECK: NoAlias: store float %1, float* %arrayidx, align 4 <-> store float %0, float* %arrayidx.i, align 4, !noalias !0
20 }
21
22 attributes #0 = { nounwind uwtable }
23
24 !0 = metadata !{metadata !0}
25
0 ; RUN: opt < %s -basicaa -scoped-noalias -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
1 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
5 entry:
6 ; CHECK-LABEL: Function: foo2
7 %0 = load float* %c, align 4, !alias.scope !0
8 %arrayidx.i = getelementptr inbounds float* %a, i64 5
9 store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
10 %arrayidx1.i = getelementptr inbounds float* %b, i64 8
11 store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
12 %1 = load float* %c, align 4
13 %arrayidx = getelementptr inbounds float* %a, i64 7
14 store float %1, float* %arrayidx, align 4
15 ret void
16
17 ; CHECK: NoAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
18 ; CHECK: NoAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
19 ; CHECK: MayAlias: %0 = load float* %c, align 4, !alias.scope !0 <-> store float %1, float* %arrayidx, align 4
20 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
21 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
22 ; CHECK: MayAlias: %1 = load float* %c, align 4 <-> store float %1, float* %arrayidx, align 4
23 ; CHECK: NoAlias: store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2 <-> store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
24 ; CHECK: NoAlias: store float %1, float* %arrayidx, align 4 <-> store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
25 ; CHECK: MayAlias: store float %1, float* %arrayidx, align 4 <-> store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
26 }
27
28 attributes #0 = { nounwind uwtable }
29
30 !0 = metadata !{metadata !1, metadata !2}
31 !1 = metadata !{metadata !1}
32 !2 = metadata !{metadata !2}
33
0 ; RUN: opt -scoped-noalias -basicaa -gvn -S < %s | FileCheck %s
1
2 define i32 @test1(i32* %p, i32* %q) {
3 ; CHECK-LABEL: @test1(i32* %p, i32* %q)
4 ; CHECK: load i32* %p
5 ; CHECK-NOT: noalias
6 ; CHECK: %c = add i32 %a, %a
7 %a = load i32* %p, !noalias !0
8 %b = load i32* %p
9 %c = add i32 %a, %b
10 ret i32 %c
11 }
12
13 define i32 @test2(i32* %p, i32* %q) {
14 ; CHECK-LABEL: @test2(i32* %p, i32* %q)
15 ; CHECK: load i32* %p, !alias.scope !0
16 ; CHECK: %c = add i32 %a, %a
17 %a = load i32* %p, !alias.scope !0
18 %b = load i32* %p, !alias.scope !0
19 %c = add i32 %a, %b
20 ret i32 %c
21 }
22
23 ; FIXME: In this case we can do better than intersecting the scopes, and can
24 ; concatenate them instead. Both loads are in the same basic block, the first
25 ; makes the second safe to speculatively execute, and there are no calls that may
26 ; throw in between.
27 define i32 @test3(i32* %p, i32* %q) {
28 ; CHECK-LABEL: @test3(i32* %p, i32* %q)
29 ; CHECK: load i32* %p, !alias.scope !1
30 ; CHECK: %c = add i32 %a, %a
31 %a = load i32* %p, !alias.scope !1
32 %b = load i32* %p, !alias.scope !2
33 %c = add i32 %a, %b
34 ret i32 %c
35 }
36
37 declare i32 @foo(i32*) readonly
38
39 !0 = metadata !{metadata !0}
40 !1 = metadata !{metadata !1}
41 !2 = metadata !{metadata !0, metadata !1}
42