[llvm] edf56f1 - [LoopInterchange] Don't rely on ASSERTS build for tests. NFC. (#116780)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 05:56:59 PST 2024


Author: Sjoerd Meijer
Date: 2024-11-19T13:56:55Z
New Revision: edf56f1fa27dce36c2b537290c26fec1af1a1140

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

LOG: [LoopInterchange] Don't rely on ASSERTS build for tests. NFC. (#116780)

A lot of interchange tests unnecessary relied on a build with ASSERTS
enabled. Instead, simply check the IR output for both negative and
positive tests so that we don't rely on debug messages. This increases
test coverage as these tests will now also run with non-assert builds.
For a couple of files keeping some of the debug tests was useful, so
separated out them out and moved them to a similarly named *-remarks.ll
file.

Added: 
    llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll
    llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll

Modified: 
    llvm/test/Transforms/LoopInterchange/call-instructions.ll
    llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
    llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
    llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll
    llvm/test/Transforms/LoopInterchange/interchange-no-deps.ll
    llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-3.ll
    llvm/test/Transforms/LoopInterchange/not-interchanged-dependencies-1.ll
    llvm/test/Transforms/LoopInterchange/not-interchanged-loop-nest-3.ll
    llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll b/llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll
new file mode 100644
index 00000000000000..4ed3e7e0f5d003
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll
@@ -0,0 +1,63 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
+; RUN:     -verify-dom-info -verify-loop-info 2>&1
+; RUN: FileCheck --input-file=%t %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+ at A = common global [100 x [100 x i32]] zeroinitializer
+
+declare void @foo(i64 %a)
+declare void @bar(i64 %a) readnone
+
+;;--------------------------------------Test case 01------------------------------------
+;; Not safe to interchange, because the called function `foo` is not marked as
+;; readnone, so it could introduce dependences.
+;;
+;;  for(int i=0;i<100;i++) {
+;;    for(int j=1;j<100;j++) {
+;;      foo(i);
+;;      A[j][i] = A[j][i]+k;
+;;    }
+;; }
+
+; CHECK: --- !Missed
+; CHECK-NEXT: Pass:            loop-interchange
+; CHECK-NEXT: Name:            CallInst
+; CHECK-NEXT: Function:        interchange_01
+; CHECK-NEXT: Args:
+; CHECK-NEXT: - String:          Cannot interchange loops due to call instruction.
+
+define void @interchange_01(i32 %k) {
+entry:
+  br label %for1.header
+
+for1.header:
+  %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc10 ]
+  br label %for2
+
+for2:
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for2 ], [ 1, %for1.header ]
+  call void @foo(i64 %indvars.iv23)
+  %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
+  %lv = load i32, ptr %arrayidx5
+  %add = add nsw i32 %lv, %k
+  store i32 %add, ptr %arrayidx5
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %exitcond = icmp eq i64 %indvars.iv, 99
+  br i1 %exitcond, label %for2.loopexit , label %for2
+
+for2.loopexit:
+  br label %for1.inc10
+
+for1.inc10:
+  %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
+  %exitcond26 = icmp eq i64 %indvars.iv23, 99
+  br i1 %exitcond26, label %for1.loopexit, label %for1.header
+
+for1.loopexit:
+  br label %exit
+
+exit:
+  ret void
+}

diff  --git a/llvm/test/Transforms/LoopInterchange/call-instructions.ll b/llvm/test/Transforms/LoopInterchange/call-instructions.ll
index 49e877aa0d36e7..b207166302d21c 100644
--- a/llvm/test/Transforms/LoopInterchange/call-instructions.ll
+++ b/llvm/test/Transforms/LoopInterchange/call-instructions.ll
@@ -1,7 +1,5 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
-; RUN:     -verify-dom-info -verify-loop-info -stats 2>&1 | FileCheck -check-prefix=STATS %s
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -S -verify-dom-info -verify-loop-info 2>&1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
@@ -10,58 +8,6 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 declare void @foo(i64 %a)
 declare void @bar(i64 %a) readnone
 
-;;--------------------------------------Test case 01------------------------------------
-;; Not safe to interchange, because the called function `foo` is not marked as
-;; readnone, so it could introduce dependences.
-;;
-;;  for(int i=0;i<100;i++) {
-;;    for(int j=1;j<100;j++) {
-;;      foo(i);
-;;      A[j][i] = A[j][i]+k;
-;;    }
-;; }
-
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass:            loop-interchange
-; CHECK-NEXT: Name:            CallInst
-; CHECK-NEXT: Function:        interchange_01
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String:          Cannot interchange loops due to call instruction.
-
-define void @interchange_01(i32 %k) {
-entry:
-  br label %for1.header
-
-for1.header:
-  %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc10 ]
-  br label %for2
-
-for2:
-  %indvars.iv = phi i64 [ %indvars.iv.next, %for2 ], [ 1, %for1.header ]
-  call void @foo(i64 %indvars.iv23)
-  %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
-  %lv = load i32, ptr %arrayidx5
-  %add = add nsw i32 %lv, %k
-  store i32 %add, ptr %arrayidx5
-  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
-  %exitcond = icmp eq i64 %indvars.iv, 99
-  br i1 %exitcond, label %for2.loopexit , label %for2
-
-for2.loopexit:
-  br label %for1.inc10
-
-for1.inc10:
-  %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
-  %exitcond26 = icmp eq i64 %indvars.iv23, 99
-  br i1 %exitcond26, label %for1.loopexit, label %for1.header
-
-for1.loopexit:
-  br label %exit
-
-exit:
-  ret void
-}
-
 ;;--------------------------------------Test case 02------------------------------------
 ;; Safe to interchange, because the called function `bar` is marked as readnone,
 ;; so it cannot introduce dependences.
@@ -72,16 +18,46 @@ exit:
 ;;      A[j][i] = A[j][i]+k;
 ;;    }
 ;; }
-
-; CHECK: --- !Passed
-; CHECK-NEXT: Pass:            loop-interchange
-; CHECK-NEXT: Name:            Interchanged
-; CHECK-NEXT: Function:        interchange_02
-; CHECK-NEXT: Args:
-; CHECK-NEXT:   - String:          Loop interchanged with enclosing loop.
-; CHECK-NEXT: ...
-
+;
 define void @interchange_02(i32 %k) {
+; CHECK-LABEL: define void @interchange_02(
+; CHECK-SAME: i32 [[K:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[FOR2_PREHEADER:.*]]
+; CHECK:       [[FOR1_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR1_HEADER:.*]]
+; CHECK:       [[FOR1_HEADER]]:
+; CHECK-NEXT:    [[INDVARS_IV23:%.*]] = phi i64 [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR1_INC10:.*]] ], [ 0, %[[FOR1_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR2_SPLIT1:.*]]
+; CHECK:       [[FOR2_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR2:.*]]
+; CHECK:       [[FOR2]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR2_SPLIT:.*]] ], [ 1, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR1_HEADER_PREHEADER]]
+; CHECK:       [[FOR2_SPLIT1]]:
+; CHECK-NEXT:    call void @bar(i64 [[INDVARS_IV23]])
+; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LV]], [[K]]
+; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV]], 99
+; CHECK-NEXT:    br label %[[FOR2_LOOPEXIT:.*]]
+; CHECK:       [[FOR2_SPLIT]]:
+; CHECK-NEXT:    [[TMP0]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[INDVARS_IV]], 99
+; CHECK-NEXT:    br i1 [[TMP1]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR2]]
+; CHECK:       [[FOR2_LOOPEXIT]]:
+; CHECK-NEXT:    br label %[[FOR1_INC10]]
+; CHECK:       [[FOR1_INC10]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT:    [[EXITCOND26:%.*]] = icmp eq i64 [[INDVARS_IV23]], 99
+; CHECK-NEXT:    br i1 [[EXITCOND26]], label %[[FOR2_SPLIT]], label %[[FOR1_HEADER]]
+; CHECK:       [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT:    br label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   br label %for1.header
 
@@ -114,6 +90,3 @@ for1.loopexit:
 exit:
   ret void
 }
-
-; Check stats, we interchanged 1 out of 2 loops.
-; STATS: 1 loop-interchange - Number of loops interchanged

diff  --git a/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll
new file mode 100644
index 00000000000000..51fa6469cdbbbf
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll
@@ -0,0 +1,117 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S -debug 2>&1 | FileCheck %s
+
+ at A = common global [100 x [100 x i64]] zeroinitializer
+ at N = dso_local local_unnamed_addr global i64 100, align 8
+
+;  for(int i=0;i<100;i++)
+;    for(int j=0;j<i;j++)
+;      A[j][i] = A[j][i]+k;
+;
+; Inner loop induction variable exit condition depends on the
+; outer loop induction variable, i.e., triangular loops.
+;
+; CHECK: Loop structure not understood by pass
+; CHECK: Not interchanging loops. Cannot prove legality.
+;
+define void @interchange_01(i64 %k) {
+entry:
+  br label %for1.header
+
+for1.header:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
+  br label %for2
+
+for2:
+  %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
+  %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
+  %lv = load i64, ptr %arrayidx5
+  %add = add nsw i64 %lv, %k
+  store i64 %add, ptr %arrayidx5
+  %j.next = add nuw nsw i64 %j, 1
+  %exitcond = icmp eq i64 %j, %i
+  br i1 %exitcond, label %for1.inc10, label %for2
+
+for1.inc10:
+  %i.next = add nuw nsw i64 %i, 1
+  %exitcond26 = icmp eq i64 %i, 99
+  br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+  ret void
+}
+
+
+;  for(int i=0;i<100;i++)
+;    for(int j=0;j+i<100;j++)
+;      A[j][i] = A[j][i]+k;
+;
+; Inner loop induction variable exit condition depends on the
+; outer loop induction variable, i.e., triangular loops.
+;
+; CHECK: Loop structure not understood by pass
+; CHECK: Not interchanging loops. Cannot prove legality.
+;
+define void @interchange_02(i64 %k) {
+entry:
+  br label %for1.header
+
+for1.header:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
+  br label %for2
+
+for2:
+  %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
+  %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
+  %lv = load i64, ptr %arrayidx5
+  %add = add nsw i64 %lv, %k
+  store i64 %add, ptr %arrayidx5
+  %0 = add nuw nsw i64 %j, %i
+  %j.next = add nuw nsw i64 %j, 1
+  %exitcond = icmp eq i64 %0, 100
+  br i1 %exitcond, label %for1.inc10, label %for2
+
+for1.inc10:
+  %i.next = add nuw nsw i64 %i, 1
+  %exitcond26 = icmp eq i64 %i, 99
+  br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+  ret void
+}
+
+;  for(int i=0;i<100;i++)
+;    for(int j=0;i>j;j++)
+;      A[j][i] = A[j][i]+k;
+;
+; Inner loop induction variable exit condition depends on the
+; outer loop induction variable, i.e., triangular loops.
+; CHECK: Loop structure not understood by pass
+; CHECK: Not interchanging loops. Cannot prove legality.
+;
+define void @interchange_03(i64 %k) {
+entry:
+  br label %for1.header
+
+for1.header:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
+  br label %for2
+
+for2:
+  %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
+  %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
+  %lv = load i64, ptr %arrayidx5
+  %add = add nsw i64 %lv, %k
+  store i64 %add, ptr %arrayidx5
+  %j.next = add nuw nsw i64 %j, 1
+  %exitcond = icmp ne i64 %i, %j
+  br i1 %exitcond, label %for2, label %for1.inc10
+
+for1.inc10:
+  %i.next = add nuw nsw i64 %i, 1
+  %exitcond26 = icmp eq i64 %i, 99
+  br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+  ret void
+}

diff  --git a/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
index 0a1d1e52507994..ff88375e318567 100644
--- a/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
+++ b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
@@ -1,130 +1,47 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 @A = common global [100 x [100 x i64]] zeroinitializer
 @N = dso_local local_unnamed_addr global i64 100, align 8
 
-
-;;  for(int i=0;i<100;i++)
-;;    for(int j=0;j<i;j++)
-;;      A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on the
-;; outer loop induction variable, i.e., triangular loops.
-; CHECK: Loop structure not understood by pass
-; CHECK: Not interchanging loops. Cannot prove legality.
-
-define void @interchange_01(i64 %k) {
-entry:
-  br label %for1.header
-
-for1.header:
-  %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
-  br label %for2
-
-for2:
-  %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
-  %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
-  %lv = load i64, ptr %arrayidx5
-  %add = add nsw i64 %lv, %k
-  store i64 %add, ptr %arrayidx5
-  %j.next = add nuw nsw i64 %j, 1
-  %exitcond = icmp eq i64 %j, %i
-  br i1 %exitcond, label %for1.inc10, label %for2
-
-for1.inc10:
-  %i.next = add nuw nsw i64 %i, 1
-  %exitcond26 = icmp eq i64 %i, 99
-  br i1 %exitcond26, label %for.end12, label %for1.header
-
-for.end12:
-  ret void
-}
-
-
-;;  for(int i=0;i<100;i++)
-;;    for(int j=0;j+i<100;j++)
-;;      A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on the
-;; outer loop induction variable, i.e., triangular loops.
-; CHECK: Loop structure not understood by pass
-; CHECK: Not interchanging loops. Cannot prove legality.
-
-define void @interchange_02(i64 %k) {
-entry:
-  br label %for1.header
-
-for1.header:
-  %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
-  br label %for2
-
-for2:
-  %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
-  %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
-  %lv = load i64, ptr %arrayidx5
-  %add = add nsw i64 %lv, %k
-  store i64 %add, ptr %arrayidx5
-  %0 = add nuw nsw i64 %j, %i
-  %j.next = add nuw nsw i64 %j, 1
-  %exitcond = icmp eq i64 %0, 100
-  br i1 %exitcond, label %for1.inc10, label %for2
-
-for1.inc10:
-  %i.next = add nuw nsw i64 %i, 1
-  %exitcond26 = icmp eq i64 %i, 99
-  br i1 %exitcond26, label %for.end12, label %for1.header
-
-for.end12:
-  ret void
-}
-
-;;  for(int i=0;i<100;i++)
-;;    for(int j=0;i>j;j++)
-;;      A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on the
-;; outer loop induction variable, i.e., triangular loops.
-; CHECK: Loop structure not understood by pass
-; CHECK: Not interchanging loops. Cannot prove legality.
-
-define void @interchange_03(i64 %k) {
-entry:
-  br label %for1.header
-
-for1.header:
-  %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
-  br label %for2
-
-for2:
-  %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
-  %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
-  %lv = load i64, ptr %arrayidx5
-  %add = add nsw i64 %lv, %k
-  store i64 %add, ptr %arrayidx5
-  %j.next = add nuw nsw i64 %j, 1
-  %exitcond = icmp ne i64 %i, %j
-  br i1 %exitcond, label %for2, label %for1.inc10
-
-for1.inc10:
-  %i.next = add nuw nsw i64 %i, 1
-  %exitcond26 = icmp eq i64 %i, 99
-  br i1 %exitcond26, label %for.end12, label %for1.header
-
-for.end12:
-  ret void
-}
-
-;;  for(int i=0;i<100;i++)
-;;    for(int j=0;N>j;j++)
-;;      A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on
-;; an outer loop invariant, can do interchange.
-; CHECK: Loops interchanged
-
+; Inner loop induction variable exit condition depends on
+; an outer loop invariant, can do interchange.
+;
 define void @interchange_04(i64 %k) {
+; CHECK-LABEL: define void @interchange_04(
+; CHECK-SAME: i64 [[K:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @N, align 4
+; CHECK-NEXT:    br label %[[FOR2_PREHEADER:.*]]
+; CHECK:       [[FOR1_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR1_HEADER:.*]]
+; CHECK:       [[FOR1_HEADER]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[FOR1_INC10:.*]] ], [ 0, %[[FOR1_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR2_SPLIT1:.*]]
+; CHECK:       [[FOR2_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR2:.*]]
+; CHECK:       [[FOR2]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ [[TMP1:%.*]], %[[FOR2_SPLIT:.*]] ], [ 0, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR1_HEADER_PREHEADER]]
+; CHECK:       [[FOR2_SPLIT1]]:
+; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 [[J]], i64 [[I]]
+; CHECK-NEXT:    [[LV:%.*]] = load i64, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[LV]], [[K]]
+; CHECK-NEXT:    store i64 [[ADD]], ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[TMP0]], [[J]]
+; CHECK-NEXT:    br label %[[FOR1_INC10]]
+; CHECK:       [[FOR2_SPLIT]]:
+; CHECK-NEXT:    [[TMP1]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[TMP0]], [[J]]
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[FOR2]], label %[[FOR_END12:.*]]
+; CHECK:       [[FOR1_INC10]]:
+; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT:    [[EXITCOND26:%.*]] = icmp eq i64 [[I]], 99
+; CHECK-NEXT:    br i1 [[EXITCOND26]], label %[[FOR2_SPLIT]], label %[[FOR1_HEADER]]
+; CHECK:       [[FOR_END12]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   %0 = load i64, ptr @N, align 4
   br label %for1.header

diff  --git a/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll b/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
index 11e59c6db9f327..bad84224d445ab 100644
--- a/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
+++ b/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
@@ -1,19 +1,61 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 @a = common global i32 0, align 4
 @d = common dso_local local_unnamed_addr global [1 x [6 x i32]] zeroinitializer, align 4
 
-;; After interchanging the innermost and the middle loop, we should not continue
-;; doing interchange for the (new) middle loop and the outermost loop, because of
-;; values defined in the new innermost loop not available in the exiting block of
-;; the entire loop nest.
-; CHECK: Loops are legal to interchange
-; CHECK: Loops interchanged.
-; CHECK: Found unsupported PHI nodes in inner loop latch.
-; CHECK: Not interchanging loops. Cannot prove legality.
+; After interchanging the innermost and the middle loop, we should not continue
+; doing interchange for the (new) middle loop and the outermost loop, because of
+; values defined in the new innermost loop not available in the exiting block of
+; the entire loop nest.
+;
 define void @innermost_latch_uses_values_in_middle_header() {
+; CHECK-LABEL: define void @innermost_latch_uses_values_in_middle_header() {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
+; CHECK-NEXT:    [[B:%.*]] = add i32 80, 1
+; CHECK-NEXT:    br label %[[OUTERMOST_HEADER:.*]]
+; CHECK:       [[OUTERMOST_HEADER]]:
+; CHECK-NEXT:    [[INDVAR_OUTERMOST:%.*]] = phi i32 [ 10, %[[ENTRY]] ], [ [[INDVAR_OUTERMOST_NEXT:%.*]], %[[OUTERMOST_LATCH:.*]] ]
+; CHECK-NEXT:    [[TOBOOL71_I:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL71_I]], label %[[INNERMOST_HEADER_PREHEADER:.*]], label %[[OUTERMOST_LATCH]]
+; CHECK:       [[MIDDLE_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[MIDDLE_HEADER:.*]]
+; CHECK:       [[MIDDLE_HEADER]]:
+; CHECK-NEXT:    [[INDVAR_MIDDLE:%.*]] = phi i64 [ [[INDVAR_MIDDLE_NEXT:%.*]], %[[MIDDLE_LATCH:.*]] ], [ 4, %[[MIDDLE_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    [[INDVAR_MIDDLE_WIDE:%.*]] = zext i32 [[B]] to i64
+; CHECK-NEXT:    br label %[[INNERMOST_BODY:.*]]
+; CHECK:       [[INNERMOST_HEADER_PREHEADER]]:
+; CHECK-NEXT:    br label %[[INNERMOST_HEADER:.*]]
+; CHECK:       [[INNERMOST_HEADER]]:
+; CHECK-NEXT:    [[INDVAR_INNERMOST:%.*]] = phi i64 [ [[TMP1:%.*]], %[[INNERMOST_LATCH_SPLIT:.*]] ], [ 4, %[[INNERMOST_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[MIDDLE_HEADER_PREHEADER]]
+; CHECK:       [[INNERMOST_BODY]]:
+; CHECK-NEXT:    [[ARRAYIDX9_I:%.*]] = getelementptr inbounds [1 x [6 x i32]], ptr @d, i64 0, i64 [[INDVAR_INNERMOST]], i64 [[INDVAR_MIDDLE]]
+; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX9_I]], align 4
+; CHECK-NEXT:    br label %[[INNERMOST_LATCH:.*]]
+; CHECK:       [[INNERMOST_LATCH]]:
+; CHECK-NEXT:    [[INDVAR_INNERMOST_NEXT:%.*]] = add nsw i64 [[INDVAR_INNERMOST]], 1
+; CHECK-NEXT:    [[TOBOOL5_I:%.*]] = icmp eq i64 [[INDVAR_INNERMOST_NEXT]], [[INDVAR_MIDDLE_WIDE]]
+; CHECK-NEXT:    br label %[[MIDDLE_LATCH]]
+; CHECK:       [[INNERMOST_LATCH_SPLIT]]:
+; CHECK-NEXT:    [[INDVAR_MIDDLE_WIDE_LCSSA:%.*]] = phi i64 [ [[INDVAR_MIDDLE_WIDE]], %[[MIDDLE_LATCH]] ]
+; CHECK-NEXT:    [[TMP1]] = add nsw i64 [[INDVAR_INNERMOST]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], [[INDVAR_MIDDLE_WIDE_LCSSA]]
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[OUTERMOST_LATCH_LOOPEXIT:.*]], label %[[INNERMOST_HEADER]]
+; CHECK:       [[MIDDLE_LATCH]]:
+; CHECK-NEXT:    [[INDVAR_MIDDLE_NEXT]] = add nsw i64 [[INDVAR_MIDDLE]], -1
+; CHECK-NEXT:    [[TOBOOL2_I:%.*]] = icmp eq i64 [[INDVAR_MIDDLE_NEXT]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL2_I]], label %[[INNERMOST_LATCH_SPLIT]], label %[[MIDDLE_HEADER]]
+; CHECK:       [[OUTERMOST_LATCH_LOOPEXIT]]:
+; CHECK-NEXT:    br label %[[OUTERMOST_LATCH]]
+; CHECK:       [[OUTERMOST_LATCH]]:
+; CHECK-NEXT:    [[INDVAR_OUTERMOST_NEXT]] = add nsw i32 [[INDVAR_OUTERMOST]], -5
+; CHECK-NEXT:    [[TOBOOL_I:%.*]] = icmp eq i32 [[INDVAR_OUTERMOST_NEXT]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL_I]], label %[[OUTERMOST_EXIT:.*]], label %[[OUTERMOST_HEADER]]
+; CHECK:       [[OUTERMOST_EXIT]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   %0 = load i32, ptr @a, align 4
   %b = add i32 80, 1

diff  --git a/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll b/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll
index 010118370bc019..6daf61a4ec0075 100644
--- a/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll
@@ -1,6 +1,5 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
@@ -8,28 +7,70 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 @B = common global [100 x i32] zeroinitializer
 @C = common global [100 x [100 x i32]] zeroinitializer
 @D = common global [100 x [100 x [100 x i32]]] zeroinitializer
-
-;; Test that a flow dependency in outer loop doesn't prevent interchange in
-;; loops i and j.
-;;
-;;  for (int k = 0; k < 100; ++k) {
-;;    T[k] = fn1();
-;;    for (int i = 0; i < 1000; ++i)
-;;      for(int j = 1; j < 1000; ++j)
-;;        Arr[j][i] = Arr[j][i]+k;
-;;    fn2(T[k]);
-;;  }
-
-; CHECK: Processing InnerLoopId = 2 and OuterLoopId = 1
-; CHECK: Loops interchanged.
-
-; CHECK: Processing InnerLoopId = 1 and OuterLoopId = 0
-; CHECK: Not interchanging loops. Cannot prove legality.
-
 @T = internal global [100 x double] zeroinitializer, align 4
 @Arr = internal global [1000 x [1000 x i32]] zeroinitializer, align 4
 
+; Test that a flow dependency in outer loop doesn't prevent interchange in
+; loops i and j.
+;
+;  for (int k = 0; k < 100; ++k) {
+;    T[k] = fn1();
+;    for (int i = 0; i < 1000; ++i)
+;      for(int j = 1; j < 1000; ++j)
+;        Arr[j][i] = Arr[j][i]+k;
+;    fn2(T[k]);
+;  }
+;
+; So, loops InnerLoopId = 2 and OuterLoopId = 1 should be interchanged,
+; but not InnerLoopId = 1 and OuterLoopId = 0.
+;
 define void @interchange_09(i32 %k) {
+; CHECK-LABEL: define void @interchange_09(
+; CHECK-SAME: i32 [[K:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV45:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT46:%.*]], %[[FOR_COND_CLEANUP4:.*]] ]
+; CHECK-NEXT:    [[CALL:%.*]] = call double @fn1()
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x double], ptr @T, i64 0, i64 [[INDVARS_IV45]]
+; CHECK-NEXT:    store double [[CALL]], ptr [[ARRAYIDX]], align 8
+; CHECK-NEXT:    br label %[[FOR_BODY9_PREHEADER:.*]]
+; CHECK:       [[FOR_COND6_PREHEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR_COND6_PREHEADER:.*]]
+; CHECK:       [[FOR_COND6_PREHEADER]]:
+; CHECK-NEXT:    [[INDVARS_IV42:%.*]] = phi i64 [ [[INDVARS_IV_NEXT43:%.*]], %[[FOR_COND_CLEANUP8:.*]] ], [ 0, %[[FOR_COND6_PREHEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_BODY9_SPLIT1:.*]]
+; CHECK:       [[FOR_BODY9_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR_BODY9:.*]]
+; CHECK:       [[FOR_COND_CLEANUP4]]:
+; CHECK-NEXT:    [[TMP:%.*]] = load double, ptr [[ARRAYIDX]], align 8
+; CHECK-NEXT:    call void @fn2(double [[TMP]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT46]] = add nuw nsw i64 [[INDVARS_IV45]], 1
+; CHECK-NEXT:    [[EXITCOND47:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT46]], 100
+; CHECK-NEXT:    br i1 [[EXITCOND47]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+; CHECK:       [[FOR_COND_CLEANUP8]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT43]] = add nuw nsw i64 [[INDVARS_IV42]], 1
+; CHECK-NEXT:    [[EXITCOND44:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT43]], 1000
+; CHECK-NEXT:    br i1 [[EXITCOND44]], label %[[FOR_COND6_PREHEADER]], label %[[FOR_BODY9_SPLIT:.*]]
+; CHECK:       [[FOR_BODY9]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR_BODY9_SPLIT]] ], [ 1, %[[FOR_BODY9_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_COND6_PREHEADER_PREHEADER]]
+; CHECK:       [[FOR_BODY9_SPLIT1]]:
+; CHECK-NEXT:    [[ARRAYIDX13:%.*]] = getelementptr inbounds [1000 x [1000 x i32]], ptr @Arr, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV42]]
+; CHECK-NEXT:    [[T1:%.*]] = load i32, ptr [[ARRAYIDX13]], align 4
+; CHECK-NEXT:    [[T2:%.*]] = trunc i64 [[INDVARS_IV45]] to i32
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[T1]], [[T2]]
+; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX13]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 1000
+; CHECK-NEXT:    br label %[[FOR_COND_CLEANUP8]]
+; CHECK:       [[FOR_BODY9_SPLIT]]:
+; CHECK-NEXT:    [[TMP0]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[TMP0]], 1000
+; CHECK-NEXT:    br i1 [[TMP1]], label %[[FOR_BODY9]], label %[[FOR_COND_CLEANUP4]]
+;
 entry:
   br label %for.body
 
@@ -62,9 +103,9 @@ for.cond.cleanup8:                                ; preds = %for.body9
 for.body9:                                        ; preds = %for.body9, %for.cond6.preheader
   %indvars.iv = phi i64 [ 1, %for.cond6.preheader ], [ %indvars.iv.next, %for.body9 ]
   %arrayidx13 = getelementptr inbounds [1000 x [1000 x i32]], ptr @Arr, i64 0, i64 %indvars.iv, i64 %indvars.iv42
-  %tmp1 = load i32, ptr %arrayidx13, align 4
-  %tmp2 = trunc i64 %indvars.iv45 to i32
-  %add = add nsw i32 %tmp1, %tmp2
+  %t1 = load i32, ptr %arrayidx13, align 4
+  %t2 = trunc i64 %indvars.iv45 to i32
+  %add = add nsw i32 %t1, %t2
   store i32 %add, ptr %arrayidx13, align 4
   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
   %exitcond = icmp ne i64 %indvars.iv.next, 1000

diff  --git a/llvm/test/Transforms/LoopInterchange/interchange-no-deps.ll b/llvm/test/Transforms/LoopInterchange/interchange-no-deps.ll
index 718e9a8bbd3f54..9e8e30d670c51f 100644
--- a/llvm/test/Transforms/LoopInterchange/interchange-no-deps.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchange-no-deps.ll
@@ -1,22 +1,42 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes='loop(loop-interchange),simplifycfg' -cache-line-size=64 -simplifycfg-require-and-preserve-domtree=1 -pass-remarks-output=%t \
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes='loop(loop-interchange),simplifycfg' -simplifycfg-require-and-preserve-domtree=1 \
 ; RUN:     -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange -stats -S 2>&1 \
 ; RUN:     | FileCheck -check-prefix=STATS %s
-; RUN: FileCheck -input-file %t %s
-
 
 ; no_deps_interchange just accesses a single nested array and can be interchange.
-; CHECK:      Name:       Interchanged
-; CHECK-NEXT: Function:   no_deps_interchange
-define i32 @no_deps_interchange(ptr nocapture %Arr) local_unnamed_addr #0 {
+;
+define i32 @no_deps_interchange(ptr nocapture %Arr) {
+; STATS-LABEL: define i32 @no_deps_interchange(
+; STATS-SAME: ptr nocapture [[ARR:%.*]]) {
+; STATS-NEXT:  [[ENTRY:.*]]:
+; STATS-NEXT:    br label %[[FOR2:.*]]
+; STATS:       [[FOR1_HEADER:.*]]:
+; STATS-NEXT:    [[INDVARS_IV19:%.*]] = phi i64 [ [[INDVARS_IV_NEXT20:%.*]], %[[FOR1_HEADER]] ], [ 0, %[[FOR2]] ]
+; STATS-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [1024 x i32], ptr [[ARR]], i64 [[INDVARS_IV:%.*]], i64 [[INDVARS_IV19]]
+; STATS-NEXT:    store i32 0, ptr [[ARRAYIDX6]], align 4
+; STATS-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; STATS-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 1024
+; STATS-NEXT:    [[INDVARS_IV_NEXT20]] = add nuw nsw i64 [[INDVARS_IV19]], 1
+; STATS-NEXT:    [[EXITCOND21:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT20]], 1024
+; STATS-NEXT:    br i1 [[EXITCOND21]], label %[[FOR1_HEADER]], label %[[FOR2_SPLIT:.*]]
+; STATS:       [[FOR2]]:
+; STATS-NEXT:    [[INDVARS_IV]] = phi i64 [ [[TMP0:%.*]], %[[FOR2_SPLIT]] ], [ 0, %[[ENTRY]] ]
+; STATS-NEXT:    br label %[[FOR1_HEADER]]
+; STATS:       [[FOR2_SPLIT]]:
+; STATS-NEXT:    [[TMP0]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; STATS-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[TMP0]], 1024
+; STATS-NEXT:    br i1 [[TMP1]], label %[[FOR2]], label %[[EXIT:.*]]
+; STATS:       [[EXIT]]:
+; STATS-NEXT:    ret i32 0
+;
 entry:
   br label %for1.header
 
-for1.header:                                         ; preds = %entry, %for1.inc
+for1.header:
   %indvars.iv19 = phi i64 [ 0, %entry ], [ %indvars.iv.next20, %for1.inc ]
   br label %for2
 
-for2:                                        ; preds = %for1.header, %for2
+for2:
   %indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next, %for2 ]
   %arrayidx6 = getelementptr inbounds [1024 x i32], ptr %Arr, i64 %indvars.iv, i64 %indvars.iv19
   store i32 0, ptr %arrayidx6, align 4
@@ -29,23 +49,42 @@ for1.inc:
   %exitcond21 = icmp ne i64 %indvars.iv.next20, 1024
   br i1 %exitcond21, label %for1.header, label %exit
 
-exit:                                 ; preds = %for1.inc
+exit:
   ret i32 0
 
 }
 
 ; No memory access using any induction variables, interchanging not beneficial.
-; CHECK:      Name:        InterchangeNotProfitable
-; CHECK-NEXT: Function:    no_mem_instrs
+;
 define i32 @no_mem_instrs(ptr %ptr) {
+; STATS-LABEL: define i32 @no_mem_instrs(
+; STATS-SAME: ptr [[PTR:%.*]]) {
+; STATS-NEXT:  [[ENTRY:.*]]:
+; STATS-NEXT:    br label %[[FOR1_HEADER:.*]]
+; STATS:       [[FOR1_HEADER]]:
+; STATS-NEXT:    [[INDVARS_IV19:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT20:%.*]], %[[FOR1_INC:.*]] ]
+; STATS-NEXT:    br label %[[FOR2:.*]]
+; STATS:       [[FOR2]]:
+; STATS-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR1_HEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR2]] ]
+; STATS-NEXT:    store i64 [[INDVARS_IV]], ptr [[PTR]], align 4
+; STATS-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; STATS-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 1024
+; STATS-NEXT:    br i1 [[EXITCOND]], label %[[FOR2]], label %[[FOR1_INC]]
+; STATS:       [[FOR1_INC]]:
+; STATS-NEXT:    [[INDVARS_IV_NEXT20]] = add nuw nsw i64 [[INDVARS_IV19]], 1
+; STATS-NEXT:    [[EXITCOND21:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT20]], 1024
+; STATS-NEXT:    br i1 [[EXITCOND21]], label %[[FOR1_HEADER]], label %[[EXIT:.*]]
+; STATS:       [[EXIT]]:
+; STATS-NEXT:    ret i32 0
+;
 entry:
   br label %for1.header
 
-for1.header:                                         ; preds = %entry, %for1.inc
+for1.header:
   %indvars.iv19 = phi i64 [ 0, %entry ], [ %indvars.iv.next20, %for1.inc ]
   br label %for2
 
-for2:                                        ; preds = %for1.header, %for2
+for2:
   %indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next, %for2 ]
   store i64 %indvars.iv, ptr %ptr, align 4
   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
@@ -60,7 +99,3 @@ for1.inc:
 exit:                                 ; preds = %for1.inc
   ret i32 0
 }
-
-
-; Check stats, we interchanged 1 out of 3 loops.
-; STATS: 1 loop-interchange - Number of loops interchanged

diff  --git a/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-3.ll b/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-3.ll
index 18832933b8841e..6be86f1a8fdcf9 100644
--- a/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-3.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchanged-loop-nest-3.ll
@@ -1,24 +1,66 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
 @D = common global [100 x [100 x [100 x i32]]] zeroinitializer
 
-;; Test for interchange in loop nest greater than 2.
-;;  for(int i=0;i<100;i++)
-;;    for(int j=0;j<100;j++)
-;;      for(int k=0;k<100;k++)
-;;        D[k][j][i] = D[k][j][i]+t;
-
-; CHECK: Processing InnerLoopId = 2 and OuterLoopId = 1
-; CHECK: Loops interchanged.
-
-; CHECK: Processing InnerLoopId = 1 and OuterLoopId = 0
-; CHECK: Loops interchanged.
-
+; Test for interchange in loop nest greater than 2.
+;  for(int i=0;i<100;i++)
+;    for(int j=0;j<100;j++)
+;      for(int k=0;k<100;k++)
+;        D[k][j][i] = D[k][j][i]+t;
+;
+; Loops InnerLoopId = 2 and OuterLoopId = 1 should be interchanged, and then
+; also InnerLoopId = 1 and OuterLoopId = 0.
+;
 define void @interchange_08(i32 %t){
+; CHECK-LABEL: define void @interchange_08(
+; CHECK-SAME: i32 [[T:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[FOR_BODY6_PREHEADER:.*]]
+; CHECK:       [[FOR_COND1_PREHEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK:       [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT:    [[I_028:%.*]] = phi i64 [ [[INC16:%.*]], %[[FOR_INC15:.*]] ], [ 0, %[[FOR_COND1_PREHEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_BODY6_SPLIT1:.*]]
+; CHECK:       [[FOR_COND4_PREHEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR_COND4_PREHEADER:.*]]
+; CHECK:       [[FOR_COND4_PREHEADER]]:
+; CHECK-NEXT:    [[J_027:%.*]] = phi i64 [ [[TMP3:%.*]], %[[FOR_INC12_SPLIT:.*]] ], [ 0, %[[FOR_COND4_PREHEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_COND1_PREHEADER_PREHEADER]]
+; CHECK:       [[FOR_BODY6_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR_BODY6:.*]]
+; CHECK:       [[FOR_BODY6]]:
+; CHECK-NEXT:    [[K_026:%.*]] = phi i64 [ [[TMP1:%.*]], %[[FOR_BODY6_SPLIT:.*]] ], [ 0, %[[FOR_BODY6_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_COND4_PREHEADER_PREHEADER]]
+; CHECK:       [[FOR_BODY6_SPLIT1]]:
+; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds [100 x [100 x [100 x i32]]], ptr @D, i64 0, i64 [[K_026]], i64 [[J_027]], i64 [[I_028]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX8]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP0]], [[T]]
+; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX8]], align 4
+; CHECK-NEXT:    [[INC:%.*]] = add nuw nsw i64 [[K_026]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INC]], 100
+; CHECK-NEXT:    br label %[[FOR_INC12:.*]]
+; CHECK:       [[FOR_BODY6_SPLIT]]:
+; CHECK-NEXT:    [[TMP1]] = add nuw nsw i64 [[K_026]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 100
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[FOR_END17:.*]], label %[[FOR_BODY6]]
+; CHECK:       [[FOR_INC12]]:
+; CHECK-NEXT:    [[INC13:%.*]] = add nuw nsw i64 [[J_027]], 1
+; CHECK-NEXT:    [[EXITCOND29:%.*]] = icmp eq i64 [[INC13]], 100
+; CHECK-NEXT:    br label %[[FOR_INC15]]
+; CHECK:       [[FOR_INC12_SPLIT]]:
+; CHECK-NEXT:    [[TMP3]] = add nuw nsw i64 [[J_027]], 1
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i64 [[TMP3]], 100
+; CHECK-NEXT:    br i1 [[TMP4]], label %[[FOR_BODY6_SPLIT]], label %[[FOR_COND4_PREHEADER]]
+; CHECK:       [[FOR_INC15]]:
+; CHECK-NEXT:    [[INC16]] = add nuw nsw i64 [[I_028]], 1
+; CHECK-NEXT:    [[EXITCOND30:%.*]] = icmp eq i64 [[INC16]], 100
+; CHECK-NEXT:    br i1 [[EXITCOND30]], label %[[FOR_INC12_SPLIT]], label %[[FOR_COND1_PREHEADER]]
+; CHECK:       [[FOR_END17]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   br label %for.cond1.preheader
 

diff  --git a/llvm/test/Transforms/LoopInterchange/not-interchanged-dependencies-1.ll b/llvm/test/Transforms/LoopInterchange/not-interchanged-dependencies-1.ll
index ffb9f106c28806..529ebeb646690a 100644
--- a/llvm/test/Transforms/LoopInterchange/not-interchanged-dependencies-1.ll
+++ b/llvm/test/Transforms/LoopInterchange/not-interchanged-dependencies-1.ll
@@ -1,20 +1,42 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
 @A = common global [100 x [100 x i32]] zeroinitializer
 @B = common global [100 x i32] zeroinitializer
 
-;; Loops should not be interchanged in this case as it is not legal due to dependency.
-;;  for(int j=0;j<99;j++)
-;;   for(int i=0;i<99;i++)
-;;       A[j][i+1] = A[j+1][i]+k;
-
-; CHECK: Not interchanging loops. Cannot prove legality.
-
+; Loops should not be interchanged in this case as it is not legal due to dependency.
+;
+;  for(int j=0;j<99;j++)
+;   for(int i=0;i<99;i++)
+;       A[j][i+1] = A[j+1][i]+k;
+;
 define void @interchange_04(i32 %k){
+; CHECK-LABEL: define void @interchange_04(
+; CHECK-SAME: i32 [[K:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK:       [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT:    [[INDVARS_IV23:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR_INC12:.*]] ]
+; CHECK-NEXT:    [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT:    br label %[[FOR_BODY3:.*]]
+; CHECK:       [[FOR_BODY3]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY3]] ]
+; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV_NEXT24]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP0]], [[K]]
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV23]], i64 [[INDVARS_IV_NEXT]]
+; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX11]], align 4
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 99
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[FOR_INC12]], label %[[FOR_BODY3]]
+; CHECK:       [[FOR_INC12]]:
+; CHECK-NEXT:    [[EXITCOND25:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT24]], 99
+; CHECK-NEXT:    br i1 [[EXITCOND25]], label %[[FOR_END14:.*]], label %[[FOR_COND1_PREHEADER]]
+; CHECK:       [[FOR_END14]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   br label %for.cond1.preheader
 

diff  --git a/llvm/test/Transforms/LoopInterchange/not-interchanged-loop-nest-3.ll b/llvm/test/Transforms/LoopInterchange/not-interchanged-loop-nest-3.ll
index ada8fb3f33eb5c..6a7f43d19eaf2b 100644
--- a/llvm/test/Transforms/LoopInterchange/not-interchanged-loop-nest-3.ll
+++ b/llvm/test/Transforms/LoopInterchange/not-interchanged-loop-nest-3.ll
@@ -1,24 +1,61 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
 @D = common global [100 x [100 x [100 x i32]]] zeroinitializer
 
-;; Test for interchange in loop nest greater than 2.
-;;  for(int i=0;i<100;i++)
-;;    for(int j=0;j<100;j++)
-;;      for(int k=0;k<100;k++)
-;;        D[i][k][j] = D[i][k][j]+t;
-
-; CHECK: Processing InnerLoopId = 2 and OuterLoopId = 1
-; CHECK: Loops interchanged.
-
-; CHECK: Processing InnerLoopId = 1 and OuterLoopId = 0
-; CHECK: Interchanging loops not profitable.
-
+; Test for interchange in loop nest greater than 2.
+;
+;  for(int i=0;i<100;i++)
+;    for(int j=0;j<100;j++)
+;      for(int k=0;k<100;k++)
+;        D[i][k][j] = D[i][k][j]+t;
+;
+; Loops InnerLoopId = 2 and OuterLoopId = 1 should be interchanged, but not
+; loops InnerLoopId = 1 and OuterLoopId = 0 as that is not profitable.
+;
 define void @interchange_08(i32 %t){
+; CHECK-LABEL: define void @interchange_08(
+; CHECK-SAME: i32 [[T:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK:       [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT:    [[I_028:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INC16:%.*]], %[[FOR_INC15:.*]] ]
+; CHECK-NEXT:    br label %[[FOR_BODY6_PREHEADER:.*]]
+; CHECK:       [[FOR_COND4_PREHEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR_COND4_PREHEADER:.*]]
+; CHECK:       [[FOR_COND4_PREHEADER]]:
+; CHECK-NEXT:    [[J_027:%.*]] = phi i64 [ [[INC13:%.*]], %[[FOR_INC12:.*]] ], [ 0, %[[FOR_COND4_PREHEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_BODY6_SPLIT1:.*]]
+; CHECK:       [[FOR_BODY6_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR_BODY6:.*]]
+; CHECK:       [[FOR_BODY6]]:
+; CHECK-NEXT:    [[K_026:%.*]] = phi i64 [ [[TMP1:%.*]], %[[FOR_BODY6_SPLIT:.*]] ], [ 0, %[[FOR_BODY6_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_COND4_PREHEADER_PREHEADER]]
+; CHECK:       [[FOR_BODY6_SPLIT1]]:
+; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds [100 x [100 x [100 x i32]]], ptr @D, i32 0, i64 [[I_028]], i64 [[K_026]], i64 [[J_027]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX8]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP0]], [[T]]
+; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX8]], align 4
+; CHECK-NEXT:    [[INC:%.*]] = add nuw nsw i64 [[K_026]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INC]], 100
+; CHECK-NEXT:    br label %[[FOR_INC12]]
+; CHECK:       [[FOR_BODY6_SPLIT]]:
+; CHECK-NEXT:    [[TMP1]] = add nuw nsw i64 [[K_026]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 100
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[FOR_INC15]], label %[[FOR_BODY6]]
+; CHECK:       [[FOR_INC12]]:
+; CHECK-NEXT:    [[INC13]] = add nuw nsw i64 [[J_027]], 1
+; CHECK-NEXT:    [[EXITCOND29:%.*]] = icmp eq i64 [[INC13]], 100
+; CHECK-NEXT:    br i1 [[EXITCOND29]], label %[[FOR_BODY6_SPLIT]], label %[[FOR_COND4_PREHEADER]]
+; CHECK:       [[FOR_INC15]]:
+; CHECK-NEXT:    [[INC16]] = add nuw nsw i64 [[I_028]], 1
+; CHECK-NEXT:    [[EXITCOND30:%.*]] = icmp eq i64 [[INC16]], 100
+; CHECK-NEXT:    br i1 [[EXITCOND30]], label %[[FOR_END17:.*]], label %[[FOR_COND1_PREHEADER]]
+; CHECK:       [[FOR_END17]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   br label %for.cond1.preheader
 

diff  --git a/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll b/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll
index b8e569afe8645d..d8b47682bbadc1 100644
--- a/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll
+++ b/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll
@@ -1,6 +1,5 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN:     -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
@@ -9,16 +8,51 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 @C = common global [100 x [100 x i32]] zeroinitializer
 @D = common global [100 x [100 x [100 x i32]]] zeroinitializer
 
-;; Loops not tightly nested are not interchanged
-;;  for(int j=0;j<N;j++) {
-;;    B[j] = j+k;
-;;    for(int i=0;i<N;i++)
-;;      A[j][i] = A[j][i]+B[j];
-;;  }
-
-; CHECK: Not interchanging loops. Cannot prove legality.
-
+; Loops not tightly nested are not interchanged
+;
+;  for(int j=0;j<N;j++) {
+;    B[j] = j+k;
+;    for(int i=0;i<N;i++)
+;      A[j][i] = A[j][i]+B[j];
+;  }
+;
 define void @interchange_05(i32 %k, i32 %N){
+; CHECK-LABEL: define void @interchange_05(
+; CHECK-SAME: i32 [[K:%.*]], i32 [[N:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP30:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP30]], label %[[FOR_BODY_LR_PH:.*]], label %[[FOR_END17:.*]]
+; CHECK:       [[FOR_BODY_LR_PH]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[K]] to i64
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV32:%.*]] = phi i64 [ 0, %[[FOR_BODY_LR_PH]] ], [ [[INDVARS_IV_NEXT33:%.*]], %[[FOR_INC15:.*]] ]
+; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i64 [[INDVARS_IV32]], [[TMP1]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i32], ptr @B, i64 0, i64 [[INDVARS_IV32]]
+; CHECK-NEXT:    [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32
+; CHECK-NEXT:    store i32 [[TMP3]], ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT:    br label %[[FOR_BODY3:.*]]
+; CHECK:       [[FOR_BODY3]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_BODY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY3]] ]
+; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV32]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX7]], align 4
+; CHECK-NEXT:    [[ADD10:%.*]] = add nsw i32 [[TMP3]], [[TMP4]]
+; CHECK-NEXT:    store i32 [[ADD10]], ptr [[ARRAYIDX7]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[TMP0]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[FOR_INC15]], label %[[FOR_BODY3]]
+; CHECK:       [[FOR_INC15]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT33]] = add nuw nsw i64 [[INDVARS_IV32]], 1
+; CHECK-NEXT:    [[LFTR_WIDEIV35:%.*]] = trunc i64 [[INDVARS_IV32]] to i32
+; CHECK-NEXT:    [[EXITCOND36:%.*]] = icmp eq i32 [[LFTR_WIDEIV35]], [[TMP0]]
+; CHECK-NEXT:    br i1 [[EXITCOND36]], label %[[FOR_END17_LOOPEXIT:.*]], label %[[FOR_BODY]]
+; CHECK:       [[FOR_END17_LOOPEXIT]]:
+; CHECK-NEXT:    br label %[[FOR_END17]]
+; CHECK:       [[FOR_END17]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   %cmp30 = icmp sgt i32 %N, 0
   br i1 %cmp30, label %for.body.lr.ph, label %for.end17
@@ -59,16 +93,46 @@ for.end17:
 
 declare void @foo(...) readnone
 
-;; Loops not tightly nested are not interchanged
-;;  for(int j=0;j<N;j++) {
-;;    foo();
-;;    for(int i=2;i<N;i++)
-;;      A[j][i] = A[j][i]+k;
-;;  }
-
-; CHECK: Not interchanging loops. Cannot prove legality.
-
+; Loops not tightly nested are not interchanged
+;  for(int j=0;j<N;j++) {
+;    foo();
+;    for(int i=2;i<N;i++)
+;      A[j][i] = A[j][i]+k;
+;  }
+;
 define void @interchange_06(i32 %k, i32 %N) {
+; CHECK-LABEL: define void @interchange_06(
+; CHECK-SAME: i32 [[K:%.*]], i32 [[N:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP22:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP22]], label %[[FOR_BODY_LR_PH:.*]], label %[[FOR_END12:.*]]
+; CHECK:       [[FOR_BODY_LR_PH]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N]], -1
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV24:%.*]] = phi i64 [ 0, %[[FOR_BODY_LR_PH]] ], [ [[INDVARS_IV_NEXT25:%.*]], %[[FOR_INC10:.*]] ]
+; CHECK-NEXT:    tail call void (...) @foo()
+; CHECK-NEXT:    br label %[[FOR_BODY3:.*]]
+; CHECK:       [[FOR_BODY3]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY3]] ], [ 2, %[[FOR_BODY]] ]
+; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV24]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP1]], [[K]]
+; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[TMP0]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[FOR_INC10]], label %[[FOR_BODY3]]
+; CHECK:       [[FOR_INC10]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT25]] = add nuw nsw i64 [[INDVARS_IV24]], 1
+; CHECK-NEXT:    [[LFTR_WIDEIV26:%.*]] = trunc i64 [[INDVARS_IV24]] to i32
+; CHECK-NEXT:    [[EXITCOND27:%.*]] = icmp eq i32 [[LFTR_WIDEIV26]], [[TMP0]]
+; CHECK-NEXT:    br i1 [[EXITCOND27]], label %[[FOR_END12_LOOPEXIT:.*]], label %[[FOR_BODY]]
+; CHECK:       [[FOR_END12_LOOPEXIT]]:
+; CHECK-NEXT:    br label %[[FOR_END12]]
+; CHECK:       [[FOR_END12]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   %cmp22 = icmp sgt i32 %N, 0
   br i1 %cmp22, label %for.body.lr.ph, label %for.end12
@@ -103,11 +167,41 @@ for.end12:
   ret void
 }
 
-;; The following Loop is not considered tightly nested and is not interchanged.
-;; The outer loop header does not branch to the inner loop preheader, or the
-;; inner loop header, or the outer loop latch.
-; CHECK: Not interchanging loops. Cannot prove legality.
+; The following Loop is not considered tightly nested and is not interchanged.
+; The outer loop header does not branch to the inner loop preheader, or the
+; inner loop header, or the outer loop latch.
+;
 define void @interchange_07(i32 %k, i32 %N, i64 %ny) {
+; CHECK-LABEL: define void @interchange_07(
+; CHECK-SAME: i32 [[K:%.*]], i32 [[N:%.*]], i64 [[NY:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR1_HEADER:.*]]
+; CHECK:       [[FOR1_HEADER]]:
+; CHECK-NEXT:    [[J23:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[J_NEXT24:%.*]], %[[FOR1_INC10:.*]] ]
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp slt i64 0, [[NY]]
+; CHECK-NEXT:    br label %[[SINGLESUCC:.*]]
+; CHECK:       [[SINGLESUCC]]:
+; CHECK-NEXT:    br i1 [[CMP21]], label %[[PREHEADER_J:.*]], label %[[FOR1_INC10]]
+; CHECK:       [[PREHEADER_J]]:
+; CHECK-NEXT:    br label %[[FOR2:.*]]
+; CHECK:       [[FOR2]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ [[J_NEXT:%.*]], %[[FOR2]] ], [ 0, %[[PREHEADER_J]] ]
+; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[J]], i64 [[J23]]
+; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LV]], [[K]]
+; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT:    [[J_NEXT]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[J]], 99
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[FOR1_INC10_LOOPEXIT:.*]], label %[[FOR2]]
+; CHECK:       [[FOR1_INC10_LOOPEXIT]]:
+; CHECK-NEXT:    br label %[[FOR1_INC10]]
+; CHECK:       [[FOR1_INC10]]:
+; CHECK-NEXT:    [[J_NEXT24]] = add nuw nsw i64 [[J23]], 1
+; CHECK-NEXT:    [[EXITCOND26:%.*]] = icmp eq i64 [[J23]], 99
+; CHECK-NEXT:    br i1 [[EXITCOND26]], label %[[FOR_END12:.*]], label %[[FOR1_HEADER]]
+; CHECK:       [[FOR_END12]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   br label %for1.header
 


        


More information about the llvm-commits mailing list