-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[LoopInterchange] Don't rely on ASSERTS build for tests. NFC. #116780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
A lot of interchange tests unnecessary relied on a build with ASSERTS enabled. Instead, simply check the IR output for both negative and positive tests so that we don't rely on debug messages. This increases test coverage as these tests will now also run with non-assert builds. For a couple of files keeping some of the debug tests was useful, so separated out them out and moved them to a similarly named *-remarks.ll file.
@llvm/pr-subscribers-llvm-transforms Author: Sjoerd Meijer (sjoerdmeijer) ChangesA lot of interchange tests unnecessary relied on a build with ASSERTS enabled. Instead, simply check the IR output for both negative and positive tests so that we don't rely on debug messages. This increases test coverage as these tests will now also run with non-assert builds. For a couple of files keeping some of the debug tests was useful, so separated out them out and moved them to a similarly named *-remarks.ll file. Patch is 52.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116780.diff 11 Files Affected:
diff --git a/llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll b/llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll
new file mode 100644
index 00000000000000..4ed3e7e0f5d003
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/call-instructions-remarks.ll
@@ -0,0 +1,63 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
+; RUN: -verify-dom-info -verify-loop-info 2>&1
+; RUN: FileCheck --input-file=%t %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+@A = common global [100 x [100 x i32]] zeroinitializer
+
+declare void @foo(i64 %a)
+declare void @bar(i64 %a) readnone
+
+;;--------------------------------------Test case 01------------------------------------
+;; Not safe to interchange, because the called function `foo` is not marked as
+;; readnone, so it could introduce dependences.
+;;
+;; for(int i=0;i<100;i++) {
+;; for(int j=1;j<100;j++) {
+;; foo(i);
+;; A[j][i] = A[j][i]+k;
+;; }
+;; }
+
+; CHECK: --- !Missed
+; CHECK-NEXT: Pass: loop-interchange
+; CHECK-NEXT: Name: CallInst
+; CHECK-NEXT: Function: interchange_01
+; CHECK-NEXT: Args:
+; CHECK-NEXT: - String: Cannot interchange loops due to call instruction.
+
+define void @interchange_01(i32 %k) {
+entry:
+ br label %for1.header
+
+for1.header:
+ %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc10 ]
+ br label %for2
+
+for2:
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for2 ], [ 1, %for1.header ]
+ call void @foo(i64 %indvars.iv23)
+ %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
+ %lv = load i32, ptr %arrayidx5
+ %add = add nsw i32 %lv, %k
+ store i32 %add, ptr %arrayidx5
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv, 99
+ br i1 %exitcond, label %for2.loopexit , label %for2
+
+for2.loopexit:
+ br label %for1.inc10
+
+for1.inc10:
+ %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
+ %exitcond26 = icmp eq i64 %indvars.iv23, 99
+ br i1 %exitcond26, label %for1.loopexit, label %for1.header
+
+for1.loopexit:
+ br label %exit
+
+exit:
+ ret void
+}
diff --git a/llvm/test/Transforms/LoopInterchange/call-instructions.ll b/llvm/test/Transforms/LoopInterchange/call-instructions.ll
index 49e877aa0d36e7..b207166302d21c 100644
--- a/llvm/test/Transforms/LoopInterchange/call-instructions.ll
+++ b/llvm/test/Transforms/LoopInterchange/call-instructions.ll
@@ -1,7 +1,5 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
-; RUN: -verify-dom-info -verify-loop-info -stats 2>&1 | FileCheck -check-prefix=STATS %s
-; RUN: FileCheck --input-file=%t %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -S -verify-dom-info -verify-loop-info 2>&1 | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -10,58 +8,6 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare void @foo(i64 %a)
declare void @bar(i64 %a) readnone
-;;--------------------------------------Test case 01------------------------------------
-;; Not safe to interchange, because the called function `foo` is not marked as
-;; readnone, so it could introduce dependences.
-;;
-;; for(int i=0;i<100;i++) {
-;; for(int j=1;j<100;j++) {
-;; foo(i);
-;; A[j][i] = A[j][i]+k;
-;; }
-;; }
-
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: CallInst
-; CHECK-NEXT: Function: interchange_01
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Cannot interchange loops due to call instruction.
-
-define void @interchange_01(i32 %k) {
-entry:
- br label %for1.header
-
-for1.header:
- %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc10 ]
- br label %for2
-
-for2:
- %indvars.iv = phi i64 [ %indvars.iv.next, %for2 ], [ 1, %for1.header ]
- call void @foo(i64 %indvars.iv23)
- %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
- %lv = load i32, ptr %arrayidx5
- %add = add nsw i32 %lv, %k
- store i32 %add, ptr %arrayidx5
- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
- %exitcond = icmp eq i64 %indvars.iv, 99
- br i1 %exitcond, label %for2.loopexit , label %for2
-
-for2.loopexit:
- br label %for1.inc10
-
-for1.inc10:
- %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
- %exitcond26 = icmp eq i64 %indvars.iv23, 99
- br i1 %exitcond26, label %for1.loopexit, label %for1.header
-
-for1.loopexit:
- br label %exit
-
-exit:
- ret void
-}
-
;;--------------------------------------Test case 02------------------------------------
;; Safe to interchange, because the called function `bar` is marked as readnone,
;; so it cannot introduce dependences.
@@ -72,16 +18,46 @@ exit:
;; A[j][i] = A[j][i]+k;
;; }
;; }
-
-; CHECK: --- !Passed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Interchanged
-; CHECK-NEXT: Function: interchange_02
-; CHECK-NEXT: Args:
-; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
-; CHECK-NEXT: ...
-
+;
define void @interchange_02(i32 %k) {
+; CHECK-LABEL: define void @interchange_02(
+; CHECK-SAME: i32 [[K:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[FOR2_PREHEADER:.*]]
+; CHECK: [[FOR1_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[INDVARS_IV23:%.*]] = phi i64 [ [[INDVARS_IV_NEXT24:%.*]], %[[FOR1_INC10:.*]] ], [ 0, %[[FOR1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR2_SPLIT1:.*]]
+; CHECK: [[FOR2_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0:%.*]], %[[FOR2_SPLIT:.*]] ], [ 1, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR1_HEADER_PREHEADER]]
+; CHECK: [[FOR2_SPLIT1]]:
+; CHECK-NEXT: call void @bar(i64 [[INDVARS_IV23]])
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV23]]
+; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LV]], [[K]]
+; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV]], 99
+; CHECK-NEXT: br label %[[FOR2_LOOPEXIT:.*]]
+; CHECK: [[FOR2_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[INDVARS_IV]], 99
+; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR1_LOOPEXIT:.*]], label %[[FOR2]]
+; CHECK: [[FOR2_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR1_INC10]]
+; CHECK: [[FOR1_INC10]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT24]] = add nuw nsw i64 [[INDVARS_IV23]], 1
+; CHECK-NEXT: [[EXITCOND26:%.*]] = icmp eq i64 [[INDVARS_IV23]], 99
+; CHECK-NEXT: br i1 [[EXITCOND26]], label %[[FOR2_SPLIT]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR1_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %for1.header
@@ -114,6 +90,3 @@ for1.loopexit:
exit:
ret void
}
-
-; Check stats, we interchanged 1 out of 2 loops.
-; STATS: 1 loop-interchange - Number of loops interchanged
diff --git a/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll
new file mode 100644
index 00000000000000..51fa6469cdbbbf
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar-remark.ll
@@ -0,0 +1,117 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S -debug 2>&1 | FileCheck %s
+
+@A = common global [100 x [100 x i64]] zeroinitializer
+@N = dso_local local_unnamed_addr global i64 100, align 8
+
+; for(int i=0;i<100;i++)
+; for(int j=0;j<i;j++)
+; A[j][i] = A[j][i]+k;
+;
+; Inner loop induction variable exit condition depends on the
+; outer loop induction variable, i.e., triangular loops.
+;
+; CHECK: Loop structure not understood by pass
+; CHECK: Not interchanging loops. Cannot prove legality.
+;
+define void @interchange_01(i64 %k) {
+entry:
+ br label %for1.header
+
+for1.header:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
+ br label %for2
+
+for2:
+ %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
+ %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
+ %lv = load i64, ptr %arrayidx5
+ %add = add nsw i64 %lv, %k
+ store i64 %add, ptr %arrayidx5
+ %j.next = add nuw nsw i64 %j, 1
+ %exitcond = icmp eq i64 %j, %i
+ br i1 %exitcond, label %for1.inc10, label %for2
+
+for1.inc10:
+ %i.next = add nuw nsw i64 %i, 1
+ %exitcond26 = icmp eq i64 %i, 99
+ br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+ ret void
+}
+
+
+; for(int i=0;i<100;i++)
+; for(int j=0;j+i<100;j++)
+; A[j][i] = A[j][i]+k;
+;
+; Inner loop induction variable exit condition depends on the
+; outer loop induction variable, i.e., triangular loops.
+;
+; CHECK: Loop structure not understood by pass
+; CHECK: Not interchanging loops. Cannot prove legality.
+;
+define void @interchange_02(i64 %k) {
+entry:
+ br label %for1.header
+
+for1.header:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
+ br label %for2
+
+for2:
+ %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
+ %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
+ %lv = load i64, ptr %arrayidx5
+ %add = add nsw i64 %lv, %k
+ store i64 %add, ptr %arrayidx5
+ %0 = add nuw nsw i64 %j, %i
+ %j.next = add nuw nsw i64 %j, 1
+ %exitcond = icmp eq i64 %0, 100
+ br i1 %exitcond, label %for1.inc10, label %for2
+
+for1.inc10:
+ %i.next = add nuw nsw i64 %i, 1
+ %exitcond26 = icmp eq i64 %i, 99
+ br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+ ret void
+}
+
+; for(int i=0;i<100;i++)
+; for(int j=0;i>j;j++)
+; A[j][i] = A[j][i]+k;
+;
+; Inner loop induction variable exit condition depends on the
+; outer loop induction variable, i.e., triangular loops.
+; CHECK: Loop structure not understood by pass
+; CHECK: Not interchanging loops. Cannot prove legality.
+;
+define void @interchange_03(i64 %k) {
+entry:
+ br label %for1.header
+
+for1.header:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
+ br label %for2
+
+for2:
+ %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
+ %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
+ %lv = load i64, ptr %arrayidx5
+ %add = add nsw i64 %lv, %k
+ store i64 %add, ptr %arrayidx5
+ %j.next = add nuw nsw i64 %j, 1
+ %exitcond = icmp ne i64 %i, %j
+ br i1 %exitcond, label %for2, label %for1.inc10
+
+for1.inc10:
+ %i.next = add nuw nsw i64 %i, 1
+ %exitcond26 = icmp eq i64 %i, 99
+ br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+ ret void
+}
diff --git a/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
index 0a1d1e52507994..ff88375e318567 100644
--- a/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
+++ b/llvm/test/Transforms/LoopInterchange/inner-indvar-depend-on-outer-indvar.ll
@@ -1,130 +1,47 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN: -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
@A = common global [100 x [100 x i64]] zeroinitializer
@N = dso_local local_unnamed_addr global i64 100, align 8
-
-;; for(int i=0;i<100;i++)
-;; for(int j=0;j<i;j++)
-;; A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on the
-;; outer loop induction variable, i.e., triangular loops.
-; CHECK: Loop structure not understood by pass
-; CHECK: Not interchanging loops. Cannot prove legality.
-
-define void @interchange_01(i64 %k) {
-entry:
- br label %for1.header
-
-for1.header:
- %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
- br label %for2
-
-for2:
- %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
- %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
- %lv = load i64, ptr %arrayidx5
- %add = add nsw i64 %lv, %k
- store i64 %add, ptr %arrayidx5
- %j.next = add nuw nsw i64 %j, 1
- %exitcond = icmp eq i64 %j, %i
- br i1 %exitcond, label %for1.inc10, label %for2
-
-for1.inc10:
- %i.next = add nuw nsw i64 %i, 1
- %exitcond26 = icmp eq i64 %i, 99
- br i1 %exitcond26, label %for.end12, label %for1.header
-
-for.end12:
- ret void
-}
-
-
-;; for(int i=0;i<100;i++)
-;; for(int j=0;j+i<100;j++)
-;; A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on the
-;; outer loop induction variable, i.e., triangular loops.
-; CHECK: Loop structure not understood by pass
-; CHECK: Not interchanging loops. Cannot prove legality.
-
-define void @interchange_02(i64 %k) {
-entry:
- br label %for1.header
-
-for1.header:
- %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
- br label %for2
-
-for2:
- %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
- %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
- %lv = load i64, ptr %arrayidx5
- %add = add nsw i64 %lv, %k
- store i64 %add, ptr %arrayidx5
- %0 = add nuw nsw i64 %j, %i
- %j.next = add nuw nsw i64 %j, 1
- %exitcond = icmp eq i64 %0, 100
- br i1 %exitcond, label %for1.inc10, label %for2
-
-for1.inc10:
- %i.next = add nuw nsw i64 %i, 1
- %exitcond26 = icmp eq i64 %i, 99
- br i1 %exitcond26, label %for.end12, label %for1.header
-
-for.end12:
- ret void
-}
-
-;; for(int i=0;i<100;i++)
-;; for(int j=0;i>j;j++)
-;; A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on the
-;; outer loop induction variable, i.e., triangular loops.
-; CHECK: Loop structure not understood by pass
-; CHECK: Not interchanging loops. Cannot prove legality.
-
-define void @interchange_03(i64 %k) {
-entry:
- br label %for1.header
-
-for1.header:
- %i = phi i64 [ 0, %entry ], [ %i.next, %for1.inc10 ]
- br label %for2
-
-for2:
- %j = phi i64 [ %j.next, %for2 ], [ 0, %for1.header ]
- %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 %j, i64 %i
- %lv = load i64, ptr %arrayidx5
- %add = add nsw i64 %lv, %k
- store i64 %add, ptr %arrayidx5
- %j.next = add nuw nsw i64 %j, 1
- %exitcond = icmp ne i64 %i, %j
- br i1 %exitcond, label %for2, label %for1.inc10
-
-for1.inc10:
- %i.next = add nuw nsw i64 %i, 1
- %exitcond26 = icmp eq i64 %i, 99
- br i1 %exitcond26, label %for.end12, label %for1.header
-
-for.end12:
- ret void
-}
-
-;; for(int i=0;i<100;i++)
-;; for(int j=0;N>j;j++)
-;; A[j][i] = A[j][i]+k;
-
-;; Inner loop induction variable exit condition depends on
-;; an outer loop invariant, can do interchange.
-; CHECK: Loops interchanged
-
+; Inner loop induction variable exit condition depends on
+; an outer loop invariant, can do interchange.
+;
define void @interchange_04(i64 %k) {
+; CHECK-LABEL: define void @interchange_04(
+; CHECK-SAME: i64 [[K:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @N, align 4
+; CHECK-NEXT: br label %[[FOR2_PREHEADER:.*]]
+; CHECK: [[FOR1_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[FOR1_HEADER:.*]]
+; CHECK: [[FOR1_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[FOR1_INC10:.*]] ], [ 0, %[[FOR1_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR2_SPLIT1:.*]]
+; CHECK: [[FOR2_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR2:.*]]
+; CHECK: [[FOR2]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP1:%.*]], %[[FOR2_SPLIT:.*]] ], [ 0, %[[FOR2_PREHEADER]] ]
+; CHECK-NEXT: br label %[[FOR1_HEADER_PREHEADER]]
+; CHECK: [[FOR2_SPLIT1]]:
+; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i64]], ptr @A, i64 0, i64 [[J]], i64 [[I]]
+; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[LV]], [[K]]
+; CHECK-NEXT: store i64 [[ADD]], ptr [[ARRAYIDX5]], align 4
+; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[TMP0]], [[J]]
+; CHECK-NEXT: br label %[[FOR1_INC10]]
+; CHECK: [[FOR2_SPLIT]]:
+; CHECK-NEXT: [[TMP1]] = add nuw nsw i64 [[J]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP0]], [[J]]
+; CHECK-NEXT: br i1 [[TMP2]], label %[[FOR2]], label %[[FOR_END12:.*]]
+; CHECK: [[FOR1_INC10]]:
+; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; CHECK-NEXT: [[EXITCOND26:%.*]] = icmp eq i64 [[I]], 99
+; CHECK-NEXT: br i1 [[EXITCOND26]], label %[[FOR2_SPLIT]], label %[[FOR1_HEADER]]
+; CHECK: [[FOR_END12]]:
+; CHECK-NEXT: ret void
+;
entry:
%0 = load i64, ptr @N, align 4
br label %for1.header
diff --git a/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll b/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
index 11e59c6db9f327..bad84224d445ab 100644
--- a/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
+++ b/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll
@@ -1,19 +1,61 @@
-; REQUIRES: asserts
-; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \
-; RUN: -S -debug 2>&1 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s
@a = common global i32 0, align 4
@d = common dso_local local_unnamed_addr global [1 x [6 x i32]] zeroinitializer, align 4
-;; After interchanging the innermost and the middle loop, we should not continue
-;; doing interchange for the (new) middle loop and the outermost loop, because of
-;; values defined in the new innermost loop not available in the exiting block of
-;; the entire loop nest.
-; CHECK: Loops are legal to interchange
-; CHECK: Loops interchanged.
-; CHECK: Found unsupported PHI nodes in inner loop latch.
-; CHECK: Not interchanging loops. Cannot prove legality.
+; After interchanging the innermost and the middle loop, we should not continue
+; doing interchange for the (new) middle loop and the outermost loop, because of
+; values defined in the new innermost loop not available in the exiting block of
+; the entire loop nest.
+;
define void @innermost_latch_uses_values_in_middle_header() {
+; CHECK-LABEL: define void @innermost_latch_uses_values_in_middle_header() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4
+; CHECK-NEXT: [[B:%.*]] = add i32 80, 1
+; CHECK-NEXT: br label %[[OUTERMOST_HEADER:.*]]
+; CHECK: [[OUTERMOST_HEADER]]:
+; CHECK-NEXT: [[INDVAR_OUTERMOST:%.*]] = phi i32 [ 10, %[[ENTRY]] ], [ [[INDVAR_OUTERMOST_NEXT:%.*]], %[[OUTERMOST_LATCH:.*]] ]
+; CHECK-NEXT: [[TOBOOL71_I:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[TOBOOL71_I]], label %[[INNERMOST_HEADER_PREHEADER:.*]], label %[[OUTERMOST_LATCH]]
+; CHECK: [[MIDDLE_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT: br label %[[MIDDLE_HEADER:.*]]
+; CHECK: [[MIDDLE_HEADER]]:
+; CHECK-NEXT: [[INDVAR_MIDDLE:%.*]] = phi i64 [ [[INDVAR_MIDDLE_NEXT:%.*]], %[[MIDDLE_LATCH:.*]] ], [ 4, %[[MIDDLE_HEADER_PREHEADER]] ]
+; CHECK-NEXT: [[INDVAR_MIDDLE_WIDE:%.*]] = zext i32 [[B]] to i64
+; CHECK-NEXT: br label %[[INNERMOST_BODY:.*]]
+; CHECK: [[INNERMOST_HEADER_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNERMOST_...
[truncated]
|
I will precommit this change soon, adding you as reviewers as a FYI, as I think this is just a NFC reshuffle of tests that increases test coverage; and no (fundamental) changes have been made to the tests itself, just the CHECKing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remarks shouldn't require asserts and checking the remark if interchange didn't happen seems like a more straight-forward way then checking the IR in some cases
; REQUIRES: asserts | ||
; RUN: opt < %s -passes='loop(loop-interchange),simplifycfg' -cache-line-size=64 -simplifycfg-require-and-preserve-domtree=1 -pass-remarks-output=%t \ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
; RUN: opt < %s -passes='loop(loop-interchange),simplifycfg' -simplifycfg-require-and-preserve-domtree=1 \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this drop the check lines for the remarks? Those don't require asserts, only -stats
does I think, which is still here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why drop -cache-line-size=64
?
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \ | ||
; RUN: -S -debug 2>&1 | FileCheck %s | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -S 2>&1 | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why drop cache-line-size?
@@ -0,0 +1,63 @@ | |||
; REQUIRES: asserts | |||
; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remarks don't require asserts I think
; STATS: [[FOR2]]: | ||
; STATS-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR1_HEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR2]] ] | ||
; STATS-NEXT: store i64 [[INDVARS_IV]], ptr [[PTR]], align 4 | ||
; STATS-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be CHECK-
?
Thanks for the comments, I will follow up soon to:
I dropped the |
Checking the remark message if interchange did or didn't happen is more straight forward than the full IR for these cases. This comment was also made when I moved some tests away from relying on debug builds in change llvm#116780, and this is a prep step for llvm#119345 that is going to change these steps.
Checking the remark message if interchange did or didn't happen is more straight forward than checking the full IR for these cases. This comment was also made when I moved some tests away from relying on debug builds in change llvm#116780, and this is a prep step for llvm#119345 that is going to change these steps.
Checking the remark message if interchange did or didn't happen is more straight forward than the full IR for these cases. This comment was also made when I moved some tests away from relying on debug builds in change #116780, and this is a prep step for #119345 that is going to change these test cases.
A lot of interchange tests unnecessary relied on a build with ASSERTS enabled. Instead, simply check the IR output for both negative and positive tests so that we don't rely on debug messages. This increases test coverage as these tests will now also run with non-assert builds. For a couple of files keeping some of the debug tests was useful, so separated out them out and moved them to a similarly named *-remarks.ll file.