[clang] 2b9a834 - [InlineFunction] Use llvm.experimental.noalias.scope.decl for noalias arguments.

Jeroen Dobbelaere via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 23 03:12:28 PST 2021


Author: Jeroen Dobbelaere
Date: 2021-01-23T12:10:57+01:00
New Revision: 2b9a834c43cb1f93d33958c14b695896bb4e9c1e

URL: https://github.com/llvm/llvm-project/commit/2b9a834c43cb1f93d33958c14b695896bb4e9c1e
DIFF: https://github.com/llvm/llvm-project/commit/2b9a834c43cb1f93d33958c14b695896bb4e9c1e.diff

LOG: [InlineFunction] Use llvm.experimental.noalias.scope.decl for noalias arguments.

Insert a llvm.experimental.noalias.scope.decl intrinsic that identifies where a noalias argument was inlined.

This patch includes some refactorings from D90104.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D93040

Added: 
    llvm/test/Transforms/Inline/noalias-calls2.ll

Modified: 
    clang/test/CodeGen/aarch64-ls64.c
    llvm/lib/Transforms/Utils/InlineFunction.cpp
    llvm/test/Transforms/Coroutines/ArgAddr.ll
    llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll
    llvm/test/Transforms/Coroutines/coro-retcon-value.ll
    llvm/test/Transforms/Coroutines/coro-retcon.ll
    llvm/test/Transforms/Coroutines/ex2.ll
    llvm/test/Transforms/Coroutines/ex3.ll
    llvm/test/Transforms/Coroutines/ex4.ll
    llvm/test/Transforms/Inline/launder.invariant.group.ll
    llvm/test/Transforms/Inline/noalias-calls-always.ll
    llvm/test/Transforms/Inline/noalias-calls.ll
    llvm/test/Transforms/Inline/noalias-cs.ll
    llvm/test/Transforms/Inline/noalias.ll
    llvm/test/Transforms/Inline/noalias2.ll
    llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
    llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll
    llvm/test/Transforms/PhaseOrdering/pr39282.ll

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGen/aarch64-ls64.c b/clang/test/CodeGen/aarch64-ls64.c
index 77e4b41fbd58..17fce0094ac9 100644
--- a/clang/test/CodeGen/aarch64-ls64.c
+++ b/clang/test/CodeGen/aarch64-ls64.c
@@ -21,6 +21,7 @@ uint64_t status;
 // CHECK-NEXT:    [[__ADDR_ADDR_I:%.*]] = alloca i8*, align 8
 // CHECK-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_DATA512_T:%.*]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load i8*, i8** @addr, align 8
+// CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !6)
 // CHECK-NEXT:    store i8* [[TMP0]], i8** [[__ADDR_ADDR_I]], align 8, !noalias !6
 // CHECK-NEXT:    [[TMP1:%.*]] = load i8*, i8** [[__ADDR_ADDR_I]], align 8, !noalias !6
 // CHECK-NEXT:    [[VAL_I:%.*]] = getelementptr inbounds [[STRUCT_DATA512_T]], %struct.data512_t* [[REF_TMP]], i32 0, i32 0

diff  --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 65bf6a3b32dc..abdd2b2361b7 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -79,6 +79,12 @@ EnableNoAliasConversion("enable-noalias-to-md-conversion", cl::init(true),
   cl::Hidden,
   cl::desc("Convert noalias attributes to metadata during inlining."));
 
+static cl::opt<bool>
+    UseNoAliasIntrinsic("use-noalias-intrinsic-during-inlining", cl::Hidden,
+                        cl::ZeroOrMore, cl::init(true),
+                        cl::desc("Use the llvm.experimental.noalias.scope.decl "
+                                 "intrinsic during inlining."));
+
 // Disabled by default, because the added alignment assumptions may increase
 // compile-time and block optimizations. This option is not suitable for use
 // with frontends that emit comprehensive parameter alignment annotations.
@@ -821,91 +827,119 @@ static void PropagateCallSiteMetadata(CallBase &CB, ValueToValueMapTy &VMap) {
   }
 }
 
-/// When inlining a function that contains noalias scope metadata,
-/// this metadata needs to be cloned so that the inlined blocks
-/// have 
diff erent "unique scopes" at every call site. Were this not done, then
-/// aliasing scopes from a function inlined into a caller multiple times could
-/// not be 
diff erentiated (and this would lead to miscompiles because the
-/// non-aliasing property communicated by the metadata could have
-/// call-site-specific control dependencies).
-static void CloneAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap) {
-  const Function *CalledFunc = CB.getCalledFunction();
+/// Utility for cloning !noalias and !alias.scope metadata. When a code region
+/// using scoped alias metadata is inlined, the aliasing relationships may not
+/// hold between the two version. It is necessary to create a deep clone of the
+/// metadata, putting the two versions in separate scope domains.
+class ScopedAliasMetadataDeepCloner {
+  using MetadataMap = DenseMap<const MDNode *, TrackingMDNodeRef>;
   SetVector<const MDNode *> MD;
-
-  // Note: We could only clone the metadata if it is already used in the
-  // caller. I'm omitting that check here because it might confuse
-  // inter-procedural alias analysis passes. We can revisit this if it becomes
-  // an efficiency or overhead problem.
-
-  for (const BasicBlock &I : *CalledFunc)
-    for (const Instruction &J : I) {
-      if (const MDNode *M = J.getMetadata(LLVMContext::MD_alias_scope))
+  MetadataMap MDMap;
+  void addRecursiveMetadataUses();
+
+public:
+  ScopedAliasMetadataDeepCloner(const Function *F);
+
+  /// Create a new clone of the scoped alias metadata, which will be used by
+  /// subsequent remap() calls.
+  void clone();
+
+  /// Remap instructions in the given VMap from the original to the cloned
+  /// metadata.
+  void remap(ValueToValueMapTy &VMap);
+};
+
+ScopedAliasMetadataDeepCloner::ScopedAliasMetadataDeepCloner(
+    const Function *F) {
+  for (const BasicBlock &BB : *F) {
+    for (const Instruction &I : BB) {
+      if (const MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope))
         MD.insert(M);
-      if (const MDNode *M = J.getMetadata(LLVMContext::MD_noalias))
+      if (const MDNode *M = I.getMetadata(LLVMContext::MD_noalias))
         MD.insert(M);
-    }
 
-  if (MD.empty())
-    return;
+      // We also need to clone the metadata in noalias intrinsics.
+      if (const auto *II = dyn_cast<IntrinsicInst>(&I))
+        if (II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl)
+          if (const auto *M = dyn_cast<MDNode>(
+                  cast<MetadataAsValue>(
+                      II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg))
+                      ->getMetadata()))
+            MD.insert(M);
+    }
+  }
+  addRecursiveMetadataUses();
+}
 
-  // Walk the existing metadata, adding the complete (perhaps cyclic) chain to
-  // the set.
+void ScopedAliasMetadataDeepCloner::addRecursiveMetadataUses() {
   SmallVector<const Metadata *, 16> Queue(MD.begin(), MD.end());
   while (!Queue.empty()) {
     const MDNode *M = cast<MDNode>(Queue.pop_back_val());
-    for (unsigned i = 0, ie = M->getNumOperands(); i != ie; ++i)
-      if (const MDNode *M1 = dyn_cast<MDNode>(M->getOperand(i)))
-        if (MD.insert(M1))
-          Queue.push_back(M1);
+    for (const Metadata *Op : M->operands())
+      if (const MDNode *OpMD = dyn_cast<MDNode>(Op))
+        if (MD.insert(OpMD))
+          Queue.push_back(OpMD);
   }
+}
+
+void ScopedAliasMetadataDeepCloner::clone() {
+  assert(MDMap.empty() && "clone() already called ?");
 
-  // Now we have a complete set of all metadata in the chains used to specify
-  // the noalias scopes and the lists of those scopes.
   SmallVector<TempMDTuple, 16> DummyNodes;
-  DenseMap<const MDNode *, TrackingMDNodeRef> MDMap;
   for (const MDNode *I : MD) {
-    DummyNodes.push_back(MDTuple::getTemporary(CalledFunc->getContext(), None));
+    DummyNodes.push_back(MDTuple::getTemporary(I->getContext(), None));
     MDMap[I].reset(DummyNodes.back().get());
   }
 
   // Create new metadata nodes to replace the dummy nodes, replacing old
   // metadata references with either a dummy node or an already-created new
   // node.
+  SmallVector<Metadata *, 4> NewOps;
   for (const MDNode *I : MD) {
-    SmallVector<Metadata *, 4> NewOps;
-    for (unsigned i = 0, ie = I->getNumOperands(); i != ie; ++i) {
-      const Metadata *V = I->getOperand(i);
-      if (const MDNode *M = dyn_cast<MDNode>(V))
+    for (const Metadata *Op : I->operands()) {
+      if (const MDNode *M = dyn_cast<MDNode>(Op))
         NewOps.push_back(MDMap[M]);
       else
-        NewOps.push_back(const_cast<Metadata *>(V));
+        NewOps.push_back(const_cast<Metadata *>(Op));
     }
 
-    MDNode *NewM = MDNode::get(CalledFunc->getContext(), NewOps);
+    MDNode *NewM = MDNode::get(I->getContext(), NewOps);
     MDTuple *TempM = cast<MDTuple>(MDMap[I]);
     assert(TempM->isTemporary() && "Expected temporary node");
 
     TempM->replaceAllUsesWith(NewM);
+    NewOps.clear();
   }
+}
 
-  // Now replace the metadata in the new inlined instructions with the
-  // repacements from the map.
-  for (ValueToValueMapTy::iterator VMI = VMap.begin(), VMIE = VMap.end();
-       VMI != VMIE; ++VMI) {
+void ScopedAliasMetadataDeepCloner::remap(ValueToValueMapTy &VMap) {
+  if (MDMap.empty())
+    return; // Nothing to do.
+
+  for (auto Entry : VMap) {
     // Check that key is an instruction, to skip the Argument mapping, which
     // points to an instruction in the original function, not the inlined one.
-    if (!VMI->second || !isa<Instruction>(VMI->first))
+    if (!Entry->second || !isa<Instruction>(Entry->first))
       continue;
 
-    Instruction *NI = dyn_cast<Instruction>(VMI->second);
-    if (!NI)
+    Instruction *I = dyn_cast<Instruction>(Entry->second);
+    if (!I)
       continue;
 
-    if (MDNode *M = NI->getMetadata(LLVMContext::MD_alias_scope))
-      NI->setMetadata(LLVMContext::MD_alias_scope, MDMap[M]);
+    if (MDNode *M = I->getMetadata(LLVMContext::MD_alias_scope))
+      I->setMetadata(LLVMContext::MD_alias_scope, MDMap[M]);
 
-    if (MDNode *M = NI->getMetadata(LLVMContext::MD_noalias))
-      NI->setMetadata(LLVMContext::MD_noalias, MDMap[M]);
+    if (MDNode *M = I->getMetadata(LLVMContext::MD_noalias))
+      I->setMetadata(LLVMContext::MD_noalias, MDMap[M]);
+
+    if (auto *II = dyn_cast<IntrinsicInst>(I))
+      if (II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl) {
+        auto *MV = cast<MetadataAsValue>(
+            II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
+        auto *NewMV = MetadataAsValue::get(
+            II->getContext(), MDMap[cast<MDNode>(MV->getMetadata())]);
+        II->setOperand(Intrinsic::NoAliasScopeDeclScopeArg, NewMV);
+      }
   }
 }
 
@@ -962,6 +996,17 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
     // property of the callee, but also all control dependencies in the caller.
     MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name);
     NewScopes.insert(std::make_pair(A, NewScope));
+
+    if (UseNoAliasIntrinsic) {
+      // Introduce a llvm.experimental.noalias.scope.decl for the noalias
+      // argument.
+      MDNode *AScopeList = MDNode::get(CalledFunc->getContext(), NewScope);
+      auto *NoAliasDecl =
+          IRBuilder<>(&CB).CreateNoAliasScopeDeclaration(AScopeList);
+      // Ignore the result for now. The result will be used when the
+      // llvm.noalias intrinsic is introduced.
+      (void)NoAliasDecl;
+    }
   }
 
   // Iterate over all new instructions in the map; for all memory-access
@@ -1759,6 +1804,14 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
     // Keep a list of pair (dst, src) to emit byval initializations.
     SmallVector<std::pair<Value*, Value*>, 4> ByValInit;
 
+    // When inlining a function that contains noalias scope metadata,
+    // this metadata needs to be cloned so that the inlined blocks
+    // have 
diff erent "unique scopes" at every call site.
+    // Track the metadata that must be cloned. Do this before other changes to
+    // the function, so that we do not get in trouble when inlining caller ==
+    // callee.
+    ScopedAliasMetadataDeepCloner SAMetadataCloner(CB.getCalledFunction());
+
     auto &DL = Caller->getParent()->getDataLayout();
 
     // Calculate the vector of arguments to pass into the function cloner, which
@@ -1876,8 +1929,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
     fixupLineNumbers(Caller, FirstNewBlock, &CB,
                      CalledFunc->getSubprogram() != nullptr);
 
-    // Clone existing noalias metadata if necessary.
-    CloneAliasScopeMetadata(CB, VMap);
+    // Now clone the inlined noalias scope metadata.
+    SAMetadataCloner.clone();
+    SAMetadataCloner.remap(VMap);
 
     // Add noalias metadata if necessary.
     AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR);

diff  --git a/llvm/test/Transforms/Coroutines/ArgAddr.ll b/llvm/test/Transforms/Coroutines/ArgAddr.ll
index 3bf2a199bafd..82667f87af5e 100644
--- a/llvm/test/Transforms/Coroutines/ArgAddr.ll
+++ b/llvm/test/Transforms/Coroutines/ArgAddr.ll
@@ -54,10 +54,12 @@ entry:
 ; CHECK-NEXT: bitcast i8* %index.addr12.i to i1*
 ; CHECK-NEXT: store i1 false
 ; CHECK-NEXT: store i32 3
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: store i32 3
 ; CHECK-NEXT: call void @print(i32 3)
 ; CHECK-NEXT: store i1 false
 ; CHECK-NEXT: store i32 2
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: store i32 2
 ; CHECK-NEXT: call void @print(i32 2)
 ; CHECK:      ret i32 0

diff  --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll
index 52e6f076f037..993fc5d01aec 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll
@@ -1,5 +1,5 @@
 ; RUN: opt < %s -enable-coroutines -O2 -S | FileCheck %s
-; RUN: opt < %s -enable-coroutines -passes='default<O2>' -S | FileCheck %s
+; RUN: opt < %s -enable-coroutines -passes='default<O2>' -aa-pipeline=default -S | FileCheck %s
 
 define i8* @f(i8* %buffer, i32 %n) {
 entry:
@@ -67,7 +67,10 @@ entry:
 ; CHECK-NEXT:  entry:
 ; CHECK:         [[BUFFER:%.*]] = alloca [8 x i8], align 4
 ; CHECK:         [[SLOT:%.*]] = bitcast [8 x i8]* [[BUFFER]] to i32*
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    store i32 7, i32* [[SLOT]], align 4
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    call void @print(i32 7)
 ; CHECK-NEXT:    ret i32 0
 

diff  --git a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll
index 2c66b6af99c6..42201a239f87 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll
@@ -79,14 +79,17 @@ entry:
 ; CHECK:         [[SLOT:%.*]] = bitcast [8 x i8]* [[BUFFER]] to i32*
 ; CHECK-NEXT:    store i32 4, i32* [[SLOT]], align 4
 ; CHECK-NEXT:    call void @print(i32 4)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4
 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LOAD]], 1
 ; CHECK-NEXT:    store i32 [[INC]], i32* [[SLOT]], align 4
 ; CHECK-NEXT:    call void @print(i32 [[INC]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4
 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LOAD]], 1
 ; CHECK-NEXT:    store i32 [[INC]], i32* [[SLOT]], align 4
 ; CHECK-NEXT:    call void @print(i32 [[INC]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    ret i32 0
 
 declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*)

diff  --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll
index b188db9ced3e..2534af8494ea 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll
@@ -69,13 +69,16 @@ entry:
 ; CHECK:         [[SLOT:%.*]] = bitcast [8 x i8]* [[BUFFER]] to i32*
 ; CHECK-NEXT:    store i32 4, i32* [[SLOT]], align 4
 ; CHECK-NEXT:    call void @print(i32 4)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4
 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LOAD]], 1
 ; CHECK-NEXT:    store i32 [[INC]], i32* [[SLOT]], align 4
 ; CHECK-NEXT:    call void @print(i32 [[INC]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, i32* [[SLOT]], align 4
 ; CHECK-NEXT:    [[INC:%.*]] = add i32 [[LOAD]], 1
 ; CHECK-NEXT:    call void @print(i32 [[INC]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT:    ret i32 0
 
 define hidden { i8*, i8* } @g(i8* %buffer, i16* %ptr) {

diff  --git a/llvm/test/Transforms/Coroutines/ex2.ll b/llvm/test/Transforms/Coroutines/ex2.ll
index 584bc909a4eb..820f53814661 100644
--- a/llvm/test/Transforms/Coroutines/ex2.ll
+++ b/llvm/test/Transforms/Coroutines/ex2.ll
@@ -49,7 +49,9 @@ return:
   ret i32 0
 ; CHECK-NOT:  call i8* @CustomAlloc
 ; CHECK:      call void @print(i32 4)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: call void @print(i32 5)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: call void @print(i32 6)
 ; CHECK-NEXT: ret i32 0
 }

diff  --git a/llvm/test/Transforms/Coroutines/ex3.ll b/llvm/test/Transforms/Coroutines/ex3.ll
index 85cf53fb576d..c75c7a1e09b1 100644
--- a/llvm/test/Transforms/Coroutines/ex3.ll
+++ b/llvm/test/Transforms/Coroutines/ex3.ll
@@ -53,7 +53,9 @@ return:
   ret i32 0
 ; CHECK-NOT:  i8* @malloc
 ; CHECK:      call void @print(i32 4)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: call void @print(i32 -5)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: call void @print(i32 5)
 ; CHECK:      ret i32 0
 }

diff  --git a/llvm/test/Transforms/Coroutines/ex4.ll b/llvm/test/Transforms/Coroutines/ex4.ll
index e60bc2c691fa..1a26107ecaf3 100644
--- a/llvm/test/Transforms/Coroutines/ex4.ll
+++ b/llvm/test/Transforms/Coroutines/ex4.ll
@@ -50,7 +50,9 @@ entry:
   call void @llvm.coro.destroy(i8* %hdl)
   ret i32 0
 ; CHECK:      call void @print(i32 4)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: call void @print(i32 5)
+; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl
 ; CHECK-NEXT: call void @print(i32 6)
 ; CHECK:      ret i32 0
 }

diff  --git a/llvm/test/Transforms/Inline/launder.invariant.group.ll b/llvm/test/Transforms/Inline/launder.invariant.group.ll
index 5ada6202f8f9..015ebe6efbf9 100644
--- a/llvm/test/Transforms/Inline/launder.invariant.group.ll
+++ b/llvm/test/Transforms/Inline/launder.invariant.group.ll
@@ -23,7 +23,7 @@ define i32 @bar(%struct.A* noalias) {
 ; CHECK-LABEL: define i32 @foo(%struct.A* noalias
 define i32 @foo(%struct.A* noalias)  {
   ; CHECK-NOT: call i32 @bar(
-  ; CHECK-NOT: noalias
+  ; CHECK-NOT: !noalias
   %2 = tail call i32 @bar(%struct.A* %0)
   ret i32 %2
 }

diff  --git a/llvm/test/Transforms/Inline/noalias-calls-always.ll b/llvm/test/Transforms/Inline/noalias-calls-always.ll
index 93d6b31ee8c8..fbe500841dcb 100644
--- a/llvm/test/Transforms/Inline/noalias-calls-always.ll
+++ b/llvm/test/Transforms/Inline/noalias-calls-always.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -aa-pipeline=basic-aa -passes=always-inline -enable-noalias-to-md-conversion -S < %s | 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"
@@ -6,6 +7,16 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i
 declare void @hey() #0
 
 define void @hello(i8* noalias nocapture %a, i8* noalias nocapture readonly %c, i8* nocapture %b) #1 {
+; CHECK-LABEL: @hello(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    call void @hey()
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    ret void
+;
 entry:
   %l = alloca i8, i32 512, align 1
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 0)
@@ -17,12 +28,36 @@ entry:
 }
 
 define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
+; CHECK-LABEL: @foo(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L_I:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false) [[ATTR4:#.*]], !noalias !3
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !0
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !alias.scope !5
+; CHECK-NEXT:    call void @hey() [[ATTR4]], !noalias !5
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !noalias !0
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    ret void
+;
 entry:
   tail call void @hello(i8* %a, i8* %c, i8* %b)
   ret void
 }
 
 define void @hello_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 {
+; CHECK-LABEL: @hello_cs(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    call void @hey()
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    ret void
+;
 entry:
   %l = alloca i8, i32 512, align 1
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 0)
@@ -34,46 +69,39 @@ entry:
 }
 
 define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
+; CHECK-LABEL: @foo_cs(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L_I:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META6:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META9:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !9
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !6
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !alias.scope !11
+; CHECK-NEXT:    call void @hey() [[ATTR4]], !noalias !11
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !noalias !6
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    ret void
+;
 entry:
   tail call void @hello_cs(i8* noalias %a, i8* noalias %c, i8* %b)
   ret void
 }
 
-; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b)
-; CHECK: entry:
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #4, !noalias !0
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 false) #4, !noalias !3
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 false) #4, !alias.scope !5
-; CHECK:   call void @hey() #4, !noalias !5
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %{{.*}}, i8* align 16 %c, i64 16, i1 false) #4, !noalias !3
-; CHECK:   ret void
-; CHECK: }
-
-; CHECK: define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b)
-; CHECK: entry:
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #4, !noalias !6
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 false) #4, !noalias !9
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 false) #4, !alias.scope !11
-; CHECK:   call void @hey() #4, !noalias !11
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %{{.*}}, i8* align 16 %c, i64 16, i1 false) #4, !noalias !9
-; CHECK:   ret void
-; CHECK: }
-
 attributes #0 = { nounwind argmemonly willreturn }
 attributes #1 = { nounwind alwaysinline }
 attributes #2 = { nounwind uwtable }
 
 ; CHECK: !0 = !{!1}
-; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
+; CHECK: !1 = distinct !{!1, !2, !"hello: %a"}
 ; CHECK: !2 = distinct !{!2, !"hello"}
 ; CHECK: !3 = !{!4}
-; CHECK: !4 = distinct !{!4, !2, !"hello: %a"}
-; CHECK: !5 = !{!4, !1}
+; CHECK: !4 = distinct !{!4, !2, !"hello: %c"}
+; CHECK: !5 = !{!1, !4}
 
 ; CHECK: !6 = !{!7}
-; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %c"}
+; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %a"}
 ; CHECK: !8 = distinct !{!8, !"hello_cs"}
 ; CHECK: !9 = !{!10}
-; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %a"}
-; CHECK: !11 = !{!10, !7}
-
+; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %c"}
+; CHECK: !11 = !{!7, !10}

diff  --git a/llvm/test/Transforms/Inline/noalias-calls.ll b/llvm/test/Transforms/Inline/noalias-calls.ll
index 8faed4dc58ac..4193b3eaf154 100644
--- a/llvm/test/Transforms/Inline/noalias-calls.ll
+++ b/llvm/test/Transforms/Inline/noalias-calls.ll
@@ -8,6 +8,17 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i
 declare void @hey() #0
 
 define void @hello(i8* noalias nocapture %a, i8* noalias nocapture readonly %c, i8* nocapture %b) #1 {
+; CHECK-LABEL: define {{[^@]+}}@hello
+; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* noalias nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR1:#.*]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    call void @hey()
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    ret void
+;
 entry:
   %l = alloca i8, i32 512, align 1
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 0)
@@ -19,12 +30,38 @@ entry:
 }
 
 define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
+; CHECK-LABEL: define {{[^@]+}}@foo
+; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR2:#.*]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L_I:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) [[ATTR2]], !noalias !3
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !0
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !alias.scope !5
+; CHECK-NEXT:    call void @hey() [[ATTR2]], !noalias !5
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !0
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    ret void
+;
 entry:
   tail call void @hello(i8* %a, i8* %c, i8* %b)
   ret void
 }
 
 define void @hello_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 {
+; CHECK-LABEL: define {{[^@]+}}@hello_cs
+; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR1]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    call void @hey()
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L]], i8* align 16 [[C]], i64 16, i1 false)
+; CHECK-NEXT:    ret void
+;
 entry:
   %l = alloca i8, i32 512, align 1
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 0)
@@ -36,46 +73,41 @@ entry:
 }
 
 define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
+; CHECK-LABEL: define {{[^@]+}}@foo_cs
+; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR2]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L_I:%.*]] = alloca i8, i32 512, align 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META6:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl([[META9:metadata !.*]])
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) [[ATTR2]], !noalias !9
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !6
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !alias.scope !11
+; CHECK-NEXT:    call void @hey() [[ATTR2]], !noalias !11
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !6
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]])
+; CHECK-NEXT:    ret void
+;
 entry:
   tail call void @hello_cs(i8* noalias %a, i8* noalias %c, i8* %b)
   ret void
 }
 
-; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
-; CHECK: entry:
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #2, !noalias !0
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 false) #2, !noalias !3
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 false) #2, !alias.scope !5
-; CHECK:   call void @hey() #2, !noalias !5
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %{{.*}}, i8* align 16 %c, i64 16, i1 false) #2, !noalias !3
-; CHECK:   ret void
-; CHECK: }
-
-; CHECK: define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 {
-; CHECK: entry:
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #2, !noalias !6
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 false) #2, !noalias !9
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 false) #2, !alias.scope !11
-; CHECK:   call void @hey() #2, !noalias !11
-; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %{{.*}}, i8* align 16 %c, i64 16, i1 false) #2, !noalias !9
-; CHECK:   ret void
-; CHECK: }
-
 attributes #0 = { argmemonly nofree nosync nounwind willreturn }
 attributes #1 = { argmemonly nounwind willreturn }
 attributes #2 = { nounwind }
 attributes #3 = { nounwind uwtable }
 
 ; CHECK: !0 = !{!1}
-; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
+; CHECK: !1 = distinct !{!1, !2, !"hello: %a"}
 ; CHECK: !2 = distinct !{!2, !"hello"}
 ; CHECK: !3 = !{!4}
-; CHECK: !4 = distinct !{!4, !2, !"hello: %a"}
-; CHECK: !5 = !{!4, !1}
+; CHECK: !4 = distinct !{!4, !2, !"hello: %c"}
+; CHECK: !5 = !{!1, !4}
 
 ; CHECK: !6 = !{!7}
-; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %c"}
+; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %a"}
 ; CHECK: !8 = distinct !{!8, !"hello_cs"}
 ; CHECK: !9 = !{!10}
-; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %a"}
-; CHECK: !11 = !{!10, !7}
+; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %c"}
+; CHECK: !11 = !{!7, !10}

diff  --git a/llvm/test/Transforms/Inline/noalias-calls2.ll b/llvm/test/Transforms/Inline/noalias-calls2.ll
new file mode 100644
index 000000000000..400bb1d6147c
--- /dev/null
+++ b/llvm/test/Transforms/Inline/noalias-calls2.ll
@@ -0,0 +1,166 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
+; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s
+; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @llvm.experimental.noalias.scope.decl(metadata) #0
+
+define void @caller_equals_callee(i32* noalias %p0, i32* noalias %p1, i32 %cnt) {
+; CHECK-LABEL: define {{[^@]+}}@caller_equals_callee
+; CHECK-SAME: (i32* noalias [[P0:%.*]], i32* noalias [[P1:%.*]], i32 [[CNT:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P0]], i64 2
+; CHECK-NEXT:    [[ADD_PTR1:%.*]] = getelementptr inbounds i32, i32* [[P1]], i64 2
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-NEXT:    store i32 10, i32* [[ADD_PTR]], align 4, !alias.scope !0, !noalias !3
+; CHECK-NEXT:    store i32 20, i32* [[ADD_PTR1]], align 4, !alias.scope !3, !noalias !0
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CNT]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    store i32 11, i32* [[P0]], align 4
+; CHECK-NEXT:    br label [[IF_END:%.*]]
+; CHECK:       if.else:
+; CHECK-NEXT:    [[ADD_PTR2:%.*]] = getelementptr inbounds i32, i32* [[P1]], i64 1
+; CHECK-NEXT:    [[ADD_PTR3:%.*]] = getelementptr inbounds i32, i32* [[P0]], i64 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !5)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !8)
+; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR2]], i64 2
+; CHECK-NEXT:    [[ADD_PTR1_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR3]], i64 2
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl(metadata !10), !noalias !13
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl(metadata !14), !noalias !13
+; CHECK-NEXT:    store i32 10, i32* [[ADD_PTR_I]], align 4, !alias.scope !16, !noalias !17
+; CHECK-NEXT:    store i32 20, i32* [[ADD_PTR1_I]], align 4, !alias.scope !17, !noalias !16
+; CHECK-NEXT:    store i32 11, i32* [[ADD_PTR2]], align 4, !alias.scope !5, !noalias !8
+; CHECK-NEXT:    store i32 12, i32* [[P1]], align 4
+; CHECK-NEXT:    br label [[IF_END]]
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %add.ptr = getelementptr inbounds i32, i32* %p0, i64 2
+  %add.ptr1 = getelementptr inbounds i32, i32* %p1, i64 2
+  tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
+  tail call void @llvm.experimental.noalias.scope.decl(metadata !3)
+  store i32 10, i32* %add.ptr, align 4, !alias.scope !0, !noalias !3
+  store i32 20, i32* %add.ptr1, align 4, !alias.scope !3, !noalias !0
+  %cmp = icmp eq i32 %cnt, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  store i32 11, i32* %p0, align 4
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  %add.ptr2 = getelementptr inbounds i32, i32* %p1, i64 1
+  %add.ptr3 = getelementptr inbounds i32, i32* %p0, i64 1
+  tail call void @caller_equals_callee(i32* nonnull %add.ptr2, i32* nonnull %add.ptr3, i32 0)
+  store i32 12, i32* %p1, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+define void @test01(i32* noalias %p0, i32* noalias %p1, i32 %cnt) {
+; CHECK-LABEL: define {{[^@]+}}@test01
+; CHECK-SAME: (i32* noalias [[P0:%.*]], i32* noalias [[P1:%.*]], i32 [[CNT:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    store i32 13, i32* [[P0]], align 4
+; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P0]], i64 1
+; CHECK-NEXT:    [[ADD_PTR1:%.*]] = getelementptr inbounds i32, i32* [[P1]], i64 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !18)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !21)
+; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR]], i64 2
+; CHECK-NEXT:    [[ADD_PTR1_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR1]], i64 2
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !23), !noalias !26
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !27), !noalias !26
+; CHECK-NEXT:    store i32 10, i32* [[ADD_PTR_I]], align 4, !alias.scope !29, !noalias !30
+; CHECK-NEXT:    store i32 20, i32* [[ADD_PTR1_I]], align 4, !alias.scope !30, !noalias !29
+; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[CNT]], 0
+; CHECK-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_ELSE_I:%.*]]
+; CHECK:       if.then.i:
+; CHECK-NEXT:    store i32 11, i32* [[ADD_PTR]], align 4, !alias.scope !18, !noalias !21
+; CHECK-NEXT:    br label [[CALLER_EQUALS_CALLEE_EXIT:%.*]]
+; CHECK:       if.else.i:
+; CHECK-NEXT:    [[ADD_PTR2_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR1]], i64 1
+; CHECK-NEXT:    [[ADD_PTR3_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR]], i64 1
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !31), !noalias !26
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !34), !noalias !26
+; CHECK-NEXT:    [[ADD_PTR_I_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR2_I]], i64 2
+; CHECK-NEXT:    [[ADD_PTR1_I_I:%.*]] = getelementptr inbounds i32, i32* [[ADD_PTR3_I]], i64 2
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !36), !noalias !39
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !40), !noalias !39
+; CHECK-NEXT:    store i32 10, i32* [[ADD_PTR_I_I]], align 4, !alias.scope !42, !noalias !43
+; CHECK-NEXT:    store i32 20, i32* [[ADD_PTR1_I_I]], align 4, !alias.scope !43, !noalias !42
+; CHECK-NEXT:    store i32 11, i32* [[ADD_PTR2_I]], align 4, !alias.scope !44, !noalias !45
+; CHECK-NEXT:    store i32 12, i32* [[ADD_PTR1]], align 4, !alias.scope !21, !noalias !18
+; CHECK-NEXT:    br label [[CALLER_EQUALS_CALLEE_EXIT]]
+; CHECK:       caller_equals_callee.exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  store i32 13, i32* %p0, align 4
+  %add.ptr = getelementptr inbounds i32, i32* %p0, i64 1
+  %add.ptr1 = getelementptr inbounds i32, i32* %p1, i64 1
+  call void @caller_equals_callee(i32* nonnull %add.ptr, i32* nonnull %add.ptr1, i32 %cnt)
+  ret void
+}
+
+attributes #0 = { inaccessiblememonly nofree nosync nounwind willreturn }
+
+!0 = !{!1}
+!1 = distinct !{!1, !2, !"do_store: %p0"}
+!2 = distinct !{!2, !"do_store"}
+!3 = !{!4}
+!4 = distinct !{!4, !2, !"do_store: %p1"}
+
+; CHECK: !0 = !{!1}
+; CHECK: !1 = distinct !{!1, !2, !"do_store: %p0"}
+; CHECK: !2 = distinct !{!2, !"do_store"}
+; CHECK: !3 = !{!4}
+; CHECK: !4 = distinct !{!4, !2, !"do_store: %p1"}
+; CHECK: !5 = !{!6}
+; CHECK: !6 = distinct !{!6, !7, !"caller_equals_callee: %p0"}
+; CHECK: !7 = distinct !{!7, !"caller_equals_callee"}
+; CHECK: !8 = !{!9}
+; CHECK: !9 = distinct !{!9, !7, !"caller_equals_callee: %p1"}
+; CHECK: !10 = !{!11}
+; CHECK: !11 = distinct !{!11, !12, !"do_store: %p0"}
+; CHECK: !12 = distinct !{!12, !"do_store"}
+; CHECK: !13 = !{!6, !9}
+; CHECK: !14 = !{!15}
+; CHECK: !15 = distinct !{!15, !12, !"do_store: %p1"}
+; CHECK: !16 = !{!11, !6}
+; CHECK: !17 = !{!15, !9}
+
+; CHECK: !18 = !{!19}
+; CHECK: !19 = distinct !{!19, !20, !"caller_equals_callee: %p0"}
+; CHECK: !20 = distinct !{!20, !"caller_equals_callee"}
+; CHECK: !21 = !{!22}
+; CHECK: !22 = distinct !{!22, !20, !"caller_equals_callee: %p1"}
+; CHECK: !23 = !{!24}
+; CHECK: !24 = distinct !{!24, !25, !"do_store: %p0"}
+; CHECK: !25 = distinct !{!25, !"do_store"}
+; CHECK: !26 = !{!19, !22}
+; CHECK: !27 = !{!28}
+; CHECK: !28 = distinct !{!28, !25, !"do_store: %p1"}
+; CHECK: !29 = !{!24, !19}
+; CHECK: !30 = !{!28, !22}
+; CHECK: !31 = !{!32}
+; CHECK: !32 = distinct !{!32, !33, !"caller_equals_callee: %p0"}
+; CHECK: !33 = distinct !{!33, !"caller_equals_callee"}
+; CHECK: !34 = !{!35}
+; CHECK: !35 = distinct !{!35, !33, !"caller_equals_callee: %p1"}
+; CHECK: !36 = !{!37}
+; CHECK: !37 = distinct !{!37, !38, !"do_store: %p0"}
+; CHECK: !38 = distinct !{!38, !"do_store"}
+; CHECK: !39 = !{!32, !35, !19, !22}
+; CHECK: !40 = !{!41}
+; CHECK: !41 = distinct !{!41, !38, !"do_store: %p1"}
+; CHECK: !42 = !{!37, !32, !22}
+; CHECK: !43 = !{!41, !35, !19}
+; CHECK: !44 = !{!32, !22}
+; CHECK: !45 = !{!35, !19}

diff  --git a/llvm/test/Transforms/Inline/noalias-cs.ll b/llvm/test/Transforms/Inline/noalias-cs.ll
index a8cbf80d5ff2..cc3d719b1cb3 100644
--- a/llvm/test/Transforms/Inline/noalias-cs.ll
+++ b/llvm/test/Transforms/Inline/noalias-cs.ll
@@ -5,7 +5,23 @@ target triple = "x86_64-unknown-linux-gnu"
 
 ; This callee uses scoped alias metadata internally itself.
 define void @callee_with_metadata(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
+; CHECK-LABEL: @callee_with_metadata(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4, !noalias !5
+; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !0, !noalias !3
+; CHECK-NEXT:    [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 8
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !3, !noalias !0
+; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
+; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX]], align 4
+; CHECK-NEXT:    ret void
+;
 entry:
+  call void @llvm.experimental.noalias.scope.decl(metadata !7)
+  call void @llvm.experimental.noalias.scope.decl(metadata !8)
   %0 = load float, float* %c, align 4, !noalias !3
   %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
   store float %0, float* %arrayidx.i, align 4, !alias.scope !7, !noalias !8
@@ -17,8 +33,22 @@ entry:
   ret void
 }
 
+declare void @llvm.experimental.noalias.scope.decl(metadata);
+
 ; This callee does not make use of scoped alias metadata itself.
 define void @callee_without_metadata(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
+; CHECK-LABEL: @callee_without_metadata(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4
+; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I]], align 4
+; CHECK-NEXT:    [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 8
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX1_I]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
+; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX]], align 4
+; CHECK-NEXT:    ret void
+;
 entry:
   %0 = load float, float* %c, align 4
   %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
@@ -35,19 +65,23 @@ define void @caller(float* nocapture %a, float* nocapture %b, float** nocapture
 ; CHECK-LABEL: @caller(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[C:%.*]] = load float*, float** [[C_PTR:%.*]], align 8, !alias.scope !6
-; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !noalias !9
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !9) [[ATTR2:#.*]], !noalias !6
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !12) [[ATTR2]], !noalias !6
+; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !noalias !14
 ; CHECK-NEXT:    [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5
-; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !13, !noalias !14
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !9, !noalias !15
 ; CHECK-NEXT:    [[ARRAYIDX1_I_I:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 8
-; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX1_I_I]], align 4, !alias.scope !15, !noalias !16
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX1_I_I]], align 4, !alias.scope !12, !noalias !16
 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4, !noalias !6
 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
 ; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !noalias !6
-; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[A]], align 4, !alias.scope !6, !noalias !17
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !17) [[ATTR2]], !alias.scope !6
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !20) [[ATTR2]], !alias.scope !6
+; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[A]], align 4, !alias.scope !6, !noalias !22
 ; CHECK-NEXT:    [[ARRAYIDX_I_I7:%.*]] = getelementptr inbounds float, float* [[B]], i64 5
-; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX_I_I7]], align 4, !alias.scope !21, !noalias !22
+; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX_I_I7]], align 4, !alias.scope !23, !noalias !20
 ; CHECK-NEXT:    [[ARRAYIDX1_I_I8:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
-; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX1_I_I8]], align 4, !alias.scope !23, !noalias !24
+; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX1_I_I8]], align 4, !alias.scope !24, !noalias !17
 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, float* [[A]], align 4, !alias.scope !6
 ; CHECK-NEXT:    [[ARRAYIDX_I9:%.*]] = getelementptr inbounds float, float* [[B]], i64 7
 ; CHECK-NEXT:    store float [[TMP3]], float* [[ARRAYIDX_I9]], align 4, !alias.scope !6
@@ -90,28 +124,28 @@ attributes #0 = { nounwind uwtable }
 !7 = !{!4}
 !8 = !{!6}
 
-; CHECK: !0 = !{!1, !3}
+; CHECK: !0 = !{!1}
 ; CHECK: !1 = distinct !{!1, !2, !"hello2: %a"}
 ; CHECK: !2 = distinct !{!2, !"hello2"}
-; CHECK: !3 = distinct !{!3, !2, !"hello2: %b"}
-; CHECK: !4 = !{!1}
-; CHECK: !5 = !{!3}
+; CHECK: !3 = !{!4}
+; CHECK: !4 = distinct !{!4, !2, !"hello2: %b"}
+; CHECK: !5 = !{!1, !4}
 ; CHECK: !6 = !{!7}
 ; CHECK: !7 = distinct !{!7, !8, !"hello: %a"}
 ; CHECK: !8 = distinct !{!8, !"hello"}
-; CHECK: !9 = !{!10, !12, !7}
+; CHECK: !9 = !{!10}
 ; CHECK: !10 = distinct !{!10, !11, !"hello2: %a"}
 ; CHECK: !11 = distinct !{!11, !"hello2"}
-; CHECK: !12 = distinct !{!12, !11, !"hello2: %b"}
-; CHECK: !13 = !{!10}
-; CHECK: !14 = !{!12, !7}
-; CHECK: !15 = !{!12}
+; CHECK: !12 = !{!13}
+; CHECK: !13 = distinct !{!13, !11, !"hello2: %b"}
+; CHECK: !14 = !{!10, !13, !7}
+; CHECK: !15 = !{!13, !7}
 ; CHECK: !16 = !{!10, !7}
-; CHECK: !17 = !{!18, !20}
+; CHECK: !17 = !{!18}
 ; CHECK: !18 = distinct !{!18, !19, !"hello2: %a"}
 ; CHECK: !19 = distinct !{!19, !"hello2"}
-; CHECK: !20 = distinct !{!20, !19, !"hello2: %b"}
-; CHECK: !21 = !{!18, !7}
-; CHECK: !22 = !{!20}
-; CHECK: !23 = !{!20, !7}
-; CHECK: !24 = !{!18}
+; CHECK: !20 = !{!21}
+; CHECK: !21 = distinct !{!21, !19, !"hello2: %b"}
+; CHECK: !22 = !{!18, !21}
+; CHECK: !23 = !{!18, !7}
+; CHECK: !24 = !{!21, !7}

diff  --git a/llvm/test/Transforms/Inline/noalias.ll b/llvm/test/Transforms/Inline/noalias.ll
index 27e53afc2a75..11e843f8e6ee 100644
--- a/llvm/test/Transforms/Inline/noalias.ll
+++ b/llvm/test/Transforms/Inline/noalias.ll
@@ -19,14 +19,15 @@ entry:
   ret void
 }
 
-; CHECK: define void @foo(float* nocapture %a, float* nocapture readonly %c) #0 {
+; CHECK-LABEL: define void @foo(float* nocapture %a, float* nocapture readonly %c) #0 {
 ; CHECK: entry:
-; CHECK:   %0 = load float, float* %c, align 4, !noalias !0
+; CHECK:   call void @llvm.experimental.noalias.scope.decl
+; CHECK:   [[TMP0:%.+]] = load float, float* %c, align 4, !noalias !0
 ; CHECK:   %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
-; CHECK:   store float %0, float* %arrayidx.i, align 4, !alias.scope !0
-; CHECK:   %1 = load float, float* %c, align 4
+; CHECK:   store float [[TMP0]], float* %arrayidx.i, align 4, !alias.scope !0
+; CHECK:   [[TMP1:%.+]] = load float, float* %c, align 4
 ; CHECK:   %arrayidx = getelementptr inbounds float, float* %a, i64 7
-; CHECK:   store float %1, float* %arrayidx, align 4
+; CHECK:   store float [[TMP1]], float* %arrayidx, align 4
 ; CHECK:   ret void
 ; CHECK: }
 
@@ -49,16 +50,18 @@ entry:
   ret void
 }
 
-; CHECK: define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
+; CHECK-LABEL: define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
 ; CHECK: entry:
-; CHECK:   %0 = load float, float* %c, align 4, !noalias !3
+; CHECK:   call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK:   call void @llvm.experimental.noalias.scope.decl(metadata !6)
+; CHECK:   [[TMP0:%.+]] = load float, float* %c, align 4, !noalias !8
 ; CHECK:   %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
-; CHECK:   store float %0, float* %arrayidx.i, align 4, !alias.scope !7, !noalias !8
+; CHECK:   store float [[TMP0]], float* %arrayidx.i, align 4, !alias.scope !3, !noalias !6
 ; CHECK:   %arrayidx1.i = getelementptr inbounds float, float* %b, i64 8
-; CHECK:   store float %0, float* %arrayidx1.i, align 4, !alias.scope !8, !noalias !7
-; CHECK:   %1 = load float, float* %c, align 4
+; CHECK:   store float [[TMP0]], float* %arrayidx1.i, align 4, !alias.scope !6, !noalias !3
+; CHECK:   [[TMP1:%.+]] = load float, float* %c, align 4
 ; CHECK:   %arrayidx = getelementptr inbounds float, float* %a, i64 7
-; CHECK:   store float %1, float* %arrayidx, align 4
+; CHECK:   store float [[TMP1]], float* %arrayidx, align 4
 ; CHECK:   ret void
 ; CHECK: }
 
@@ -67,10 +70,9 @@ attributes #0 = { nounwind uwtable }
 ; CHECK: !0 = !{!1}
 ; CHECK: !1 = distinct !{!1, !2, !"hello: %a"}
 ; CHECK: !2 = distinct !{!2, !"hello"}
-; CHECK: !3 = !{!4, !6}
+; CHECK: !3 = !{!4}
 ; CHECK: !4 = distinct !{!4, !5, !"hello2: %a"}
 ; CHECK: !5 = distinct !{!5, !"hello2"}
-; CHECK: !6 = distinct !{!6, !5, !"hello2: %b"}
-; CHECK: !7 = !{!4}
-; CHECK: !8 = !{!6}
-
+; CHECK: !6 = !{!7}
+; CHECK: !7 = distinct !{!7, !5, !"hello2: %b"}
+; CHECK: !8 = !{!4, !7}

diff  --git a/llvm/test/Transforms/Inline/noalias2.ll b/llvm/test/Transforms/Inline/noalias2.ll
index 8732cb538730..c2c743605699 100644
--- a/llvm/test/Transforms/Inline/noalias2.ll
+++ b/llvm/test/Transforms/Inline/noalias2.ll
@@ -25,9 +25,11 @@ define void @foo(float* noalias nocapture %a, float* noalias nocapture readonly
 ; CHECK-LABEL: define {{[^@]+}}@foo
 ; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) [[ATTR0]] {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !0, !noalias !3
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !0)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !3)
+; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !3, !noalias !0
 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
-; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !3, !noalias !0
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !0, !noalias !3
 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4
 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
 ; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX]], align 4
@@ -67,17 +69,23 @@ define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture rea
 ; CHECK-LABEL: define {{[^@]+}}@foo2
 ; CHECK-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) [[ATTR0]] {
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !5, !noalias !10
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !5)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !8)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !10) [[ATTR2:#.*]], !noalias !13
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !14) [[ATTR2]], !noalias !13
+; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !16, !noalias !17
 ; CHECK-NEXT:    [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
-; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !10, !noalias !5
-; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !13, !noalias !14
+; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !17, !noalias !16
+; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !8, !noalias !5
 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
-; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !14, !noalias !13
-; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !15
+; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !5, !noalias !8
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !18)
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !21)
+; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !23
 ; CHECK-NEXT:    [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6
-; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !19, !noalias !20
+; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !18, !noalias !21
 ; CHECK-NEXT:    [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
-; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !20, !noalias !19
+; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !21, !noalias !18
 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, float* [[C]], align 4
 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
 ; CHECK-NEXT:    store float [[TMP3]], float* [[ARRAYIDX]], align 4
@@ -93,26 +101,29 @@ entry:
 }
 
 ; CHECK: !0 = !{!1}
-; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
+; CHECK: !1 = distinct !{!1, !2, !"hello: %a"}
 ; CHECK: !2 = distinct !{!2, !"hello"}
 ; CHECK: !3 = !{!4}
-; CHECK: !4 = distinct !{!4, !2, !"hello: %a"}
-; CHECK: !5 = !{!6, !8}
-; CHECK: !6 = distinct !{!6, !7, !"hello: %c"}
-; CHECK: !7 = distinct !{!7, !"hello"}
-; CHECK: !8 = distinct !{!8, !9, !"foo: %c"}
-; CHECK: !9 = distinct !{!9, !"foo"}
-; CHECK: !10 = !{!11, !12}
-; CHECK: !11 = distinct !{!11, !7, !"hello: %a"}
-; CHECK: !12 = distinct !{!12, !9, !"foo: %a"}
-; CHECK: !13 = !{!8}
-; CHECK: !14 = !{!12}
-; CHECK: !15 = !{!16, !18}
-; CHECK: !16 = distinct !{!16, !17, !"hello2: %a"}
-; CHECK: !17 = distinct !{!17, !"hello2"}
-; CHECK: !18 = distinct !{!18, !17, !"hello2: %b"}
-; CHECK: !19 = !{!16}
-; CHECK: !20 = !{!18}
+; CHECK: !4 = distinct !{!4, !2, !"hello: %c"}
+; CHECK: !5 = !{!6}
+; CHECK: !6 = distinct !{!6, !7, !"foo: %a"}
+; CHECK: !7 = distinct !{!7, !"foo"}
+; CHECK: !8 = !{!9}
+; CHECK: !9 = distinct !{!9, !7, !"foo: %c"}
+; CHECK: !10 = !{!11}
+; CHECK: !11 = distinct !{!11, !12, !"hello: %a"}
+; CHECK: !12 = distinct !{!12, !"hello"}
+; CHECK: !13 = !{!6, !9}
+; CHECK: !14 = !{!15}
+; CHECK: !15 = distinct !{!15, !12, !"hello: %c"}
+; CHECK: !16 = !{!15, !9}
+; CHECK: !17 = !{!11, !6}
+; CHECK: !18 = !{!19}
+; CHECK: !19 = distinct !{!19, !20, !"hello2: %a"}
+; CHECK: !20 = distinct !{!20, !"hello2"}
+; CHECK: !21 = !{!22}
+; CHECK: !22 = distinct !{!22, !20, !"hello2: %b"}
+; CHECK: !23 = !{!19, !22}
 
 attributes #0 = { nounwind uwtable }
 

diff  --git a/llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll b/llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
index 4fe75883959e..9e96ba081bac 100644
--- a/llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
+++ b/llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
@@ -95,6 +95,7 @@ define internal void @callee2(i64* noalias sret(i64) align 32 %arg) {
 
 define amdgpu_kernel void @caller2() {
 ; CHECK-LABEL: @caller2(
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]])
 ; CHECK-NEXT:    ret void
 ;
   %alloca = alloca i64, align 8, addrspace(5)

diff  --git a/llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll b/llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll
index 9052fd5a03e4..2ce1c49e04c4 100644
--- a/llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll
+++ b/llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll
@@ -70,6 +70,7 @@ define dso_local i32* @_Z3foo1S(%0* byval(%0) align 8 %arg) {
 ; CHECK-NEXT:    [[I2:%.*]] = alloca [[TMP0:%.*]], align 8
 ; CHECK-NEXT:    [[I1_SROA_0_0_I5_SROA_IDX:%.*]] = getelementptr inbounds [[TMP0]], %0* [[ARG:%.*]], i64 0, i32 0
 ; CHECK-NEXT:    [[I1_SROA_0_0_COPYLOAD:%.*]] = load i32*, i32** [[I1_SROA_0_0_I5_SROA_IDX]], align 8
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]])
 ; CHECK-NEXT:    [[I_SROA_0_0_I6_SROA_IDX:%.*]] = getelementptr inbounds [[TMP0]], %0* [[I2]], i64 0, i32 0
 ; CHECK-NEXT:    store i32* [[I1_SROA_0_0_COPYLOAD]], i32** [[I_SROA_0_0_I6_SROA_IDX]], align 8
 ; CHECK-NEXT:    tail call void @_Z7escape01S(%0* nonnull byval(%0) align 8 [[I2]])
@@ -109,6 +110,7 @@ define dso_local i32* @_Z3bar1S(%0* byval(%0) align 8 %arg) {
 ; CHECK-NEXT:  bb:
 ; CHECK-NEXT:    [[I1_SROA_0_0_I4_SROA_IDX:%.*]] = getelementptr inbounds [[TMP0:%.*]], %0* [[ARG:%.*]], i64 0, i32 0
 ; CHECK-NEXT:    [[I1_SROA_0_0_COPYLOAD:%.*]] = load i32*, i32** [[I1_SROA_0_0_I4_SROA_IDX]], align 8
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]])
 ; CHECK-NEXT:    [[I5:%.*]] = tail call i32 @_Z4condv()
 ; CHECK-NEXT:    [[I6_NOT:%.*]] = icmp eq i32 [[I5]], 0
 ; CHECK-NEXT:    br i1 [[I6_NOT]], label [[BB10:%.*]], label [[BB7:%.*]]

diff  --git a/llvm/test/Transforms/PhaseOrdering/pr39282.ll b/llvm/test/Transforms/PhaseOrdering/pr39282.ll
index 0574b4b83bdf..5d89166c283a 100644
--- a/llvm/test/Transforms/PhaseOrdering/pr39282.ll
+++ b/llvm/test/Transforms/PhaseOrdering/pr39282.ll
@@ -19,12 +19,20 @@ define void @copy(i32* noalias %to, i32* noalias %from) {
 define void @pr39282(i32* %addr1, i32* %addr2) {
 ; CHECK-LABEL: @pr39282(
 ; CHECK-NEXT:  start:
-; CHECK-NEXT:    [[X_I:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !0, !noalias !3
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]])
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]])
+; CHECK-NEXT:    [[X_I:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !3, !noalias !0
 ; CHECK-NEXT:    [[ADDR1I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i64 1
 ; CHECK-NEXT:    [[ADDR2I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR2:%.*]], i64 1
-; CHECK-NEXT:    [[X_I_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !0, !noalias !3
-; CHECK-NEXT:    store i32 [[X_I]], i32* [[ADDR2]], align 4, !alias.scope !3, !noalias !0
-; CHECK-NEXT:    store i32 [[X_I_1]], i32* [[ADDR2I_1]], align 4, !alias.scope !3, !noalias !0
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META0]])
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META3]])
+; CHECK-NEXT:    [[X_I_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !3, !noalias !0
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META0]])
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META3]])
+; CHECK-NEXT:    store i32 [[X_I]], i32* [[ADDR2]], align 4, !alias.scope !0, !noalias !3
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META0]])
+; CHECK-NEXT:    tail call void @llvm.experimental.noalias.scope.decl([[META3]])
+; CHECK-NEXT:    store i32 [[X_I_1]], i32* [[ADDR2I_1]], align 4, !alias.scope !0, !noalias !3
 ; CHECK-NEXT:    ret void
 ;
 start:


        


More information about the cfe-commits mailing list