1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00
llvm-mirror/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll
Florian Hahn 5f133744e9 [LoopInterchange] Only skip PHIs with incoming values from the inner loop.
Currently we have limited support for outer loops with multiple basic
blocks after the inner loop exit. But the current checks for creating
PHIs for loop exit values only assumes the header and latches of the
outer loop. It is better to just skip incoming values defined in the
original inner loops. Those are handled earlier.

Reviewers: efriedma, mcrosier

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D70059
2019-11-12 10:30:51 +00:00

151 lines
7.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -loop-interchange -verify-loop-lcssa -S %s | FileCheck %s
; Tests for PR43797.
@wdtdr = external dso_local global [5 x [5 x double]], align 16
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
outer.header: ; preds = %for.inc27, %entry
%outer.idx = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ]
%arrayidx8 = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 %outer.idx
br label %inner.header
inner.header: ; preds = %for.inc, %for.body
%inner.idx = phi i64 [ 0, %outer.header ], [ %inner.idx.inc, %inner.latch]
%0 = load double, double* %arrayidx8, align 8
store double undef, double* %arrayidx8, align 8
br label %inner.latch
inner.latch: ; preds = %for.body6
%inner.idx.inc = add nsw i64 %inner.idx, 1
br i1 undef, label %inner.header, label %inner.exit
inner.exit: ; preds = %for.inc
%outer.v = add nsw i64 %outer.idx, 1
br label %outer.latch
outer.latch: ; preds = %for.end
%outer.idx.inc = add nsw i64 %outer.idx, 1
br i1 undef, label %outer.header, label %outer.exit
outer.exit: ; preds = %for.inc27
%exit1.lcssa = phi i64 [ %outer.v, %outer.latch ]
%exit2.lcssa = phi i64 [ %outer.idx.inc, %outer.latch ]
ret void
}
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
outer.header: ; preds = %for.inc27, %entry
%outer.idx = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ]
%arrayidx8 = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 %outer.idx
br label %inner.header
inner.header: ; preds = %for.inc, %for.body
%inner.idx = phi i64 [ 0, %outer.header ], [ %inner.idx.inc, %inner.latch]
%0 = load double, double* %arrayidx8, align 8
store double undef, double* %arrayidx8, align 8
br label %inner.latch
inner.latch: ; preds = %for.body6
%inner.idx.inc = add nsw i64 %inner.idx , 1
br i1 undef, label %inner.header, label %inner.exit
inner.exit: ; preds = %for.inc
%outer.v = add nsw i64 %outer.idx, 1
br label %outer.latch
outer.latch: ; preds = %for.end
%outer.idx.inc = add nsw i64 %outer.idx, 1
br i1 undef, label %outer.header, label %outer.exit
outer.exit: ; preds = %for.inc27
%exit1.lcssa = phi i64 [ 0, %entry ], [ %outer.v, %outer.latch ]
%exit2.lcssa = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ]
ret void
}