[llvm] r213948 - Simplify and improve scoped-noalias metadata semantics

Hal Finkel hfinkel at anl.gov
Fri Jul 25 08:50:02 PDT 2014


Author: hfinkel
Date: Fri Jul 25 10:50:02 2014
New Revision: 213948

URL: http://llvm.org/viewvc/llvm-project?rev=213948&view=rev
Log:
Simplify and improve scoped-noalias metadata semantics

In the process of fixing the noalias parameter -> metadata conversion process
that will take place during inlining (which will be committed soon, but not
turned on by default), I have come to realize that the semantics provided by
yesterday's commit are not really what we want. Here's why:

void foo(noalias a, noalias b, noalias c, bool x) {
  *q = x ? a : b;
  *c = *q;
}

Generically, we know that *c does not alias with *a and with *b (so there is an
'and' in what we know we're not), and we know that *q might be derived from *a
or from *b (so there is an 'or' in what we know that we are). So we do not want
the semantics currently, where any noalias scope matching any alias.scope
causes a NoAlias return. What we want to know is that the noalias scopes form a
superset of the alias.scope list (meaning that all the things we know we're not
is a superset of all of things the other instruction might be).

Making that change, however, introduces a composibility problem. If we inline
once, adding the noalias metadata, and then inline again adding more, and we
append new scopes onto the noalias and alias.scope lists each time. But, this
means that we could change what was a NoAlias result previously into a MayAlias
result because we appended an additional scope onto one of the alias.scope
lists. So, instead of giving scopes the ability to have parents (which I had
borrowed from the TBAA implementation, but seems increasingly unlikely to be
useful in practice), I've given them domains. The subset/superset condition now
applies within each domain independently, and we only need it to hold in one
domain. Each time we inline, we add the new scopes in a new scope domain, and
everything now composes nicely. In addition, this simplifies the
implementation.

Added:
    llvm/trunk/test/Analysis/ScopedNoAliasAA/basic-domains.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/MDBuilder.h
    llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp
    llvm/trunk/lib/IR/MDBuilder.cpp
    llvm/trunk/test/Analysis/ScopedNoAliasAA/basic.ll
    llvm/trunk/test/Analysis/ScopedNoAliasAA/basic2.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=213948&r1=213947&r2=213948&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Fri Jul 25 10:50:02 2014
@@ -2837,50 +2837,58 @@ noalias memory-access sets. This means t
 instructions (loads, stores, memory-accessing calls, etc.) that carry
 ``noalias`` metadata can specifically be specified not to alias with some other
 collection of memory access instructions that carry ``alias.scope`` metadata.
-Each type of metadata specifies a list of scopes, and when evaluating an
-aliasing query, if one of the instructions has a scope in its ``alias.scope``
-list that is identical to a scope in the other instruction's ``noalias`` list,
-or is a descendant (in the scope hierarchy) of a scope in the other
-instruction's ``noalias`` list , then the two memory accesses are assumed not
-to alias.
+Each type of metadata specifies a list of scopes where each scope has an id and
+a domain. When evaluating an aliasing query, if for some some domain, the set
+of scopes with that domain in one instruction's ``alias.scope`` list is a
+subset of (or qual to) the set of scopes for that domain in another
+instruction's ``noalias`` list, then the two memory accesses are assumed not to
+alias.
 
-The metadata identifying each scope is itself a list containing one or two
-entries. The first entry is the name of the scope. Note that if the name is a
+The metadata identifying each domain is itself a list containing one or two
+entries. The first entry is the name of the domain. Note that if the name is a
 string then it can be combined accross functions and translation units. A
-self-reference can be used to create globally unique scope names.
-Optionally, a metadata reference to a parent scope can be provided as a second
-entry in the list.
+self-reference can be used to create globally unique domain names. A
+descriptive string may optionally be provided as a second list entry.
+
+The metadata identifying each scope is also itself a list containing two or
+three entries. The first entry is the name of the scope. Note that if the name
+is a string then it can be combined accross functions and translation units. A
+self-reference can be used to create globally unique scope names. A metadata
+reference to the scope's domain is the second entry. A descriptive string may
+optionally be provided as a third list entry.
 
 For example,
 
 .. code-block:: llvm
 
-    ; A root scope (which doubles as a list of itself):
+    ; Two scope domains:
     !0 = metadata !{metadata !0}
+    !1 = metadata !{metadata !1}
 
-    ; Two child scopes (which must be self-referential to avoid being "uniqued"):
-    !1 = metadata !{metadata !2} ; A list containing only scope !2
-    !2 = metadata !{metadata !2, metadata !0} ; Scope !2 is a descendant of scope !0
-
-    !3 = metadata !{metadata !4} ; A list containing only scope !4
-    !4 = metadata !{metadata !4, metadata !0} ; Scope !4 is a descendant of scope !0
+    ; Some scopes in these domains:
+    !2 = metadata !{metadata !2, metadata !0}
+    !3 = metadata !{metadata !3, metadata !0}
+    !4 = metadata !{metadata !4, metadata !1}
+
+    ; Some scope lists:
+    !5 = metadata !{metadata !4} ; A list containing only scope !4
+    !6 = metadata !{metadata !4, metadata !3, metadata !2}
+    !7 = metadata !{metadata !3}
 
     ; These two instructions don't alias:
-    %0 = load float* %c, align 4, !alias.scope !0
-    store float %0, float* %arrayidx.i, align 4, !noalias !0
+    %0 = load float* %c, align 4, !alias.scope !5
+    store float %0, float* %arrayidx.i, align 4, !noalias !5
 
-    ; These two instructions may alias (scope !2 and scope !4 are peers):
-    %2 = load float* %c, align 4, !alias.scope !1
-    store float %2, float* %arrayidx.i2, align 4, !noalias !3
-
-    ; These two instructions don't alias (scope !2 is a descendant of scope !0
-    ; and the store does not alias with anything in scope !0 or any of its descendants):
-    %2 = load float* %c, align 4, !alias.scope !1
-    store float %0, float* %arrayidx.i, align 4, !noalias !0
-
-    ; These two instructions may alias:
-    %2 = load float* %c, align 4, !alias.scope !0
-    store float %0, float* %arrayidx.i, align 4, !noalias !1
+    ; These two instructions also don't alias (for domain !1, the set of scopes
+    ; in the !alias.scope equals that in the !noalias list):
+    %2 = load float* %c, align 4, !alias.scope !5
+    store float %2, float* %arrayidx.i2, align 4, !noalias !6
+
+    ; These two instructions don't alias (for domain !0, the set of scopes in
+    ; the !noalias list is not a superset of, or equal to, the scopes in the
+    ; !alias.scope list):
+    %2 = load float* %c, align 4, !alias.scope !6
+    store float %0, float* %arrayidx.i, align 4, !noalias !7
 
 '``fpmath``' Metadata
 ^^^^^^^^^^^^^^^^^^^^^

Modified: llvm/trunk/include/llvm/IR/MDBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/MDBuilder.h?rev=213948&r1=213947&r2=213948&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/MDBuilder.h (original)
+++ llvm/trunk/include/llvm/IR/MDBuilder.h Fri Jul 25 10:50:02 2014
@@ -70,7 +70,8 @@ protected:
   /// \brief Return metadata appropriate for a AA root node (scope or TBAA).
   /// Each returned node is distinct from all other metadata and will never
   /// be identified (uniqued) with anything else.
-  MDNode *createAnonymousAARoot(StringRef Name = StringRef());
+  MDNode *createAnonymousAARoot(StringRef Name = StringRef(),
+                                MDNode *Extra = nullptr);
 
 public:
   /// \brief Return metadata appropriate for a TBAA root node. Each returned
@@ -80,32 +81,41 @@ public:
     return createAnonymousAARoot();
   }
 
-  /// \brief Return metadata appropriate for an alias scope root node.
+  /// \brief Return metadata appropriate for an alias scope domain node.
   /// Each returned node is distinct from all other metadata and will never
   /// be identified (uniqued) with anything else.
-  MDNode *createAnonymousAliasScopeRoot(StringRef Name = StringRef()) {
+  MDNode *createAnonymousAliasScopeDomain(StringRef Name = StringRef()) {
     return createAnonymousAARoot(Name);
   }
 
+  /// \brief Return metadata appropriate for an alias scope root node.
+  /// Each returned node is distinct from all other metadata and will never
+  /// be identified (uniqued) with anything else.
+  MDNode *createAnonymousAliasScope(MDNode *Domain,
+                                    StringRef Name = StringRef()) {
+    return createAnonymousAARoot(Name, Domain);
+  }
+
   /// \brief Return metadata appropriate for a TBAA root node with the given
   /// name.  This may be identified (uniqued) with other roots with the same
   /// name.
   MDNode *createTBAARoot(StringRef Name);
 
-  /// \brief Return metadata appropriate for an alias scope root node with
+  /// \brief Return metadata appropriate for an alias scope domain node with
   /// the given name. This may be identified (uniqued) with other roots with
   /// the same name.
-  MDNode *createAliasScopeRoot(StringRef Name);
+  MDNode *createAliasScopeDomain(StringRef Name);
+
+  /// \brief Return metadata appropriate for an alias scope node with
+  /// the given name. This may be identified (uniqued) with other scopes with
+  /// the same name and domain.
+  MDNode *createAliasScope(StringRef Name, MDNode *Domain);
 
   /// \brief Return metadata for a non-root TBAA node with the given name,
   /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
   MDNode *createTBAANode(StringRef Name, MDNode *Parent,
                          bool isConstant = false);
 
-  /// \brief Return metadata for a non-root alias scope node with the given
-  /// name and parent in the scope tree.
-  MDNode *createAliasScopeNode(StringRef Name, MDNode *Parent);
-
   struct TBAAStructField {
     uint64_t Offset;
     uint64_t Size;

Modified: llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp?rev=213948&r1=213947&r2=213948&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp (original)
+++ llvm/trunk/lib/Analysis/ScopedNoAliasAA.cpp Fri Jul 25 10:50:02 2014
@@ -10,13 +10,14 @@
 // This file defines the ScopedNoAlias alias-analysis pass, which implements
 // metadata-based scoped no-alias support.
 //
-// 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 }
+// Alias-analysis scopes are defined by an id (which can be a string or some
+// other metadata node), a domain node, and an optional descriptive string.
+// A domain is defined by an id (which can be a string or some other metadata
+// node), and an optional descriptive string.
+//
+// !dom0 =   metadata !{ metadata !"domain of foo()" }
+// !scope1 = metadata !{ metadata !scope1, metadata !dom0, metadata !"scope 1" }
+// !scope2 = metadata !{ metadata !scope2, metadata !dom0, metadata !"scope 2" }
 //
 // Loads and stores can be tagged with an alias-analysis scope, and also, with
 // a noalias tag for a specific scope:
@@ -25,17 +26,13 @@
 // ... = 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
+// has a set of noalias scopes in some domain that is superset of the alias
+// scopes in that domain of some other instruction, then the two memory
 // accesses are assumed not to alias.
 //
-// Note that if 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.
-//
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/IR/Constants.h"
@@ -66,15 +63,11 @@ public:
   /// getNode - Get the MDNode for this AliasScopeNode.
   const MDNode *getNode() const { return Node; }
 
-  /// getParent - Get this AliasScopeNode's Alias tree parent.
-  AliasScopeNode getParent() const {
+  /// getDomain - Get the MDNode for this AliasScopeNode's domain.
+  const MDNode *getDomain() const {
     if (Node->getNumOperands() < 2)
-      return AliasScopeNode();
-    MDNode *P = dyn_cast_or_null<MDNode>(Node->getOperand(1));
-    if (!P)
-      return AliasScopeNode();
-    // Ok, this node has a valid parent. Return it.
-    return AliasScopeNode(P);
+      return nullptr;
+    return dyn_cast_or_null<MDNode>(Node->getOperand(1));
   }
 };
 
@@ -102,8 +95,9 @@ public:
   }
 
 protected:
-  bool mayAlias(const MDNode *A, const MDNode *B) const;
   bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const;
+  void collectMDInDomain(const MDNode *List, const MDNode *Domain,
+                         SmallPtrSetImpl<const MDNode *> &Nodes) const;
 
 private:
   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
@@ -133,24 +127,13 @@ ScopedNoAliasAA::getAnalysisUsage(Analys
   AliasAnalysis::getAnalysisUsage(AU);
 }
 
-/// mayAlias - Test whether the scope represented by A may alias the
-/// scope represented by B. Specifically, A is the target scope, and B is the
-/// noalias scope.
-bool
-ScopedNoAliasAA::mayAlias(const MDNode *A,
-                          const MDNode *B) const {
-  // Climb the tree from A to see if we reach B.
-  for (AliasScopeNode T(A); ; ) {
-    if (T.getNode() == B)
-      // B is an ancestor of A.
-      return false;
-
-    T = T.getParent();
-    if (!T.getNode())
-      break;
-  }
-
-  return true;
+void
+ScopedNoAliasAA::collectMDInDomain(const MDNode *List, const MDNode *Domain,
+                   SmallPtrSetImpl<const MDNode *> &Nodes) const {
+  for (unsigned i = 0, ie = List->getNumOperands(); i != ie; ++i)
+    if (const MDNode *MD = dyn_cast<MDNode>(List->getOperand(i)))
+      if (AliasScopeNode(MD).getDomain() == Domain)
+        Nodes.insert(MD);
 }
 
 bool
@@ -159,14 +142,35 @@ ScopedNoAliasAA::mayAliasInScopes(const
   if (!Scopes || !NoAlias)
     return true;
 
-  for (unsigned i = 0, ie = Scopes->getNumOperands(); i != ie; ++i)
-    if (const MDNode *SMD = dyn_cast<MDNode>(Scopes->getOperand(i)))
-      for (unsigned j = 0, je = NoAlias->getNumOperands(); j != je; ++j)
-        if (const MDNode *NAMD = dyn_cast<MDNode>(NoAlias->getOperand(j)))
-          if (!mayAlias(SMD, NAMD))
-            return false;
+  // Collect the set of scope domains relevant to the noalias scopes.
+  SmallPtrSet<const MDNode *, 16> Domains;
+  for (unsigned i = 0, ie = NoAlias->getNumOperands(); i != ie; ++i)
+    if (const MDNode *NAMD = dyn_cast<MDNode>(NoAlias->getOperand(i)))
+      if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
+        Domains.insert(Domain);
+
+  // We alias unless, for some domain, the set of noalias scopes in that domain
+  // is a superset of the set of alias scopes in that domain.
+  for (const MDNode *Domain : Domains) {
+    SmallPtrSet<const MDNode *, 16> NANodes, ScopeNodes;
+    collectMDInDomain(NoAlias, Domain, NANodes);
+    collectMDInDomain(Scopes, Domain, ScopeNodes);
+    if (!ScopeNodes.size())
+      continue;
+
+    // To not alias, all of the nodes in ScopeNodes must be in NANodes.
+    bool FoundAll = true;
+    for (const MDNode *SMD : ScopeNodes)
+      if (!NANodes.count(SMD)) {
+        FoundAll = false;
+        break;
+      }
+
+    if (FoundAll)
+      return false;
+  }
 
-  return true; 
+  return true;
 }
 
 AliasAnalysis::AliasResult

Modified: llvm/trunk/lib/IR/MDBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/MDBuilder.cpp?rev=213948&r1=213947&r2=213948&view=diff
==============================================================================
--- llvm/trunk/lib/IR/MDBuilder.cpp (original)
+++ llvm/trunk/lib/IR/MDBuilder.cpp Fri Jul 25 10:50:02 2014
@@ -60,11 +60,13 @@ MDNode *MDBuilder::createRange(const API
   return MDNode::get(Context, Range);
 }
 
-MDNode *MDBuilder::createAnonymousAARoot(StringRef Name) {
+MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
   // To ensure uniqueness the root node is self-referential.
   MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>());
 
-  SmallVector<Value *, 2> Args(1, Dummy);
+  SmallVector<Value *, 3> Args(1, Dummy);
+  if (Extra)
+    Args.push_back(Extra);
   if (!Name.empty())
     Args.push_back(createString(Name));
   MDNode *Root = MDNode::get(Context, Args);
@@ -98,12 +100,12 @@ MDNode *MDBuilder::createTBAANode(String
   }
 }
 
-MDNode *MDBuilder::createAliasScopeRoot(StringRef Name) {
+MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
   return MDNode::get(Context, createString(Name));
 }
 
-MDNode *MDBuilder::createAliasScopeNode(StringRef Name, MDNode *Parent) {
-  Value *Ops[2] = { createString(Name), Parent };
+MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
+  Value *Ops[2] = { createString(Name), Domain };
   return MDNode::get(Context, Ops);
 }
 

Added: llvm/trunk/test/Analysis/ScopedNoAliasAA/basic-domains.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScopedNoAliasAA/basic-domains.ll?rev=213948&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScopedNoAliasAA/basic-domains.ll (added)
+++ llvm/trunk/test/Analysis/ScopedNoAliasAA/basic-domains.ll Fri Jul 25 10:50:02 2014
@@ -0,0 +1,57 @@
+; RUN: opt < %s -basicaa -scoped-noalias -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo1(float* nocapture %a, float* nocapture readonly %c) #0 {
+entry:
+; CHECK-LABEL: Function: foo1
+  %0 = load float* %c, align 4, !alias.scope !9
+  %arrayidx.i = getelementptr inbounds float* %a, i64 5
+  store float %0, float* %arrayidx.i, align 4, !noalias !6
+
+  %1 = load float* %c, align 4, !alias.scope !5
+  %arrayidx.i2 = getelementptr inbounds float* %a, i64 15
+  store float %1, float* %arrayidx.i2, align 4, !noalias !6
+
+  %2 = load float* %c, align 4, !alias.scope !6
+  %arrayidx.i3 = getelementptr inbounds float* %a, i64 16
+  store float %2, float* %arrayidx.i3, align 4, !noalias !5
+
+  ret void
+}
+
+attributes #0 = { nounwind uwtable }
+
+!0 = metadata !{metadata !0, metadata !"some domain"}
+!1 = metadata !{metadata !1, metadata !"some other domain"}
+
+; Two scopes (which must be self-referential to avoid being "uniqued"):
+!2 = metadata !{metadata !2, metadata !0, metadata !"a scope in dom0"}
+!3 = metadata !{metadata !2}
+
+!4 = metadata !{metadata !4, metadata !0, metadata !"another scope in dom0"}
+!5 = metadata !{metadata !4}
+
+; A list of the two scopes.
+!6 = metadata !{metadata !2, metadata !4}
+
+; Another scope in the second domain
+!7 = metadata !{metadata !7, metadata !1, metadata !"another scope in dom1"}
+!8 = metadata !{metadata !7}
+
+; A list of scopes from both domains.
+!9 = metadata !{metadata !2, metadata !4, metadata !7}
+
+; CHECK: NoAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %0, float* %arrayidx.i, align 4, !noalias !6
+; CHECK: NoAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %1, float* %arrayidx.i2, align 4, !noalias !6
+; CHECK: MayAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %2, float* %arrayidx.i3, align 4, !noalias !7
+; CHECK: NoAlias:   %1 = load float* %c, align 4, !alias.scope !7 <->   store float %0, float* %arrayidx.i, align 4, !noalias !6
+; CHECK: NoAlias:   %1 = load float* %c, align 4, !alias.scope !7 <->   store float %1, float* %arrayidx.i2, align 4, !noalias !6
+; CHECK: NoAlias:   %1 = load float* %c, align 4, !alias.scope !7 <->   store float %2, float* %arrayidx.i3, align 4, !noalias !7
+; CHECK: NoAlias:   %2 = load float* %c, align 4, !alias.scope !6 <->   store float %0, float* %arrayidx.i, align 4, !noalias !6
+; CHECK: NoAlias:   %2 = load float* %c, align 4, !alias.scope !6 <->   store float %1, float* %arrayidx.i2, align 4, !noalias !6
+; CHECK: MayAlias:   %2 = load float* %c, align 4, !alias.scope !6 <->   store float %2, float* %arrayidx.i3, align 4, !noalias !7
+; CHECK: NoAlias:   store float %1, float* %arrayidx.i2, align 4, !noalias !6 <->   store float %0, float* %arrayidx.i, align 4, !noalias !6
+; CHECK: NoAlias:   store float %2, float* %arrayidx.i3, align 4, !noalias !7 <->   store float %0, float* %arrayidx.i, align 4, !noalias !6
+; CHECK: NoAlias:   store float %2, float* %arrayidx.i3, align 4, !noalias !7 <->   store float %1, float* %arrayidx.i2, align 4, !noalias !6
+

Modified: llvm/trunk/test/Analysis/ScopedNoAliasAA/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScopedNoAliasAA/basic.ll?rev=213948&r1=213947&r2=213948&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScopedNoAliasAA/basic.ll (original)
+++ llvm/trunk/test/Analysis/ScopedNoAliasAA/basic.ll Fri Jul 25 10:50:02 2014
@@ -5,9 +5,9 @@ target triple = "x86_64-unknown-linux-gn
 define void @foo1(float* nocapture %a, float* nocapture readonly %c) #0 {
 entry:
 ; CHECK-LABEL: Function: foo1
-  %0 = load float* %c, align 4, !alias.scope !0
+  %0 = load float* %c, align 4, !alias.scope !1
   %arrayidx.i = getelementptr inbounds float* %a, i64 5
-  store float %0, float* %arrayidx.i, align 4, !noalias !0
+  store float %0, float* %arrayidx.i, align 4, !noalias !1
   %1 = load float* %c, align 4
   %arrayidx = getelementptr inbounds float* %a, i64 7
   store float %1, float* %arrayidx, align 4
@@ -22,5 +22,6 @@ entry:
 
 attributes #0 = { nounwind uwtable }
 
-!0 = metadata !{metadata !0}
+!0 = metadata !{metadata !0, metadata !"some domain"}
+!1 = metadata !{metadata !1, metadata !0, metadata !"some scope"}
 

Modified: llvm/trunk/test/Analysis/ScopedNoAliasAA/basic2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScopedNoAliasAA/basic2.ll?rev=213948&r1=213947&r2=213948&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScopedNoAliasAA/basic2.ll (original)
+++ llvm/trunk/test/Analysis/ScopedNoAliasAA/basic2.ll Fri Jul 25 10:50:02 2014
@@ -7,28 +7,35 @@ entry:
 ; CHECK-LABEL: Function: foo2
   %0 = load float* %c, align 4, !alias.scope !0
   %arrayidx.i = getelementptr inbounds float* %a, i64 5
-  store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
+  store float %0, float* %arrayidx.i, align 4, !alias.scope !5, !noalias !4
   %arrayidx1.i = getelementptr inbounds float* %b, i64 8
-  store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
+  store float %0, float* %arrayidx1.i, align 4, !alias.scope !0, !noalias !5
   %1 = load float* %c, align 4
   %arrayidx = getelementptr inbounds float* %a, i64 7
   store float %1, float* %arrayidx, align 4
   ret void
 
-; CHECK: NoAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
-; CHECK: NoAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
+; CHECK: MayAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %0, float* %arrayidx.i, align 4, !alias.scope !4, !noalia
+; CHECK: s !5
+; CHECK: MayAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %0, float* %arrayidx1.i, align 4, !alias.scope !0, !noali
+; CHECK: as !4
 ; CHECK: MayAlias:   %0 = load float* %c, align 4, !alias.scope !0 <->   store float %1, float* %arrayidx, align 4
-; CHECK: MayAlias:   %1 = load float* %c, align 4 <->   store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
-; CHECK: MayAlias:   %1 = load float* %c, align 4 <->   store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
+; CHECK: MayAlias:   %1 = load float* %c, align 4 <->   store float %0, float* %arrayidx.i, align 4, !alias.scope !4, !noalias !5
+; CHECK: MayAlias:   %1 = load float* %c, align 4 <->   store float %0, float* %arrayidx1.i, align 4, !alias.scope !0, !noalias !4
 ; CHECK: MayAlias:   %1 = load float* %c, align 4 <->   store float %1, float* %arrayidx, align 4
-; 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
-; CHECK: NoAlias:   store float %1, float* %arrayidx, align 4 <->   store float %0, float* %arrayidx.i, align 4, !alias.scope !2, !noalias !1
-; CHECK: MayAlias:   store float %1, float* %arrayidx, align 4 <->   store float %0, float* %arrayidx1.i, align 4, !alias.scope !1, !noalias !2
+; CHECK: NoAlias:   store float %0, float* %arrayidx1.i, align 4, !alias.scope !0, !noalias !4 <->   store float %0, float* %arrayidx.i, align
+; CHECK: 4, !alias.scope !4, !noalias !5
+; CHECK: NoAlias:   store float %1, float* %arrayidx, align 4 <->   store float %0, float* %arrayidx.i, align 4, !alias.scope !4, !noalias !5
+; CHECK: MayAlias:   store float %1, float* %arrayidx, align 4 <->   store float %0, float* %arrayidx1.i, align 4, !alias.scope !0, !noalias !
+; CHECK: 4
 }
 
 attributes #0 = { nounwind uwtable }
 
-!0 = metadata !{metadata !1, metadata !2}
-!1 = metadata !{metadata !1}
-!2 = metadata !{metadata !2}
+!0 = metadata !{metadata !1, metadata !3}
+!1 = metadata !{metadata !1, metadata !2, metadata !"some scope"}
+!2 = metadata !{metadata !2, metadata !"some domain"}
+!3 = metadata !{metadata !3, metadata !2, metadata !"some other scope"}
+!4 = metadata !{metadata !1}
+!5 = metadata !{metadata !3}
 





More information about the llvm-commits mailing list