diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index a527c4b98f1ac..a90a9ba88fbe7 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -106,8 +106,7 @@ static cl::list Profitabilities( cl::Hidden, cl::desc("List of profitability heuristics to be used. They are applied in " "the given order"), - cl::list_init({RuleTy::PerLoopCacheAnalysis, - RuleTy::PerInstrOrderCost, + cl::list_init({RuleTy::PerInstrOrderCost, RuleTy::ForVectorization}), cl::values(clEnumValN(RuleTy::PerLoopCacheAnalysis, "cache", "Prioritize loop cache cost"), diff --git a/llvm/test/Transforms/LoopInterchange/delay-cachecost-calculation.ll b/llvm/test/Transforms/LoopInterchange/delay-cachecost-calculation.ll index 14403469440c3..5e90abc75e43b 100644 --- a/llvm/test/Transforms/LoopInterchange/delay-cachecost-calculation.ll +++ b/llvm/test/Transforms/LoopInterchange/delay-cachecost-calculation.ll @@ -1,6 +1,6 @@ ; REQUIRES: asserts -; RUN: opt -passes=loop-interchange -debug -disable-output %s 2>&1 | FileCheck %s +; RUN: opt -passes=loop-interchange -debug -disable-output -loop-interchange-profitabilities=cache %s 2>&1 | FileCheck %s @A = global [16 x [16 x i32]] zeroinitializer diff --git a/llvm/test/Transforms/LoopInterchange/dependency-all-eq.ll b/llvm/test/Transforms/LoopInterchange/dependency-all-eq.ll new file mode 100644 index 0000000000000..7c5dd5489ef1b --- /dev/null +++ b/llvm/test/Transforms/LoopInterchange/dependency-all-eq.ll @@ -0,0 +1,117 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt < %s -S -passes=loop-interchange -loop-interchange-profitabilities=instorder \ +; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PROFIT-INSTORDER +; RUN: opt < %s -S -passes=loop-interchange -loop-interchange-profitabilities=ignore \ +; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PROFIT-IGNORE + +; for (i = 0; i < 100; i++) +; for (j = 0; j < 100; j++) +; A[j] = 0; +; +; The direction vector for this loop nest is [* =]. Interchanging the loops is +; legal. +; + +define void @all_eq(ptr %A) { +; CHECK-LABEL: define void @all_eq( +; CHECK-SAME: ptr [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP_I_HEADER:.*]] +; CHECK: [[LOOP_I_HEADER]]: +; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ] +; CHECK-NEXT: br label %[[LOOP_J:.*]] +; CHECK: [[LOOP_J]]: +; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[LOOP_I_HEADER]] ], [ [[J_INC:%.*]], %[[LOOP_J]] ] +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[J]] +; CHECK-NEXT: store i8 0, ptr [[GEP]], align 1 +; CHECK-NEXT: [[J_INC]] = add i64 [[J]], 1 +; CHECK-NEXT: [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 100 +; CHECK-NEXT: br i1 [[EC_J]], label %[[LOOP_I_LATCH]], label %[[LOOP_J]] +; CHECK: [[LOOP_I_LATCH]]: +; CHECK-NEXT: [[I_INC]] = add i64 [[I]], 1 +; CHECK-NEXT: [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 100 +; CHECK-NEXT: br i1 [[EC_I]], label %[[EXIT:.*]], label %[[LOOP_I_HEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop.i.header + +loop.i.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ] + br label %loop.j + +loop.j: + %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ] + %gep = getelementptr i8, ptr %A, i64 %j + store i8 0, ptr %gep + %j.inc = add i64 %j, 1 + %ec.j = icmp eq i64 %j.inc, 100 + br i1 %ec.j, label %loop.i.latch, label %loop.j + +loop.i.latch: + %i.inc = add i64 %i, 1 + %ec.i = icmp eq i64 %i.inc, 100 + br i1 %ec.i, label %exit, label %loop.i.header + +exit: + ret void +} + + +; for (i = 0; i < 100; i++) +; for (j = 0; j < 100; j++) +; A[i] = 0; +; +; The direction vector for this loop nest is [= *]. Interchanging the loops is +; legal. +; + +define void @eq_all(ptr %A) { +; CHECK-LABEL: define void @eq_all( +; CHECK-SAME: ptr [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP_I_HEADER:.*]] +; CHECK: [[LOOP_I_HEADER]]: +; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ] +; CHECK-NEXT: br label %[[LOOP_J:.*]] +; CHECK: [[LOOP_J]]: +; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[LOOP_I_HEADER]] ], [ [[J_INC:%.*]], %[[LOOP_J]] ] +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[I]] +; CHECK-NEXT: store i8 0, ptr [[GEP]], align 1 +; CHECK-NEXT: [[J_INC]] = add i64 [[J]], 1 +; CHECK-NEXT: [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 100 +; CHECK-NEXT: br i1 [[EC_J]], label %[[LOOP_I_LATCH]], label %[[LOOP_J]] +; CHECK: [[LOOP_I_LATCH]]: +; CHECK-NEXT: [[I_INC]] = add i64 [[I]], 1 +; CHECK-NEXT: [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 100 +; CHECK-NEXT: br i1 [[EC_I]], label %[[EXIT:.*]], label %[[LOOP_I_HEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop.i.header + +loop.i.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ] + br label %loop.j + +loop.j: + %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ] + %gep = getelementptr i8, ptr %A, i64 %i + store i8 0, ptr %gep + %j.inc = add i64 %j, 1 + %ec.j = icmp eq i64 %j.inc, 100 + br i1 %ec.j, label %loop.i.latch, label %loop.j + +loop.i.latch: + %i.inc = add i64 %i, 1 + %ec.i = icmp eq i64 %i.inc, 100 + br i1 %ec.i, label %exit, label %loop.i.header + +exit: + ret void +} +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK-PROFIT-IGNORE: {{.*}} +; CHECK-PROFIT-INSTORDER: {{.*}} diff --git a/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll b/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll index 92ce3288b4529..925a7b7bcda0d 100644 --- a/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll +++ b/llvm/test/Transforms/LoopInterchange/lcssa-phi-outer-latch.ll @@ -1,5 +1,5 @@ ; 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-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s +; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s ; This test is checking that blocks outer.body and outer.latch, where outer.body is the exit ; block of the inner loop and outer.latch the latch of the outer loop, correctly diff --git a/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll b/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll index 14836ba73433d..22b6efee6e11e 100644 --- a/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll +++ b/llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll @@ -7,7 +7,8 @@ ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info \ ; RUN: -pass-remarks-output=%t -pass-remarks-missed='loop-interchange' \ -; RUN: -pass-remarks='loop-interchange' -S -da-disable-delinearization-checks +; RUN: -pass-remarks='loop-interchange' -S -da-disable-delinearization-checks \ +; RUN: -loop-interchange-profitabilities=cache ; RUN: cat %t | FileCheck --check-prefix=DELIN %s @A = common global [100 x [100 x i32]] zeroinitializer @@ -87,7 +88,7 @@ for.end19: ; DELIN-NEXT: Name: InterchangeNotProfitable ; DELIN-NEXT: Function: test01 ; DELIN-NEXT: Args: -; DELIN-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization. +; DELIN-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorizatio ; DELIN-NEXT: ... ;;--------------------------------------Test case 02------------------------------------ diff --git a/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll b/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll index 11d79c0d86f2e..9fc70b16acbdc 100644 --- a/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll +++ b/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -loop-interchange-threshold=-100 -verify-loop-lcssa -S | FileCheck %s +; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -loop-interchange-threshold=-100 -verify-loop-lcssa -S | FileCheck %s ; Test case for PR41725. The induction variables in the latches escape the ; loops and we must move some PHIs around. diff --git a/llvm/test/Transforms/LoopInterchange/pr57148.ll b/llvm/test/Transforms/LoopInterchange/pr57148.ll index fcafde2bb2688..2a1a21c57bfe7 100644 --- a/llvm/test/Transforms/LoopInterchange/pr57148.ll +++ b/llvm/test/Transforms/LoopInterchange/pr57148.ll @@ -1,5 +1,5 @@ ; 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 -loop-interchange-threshold=-100 -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s +; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=cache -loop-interchange-threshold=-100 -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s ; Make sure the loops are in LCSSA form after loop interchange, ; and loop interchange does not hit assertion errors and crash. diff --git a/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll b/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll index 90813593b8500..be7d8c9837c75 100644 --- a/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll +++ b/llvm/test/Transforms/LoopInterchange/profitability-vectorization.ll @@ -1,5 +1,5 @@ ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \ -; RUN: -pass-remarks-output=%t -disable-output +; RUN: -pass-remarks-output=%t -disable-output -loop-interchange-profitabilities=instorder ; RUN: FileCheck -input-file %t --check-prefix=PROFIT-CACHE %s ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 \ @@ -27,7 +27,7 @@ ; PROFIT-CACHE-NEXT: Name: InterchangeNotProfitable ; PROFIT-CACHE-NEXT: Function: f ; PROFIT-CACHE-NEXT: Args: -; PROFIT-CACHE-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization. +; PROFIT-CACHE-NEXT: - String: Insufficient information to calculate the cost of loop for interchange. ; PROFIT-CACHE-NEXT: ... ; PROFIT-VEC: --- !Passed