mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
5f133744e9
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
151 lines
7.2 KiB
LLVM
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
|
|
}
|