1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -loop-interchange -verify-loop-lcssa -S %s | FileCheck %s
3
4; Tests for PR43797.
5
6target triple = "powerpc64le-unknown-linux-gnu"
7@wdtdr = external dso_local global [5 x [5 x double]], align 16
8
9define void @test1() {
10; CHECK-LABEL: @test1(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    br label [[INNER_HEADER_PREHEADER:%.*]]
13; CHECK:       outer.header.preheader:
14; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
15; CHECK:       outer.header:
16; CHECK-NEXT:    [[OUTER_IDX:%.*]] = phi i64 [ [[OUTER_IDX_INC:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ]
17; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 [[OUTER_IDX]]
18; CHECK-NEXT:    br label [[INNER_HEADER_SPLIT:%.*]]
19; CHECK:       inner.header.preheader:
20; CHECK-NEXT:    br label [[INNER_HEADER:%.*]]
21; CHECK:       inner.header:
22; CHECK-NEXT:    [[INNER_IDX:%.*]] = phi i64 [ [[TMP3:%.*]], [[INNER_LATCH_SPLIT:%.*]] ], [ 0, [[INNER_HEADER_PREHEADER]] ]
23; CHECK-NEXT:    br label [[OUTER_HEADER_PREHEADER]]
24; CHECK:       inner.header.split:
25; CHECK-NEXT:    [[TMP0:%.*]] = load double, double* [[ARRAYIDX8]], align 8
26; CHECK-NEXT:    store double undef, double* [[ARRAYIDX8]], align 8
27; CHECK-NEXT:    br label [[INNER_LATCH:%.*]]
28; CHECK:       inner.latch:
29; CHECK-NEXT:    [[INNER_IDX_INC:%.*]] = add nsw i64 [[INNER_IDX]], 1
30; CHECK-NEXT:    br label [[INNER_EXIT:%.*]]
31; CHECK:       inner.latch.split:
32; CHECK-NEXT:    [[TMP1:%.*]] = phi i64 [ [[OUTER_V:%.*]], [[OUTER_LATCH]] ]
33; CHECK-NEXT:    [[TMP2:%.*]] = phi i64 [ [[OUTER_IDX_INC]], [[OUTER_LATCH]] ]
34; CHECK-NEXT:    [[TMP3]] = add nsw i64 [[INNER_IDX]], 1
35; CHECK-NEXT:    br i1 false, label [[INNER_HEADER]], label [[OUTER_EXIT:%.*]]
36; CHECK:       inner.exit:
37; CHECK-NEXT:    [[OUTER_V]] = add nsw i64 [[OUTER_IDX]], 1
38; CHECK-NEXT:    br label [[OUTER_LATCH]]
39; CHECK:       outer.latch:
40; CHECK-NEXT:    [[OUTER_IDX_INC]] = add nsw i64 [[OUTER_IDX]], 1
41; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER]], label [[INNER_LATCH_SPLIT]]
42; CHECK:       outer.exit:
43; CHECK-NEXT:    [[EXIT1_LCSSA:%.*]] = phi i64 [ [[TMP1]], [[INNER_LATCH_SPLIT]] ]
44; CHECK-NEXT:    [[EXIT2_LCSSA:%.*]] = phi i64 [ [[TMP2]], [[INNER_LATCH_SPLIT]] ]
45; CHECK-NEXT:    ret void
46;
47entry:
48  br label %outer.header
49
50outer.header:                                         ; preds = %for.inc27, %entry
51  %outer.idx = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ]
52  %arrayidx8 = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 %outer.idx
53  br label %inner.header
54
55inner.header:                                        ; preds = %for.inc, %for.body
56  %inner.idx = phi i64 [ 0, %outer.header ], [ %inner.idx.inc, %inner.latch]
57  %0 = load double, double* %arrayidx8, align 8
58  store double undef, double* %arrayidx8, align 8
59  br label %inner.latch
60
61inner.latch:                                          ; preds = %for.body6
62  %inner.idx.inc = add nsw i64 %inner.idx, 1
63  br i1 undef, label %inner.header, label %inner.exit
64
65inner.exit:                                          ; preds = %for.inc
66  %outer.v = add nsw i64 %outer.idx, 1
67  br label %outer.latch
68
69outer.latch:                                        ; preds = %for.end
70  %outer.idx.inc = add nsw i64 %outer.idx, 1
71  br i1 undef, label %outer.header, label %outer.exit
72
73outer.exit:                                        ; preds = %for.inc27
74  %exit1.lcssa = phi i64 [ %outer.v, %outer.latch ]
75  %exit2.lcssa = phi i64 [ %outer.idx.inc, %outer.latch ]
76  ret void
77}
78
79define void @test2(i1 %cond) {
80; CHECK-LABEL: @test2(
81; CHECK-NEXT:  entry:
82; CHECK-NEXT:    br i1 [[COND:%.*]], label [[INNER_HEADER_PREHEADER:%.*]], label [[OUTER_EXIT:%.*]]
83; CHECK:       outer.header.preheader:
84; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
85; CHECK:       outer.header:
86; CHECK-NEXT:    [[OUTER_IDX:%.*]] = phi i64 [ [[OUTER_IDX_INC:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ]
87; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 [[OUTER_IDX]]
88; CHECK-NEXT:    br label [[INNER_HEADER_SPLIT:%.*]]
89; CHECK:       inner.header.preheader:
90; CHECK-NEXT:    br label [[INNER_HEADER:%.*]]
91; CHECK:       inner.header:
92; CHECK-NEXT:    [[INNER_IDX:%.*]] = phi i64 [ [[TMP3:%.*]], [[INNER_LATCH_SPLIT:%.*]] ], [ 0, [[INNER_HEADER_PREHEADER]] ]
93; CHECK-NEXT:    br label [[OUTER_HEADER_PREHEADER]]
94; CHECK:       inner.header.split:
95; CHECK-NEXT:    [[TMP0:%.*]] = load double, double* [[ARRAYIDX8]], align 8
96; CHECK-NEXT:    store double undef, double* [[ARRAYIDX8]], align 8
97; CHECK-NEXT:    br label [[INNER_LATCH:%.*]]
98; CHECK:       inner.latch:
99; CHECK-NEXT:    [[INNER_IDX_INC:%.*]] = add nsw i64 [[INNER_IDX]], 1
100; CHECK-NEXT:    br label [[INNER_EXIT:%.*]]
101; CHECK:       inner.latch.split:
102; CHECK-NEXT:    [[TMP1:%.*]] = phi i64 [ [[OUTER_IDX_INC]], [[OUTER_LATCH]] ]
103; CHECK-NEXT:    [[TMP2:%.*]] = phi i64 [ [[OUTER_V:%.*]], [[OUTER_LATCH]] ]
104; CHECK-NEXT:    [[TMP3]] = add nsw i64 [[INNER_IDX]], 1
105; CHECK-NEXT:    br i1 false, label [[INNER_HEADER]], label [[OUTER_EXIT_LOOPEXIT:%.*]]
106; CHECK:       inner.exit:
107; CHECK-NEXT:    [[OUTER_V]] = add nsw i64 [[OUTER_IDX]], 1
108; CHECK-NEXT:    br label [[OUTER_LATCH]]
109; CHECK:       outer.latch:
110; CHECK-NEXT:    [[OUTER_IDX_INC]] = add nsw i64 [[OUTER_IDX]], 1
111; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER]], label [[INNER_LATCH_SPLIT]]
112; CHECK:       outer.exit.loopexit:
113; CHECK-NEXT:    [[OUTER_IDX_INC_LCSSA:%.*]] = phi i64 [ [[TMP1]], [[INNER_LATCH_SPLIT]] ]
114; CHECK-NEXT:    [[OUTER_V_LCSSA:%.*]] = phi i64 [ [[TMP2]], [[INNER_LATCH_SPLIT]] ]
115; CHECK-NEXT:    br label [[OUTER_EXIT]]
116; CHECK:       outer.exit:
117; CHECK-NEXT:    [[EXIT1_LCSSA:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_V_LCSSA]], [[OUTER_EXIT_LOOPEXIT]] ]
118; CHECK-NEXT:    [[EXIT2_LCSSA:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[OUTER_IDX_INC_LCSSA]], [[OUTER_EXIT_LOOPEXIT]] ]
119; CHECK-NEXT:    ret void
120;
121entry:
122  br i1 %cond, label %outer.header, label %outer.exit
123
124outer.header:                                         ; preds = %for.inc27, %entry
125  %outer.idx = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ]
126  %arrayidx8 = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 %outer.idx
127  br label %inner.header
128
129inner.header:                                        ; preds = %for.inc, %for.body
130  %inner.idx = phi i64 [ 0, %outer.header ], [ %inner.idx.inc, %inner.latch]
131  %0 = load double, double* %arrayidx8, align 8
132  store double undef, double* %arrayidx8, align 8
133  br label %inner.latch
134
135inner.latch:                                          ; preds = %for.body6
136  %inner.idx.inc = add nsw i64 %inner.idx , 1
137  br i1 undef, label %inner.header, label %inner.exit
138
139inner.exit:                                          ; preds = %for.inc
140  %outer.v = add nsw i64 %outer.idx, 1
141  br label %outer.latch
142
143outer.latch:                                        ; preds = %for.end
144  %outer.idx.inc = add nsw i64 %outer.idx, 1
145  br i1 undef, label %outer.header, label %outer.exit
146
147outer.exit:                                        ; preds = %for.inc27
148  %exit1.lcssa = phi i64 [ 0, %entry ], [ %outer.v, %outer.latch ]
149  %exit2.lcssa = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ]
150  ret void
151}
152