[llvm] d6abc8f - [LoopInterchange] Use UTC as much as possible (NFC) (#202096)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 00:58:35 PDT 2026
Author: Ryotaro Kasuga
Date: 2026-06-11T07:58:29Z
New Revision: d6abc8f78de200e045ce3bdcb4cc57a7f1b7c5c6
URL: https://github.com/llvm/llvm-project/commit/d6abc8f78de200e045ce3bdcb4cc57a7f1b7c5c6
DIFF: https://github.com/llvm/llvm-project/commit/d6abc8f78de200e045ce3bdcb4cc57a7f1b7c5c6.diff
LOG: [LoopInterchange] Use UTC as much as possible (NFC) (#202096)
Historically, the loop-interchange tests have relied heavily on checks
via pass remarks. This is because pass remarks are more human-readable
than the CHECK directives generated by UTC. However, during recent
development, I found some downsides:
- Updating them manually is a bit tedious.
- We need to carefully keep the remarks and the code consistent with
each other. In other words, we don't have any way to verify whether the
remarks themselves are reasonable.
For these reasons, I now think it makes more sense to rely on UTC as
much as possible, and this patch does that. Some tests are left as-is,
e.g., the test for checking remarks.
Disclosure: This patch is assisted-by Claude Code.
Added:
Modified:
llvm/test/Transforms/LoopInterchange/confused-dependence.ll
llvm/test/Transforms/LoopInterchange/currentLimitation.ll
llvm/test/Transforms/LoopInterchange/debuginfo.ll
llvm/test/Transforms/LoopInterchange/force-interchange.ll
llvm/test/Transforms/LoopInterchange/fp-reductions.ll
llvm/test/Transforms/LoopInterchange/guarded-inner-loop.ll
llvm/test/Transforms/LoopInterchange/inner-only-reductions.ll
llvm/test/Transforms/LoopInterchange/interchange-insts-between-indvar.ll
llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
llvm/test/Transforms/LoopInterchange/loopnest-with-outer-btc0.ll
llvm/test/Transforms/LoopInterchange/multilevel-partial-reduction.ll
llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
llvm/test/Transforms/LoopInterchange/outer-only-reductions.ll
llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll
llvm/test/Transforms/LoopInterchange/pr43326.ll
llvm/test/Transforms/LoopInterchange/pr48212.ll
llvm/test/Transforms/LoopInterchange/profitability-redundant-interchange.ll
llvm/test/Transforms/LoopInterchange/profitability-vectorization-heuristic.ll
llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/LoopInterchange/confused-dependence.ll b/llvm/test/Transforms/LoopInterchange/confused-dependence.ll
index 94080949f0af8..da04aee3c210b 100644
--- a/llvm/test/Transforms/LoopInterchange/confused-dependence.ll
+++ b/llvm/test/Transforms/LoopInterchange/confused-dependence.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t \
-; RUN: -disable-output
-; RUN: FileCheck -input-file %t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -S | FileCheck %s
;; In the following case, p0 and p1 may alias, so the direction vector must be [* *].
;;
@@ -10,14 +9,30 @@
;; p0[4 * i + j] = p1[4 * j + i];
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: may_alias
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
-; CHECK-NEXT: ...
define void @may_alias(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define void @may_alias(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ]
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_I_HEADER]] ], [ [[J_INC:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[IDX_0:%.*]] = getelementptr inbounds [4 x [4 x float]], ptr [[P0]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[IDX_1:%.*]] = getelementptr inbounds [4 x [4 x float]], ptr [[P1]], i32 0, i32 [[I]], i32 [[J]]
+; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[IDX_0]], align 4
+; CHECK-NEXT: store float [[TMP0]], ptr [[IDX_1]], align 4
+; CHECK-NEXT: [[J_INC]] = add nuw nsw i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 4
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_J]], label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 4
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
diff --git a/llvm/test/Transforms/LoopInterchange/currentLimitation.ll b/llvm/test/Transforms/LoopInterchange/currentLimitation.ll
index 898627b05eacb..6244b9935817e 100644
--- a/llvm/test/Transforms/LoopInterchange/currentLimitation.ll
+++ b/llvm/test/Transforms/LoopInterchange/currentLimitation.ll
@@ -1,11 +1,9 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' \
-; RUN: -pass-remarks-output=%t -verify-loop-info -verify-dom-info -S | FileCheck -check-prefix=IR %s
-; RUN: FileCheck --input-file=%t %s
-
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' \
-; RUN: -da-disable-delinearization-checks -pass-remarks-output=%t \
-; RUN: -verify-loop-info -verify-dom-info -S | FileCheck -check-prefix=IR %s
-; RUN: FileCheck --check-prefix=DELIN --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-loop-info \
+; RUN: -verify-dom-info -S | FileCheck %s
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \
+; RUN: -da-disable-delinearization-checks -verify-loop-info -verify-dom-info -S \
+; RUN: | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -22,59 +20,113 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
;; for(int j=1;j<N-1;j++)
;; A[j+1][i+1] = A[j+1][i+1] + k;
-; CHECK: Name: Dependence
-; CHECK-NEXT: Function: interchange_01
; Guarded nest: %for.cond1.preheader runs the inner loop only when
; %cmp324 = (N-1 > 1). The inner exit (inner IV == N-2) only terminates under
-; that guard, so interchanging it loops forever for N == 2.
-; DELIN: Name: NotTightlyNested
-; DELIN-NEXT: Function: interchange_01
+; that guard, so interchanging it loops forever for N == 2.
define void @interchange_01(i32 %k, i32 %N) {
- entry:
- %sub = add nsw i32 %N, -1
- %cmp26 = icmp sgt i32 %N, 1
- br i1 %cmp26, label %for.cond1.preheader.lr.ph, label %for.end17
-
- for.cond1.preheader.lr.ph:
- %cmp324 = icmp sgt i32 %sub, 1
- %0 = add i32 %N, -2
- %1 = sext i32 %sub to i64
- br label %for.cond1.preheader
-
- for.cond.loopexit:
- %cmp = icmp slt i64 %indvars.iv.next29, %1
- br i1 %cmp, label %for.cond1.preheader, label %for.end17
-
- for.cond1.preheader:
- %indvars.iv28 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next29, %for.cond.loopexit ]
- %indvars.iv.next29 = add nuw nsw i64 %indvars.iv28, 1
- br i1 %cmp324, label %for.body4, label %for.cond.loopexit
-
- for.body4:
- %indvars.iv = phi i64 [ %indvars.iv.next, %for.body4 ], [ 1, %for.cond1.preheader ]
- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
- %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 %indvars.iv.next, i64 %indvars.iv.next29
- %2 = load i32, ptr %arrayidx7
- %add8 = add nsw i32 %2, %k
- store i32 %add8, ptr %arrayidx7
- %lftr.wideiv = trunc i64 %indvars.iv to i32
- %exitcond = icmp eq i32 %lftr.wideiv, %0
- br i1 %exitcond, label %for.cond.loopexit, label %for.body4
-
- for.end17:
- ret void
+; CHECK-LABEL: define void @interchange_01(
+; CHECK-SAME: i32 [[K:%.*]], i32 [[N:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[N]], -1
+; CHECK-NEXT: [[CMP26:%.*]] = icmp sgt i32 [[N]], 1
+; CHECK-NEXT: br i1 [[CMP26]], label %[[FOR_COND1_PREHEADER_LR_PH:.*]], label %[[FOR_END17:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_LR_PH]]:
+; CHECK-NEXT: [[CMP324:%.*]] = icmp sgt i32 [[SUB]], 1
+; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -2
+; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[SUB]] to i64
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND_LOOPEXIT_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND_LOOPEXIT:.*]]
+; CHECK: [[FOR_COND_LOOPEXIT]]:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT29:%.*]], [[TMP1]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_END17_LOOPEXIT:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV28:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER_LR_PH]] ], [ [[INDVARS_IV_NEXT29]], %[[FOR_COND_LOOPEXIT]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT29]] = add nuw nsw i64 [[INDVARS_IV28]], 1
+; CHECK-NEXT: br i1 [[CMP324]], label %[[FOR_BODY4_PREHEADER:.*]], label %[[FOR_COND_LOOPEXIT]]
+; CHECK: [[FOR_BODY4_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_BODY4:.*]]
+; CHECK: [[FOR_BODY4]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY4]] ], [ 1, %[[FOR_BODY4_PREHEADER]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV_NEXT]], i64 [[INDVARS_IV_NEXT29]]
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX7]], align 4
+; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP2]], [[K]]
+; CHECK-NEXT: store i32 [[ADD8]], ptr [[ARRAYIDX7]], align 4
+; 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_COND_LOOPEXIT_LOOPEXIT]], label %[[FOR_BODY4]]
+; CHECK: [[FOR_END17_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_END17]]
+; CHECK: [[FOR_END17]]:
+; CHECK-NEXT: ret void
+;
+ entry:
+ %sub = add nsw i32 %N, -1
+ %cmp26 = icmp sgt i32 %N, 1
+ br i1 %cmp26, label %for.cond1.preheader.lr.ph, label %for.end17
+
+ for.cond1.preheader.lr.ph:
+ %cmp324 = icmp sgt i32 %sub, 1
+ %0 = add i32 %N, -2
+ %1 = sext i32 %sub to i64
+ br label %for.cond1.preheader
+
+ for.cond.loopexit:
+ %cmp = icmp slt i64 %indvars.iv.next29, %1
+ br i1 %cmp, label %for.cond1.preheader, label %for.end17
+
+ for.cond1.preheader:
+ %indvars.iv28 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next29, %for.cond.loopexit ]
+ %indvars.iv.next29 = add nuw nsw i64 %indvars.iv28, 1
+ br i1 %cmp324, label %for.body4, label %for.cond.loopexit
+
+ for.body4:
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body4 ], [ 1, %for.cond1.preheader ]
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 %indvars.iv.next, i64 %indvars.iv.next29
+ %2 = load i32, ptr %arrayidx7
+ %add8 = add nsw i32 %2, %k
+ store i32 %add8, ptr %arrayidx7
+ %lftr.wideiv = trunc i64 %indvars.iv to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, %0
+ br i1 %exitcond, label %for.cond.loopexit, label %for.body4
+
+ for.end17:
+ ret void
}
; When currently cannot interchange this loop, because transform currently
; expects the latches to be the exiting blocks too.
-; IR-LABEL: @interchange_02
-; IR-NOT: split
;
-; CHECK: Name: ExitingNotLatch
-; CHECK-NEXT: Function: interchange_02
define void @interchange_02(i64 %k, i64 %N) {
+; CHECK-LABEL: define void @interchange_02(
+; CHECK-SAME: i64 [[K:%.*]], i64 [[N:%.*]]) {
+; 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: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_NEXT:%.*]], %[[LATCH:.*]] ], [ 0, %[[FOR1_HEADER]] ]
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr @C, i64 0, i64 [[J]], i64 [[J23]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX5]], align 8
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[LV]], [[K]]
+; CHECK-NEXT: store i64 [[ADD]], ptr [[ARRAYIDX5]], align 8
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[J]], 99
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR1_INC10]], label %[[LATCH]]
+; CHECK: [[LATCH]]:
+; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: br label %[[FOR2]]
+; 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
diff --git a/llvm/test/Transforms/LoopInterchange/debuginfo.ll b/llvm/test/Transforms/LoopInterchange/debuginfo.ll
index 87f4208ad0a1c..5deb52ea18306 100644
--- a/llvm/test/Transforms/LoopInterchange/debuginfo.ll
+++ b/llvm/test/Transforms/LoopInterchange/debuginfo.ll
@@ -1,7 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks='loop-interchange' -pass-remarks-output=%t -S \
-; RUN: -verify-dom-info -verify-loop-info | FileCheck %s
-; RUN: FileCheck -check-prefix=REMARK --input-file=%t %s
-
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -11,11 +9,44 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
;; for(int j=0;j<100;j++)
;; A[j][i] = A[j][i]+k;
-; REMARK: Name: Interchanged
-; REMARK-NEXT: Function: interchange_01
-; CHECK: split
-
define void @interchange_01(i64 %k, i64 %N) !dbg !5 {
+; CHECK-LABEL: define void @interchange_01(
+; CHECK-SAME: i64 [[K:%.*]], i64 [[N:%.*]]) !dbg [[DBG5:![0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR2_PREHEADER:.*]]
+; CHECK: [[FOR1_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[J23:%.*]] = phi i64 [ [[J_NEXT24:%.*]], %[[FOR1_INC10:.*]] ], [ 0, %[[FOR1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: #dbg_value(i64 [[J:%.*]], [[META13:![0-9]+]], !DIExpression(), [[META14:![0-9]+]])
+; CHECK-NEXT: br label %[[FOR2_SPLIT1:.*]]
+; CHECK: [[FOR2_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[J]] = phi i64 [ [[TMP0:%.*]], %[[FOR2_SPLIT:.*]] ], [ 0, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR1_HEADER_PREHEADER]]
+; CHECK: [[FOR2_SPLIT1]]:
+; CHECK-NEXT: #dbg_value(i64 [[J]], [[META13]], !DIExpression(), [[META14]])
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 [[J]], i64 [[J23]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX5]], align 8
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[LV]], [[K]]
+; CHECK-NEXT: store i64 [[ADD]], ptr [[ARRAYIDX5]], align 8
+; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[J]], 99
+; CHECK-NEXT: #dbg_value(i64 [[J]], [[META13]], !DIExpression(), [[META14]])
+; CHECK-NEXT: br label %[[FOR1_INC10]]
+; CHECK: [[FOR2_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[J]], 99
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_END12:.*]], label %[[FOR2]]
+; CHECK: [[FOR1_INC10]]:
+; CHECK-NEXT: [[J_NEXT24]] = add nuw nsw i64 [[J23]], 1
+; CHECK-NEXT: #dbg_value(i64 [[J]], [[META13]], !DIExpression(), [[META14]])
+; CHECK-NEXT: [[EXITCOND26:%.*]] = icmp eq i64 [[J23]], 99
+; CHECK-NEXT: br i1 [[EXITCOND26]], label %[[FOR2_SPLIT]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR_END12]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for1.header
@@ -67,3 +98,18 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
!12 = !{!13}
!13 = !DILocalVariable(name: "a", arg: 1, scope: !5, file: !1, line: 1, type: !8)
!14 = !DILocation(line: 1, column: 27, scope: !5)
+;.
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META1:![0-9]+]], producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: [[META2:![0-9]+]])
+; CHECK: [[META1]] = !DIFile(filename: "{{.*}}test.c", directory: {{.*}})
+; CHECK: [[META2]] = !{}
+; CHECK: [[DBG5]] = distinct !DISubprogram(name: "foo", scope: [[META1]], file: [[META1]], line: 1, type: [[META6:![0-9]+]], scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12:![0-9]+]])
+; CHECK: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
+; CHECK: [[META7]] = !{null, [[META8:![0-9]+]], [[META8]], [[META11:![0-9]+]]}
+; CHECK: [[META8]] = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: [[META9:![0-9]+]])
+; CHECK: [[META9]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META10:![0-9]+]], size: 32, align: 32)
+; CHECK: [[META10]] = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float)
+; CHECK: [[META11]] = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+; CHECK: [[META12]] = !{[[META13]]}
+; CHECK: [[META13]] = !DILocalVariable(name: "a", arg: 1, scope: [[DBG5]], file: [[META1]], line: 1, type: [[META8]])
+; CHECK: [[META14]] = !DILocation(line: 1, column: 27, scope: [[DBG5]])
+;.
diff --git a/llvm/test/Transforms/LoopInterchange/force-interchange.ll b/llvm/test/Transforms/LoopInterchange/force-interchange.ll
index c33ecdf7d9905..a3ce98a42ed5c 100644
--- a/llvm/test/Transforms/LoopInterchange/force-interchange.ll
+++ b/llvm/test/Transforms/LoopInterchange/force-interchange.ll
@@ -1,23 +1,45 @@
-; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=ignore -S
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -S | FileCheck %s
; There should be no reason to interchange this, unless it is forced.
;
; for (int i = 0; i<1024; i++)
; for (int j = 0; j<1024; j++)
; A[i][j] = 42;
-;
-; CHECK: --- !Passed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: f
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
-; CHECK-NEXT: ...
@A = dso_local local_unnamed_addr global [1024 x [1024 x i32]] zeroinitializer, align 4
define dso_local void @f() local_unnamed_addr #0 {
+; CHECK-LABEL: define dso_local void @f() local_unnamed_addr {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[INNER_BODY_PREHEADER:.*]]
+; CHECK: [[OUTER_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[INNER_HEADER:.*]] ], [ 0, %[[OUTER_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[INNER_BODY_SPLIT1:.*]]
+; CHECK: [[INNER_BODY_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER_BODY:.*]]
+; CHECK: [[INNER_HEADER]]:
+; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: [[EXITCOND20_NOT:%.*]] = icmp eq i64 [[I_NEXT]], 1024
+; CHECK-NEXT: br i1 [[EXITCOND20_NOT]], label %[[INNER_BODY_SPLIT:.*]], label %[[OUTER_HEADER]]
+; CHECK: [[INNER_BODY]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[INNER_BODY_SPLIT]] ], [ 0, %[[INNER_BODY_PREHEADER]] ]
+; CHECK-NEXT: br label %[[OUTER_HEADER_PREHEADER]]
+; CHECK: [[INNER_BODY_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [1024 x [1024 x i32]], ptr @A, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: store i32 42, ptr [[ARRAYIDX6]], align 4
+; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[J_NEXT]], 1024
+; CHECK-NEXT: br label %[[INNER_HEADER]]
+; CHECK: [[INNER_BODY_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 1024
+; CHECK-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[INNER_BODY]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %outer.header
diff --git a/llvm/test/Transforms/LoopInterchange/fp-reductions.ll b/llvm/test/Transforms/LoopInterchange/fp-reductions.ll
index 0703a7b27979a..ebd48c203139a 100644
--- a/llvm/test/Transforms/LoopInterchange/fp-reductions.ll
+++ b/llvm/test/Transforms/LoopInterchange/fp-reductions.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-output=%t -disable-output \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa
-; RUN: FileCheck -input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
; Check that the loops aren't exchanged if there is a reduction of
; non-reassociative floating-point addition.
@@ -10,11 +9,32 @@
; for (int j = 0; j < 2; j++)
; sum += A[j][i];
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: UnsupportedPHIOuter
-; CHECK-NEXT: Function: reduction_fadd
define void @reduction_fadd(ptr %A) {
+; CHECK-LABEL: define void @reduction_fadd(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ]
+; CHECK-NEXT: [[SUM_I:%.*]] = phi float [ 0.000000e+00, %[[ENTRY]] ], [ [[SUM_I_LCSSA:%.*]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_I_HEADER]] ], [ [[J_INC:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[SUM_J:%.*]] = phi float [ [[SUM_I]], %[[FOR_I_HEADER]] ], [ [[SUM_J_NEXT:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[SUM_J_NEXT]] = fadd float [[SUM_J]], [[A]]
+; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_J]], label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[SUM_I_LCSSA]] = phi float [ [[SUM_J_NEXT]], %[[FOR_J]] ]
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -46,11 +66,42 @@ exit:
; Check that the interchange is legal if the floating-point addition is marked
; as reassoc.
;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_reassoc_fadd
define void @reduction_reassoc_fadd(ptr %A) {
+; CHECK-LABEL: define void @reduction_reassoc_fadd(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[SUM_J:%.*]] = phi float [ [[SUM_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[SUM_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[SUM_I]] = phi float [ [[SUM_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 0.000000e+00, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[SUM_J_NEXT]] = fadd reassoc float [[SUM_J]], [[A]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[SUM_I_LCSSA]] = phi float [ [[SUM_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -84,11 +135,42 @@ exit:
; Check that the interchange is legal if the floating-point addition is marked
; as reassoc.
;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_reassoc_ninf_fadd
define void @reduction_reassoc_ninf_fadd(ptr %A) {
+; CHECK-LABEL: define void @reduction_reassoc_ninf_fadd(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[SUM_J:%.*]] = phi float [ [[SUM_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[SUM_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[SUM_I]] = phi float [ [[SUM_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 0.000000e+00, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[SUM_J_NEXT]] = fadd reassoc float [[SUM_J]], [[A]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[SUM_I_LCSSA]] = phi float [ [[SUM_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -125,11 +207,32 @@ exit:
; for (int j = 0; j < 2; j++)
; prod *= A[j][i];
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: UnsupportedPHIOuter
-; CHECK-NEXT: Function: reduction_fmul
define void @reduction_fmul(ptr %A) {
+; CHECK-LABEL: define void @reduction_fmul(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ]
+; CHECK-NEXT: [[PROD_I:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[PROD_I_LCSSA:%.*]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_I_HEADER]] ], [ [[J_INC:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[PROD_J:%.*]] = phi float [ [[PROD_I]], %[[FOR_I_HEADER]] ], [ [[PROD_J_NEXT:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[PROD_J_NEXT]] = fmul float [[PROD_J]], [[A]]
+; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_J]], label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[PROD_I_LCSSA]] = phi float [ [[PROD_J_NEXT]], %[[FOR_J]] ]
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -161,11 +264,42 @@ exit:
; Check that the interchange is legal if the floating-point multiplication is
; marked as reassoc.
;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_reassoc_fmul
define void @reduction_reassoc_fmul(ptr %A) {
+; CHECK-LABEL: define void @reduction_reassoc_fmul(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[PROD_J:%.*]] = phi float [ [[PROD_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[PROD_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[PROD_I]] = phi float [ [[PROD_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 1.000000e+00, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[PROD_J_NEXT]] = fmul reassoc float [[PROD_J]], [[A]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[PROD_I_LCSSA]] = phi float [ [[PROD_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -202,11 +336,34 @@ exit:
; for (int j = 0; j < 2; j++)
; fmuladd += A[j][i] * B[j][i];
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: UnsupportedPHIOuter
-; CHECK-NEXT: Function: reduction_fmuladd
define void @reduction_fmuladd(ptr %A, ptr %B) {
+; CHECK-LABEL: define void @reduction_fmuladd(
+; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ]
+; CHECK-NEXT: [[FMULADD_I:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[FMULADD_I_LCSSA:%.*]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_I_HEADER]] ], [ [[J_INC:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[FMULADD_J:%.*]] = phi float [ [[FMULADD_I]], %[[FOR_I_HEADER]] ], [ [[FMULADD_J_NEXT:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[IDX_A:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[IDX_B:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[B]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX_A]], align 4
+; CHECK-NEXT: [[B:%.*]] = load float, ptr [[IDX_B]], align 4
+; CHECK-NEXT: [[FMULADD_J_NEXT]] = call float @llvm.fmuladd.f32(float [[A]], float [[B]], float [[FMULADD_J]])
+; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_J]], label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[FMULADD_I_LCSSA]] = phi float [ [[FMULADD_J_NEXT]], %[[FOR_J]] ]
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -240,11 +397,44 @@ exit:
; Check that the interchange is legal if the floating-point fmuladd is marked
; as reassoc.
;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_reassoc_fmuladd
define void @reduction_reassoc_fmuladd(ptr %A, ptr %B) {
+; CHECK-LABEL: define void @reduction_reassoc_fmuladd(
+; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[FMULADD_J:%.*]] = phi float [ [[FMULADD_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[FMULADD_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[FMULADD_I]] = phi float [ [[FMULADD_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 1.000000e+00, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX_A:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[IDX_B:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[B]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX_A]], align 4
+; CHECK-NEXT: [[B:%.*]] = load float, ptr [[IDX_B]], align 4
+; CHECK-NEXT: [[FMULADD_J_NEXT]] = call reassoc float @llvm.fmuladd.f32(float [[A]], float [[B]], float [[FMULADD_J]])
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[FMULADD_I_LCSSA]] = phi float [ [[FMULADD_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -283,11 +473,43 @@ exit:
; for (int j = 0; j < 2; j++)
; fmin = (A[j][i] < fmin) ? A[j][i] : fmin;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_fmin
define void @reduction_fmin(ptr %A, float %init) {
+; CHECK-LABEL: define void @reduction_fmin(
+; CHECK-SAME: ptr [[A:%.*]], float [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[FMIN_J:%.*]] = phi float [ [[FMIN_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[FMIN_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[FMIN_I]] = phi float [ [[FMIN_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan nsz olt float [[A]], [[FMIN_J]]
+; CHECK-NEXT: [[FMIN_J_NEXT]] = select nnan nsz i1 [[CMP]], float [[A]], float [[FMIN_J]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[FMIN_I_LCSSA]] = phi float [ [[FMIN_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -317,15 +539,45 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the floating-point
; llvm.minimumnum.
;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_fmininumnum
define void @reduction_fmininumnum(ptr %A, float %init) {
+; CHECK-LABEL: define void @reduction_fmininumnum(
+; CHECK-SAME: ptr [[A:%.*]], float [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[FMIN_J:%.*]] = phi float [ [[FMIN_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[FMIN_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[FMIN_I]] = phi float [ [[FMIN_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[FMIN_J_NEXT]] = call float @llvm.minimumnum.f32(float [[A]], float [[FMIN_J]])
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[FMIN_I_LCSSA]] = phi float [ [[FMIN_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -362,11 +614,43 @@ exit:
; for (int j = 0; j < 2; j++)
; fmax = (A[j][i] > fmax) ? A[j][i] : fmax;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_fmax
define void @reduction_fmax(ptr %A, float %init) {
+; CHECK-LABEL: define void @reduction_fmax(
+; CHECK-SAME: ptr [[A:%.*]], float [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[FMAX_J:%.*]] = phi float [ [[FMAX_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[FMAX_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[FMAX_I]] = phi float [ [[FMAX_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan nsz ogt float [[A]], [[FMAX_J]]
+; CHECK-NEXT: [[FMAX_J_NEXT]] = select nnan nsz i1 [[CMP]], float [[A]], float [[FMAX_J]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[FMAX_I_LCSSA]] = phi float [ [[FMAX_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -399,11 +683,42 @@ exit:
; Check that interchanging the loops is legal for the floating-point
; llvm.maximumnum.
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_fmaxinumnum
define void @reduction_fmaxinumnum(ptr %A, float %init) {
+; CHECK-LABEL: define void @reduction_fmaxinumnum(
+; CHECK-SAME: ptr [[A:%.*]], float [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[FMAX_J:%.*]] = phi float [ [[FMAX_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[FMAX_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[FMAX_I]] = phi float [ [[FMAX_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[IDX]], align 4
+; CHECK-NEXT: [[FMAX_J_NEXT]] = call float @llvm.maximumnum.f32(float [[A]], float [[FMAX_J]])
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[FMAX_I_LCSSA]] = phi float [ [[FMAX_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -434,4 +749,4 @@ exit:
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
declare float @llvm.minimumnum.f32(float %a, float %b)
-declare float @llvm.maximumnum.f32(float %a, float %b)
\ No newline at end of file
+declare float @llvm.maximumnum.f32(float %a, float %b)
diff --git a/llvm/test/Transforms/LoopInterchange/guarded-inner-loop.ll b/llvm/test/Transforms/LoopInterchange/guarded-inner-loop.ll
index 681dca5bbcba3..ec12ff2878743 100644
--- a/llvm/test/Transforms/LoopInterchange/guarded-inner-loop.ll
+++ b/llvm/test/Transforms/LoopInterchange/guarded-inner-loop.ll
@@ -1,8 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange \
-; RUN: -loop-interchange-profitabilities=ignore \
-; RUN: -pass-remarks-missed='loop-interchange' -disable-output \
-; RUN: -pass-remarks-output=%t
-; RUN: FileCheck -input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -S | FileCheck %s
; The middle loop %for.j guards the inner loop %for.k: %for.k runs only when
; %i != 0 (the outer loop's IV), and its exit %k.next == %i is only well-defined
@@ -18,16 +15,62 @@
; if (k + 1 == i) break;
; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: NotTightlyNested
-; CHECK-NEXT: Function: main
-
@x = global [3 x [3 x [3 x i32]]] zeroinitializer
@w = global [3 x [3 x [3 x i32]]] zeroinitializer
@y = global [3 x [3 x [3 x i32]]] zeroinitializer
define i32 @main() {
+; CHECK-LABEL: define i32 @main() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_I_PREHEADER:.*]]
+; CHECK: [[FOR_I_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_I:.*]]
+; CHECK: [[FOR_I]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], %[[FOR_I_INC:.*]] ], [ 0, %[[FOR_I_PREHEADER]] ]
+; CHECK-NEXT: [[I_IS_ZERO:%.*]] = icmp eq i32 [[I]], 0
+; CHECK-NEXT: [[XBASE:%.*]] = getelementptr [9 x i32], ptr @x, i32 [[I]]
+; CHECK-NEXT: [[WBASE:%.*]] = getelementptr [9 x i32], ptr @w, i32 [[I]]
+; CHECK-NEXT: [[YBASE:%.*]] = getelementptr [3 x i32], ptr @y, i32 [[I]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_INC_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br i1 [[I_IS_ZERO]], label %[[FOR_J_INC:.*]], label %[[FOR_K_PH:.*]]
+; CHECK: [[FOR_K_PH]]:
+; CHECK-NEXT: [[XP:%.*]] = getelementptr i32, ptr [[XBASE]], i32 [[J]]
+; CHECK-NEXT: [[WP:%.*]] = getelementptr i32, ptr [[WBASE]], i32 [[J]]
+; CHECK-NEXT: [[YP:%.*]] = getelementptr [9 x i32], ptr [[YBASE]], i32 [[J]]
+; CHECK-NEXT: br label %[[FOR_K:.*]]
+; CHECK: [[FOR_K]]:
+; CHECK-NEXT: [[K:%.*]] = phi i32 [ 0, %[[FOR_K_PH]] ], [ [[K_NEXT:%.*]], %[[FOR_K]] ]
+; CHECK-NEXT: [[XK:%.*]] = getelementptr [3 x i32], ptr [[XP]], i32 [[K]]
+; CHECK-NEXT: [[XV:%.*]] = load i32, ptr [[XK]], align 4
+; CHECK-NEXT: [[WK:%.*]] = getelementptr [3 x i32], ptr [[WP]], i32 [[K]]
+; CHECK-NEXT: [[WV:%.*]] = load i32, ptr [[WK]], align 4
+; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XV]], [[WV]]
+; CHECK-NEXT: [[YK:%.*]] = getelementptr i32, ptr [[YP]], i32 [[K]]
+; CHECK-NEXT: store i32 [[ADD]], ptr [[YK]], align 4
+; CHECK-NEXT: [[K_NEXT]] = add i32 [[K]], 1
+; CHECK-NEXT: [[K_DONE:%.*]] = icmp eq i32 [[K_NEXT]], [[I]]
+; CHECK-NEXT: br i1 [[K_DONE]], label %[[FOR_J_INC_LOOPEXIT:.*]], label %[[FOR_K]]
+; CHECK: [[FOR_J_INC_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_J_INC]]
+; CHECK: [[FOR_J_INC]]:
+; CHECK-NEXT: [[J_NEXT:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[J_CMP:%.*]] = icmp eq i32 [[J]], 0
+; CHECK-NEXT: br label %[[FOR_J_INC_SPLIT]]
+; CHECK: [[FOR_J_INC_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[J]], 0
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[FOR_I_INC]]
+; CHECK: [[FOR_I_INC]]:
+; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
+; CHECK-NEXT: [[I_DONE:%.*]] = icmp eq i32 [[I_NEXT]], 3
+; CHECK-NEXT: br i1 [[I_DONE]], label %[[EXIT:.*]], label %[[FOR_I]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret i32 0
+;
entry:
br label %for.i
diff --git a/llvm/test/Transforms/LoopInterchange/inner-only-reductions.ll b/llvm/test/Transforms/LoopInterchange/inner-only-reductions.ll
index c6c2e2a8a5187..309c72227d266 100644
--- a/llvm/test/Transforms/LoopInterchange/inner-only-reductions.ll
+++ b/llvm/test/Transforms/LoopInterchange/inner-only-reductions.ll
@@ -1,6 +1,5 @@
-; 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 -verify-loop-lcssa 2>&1 | FileCheck -check-prefix=IR %s
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
; Both tests should be rejected as interchange candidates. For now, they are
; rejected for dependence analysis reasons, but that's because support for 'S'
@@ -19,15 +18,40 @@
;; for( int j=1;j<N;j++)
;; X+=A[j][i];
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: reduction_01
-
-; IR-LABEL: @reduction_01(
-; IR-NOT: split
-
define void @reduction_01(i32 %N) {
+; CHECK-LABEL: define void @reduction_01(
+; CHECK-SAME: i32 [[N:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP16:%.*]] = icmp sgt i32 [[N]], 1
+; CHECK-NEXT: br i1 [[CMP16]], label %[[FOR_BODY3_LR_PH_PREHEADER:.*]], label %[[FOR_END8:.*]]
+; CHECK: [[FOR_BODY3_LR_PH_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_BODY3_LR_PH:.*]]
+; CHECK: [[FOR_BODY3_LR_PH]]:
+; CHECK-NEXT: [[INDVARS_IV18:%.*]] = phi i64 [ [[INDVARS_IV_NEXT19:%.*]], %[[FOR_COND1_FOR_INC6_CRIT_EDGE:.*]] ], [ 1, %[[FOR_BODY3_LR_PH_PREHEADER]] ]
+; CHECK-NEXT: [[X_PROMOTED:%.*]] = load i32, ptr @X, align 4
+; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
+; CHECK: [[FOR_BODY3]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, %[[FOR_BODY3_LR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: [[ADD15:%.*]] = phi i32 [ [[X_PROMOTED]], %[[FOR_BODY3_LR_PH]] ], [ [[ADD:%.*]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [500 x [500 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV18]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD15]], [[TMP0]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND1_FOR_INC6_CRIT_EDGE]], label %[[FOR_BODY3]]
+; CHECK: [[FOR_COND1_FOR_INC6_CRIT_EDGE]]:
+; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: store i32 [[ADD_LCSSA]], ptr @X, align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT19]] = add nuw nsw i64 [[INDVARS_IV18]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV20:%.*]] = trunc i64 [[INDVARS_IV_NEXT19]] to i32
+; CHECK-NEXT: [[EXITCOND21:%.*]] = icmp eq i32 [[LFTR_WIDEIV20]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND21]], label %[[FOR_END8_LOOPEXIT:.*]], label %[[FOR_BODY3_LR_PH]]
+; CHECK: [[FOR_END8_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_END8]]
+; CHECK: [[FOR_END8]]:
+; CHECK-NEXT: ret void
+;
entry:
%cmp16 = icmp sgt i32 %N, 1
br i1 %cmp16, label %for.body3.lr.ph, label %for.end8
@@ -72,15 +96,51 @@ for.end8: ; preds = %for.cond1.for.inc6_
;; Not tightly nested. Do not interchange.
;; Not interchanged hence the phi's in the inner loop will not be split.
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: UnsupportedPHIOuter
-; CHECK-NEXT: Function: reduction_03
-
-; IR-LABEL: @reduction_03(
-; IR-NOT: split
-
define void @reduction_03(i32 %N) {
+; CHECK-LABEL: define void @reduction_03(
+; CHECK-SAME: i32 [[N:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP35:%.*]] = icmp sgt i32 [[N]], 1
+; CHECK-NEXT: br i1 [[CMP35]], label %[[FOR_COND4_PREHEADER_LR_PH_PREHEADER:.*]], label %[[FOR_END19:.*]]
+; CHECK: [[FOR_COND4_PREHEADER_LR_PH_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_COND4_PREHEADER_LR_PH:.*]]
+; CHECK: [[FOR_COND4_PREHEADER_LR_PH]]:
+; CHECK-NEXT: [[INDVARS_IV41:%.*]] = phi i64 [ [[INDVARS_IV_NEXT42:%.*]], %[[FOR_COND1_FOR_INC17_CRIT_EDGE:.*]] ], [ 1, %[[FOR_COND4_PREHEADER_LR_PH_PREHEADER]] ]
+; CHECK-NEXT: [[Y_PROMOTED:%.*]] = load i32, ptr @Y, align 4
+; CHECK-NEXT: br label %[[FOR_BODY6_LR_PH:.*]]
+; CHECK: [[FOR_BODY6_LR_PH]]:
+; CHECK-NEXT: [[INDVARS_IV37:%.*]] = phi i64 [ 1, %[[FOR_COND4_PREHEADER_LR_PH]] ], [ [[INDVARS_IV_NEXT38:%.*]], %[[FOR_COND4_FOR_END_CRIT_EDGE:.*]] ]
+; CHECK-NEXT: [[ADD1334:%.*]] = phi i32 [ [[Y_PROMOTED]], %[[FOR_COND4_PREHEADER_LR_PH]] ], [ [[ADD13:%.*]], %[[FOR_COND4_FOR_END_CRIT_EDGE]] ]
+; CHECK-NEXT: [[X_PROMOTED:%.*]] = load i32, ptr @X, align 4
+; CHECK-NEXT: br label %[[FOR_BODY6:.*]]
+; CHECK: [[FOR_BODY6]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, %[[FOR_BODY6_LR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY6]] ]
+; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [500 x [500 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV37]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX8]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND4_FOR_END_CRIT_EDGE]], label %[[FOR_BODY6]]
+; CHECK: [[FOR_COND4_FOR_END_CRIT_EDGE]]:
+; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [500 x [500 x i32]], ptr @B, i64 0, i64 [[INDVARS_IV37]], i64 [[INDVARS_IV41]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX12]], align 4
+; CHECK-NEXT: [[ADD13]] = add nsw i32 [[ADD1334]], [[TMP1]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT38]] = add nuw nsw i64 [[INDVARS_IV37]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV39:%.*]] = trunc i64 [[INDVARS_IV_NEXT38]] to i32
+; CHECK-NEXT: [[EXITCOND40:%.*]] = icmp eq i32 [[LFTR_WIDEIV39]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND40]], label %[[FOR_COND1_FOR_INC17_CRIT_EDGE]], label %[[FOR_BODY6_LR_PH]]
+; CHECK: [[FOR_COND1_FOR_INC17_CRIT_EDGE]]:
+; CHECK-NEXT: [[ADD13_LCSSA:%.*]] = phi i32 [ [[ADD13]], %[[FOR_COND4_FOR_END_CRIT_EDGE]] ]
+; CHECK-NEXT: store i32 [[ADD13_LCSSA]], ptr @Y, align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT42]] = add nuw nsw i64 [[INDVARS_IV41]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV43:%.*]] = trunc i64 [[INDVARS_IV_NEXT42]] to i32
+; CHECK-NEXT: [[EXITCOND44:%.*]] = icmp eq i32 [[LFTR_WIDEIV43]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND44]], label %[[FOR_END19_LOOPEXIT:.*]], label %[[FOR_COND4_PREHEADER_LR_PH]]
+; CHECK: [[FOR_END19_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_END19]]
+; CHECK: [[FOR_END19]]:
+; CHECK-NEXT: ret void
+;
entry:
%cmp35 = icmp sgt i32 %N, 1
br i1 %cmp35, label %for.cond4.preheader.lr.ph, label %for.end19
diff --git a/llvm/test/Transforms/LoopInterchange/interchange-insts-between-indvar.ll b/llvm/test/Transforms/LoopInterchange/interchange-insts-between-indvar.ll
index 343c8c44b8c22..f535665475838 100644
--- a/llvm/test/Transforms/LoopInterchange/interchange-insts-between-indvar.ll
+++ b/llvm/test/Transforms/LoopInterchange/interchange-insts-between-indvar.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN: -S -pass-remarks=loop-interchange -da-enable-dependence-test=all 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --prefix-filecheck-ir-name VAL_ --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -da-enable-dependence-test=all -S | FileCheck %s
@A10 = local_unnamed_addr global [3 x [3 x i32]] zeroinitializer, align 16
@@ -11,11 +11,43 @@
;; A[j][i] = i;
;; }
-; CHECK: Loop interchanged with enclosing loop.
-
@A11 = local_unnamed_addr global [3 x [3 x i32]] zeroinitializer, align 16
define void @interchange_11(i32 %n) {
+; CHECK-LABEL: define void @interchange_11(
+; CHECK-SAME: i32 [[N:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_BODY4_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND_LOOPEXIT:.*]]:
+; CHECK-NEXT: [[EXITCOND28:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT27:%.*]], 2
+; CHECK-NEXT: br i1 [[EXITCOND28]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_BODY4_SPLIT:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV26:%.*]] = phi i64 [ [[INDVARS_IV_NEXT27]], %[[FOR_COND_LOOPEXIT]] ], [ 0, %[[FOR_COND1_PREHEADER_PREHEADER]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT27]] = add nuw nsw i64 [[INDVARS_IV26]], 1
+; CHECK-NEXT: br label %[[FOR_BODY4_SPLIT1:.*]]
+; CHECK: [[FOR_BODY4_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_BODY4:.*]]
+; CHECK: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_BODY4]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP3:%.*]], %[[FOR_BODY4_SPLIT]] ], [ 0, %[[FOR_BODY4_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER_PREHEADER]]
+; CHECK: [[FOR_BODY4_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [3 x [3 x i32]], ptr @A10, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV_NEXT27]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX10]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[N_WIDE:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N_WIDE]]
+; CHECK-NEXT: br label %[[FOR_COND_LOOPEXIT]]
+; CHECK: [[FOR_BODY4_SPLIT]]:
+; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64
+; CHECK-NEXT: [[TMP3]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP3]], [[TMP0]]
+; CHECK-NEXT: br i1 [[TMP2]], label %[[FOR_BODY4]], label %[[FOR_COND_CLEANUP]]
+;
entry:
br label %for.cond1.preheader
diff --git a/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll b/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
index 5f4a8486d9ad7..8dc23ad6ced0a 100644
--- a/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
+++ b/llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t -disable-output
-; RUN: FileCheck -input-file %t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -S | FileCheck %s
; This is a collection of cases where the loops were incorrectly interchanged
; due to mishandling of scalar dependencies.
@@ -16,19 +16,70 @@
;; }
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: issue46867
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: issue46867
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue46867(ptr noundef captures(none) %s, i32 noundef %c, ptr noundef readonly captures(none) %ff) {
+; CHECK-LABEL: define void @issue46867(
+; CHECK-SAME: ptr noundef captures(none) [[S:%.*]], i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[FF:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TOBOOL7_NOT:%.*]] = icmp eq i32 [[C]], 0
+; CHECK-NEXT: br i1 [[TOBOOL7_NOT]], label %[[FOR_COND1_PREHEADER_US_PREHEADER:.*]], label %[[ENTRY_SPLIT:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_US_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER_US:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_US]]:
+; CHECK-NEXT: [[INDVARS_IV31:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER_US_PREHEADER]] ], [ [[INDVARS_IV_NEXT32:%.*]], %[[FOR_COND_CLEANUP3_SPLIT_US_US:.*]] ]
+; CHECK-NEXT: br label %[[FOR_BODY4_US_US:.*]]
+; CHECK: [[FOR_BODY4_US_US]]:
+; CHECK-NEXT: [[INDVARS_IV27:%.*]] = phi i64 [ [[INDVARS_IV_NEXT28:%.*]], %[[LAND_END_US_US:.*]] ], [ 0, %[[FOR_COND1_PREHEADER_US]] ]
+; CHECK-NEXT: [[ARRAYIDX6_US_US:%.*]] = getelementptr inbounds nuw [9 x i32], ptr [[FF]], i64 [[INDVARS_IV27]], i64 [[INDVARS_IV31]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX6_US_US]], align 4
+; CHECK-NEXT: [[TOBOOL_NOT_US_US:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[TOBOOL_NOT_US_US]], label %[[LAND_END_US_US]], label %[[LAND_RHS_US_US:.*]]
+; CHECK: [[LAND_RHS_US_US]]:
+; CHECK-NEXT: store i32 3, ptr [[S]], align 4
+; CHECK-NEXT: br label %[[LAND_END_US_US]]
+; CHECK: [[LAND_END_US_US]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT28]] = add nuw nsw i64 [[INDVARS_IV27]], 1
+; CHECK-NEXT: [[EXITCOND30:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT28]], 3
+; CHECK-NEXT: br i1 [[EXITCOND30]], label %[[FOR_BODY4_US_US]], label %[[FOR_COND_CLEANUP3_SPLIT_US_US]]
+; CHECK: [[FOR_COND_CLEANUP3_SPLIT_US_US]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT32]] = add nuw nsw i64 [[INDVARS_IV31]], 1
+; CHECK-NEXT: [[EXITCOND34:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT32]], 3
+; CHECK-NEXT: br i1 [[EXITCOND34]], label %[[FOR_COND1_PREHEADER_US]], label %[[FOR_COND_CLEANUP_LOOPEXIT:.*]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[S_PROMOTED19:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV23:%.*]] = phi i64 [ 0, %[[ENTRY_SPLIT]] ], [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR_COND_CLEANUP3_SPLIT:.*]] ]
+; CHECK-NEXT: [[S_PROMOTED20:%.*]] = phi i32 [ [[S_PROMOTED19]], %[[ENTRY_SPLIT]] ], [ [[INC_LCSSA:%.*]], %[[FOR_COND_CLEANUP3_SPLIT]] ]
+; CHECK-NEXT: br label %[[FOR_BODY4:.*]]
+; CHECK: [[FOR_COND_CLEANUP_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP_LOOPEXIT21:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_COND_CLEANUP3_SPLIT]]:
+; CHECK-NEXT: [[INC_LCSSA]] = phi i32 [ [[INC:%.*]], %[[LAND_END:.*]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT: [[EXITCOND26:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT24]], 3
+; CHECK-NEXT: br i1 [[EXITCOND26]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP_LOOPEXIT21]]
+; CHECK: [[FOR_BODY4]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[LAND_END]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[S_PROMOTED20]], %[[FOR_COND1_PREHEADER]] ], [ [[INC]], %[[LAND_END]] ]
+; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [9 x i32], ptr [[FF]], i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX6]], align 4
+; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label %[[LAND_END]], label %[[LAND_RHS:.*]]
+; CHECK: [[LAND_RHS]]:
+; CHECK-NEXT: store i32 3, ptr [[S]], align 4
+; CHECK-NEXT: br label %[[LAND_END]]
+; CHECK: [[LAND_END]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ 3, %[[LAND_RHS]] ], [ [[TMP1]], %[[FOR_BODY4]] ]
+; CHECK-NEXT: [[INC]] = add nsw i32 [[TMP3]], 1
+; CHECK-NEXT: store i32 [[INC]], ptr [[S]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 3
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY4]], label %[[FOR_COND_CLEANUP3_SPLIT]]
+;
entry:
%tobool7.not = icmp eq i32 %c, 0
br i1 %tobool7.not, label %for.cond1.preheader.us.preheader, label %entry.split
@@ -106,7 +157,6 @@ land.end:
br i1 %exitcond, label %for.body4, label %for.cond.cleanup3.split
}
-
;; The original code is as follows, with some simplifications from the one in
;; the issue #47401. The interchange is illegal due to the dependency of `e`.
;;
@@ -116,13 +166,37 @@ land.end:
;; bb[d + 2][c] && (*e = bb[d][0]);
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: issue47401
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue47401(ptr noundef writeonly captures(none) %e, ptr noundef readonly captures(none) %bb) {
+; CHECK-LABEL: define void @issue47401(
+; CHECK-SAME: ptr noundef writeonly captures(none) [[E:%.*]], ptr noundef readonly captures(none) [[BB:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV22:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT23:%.*]], %[[FOR_COND_CLEANUP2:.*]] ]
+; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
+; CHECK: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_COND_CLEANUP2]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT23]] = add nuw nsw i64 [[INDVARS_IV22]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT23]], 8
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_BODY3]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 4, %[[FOR_COND1_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[LAND_END:.*]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [8 x i32], ptr [[BB]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr i8, ptr [[TMP0]], i64 64
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [8 x i32], ptr [[ARRAYIDX]], i64 0, i64 [[INDVARS_IV22]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[TOBOOL6_NOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[TOBOOL6_NOT]], label %[[LAND_END]], label %[[LAND_RHS:.*]]
+; CHECK: [[LAND_RHS]]:
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-NEXT: store i32 [[TMP2]], ptr [[E]], align 4
+; CHECK-NEXT: br label %[[LAND_END]]
+; CHECK: [[LAND_END]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
+; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 0
+; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label %[[FOR_COND_CLEANUP2]], label %[[FOR_BODY3]]
+;
entry:
br label %for.cond1.preheader
@@ -170,13 +244,31 @@ land.end:
;; }
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: issue47295
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue47295(ptr noundef captures(none) %f, ptr noundef writeonly captures(none) %cc) {
+; CHECK-LABEL: define void @issue47295(
+; CHECK-SAME: ptr noundef captures(none) [[F:%.*]], ptr noundef writeonly captures(none) [[CC:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV18:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT19:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
+; CHECK-NEXT: br label %[[FOR_BODY4:.*]]
+; CHECK: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_COND_CLEANUP3]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT19]] = add nuw nsw i64 [[INDVARS_IV18]], 1
+; CHECK-NEXT: [[EXITCOND21:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT19]], 4
+; CHECK-NEXT: br i1 [[EXITCOND21]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_BODY4]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY4]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[F]], align 4
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP0]], 4096
+; CHECK-NEXT: store i32 [[XOR]], ptr [[F]], align 4
+; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[CC]], i64 [[INDVARS_IV]], i64 [[INDVARS_IV18]]
+; CHECK-NEXT: store i32 [[XOR]], ptr [[ARRAYIDX6]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 4
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY4]], label %[[FOR_COND_CLEANUP3]]
+;
entry:
br label %for.cond1.preheader
@@ -216,14 +308,38 @@ for.body4:
;; }
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: issue54176
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
define void @issue54176(i32 noundef %n, i32 noundef %m, ptr noundef captures(none) %aa, ptr noundef readonly captures(none) %bb, ptr noundef writeonly captures(none) %cc) {
-
+; CHECK-LABEL: define void @issue54176(
+; CHECK-SAME: i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], ptr noundef captures(none) [[AA:%.*]], ptr noundef readonly captures(none) [[BB:%.*]], ptr noundef writeonly captures(none) [[CC:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[AA]], i64 512
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV32:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT33:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw [128 x float], ptr [[ARRAYIDX]], i64 0, i64 [[INDVARS_IV32]]
+; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[INDVARS_IV32]], -1
+; CHECK-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [128 x float], ptr [[ARRAYIDX]], i64 0, i64 [[TMP0]]
+; CHECK-NEXT: br label %[[FOR_BODY4:.*]]
+; CHECK: [[FOR_COND_CLEANUP3]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT33]] = add nuw nsw i64 [[INDVARS_IV32]], 1
+; CHECK-NEXT: [[EXITCOND36:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT33]], 128
+; CHECK-NEXT: br i1 [[EXITCOND36]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_BODY4]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, %[[FOR_COND1_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY4]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw [128 x float], ptr [[CC]], i64 [[INDVARS_IV]], i64 [[INDVARS_IV32]]
+; CHECK-NEXT: store float [[TMP1]], ptr [[ARRAYIDX9]], align 4
+; CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw [128 x float], ptr [[BB]], i64 [[INDVARS_IV]], i64 [[INDVARS_IV32]]
+; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX13]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX16]], align 4
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP2]], [[TMP3]]
+; CHECK-NEXT: store float [[ADD]], ptr [[ARRAYIDX16]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 1024
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY4]], label %[[FOR_COND_CLEANUP3]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: ret void
+;
entry:
%arrayidx = getelementptr inbounds nuw i8, ptr %aa, i64 512
br label %for.cond1.preheader
@@ -268,13 +384,45 @@ for.cond.cleanup:
;; }
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: issue116114
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
define void @issue116114(ptr noundef captures(none) %A, i32 noundef %x, i32 noundef %N, i32 noundef %M) {
+; CHECK-LABEL: define void @issue116114(
+; CHECK-SAME: ptr noundef captures(none) [[A:%.*]], i32 noundef [[X:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP18_NOT:%.*]] = icmp eq i32 [[M]], 0
+; CHECK-NEXT: br i1 [[CMP18_NOT]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_COND1_PREHEADER_LR_PH:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_LR_PH]]:
+; CHECK-NEXT: [[SUB:%.*]] = add i32 [[N]], -1
+; CHECK-NEXT: [[CMP216_NOT:%.*]] = icmp eq i32 [[SUB]], 0
+; CHECK-NEXT: br i1 [[CMP216_NOT]], label %[[FOR_COND1_PREHEADER_PREHEADER:.*]], label %[[FOR_COND1_PREHEADER_US_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_US_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER_US:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_COND_CLEANUP_LOOPEXIT:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_US]]:
+; CHECK-NEXT: [[M_019_US:%.*]] = phi i32 [ [[INC9_US:%.*]], %[[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:.*]] ], [ 0, %[[FOR_COND1_PREHEADER_US_PREHEADER]] ]
+; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SUB]] to i64
+; CHECK-NEXT: br label %[[FOR_BODY4_US:.*]]
+; CHECK: [[FOR_BODY4_US]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER_US]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY4_US]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[INDVARS_IV_NEXT]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
+; CHECK-NEXT: [[ADD5_US:%.*]] = add nsw i32 [[TMP0]], [[X]]
+; CHECK-NEXT: [[ARRAYIDX7_US:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i32 [[ADD5_US]], ptr [[ARRAYIDX7_US]], align 4
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY4_US]], label %[[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
+; CHECK: [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]:
+; CHECK-NEXT: [[INC9_US]] = add nuw i32 [[M_019_US]], 1
+; CHECK-NEXT: [[EXITCOND22:%.*]] = icmp ne i32 [[INC9_US]], [[M]]
+; CHECK-NEXT: br i1 [[EXITCOND22]], label %[[FOR_COND1_PREHEADER_US]], label %[[FOR_COND_CLEANUP_LOOPEXIT20:.*]]
+; CHECK: [[FOR_COND_CLEANUP_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_COND_CLEANUP_LOOPEXIT20]]:
+; CHECK-NEXT: br label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: ret void
+;
entry:
%cmp18.not = icmp eq i32 %M, 0
br i1 %cmp18.not, label %for.cond.cleanup, label %for.cond1.preheader.lr.ph
diff --git a/llvm/test/Transforms/LoopInterchange/loopnest-with-outer-btc0.ll b/llvm/test/Transforms/LoopInterchange/loopnest-with-outer-btc0.ll
index 613dcd4db0afc..71cc2c21b70b0 100644
--- a/llvm/test/Transforms/LoopInterchange/loopnest-with-outer-btc0.ll
+++ b/llvm/test/Transforms/LoopInterchange/loopnest-with-outer-btc0.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info \
-; RUN: -pass-remarks-output=%t -pass-remarks='loop-interchange' -S
-; RUN: cat %t | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -15,29 +14,47 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; D[i][k][j] = D[i][k][j]+t;
;
-; CHECK: --- !Analysis
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: interchange_i_and_j
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Computed dependence info, invoking the transform.
-; CHECK-NEXT: ...
-; CHECK-NEXT: --- !Passed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: interchange_i_and_j
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
-; CHECK-NEXT: ...
-; CHECK-NEXT: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: InterchangeNotProfitable
-; CHECK-NEXT: Function: interchange_i_and_j
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Insufficient information to calculate the cost of loop for interchange.
-; CHECK-NEXT: ...
-
define void @interchange_i_and_j(i32 %t){
+; CHECK-LABEL: define void @interchange_i_and_j(
+; CHECK-SAME: i32 [[T:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INC16:%.*]], %[[FOR_INC15:.*]] ]
+; CHECK-NEXT: br label %[[INNER2_BODY_PREHEADER:.*]]
+; CHECK: [[INNER1_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[INNER1_HEADER:.*]]
+; CHECK: [[INNER1_HEADER]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[INC13:%.*]], %[[FOR_INC12:.*]] ], [ 0, %[[INNER1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[INNER2_BODY_SPLIT1:.*]]
+; CHECK: [[INNER2_BODY_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER2_BODY:.*]]
+; CHECK: [[INNER2_BODY]]:
+; CHECK-NEXT: [[K:%.*]] = phi i64 [ [[TMP1:%.*]], %[[INNER2_BODY_SPLIT:.*]] ], [ 0, %[[INNER2_BODY_PREHEADER]] ]
+; CHECK-NEXT: br label %[[INNER1_HEADER_PREHEADER]]
+; CHECK: [[INNER2_BODY_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @D, i64 [[I]], i64 [[K]], i64 [[J]]
+; 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]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INC]], 100
+; CHECK-NEXT: br label %[[FOR_INC12]]
+; CHECK: [[INNER2_BODY_SPLIT]]:
+; CHECK-NEXT: [[TMP1]] = add nuw nsw i64 [[K]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 100
+; CHECK-NEXT: br i1 [[TMP2]], label %[[FOR_INC15]], label %[[INNER2_BODY]]
+; CHECK: [[FOR_INC12]]:
+; CHECK-NEXT: [[INC13]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[EXITCOND29:%.*]] = icmp eq i64 [[INC13]], 100
+; CHECK-NEXT: br i1 [[EXITCOND29]], label %[[INNER2_BODY_SPLIT]], label %[[INNER1_HEADER]]
+; CHECK: [[FOR_INC15]]:
+; CHECK-NEXT: [[INC16]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: [[EXITCOND30:%.*]] = icmp eq i64 [[INC16]], 1
+; CHECK-NEXT: br i1 [[EXITCOND30]], label %[[FOR_END17:.*]], label %[[OUTER_HEADER]]
+; CHECK: [[FOR_END17]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %outer.header
diff --git a/llvm/test/Transforms/LoopInterchange/multilevel-partial-reduction.ll b/llvm/test/Transforms/LoopInterchange/multilevel-partial-reduction.ll
index 49c706d69d167..d3766ca885066 100644
--- a/llvm/test/Transforms/LoopInterchange/multilevel-partial-reduction.ll
+++ b/llvm/test/Transforms/LoopInterchange/multilevel-partial-reduction.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=4 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa
-; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=4 -S | FileCheck %s
@b = external global [512 x [4 x i32]]
@c = global [2 x [4 x i32]] zeroinitializer, align 1
@@ -10,16 +9,56 @@
; that loop interchange can handle. Interchanging the outermost and the
; middle loops would intervene with the reduction and cause miscompile.
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: UnsupportedPHIInner
-; REMARKS-NEXT: Function: test7
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: UnsupportedPHIInner
-; REMARKS-NEXT: Function: test7
-
define i32 @test7() {
+; CHECK-LABEL: define i32 @test7() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER_I:.*]]
+; CHECK: [[FOR_COND1_PREHEADER_I]]:
+; CHECK-NEXT: [[I_011_I:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[INC20_I:%.*]], %[[FOR_INC19_I:.*]] ]
+; CHECK-NEXT: br label %[[FOR_COND4_PREHEADER_I:.*]]
+; CHECK: [[FOR_COND4_PREHEADER_I]]:
+; CHECK-NEXT: [[J_010_I:%.*]] = phi i16 [ 0, %[[FOR_COND1_PREHEADER_I]] ], [ [[INC17_I:%.*]], %[[MIDDLE_BLOCK:.*]] ]
+; CHECK-NEXT: [[ARRAYIDX14_I:%.*]] = getelementptr inbounds [2 x [4 x i32]], ptr @c, i16 0, i16 [[I_011_I]], i16 [[J_010_I]]
+; CHECK-NEXT: [[ARRAYIDX14_PROMOTED_I:%.*]] = load i32, ptr [[ARRAYIDX14_I]], align 1
+; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 [[ARRAYIDX14_PROMOTED_I]], i64 0
+; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
+; CHECK: [[VECTOR_BODY]]:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i16 [ 0, %[[FOR_COND4_PREHEADER_I]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[TMP0]], %[[FOR_COND4_PREHEADER_I]] ], [ [[TMP16:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = or i16 [[INDEX]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = or i16 [[INDEX]], 2
+; CHECK-NEXT: [[TMP3:%.*]] = or i16 [[INDEX]], 3
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 [[INDEX]], i16 [[J_010_I]]
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 [[TMP1]], i16 [[J_010_I]]
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 [[TMP2]], i16 [[J_010_I]]
+; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 [[TMP3]], i16 [[J_010_I]]
+; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP4]], align 1
+; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP6]], align 1
+; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[TMP7]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = insertelement <4 x i32> poison, i32 [[TMP8]], i64 0
+; CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x i32> [[TMP12]], i32 [[TMP9]], i64 1
+; CHECK-NEXT: [[TMP14:%.*]] = insertelement <4 x i32> [[TMP13]], i32 [[TMP10]], i64 2
+; CHECK-NEXT: [[TMP15:%.*]] = insertelement <4 x i32> [[TMP14]], i32 [[TMP11]], i64 3
+; CHECK-NEXT: [[TMP16]] = add <4 x i32> [[TMP15]], [[VEC_PHI]]
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i16 [[INDEX]], 4
+; CHECK-NEXT: [[TMP17:%.*]] = icmp eq i16 [[INDEX_NEXT]], 512
+; CHECK-NEXT: br i1 [[TMP17]], label %[[MIDDLE_BLOCK]], label %[[VECTOR_BODY]]
+; CHECK: [[MIDDLE_BLOCK]]:
+; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi <4 x i32> [ [[TMP16]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP18:%.*]] = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[DOTLCSSA]])
+; CHECK-NEXT: store i32 [[TMP18]], ptr [[ARRAYIDX14_I]], align 1
+; CHECK-NEXT: [[INC17_I]] = add nuw nsw i16 [[J_010_I]], 1
+; CHECK-NEXT: [[EXITCOND12_NOT_I:%.*]] = icmp eq i16 [[INC17_I]], 4
+; CHECK-NEXT: br i1 [[EXITCOND12_NOT_I]], label %[[FOR_INC19_I]], label %[[FOR_COND4_PREHEADER_I]]
+; CHECK: [[FOR_INC19_I]]:
+; CHECK-NEXT: [[INC20_I]] = add nuw nsw i16 [[I_011_I]], 1
+; CHECK-NEXT: [[EXITCOND13_NOT_I:%.*]] = icmp eq i16 [[INC20_I]], 2
+; CHECK-NEXT: br i1 [[EXITCOND13_NOT_I]], label %[[TEST_EXIT:.*]], label %[[FOR_COND1_PREHEADER_I]]
+; CHECK: [[TEST_EXIT]]:
+; CHECK-NEXT: [[TMP19:%.*]] = load i32, ptr @c, align 1
+; CHECK-NEXT: ret i32 [[TMP19]]
+;
entry:
br label %for.cond1.preheader.i
diff --git a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
index 4aba99f35678e..3b324314f07c3 100644
--- a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
+++ b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -S | FileCheck %s
;; The original code:
;;
@@ -17,18 +16,49 @@
;; We need to treat this as `*`, not `<`. See issue #123920 for details.
;; In conclusion, we must not interchange the loops.
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: f
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: All loops have dependencies in all directions.
-; CHECK-NEXT: ...
-
-
@a = dso_local global [16 x [16 x [16 x i32]]] zeroinitializer, align 4
define dso_local void @f() {
+; CHECK-LABEL: define dso_local void @f() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[I_039:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC26:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
+; CHECK-NEXT: [[SUB:%.*]] = add nuw nsw i32 [[I_039]], 3
+; CHECK-NEXT: [[IDXPROM:%.*]] = zext nneg i32 [[SUB]] to i64
+; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i32 [[I_039]], 1
+; CHECK-NEXT: [[IDXPROM13:%.*]] = zext nneg i32 [[MUL]] to i64
+; CHECK-NEXT: br label %[[FOR_COND5_PREHEADER:.*]]
+; CHECK: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_COND5_PREHEADER]]:
+; CHECK-NEXT: [[J_038:%.*]] = phi i32 [ 1, %[[FOR_COND1_PREHEADER]] ], [ [[INC23:%.*]], %[[FOR_COND_CLEANUP7:.*]] ]
+; CHECK-NEXT: [[IDXPROM11:%.*]] = zext nneg i32 [[J_038]] to i64
+; CHECK-NEXT: [[SUB18:%.*]] = add nsw i32 [[J_038]], -1
+; CHECK-NEXT: [[IDXPROM19:%.*]] = sext i32 [[SUB18]] to i64
+; CHECK-NEXT: br label %[[FOR_BODY8:.*]]
+; CHECK: [[FOR_COND_CLEANUP3]]:
+; CHECK-NEXT: [[INC26]] = add nuw nsw i32 [[I_039]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[I_039]], 3
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_COND_CLEANUP7]]:
+; CHECK-NEXT: [[INC23]] = add nuw nsw i32 [[J_038]], 1
+; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i32 [[J_038]], 7
+; CHECK-NEXT: br i1 [[CMP2]], label %[[FOR_COND5_PREHEADER]], label %[[FOR_COND_CLEANUP3]]
+; CHECK: [[FOR_BODY8]]:
+; CHECK-NEXT: [[K_037:%.*]] = phi i32 [ 1, %[[FOR_COND5_PREHEADER]] ], [ [[ADD15:%.*]], %[[FOR_BODY8]] ]
+; CHECK-NEXT: [[IDXPROM9:%.*]] = zext nneg i32 [[K_037]] to i64
+; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[IDXPROM]], i64 [[IDXPROM9]], i64 [[IDXPROM11]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX12]], align 4
+; CHECK-NEXT: [[ADD15]] = add nuw nsw i32 [[K_037]], 1
+; CHECK-NEXT: [[IDXPROM16:%.*]] = zext nneg i32 [[ADD15]] to i64
+; CHECK-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[IDXPROM13]], i64 [[IDXPROM16]], i64 [[IDXPROM19]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4
+; CHECK-NEXT: [[SUB21:%.*]] = sub nsw i32 [[TMP1]], [[TMP0]]
+; CHECK-NEXT: store i32 [[SUB21]], ptr [[ARRAYIDX20]], align 4
+; CHECK-NEXT: [[CMP6:%.*]] = icmp samesign ult i32 [[K_037]], 7
+; CHECK-NEXT: br i1 [[CMP6]], label %[[FOR_BODY8]], label %[[FOR_COND_CLEANUP7]]
+;
entry:
br label %for.cond1.preheader
diff --git a/llvm/test/Transforms/LoopInterchange/outer-only-reductions.ll b/llvm/test/Transforms/LoopInterchange/outer-only-reductions.ll
index 385f39242157a..0b931d2f0523f 100644
--- a/llvm/test/Transforms/LoopInterchange/outer-only-reductions.ll
+++ b/llvm/test/Transforms/LoopInterchange/outer-only-reductions.ll
@@ -1,6 +1,5 @@
-; 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 -verify-loop-lcssa 2>&1 | FileCheck -check-prefix=IR %s
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
; Outer loop only reductions are not supported currently.
@@ -14,15 +13,34 @@
;; X+=A[j][i];
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: UnsupportedPHI
-; CHECK-NEXT: Function: reduction_01
-
-; IR-LABEL: @reduction_01(
-; IR-NOT: split
-
define i32 @reduction_01(i32 %N) {
+; CHECK-LABEL: define i32 @reduction_01(
+; CHECK-SAME: i32 [[N:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[INDVARS_IV18:%.*]] = phi i64 [ [[INDVARS_IV_NEXT19:%.*]], %[[OUTER_INC:.*]] ], [ 1, %[[ENTRY]] ]
+; CHECK-NEXT: [[ADD15:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[ADD:%.*]], %[[OUTER_INC]] ]
+; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
+; CHECK: [[FOR_BODY3]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, %[[OUTER_HEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[OUTER_INC]], label %[[FOR_BODY3]]
+; CHECK: [[OUTER_INC]]:
+; CHECK-NEXT: [[INDVARS_IV_LCSSA:%.*]] = phi i64 [ [[INDVARS_IV]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [500 x [500 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV_LCSSA]], i64 [[INDVARS_IV18]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD15]], [[TMP0]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT19]] = add nuw nsw i64 [[INDVARS_IV18]], 1
+; CHECK-NEXT: [[LFTR_WIDEIV20:%.*]] = trunc i64 [[INDVARS_IV_NEXT19]] to i32
+; CHECK-NEXT: [[EXITCOND21:%.*]] = icmp eq i32 [[LFTR_WIDEIV20]], [[N]]
+; CHECK-NEXT: br i1 [[EXITCOND21]], label %[[FOR_END8:.*]], label %[[OUTER_HEADER]]
+; CHECK: [[FOR_END8]]:
+; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], %[[OUTER_INC]] ]
+; CHECK-NEXT: ret i32 [[ADD_LCSSA]]
+;
entry:
br label %outer.header
diff --git a/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll b/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
index 69ef1e8ff7b95..6301d4842b71e 100644
--- a/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
@b = external dso_local global [5 x i32], align 16
@@ -11,14 +11,33 @@
;; }
;; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: test1
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
-
define void @test1() {
+; CHECK-LABEL: define void @test1() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], %[[OUTER_LATCH:.*]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x i32], ptr @b, i64 0, i64 [[IDXPROM]]
+; CHECK-NEXT: br label %[[INNER_HEADER:.*]]
+; CHECK: [[INNER_HEADER]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], %[[INNER_LATCH:.*]] ], [ 1, %[[OUTER_HEADER]] ]
+; CHECK-NEXT: br label %[[INNER_LATCH]]
+; CHECK: [[INNER_LATCH]]:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: store i32 undef, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[J]], 4
+; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1
+; CHECK-NEXT: br i1 [[CMP]], label %[[INNER_HEADER]], label %[[OUTER_BODY:.*]]
+; CHECK: [[OUTER_BODY]]:
+; CHECK-NEXT: br label %[[OUTER_LATCH]]
+; CHECK: [[OUTER_LATCH]]:
+; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[I]], 4
+; CHECK-NEXT: br i1 [[CMP2]], label %[[OUTER_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %outer.header
@@ -51,15 +70,34 @@ exit:
ret void
}
-
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: test2
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
-
define void @test2() {
+; CHECK-LABEL: define void @test2() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], %[[OUTER_LATCH:.*]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x i32], ptr @b, i64 0, i64 [[IDXPROM]]
+; CHECK-NEXT: br label %[[INNER_HEADER:.*]]
+; CHECK: [[INNER_HEADER]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[INNER_LATCH:.*]] ], [ 1, %[[OUTER_HEADER]] ]
+; CHECK-NEXT: br label %[[INNER_LATCH]]
+; CHECK: [[INNER_LATCH]]:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[LSR_IV]], 4
+; CHECK-NEXT: [[CMP_ZEXT:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT: store i32 [[CMP_ZEXT]], ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
+; CHECK-NEXT: br i1 [[CMP]], label %[[INNER_HEADER]], label %[[OUTER_BODY:.*]]
+; CHECK: [[OUTER_BODY]]:
+; CHECK-NEXT: br label %[[OUTER_LATCH]]
+; CHECK: [[OUTER_LATCH]]:
+; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[I]], 4
+; CHECK-NEXT: br i1 [[CMP2]], label %[[OUTER_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %outer.header
diff --git a/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll b/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll
index 732b9b2766302..d3bccaff36c26 100644
--- a/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr43326-ideal-access-pattern.ll
@@ -1,6 +1,5 @@
-; 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 -verify-loop-lcssa -stats 2>&1
-; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
; Triply nested loop, should be able to do interchange three times
; to get the ideal access pattern.
@@ -14,28 +13,57 @@
; }
; }
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: pr43326-triply-nested
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: pr43326-triply-nested
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: pr43326-triply-nested
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: pr43326-triply-nested
-
define void @pr43326-triply-nested(ptr noalias %e, ptr noalias %f) {
+; CHECK-LABEL: define void @pr43326-triply-nested(
+; CHECK-SAME: ptr noalias [[E:%.*]], ptr noalias [[F:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_INNERMOST_PREHEADER:.*]]
+; CHECK: [[FOR_OUTERMOST_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_OUTERMOST_HEADER:.*]]
+; CHECK: [[FOR_OUTERMOST_HEADER]]:
+; CHECK-NEXT: [[INDVARS_OUTERMOST:%.*]] = phi i64 [ [[INDVARS_OUTERMOST_NEXT:%.*]], %[[FOR_OUTERMOST_LATCH:.*]] ], [ 0, %[[FOR_OUTERMOST_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_INNERMOST_SPLIT1:.*]]
+; CHECK: [[FOR_MIDDLE_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_MIDDLE_HEADER:.*]]
+; CHECK: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_MIDDLE_HEADER]]:
+; CHECK-NEXT: [[INDVARS_MIDDLE:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR_MIDDLE_LATCH_SPLIT:.*]] ], [ 0, %[[FOR_MIDDLE_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_OUTERMOST_HEADER_PREHEADER]]
+; CHECK: [[FOR_INNERMOST_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_INNERMOST:.*]]
+; CHECK: [[FOR_OUTERMOST_LATCH]]:
+; CHECK-NEXT: [[INDVARS_OUTERMOST_NEXT]] = add nuw nsw i64 [[INDVARS_OUTERMOST]], 1
+; CHECK-NEXT: [[EXITCOND_OUTERMOST:%.*]] = icmp ne i64 [[INDVARS_OUTERMOST_NEXT]], 10
+; CHECK-NEXT: br i1 [[EXITCOND_OUTERMOST]], label %[[FOR_OUTERMOST_HEADER]], label %[[FOR_MIDDLE_LATCH_SPLIT]]
+; CHECK: [[FOR_MIDDLE_LATCH:.*]]:
+; CHECK-NEXT: [[INDVARS_MIDDLE_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_MIDDLE]], 1
+; CHECK-NEXT: [[EXITCOND_MIDDLE:%.*]] = icmp ne i64 [[INDVARS_MIDDLE_NEXT]], 10
+; CHECK-NEXT: br label %[[FOR_INNERMOST_SPLIT:.*]]
+; CHECK: [[FOR_MIDDLE_LATCH_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[INDVARS_MIDDLE]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[TMP0]], 10
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_MIDDLE_HEADER]], label %[[FOR_INNERMOST_SPLIT_SPLIT:.*]]
+; CHECK: [[FOR_INNERMOST]]:
+; CHECK-NEXT: [[INDVARS_INNERMOST:%.*]] = phi i64 [ [[TMP5:%.*]], %[[FOR_INNERMOST_SPLIT_SPLIT]] ], [ 0, %[[FOR_INNERMOST_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_MIDDLE_HEADER_PREHEADER]]
+; CHECK: [[FOR_INNERMOST_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[E]], i64 [[INDVARS_INNERMOST]], i64 [[INDVARS_MIDDLE]], i64 [[INDVARS_OUTERMOST]]
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX12]], align 4
+; CHECK-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[F]], i64 [[INDVARS_INNERMOST]], i64 [[INDVARS_MIDDLE]], i64 [[INDVARS_OUTERMOST]]
+; CHECK-NEXT: store i32 [[TMP2]], ptr [[ARRAYIDX18]], align 4
+; CHECK-NEXT: [[INDVARS_INNERMOST_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_INNERMOST]], 1
+; CHECK-NEXT: [[EXITCOND_INNERMOST:%.*]] = icmp ne i64 [[INDVARS_INNERMOST_NEXT]], 10
+; CHECK-NEXT: br label %[[FOR_MIDDLE_LATCH]]
+; CHECK: [[FOR_INNERMOST_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[INDVARS_INNERMOST]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], 10
+; CHECK-NEXT: br label %[[FOR_OUTERMOST_LATCH]]
+; CHECK: [[FOR_INNERMOST_SPLIT_SPLIT]]:
+; CHECK-NEXT: [[TMP5]] = add nuw nsw i64 [[INDVARS_INNERMOST]], 1
+; CHECK-NEXT: [[TMP6:%.*]] = icmp ne i64 [[TMP5]], 10
+; CHECK-NEXT: br i1 [[TMP6]], label %[[FOR_INNERMOST]], label %[[FOR_COND_CLEANUP]]
+;
entry:
br label %for.outermost.header
diff --git a/llvm/test/Transforms/LoopInterchange/pr43326.ll b/llvm/test/Transforms/LoopInterchange/pr43326.ll
index c224bd3cd93ab..745a28f91e965 100644
--- a/llvm/test/Transforms/LoopInterchange/pr43326.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr43326.ll
@@ -1,6 +1,5 @@
-; 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 -verify-loop-lcssa -loop-interchange-profitabilities=ignore -stats 2>&1
-; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -loop-interchange-profitabilities=ignore -S | FileCheck %s
@a = global i32 0
@b = global i8 0
@@ -8,20 +7,83 @@
@d = global i32 0
@e = global [1 x [1 x i32]] zeroinitializer
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: pr43326
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: pr43326
-
define void @pr43326() {
+; CHECK-LABEL: define void @pr43326() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4
+; CHECK-NEXT: [[TOBOOL_NOT2:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[TOBOOL_NOT2]], label %[[FOR_END14:.*]], label %[[OUTER_PREHEADER:.*]]
+; CHECK: [[OUTER_PREHEADER]]:
+; CHECK-NEXT: [[D_PROMOTED:%.*]] = load i32, ptr @d, align 4
+; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr @a, align 4
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[INC1312:%.*]] = phi i32 [ [[A_PROMOTED]], %[[OUTER_PREHEADER]] ], [ [[INC13:%.*]], %[[FOR_INC12:.*]] ]
+; CHECK-NEXT: [[XOR_LCSSA_LCSSA11:%.*]] = phi i32 [ [[D_PROMOTED]], %[[OUTER_PREHEADER]] ], [ [[XOR_LCSSA_LCSSA:%.*]], %[[FOR_INC12]] ]
+; CHECK-NEXT: br label %[[INNER1_HEADER_PREHEADER:.*]]
+; CHECK: [[INNER1_HEADER_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER1_HEADER:.*]]
+; CHECK: [[INNER1_HEADER]]:
+; CHECK-NEXT: [[J:%.*]] = phi i8 [ [[TMP5:%.*]], %[[FOR_INC10_SPLIT:.*]] ], [ 0, %[[INNER1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[XOR_LCSSA9:%.*]] = phi i32 [ [[XOR_LCSSA:%.*]], %[[FOR_INC10_SPLIT]] ], [ [[XOR_LCSSA_LCSSA11]], %[[INNER1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[INNER2_HEADER_PREHEADER:.*]]
+; CHECK: [[INNER1_HEADER_SPLIT:.*]]:
+; CHECK-NEXT: [[IDXPROM8:%.*]] = sext i8 [[J]] to i64
+; CHECK-NEXT: br label %[[INNER2_HEADER_SPLIT:.*]]
+; CHECK: [[INNER2_HEADER_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER2_HEADER:.*]]
+; CHECK: [[INNER2_HEADER]]:
+; CHECK-NEXT: [[K:%.*]] = phi i32 [ [[TMP2:%.*]], %[[FOR_INC_SPLIT:.*]] ], [ 0, %[[INNER2_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[XOR5:%.*]] = phi i32 [ [[XOR:%.*]], %[[FOR_INC_SPLIT]] ], [ [[XOR_LCSSA9]], %[[INNER2_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[INNER1_HEADER_SPLIT]]
+; CHECK: [[INNER2_HEADER_SPLIT]]:
+; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[K]] to i64
+; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [1 x [1 x i32]], ptr @e, i64 0, i64 [[IDXPROM]], i64 [[IDXPROM8]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4
+; CHECK-NEXT: [[XOR]] = xor i32 [[XOR5]], [[TMP1]]
+; CHECK-NEXT: br label %[[FOR_INC:.*]]
+; CHECK: [[FOR_INC]]:
+; CHECK-NEXT: [[K_NEXT:%.*]] = add nsw i32 [[K]], 1
+; CHECK-NEXT: [[CMP5:%.*]] = icmp slt i32 [[K_NEXT]], 42
+; CHECK-NEXT: br label %[[FOR_END:.*]]
+; CHECK: [[FOR_INC_SPLIT]]:
+; CHECK-NEXT: [[TMP2]] = add nsw i32 [[K]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 42
+; CHECK-NEXT: br i1 [[TMP3]], label %[[INNER2_HEADER]], label %[[FOR_INC10_SPLIT]]
+; CHECK: [[FOR_END]]:
+; CHECK-NEXT: br label %[[FOR_INC10:.*]]
+; CHECK: [[FOR_INC10]]:
+; CHECK-NEXT: [[J_NEXT:%.*]] = add i8 [[J]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[J_NEXT]], -10
+; CHECK-NEXT: br label %[[FOR_INC_SPLIT]]
+; CHECK: [[FOR_INC10_SPLIT]]:
+; CHECK-NEXT: [[XOR_LCSSA]] = phi i32 [ [[XOR]], %[[FOR_INC_SPLIT]] ]
+; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP2]], %[[FOR_INC_SPLIT]] ]
+; CHECK-NEXT: [[TMP5]] = add i8 [[J]], -1
+; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i8 [[TMP5]], -10
+; CHECK-NEXT: br i1 [[TMP6]], label %[[INNER1_HEADER]], label %[[FOR_END11:.*]]
+; CHECK: [[FOR_END11]]:
+; CHECK-NEXT: [[XOR_LCSSA_LCSSA]] = phi i32 [ [[XOR_LCSSA]], %[[FOR_INC10_SPLIT]] ]
+; CHECK-NEXT: [[DEC_LCSSA:%.*]] = phi i8 [ [[TMP5]], %[[FOR_INC10_SPLIT]] ]
+; CHECK-NEXT: [[INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[TMP4]], %[[FOR_INC10_SPLIT]] ]
+; CHECK-NEXT: br label %[[FOR_INC12]]
+; CHECK: [[FOR_INC12]]:
+; CHECK-NEXT: [[INC13]] = add nsw i32 [[INC1312]], 1
+; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp slt i32 [[INC13]], 42
+; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label %[[OUTER_HEADER]], label %[[FOR_COND_FOR_END14_CRIT_EDGE:.*]]
+; CHECK: [[FOR_COND_FOR_END14_CRIT_EDGE]]:
+; CHECK-NEXT: [[INC13_LCSSA:%.*]] = phi i32 [ [[INC13]], %[[FOR_INC12]] ]
+; CHECK-NEXT: [[INC_LCSSA_LCSSA_LCSSA:%.*]] = phi i32 [ [[INC_LCSSA_LCSSA]], %[[FOR_INC12]] ]
+; CHECK-NEXT: [[XOR_LCSSA_LCSSA_LCSSA:%.*]] = phi i32 [ [[XOR_LCSSA_LCSSA]], %[[FOR_INC12]] ]
+; CHECK-NEXT: [[DEC_LCSSA_LCSSA:%.*]] = phi i8 [ [[DEC_LCSSA]], %[[FOR_INC12]] ]
+; CHECK-NEXT: store i8 [[DEC_LCSSA_LCSSA]], ptr @b, align 1
+; CHECK-NEXT: store i32 [[XOR_LCSSA_LCSSA_LCSSA]], ptr @d, align 4
+; CHECK-NEXT: store i32 [[INC_LCSSA_LCSSA_LCSSA]], ptr @c, align 4
+; CHECK-NEXT: store i32 [[INC13_LCSSA]], ptr @a, align 4
+; CHECK-NEXT: br label %[[FOR_END14]]
+; CHECK: [[FOR_END14]]:
+; CHECK-NEXT: ret void
+;
entry:
%0 = load i32, ptr @a
%tobool.not2 = icmp eq i32 %0, 0
diff --git a/llvm/test/Transforms/LoopInterchange/pr48212.ll b/llvm/test/Transforms/LoopInterchange/pr48212.ll
index 936c53e217540..fa81571823583 100644
--- a/llvm/test/Transforms/LoopInterchange/pr48212.ll
+++ b/llvm/test/Transforms/LoopInterchange/pr48212.ll
@@ -1,21 +1,49 @@
-; 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 -verify-loop-lcssa 2>&1
-; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
-
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: pr48212
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: pr48212
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
define void @pr48212(ptr %filter) {
+; CHECK-LABEL: define void @pr48212(
+; CHECK-SAME: ptr [[FILTER:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[L2:.*]]
+; CHECK: [[L1:.*]]:
+; CHECK-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[K1_03:%.*]] = phi i32 [ 0, %[[L1]] ], [ [[INC7:%.*]], %[[FOR_INC6:.*]] ]
+; CHECK-NEXT: [[TEMP_12:%.*]] = phi i32 [ [[TEMP_04:%.*]], %[[L1]] ], [ [[ADD:%.*]], %[[FOR_INC6]] ]
+; CHECK-NEXT: br label %[[FOR_BODY3_SPLIT:.*]]
+; CHECK: [[L2]]:
+; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
+; CHECK: [[FOR_BODY3]]:
+; CHECK-NEXT: [[K2_01:%.*]] = phi i32 [ 0, %[[L2]] ], [ [[TMP1:%.*]], %[[FOR_INC_SPLIT:.*]] ]
+; CHECK-NEXT: [[TEMP_04]] = phi i32 [ undef, %[[L2]] ], [ [[TEMP_1_LCSSA:%.*]], %[[FOR_INC_SPLIT]] ]
+; CHECK-NEXT: br label %[[L1]]
+; CHECK: [[FOR_BODY3_SPLIT]]:
+; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[K2_01]] to i64
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x i32], ptr [[FILTER]], i64 [[IDXPROM]]
+; CHECK-NEXT: [[IDXPROM4:%.*]] = sext i32 [[K1_03]] to i64
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [5 x i32], ptr [[ARRAYIDX]], i64 0, i64 [[IDXPROM4]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[ADD]] = add i32 [[TEMP_12]], [[TMP0]]
+; CHECK-NEXT: br label %[[FOR_INC:.*]]
+; CHECK: [[FOR_INC]]:
+; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[K2_01]], 1
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[INC]], 3
+; CHECK-NEXT: br label %[[FOR_END:.*]]
+; CHECK: [[FOR_INC_SPLIT]]:
+; CHECK-NEXT: [[TEMP_1_LCSSA]] = phi i32 [ [[ADD]], %[[FOR_INC6]] ]
+; CHECK-NEXT: [[TMP1]] = add nsw i32 [[K2_01]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 3
+; CHECK-NEXT: br i1 [[TMP2]], label %[[FOR_BODY3]], label %[[FOR_END8:.*]]
+; CHECK: [[FOR_END]]:
+; CHECK-NEXT: br label %[[FOR_INC6]]
+; CHECK: [[FOR_INC6]]:
+; CHECK-NEXT: [[INC7]] = add nsw i32 [[K1_03]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC7]], 5
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_INC_SPLIT]]
+; CHECK: [[FOR_END8]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %L1
@@ -59,4 +87,3 @@ for.end8: ; preds = %for.inc6
ret void
}
-
diff --git a/llvm/test/Transforms/LoopInterchange/profitability-redundant-interchange.ll b/llvm/test/Transforms/LoopInterchange/profitability-redundant-interchange.ll
index ceea36ae7bc4a..fee026d299709 100644
--- a/llvm/test/Transforms/LoopInterchange/profitability-redundant-interchange.ll
+++ b/llvm/test/Transforms/LoopInterchange/profitability-redundant-interchange.ll
@@ -1,7 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=1 -pass-remarks-output=%t -disable-output \
-; RUN: -verify-dom-info -verify-loop-info
-; RUN: FileCheck -input-file %t %s
-
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=1 -S | FileCheck %s
; Test that loop-interchange doesn't undo its own transoformation. This is
; the case when the cost computed by CacheCost is the same for the loop of `j`
@@ -16,31 +14,52 @@
; a[i][k+1][j-1] -= a[i+N-1][k][j];
; }
-; CHECK: --- !Passed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: f
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
-; CHECK-NEXT: ...
-; CHECK-NEXT: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: f
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
-; CHECK-NEXT: ...
-; CHECK-NEXT: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: InterchangeNotProfitable
-; CHECK-NEXT: Function: f
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
-; CHECK-NEXT: ...
-
@a = dso_local local_unnamed_addr global [16 x [16 x [16 x i32]]] zeroinitializer, align 4
define dso_local void @f() {
+; CHECK-LABEL: define dso_local void @f() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV46:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT47:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV46]], 3
+; CHECK-NEXT: br label %[[FOR_BODY8_PREHEADER:.*]]
+; CHECK: [[FOR_COND5_PREHEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND5_PREHEADER:.*]]
+; CHECK: [[FOR_COND5_PREHEADER]]:
+; CHECK-NEXT: [[INDVARS_IV41:%.*]] = phi i64 [ [[INDVARS_IV_NEXT42:%.*]], %[[FOR_COND_CLEANUP7:.*]] ], [ 1, %[[FOR_COND5_PREHEADER_PREHEADER]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV41]], -1
+; CHECK-NEXT: br label %[[FOR_BODY8_SPLIT1:.*]]
+; CHECK: [[FOR_BODY8_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_BODY8:.*]]
+; CHECK: [[FOR_COND_CLEANUP3]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT47]] = add nuw nsw i64 [[INDVARS_IV46]], 1
+; CHECK-NEXT: [[EXITCOND50:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT47]], 4
+; CHECK-NEXT: br i1 [[EXITCOND50]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP7]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT42]] = add nuw nsw i64 [[INDVARS_IV41]], 1
+; CHECK-NEXT: [[EXITCOND45:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT42]], 8
+; CHECK-NEXT: br i1 [[EXITCOND45]], label %[[FOR_COND5_PREHEADER]], label %[[FOR_BODY8_SPLIT:.*]]
+; CHECK: [[FOR_BODY8]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP4:%.*]], %[[FOR_BODY8_SPLIT]] ], [ 1, %[[FOR_BODY8_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_COND5_PREHEADER_PREHEADER]]
+; CHECK: [[FOR_BODY8_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[TMP0]], i64 [[INDVARS_IV]], i64 [[INDVARS_IV41]]
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX12]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[INDVARS_IV46]], i64 [[INDVARS_IV_NEXT]], i64 [[TMP1]]
+; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4
+; CHECK-NEXT: [[SUB21:%.*]] = sub nsw i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT: store i32 [[SUB21]], ptr [[ARRAYIDX20]], align 4
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 8
+; CHECK-NEXT: br label %[[FOR_COND_CLEANUP7]]
+; CHECK: [[FOR_BODY8_SPLIT]]:
+; CHECK-NEXT: [[TMP4]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 8
+; CHECK-NEXT: br i1 [[TMP5]], label %[[FOR_BODY8]], label %[[FOR_COND_CLEANUP3]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.cond1.preheader
diff --git a/llvm/test/Transforms/LoopInterchange/profitability-vectorization-heuristic.ll b/llvm/test/Transforms/LoopInterchange/profitability-vectorization-heuristic.ll
index f05ba0d84211b..342a9e3fb49f6 100644
--- a/llvm/test/Transforms/LoopInterchange/profitability-vectorization-heuristic.ll
+++ b/llvm/test/Transforms/LoopInterchange/profitability-vectorization-heuristic.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \
-; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=vectorize
-; RUN: FileCheck -input-file %t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -loop-interchange-profitabilities=vectorize -S | FileCheck %s
@A = dso_local global [256 x [256 x float]] zeroinitializer
@B = dso_local global [256 x [256 x float]] zeroinitializer
@@ -18,13 +17,47 @@
; }
;
-; CHECK: --- !Passed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: interchange_necessary_for_vectorization
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
define void @interchange_necessary_for_vectorization() {
+; CHECK-LABEL: define void @interchange_necessary_for_vectorization() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_BODY_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[FOR_I_INC:.*]] ], [ 1, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_BODY_SPLIT1:.*]]
+; CHECK: [[FOR_J_BODY_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J_BODY:.*]]
+; CHECK: [[FOR_J_BODY]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR_J_BODY_SPLIT:.*]] ], [ 1, %[[FOR_J_BODY_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_BODY_SPLIT1]]:
+; CHECK-NEXT: [[J_DEC:%.*]] = add nsw i64 [[J]], -1
+; CHECK-NEXT: [[A_LOAD_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @A, i64 0, i64 [[I]], i64 [[J_DEC]]
+; CHECK-NEXT: [[B_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @B, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: [[C_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @C, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[A_LOAD_INDEX]], align 4
+; CHECK-NEXT: [[B:%.*]] = load float, ptr [[B_INDEX]], align 4
+; CHECK-NEXT: [[C:%.*]] = load float, ptr [[C_INDEX]], align 4
+; CHECK-NEXT: [[ADD_0:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: [[A_STORE_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @A, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: store float [[ADD_0]], ptr [[A_STORE_INDEX]], align 4
+; CHECK-NEXT: [[ADD_1:%.*]] = fadd float [[C]], 1.000000e+00
+; CHECK-NEXT: store float [[ADD_1]], ptr [[C_INDEX]], align 4
+; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp eq i64 [[J_NEXT]], 256
+; CHECK-NEXT: br label %[[FOR_I_INC]]
+; CHECK: [[FOR_J_BODY_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 256
+; CHECK-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[FOR_J_BODY]]
+; CHECK: [[FOR_I_INC]]:
+; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I_NEXT]], 256
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_J_BODY_SPLIT]], label %[[FOR_I_HEADER]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -67,13 +100,33 @@ exit:
; A[i][j-1] = A[i][j] + B[i][j];
;
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: InterchangeNotProfitable
-; CHECK-NEXT: Function: interchange_unnecesasry_for_vectorization
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Insufficient information to calculate the cost of loop for interchange.
define void @interchange_unnecesasry_for_vectorization() {
+; CHECK-LABEL: define void @interchange_unnecesasry_for_vectorization() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[FOR_I_INC:.*]] ]
+; CHECK-NEXT: br label %[[FOR_J_BODY:.*]]
+; CHECK: [[FOR_J_BODY]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ 1, %[[FOR_I_HEADER]] ], [ [[J_NEXT:%.*]], %[[FOR_J_BODY]] ]
+; CHECK-NEXT: [[J_DEC:%.*]] = add nsw i64 [[J]], -1
+; CHECK-NEXT: [[A_LOAD_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @A, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: [[B_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @B, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[A_LOAD_INDEX]], align 4
+; CHECK-NEXT: [[B:%.*]] = load float, ptr [[B_INDEX]], align 4
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: [[A_STORE_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @A, i64 0, i64 [[I]], i64 [[J_DEC]]
+; CHECK-NEXT: store float [[ADD]], ptr [[A_STORE_INDEX]], align 4
+; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp eq i64 [[J_NEXT]], 256
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_I_INC]], label %[[FOR_J_BODY]]
+; CHECK: [[FOR_I_INC]]:
+; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I_NEXT]], 256
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[EXIT:.*]], label %[[FOR_I_HEADER]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -118,13 +171,50 @@ exit:
; }
;
-; CHECK: --- !Passed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: interchange_necessary_for_vectorization2
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
define void @interchange_necessary_for_vectorization2() {
+; CHECK-LABEL: define void @interchange_necessary_for_vectorization2() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_BODY_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[FOR_I_INC:.*]] ], [ 1, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[I_INC:%.*]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: br label %[[FOR_J_BODY_SPLIT1:.*]]
+; CHECK: [[FOR_J_BODY_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J_BODY:.*]]
+; CHECK: [[FOR_J_BODY]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR_J_BODY_SPLIT:.*]] ], [ 1, %[[FOR_J_BODY_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_BODY_SPLIT1]]:
+; CHECK-NEXT: [[J_DEC:%.*]] = add nsw i64 [[J]], -1
+; CHECK-NEXT: [[A_LOAD_INDEX:%.*]] = getelementptr inbounds [256 x [256 x float]], ptr @A, i64 0, i64 [[I]], i64 [[J_DEC]]
+; CHECK-NEXT: [[B_INDEX:%.*]] = getelementptr inbounds [256 x [256 x float]], ptr @B, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: [[C_LOAD_INDEX:%.*]] = getelementptr inbounds [256 x [256 x float]], ptr @C, i64 0, i64 [[I_INC]], i64 [[J]]
+; CHECK-NEXT: [[C_STORE_INDEX:%.*]] = getelementptr inbounds [256 x [256 x float]], ptr @C, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: [[A:%.*]] = load float, ptr [[A_LOAD_INDEX]], align 4
+; CHECK-NEXT: [[B:%.*]] = load float, ptr [[B_INDEX]], align 4
+; CHECK-NEXT: [[C0:%.*]] = load float, ptr [[C_LOAD_INDEX]], align 4
+; CHECK-NEXT: [[C1:%.*]] = load float, ptr [[C_STORE_INDEX]], align 4
+; CHECK-NEXT: [[ADD_0:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: [[A_STORE_INDEX:%.*]] = getelementptr inbounds [256 x [256 x float]], ptr @A, i64 0, i64 [[I]], i64 [[J]]
+; CHECK-NEXT: store float [[ADD_0]], ptr [[A_STORE_INDEX]], align 4
+; CHECK-NEXT: [[ADD_1:%.*]] = fadd float [[C0]], [[C1]]
+; CHECK-NEXT: store float [[ADD_1]], ptr [[C_STORE_INDEX]], align 4
+; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp eq i64 [[J_NEXT]], 256
+; CHECK-NEXT: br label %[[FOR_I_INC]]
+; CHECK: [[FOR_J_BODY_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 256
+; CHECK-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[FOR_J_BODY]]
+; CHECK: [[FOR_I_INC]]:
+; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I_NEXT]], 255
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_J_BODY_SPLIT]], label %[[FOR_I_HEADER]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -177,19 +267,44 @@ exit:
; }
; }
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: InterchangeNotProfitable
-; CHECK-NEXT: Function: multiple_BBs_in_loop
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: InterchangeNotProfitable
-; CHECK-NEXT: Function: multiple_BBs_in_loop
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
define void @multiple_BBs_in_loop() {
+; CHECK-LABEL: define void @multiple_BBs_in_loop() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[FOR_I_INC:.*]] ]
+; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: br label %[[FOR_J_HEADER:.*]]
+; CHECK: [[FOR_J_HEADER]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[FOR_I_HEADER]] ], [ [[J_INC:%.*]], %[[FOR_J_INC:.*]] ]
+; CHECK-NEXT: [[J_INC]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: br label %[[FOR_K_BODY:.*]]
+; CHECK: [[FOR_K_BODY]]:
+; CHECK-NEXT: [[K:%.*]] = phi i64 [ 0, %[[FOR_J_HEADER]] ], [ [[K_INC:%.*]], %[[FOR_K_INC:.*]] ]
+; CHECK-NEXT: [[K_INC]] = add nuw nsw i64 [[K]], 1
+; CHECK-NEXT: [[K_2:%.*]] = mul nuw nsw i64 [[K]], 2
+; CHECK-NEXT: [[D_INDEX:%.*]] = getelementptr inbounds [256 x [256 x [256 x float]]], ptr @D, i64 0, i64 [[I_INC]], i64 [[J_INC]], i64 [[K_2]]
+; CHECK-NEXT: [[E_INDEX:%.*]] = getelementptr inbounds [256 x [256 x [256 x float]]], ptr @E, i64 0, i64 [[I]], i64 [[J]], i64 [[K]]
+; CHECK-NEXT: [[D_LOAD:%.*]] = load float, ptr [[D_INDEX]], align 4
+; CHECK-NEXT: store float [[D_LOAD]], ptr [[E_INDEX]], align 4
+; CHECK-NEXT: [[COND:%.*]] = freeze i1 undef
+; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FOR_K_INC]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[D_INDEX2:%.*]] = getelementptr inbounds [256 x [256 x [256 x float]]], ptr @D, i64 0, i64 [[I]], i64 [[J]], i64 [[K_INC]]
+; CHECK-NEXT: store float 1.000000e+00, ptr [[D_INDEX2]], align 4
+; CHECK-NEXT: br label %[[FOR_K_INC]]
+; CHECK: [[FOR_K_INC]]:
+; CHECK-NEXT: [[CMP_K:%.*]] = icmp eq i64 [[K_INC]], 128
+; CHECK-NEXT: br i1 [[CMP_K]], label %[[FOR_J_INC]], label %[[FOR_K_BODY]]
+; CHECK: [[FOR_J_INC]]:
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp eq i64 [[J_INC]], 255
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_I_INC]], label %[[FOR_J_HEADER]]
+; CHECK: [[FOR_I_INC]]:
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I_INC]], 255
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[EXIT:.*]], label %[[FOR_I_HEADER]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
diff --git a/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll b/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
index be7d8c9837c75..886b0484498d7 100644
--- a/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
+++ b/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll
@@ -1,10 +1,8 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \
-; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=instorder
-; RUN: FileCheck -input-file %t --check-prefix=PROFIT-CACHE %s
-
+; RUN: -loop-interchange-profitabilities=instorder -S | FileCheck --check-prefix=PROFIT-CACHE %s
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \
-; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=vectorize,cache,instorder
-; RUN: FileCheck -input-file %t --check-prefix=PROFIT-VEC %s
+; RUN: -loop-interchange-profitabilities=vectorize,cache,instorder -S | FileCheck --check-prefix=PROFIT-VEC %s
@A = dso_local global [256 x [256 x float]] zeroinitializer
@B = dso_local global [256 x [256 x float]] zeroinitializer
@@ -22,22 +20,93 @@
; A[j][i] = A[j-1][i] + B[j][i] + C[i][j] + D[i][j] + E[i][j] + F[i][j];
;
-; PROFIT-CACHE: --- !Missed
-; PROFIT-CACHE-NEXT: Pass: loop-interchange
-; PROFIT-CACHE-NEXT: Name: InterchangeNotProfitable
-; PROFIT-CACHE-NEXT: Function: f
-; PROFIT-CACHE-NEXT: Args:
-; PROFIT-CACHE-NEXT: - String: Insufficient information to calculate the cost of loop for interchange.
-; PROFIT-CACHE-NEXT: ...
-
-; PROFIT-VEC: --- !Passed
-; PROFIT-VEC-NEXT: Pass: loop-interchange
-; PROFIT-VEC-NEXT: Name: Interchanged
-; PROFIT-VEC-NEXT: Function: f
-; PROFIT-VEC-NEXT: Args:
-; PROFIT-VEC-NEXT: - String: Loop interchanged with enclosing loop.
-; PROFIT-VEC-NEXT: ...
define void @f() {
+; PROFIT-CACHE-LABEL: define void @f() {
+; PROFIT-CACHE-NEXT: [[ENTRY:.*]]:
+; PROFIT-CACHE-NEXT: br label %[[FOR_I_HEADER:.*]]
+; PROFIT-CACHE: [[FOR_I_HEADER]]:
+; PROFIT-CACHE-NEXT: [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[FOR_I_INC:.*]] ]
+; PROFIT-CACHE-NEXT: br label %[[FOR_J_BODY:.*]]
+; PROFIT-CACHE: [[FOR_J_BODY]]:
+; PROFIT-CACHE-NEXT: [[J:%.*]] = phi i64 [ 1, %[[FOR_I_HEADER]] ], [ [[J_NEXT:%.*]], %[[FOR_J_BODY]] ]
+; PROFIT-CACHE-NEXT: [[J_DEC:%.*]] = add nsw i64 [[J]], -1
+; PROFIT-CACHE-NEXT: [[A_0_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @A, i64 0, i64 [[J_DEC]], i64 [[I]]
+; PROFIT-CACHE-NEXT: [[B_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @B, i64 0, i64 [[J]], i64 [[I]]
+; PROFIT-CACHE-NEXT: [[C_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @C, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-CACHE-NEXT: [[D_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @D, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-CACHE-NEXT: [[E_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @E, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-CACHE-NEXT: [[F_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @F, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-CACHE-NEXT: [[A_0:%.*]] = load float, ptr [[A_0_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[B:%.*]] = load float, ptr [[B_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[C:%.*]] = load float, ptr [[C_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[D:%.*]] = load float, ptr [[D_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[E:%.*]] = load float, ptr [[E_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[F:%.*]] = load float, ptr [[F_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[ADD_0:%.*]] = fadd float [[A_0]], [[B]]
+; PROFIT-CACHE-NEXT: [[ADD_1:%.*]] = fadd float [[ADD_0]], [[C]]
+; PROFIT-CACHE-NEXT: [[ADD_2:%.*]] = fadd float [[ADD_1]], [[D]]
+; PROFIT-CACHE-NEXT: [[ADD_3:%.*]] = fadd float [[ADD_2]], [[E]]
+; PROFIT-CACHE-NEXT: [[ADD_4:%.*]] = fadd float [[ADD_3]], [[F]]
+; PROFIT-CACHE-NEXT: [[A_1_INDEX:%.*]] = getelementptr inbounds nuw [256 x float], ptr @A, i64 [[J]], i64 [[I]]
+; PROFIT-CACHE-NEXT: store float [[ADD_4]], ptr [[A_1_INDEX]], align 4
+; PROFIT-CACHE-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J]], 1
+; PROFIT-CACHE-NEXT: [[CMP_J:%.*]] = icmp eq i64 [[J_NEXT]], 256
+; PROFIT-CACHE-NEXT: br i1 [[CMP_J]], label %[[FOR_I_INC]], label %[[FOR_J_BODY]]
+; PROFIT-CACHE: [[FOR_I_INC]]:
+; PROFIT-CACHE-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; PROFIT-CACHE-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I_NEXT]], 256
+; PROFIT-CACHE-NEXT: br i1 [[CMP_I]], label %[[EXIT:.*]], label %[[FOR_I_HEADER]]
+; PROFIT-CACHE: [[EXIT]]:
+; PROFIT-CACHE-NEXT: ret void
+;
+; PROFIT-VEC-LABEL: define void @f() {
+; PROFIT-VEC-NEXT: [[ENTRY:.*:]]
+; PROFIT-VEC-NEXT: br label %[[FOR_J_BODY_PREHEADER:.*]]
+; PROFIT-VEC: [[FOR_I_HEADER_PREHEADER:.*]]:
+; PROFIT-VEC-NEXT: br label %[[FOR_I_HEADER:.*]]
+; PROFIT-VEC: [[FOR_I_HEADER]]:
+; PROFIT-VEC-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[FOR_I_INC:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; PROFIT-VEC-NEXT: br label %[[FOR_J_BODY_SPLIT1:.*]]
+; PROFIT-VEC: [[FOR_J_BODY_PREHEADER]]:
+; PROFIT-VEC-NEXT: br label %[[FOR_J_BODY:.*]]
+; PROFIT-VEC: [[FOR_J_BODY]]:
+; PROFIT-VEC-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR_J_BODY_SPLIT:.*]] ], [ 1, %[[FOR_J_BODY_PREHEADER]] ]
+; PROFIT-VEC-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; PROFIT-VEC: [[FOR_J_BODY_SPLIT1]]:
+; PROFIT-VEC-NEXT: [[J_DEC:%.*]] = add nsw i64 [[J]], -1
+; PROFIT-VEC-NEXT: [[A_0_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @A, i64 0, i64 [[J_DEC]], i64 [[I]]
+; PROFIT-VEC-NEXT: [[B_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @B, i64 0, i64 [[J]], i64 [[I]]
+; PROFIT-VEC-NEXT: [[C_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @C, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-VEC-NEXT: [[D_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @D, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-VEC-NEXT: [[E_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @E, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-VEC-NEXT: [[F_INDEX:%.*]] = getelementptr inbounds nuw [256 x [256 x float]], ptr @F, i64 0, i64 [[I]], i64 [[J]]
+; PROFIT-VEC-NEXT: [[A_0:%.*]] = load float, ptr [[A_0_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[B:%.*]] = load float, ptr [[B_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[C:%.*]] = load float, ptr [[C_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[D:%.*]] = load float, ptr [[D_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[E:%.*]] = load float, ptr [[E_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[F:%.*]] = load float, ptr [[F_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[ADD_0:%.*]] = fadd float [[A_0]], [[B]]
+; PROFIT-VEC-NEXT: [[ADD_1:%.*]] = fadd float [[ADD_0]], [[C]]
+; PROFIT-VEC-NEXT: [[ADD_2:%.*]] = fadd float [[ADD_1]], [[D]]
+; PROFIT-VEC-NEXT: [[ADD_3:%.*]] = fadd float [[ADD_2]], [[E]]
+; PROFIT-VEC-NEXT: [[ADD_4:%.*]] = fadd float [[ADD_3]], [[F]]
+; PROFIT-VEC-NEXT: [[A_1_INDEX:%.*]] = getelementptr inbounds nuw [256 x float], ptr @A, i64 [[J]], i64 [[I]]
+; PROFIT-VEC-NEXT: store float [[ADD_4]], ptr [[A_1_INDEX]], align 4
+; PROFIT-VEC-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; PROFIT-VEC-NEXT: [[CMP_J:%.*]] = icmp eq i64 [[J_NEXT]], 256
+; PROFIT-VEC-NEXT: br label %[[FOR_I_INC]]
+; PROFIT-VEC: [[FOR_J_BODY_SPLIT]]:
+; PROFIT-VEC-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
+; PROFIT-VEC-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 256
+; PROFIT-VEC-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[FOR_J_BODY]]
+; PROFIT-VEC: [[FOR_I_INC]]:
+; PROFIT-VEC-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; PROFIT-VEC-NEXT: [[CMP_I:%.*]] = icmp eq i64 [[I_NEXT]], 256
+; PROFIT-VEC-NEXT: br i1 [[CMP_I]], label %[[FOR_J_BODY_SPLIT]], label %[[FOR_I_HEADER]]
+; PROFIT-VEC: [[EXIT]]:
+; PROFIT-VEC-NEXT: ret void
+;
entry:
br label %for.i.header
diff --git a/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll b/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
index 51fda4cf1ebe1..041428a8fe1e0 100644
--- a/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
+++ b/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll
@@ -1,57 +1,44 @@
-; 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 -verify-loop-lcssa -stats 2>&1 | FileCheck %s
-; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s
-
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test1
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: test1
-
define i64 @test1(ptr %Arr) {
-; CHECK-LABEL: @test1(
-; 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_INC:%.*]] ], [ 0, [[FOR1_HEADER_PREHEADER:%.*]] ]
-; CHECK-NEXT: [[SUM_INNER:%.*]] = phi i64 [ [[SUM_INC:%.*]], [[FOR1_INC]] ], [ [[SUM_OUTER:%.*]], [[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 [ [[INDVARS_IV_NEXT_3:%.*]], [[FOR2_SPLIT:%.*]] ], [ 0, [[FOR2_PREHEADER]] ]
-; CHECK-NEXT: [[SUM_OUTER]] = phi i64 [ [[SUM_INC_LCSSA:%.*]], [[FOR2_SPLIT]] ], [ 0, [[FOR2_PREHEADER]] ]
-; CHECK-NEXT: br label [[FOR1_HEADER_PREHEADER]]
-; CHECK: for2.split1:
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr [[ARR:%.*]], i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+;
+; CHECK-LABEL: define i64 @test1(
+; CHECK-SAME: ptr [[ARR:%.*]]) {
+; 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_INC:.*]] ], [ 0, %[[FOR1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[SUM_INNER:%.*]] = phi i64 [ [[SUM_INC:%.*]], %[[FOR1_INC]] ], [ [[SUM_OUTER:%.*]], %[[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:.*]] ], [ 0, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT: [[SUM_OUTER]] = phi i64 [ [[SUM_INC_LCSSA:%.*]], %[[FOR2_SPLIT]] ], [ 0, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR1_HEADER_PREHEADER]]
+; CHECK: [[FOR2_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr [[ARR]], i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX]], align 4
; CHECK-NEXT: [[SUM_INC]] = add i64 [[SUM_INNER]], [[LV]]
-; CHECK-NEXT: [[IV_ORIGINAL:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
-; CHECK-NEXT: [[EXIT1_ORIGINAL:%.*]] = icmp eq i64 [[IV_ORIGINAL]], 100
-; CHECK-NEXT: br label [[FOR1_INC]]
-; CHECK: for2.split:
-; CHECK-NEXT: [[SUM_INC_LCSSA]] = phi i64 [ [[SUM_INC]], %for1.inc ]
-; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[EXIT1:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_3]], 100
-; CHECK-NEXT: br i1 [[EXIT1]], label [[FOR1_LOOPEXIT:%.*]], label [[FOR2]]
-; CHECK: for1.inc:
+; CHECK-NEXT: br label %[[FOR1_INC]]
+; CHECK: [[FOR2_SPLIT]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA]] = phi i64 [ [[SUM_INC]], %[[FOR1_INC]] ]
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 100
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR2]]
+; CHECK: [[FOR1_INC]]:
; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
; CHECK-NEXT: [[EXIT2:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT24]], 100
-; CHECK-NEXT: br i1 [[EXIT2]], label [[FOR2_SPLIT]], label [[FOR1_HEADER]]
-; CHECK: for1.loopexit:
-; CHECK-NEXT: [[SUM_INC_LCSSA2:%.*]] = phi i64 [ [[SUM_INC_LCSSA]], [[FOR2_SPLIT]] ]
+; CHECK-NEXT: br i1 [[EXIT2]], label %[[FOR2_SPLIT]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA2:%.*]] = phi i64 [ [[SUM_INC_LCSSA]], %[[FOR2_SPLIT]] ]
; CHECK-NEXT: ret i64 [[SUM_INC_LCSSA2]]
;
entry:
@@ -85,20 +72,34 @@ for1.loopexit: ; preds = %for1.inc
; In this test case, the inner reduction PHI %inner does not involve the outer
; reduction PHI %sum.outer, do not interchange.
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test2
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: UnsupportedPHIOuter
-; REMARKS-NEXT: Function: test2
define i64 @test2(ptr %Arr) {
+; CHECK-LABEL: define i64 @test2(
+; CHECK-SAME: ptr [[ARR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[INDVARS_IV23:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR1_INC:.*]] ]
+; CHECK-NEXT: [[SUM_OUTER:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[SUM_INC_LCSSA:%.*]], %[[FOR1_INC]] ]
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR1_HEADER]] ], [ [[INDVARS_IV_NEXT_3:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[INNER:%.*]] = phi i64 [ [[INDVARS_IV23]], %[[FOR1_HEADER]] ], [ [[SUM_INC:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr [[ARR]], i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[SUM_INC]] = add i64 [[INNER]], [[LV]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT1:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_3]], 100
+; CHECK-NEXT: br i1 [[EXIT1]], label %[[FOR1_INC]], label %[[FOR2]]
+; CHECK: [[FOR1_INC]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA]] = phi i64 [ [[SUM_INC]], %[[FOR2]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT: [[EXIT2:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT24]], 100
+; CHECK-NEXT: br i1 [[EXIT2]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA2:%.*]] = phi i64 [ [[SUM_INC_LCSSA]], %[[FOR1_INC]] ]
+; CHECK-NEXT: ret i64 [[SUM_INC_LCSSA2]]
+;
entry:
br label %for1.header
@@ -130,20 +131,35 @@ for1.loopexit: ; preds = %for1.inc
; Check that we do not interchange if there is an additional instruction
; between the outer and inner reduction PHIs.
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test3
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: UnsupportedPHIOuter
-; REMARKS-NEXT: Function: test3
define i64 @test3(ptr %Arr) {
+; CHECK-LABEL: define i64 @test3(
+; CHECK-SAME: ptr [[ARR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[INDVARS_IV23:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR1_INC:.*]] ]
+; CHECK-NEXT: [[SUM_OUTER:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[SUM_INC_LCSSA:%.*]], %[[FOR1_INC]] ]
+; CHECK-NEXT: [[SO:%.*]] = add i64 [[SUM_OUTER]], 10
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR1_HEADER]] ], [ [[INDVARS_IV_NEXT_3:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[SUM_INNER:%.*]] = phi i64 [ [[SO]], %[[FOR1_HEADER]] ], [ [[SUM_INC:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr [[ARR]], i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[SUM_INC]] = add i64 [[SUM_INNER]], [[LV]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT1:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_3]], 100
+; CHECK-NEXT: br i1 [[EXIT1]], label %[[FOR1_INC]], label %[[FOR2]]
+; CHECK: [[FOR1_INC]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA]] = phi i64 [ [[SUM_INC]], %[[FOR2]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT: [[EXIT2:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT24]], 100
+; CHECK-NEXT: br i1 [[EXIT2]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA2:%.*]] = phi i64 [ [[SUM_INC_LCSSA]], %[[FOR1_INC]] ]
+; CHECK-NEXT: ret i64 [[SUM_INC_LCSSA2]]
+;
entry:
br label %for1.header
@@ -175,20 +191,36 @@ for1.loopexit: ; preds = %for1.inc
}
; Check that we do not interchange if reduction is stored in an invariant address inside inner loop
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test4
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test4
define i64 @test4(ptr %Arr, ptr %dst) {
+; CHECK-LABEL: define i64 @test4(
+; CHECK-SAME: ptr [[ARR:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 42
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[INDVARS_IV23:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR1_INC:.*]] ]
+; CHECK-NEXT: [[SUM_OUTER:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[SUM_INC_LCSSA:%.*]], %[[FOR1_INC]] ]
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR1_HEADER]] ], [ [[INDVARS_IV_NEXT_3:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[SUM_INNER:%.*]] = phi i64 [ [[SUM_OUTER]], %[[FOR1_HEADER]] ], [ [[SUM_INC:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr [[ARR]], i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[SUM_INC]] = add i64 [[SUM_INNER]], [[LV]]
+; CHECK-NEXT: store i64 [[SUM_INC]], ptr [[GEP_DST]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT1:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_3]], 100
+; CHECK-NEXT: br i1 [[EXIT1]], label %[[FOR1_INC]], label %[[FOR2]]
+; CHECK: [[FOR1_INC]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA]] = phi i64 [ [[SUM_INC]], %[[FOR2]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT: [[EXIT2:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT24]], 100
+; CHECK-NEXT: br i1 [[EXIT2]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA2:%.*]] = phi i64 [ [[SUM_INC_LCSSA]], %[[FOR1_INC]] ]
+; CHECK-NEXT: ret i64 [[SUM_INC_LCSSA2]]
+;
entry:
%gep.dst = getelementptr inbounds i64, ptr %dst, i64 42
br label %for1.header
@@ -222,20 +254,36 @@ for1.loopexit: ; preds = %for1.inc
; Check that we do not interchange or crash if the PHI in the outer loop gets a
; constant from the inner loop.
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test_constant_inner_loop_res
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: UnsupportedPHIOuter
-; REMARKS-NEXT: Function: test_constant_inner_loop_res
define i64 @test_constant_inner_loop_res(ptr %Arr) {
+; CHECK-LABEL: define i64 @test_constant_inner_loop_res(
+; CHECK-SAME: ptr [[ARR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[INDVARS_IV23:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR1_INC:.*]] ]
+; CHECK-NEXT: [[SUM_OUTER:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[SUM_INC_AMEND:%.*]], %[[FOR1_INC]] ]
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR1_HEADER]] ], [ [[INDVARS_IV_NEXT_3:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[SUM_INNER:%.*]] = phi i64 [ [[SUM_OUTER]], %[[FOR1_HEADER]] ], [ [[SUM_INC:%.*]], %[[FOR2]] ]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr [[ARR]], i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[SUM_INC]] = add i64 [[SUM_INNER]], [[LV]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT1:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_3]], 100
+; CHECK-NEXT: br i1 [[EXIT1]], label %[[FOR1_INC]], label %[[FOR2]]
+; CHECK: [[FOR1_INC]]:
+; CHECK-NEXT: [[SUM_INC_LCSSA:%.*]] = phi i64 [ [[SUM_INC]], %[[FOR2]] ]
+; CHECK-NEXT: [[CONST_LCSSA:%.*]] = phi i64 [ 0, %[[FOR2]] ]
+; CHECK-NEXT: [[SUM_INC_AMEND]] = add i64 [[CONST_LCSSA]], [[SUM_INC_LCSSA]]
+; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT: [[EXIT2:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT24]], 100
+; CHECK-NEXT: br i1 [[EXIT2]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT: [[IL_RES_LCSSA2:%.*]] = phi i64 [ [[SUM_INC_AMEND]], %[[FOR1_INC]] ]
+; CHECK-NEXT: ret i64 [[IL_RES_LCSSA2]]
+;
entry:
br label %for1.header
@@ -269,20 +317,47 @@ for1.loopexit: ; preds = %for1.inc
; Floating point reductions are interchanged if all the fp instructions
; involved allow reassociation.
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test5
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Passed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Interchanged
-; REMARKS-NEXT: Function: test5
define float @test5(ptr %Arr, ptr %Arr2) {
+; CHECK-LABEL: define float @test5(
+; CHECK-SAME: ptr [[ARR:%.*]], ptr [[ARR2:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_BODY3_PREHEADER:.*]]
+; CHECK: [[OUTER_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i64 [ [[IV_OUTER_NEXT:%.*]], %[[OUTER_INC:.*]] ], [ 1, %[[OUTER_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[FLOAT_INNER:%.*]] = phi float [ [[FLOAT_INNER_INC_INC:%.*]], %[[OUTER_INC]] ], [ [[FLOAT_OUTER:%.*]], %[[OUTER_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_BODY3_SPLIT1:.*]]
+; CHECK: [[FOR_BODY3_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
+; CHECK: [[FOR_BODY3]]:
+; CHECK-NEXT: [[IV_INNER:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR_BODY3_SPLIT:.*]] ], [ 1, %[[FOR_BODY3_PREHEADER]] ]
+; CHECK-NEXT: [[FLOAT_OUTER]] = phi float [ [[FLOAT_INNER_LCSSA:%.*]], %[[FOR_BODY3_SPLIT]] ], [ 1.000000e+00, %[[FOR_BODY3_PREHEADER]] ]
+; CHECK-NEXT: br label %[[OUTER_HEADER_PREHEADER]]
+; CHECK: [[FOR_BODY3_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x float]], ptr [[ARR]], i64 0, i64 [[IV_INNER]], i64 [[IV_OUTER]]
+; CHECK-NEXT: [[VA:%.*]] = load float, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[FLOAT_INNER_INC:%.*]] = fadd reassoc nnan nsz arcp contract afn float [[FLOAT_INNER]], [[VA]]
+; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x [100 x float]], ptr [[ARR2]], i64 0, i64 [[IV_INNER]], i64 [[IV_OUTER]]
+; CHECK-NEXT: [[VB:%.*]] = load float, ptr [[ARRAYIDX6]], align 4
+; CHECK-NEXT: [[FLOAT_INNER_INC_INC]] = fadd reassoc nnan nsz arcp contract afn float [[FLOAT_INNER_INC]], [[VB]]
+; CHECK-NEXT: [[IV_INNER_NEXT:%.*]] = add nuw nsw i64 [[IV_INNER]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp slt i64 [[IV_INNER_NEXT]], 100
+; CHECK-NEXT: br label %[[OUTER_INC]]
+; CHECK: [[FOR_BODY3_SPLIT]]:
+; CHECK-NEXT: [[FLOAT_INNER_LCSSA]] = phi float [ [[FLOAT_INNER_INC_INC]], %[[OUTER_INC]] ]
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[IV_INNER]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[TMP0]], 100
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_BODY3]], label %[[FOR_EXIT:.*]]
+; CHECK: [[OUTER_INC]]:
+; CHECK-NEXT: [[IV_OUTER_NEXT]] = add nsw i64 [[IV_OUTER]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[IV_OUTER_NEXT]], 100
+; CHECK-NEXT: br i1 [[CMP]], label %[[OUTER_HEADER]], label %[[FOR_BODY3_SPLIT]]
+; CHECK: [[FOR_EXIT]]:
+; CHECK-NEXT: [[FLOAT_OUTER_LCSSA:%.*]] = phi float [ [[FLOAT_INNER_LCSSA]], %[[FOR_BODY3_SPLIT]] ]
+; CHECK-NEXT: ret float [[FLOAT_OUTER_LCSSA]]
+;
entry:
br label %outer.header
@@ -317,20 +392,37 @@ for.exit: ; preds = %outer.inc
; Floating point reductions are not interchanged if not all the fp instructions
; involved allow reassociation.
-; REMARKS: --- !Analysis
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: Dependence
-; REMARKS-NEXT: Function: test6
-; REMARKS-NEXT: Args:
-; REMARKS-NEXT: - String: Computed dependence info, invoking the transform.
-; REMARKS-NEXT: ...
-
-; REMARKS: --- !Missed
-; REMARKS-NEXT: Pass: loop-interchange
-; REMARKS-NEXT: Name: UnsupportedPHIOuter
-; REMARKS-NEXT: Function: test6
define float @test6(ptr %Arr, ptr %Arr2) {
+; CHECK-LABEL: define float @test6(
+; CHECK-SAME: ptr [[ARR:%.*]], ptr [[ARR2:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[IV_OUTER_NEXT:%.*]], %[[OUTER_INC:.*]] ]
+; CHECK-NEXT: [[FLOAT_OUTER:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[FLOAT_INNER_LCSSA:%.*]], %[[OUTER_INC]] ]
+; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
+; CHECK: [[FOR_BODY3]]:
+; CHECK-NEXT: [[FLOAT_INNER:%.*]] = phi float [ [[FLOAT_OUTER]], %[[OUTER_HEADER]] ], [ [[FLOAT_INNER_INC_INC:%.*]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: [[IV_INNER:%.*]] = phi i64 [ [[IV_INNER_NEXT:%.*]], %[[FOR_BODY3]] ], [ 1, %[[OUTER_HEADER]] ]
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x float]], ptr [[ARR]], i64 0, i64 [[IV_INNER]], i64 [[IV_OUTER]]
+; CHECK-NEXT: [[VA:%.*]] = load float, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[FLOAT_INNER_INC:%.*]] = fadd float [[FLOAT_INNER]], [[VA]]
+; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x [100 x float]], ptr [[ARR2]], i64 0, i64 [[IV_INNER]], i64 [[IV_OUTER]]
+; CHECK-NEXT: [[VB:%.*]] = load float, ptr [[ARRAYIDX6]], align 4
+; CHECK-NEXT: [[FLOAT_INNER_INC_INC]] = fadd fast float [[FLOAT_INNER_INC]], [[VB]]
+; CHECK-NEXT: [[IV_INNER_NEXT]] = add nuw nsw i64 [[IV_INNER]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[IV_INNER_NEXT]], 100
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[OUTER_INC]], label %[[FOR_BODY3]]
+; CHECK: [[OUTER_INC]]:
+; CHECK-NEXT: [[FLOAT_INNER_LCSSA]] = phi float [ [[FLOAT_INNER_INC_INC]], %[[FOR_BODY3]] ]
+; CHECK-NEXT: [[IV_OUTER_NEXT]] = add nsw i64 [[IV_OUTER]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_OUTER_NEXT]], 100
+; CHECK-NEXT: br i1 [[CMP]], label %[[OUTER_HEADER]], label %[[FOR_EXIT:.*]]
+; CHECK: [[FOR_EXIT]]:
+; CHECK-NEXT: [[FLOAT_OUTER_LCSSA:%.*]] = phi float [ [[FLOAT_INNER_LCSSA]], %[[OUTER_INC]] ]
+; CHECK-NEXT: ret float [[FLOAT_OUTER_LCSSA]]
+;
entry:
br label %outer.header
diff --git a/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll b/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
index a1404b83cea4a..29067ff926347 100644
--- a/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
+++ b/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-output=%t -disable-output \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa
-; RUN: FileCheck -input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -S | FileCheck %s
; Check that interchanging the loops is legal for the bitwise-or reduction.
;
@@ -9,11 +8,42 @@
; for (int j = 0; j < 2; j++)
; b_or |= A[j][i];
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_or
define void @reduction_or(ptr %A) {
+; CHECK-LABEL: define void @reduction_or(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[OR_J:%.*]] = phi i32 [ [[OR_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[OR_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[OR_I]] = phi i32 [ [[OR_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[OR_J_NEXT]] = or i32 [[OR_J]], [[A]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[OR_I_LCSSA]] = phi i32 [ [[OR_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -42,7 +72,6 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the bitwise-and reduction.
;
; int b_and = -1;
@@ -50,11 +79,42 @@ exit:
; for (int j = 0; j < 2; j++)
; b_and &= A[j][i];
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_and
define void @reduction_and(ptr %A) {
+; CHECK-LABEL: define void @reduction_and(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[AND_J:%.*]] = phi i32 [ [[AND_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[AND_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[AND_I]] = phi i32 [ [[AND_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ -1, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[AND_J_NEXT]] = and i32 [[AND_J]], [[A]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[AND_I_LCSSA]] = phi i32 [ [[AND_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -83,7 +143,6 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the bitwise-xor reduction.
;
; int b_xor = 0;
@@ -91,11 +150,42 @@ exit:
; for (int j = 0; j < 2; j++)
; b_xor ^= A[j][i];
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_xor
define void @reduction_xor(ptr %A) {
+; CHECK-LABEL: define void @reduction_xor(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[XOR_J:%.*]] = phi i32 [ [[XOR_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[XOR_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[XOR_I]] = phi i32 [ [[XOR_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[XOR_J_NEXT]] = xor i32 [[XOR_J]], [[A]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[XOR_I_LCSSA]] = phi i32 [ [[XOR_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -124,7 +214,6 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the signed-minimum reduction.
;
; int smin = init;
@@ -132,11 +221,43 @@ exit:
; for (int j = 0; j < 2; j++)
; smin = (A[j][i] < smin) ? A[j][i] : smin;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_smin
define void @reduction_smin(ptr %A, i32 %init) {
+; CHECK-LABEL: define void @reduction_smin(
+; CHECK-SAME: ptr [[A:%.*]], i32 [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[SMIN_J:%.*]] = phi i32 [ [[SMIN_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[SMIN_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[SMIN_I]] = phi i32 [ [[SMIN_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[SMIN_J]]
+; CHECK-NEXT: [[SMIN_J_NEXT]] = select i1 [[CMP]], i32 [[A]], i32 [[SMIN_J]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[SMIN_I_LCSSA]] = phi i32 [ [[SMIN_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -166,7 +287,6 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the signed-maximum reduction.
;
; int smax = init;
@@ -174,11 +294,43 @@ exit:
; for (int j = 0; j < 2; j++)
; smax = (A[j][i] > smax) ? A[j][i] : smax;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_smax
define void @reduction_smax(ptr %A, i32 %init) {
+; CHECK-LABEL: define void @reduction_smax(
+; CHECK-SAME: ptr [[A:%.*]], i32 [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[SMAX_J:%.*]] = phi i32 [ [[SMAX_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[SMAX_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[SMAX_I]] = phi i32 [ [[SMAX_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[SMAX_J]]
+; CHECK-NEXT: [[SMAX_J_NEXT]] = select i1 [[CMP]], i32 [[A]], i32 [[SMAX_J]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[SMAX_I_LCSSA]] = phi i32 [ [[SMAX_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -208,7 +360,6 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the unsigned-minimum reduction.
;
; unsigned umin = init;
@@ -216,11 +367,43 @@ exit:
; for (int j = 0; j < 2; j++)
; umin = (A[j][i] < umin) ? A[j][i] : umin;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_umin
define void @reduction_umin(ptr %A, i32 %init) {
+; CHECK-LABEL: define void @reduction_umin(
+; CHECK-SAME: ptr [[A:%.*]], i32 [[INIT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[UMIN_J:%.*]] = phi i32 [ [[UMIN_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[UMIN_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[UMIN_I]] = phi i32 [ [[UMIN_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ [[INIT]], %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[UMIN_J]]
+; CHECK-NEXT: [[UMIN_J_NEXT]] = select i1 [[CMP]], i32 [[A]], i32 [[UMIN_J]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[UMIN_I_LCSSA]] = phi i32 [ [[UMIN_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -250,7 +433,6 @@ exit:
ret void
}
-
; Check that interchanging the loops is legal for the unsigned-maximum reduction.
;
; unsigned umax = 0;
@@ -258,11 +440,43 @@ exit:
; for (int j = 0; j < 2; j++)
; smax = (A[j][i] > smax) ? A[j][i] : smax;
-; CHECK: --- !Pass
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: reduction_umax
define void @reduction_umax(ptr %A) {
+; CHECK-LABEL: define void @reduction_umax(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR_J_PREHEADER:.*]]
+; CHECK: [[FOR_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[UMAX_J:%.*]] = phi i32 [ [[UMAX_J_NEXT:%.*]], %[[FOR_I_LATCH]] ], [ [[UMAX_I:%.*]], %[[FOR_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_J_SPLIT1:.*]]
+; CHECK: [[FOR_J_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[TMP0:%.*]], %[[FOR_J_SPLIT:.*]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: [[UMAX_I]] = phi i32 [ [[UMAX_I_LCSSA:%.*]], %[[FOR_J_SPLIT]] ], [ 0, %[[FOR_J_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR_I_HEADER_PREHEADER]]
+; CHECK: [[FOR_J_SPLIT1]]:
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[UMAX_J]]
+; CHECK-NEXT: [[UMAX_J_NEXT]] = select i1 [[CMP]], i32 [[A]], i32 [[UMAX_J]]
+; CHECK-NEXT: [[J_INC:%.*]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_J_SPLIT]]:
+; CHECK-NEXT: [[UMAX_I_LCSSA]] = phi i32 [ [[UMAX_J_NEXT]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: [[TMP0]] = add i32 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_J]], label %[[EXIT:.*]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[FOR_J_SPLIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
@@ -301,13 +515,33 @@ exit:
; for (int j = 0; j < 2; j++)
; any_of = (A[j][i] == 42) ? 1 : any_of;
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: UnsupportedPHIOuter
-; CHECK-NEXT: Function: reduction_anyof
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Only outer loops with induction or reduction PHI nodes
define void @reduction_anyof(ptr %A) {
+; CHECK-LABEL: define void @reduction_anyof(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_I_HEADER:.*]]
+; CHECK: [[FOR_I_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ]
+; CHECK-NEXT: [[ANYOF_I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[ANYOF_I_LCSSA:%.*]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT: br label %[[FOR_J:.*]]
+; CHECK: [[FOR_J]]:
+; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[FOR_I_HEADER]] ], [ [[J_INC:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[ANYOF_J:%.*]] = phi i32 [ [[ANYOF_I]], %[[FOR_I_HEADER]] ], [ [[ANYOF_J_NEXT:%.*]], %[[FOR_J]] ]
+; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[A]], i32 0, i32 [[J]], i32 [[I]]
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[IDX]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 42
+; CHECK-NEXT: [[ANYOF_J_NEXT]] = select i1 [[CMP]], i32 1, i32 [[ANYOF_J]]
+; CHECK-NEXT: [[J_INC]] = add i32 [[J]], 1
+; CHECK-NEXT: [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_J]], label %[[FOR_J]], label %[[FOR_I_LATCH]]
+; CHECK: [[FOR_I_LATCH]]:
+; CHECK-NEXT: [[ANYOF_I_LCSSA]] = phi i32 [ [[ANYOF_J_NEXT]], %[[FOR_J]] ]
+; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[I_INC]], 2
+; CHECK-NEXT: br i1 [[CMP_I]], label %[[FOR_I_HEADER]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for.i.header
More information about the llvm-commits
mailing list