Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -1117,10 +1117,10 @@ // If the inner loop is loop independent or doesn't carry any dependency it is // profitable to move this to outer position. for (auto &Row : DepMatrix) { - if (Row[InnerLoopId] != 'S' && Row[InnerLoopId] != 'I') + if (Row[InnerLoopId] != 'I' && Row[InnerLoopId] != '=') return false; // TODO: We need to improve this heuristic. - if (Row[OuterLoopId] != '=') + if (Row[OuterLoopId] == '=') return false; } // If outer loop has dependence and inner loop is loop independent then it is Index: llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll =================================================================== --- llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll +++ llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll @@ -1,48 +1,16 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -loop-interchange -cache-line-size=64 -verify-loop-lcssa -S %s | FileCheck %s +; RUN: opt < %s -loop-interchange -cache-line-size=64 -verify-loop-lcssa -pass-remarks-output=%t \ +; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange -stats -S 2>&1 \ +; RUN: | FileCheck -check-prefix=STATS %s +; RUN: FileCheck -input-file=%t %s ; Tests for PR43797. @wdtdr = external dso_local global [5 x [5 x double]], align 16 +; CHECK: Name: InterchangeNotProfitable +; CHECK-NEXT: Function: test1 define void @test1() { -; CHECK-LABEL: @test1( -; CHECK-NEXT: entry: -; CHECK-NEXT: br label [[INNER_HEADER_PREHEADER:%.*]] -; CHECK: outer.header.preheader: -; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] -; CHECK: outer.header: -; CHECK-NEXT: [[OUTER_IDX:%.*]] = phi i64 [ [[OUTER_IDX_INC:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ] -; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 [[OUTER_IDX]] -; CHECK-NEXT: br label [[INNER_HEADER_SPLIT:%.*]] -; CHECK: inner.header.preheader: -; CHECK-NEXT: br label [[INNER_HEADER:%.*]] -; CHECK: inner.header: -; CHECK-NEXT: [[INNER_IDX:%.*]] = phi i64 [ [[TMP3:%.*]], [[INNER_LATCH_SPLIT:%.*]] ], [ 0, [[INNER_HEADER_PREHEADER]] ] -; CHECK-NEXT: br label [[OUTER_HEADER_PREHEADER]] -; CHECK: inner.header.split: -; CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[ARRAYIDX8]], align 8 -; CHECK-NEXT: store double undef, double* [[ARRAYIDX8]], align 8 -; CHECK-NEXT: br label [[INNER_LATCH:%.*]] -; CHECK: inner.latch: -; CHECK-NEXT: [[INNER_IDX_INC:%.*]] = add nsw i64 [[INNER_IDX]], 1 -; CHECK-NEXT: br label [[INNER_EXIT:%.*]] -; CHECK: inner.latch.split: -; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ [[OUTER_V:%.*]], [[OUTER_LATCH]] ] -; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ [[OUTER_IDX_INC]], [[OUTER_LATCH]] ] -; CHECK-NEXT: [[TMP3]] = add nsw i64 [[INNER_IDX]], 1 -; CHECK-NEXT: br i1 false, label [[INNER_HEADER]], label [[OUTER_EXIT:%.*]] -; CHECK: inner.exit: -; CHECK-NEXT: [[OUTER_V]] = add nsw i64 [[OUTER_IDX]], 1 -; CHECK-NEXT: br label [[OUTER_LATCH]] -; CHECK: outer.latch: -; CHECK-NEXT: [[OUTER_IDX_INC]] = add nsw i64 [[OUTER_IDX]], 1 -; CHECK-NEXT: br i1 false, label [[OUTER_HEADER]], label [[INNER_LATCH_SPLIT]] -; CHECK: outer.exit: -; CHECK-NEXT: [[EXIT1_LCSSA:%.*]] = phi i64 [ [[TMP1]], [[INNER_LATCH_SPLIT]] ] -; CHECK-NEXT: [[EXIT2_LCSSA:%.*]] = phi i64 [ [[TMP2]], [[INNER_LATCH_SPLIT]] ] -; CHECK-NEXT: ret void -; entry: br label %outer.header @@ -75,48 +43,9 @@ ret void } +; CHECK: Name: InterchangeNotProfitable +; CHECK-NEXT: Function: test2 define void @test2(i1 %cond) { -; CHECK-LABEL: @test2( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[COND:%.*]], label [[INNER_HEADER_PREHEADER:%.*]], label [[OUTER_EXIT:%.*]] -; CHECK: outer.header.preheader: -; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] -; CHECK: outer.header: -; CHECK-NEXT: [[OUTER_IDX:%.*]] = phi i64 [ [[OUTER_IDX_INC:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ] -; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 [[OUTER_IDX]] -; CHECK-NEXT: br label [[INNER_HEADER_SPLIT:%.*]] -; CHECK: inner.header.preheader: -; CHECK-NEXT: br label [[INNER_HEADER:%.*]] -; CHECK: inner.header: -; CHECK-NEXT: [[INNER_IDX:%.*]] = phi i64 [ [[TMP3:%.*]], [[INNER_LATCH_SPLIT:%.*]] ], [ 0, [[INNER_HEADER_PREHEADER]] ] -; CHECK-NEXT: br label [[OUTER_HEADER_PREHEADER]] -; CHECK: inner.header.split: -; CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[ARRAYIDX8]], align 8 -; CHECK-NEXT: store double undef, double* [[ARRAYIDX8]], align 8 -; CHECK-NEXT: br label [[INNER_LATCH:%.*]] -; CHECK: inner.latch: -; CHECK-NEXT: [[INNER_IDX_INC:%.*]] = add nsw i64 [[INNER_IDX]], 1 -; CHECK-NEXT: br label [[INNER_EXIT:%.*]] -; CHECK: inner.latch.split: -; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ [[OUTER_IDX_INC]], [[OUTER_LATCH]] ] -; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ [[OUTER_V:%.*]], [[OUTER_LATCH]] ] -; CHECK-NEXT: [[TMP3]] = add nsw i64 [[INNER_IDX]], 1 -; CHECK-NEXT: br i1 false, label [[INNER_HEADER]], label [[OUTER_EXIT_LOOPEXIT:%.*]] -; CHECK: inner.exit: -; CHECK-NEXT: [[OUTER_V]] = add nsw i64 [[OUTER_IDX]], 1 -; CHECK-NEXT: br label [[OUTER_LATCH]] -; CHECK: outer.latch: -; CHECK-NEXT: [[OUTER_IDX_INC]] = add nsw i64 [[OUTER_IDX]], 1 -; CHECK-NEXT: br i1 false, label [[OUTER_HEADER]], label [[INNER_LATCH_SPLIT]] -; CHECK: outer.exit.loopexit: -; CHECK-NEXT: [[OUTER_IDX_INC_LCSSA:%.*]] = phi i64 [ [[TMP1]], [[INNER_LATCH_SPLIT]] ] -; CHECK-NEXT: [[OUTER_V_LCSSA:%.*]] = phi i64 [ [[TMP2]], [[INNER_LATCH_SPLIT]] ] -; CHECK-NEXT: br label [[OUTER_EXIT]] -; CHECK: outer.exit: -; CHECK-NEXT: [[EXIT1_LCSSA:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_V_LCSSA]], [[OUTER_EXIT_LOOPEXIT]] ] -; CHECK-NEXT: [[EXIT2_LCSSA:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[OUTER_IDX_INC_LCSSA]], [[OUTER_EXIT_LOOPEXIT]] ] -; CHECK-NEXT: ret void -; entry: br i1 %cond, label %outer.header, label %outer.exit @@ -148,3 +77,5 @@ %exit2.lcssa = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ] ret void } +; Check stats, we interchanged 0 out of 2 loops. +; STATS-NOT: loop-interchange