[llvm] update_analyze_test_checks: support output from LAA (PR #67584)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 27 11:10:42 PDT 2023


https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/67584

update_analyze_test_checks.py is an invaluable tool in updating tests. Unfortunately, it only supports output from the CostModel, ScalarEvolution, and LoopVectorize analyses. Many LoopAccessAnalysis tests use hand-crafted CHECK lines, and it is moreover tedious to generate these CHECK lines, as the output fom the analysis is not stable, and requires the test-writer to hand-craft FileCheck matches. Alleviate this pain, and support output from:

```
  $ opt -passes='print<loop-accesses>'
```

This patch includes several non-trivial changes including:

- Preserving whitespace at the beginning of the line, so that the LAA output can be properly indented.
- Regexes matching the unstable output, which is basically a pointer address hex.

To demonstate the utility of this patch, several tests in LoopAccessAnalysis have been auto-generated by
update_analyze_test_checks.py.

>From c34b817b121bf95ca1d7173f308d9be192fe9d51 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <Ramkumar.Ramachandra at imgtec.com>
Date: Mon, 25 Sep 2023 12:58:23 +0100
Subject: [PATCH] update_analyze_test_checks: support output from LAA

update_analyze_test_checks.py is an invaluable tool in updating tests.
Unfortunately, it only supports output from the CostModel,
ScalarEvolution, and LoopVectorize analyses. Many LoopAccessAnalysis
tests use hand-crafted CHECK lines, and it is moreover tedious to
generate these CHECK lines, as the output fom the analysis is not
stable, and requires the test-writer to hand-craft FileCheck matches.
Alleviate this pain, and support output from:

  $ opt -passes='print<loop-accesses>'

This patch includes several non-trivial changes including:

- Preserving whitespace at the beginning of the line, so that the LAA
  output can be properly indented.
- Regexes matching the unstable output, which is basically a pointer
  address hex.

To demonstate the utility of this patch, several tests in
LoopAccessAnalysis have been auto-generated by
update_analyze_test_checks.py.
---
 .../Scalar/LoopAccessAnalysisPrinter.cpp      |    3 +-
 .../LoopAccessAnalysis/forked-pointers.ll     | 1380 +++++++++++------
 ...invariant-dep-with-backedge-taken-count.ll |  160 +-
 .../max_safe_dep_dist_non_unit_stride.ll      |   28 +-
 .../LoopAccessAnalysis/pointer-phis.ll        |  412 ++---
 .../LoopAccessAnalysis/symbolic-stride.ll     |  120 +-
 .../LoopUnroll/unroll-loop-invalidation.ll    |    2 +-
 .../Inputs/dotvariable-laa.ll                 |   23 +
 .../Inputs/dotvariable-laa.ll.expected        |   62 +
 .../Inputs/loop-access-analysis.ll            |   23 +
 .../Inputs/loop-access-analysis.ll.expected   |   56 +
 .../dotvariable-laa.test                      |    6 +
 .../loop-access-analysis.test                 |    6 +
 llvm/utils/UpdateTestChecks/common.py         |   72 +-
 llvm/utils/update_analyze_test_checks.py      |    4 -
 15 files changed, 1497 insertions(+), 860 deletions(-)
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll.expected
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/dotvariable-laa.test
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-access-analysis.test

diff --git a/llvm/lib/Transforms/Scalar/LoopAccessAnalysisPrinter.cpp b/llvm/lib/Transforms/Scalar/LoopAccessAnalysisPrinter.cpp
index 9ae55b9018dad34..3d3f22d686e32ed 100644
--- a/llvm/lib/Transforms/Scalar/LoopAccessAnalysisPrinter.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopAccessAnalysisPrinter.cpp
@@ -20,7 +20,8 @@ PreservedAnalyses LoopAccessInfoPrinterPass::run(Function &F,
                                                  FunctionAnalysisManager &AM) {
   auto &LAIs = AM.getResult<LoopAccessAnalysis>(F);
   auto &LI = AM.getResult<LoopAnalysis>(F);
-  OS << "Loop access info in function '" << F.getName() << "':\n";
+  OS << "Printing analysis 'Loop Access Analysis' for function '" << F.getName()
+     << "':\n";
 
   SmallPriorityWorklist<Loop *, 4> Worklist;
   appendLoopsToWorklist(LI, Worklist);
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
index 30ffc4cb5e1e85f..51a11809cf4e333 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
@@ -1,43 +1,74 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
 ; RUN: opt -disable-output -passes='print<access-info>' %s 2>&1 | FileCheck %s
 ; RUN: opt -disable-output -passes='print<access-info>' -max-forked-scev-depth=2 %s 2>&1 | FileCheck -check-prefix=RECURSE %s
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 
-; CHECK-LABEL: function 'forked_ptrs_simple':
-; CHECK-NEXT:  loop:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT:        %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT:        %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]
-; CHECK-NEXT:        (Low: %Dest High: (400 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%loop>
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%loop>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Base1 High: (400 + %Base1))
-; CHECK-NEXT:          Member: {%Base1,+,4}<nw><%loop>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %Base2 High: (400 + %Base2))
-; CHECK-NEXT:          Member: {%Base2,+,4}<nw><%loop>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define void @forked_ptrs_simple(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr %Dest) {
+; CHECK-LABEL: 'forked_ptrs_simple'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP1]]):
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP3:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP1]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%loop>
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%loop>
+; CHECK-NEXT:        Group [[GRP2]]:
+; CHECK-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,4}<nw><%loop>
+; CHECK-NEXT:        Group [[GRP3]]:
+; CHECK-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,4}<nw><%loop>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_simple'
+; RECURSE-NEXT:    loop:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP4:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; RECURSE-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; RECURSE-NEXT:        Against group ([[GRP5:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP4]]):
+; RECURSE-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; RECURSE-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; RECURSE-NEXT:        Against group ([[GRP6:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP4]]:
+; RECURSE-NEXT:          (Low: %Dest High: (400 + %Dest))
+; RECURSE-NEXT:            Member: {%Dest,+,4}<nuw><%loop>
+; RECURSE-NEXT:            Member: {%Dest,+,4}<nuw><%loop>
+; RECURSE-NEXT:        Group [[GRP5]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; RECURSE-NEXT:            Member: {%Base1,+,4}<nw><%loop>
+; RECURSE-NEXT:        Group [[GRP6]]:
+; RECURSE-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,4}<nw><%loop>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %loop
 
@@ -59,59 +90,9 @@ exit:
   ret void
 }
 
-; CHECK-LABEL: function 'forked_ptrs_different_base_same_offset':
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (400 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %Base2 High: (400 + %Base2))
-; CHECK-NEXT:          Member: {%Base2,+,4}<nw><%for.body>
-; CHECK-NEXT:      Group [[G4]]:
-; CHECK-NEXT:        (Low: %Base1 High: (400 + %Base1))
-; CHECK-NEXT:          Member: {%Base1,+,4}<nw><%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:   Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:   SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:   Expressions re-written:
-
 ;; We have a limit on the recursion depth for finding a loop invariant or
 ;; addrec term; confirm we won't exceed that depth by forcing a lower
 ;; limit via -max-forked-scev-depth=2
-; RECURSE-LABEL: Loop access info in function 'forked_ptrs_same_base_different_offset':
-; RECURSE-NEXT:   for.body:
-; RECURSE-NEXT:     Report: cannot identify array bounds
-; RECURSE-NEXT:     Dependences:
-; RECURSE-NEXT:     Run-time memory checks:
-; RECURSE-NEXT:     Grouped accesses:
-; RECURSE-EMPTY:
-; RECURSE-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; RECURSE-NEXT:     SCEV assumptions:
-; RECURSE-EMPTY:
-; RECURSE-NEXT:     Expressions re-written:
 
 ;;;; Derived from the following C code
 ;; void forked_ptrs_different_base_same_offset(float *A, float *B, float *C, int *D) {
@@ -125,6 +106,80 @@ exit:
 ;; }
 
 define dso_local void @forked_ptrs_different_base_same_offset(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_different_base_same_offset'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP7:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP8:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP7]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP9:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP7]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP10:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP7]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP8]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP9]]:
+; CHECK-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,4}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP10]]:
+; CHECK-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,4}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP11:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP12:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP11]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP13:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Check 2:
+; RECURSE-NEXT:        Comparing group ([[GRP11]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP14:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP11]]:
+; RECURSE-NEXT:          (Low: %Dest High: (400 + %Dest))
+; RECURSE-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP12]]:
+; RECURSE-NEXT:          (Low: %Preds High: (400 + %Preds))
+; RECURSE-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP13]]:
+; RECURSE-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,4}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP14]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; RECURSE-NEXT:            Member: {%Base1,+,4}<nw><%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -146,46 +201,81 @@ for.body:
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_different_base_same_offset_64b':
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (800 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,8}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %Base2 High: (800 + %Base2))
-; CHECK-NEXT:          Member: {%Base2,+,8}<nw><%for.body>
-; CHECK-NEXT:      Group [[G4]]:
-; CHECK-NEXT:        (Low: %Base1 High: (800 + %Base1))
-; CHECK-NEXT:          Member: {%Base1,+,8}<nw><%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_different_base_same_offset_64b(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_64b'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP15:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP16:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP15]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP17:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP15]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP18:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP15]]:
+; CHECK-NEXT:          (Low: %Dest High: (800 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,8}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP16]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP17]]:
+; CHECK-NEXT:          (Low: %Base2 High: (800 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,8}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP18]]:
+; CHECK-NEXT:          (Low: %Base1 High: (800 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,8}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_64b'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP19:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP20:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP19]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP21:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Check 2:
+; RECURSE-NEXT:        Comparing group ([[GRP19]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP22:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP19]]:
+; RECURSE-NEXT:          (Low: %Dest High: (800 + %Dest))
+; RECURSE-NEXT:            Member: {%Dest,+,8}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP20]]:
+; RECURSE-NEXT:          (Low: %Preds High: (400 + %Preds))
+; RECURSE-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP21]]:
+; RECURSE-NEXT:          (Low: %Base2 High: (800 + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,8}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP22]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (800 + %Base1))
+; RECURSE-NEXT:            Member: {%Base1,+,8}<nw><%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -207,46 +297,81 @@ for.body:
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_different_base_same_offset_23b':
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (399 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %Base2 High: (399 + %Base2))
-; CHECK-NEXT:          Member: {%Base2,+,4}<nw><%for.body>
-; CHECK-NEXT:      Group [[G4]]:
-; CHECK-NEXT:        (Low: %Base1 High: (399 + %Base1))
-; CHECK-NEXT:          Member: {%Base1,+,4}<nw><%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_different_base_same_offset_23b(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_23b'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP23:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP24:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP23]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP25:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP23]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP26:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP23]]:
+; CHECK-NEXT:          (Low: %Dest High: (399 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP24]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP25]]:
+; CHECK-NEXT:          (Low: %Base2 High: (399 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,4}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP26]]:
+; CHECK-NEXT:          (Low: %Base1 High: (399 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,4}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_23b'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP27:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP28:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP27]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP29:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Check 2:
+; RECURSE-NEXT:        Comparing group ([[GRP27]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP30:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP27]]:
+; RECURSE-NEXT:          (Low: %Dest High: (399 + %Dest))
+; RECURSE-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP28]]:
+; RECURSE-NEXT:          (Low: %Preds High: (400 + %Preds))
+; RECURSE-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP29]]:
+; RECURSE-NEXT:          (Low: %Base2 High: (399 + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,4}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP30]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (399 + %Base1))
+; RECURSE-NEXT:            Member: {%Base1,+,4}<nw><%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -268,46 +393,81 @@ for.body:
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_different_base_same_offset_6b':
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (100 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,1}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %Base2 High: (100 + %Base2))
-; CHECK-NEXT:          Member: {%Base2,+,1}<nw><%for.body>
-; CHECK-NEXT:      Group [[G4]]:
-; CHECK-NEXT:        (Low: %Base1 High: (100 + %Base1))
-; CHECK-NEXT:          Member: {%Base1,+,1}<nw><%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_different_base_same_offset_6b(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_6b'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP31:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP32:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP31]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP33:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP31]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP34:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP31]]:
+; CHECK-NEXT:          (Low: %Dest High: (100 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,1}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP32]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP33]]:
+; CHECK-NEXT:          (Low: %Base2 High: (100 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,1}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP34]]:
+; CHECK-NEXT:          (Low: %Base1 High: (100 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,1}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_6b'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP35:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP36:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP35]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP37:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Check 2:
+; RECURSE-NEXT:        Comparing group ([[GRP35]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP38:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP35]]:
+; RECURSE-NEXT:          (Low: %Dest High: (100 + %Dest))
+; RECURSE-NEXT:            Member: {%Dest,+,1}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP36]]:
+; RECURSE-NEXT:          (Low: %Preds High: (400 + %Preds))
+; RECURSE-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP37]]:
+; RECURSE-NEXT:          (Low: %Base2 High: (100 + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,1}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP38]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (100 + %Base1))
+; RECURSE-NEXT:            Member: {%Base1,+,1}<nw><%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -329,46 +489,81 @@ for.body:
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_different_base_same_offset_possible_poison':
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4:.+]]):
-; CHECK-NEXT:        %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (400 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %Base2 High: (400 + %Base2))
-; CHECK-NEXT:          Member: {%Base2,+,4}<nw><%for.body>
-; CHECK-NEXT:      Group [[G4]]:
-; CHECK-NEXT:        (Low: %Base1 High: (400 + %Base1))
-; CHECK-NEXT:          Member: {%Base1,+,4}<nw><%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:   Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:   SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:   Expressions re-written:
-
 define dso_local void @forked_ptrs_different_base_same_offset_possible_poison(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds, i1 %c) {
+; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_possible_poison'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP39:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP40:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP39]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP41:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP39]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP42:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP39]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP40]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP41]]:
+; CHECK-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,4}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP42]]:
+; CHECK-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,4}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_possible_poison'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP43:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP44:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP43]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP45:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Check 2:
+; RECURSE-NEXT:        Comparing group ([[GRP43]]):
+; RECURSE-NEXT:          %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP46:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP43]]:
+; RECURSE-NEXT:          (Low: %Dest High: (400 + %Dest))
+; RECURSE-NEXT:            Member: {%Dest,+,4}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP44]]:
+; RECURSE-NEXT:          (Low: %Preds High: (400 + %Preds))
+; RECURSE-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP45]]:
+; RECURSE-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,4}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP46]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; RECURSE-NEXT:            Member: {%Base1,+,4}<nw><%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -396,18 +591,6 @@ latch:
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_same_base_different_offset':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:     Report: cannot identify array bounds
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:     SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Expressions re-written:
-
 ;;;; Derived from the following C code
 ;; void forked_ptrs_same_base_different_offset(float *A, float *B, int *C) {
 ;;   int offset;
@@ -421,6 +604,26 @@ latch:
 ;; }
 
 define dso_local void @forked_ptrs_same_base_different_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_same_base_different_offset'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_same_base_different_offset'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -446,40 +649,48 @@ for.body:                                         ; preds = %entry, %for.body
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_add_to_offset'
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
-; CHECK-NEXT:        %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (400 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: ((4 * %extra_offset) + %Base) High: (404 + (4 * %extra_offset) + %Base))
-; CHECK-NEXT:          Member: {(4 + (4 * %extra_offset) + %Base),+,4}<%for.body>
-; CHECK-NEXT:          Member: {((4 * %extra_offset) + %Base),+,4}<%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_add_to_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) {
+; CHECK-LABEL: 'forked_ptrs_add_to_offset'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP47:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP48:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP47]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP49:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
+; CHECK-NEXT:          %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP47]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP48]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP49]]:
+; CHECK-NEXT:          (Low: ((4 * %extra_offset) + %Base) High: (404 + (4 * %extra_offset) + %Base))
+; CHECK-NEXT:            Member: {(4 + (4 * %extra_offset) + %Base),+,4}<%for.body>
+; CHECK-NEXT:            Member: {((4 * %extra_offset) + %Base),+,4}<%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_add_to_offset'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -502,40 +713,48 @@ for.body:                                         ; preds = %entry, %for.body
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_sub_from_offset'
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
-; CHECK-NEXT:        %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (400 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: ((-4 * %extra_offset) + %Base) High: (404 + (-4 * %extra_offset) + %Base))
-; CHECK-NEXT:          Member: {(4 + (-4 * %extra_offset) + %Base),+,4}<%for.body>
-; CHECK-NEXT:          Member: {((-4 * %extra_offset) + %Base),+,4}<%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_sub_from_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) {
+; CHECK-LABEL: 'forked_ptrs_sub_from_offset'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP50:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP51:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP50]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP52:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
+; CHECK-NEXT:          %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP50]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP51]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP52]]:
+; CHECK-NEXT:          (Low: ((-4 * %extra_offset) + %Base) High: (404 + (-4 * %extra_offset) + %Base))
+; CHECK-NEXT:            Member: {(4 + (-4 * %extra_offset) + %Base),+,4}<%for.body>
+; CHECK-NEXT:            Member: {((-4 * %extra_offset) + %Base),+,4}<%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_sub_from_offset'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -558,40 +777,48 @@ for.body:                                         ; preds = %entry, %for.body
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_add_sub_offset'
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G3:.+]]):
-; CHECK-NEXT:        %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
-; CHECK-NEXT:        %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %Dest High: (400 + %Dest))
-; CHECK-NEXT:          Member: {%Dest,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (400 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: ((4 * %to_add) + (-4 * %to_sub) + %Base) High: (404 + (4 * %to_add) + (-4 * %to_sub) + %Base))
-; CHECK-NEXT:          Member: {(4 + (4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body>
-; CHECK-NEXT:          Member: {((4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_add_sub_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %to_add, i64 %to_sub) {
+; CHECK-LABEL: 'forked_ptrs_add_sub_offset'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP53:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP54:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP53]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP55:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
+; CHECK-NEXT:          %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP53]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP54]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP55]]:
+; CHECK-NEXT:          (Low: ((4 * %to_add) + (-4 * %to_sub) + %Base) High: (404 + (4 * %to_add) + (-4 * %to_sub) + %Base))
+; CHECK-NEXT:            Member: {(4 + (4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body>
+; CHECK-NEXT:            Member: {((4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_add_sub_offset'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -617,19 +844,27 @@ for.body:                                         ; preds = %entry, %for.body
 
 ;;;; Cases that can be handled by a forked pointer but are not currently allowed.
 
-; CHECK-LABEL: function 'forked_ptrs_mul_by_offset'
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Report: cannot identify array bounds
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define dso_local void @forked_ptrs_mul_by_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) {
+; CHECK-LABEL: 'forked_ptrs_mul_by_offset'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_mul_by_offset'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -652,22 +887,30 @@ for.body:                                         ; preds = %entry, %for.body
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL: function 'forked_ptrs_uniform_and_strided_forks':
-; CHECK-NEXT:  for.body:
-; CHECK-NEXT:    Report: cannot identify array bounds
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 ;;;; Derived from forked_ptrs_same_base_different_offset with a manually
 ;;;; added uniform offset and a mul to provide a stride
 
 define dso_local void @forked_ptrs_uniform_and_strided_forks(float* nocapture readonly %Base, float* nocapture %Dest, i32* nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_uniform_and_strided_forks'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_uniform_and_strided_forks'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -694,23 +937,31 @@ for.body:                                         ; preds = %entry, %for.body
   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
 }
 
-; CHECK-LABEL:  function 'forked_ptrs_gather_and_contiguous_forks':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:     Report: cannot identify array bounds
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:     SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Expressions re-written:
-
 ;;;; Derived from forked_ptrs_same_base_different_offset with a gather
 ;;;; added using Preds as an index array in addition to the per-iteration
 ;;;; condition.
 
 define dso_local void @forked_ptrs_gather_and_contiguous_forks(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_gather_and_contiguous_forks'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_gather_and_contiguous_forks'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -737,19 +988,27 @@ for.body:                                         ; preds = %entry, %for.body
 ;; We don't currently handle a fork in both the base and the offset of a
 ;; GEP instruction.
 
-; CHECK-LABEL: Loop access info in function 'forked_ptrs_two_forks_gep':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:     Report: cannot identify array bounds
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:     SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Expressions re-written:
-
 define dso_local void @forked_ptrs_two_forks_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_two_forks_gep'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_two_forks_gep'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -774,19 +1033,27 @@ for.body:
 
 ;; We don't handle forks as children of a select
 
-; CHECK-LABEL: Loop access info in function 'forked_ptrs_two_select':
-; CHECK-NEXT:  loop:
-; CHECK-NEXT:    Report: cannot identify array bounds
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-
 define void @forked_ptrs_two_select(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture readonly %Base3, ptr %Dest) {
+; CHECK-LABEL: 'forked_ptrs_two_select'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_two_select'
+; RECURSE-NEXT:    loop:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %loop
 
@@ -812,19 +1079,28 @@ exit:
 }
 
 ;; We don't yet handle geps with more than 2 operands
-; CHECK-LABEL: Loop access info in function 'forked_ptrs_too_many_gep_ops':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:     Report: cannot identify array bounds
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:     SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Expressions re-written:
 
 define void @forked_ptrs_too_many_gep_ops(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_too_many_gep_ops'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_too_many_gep_ops'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -847,19 +1123,28 @@ for.cond.cleanup:
 }
 
 ;; We don't currently handle vector GEPs
-; CHECK-LABEL: Loop access info in function 'forked_ptrs_vector_gep':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:     Report: cannot identify array bounds
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:     SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:     Expressions re-written:
 
 define void @forked_ptrs_vector_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'forked_ptrs_vector_gep'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_vector_gep'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   br label %for.body
 
@@ -881,33 +1166,6 @@ for.cond.cleanup:
   ret void
 }
 
-; CHECK-LABEL: Loop access info in function 'sc_add_expr_ice':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:     Memory dependences are safe with run-time checks
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Check 0:
-; CHECK-NEXT:       Comparing group ([[G1:.+]]):
-; CHECK-NEXT:       ptr %Base1
-; CHECK-NEXT:       Against group ([[G2:.+]]):
-; CHECK-NEXT:         %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-NEXT:       Group [[G1]]:
-; CHECK-NEXT:         (Low: %Base1 High: (8 + %Base1))
-; CHECK-NEXT:           Member: %Base1
-; CHECK-NEXT:       Group [[G2]]:
-; CHECK-NEXT:         (Low: %Base2 High: ((8 * %N) + %Base2))
-; CHECK-NEXT:           Member: {%Base2,+,8}<%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:     Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:     SCEV assumptions:
-; CHECK-NEXT:     {0,+,1}<%for.body> Added Flags: <nusw>
-; CHECK-EMPTY:
-; CHECK-NEXT:     Expressions re-written:
-; CHECK-NEXT:     [PSE]  %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel:
-; CHECK-NEXT:       ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>
-; CHECK-NEXT:       --> {%Base2,+,8}<%for.body>
-
 ;;; The following test caused an ICE with the initial forked pointers work.
 ;;; One fork is loop invariant (%Base2 + 0), the other is an scAddExpr that
 ;;; contains an scAddRecExpr inside it:
@@ -918,6 +1176,56 @@ for.cond.cleanup:
 ;;; forks only, but we should be able to do better.
 
 define void @sc_add_expr_ice(ptr %Base1, ptr %Base2, i64 %N) {
+; CHECK-LABEL: 'sc_add_expr_ice'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP56:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %Base1
+; CHECK-NEXT:        Against group ([[GRP57:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP56]]:
+; CHECK-NEXT:          (Low: %Base1 High: (8 + %Base1))
+; CHECK-NEXT:            Member: %Base1
+; CHECK-NEXT:        Group [[GRP57]]:
+; CHECK-NEXT:          (Low: %Base2 High: ((8 * %N) + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,8}<%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK-NEXT:      {0,+,1}<%for.body> Added Flags: <nusw>
+; CHECK:           Expressions re-written:
+; CHECK-NEXT:      [PSE] %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel:
+; CHECK-NEXT:        ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>
+; CHECK-NEXT:        --> {%Base2,+,8}<%for.body>
+;
+; RECURSE-LABEL: 'sc_add_expr_ice'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP58:0x[0-9a-f]+]]):
+; RECURSE-NEXT:        ptr %Base1
+; RECURSE-NEXT:        Against group ([[GRP59:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP58]]:
+; RECURSE-NEXT:          (Low: %Base1 High: (8 + %Base1))
+; RECURSE-NEXT:            Member: %Base1
+; RECURSE-NEXT:        Group [[GRP59]]:
+; RECURSE-NEXT:          (Low: %Base2 High: ((8 * %N) + %Base2))
+; RECURSE-NEXT:            Member: {%Base2,+,8}<%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE-NEXT:      {0,+,1}<%for.body> Added Flags: <nusw>
+; RECURSE:           Expressions re-written:
+; RECURSE-NEXT:      [PSE] %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel:
+; RECURSE-NEXT:        ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>
+; RECURSE-NEXT:        --> {%Base2,+,8}<%for.body>
+;
 entry:
   br label %for.body
 
@@ -938,45 +1246,90 @@ exit:
 }
 
 define void @forked_ptrs_with_different_base(ptr nocapture readonly %Preds, ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c)  {
-; CHECK:       for.body:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[G1:.+]]):
-; CHECK-NEXT:        %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[G1]]):
-; CHECK-NEXT:        %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4:.+]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[G3:.+]]):
-; CHECK-NEXT:        %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G2]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
-; CHECK-NEXT:    Check 3:
-; CHECK-NEXT:      Comparing group ([[G3]]):
-; CHECK-NEXT:        %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
-; CHECK-NEXT:      Against group ([[G4]]):
-; CHECK-NEXT:        %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[G1]]:
-; CHECK-NEXT:        (Low: %1 High: (63992 + %1))
-; CHECK-NEXT:          Member: {%1,+,8}<nw><%for.body>
-; CHECK-NEXT:      Group [[G3]]:
-; CHECK-NEXT:        (Low: %2 High: (63992 + %2))
-; CHECK-NEXT:          Member: {%2,+,8}<nw><%for.body>
-; CHECK-NEXT:      Group [[G2]]:
-; CHECK-NEXT:        (Low: %Preds High: (31996 + %Preds))
-; CHECK-NEXT:          Member: {%Preds,+,4}<nuw><%for.body>
-; CHECK-NEXT:      Group [[G4]]:
-; CHECK-NEXT:        (Low: %0 High: (63992 + %0))
-; CHECK-NEXT:          Member: {%0,+,8}<nw><%for.body>
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
+; CHECK-LABEL: 'forked_ptrs_with_different_base'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP60:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP61:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP60]]):
+; CHECK-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP62:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP63:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP61]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 3:
+; CHECK-NEXT:        Comparing group ([[GRP63]]):
+; CHECK-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP62]]):
+; CHECK-NEXT:          %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP60]]:
+; CHECK-NEXT:          (Low: %1 High: (63992 + %1))
+; CHECK-NEXT:            Member: {%1,+,8}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP63]]:
+; CHECK-NEXT:          (Low: %2 High: (63992 + %2))
+; CHECK-NEXT:            Member: {%2,+,8}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP61]]:
+; CHECK-NEXT:          (Low: %Preds High: (31996 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP62]]:
+; CHECK-NEXT:          (Low: %0 High: (63992 + %0))
+; CHECK-NEXT:            Member: {%0,+,8}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_with_different_base'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Memory dependences are safe with run-time checks
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Check 0:
+; RECURSE-NEXT:        Comparing group ([[GRP64:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP65:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 1:
+; RECURSE-NEXT:        Comparing group ([[GRP64]]):
+; RECURSE-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP66:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv
+; RECURSE-NEXT:      Check 2:
+; RECURSE-NEXT:        Comparing group ([[GRP67:0x[0-9a-f]+]]):
+; RECURSE-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP65]]):
+; RECURSE-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; RECURSE-NEXT:      Check 3:
+; RECURSE-NEXT:        Comparing group ([[GRP67]]):
+; RECURSE-NEXT:          %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv
+; RECURSE-NEXT:        Against group ([[GRP66]]):
+; RECURSE-NEXT:          %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE-NEXT:        Group [[GRP64]]:
+; RECURSE-NEXT:          (Low: %1 High: (63992 + %1))
+; RECURSE-NEXT:            Member: {%1,+,8}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP67]]:
+; RECURSE-NEXT:          (Low: %2 High: (63992 + %2))
+; RECURSE-NEXT:            Member: {%2,+,8}<nw><%for.body>
+; RECURSE-NEXT:        Group [[GRP65]]:
+; RECURSE-NEXT:          (Low: %Preds High: (31996 + %Preds))
+; RECURSE-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; RECURSE-NEXT:        Group [[GRP66]]:
+; RECURSE-NEXT:          (Low: %0 High: (63992 + %0))
+; RECURSE-NEXT:            Member: {%0,+,8}<nw><%for.body>
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   %0 = load ptr, ptr %c, align 64
   %1 = load ptr, ptr %a, align 64
@@ -1017,13 +1370,26 @@ for.inc:                                          ; preds = %if.then, %if.else
 
 ; Negative test: the operator number of PhiNode is not 2.
 define void @forked_ptrs_with_different_base3(ptr nocapture readonly %Preds, ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c)  {
-; CHECK:       for.body:
-; CHECK-NEXT:    Report: cannot identify array bounds
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
+; CHECK-LABEL: 'forked_ptrs_with_different_base3'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+; RECURSE-LABEL: 'forked_ptrs_with_different_base3'
+; RECURSE-NEXT:    for.body:
+; RECURSE-NEXT:      Report: cannot identify array bounds
+; RECURSE-NEXT:      Dependences:
+; RECURSE-NEXT:      Run-time memory checks:
+; RECURSE-NEXT:      Grouped accesses:
+; RECURSE:           Non vectorizable stores to invariant address were not found in loop.
+; RECURSE-NEXT:      SCEV assumptions:
+; RECURSE:           Expressions re-written:
+;
 entry:
   %ld.c = load ptr, ptr %c, align 64
   %ld.a = load ptr, ptr %a, align 64
@@ -1058,4 +1424,4 @@ for.inc:                                          ; preds = %if.br1, %if.br0
 
 for.cond.cleanup:                                 ; preds = %for.inc
   ret void
-}
\ No newline at end of file
+}
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/loop-invariant-dep-with-backedge-taken-count.ll b/llvm/test/Analysis/LoopAccessAnalysis/loop-invariant-dep-with-backedge-taken-count.ll
index 63e483dd72ff19f..d48628cb8b2ecc0 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/loop-invariant-dep-with-backedge-taken-count.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/loop-invariant-dep-with-backedge-taken-count.ll
@@ -1,21 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
 ; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
 
 ; Test cases for using the backedge-taken-count to rule out dependencies between
 ; an invariant and strided accesses.
 
 define void @test_distance_greater_than_BTC_100(ptr %a) {
-; CHECK-LABEL: Loop access info in function 'test_distance_greater_than_BTC_100':
-; CHECK-NEXT:   loop:
-; CHECK-NEXT:     Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT: Unknown data dependence.
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:       Unknown:
-; CHECK-NEXT:           %l = load i32, ptr %gep.x, align 4 ->
-; CHECK-NEXT:           store i32 %l, ptr %gep, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
+; CHECK-LABEL: 'test_distance_greater_than_BTC_100'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %l = load i32, ptr %gep.x, align 4 ->
+; CHECK-NEXT:            store i32 %l, ptr %gep, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   %gep.x = getelementptr i32, ptr %a, i32 100
@@ -35,18 +37,19 @@ exit:
 }
 
 define void @test_distance_much_greater_than_BTC_100(ptr %a) {
-; CHECK-LABEL: Loop access info in function 'test_distance_much_greater_than_BTC_100':
-; CHECK-NEXT:   loop:
-; CHECK-NEXT:     Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT: Unknown data dependence.
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:       Unknown:
-; CHECK-NEXT:           %l = load i32, ptr %gep.x, align 4 ->
-; CHECK-NEXT:           store i32 %l, ptr %gep, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
+; CHECK-LABEL: 'test_distance_much_greater_than_BTC_100'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %l = load i32, ptr %gep.x, align 4 ->
+; CHECK-NEXT:            store i32 %l, ptr %gep, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   %gep.x = getelementptr i32, ptr %a, i32 200
@@ -66,18 +69,19 @@ exit:
 }
 
 define void @test_distance_equal_BTC_100(ptr %a) {
-; CHECK-LABEL: Loop access info in function 'test_distance_equal_BTC_100':
-; CHECK-NEXT:   loop:
-; CHECK-NEXT:     Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT: Unknown data dependence.
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:       Unknown:
-; CHECK-NEXT:           %l = load i32, ptr %gep.x, align 4 ->
-; CHECK-NEXT:           store i32 %l, ptr %gep, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
+; CHECK-LABEL: 'test_distance_equal_BTC_100'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %l = load i32, ptr %gep.x, align 4 ->
+; CHECK-NEXT:            store i32 %l, ptr %gep, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   %gep.x = getelementptr i32, ptr %a, i32 99
@@ -97,18 +101,19 @@ exit:
 }
 
 define void @test_distance_greater_than_BTC_10000(ptr %a) {
-; CHECK-LABEL: Loop access info in function 'test_distance_greater_than_BTC_10000':
-; CHECK-NEXT:   loop:
-; CHECK-NEXT:     Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT: Unknown data dependence.
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:       Unknown:
-; CHECK-NEXT:           %l = load i32, ptr %gep.x, align 4 ->
-; CHECK-NEXT:           store i32 %l, ptr %gep, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
+; CHECK-LABEL: 'test_distance_greater_than_BTC_10000'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %l = load i32, ptr %gep.x, align 4 ->
+; CHECK-NEXT:            store i32 %l, ptr %gep, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   %gep.x = getelementptr i32, ptr %a, i32 10000
@@ -128,18 +133,19 @@ exit:
 }
 
 define void @test_distance_equal_to_BTC_10000(ptr %a) {
-; CHECK-LABEL: Loop access info in function 'test_distance_equal_to_BTC_10000':
-; CHECK-NEXT:   loop:
-; CHECK-NEXT:     Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT: Unknown data dependence.
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:       Unknown:
-; CHECK-NEXT:           %l = load i32, ptr %gep.x, align 4 ->
-; CHECK-NEXT:           store i32 %l, ptr %gep, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
+; CHECK-LABEL: 'test_distance_equal_to_BTC_10000'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %l = load i32, ptr %gep.x, align 4 ->
+; CHECK-NEXT:            store i32 %l, ptr %gep, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   %gep.x = getelementptr i32, ptr %a, i32 9999
@@ -159,17 +165,29 @@ exit:
 }
 
 define void @test_btc_is_unknown_value(ptr %a, i32 %N) {
-; CHECK-LABEL: Loop access info in function 'test_btc_is_unknown_value':
-; CHECK-NEXT:   loop:
-; CHECK-NEXT:     Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT: Unknown data dependence.
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:       Unknown:
-; CHECK-NEXT:           %l = load i32, ptr %gep.x, align 4 ->
-; CHECK-NEXT:           store i32 %l, ptr %gep, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
+; CHECK-LABEL: 'test_btc_is_unknown_value'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %l = load i32, ptr %gep.x, align 4 ->
+; CHECK-NEXT:            store i32 %l, ptr %gep, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP1:0x[0-9a-f]+]]:
+; CHECK-NEXT:          (Low: (400 + %a) High: (404 + %a))
+; CHECK-NEXT:            Member: (400 + %a)
+; CHECK-NEXT:        Group [[GRP2:0x[0-9a-f]+]]:
+; CHECK-NEXT:          (Low: %a High: (4 + (4 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %a))
+; CHECK-NEXT:            Member: {%a,+,4}<nw><%loop>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK-NEXT:      {0,+,1}<nuw><%loop> Added Flags: <nssw>
+; CHECK:           Expressions re-written:
+; CHECK-NEXT:      [PSE] %gep = getelementptr i32, ptr %a, i32 %iv:
+; CHECK-NEXT:        ((4 * (sext i32 {0,+,1}<nuw><%loop> to i64))<nsw> + %a)
+; CHECK-NEXT:        --> {%a,+,4}<nw><%loop>
 ;
 entry:
   %gep.x = getelementptr i32, ptr %a, i32 100
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/max_safe_dep_dist_non_unit_stride.ll b/llvm/test/Analysis/LoopAccessAnalysis/max_safe_dep_dist_non_unit_stride.ll
index 0364248b004cf88..aafaecfc8f25a5c 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/max_safe_dep_dist_non_unit_stride.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/max_safe_dep_dist_non_unit_stride.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
 ; RUN: opt -S -disable-output -passes='print<access-info>' < %s 2>&1 | FileCheck %s
 
 ; Generated from following C program:
@@ -8,21 +9,18 @@
 ;   }
 ; }
 define void @foo(i64  %len, ptr %a) {
-; CHECK-LABEL: Loop access info in function 'foo':
-; CHECK-NEXT:  loop:
-; CHECK-NEXT:   Memory dependences are safe with a maximum safe vector width of 64 bits
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      BackwardVectorizable:
-; CHECK-NEXT:          store i32 %0, ptr %arrayidx2, align 4 ->
-; CHECK-NEXT:          %1 = load i32, ptr %arrayidx5, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
+; CHECK-LABEL: 'foo'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Memory dependences are safe with a maximum safe vector width of 64 bits
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        BackwardVectorizable:
+; CHECK-NEXT:            store i32 %0, ptr %arrayidx2, align 4 ->
+; CHECK-NEXT:            %1 = load i32, ptr %arrayidx5, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 loop.preheader:
   br label %loop
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll b/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
index 07ebaf2dfe0583f..96d1ee1ec2de28a 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
@@ -1,11 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
 ; RUN: opt -passes='print<access-info>' -disable-output  < %s 2>&1 | FileCheck %s
 
 %s1 = type { [32000 x double], [32000 x double], [32000 x double] }
 
 define i32 @load_with_pointer_phi_no_runtime_checks(ptr %data) {
-; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Memory dependences are safe
+; CHECK-LABEL: 'load_with_pointer_phi_no_runtime_checks'
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Memory dependences are safe
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br label %loop.header
@@ -39,8 +46,14 @@ exit:                                             ; preds = %loop.latch
 
 define i32 @store_with_pointer_phi_no_runtime_checks(ptr %data) {
 ; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Memory dependences are safe
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Memory dependences are safe
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br label %loop.header
@@ -74,24 +87,38 @@ exit:                                             ; preds = %loop.latch
 
 define i32 @store_with_pointer_phi_runtime_checks(ptr %A, ptr %B, ptr %C) {
 ; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Memory dependences are safe with run-time checks
-; CHECK:         Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[GROUP_B:.+]]):
-; CHECK-NEXT:        %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
-; CHECK-NEXT:      Against group ([[GROUP_C:.+]]):
-; CHECK-NEXT:        %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[GROUP_B]]):
-; CHECK-NEXT:        %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
-; CHECK-NEXT:      Against group ([[GROUP_A:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[GROUP_C]]):
-; CHECK-NEXT:        %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
-; CHECK-NEXT:      Against group ([[GROUP_A]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP1]]):
+; CHECK-NEXT:          %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP3:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP2]]):
+; CHECK-NEXT:          %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP3]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP1]]:
+; CHECK-NEXT:          (Low: %B High: (256000 + %B))
+; CHECK-NEXT:            Member: {%B,+,8}<nw><%loop.header>
+; CHECK-NEXT:        Group [[GRP2]]:
+; CHECK-NEXT:          (Low: %C High: (256000 + %C))
+; CHECK-NEXT:            Member: {%C,+,8}<nw><%loop.header>
+; CHECK-NEXT:        Group [[GRP3]]:
+; CHECK-NEXT:          (Low: %A High: (256000 + %A))
+; CHECK-NEXT:            Member: {%A,+,8}<nw><%loop.header>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br label %loop.header
@@ -125,13 +152,18 @@ exit:                                             ; preds = %loop.latch
 
 define i32 @load_with_pointer_phi_outside_loop(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
 ; CHECK-LABEL: 'load_with_pointer_phi_outside_loop'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop
-; CHECK-NEXT:    Unknown data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %v8 = load double, ptr %ptr, align 8 ->
-; CHECK-NEXT:          store double %mul16, ptr %arrayidx, align 8
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %v8 = load double, ptr %ptr, align 8 ->
+; CHECK-NEXT:            store double %mul16, ptr %arrayidx, align 8
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br i1 %c.0, label %if.then, label %if.else
@@ -163,13 +195,18 @@ exit:                                             ; preds = %loop.latch
 
 define i32 @store_with_pointer_phi_outside_loop(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
 ; CHECK-LABEL: 'store_with_pointer_phi_outside_loop'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT:    Unknown data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %v8 = load double, ptr %arrayidx, align 8 ->
-; CHECK-NEXT:          store double %mul16, ptr %ptr, align 8
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
+; CHECK-NEXT:            store double %mul16, ptr %ptr, align 8
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br i1 %c.0, label %if.then, label %if.else
@@ -201,43 +238,46 @@ exit:                                             ; preds = %loop.latch
 
 define i32 @store_with_pointer_phi_incoming_phi(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
 ; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
-; CHECK-NEXT:    Unknown data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %v8 = load double, ptr %arrayidx, align 8 ->
-; CHECK-NEXT:          store double %mul16, ptr %ptr.2, align 8
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[GROUP_C:.+]]):
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      Against group ([[GROUP_B:.+]]):
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[GROUP_C]]):
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      Against group ([[GROUP_A:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[GROUP_B]]):
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:      Against group ([[GROUP_A]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[GROUP_C]]:
-; CHECK-NEXT:        (Low: %C High: (8 + %C))
-; CHECK-NEXT:          Member: %C
-; CHECK-NEXT:      Group [[GROUP_B]]:
-; CHECK-NEXT:        (Low: %B High: (8 + %B))
-; CHECK-NEXT:          Member: %B
-; CHECK-NEXT:      Group [[GROUP_A]]:
-; CHECK-NEXT:        (Low: %A High: (256000 + %A))
-; CHECK-NEXT:          Member: {%A,+,8}<nuw><%loop.header>
-; CHECK-NEXT:          Member: %A
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
+; CHECK-NEXT:            store double %mul16, ptr %ptr.2, align 8
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP4:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        Against group ([[GRP5:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP4]]):
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        Against group ([[GRP6:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP5]]):
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:        Against group ([[GRP6]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP4]]:
+; CHECK-NEXT:          (Low: %C High: (8 + %C))
+; CHECK-NEXT:            Member: %C
+; CHECK-NEXT:        Group [[GRP5]]:
+; CHECK-NEXT:          (Low: %B High: (8 + %B))
+; CHECK-NEXT:            Member: %B
+; CHECK-NEXT:        Group [[GRP6]]:
+; CHECK-NEXT:          (Low: %A High: (256000 + %A))
+; CHECK-NEXT:            Member: {%A,+,8}<nuw><%loop.header>
+; CHECK-NEXT:            Member: %A
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
 ; CHECK-EMPTY
 entry:
   br label %loop.header
@@ -278,43 +318,46 @@ exit:                                             ; preds = %loop.latch
 ; Test cases with pointer phis forming a cycle.
 define i32 @store_with_pointer_phi_incoming_phi_irreducible_cycle(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
 ; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi_irreducible_cycle'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
-; CHECK-NEXT:    Unknown data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %v8 = load double, ptr %arrayidx, align 8 ->
-; CHECK-NEXT:          store double %mul16, ptr %ptr.3, align 8
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[GROUP_C:.+]]):
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      Against group ([[GROUP_B:.+]]):
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[GROUP_C]]):
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      Against group ([[GROUP_A:.+]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[GROUP_B]]):
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:      Against group ([[GROUP_A]]):
-; CHECK-NEXT:        %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[GROUP_C]]
-; CHECK-NEXT:        (Low: %C High: (8 + %C))
-; CHECK-NEXT:          Member: %C
-; CHECK-NEXT:      Group [[GROUP_B]]
-; CHECK-NEXT:        (Low: %B High: (8 + %B))
-; CHECK-NEXT:          Member: %B
-; CHECK-NEXT:      Group [[GROUP_A]]
-; CHECK-NEXT:        (Low: %A High: (256000 + %A))
-; CHECK-NEXT:          Member: {%A,+,8}<nuw><%loop.header>
-; CHECK-NEXT:          Member: %A
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
+; CHECK-NEXT:            store double %mul16, ptr %ptr.3, align 8
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP7:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        Against group ([[GRP8:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP7]]):
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        Against group ([[GRP9:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP8]]):
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:        Against group ([[GRP9]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP7]]:
+; CHECK-NEXT:          (Low: %C High: (8 + %C))
+; CHECK-NEXT:            Member: %C
+; CHECK-NEXT:        Group [[GRP8]]:
+; CHECK-NEXT:          (Low: %B High: (8 + %B))
+; CHECK-NEXT:            Member: %B
+; CHECK-NEXT:        Group [[GRP9]]:
+; CHECK-NEXT:          (Low: %A High: (256000 + %A))
+; CHECK-NEXT:            Member: {%A,+,8}<nuw><%loop.header>
+; CHECK-NEXT:            Member: %A
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
 ; CHECK-EMPTY
 entry:
   br label %loop.header
@@ -350,13 +393,18 @@ exit:                                             ; preds = %loop.latch
 
 define i32 @store_with_pointer_phi_outside_loop_select(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
 ; CHECK-LABEL: 'store_with_pointer_phi_outside_loop_select'
-; CHECK-NEXT:  loop.header:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT:    Unknown data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %v8 = load double, ptr %arrayidx, align 8 ->
-; CHECK-NEXT:          store double %mul16, ptr %ptr, align 8
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
+; CHECK-NEXT:            store double %mul16, ptr %ptr, align 8
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br i1 %c.0, label %if.then, label %if.else
@@ -387,13 +435,15 @@ exit:                                             ; preds = %loop.latch
 }
 
 define i32 @store_with_pointer_phi_in_same_bb_use_other_phi(ptr %A, ptr %B, ptr %C, ptr %D, i1 %c.0, i1 %c.1) {
-; CHECK-LABEL: Loop access info in function 'store_with_pointer_phi_in_same_bb_use_other_phi':
-; CHECK-NEXT:   loop.header:
-; CHECK-NEXT:     Report: cannot identify array bounds
-; CHECK-NEXT:     Dependences:
-; CHECK-NEXT:     Run-time memory checks:
-; CHECK-NEXT:     Grouped accesses:
-; CHECK-EMPTY:
+; CHECK-LABEL: 'store_with_pointer_phi_in_same_bb_use_other_phi'
+; CHECK-NEXT:    loop.header:
+; CHECK-NEXT:      Report: cannot identify array bounds
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br label %loop.header
@@ -415,63 +465,61 @@ exit:                                             ; preds = %loop.latch
 }
 
 define void @phi_load_store_memdep_check(i1 %c, ptr %A, ptr %B, ptr %C) {
-; CHECK-LABEL: Loop access info in function 'phi_load_store_memdep_check':
-; CHECK-NEXT:   for.body:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
-; CHECK-NEXT:    Unknown data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %lv3 = load i16, ptr %c.sink, align 2 ->
-; CHECK-NEXT:          store i16 %add, ptr %c.sink, align 1
-; CHECK-EMPTY:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %lv3 = load i16, ptr %c.sink, align 2 ->
-; CHECK-NEXT:          store i16 %add, ptr %c.sink, align 1
-; CHECK-EMPTY:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          %lv = load i16, ptr %A, align 1 ->
-; CHECK-NEXT:          store i16 %lv, ptr %A, align 1
-; CHECK-EMPTY:
-; CHECK-NEXT:      Unknown:
-; CHECK-NEXT:          store i16 %lv, ptr %A, align 1 ->
-; CHECK-NEXT:          %lv2 = load i16, ptr %A, align 1
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Check 0:
-; CHECK-NEXT:      Comparing group ([[GROUP_A:.+]]):
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:      Against group ([[GROUP_C:.+]]):
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:    Check 1:
-; CHECK-NEXT:      Comparing group ([[GROUP_A]]):
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:      ptr %A
-; CHECK-NEXT:      Against group ([[GROUP_B:.+]]):
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:    Check 2:
-; CHECK-NEXT:      Comparing group ([[GROUP_C]]):
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      ptr %C
-; CHECK-NEXT:      Against group ([[GROUP_B]]):
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:      ptr %B
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-NEXT:      Group [[GROUP_A]]
-; CHECK-NEXT:        (Low: %A High: (2 + %A))
-; CHECK-NEXT:          Member: %A
-; CHECK-NEXT:          Member: %A
-; CHECK-NEXT:      Group [[GROUP_C]]
-; CHECK-NEXT:        (Low: %C High: (2 + %C))
-; CHECK-NEXT:          Member: %C
-; CHECK-NEXT:          Member: %C
-; CHECK-NEXT:      Group [[GROUP_B]]
-; CHECK-NEXT:        (Low: %B High: (2 + %B))
-; CHECK-NEXT:          Member: %B
-; CHECK-NEXT:          Member: %B
-; CHECK-EMPTY:
+; CHECK-LABEL: 'phi_load_store_memdep_check'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Unknown data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Unknown:
+; CHECK-NEXT:            %lv3 = load i16, ptr %c.sink, align 2 ->
+; CHECK-NEXT:            store i16 %add, ptr %c.sink, align 1
+; CHECK:             Unknown:
+; CHECK-NEXT:            %lv3 = load i16, ptr %c.sink, align 2 ->
+; CHECK-NEXT:            store i16 %add, ptr %c.sink, align 1
+; CHECK:             Unknown:
+; CHECK-NEXT:            %lv = load i16, ptr %A, align 1 ->
+; CHECK-NEXT:            store i16 %lv, ptr %A, align 1
+; CHECK:             Unknown:
+; CHECK-NEXT:            store i16 %lv, ptr %A, align 1 ->
+; CHECK-NEXT:            %lv2 = load i16, ptr %A, align 1
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP10:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:        Against group ([[GRP11:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP10]]):
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:        ptr %A
+; CHECK-NEXT:        Against group ([[GRP12:0x[0-9a-f]+]]):
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP11]]):
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        ptr %C
+; CHECK-NEXT:        Against group ([[GRP12]]):
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:        ptr %B
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP10]]:
+; CHECK-NEXT:          (Low: %A High: (2 + %A))
+; CHECK-NEXT:            Member: %A
+; CHECK-NEXT:            Member: %A
+; CHECK-NEXT:        Group [[GRP11]]:
+; CHECK-NEXT:          (Low: %C High: (2 + %C))
+; CHECK-NEXT:            Member: %C
+; CHECK-NEXT:            Member: %C
+; CHECK-NEXT:        Group [[GRP12]]:
+; CHECK-NEXT:          (Low: %B High: (2 + %B))
+; CHECK-NEXT:            Member: %B
+; CHECK-NEXT:            Member: %B
+; CHECK:           Non vectorizable stores to invariant address were found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
 ;
 entry:
   br label %for.body
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll b/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll
index 016c574b3b7cb1d..b10d42b7e508d7c 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
 ; RUN: opt -S -disable-output -passes='print<access-info>' %s 2>&1 | FileCheck %s
 
 ;
@@ -5,26 +6,23 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 
 ; A forwarding in the presence of symbolic strides.
 define void @single_stride(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {
-; CHECK-LABEL: Loop access info in function 'single_stride':
-; CHECK-NEXT:  loop:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT:    Backward loop carried data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Backward:
-; CHECK-NEXT:          %load = load i32, ptr %gep.A, align 4 ->
-; CHECK-NEXT:          store i32 %add, ptr %gep.A.next, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-NEXT:    Equal predicate: %stride == 1
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-; CHECK-NEXT:    [PSE]  %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:
-; CHECK-NEXT:      {%A,+,(4 * %stride)}<%loop>
-; CHECK-NEXT:      --> {%A,+,4}<%loop>
+; CHECK-LABEL: 'single_stride'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Backward loop carried data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Backward:
+; CHECK-NEXT:            %load = load i32, ptr %gep.A, align 4 ->
+; CHECK-NEXT:            store i32 %add, ptr %gep.A.next, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK-NEXT:      Equal predicate: %stride == 1
+; CHECK:           Expressions re-written:
+; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:
+; CHECK-NEXT:        {%A,+,(4 * %stride)}<%loop>
+; CHECK-NEXT:        --> {%A,+,4}<%loop>
 ;
 entry:
   br label %loop
@@ -49,26 +47,23 @@ exit:                                          ; preds = %loop
 
 ; Similar to @single_stride, but with struct types.
 define void @single_stride_struct(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {
-; CHECK-LABEL: Loop access info in function 'single_stride_struct':
-; CHECK-NEXT:  loop:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT:    Backward loop carried data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Backward:
-; CHECK-NEXT:          %load = load { i32, i8 }, ptr %gep.A, align 4 ->
-; CHECK-NEXT:          store { i32, i8 } %ins, ptr %gep.A.next, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-NEXT:    Equal predicate: %stride == 1
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-; CHECK-NEXT:    [PSE]  %gep.A = getelementptr inbounds { i32, i8 }, ptr %A, i64 %mul:
-; CHECK-NEXT:      {%A,+,(8 * %stride)}<%loop>
-; CHECK-NEXT:      --> {%A,+,8}<%loop>
+; CHECK-LABEL: 'single_stride_struct'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Backward loop carried data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Backward:
+; CHECK-NEXT:            %load = load { i32, i8 }, ptr %gep.A, align 4 ->
+; CHECK-NEXT:            store { i32, i8 } %ins, ptr %gep.A.next, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK-NEXT:      Equal predicate: %stride == 1
+; CHECK:           Expressions re-written:
+; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds { i32, i8 }, ptr %A, i64 %mul:
+; CHECK-NEXT:        {%A,+,(8 * %stride)}<%loop>
+; CHECK-NEXT:        --> {%A,+,8}<%loop>
 ;
 entry:
   br label %loop
@@ -96,30 +91,27 @@ exit:
 
 ; A loop with two symbolic strides.
 define void @two_strides(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride.1, i64 %stride.2) {
-; CHECK-LABEL: Loop access info in function 'two_strides':
-; CHECK-NEXT:  loop:
-; CHECK-NEXT:    Report: unsafe dependent memory operations in loop.
-; CHECK-NEXT:    Backward loop carried data dependence.
-; CHECK-NEXT:    Dependences:
-; CHECK-NEXT:      Backward:
-; CHECK-NEXT:          %load = load i32, ptr %gep.A, align 4 ->
-; CHECK-NEXT:          store i32 %add, ptr %gep.A.next, align 4
-; CHECK-EMPTY:
-; CHECK-NEXT:    Run-time memory checks:
-; CHECK-NEXT:    Grouped accesses:
-; CHECK-EMPTY:
-; CHECK-NEXT:    Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT:    SCEV assumptions:
-; CHECK-NEXT:    Equal predicate: %stride.2 == 1
-; CHECK-NEXT:    Equal predicate: %stride.1 == 1
-; CHECK-EMPTY:
-; CHECK-NEXT:    Expressions re-written:
-; CHECK-NEXT:    [PSE]  %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:
-; CHECK-NEXT:      {%A,+,(4 * %stride.1)}<%loop>
-; CHECK-NEXT:      --> {%A,+,4}<%loop>
-; CHECK-NEXT:    [PSE]  %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %mul.2:
-; CHECK-NEXT:      {((4 * %stride.2) + %A),+,(4 * %stride.2)}<%loop>
-; CHECK-NEXT:      --> {(4 + %A),+,4}<%loop>
+; CHECK-LABEL: 'two_strides'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
+; CHECK-NEXT:  Backward loop carried data dependence.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        Backward:
+; CHECK-NEXT:            %load = load i32, ptr %gep.A, align 4 ->
+; CHECK-NEXT:            store i32 %add, ptr %gep.A.next, align 4
+; CHECK:           Run-time memory checks:
+; CHECK-NEXT:      Grouped accesses:
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK-NEXT:      Equal predicate: %stride.2 == 1
+; CHECK-NEXT:      Equal predicate: %stride.1 == 1
+; CHECK:           Expressions re-written:
+; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:
+; CHECK-NEXT:        {%A,+,(4 * %stride.1)}<%loop>
+; CHECK-NEXT:        --> {%A,+,4}<%loop>
+; CHECK-NEXT:      [PSE] %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %mul.2:
+; CHECK-NEXT:        {((4 * %stride.2) + %A),+,(4 * %stride.2)}<%loop>
+; CHECK-NEXT:        --> {(4 + %A),+,4}<%loop>
 ;
 entry:
   br label %loop
diff --git a/llvm/test/Transforms/LoopUnroll/unroll-loop-invalidation.ll b/llvm/test/Transforms/LoopUnroll/unroll-loop-invalidation.ll
index bd77e98df31b08a..1018868702300e6 100644
--- a/llvm/test/Transforms/LoopUnroll/unroll-loop-invalidation.ll
+++ b/llvm/test/Transforms/LoopUnroll/unroll-loop-invalidation.ll
@@ -11,7 +11,7 @@
 ; CHECK: Invalidating analysis: LoopAccessAnalysis on test
 ; CHECK: Running pass: LoopAccessInfoPrinterPass
 ; CHECK: Running analysis: LoopAccessAnalysis on test
-; CHECK: Loop access info in function 'test':
+; CHECK: Printing analysis 'Loop Access Analysis' on function 'test':
 ; CHECK:   inner1.header:
 
 ; CHECK:   inner1.header.1:
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll
new file mode 100644
index 000000000000000..61fd0f2f66d577a
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll
@@ -0,0 +1,23 @@
+; RUN: opt -passes='print<access-info>' < %s -disable-output 2>&1 | FileCheck %s
+
+define dso_local void @dotvariable_laa(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+entry:
+  br label %for.body
+
+for.cond.cleanup:
+  ret void
+
+for.body:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+  %0 = load i32, ptr %arrayidx, align 4
+  %cmp1.not = icmp eq i32 %0, 0
+  %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+  %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+  %.sink = load double, ptr %.sink.in, align 8
+  %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+  store double %.sink, ptr %1, align 8
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %exitcond.not = icmp eq i64 %indvars.iv.next, 100
+  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
\ No newline at end of file
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll.expected
new file mode 100644
index 000000000000000..3e4a0559f513301
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/dotvariable-laa.ll.expected
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; RUN: opt -passes='print<access-info>' < %s -disable-output 2>&1 | FileCheck %s
+
+define dso_local void @dotvariable_laa(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+; CHECK-LABEL: 'dotvariable_laa'
+; CHECK-NEXT:    for.body:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP1]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP3:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group ([[GRP1]]):
+; CHECK-NEXT:          %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+; CHECK-NEXT:        Against group ([[GRP4:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP1]]:
+; CHECK-NEXT:          (Low: %Dest High: (800 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,8}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP2]]:
+; CHECK-NEXT:          (Low: %Preds High: (400 + %Preds))
+; CHECK-NEXT:            Member: {%Preds,+,4}<nuw><%for.body>
+; CHECK-NEXT:        Group [[GRP3]]:
+; CHECK-NEXT:          (Low: %Base2 High: (800 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,8}<nw><%for.body>
+; CHECK-NEXT:        Group [[GRP4]]:
+; CHECK-NEXT:          (Low: %Base1 High: (800 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,8}<nw><%for.body>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+
+entry:
+  br label %for.body
+
+for.cond.cleanup:
+  ret void
+
+for.body:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+  %0 = load i32, ptr %arrayidx, align 4
+  %cmp1.not = icmp eq i32 %0, 0
+  %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+  %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv
+  %.sink = load double, ptr %.sink.in, align 8
+  %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv
+  store double %.sink, ptr %1, align 8
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %exitcond.not = icmp eq i64 %indvars.iv.next, 100
+  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll
new file mode 100644
index 000000000000000..618c8f11cde9c86
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll
@@ -0,0 +1,23 @@
+; RUN: opt -passes='print<access-info>' < %s -disable-output 2>&1 | FileCheck %s
+
+define void @laa(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr %Dest) {
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+  %l.Dest = load float, ptr %gep.Dest
+  %cmp = fcmp une float %l.Dest, 0.0
+  %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv
+  %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv
+  %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+  %sink = load float, ptr %select, align 4
+  store float %sink, ptr %gep.Dest, align 4
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 100
+  br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+  ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected
new file mode 100644
index 000000000000000..793e815dbdf662b
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; RUN: opt -passes='print<access-info>' < %s -disable-output 2>&1 | FileCheck %s
+
+define void @laa(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr %Dest) {
+; CHECK-LABEL: 'laa'
+; CHECK-NEXT:    loop:
+; CHECK-NEXT:      Memory dependences are safe with run-time checks
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group ([[GRP1]]):
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:          %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT:        Against group ([[GRP3:0x[0-9a-f]+]]):
+; CHECK-NEXT:          %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group [[GRP1]]:
+; CHECK-NEXT:          (Low: %Dest High: (400 + %Dest))
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%loop>
+; CHECK-NEXT:            Member: {%Dest,+,4}<nuw><%loop>
+; CHECK-NEXT:        Group [[GRP2]]:
+; CHECK-NEXT:          (Low: %Base1 High: (400 + %Base1))
+; CHECK-NEXT:            Member: {%Base1,+,4}<nw><%loop>
+; CHECK-NEXT:        Group [[GRP3]]:
+; CHECK-NEXT:          (Low: %Base2 High: (400 + %Base2))
+; CHECK-NEXT:            Member: {%Base2,+,4}<nw><%loop>
+; CHECK:           Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT:      SCEV assumptions:
+; CHECK:           Expressions re-written:
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+  %l.Dest = load float, ptr %gep.Dest
+  %cmp = fcmp une float %l.Dest, 0.0
+  %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv
+  %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv
+  %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+  %sink = load float, ptr %select, align 4
+  store float %sink, ptr %gep.Dest, align 4
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, 100
+  br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+  ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/dotvariable-laa.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/dotvariable-laa.test
new file mode 100644
index 000000000000000..d72bcbcf1c23cd0
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/dotvariable-laa.test
@@ -0,0 +1,6 @@
+## Basic test checking that update_analyze_test_checks.py works correctly
+# RUN: cp -f %S/Inputs/dotvariable-laa.ll %t.ll && %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/dotvariable-laa.ll.expected
+## Check that running the script again does not change the result:
+# RUN: %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/dotvariable-laa.ll.expected
\ No newline at end of file
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-access-analysis.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-access-analysis.test
new file mode 100644
index 000000000000000..6531f0610660ad7
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-access-analysis.test
@@ -0,0 +1,6 @@
+## Basic test checking that update_analyze_test_checks.py works correctly
+# RUN: cp -f %S/Inputs/loop-access-analysis.ll %t.ll && %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/loop-access-analysis.ll.expected
+## Check that running the script again does not change the result:
+# RUN: %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/loop-access-analysis.ll.expected
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index c8c8d85e0dc68c8..7e9e5deb3b64614 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -502,6 +502,7 @@ def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, verbose=False):
 
 SCRUB_LEADING_WHITESPACE_RE = re.compile(r"^(\s+)")
 SCRUB_WHITESPACE_RE = re.compile(r"(?!^(|  \w))[ \t]+", flags=re.M)
+SCRUB_PRESERVE_LEADING_WHITESPACE_RE = re.compile(r"((?!^)[ \t]*(\S))[ \t]+")
 SCRUB_TRAILING_WHITESPACE_RE = re.compile(r"[ \t]+$", flags=re.M)
 SCRUB_TRAILING_WHITESPACE_TEST_RE = SCRUB_TRAILING_WHITESPACE_RE
 SCRUB_TRAILING_WHITESPACE_AND_ATTRIBUTES_RE = re.compile(
@@ -592,7 +593,8 @@ def do_filter(body, filters):
 def scrub_body(body):
     # Scrub runs of whitespace out of the assembly, but leave the leading
     # whitespace in place.
-    body = SCRUB_WHITESPACE_RE.sub(r" ", body)
+    body = SCRUB_PRESERVE_LEADING_WHITESPACE_RE.sub(lambda m: m.group(2) + " ", body)
+
     # Expand the tabs used for indentation.
     body = str.expandtabs(body, 2)
     # Strip trailing whitespace.
@@ -770,6 +772,7 @@ def process_run_line(
                 supported_analyses = {
                     "cost model analysis",
                     "scalar evolution analysis",
+                    "loop access analysis",
                 }
                 if analysis.lower() not in supported_analyses:
                     warn("Unsupported analysis mode: %r!" % (analysis,))
@@ -931,7 +934,7 @@ def get_ir_regex_from_ir_value_re_match(self, match):
     def get_value_name(self, var: str, check_prefix: str):
         var = var.replace("!", "")
         if self.replace_number_with_counter:
-            assert var.isdigit(), var
+            assert var
             replacement = self.variable_mapping.get(var, None)
             if replacement is None:
                 # Replace variable with an incrementing counter
@@ -1023,6 +1026,16 @@ def get_value_use(self, var, match, var_prefix=None):
     ),
 ]
 
+analyze_nameless_values = [
+    NamelessValue(
+        r"GRP",
+        "#",
+        r"",
+        r"0x[0-9a-f]+",
+        None,
+        replace_number_with_counter=True,
+    ),
+]
 
 def createOrRegexp(old, new):
     if not old:
@@ -1066,6 +1079,20 @@ def createPrefixMatch(prefix_str, prefix_re):
     r"((?:#|//)\s*)" + "(" + ASM_VALUE_REGEXP_STRING + ")" + ASM_VALUE_REGEXP_SUFFIX
 )
 
+ANALYZE_VALUE_REGEXP_PREFIX = r"(\s*)"
+ANALYZE_VALUE_REGEXP_STRING = r""
+for nameless_value in analyze_nameless_values:
+    match = createPrefixMatch(nameless_value.ir_prefix, nameless_value.ir_regexp)
+    ANALYZE_VALUE_REGEXP_STRING = createOrRegexp(ANALYZE_VALUE_REGEXP_STRING, match)
+ANALYZE_VALUE_REGEXP_SUFFIX = r"(\)?:)"
+ANALYZE_VALUE_RE = re.compile(
+    ANALYZE_VALUE_REGEXP_PREFIX
+    + r"("
+    + ANALYZE_VALUE_REGEXP_STRING
+    + r")"
+    + ANALYZE_VALUE_REGEXP_SUFFIX
+)
+
 # The entire match is group 0, the prefix has one group (=1), the entire
 # IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start.
 first_nameless_group_in_ir_value_match = 3
@@ -1145,7 +1172,7 @@ def transform_line_vars(match):
     lines_with_def = []
 
     for i, line in enumerate(lines):
-        if not is_asm:
+        if not is_asm and not is_analyze:
             # An IR variable named '%.' matches the FileCheck regex string.
             line = line.replace("%.", "%dot")
             for regex in _global_hex_value_regex:
@@ -1163,15 +1190,14 @@ def transform_line_vars(match):
             # Ignore any comments, since the check lines will too.
             scrubbed_line = SCRUB_IR_COMMENT_RE.sub(r"", line)
             lines[i] = scrubbed_line
-        if is_asm or not is_analyze:
-            # It can happen that two matches are back-to-back and for some reason sub
-            # will not replace both of them. For now we work around this by
-            # substituting until there is no more match.
-            changed = True
-            while changed:
-                (lines[i], changed) = nameless_value_regex.subn(
-                    transform_line_vars, lines[i], count=1
-                )
+        # It can happen that two matches are back-to-back and for some reason sub
+        # will not replace both of them. For now we work around this by
+        # substituting until there is no more match.
+        changed = True
+        while changed:
+            (lines[i], changed) = nameless_value_regex.subn(
+                transform_line_vars, lines[i], count=1
+            )
     return lines
 
 
@@ -1200,6 +1226,17 @@ def generalize_asm_check_lines(lines, vars_seen, global_vars_seen):
     )
 
 
+def generalize_analyze_check_lines(lines, vars_seen, global_vars_seen):
+    return generalize_check_lines_common(
+        lines,
+        True,
+        vars_seen,
+        global_vars_seen,
+        analyze_nameless_values,
+        ANALYZE_VALUE_RE,
+        False,
+    )
+
 def add_checks(
     output_lines,
     comment_marker,
@@ -1357,11 +1394,16 @@ def add_checks(
                         global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
                 break
 
+            if is_analyze:
+                func_body = generalize_analyze_check_lines(
+                    func_body, vars_seen, global_vars_seen
+                )
             # For IR output, change all defs to FileCheck variables, so we're immune
             # to variable naming fashions.
-            func_body = generalize_check_lines(
-                func_body, is_analyze, vars_seen, global_vars_seen
-            )
+            else:
+                func_body = generalize_check_lines(
+                    func_body, False, vars_seen, global_vars_seen
+                )
 
             # This could be selectively enabled with an optional invocation argument.
             # Disabled for now: better to check everything. Be safe rather than sorry.
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index ac0df3c51176dd4..03053e5447d1197 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -187,10 +187,6 @@ def main():
             if is_in_function:
                 if common.should_add_line_to_output(input_line, prefix_set):
                     # This input line of the function body will go as-is into the output.
-                    # Except make leading whitespace uniform: 2 spaces.
-                    input_line = common.SCRUB_LEADING_WHITESPACE_RE.sub(
-                        r"  ", input_line
-                    )
                     output_lines.append(input_line)
                 else:
                     continue



More information about the llvm-commits mailing list