Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopRotate / loopexitinglatch.ll
blobdbc51fb132b37527db305d45c05526b5bbcdb52f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=loop-rotate < %s -verify-loop-info -verify-dom-info -verify-memoryssa | FileCheck %s
4 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
5 target triple = "thumbv8m.base-arm-none-eabi"
7 %struct.List = type { ptr, i32 }
9 define void @list_add(ptr nocapture %list, ptr %data) {
10 ; CHECK-LABEL: @list_add(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[LIST:%.*]], align 4
13 ; CHECK-NEXT:    [[VAL2:%.*]] = getelementptr inbounds [[STRUCT_LIST:%.*]], ptr [[TMP0]], i32 0, i32 1
14 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[VAL2]], align 4
15 ; CHECK-NEXT:    [[VAL1:%.*]] = getelementptr inbounds [[STRUCT_LIST]], ptr [[DATA:%.*]], i32 0, i32 1
16 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[VAL1]], align 4
17 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]]
18 ; CHECK-NEXT:    br i1 [[CMP3]], label [[IF_THEN_LR_PH:%.*]], label [[IF_ELSE6:%.*]]
19 ; CHECK:       if.then.lr.ph:
20 ; CHECK-NEXT:    br label [[IF_THEN:%.*]]
21 ; CHECK:       for.cond:
22 ; CHECK-NEXT:    [[CURR_0:%.*]] = phi ptr [ [[TMP5:%.*]], [[IF_THEN]] ]
23 ; CHECK-NEXT:    [[PREV_0:%.*]] = phi ptr [ [[CURR_04:%.*]], [[IF_THEN]] ]
24 ; CHECK-NEXT:    [[VAL:%.*]] = getelementptr inbounds [[STRUCT_LIST]], ptr [[CURR_0]], i32 0, i32 1
25 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[VAL]], align 4
26 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[VAL1]], align 4
27 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP3]], [[TMP4]]
28 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN]], label [[FOR_COND_IF_ELSE6_CRIT_EDGE:%.*]]
29 ; CHECK:       if.then:
30 ; CHECK-NEXT:    [[CURR_04]] = phi ptr [ [[TMP0]], [[IF_THEN_LR_PH]] ], [ [[CURR_0]], [[FOR_COND:%.*]] ]
31 ; CHECK-NEXT:    [[TMP5]] = load ptr, ptr [[CURR_04]], align 4
32 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq ptr [[TMP5]], null
33 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[FOR_COND]]
34 ; CHECK:       if.else:
35 ; CHECK-NEXT:    [[NEXT_LCSSA:%.*]] = phi ptr [ [[CURR_04]], [[IF_THEN]] ]
36 ; CHECK-NEXT:    store ptr [[DATA]], ptr [[NEXT_LCSSA]], align 4
37 ; CHECK-NEXT:    store ptr null, ptr [[DATA]], align 4
38 ; CHECK-NEXT:    br label [[FOR_END:%.*]]
39 ; CHECK:       for.cond.if.else6_crit_edge:
40 ; CHECK-NEXT:    [[SPLIT:%.*]] = phi ptr [ [[PREV_0]], [[FOR_COND]] ]
41 ; CHECK-NEXT:    br label [[IF_ELSE6]]
42 ; CHECK:       if.else6:
43 ; CHECK-NEXT:    [[PREV_0_LCSSA:%.*]] = phi ptr [ [[SPLIT]], [[FOR_COND_IF_ELSE6_CRIT_EDGE]] ], [ null, [[ENTRY:%.*]] ]
44 ; CHECK-NEXT:    [[TOBOOL7:%.*]] = icmp eq ptr [[PREV_0_LCSSA]], null
45 ; CHECK-NEXT:    br i1 [[TOBOOL7]], label [[IF_ELSE12:%.*]], label [[IF_THEN8:%.*]]
46 ; CHECK:       if.then8:
47 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[PREV_0_LCSSA]], align 4
48 ; CHECK-NEXT:    store i32 [[TMP7]], ptr [[DATA]], align 4
49 ; CHECK-NEXT:    store ptr [[DATA]], ptr [[PREV_0_LCSSA]], align 4
50 ; CHECK-NEXT:    br label [[FOR_END]]
51 ; CHECK:       if.else12:
52 ; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[LIST]], align 4
53 ; CHECK-NEXT:    store i32 [[TMP10]], ptr [[DATA]], align 4
54 ; CHECK-NEXT:    store ptr [[DATA]], ptr [[LIST]], align 4
55 ; CHECK-NEXT:    br label [[FOR_END]]
56 ; CHECK:       for.end:
57 ; CHECK-NEXT:    ret void
59 entry:
60   %0 = load ptr, ptr %list, align 4
61   br label %for.cond
63 for.cond:                                         ; preds = %if.then, %entry
64   %curr.0 = phi ptr [ %0, %entry ], [ %3, %if.then ]
65   %prev.0 = phi ptr [ null, %entry ], [ %curr.0, %if.then ]
66   %val = getelementptr inbounds %struct.List, ptr %curr.0, i32 0, i32 1
67   %1 = load i32, ptr %val, align 4
68   %val1 = getelementptr inbounds %struct.List, ptr %data, i32 0, i32 1
69   %2 = load i32, ptr %val1, align 4
70   %cmp = icmp slt i32 %1, %2
71   br i1 %cmp, label %if.then, label %if.else6
73 if.then:                                          ; preds = %for.cond
74   %3 = load ptr, ptr %curr.0, align 4
75   %tobool = icmp eq ptr %3, null
76   br i1 %tobool, label %if.else, label %for.cond
78 if.else:                                          ; preds = %if.then
79   %next.lcssa = phi ptr [ %curr.0, %if.then ]
80   store ptr %data, ptr %next.lcssa, align 4
81   store ptr null, ptr %data, align 4
82   br label %for.end
84 if.else6:                                         ; preds = %for.cond
85   %prev.0.lcssa = phi ptr [ %prev.0, %for.cond ]
86   %tobool7 = icmp eq ptr %prev.0.lcssa, null
87   br i1 %tobool7, label %if.else12, label %if.then8
89 if.then8:                                         ; preds = %if.else6
90   %4 = load i32, ptr %prev.0.lcssa, align 4
91   store i32 %4, ptr %data, align 4
92   store ptr %data, ptr %prev.0.lcssa, align 4
93   br label %for.end
95 if.else12:                                        ; preds = %if.else6
96   %5 = load i32, ptr %list, align 4
97   store i32 %5, ptr %data, align 4
98   store ptr %data, ptr %list, align 4
99   br label %for.end
101 for.end:                                          ; preds = %if.else12, %if.then8, %if.else
102   ret void
105 define i32 @test2(ptr %l) {
106 ; CHECK-LABEL: @test2(
107 ; CHECK-NEXT:  entry:
108 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[L:%.*]], align 4
109 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp eq i32 [[TMP0]], 0
110 ; CHECK-NEXT:    br i1 [[TOBOOL2]], label [[CLEANUP:%.*]], label [[DO_COND_LR_PH:%.*]]
111 ; CHECK:       do.cond.lr.ph:
112 ; CHECK-NEXT:    br label [[DO_COND:%.*]]
113 ; CHECK:       do.body:
114 ; CHECK-NEXT:    [[A_0:%.*]] = phi i32 [ [[REM:%.*]], [[DO_COND]] ]
115 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[L]], align 4
116 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP1]], 0
117 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[DO_BODY_CLEANUP_CRIT_EDGE:%.*]], label [[DO_COND]]
118 ; CHECK:       do.body.cleanup_crit_edge:
119 ; CHECK-NEXT:    [[SPLIT:%.*]] = phi i32 [ [[A_0]], [[DO_BODY:%.*]] ]
120 ; CHECK-NEXT:    br label [[CLEANUP]]
121 ; CHECK:       cleanup:
122 ; CHECK-NEXT:    [[A_0_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[DO_BODY_CLEANUP_CRIT_EDGE]] ], [ 100, [[ENTRY:%.*]] ]
123 ; CHECK-NEXT:    store i32 10, ptr [[L]], align 4
124 ; CHECK-NEXT:    br label [[CLEANUP2:%.*]]
125 ; CHECK:       do.cond:
126 ; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP0]], [[DO_COND_LR_PH]] ], [ [[TMP1]], [[DO_BODY]] ]
127 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 13
128 ; CHECK-NEXT:    [[REM]] = srem i32 [[MUL]], 27
129 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[L]], align 4
130 ; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[TMP3]], 0
131 ; CHECK-NEXT:    br i1 [[TOBOOL1]], label [[CLEANUP2_LOOPEXIT:%.*]], label [[DO_BODY]]
132 ; CHECK:       cleanup2.loopexit:
133 ; CHECK-NEXT:    br label [[CLEANUP2]]
134 ; CHECK:       cleanup2:
135 ; CHECK-NEXT:    [[RETVAL_2:%.*]] = phi i32 [ [[A_0_LCSSA]], [[CLEANUP]] ], [ 0, [[CLEANUP2_LOOPEXIT]] ]
136 ; CHECK-NEXT:    ret i32 [[RETVAL_2]]
138 entry:
139   br label %do.body
141 do.body:                                          ; preds = %do.cond, %entry
142   %a.0 = phi i32 [ 100, %entry ], [ %rem, %do.cond ]
143   %0 = load i32, ptr %l, align 4
144   %tobool = icmp eq i32 %0, 0
145   br i1 %tobool, label %cleanup, label %do.cond
147 cleanup:                                          ; preds = %do.body
148   %a.0.lcssa = phi i32 [ %a.0, %do.body ]
149   store i32 10, ptr %l, align 4
150   br label %cleanup2
152 do.cond:                                          ; preds = %do.body
153   %mul = mul nsw i32 %0, 13
154   %rem = srem i32 %mul, 27
155   %1 = load i32, ptr %l, align 4
156   %tobool1 = icmp eq i32 %1, 0
157   br i1 %tobool1, label %cleanup2.loopexit, label %do.body
159 cleanup2.loopexit:                                ; preds = %do.cond
160   br label %cleanup2
162 cleanup2:                                         ; preds = %cleanup2.loopexit, %cleanup
163   %retval.2 = phi i32 [ %a.0.lcssa, %cleanup ], [ 0, %cleanup2.loopexit ]
164   ret i32 %retval.2
167 define i32 @no_rotate(ptr %l) {
168 ; CHECK-LABEL: @no_rotate(
169 ; CHECK-NEXT:  entry:
170 ; CHECK-NEXT:    br label [[DO_BODY:%.*]]
171 ; CHECK:       do.body:
172 ; CHECK-NEXT:    [[A_0:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[REM:%.*]], [[DO_COND:%.*]] ]
173 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[L:%.*]], align 4
174 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
175 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[CLEANUP:%.*]], label [[DO_COND]]
176 ; CHECK:       cleanup:
177 ; CHECK-NEXT:    [[A_0_LCSSA:%.*]] = phi i32 [ [[A_0]], [[DO_BODY]] ]
178 ; CHECK-NEXT:    store i32 10, ptr [[L]], align 4
179 ; CHECK-NEXT:    br label [[CLEANUP2:%.*]]
180 ; CHECK:       do.cond:
181 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[A_0]], 13
182 ; CHECK-NEXT:    [[REM]] = srem i32 [[MUL]], 27
183 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[L]], align 4
184 ; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[TMP1]], 0
185 ; CHECK-NEXT:    br i1 [[TOBOOL1]], label [[CLEANUP2_LOOPEXIT:%.*]], label [[DO_BODY]]
186 ; CHECK:       cleanup2.loopexit:
187 ; CHECK-NEXT:    br label [[CLEANUP2]]
188 ; CHECK:       cleanup2:
189 ; CHECK-NEXT:    [[RETVAL_2:%.*]] = phi i32 [ [[A_0_LCSSA]], [[CLEANUP]] ], [ 0, [[CLEANUP2_LOOPEXIT]] ]
190 ; CHECK-NEXT:    ret i32 [[RETVAL_2]]
192 entry:
193   br label %do.body
195 do.body:                                          ; preds = %do.cond, %entry
196   %a.0 = phi i32 [ 100, %entry ], [ %rem, %do.cond ]
197   %0 = load i32, ptr %l, align 4
198   %tobool = icmp eq i32 %0, 0
199   br i1 %tobool, label %cleanup, label %do.cond
201 cleanup:                                          ; preds = %do.body
202   %a.0.lcssa = phi i32 [ %a.0, %do.body ]
203   store i32 10, ptr %l, align 4
204   br label %cleanup2
206 do.cond:                                          ; preds = %do.body
207   %mul = mul nsw i32 %a.0, 13
208   %rem = srem i32 %mul, 27
209   %1 = load i32, ptr %l, align 4
210   %tobool1 = icmp eq i32 %1, 0
211   br i1 %tobool1, label %cleanup2.loopexit, label %do.body
213 cleanup2.loopexit:                                ; preds = %do.cond
214   br label %cleanup2
216 cleanup2:                                         ; preds = %cleanup2.loopexit, %cleanup
217   %retval.2 = phi i32 [ %a.0.lcssa, %cleanup ], [ 0, %cleanup2.loopexit ]
218   ret i32 %retval.2