Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopInterchange / perserve-lcssa.ll
blob11d79c0d86f2ef32c8188883f51af6fbac5cfb15
1 ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -loop-interchange-threshold=-100 -verify-loop-lcssa -S | FileCheck %s
3 ; Test case for PR41725. The induction variables in the latches escape the
4 ; loops and we must move some PHIs around.
6 @a = common dso_local global i64 0, align 4
7 @b = common dso_local global i64 0, align 4
8 @c = common dso_local global [10 x [10 x i32 ]] zeroinitializer, align 16
11 define void @test_lcssa_indvars1()  {
12 ; CHECK-LABEL: @test_lcssa_indvars1()
13 ; CHECK-LABEL: inner.body:
14 ; CHECK-NEXT:    %iv.inner = phi i64 [ %[[IVNEXT:[0-9]+]], %inner.body.split ], [ 5, %inner.body.preheader ]
16 ; CHECK-LABEL: inner.body.split:
17 ; CHECK-NEXT:    %0 = phi i64 [ %iv.outer.next, %outer.latch ]
18 ; CHECK-NEXT:    %[[IVNEXT]] = add nsw i64 %iv.inner, -1
19 ; CHECK-NEXT:    %[[COND:[0-9]+]] = icmp eq i64 %iv.inner, 0
20 ; CHECK-NEXT:    br i1 %[[COND]], label %exit, label %inner.body
22 ; CHECK-LABEL: exit:
23 ; CHECK-NEXT:    %v4.lcssa = phi i64 [ %0, %inner.body.split ]
24 ; CHECK-NEXT:    %v8.lcssa.lcssa = phi i64 [ %[[IVNEXT]], %inner.body.split ]
25 ; CHECK-NEXT:    store i64 %v8.lcssa.lcssa, ptr @b, align 4
26 ; CHECK-NEXT:    store i64 %v4.lcssa, ptr @a, align 4
28 entry:
29   br label %outer.header
31 outer.header:                                     ; preds = %outer.latch, %entry
32   %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ]
33   br label %inner.body
35 inner.body:                                       ; preds = %inner.body, %outer.header
36   %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ]
37   %v7 = getelementptr inbounds [10 x [10 x i32]], ptr @c, i64 0, i64 %iv.inner, i64 %iv.outer
38   store i32 0, ptr %v7, align 4
39   %iv.inner.next = add nsw i64 %iv.inner, -1
40   %v9 = icmp eq i64 %iv.inner, 0
41   br i1 %v9, label %outer.latch, label %inner.body
43 outer.latch:                                      ; preds = %inner.body
44   %v8.lcssa = phi i64 [ %iv.inner.next, %inner.body ]
45   %iv.outer.next = add nuw nsw i64 %iv.outer, 1
46   %v5 = icmp ult i64 %iv.outer, 2
47   br i1 %v5, label %outer.header, label %exit
49 exit:                                             ; preds = %outer.latch
50   %v4.lcssa = phi i64 [ %iv.outer.next, %outer.latch ]
51   %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ]
52   store i64 %v8.lcssa.lcssa, ptr @b, align 4
53   store i64 %v4.lcssa, ptr @a, align 4
54   ret void
58 define void @test_lcssa_indvars2()  {
59 ; CHECK-LABEL: @test_lcssa_indvars2()
60 ; CHECK-LABEL: inner.body:
61 ; CHECK-NEXT:    %iv.inner = phi i64 [ %[[IVNEXT:[0-9]+]], %inner.body.split ], [ 5, %inner.body.preheader ]
63 ; CHECK-LABEL: inner.body.split:
64 ; CHECK-NEXT:    %0 = phi i64 [ %iv.outer, %outer.latch ]
65 ; CHECK-NEXT:    %[[IVNEXT]] = add nsw i64 %iv.inner, -1
66 ; CHECK-NEXT:    %[[COND:[0-9]+]] = icmp eq i64 %[[IVNEXT]], 0
67 ; CHECK-NEXT:    br i1 %[[COND]], label %exit, label %inner.body
69 ; CHECK-LABEL: exit:
70 ; CHECK-NEXT:    %v4.lcssa = phi i64 [ %0, %inner.body.split ]
71 ; CHECK-NEXT:    %v8.lcssa.lcssa = phi i64 [ %iv.inner, %inner.body.split ]
72 ; CHECK-NEXT:    store i64 %v8.lcssa.lcssa, ptr @b, align 4
73 ; CHECK-NEXT:    store i64 %v4.lcssa, ptr @a, align 4
75 entry:
76   br label %outer.header
78 outer.header:                                     ; preds = %outer.latch, %entry
79   %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ]
80   br label %inner.body
82 inner.body:                                       ; preds = %inner.body, %outer.header
83   %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ]
84   %v7 = getelementptr inbounds [10 x [10 x i32]], ptr @c, i64 0, i64 %iv.inner, i64 %iv.outer
85   store i32 0, ptr %v7, align 4
86   %iv.inner.next = add nsw i64 %iv.inner, -1
87   %v9 = icmp eq i64 %iv.inner.next, 0
88   br i1 %v9, label %outer.latch, label %inner.body
90 outer.latch:                                      ; preds = %inner.body
91   %v8.lcssa = phi i64 [ %iv.inner, %inner.body ]
92   %iv.outer.next = add nuw nsw i64 %iv.outer, 1
93   %v5 = icmp ult i64 %iv.outer.next, 2
94   br i1 %v5, label %outer.header, label %exit
96 exit:                                             ; preds = %outer.latch
97   %v4.lcssa = phi i64 [ %iv.outer, %outer.latch ]
98   %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ]
99   store i64 %v8.lcssa.lcssa, ptr @b, align 4
100   store i64 %v4.lcssa, ptr @a, align 4
101   ret void
104 define void @test_lcssa_indvars3()  {
105 ; CHECK-LABEL: @test_lcssa_indvars3()
106 ; CHECK-LABEL: inner.body:
107 ; CHECK-NEXT:    %iv.inner = phi i64 [ %[[IVNEXT:[0-9]+]], %inner.body.split ], [ 5, %inner.body.preheader ]
109 ; CHECK-LABEL: inner.body.split:
110 ; CHECK-NEXT:    %0 = phi i64 [ %iv.outer.next, %outer.latch ]
111 ; CHECK-NEXT:    %[[IVNEXT]] = add nsw i64 %iv.inner, -1
112 ; CHECK-NEXT:    %[[COND:[0-9]+]] = icmp eq i64 %iv.inner, 0
113 ; CHECK-NEXT:    br i1 %[[COND]], label %exit, label %inner.body
115 ; CHECK-LABEL: exit:
116 ; CHECK-NEXT:    %v4.lcssa = phi i64 [ %0, %inner.body.split ]
117 ; CHECK-NEXT:    %v8.lcssa.lcssa = phi i64 [ %[[IVNEXT]], %inner.body.split ]
118 ; CHECK-NEXT:    %v8.lcssa.lcssa.2 = phi i64 [ %[[IVNEXT]], %inner.body.split ]
119 ; CHECK-NEXT:    %r1 = add i64 %v8.lcssa.lcssa, %v8.lcssa.lcssa.2
120 ; CHECK-NEXT:    store i64 %r1, ptr @b, align 4
121 ; CHECK-NEXT:    store i64 %v4.lcssa, ptr @a, align 4
124 entry:
125   br label %outer.header
127 outer.header:                                     ; preds = %outer.latch, %entry
128   %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ]
129   br label %inner.body
131 inner.body:                                       ; preds = %inner.body, %outer.header
132   %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ]
133   %v7 = getelementptr inbounds [10 x [10 x i32]], ptr @c, i64 0, i64 %iv.inner, i64 %iv.outer
134   store i32 0, ptr %v7, align 4
135   %iv.inner.next = add nsw i64 %iv.inner, -1
136   %v9 = icmp eq i64 %iv.inner, 0
137   br i1 %v9, label %outer.latch, label %inner.body
139 outer.latch:                                      ; preds = %inner.body
140   %v8.lcssa = phi i64 [ %iv.inner.next, %inner.body ]
141   ;%const.lcssa = phi i64 [ 111, %inner.body ]
142   %iv.outer.next = add nuw nsw i64 %iv.outer, 1
143   %v5 = icmp ult i64 %iv.outer, 2
144   br i1 %v5, label %outer.header, label %exit
146 exit:                                             ; preds = %outer.latch
147   %v4.lcssa = phi i64 [ %iv.outer.next, %outer.latch ]
148   %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ]
149   %v8.lcssa.lcssa.2 = phi i64 [ %v8.lcssa, %outer.latch ]
150   %r1 = add i64 %v8.lcssa.lcssa, %v8.lcssa.lcssa.2
151   store i64 %r1, ptr @b, align 4
152   store i64 %v4.lcssa, ptr @a, align 4
153   ret void
157 ; Make sure we do not crash for loops without reachable exits.
158 define void @no_reachable_exits() {
159 ; Check we do not crash.
160 ; CHECK-LABEL: @no_reachable_exits(
161 ; CHECK-NEXT:  bb:
162 ; CHECK-NEXT:    br label [[OUTER_PH:%.*]]
163 ; CHECK:       outer.ph:
164 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
165 ; CHECK:       outer.header:
166 ; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ 0, [[OUTER_PH]] ], [ [[TMP8:%.*]], [[OUTER_LATCH:%.*]] ]
167 ; CHECK-NEXT:    br i1 undef, label [[INNER_PH:%.*]], label [[OUTER_LATCH]]
168 ; CHECK:       inner.ph:
169 ; CHECK-NEXT:    br label [[INNER_BODY:%.*]]
170 ; CHECK:       inner.body:
171 ; CHECK-NEXT:    [[TMP31:%.*]] = phi i32 [ 0, [[INNER_PH]] ], [ [[TMP6:%.*]], [[INNER_BODY]] ]
172 ; CHECK-NEXT:    [[TMP5:%.*]] = load ptr, ptr undef, align 8
173 ; CHECK-NEXT:    [[TMP6]] = add nsw i32 [[TMP31]], 1
174 ; CHECK-NEXT:    br i1 false, label [[INNER_BODY]], label [[OUTER_LATCH_LOOPEXIT:%.*]]
175 ; CHECK:       outer.latch.loopexit:
176 ; CHECK-NEXT:    br label [[OUTER_LATCH]]
177 ; CHECK:       outer.latch:
178 ; CHECK-NEXT:    [[TMP8]] = add nsw i32 [[TMP2]], 1
179 ; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER]], label [[EXIT:%.*]]
180 ; CHECK:       exit:
181 ; CHECK-NEXT:    unreachable
185   br label %outer.ph
187 outer.ph:                              ; preds = %bb
188   br label %outer.header
190 outer.header:                                    ; preds = %outer.ph, %outer.latch
191   %tmp2 = phi i32 [ 0, %outer.ph ], [ %tmp8, %outer.latch ]
192   br i1 undef, label %inner.ph, label %outer.latch
194 inner.ph:                                        ; preds = %outer.header
195   br label %inner.body
197 inner.body:                                              ; preds = %inner.ph, %inner.body
198   %tmp31 = phi i32 [ 0, %inner.ph ], [ %tmp6, %inner.body]
199   %tmp5 = load ptr, ptr undef, align 8
200   %tmp6 = add nsw i32 %tmp31, 1
201   br i1 undef, label %inner.body, label %outer.latch
203 outer.latch:                                              ; preds = %inner.body, %outer.header
204   %tmp8 = add nsw i32 %tmp2, 1
205   br i1 undef, label %outer.header, label %exit
207 exit:                                              ; preds = %outer.latch
208   unreachable