[mlir][LLVM] `LLVMTypeConverter`: Tighten materialization checks (#116532)
[llvm-project.git] / llvm / test / Transforms / LoopUnroll / 2011-08-08-PhiUpdate.ll
blob57ee7b659d7b5016a467187e0ab1dcaef7bb1a0b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=loop-unroll -S -unroll-count=4 | FileCheck %s
3 ; Test phi update after partial unroll.
5 declare i1 @check() nounwind
7 define void @test1(i32 %i, i32 %j) nounwind uwtable ssp {
9 ; CHECK-LABEL: @test1(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[COND1:%.*]] = call zeroext i1 @check()
12 ; CHECK-NEXT:    br i1 [[COND1]], label [[IF_THEN:%.*]], label [[IF_ELSE_LR_PH:%.*]]
13 ; CHECK:       if.else.lr.ph:
14 ; CHECK-NEXT:    br label [[IF_ELSE:%.*]]
15 ; CHECK:       if.else:
16 ; CHECK-NEXT:    [[SUB:%.*]] = phi i32 [ [[I:%.*]], [[IF_ELSE_LR_PH]] ], [ [[SUB5_3:%.*]], [[IF_ELSE_3:%.*]] ]
17 ; CHECK-NEXT:    [[SUB5:%.*]] = sub i32 [[SUB]], [[J:%.*]]
18 ; CHECK-NEXT:    [[COND2:%.*]] = call zeroext i1 @check()
19 ; CHECK-NEXT:    br i1 [[COND2]], label [[IF_THEN_LOOPEXIT:%.*]], label [[IF_ELSE_1:%.*]]
20 ; CHECK:       if.else.1:
21 ; CHECK-NEXT:    [[SUB5_1:%.*]] = sub i32 [[SUB5]], [[J]]
22 ; CHECK-NEXT:    [[COND2_1:%.*]] = call zeroext i1 @check()
23 ; CHECK-NEXT:    br i1 [[COND2_1]], label [[IF_THEN_LOOPEXIT]], label [[IF_ELSE_2:%.*]]
24 ; CHECK:       if.else.2:
25 ; CHECK-NEXT:    [[SUB5_2:%.*]] = sub i32 [[SUB5_1]], [[J]]
26 ; CHECK-NEXT:    [[COND2_2:%.*]] = call zeroext i1 @check()
27 ; CHECK-NEXT:    br i1 [[COND2_2]], label [[IF_THEN_LOOPEXIT]], label [[IF_ELSE_3]]
28 ; CHECK:       if.else.3:
29 ; CHECK-NEXT:    [[SUB5_3]] = sub i32 [[SUB5_2]], [[J]]
30 ; CHECK-NEXT:    [[COND2_3:%.*]] = call zeroext i1 @check()
31 ; CHECK-NEXT:    br i1 [[COND2_3]], label [[IF_THEN_LOOPEXIT]], label [[IF_ELSE]], !llvm.loop [[LOOP0:![0-9]+]]
32 ; CHECK:       if.then.loopexit:
33 ; CHECK-NEXT:    [[SUB5_LCSSA:%.*]] = phi i32 [ [[SUB5]], [[IF_ELSE]] ], [ [[SUB5_1]], [[IF_ELSE_1]] ], [ [[SUB5_2]], [[IF_ELSE_2]] ], [ [[SUB5_3]], [[IF_ELSE_3]] ]
34 ; CHECK-NEXT:    br label [[IF_THEN]]
35 ; CHECK:       if.then:
36 ; CHECK-NEXT:    [[I_TR:%.*]] = phi i32 [ [[I]], [[ENTRY:%.*]] ], [ [[SUB5_LCSSA]], [[IF_THEN_LOOPEXIT]] ]
37 ; CHECK-NEXT:    ret void
39 entry:
40   %cond1 = call zeroext i1 @check()
41   br i1 %cond1, label %if.then, label %if.else.lr.ph
43 if.else.lr.ph:                                    ; preds = %entry
44   br label %if.else
46 if.else:                                          ; preds = %if.else, %if.else.lr.ph
47   %sub = phi i32 [ %i, %if.else.lr.ph ], [ %sub5, %if.else ]
48   %sub5 = sub i32 %sub, %j
49   %cond2 = call zeroext i1 @check()
50   br i1 %cond2, label %if.then, label %if.else
52 if.then:                                          ; preds = %if.else, %entry
53   %i.tr = phi i32 [ %i, %entry ], [ %sub5, %if.else ]
54   ret void
58 ; PR7318: assertion failure after doing a simple loop unroll
60 define i32 @test2(ptr nocapture %p, i32 %n) nounwind readonly {
62 ; CHECK-LABEL: @test2(
63 ; CHECK-NEXT:  entry:
64 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 0
65 ; CHECK-NEXT:    br i1 [[TMP0]], label [[BB_NPH:%.*]], label [[BB2:%.*]]
66 ; CHECK:       bb.nph:
67 ; CHECK-NEXT:    [[TMP:%.*]] = zext i32 [[N]] to i64
68 ; CHECK-NEXT:    br label [[BB:%.*]]
69 ; CHECK:       bb:
70 ; CHECK-NEXT:    [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[INDVAR_NEXT_3:%.*]], [[BB1_3:%.*]] ]
71 ; CHECK-NEXT:    [[S_01:%.*]] = phi i32 [ 0, [[BB_NPH]] ], [ [[TMP8:%.*]], [[BB1_3]] ]
72 ; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDVAR]]
73 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SCEVGEP]], align 1
74 ; CHECK-NEXT:    [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[S_01]]
75 ; CHECK-NEXT:    br label [[BB1:%.*]]
76 ; CHECK:       bb1:
77 ; CHECK-NEXT:    [[INDVAR_NEXT:%.*]] = add nuw nsw i64 [[INDVAR]], 1
78 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVAR_NEXT]], [[TMP]]
79 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[BB_1:%.*]], label [[BB1_BB2_CRIT_EDGE:%.*]]
80 ; CHECK:       bb.1:
81 ; CHECK-NEXT:    [[SCEVGEP_1:%.*]] = getelementptr i32, ptr [[P]], i64 [[INDVAR_NEXT]]
82 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[SCEVGEP_1]], align 1
83 ; CHECK-NEXT:    [[TMP4:%.*]] = add nsw i32 [[TMP3]], [[TMP2]]
84 ; CHECK-NEXT:    br label [[BB1_1:%.*]]
85 ; CHECK:       bb1.1:
86 ; CHECK-NEXT:    [[INDVAR_NEXT_1:%.*]] = add nuw nsw i64 [[INDVAR]], 2
87 ; CHECK-NEXT:    [[EXITCOND_1:%.*]] = icmp ne i64 [[INDVAR_NEXT_1]], [[TMP]]
88 ; CHECK-NEXT:    br i1 [[EXITCOND_1]], label [[BB_2:%.*]], label [[BB1_BB2_CRIT_EDGE]]
89 ; CHECK:       bb.2:
90 ; CHECK-NEXT:    [[SCEVGEP_2:%.*]] = getelementptr i32, ptr [[P]], i64 [[INDVAR_NEXT_1]]
91 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[SCEVGEP_2]], align 1
92 ; CHECK-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP5]], [[TMP4]]
93 ; CHECK-NEXT:    br label [[BB1_2:%.*]]
94 ; CHECK:       bb1.2:
95 ; CHECK-NEXT:    [[INDVAR_NEXT_2:%.*]] = add nuw nsw i64 [[INDVAR]], 3
96 ; CHECK-NEXT:    [[EXITCOND_2:%.*]] = icmp ne i64 [[INDVAR_NEXT_2]], [[TMP]]
97 ; CHECK-NEXT:    br i1 [[EXITCOND_2]], label [[BB_3:%.*]], label [[BB1_BB2_CRIT_EDGE]]
98 ; CHECK:       bb.3:
99 ; CHECK-NEXT:    [[SCEVGEP_3:%.*]] = getelementptr i32, ptr [[P]], i64 [[INDVAR_NEXT_2]]
100 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[SCEVGEP_3]], align 1
101 ; CHECK-NEXT:    [[TMP8]] = add nsw i32 [[TMP7]], [[TMP6]]
102 ; CHECK-NEXT:    br label [[BB1_3]]
103 ; CHECK:       bb1.3:
104 ; CHECK-NEXT:    [[INDVAR_NEXT_3]] = add i64 [[INDVAR]], 4
105 ; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp ne i64 [[INDVAR_NEXT_3]], [[TMP]]
106 ; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[BB]], label [[BB1_BB2_CRIT_EDGE]], !llvm.loop [[LOOP2:![0-9]+]]
107 ; CHECK:       bb1.bb2_crit_edge:
108 ; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi i32 [ [[TMP2]], [[BB1]] ], [ [[TMP4]], [[BB1_1]] ], [ [[TMP6]], [[BB1_2]] ], [ [[TMP8]], [[BB1_3]] ]
109 ; CHECK-NEXT:    br label [[BB2]]
110 ; CHECK:       bb2:
111 ; CHECK-NEXT:    [[S_0_LCSSA:%.*]] = phi i32 [ [[DOTLCSSA]], [[BB1_BB2_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]
112 ; CHECK-NEXT:    ret i32 [[S_0_LCSSA]]
114 entry:
115   %0 = icmp sgt i32 %n, 0                         ; <i1> [#uses=1]
116   br i1 %0, label %bb.nph, label %bb2
118 bb.nph:                                           ; preds = %entry
119   %tmp = zext i32 %n to i64                       ; <i64> [#uses=1]
120   br label %bb
122 bb:                                               ; preds = %bb.nph, %bb1
123   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; <i64> [#uses=2]
124   %s.01 = phi i32 [ 0, %bb.nph ], [ %2, %bb1 ]    ; <i32> [#uses=1]
125   %scevgep = getelementptr i32, ptr %p, i64 %indvar   ; <ptr> [#uses=1]
126   %1 = load i32, ptr %scevgep, align 1                ; <i32> [#uses=1]
127   %2 = add nsw i32 %1, %s.01                      ; <i32> [#uses=2]
128   br label %bb1
130 bb1:                                              ; preds = %bb
131   %indvar.next = add i64 %indvar, 1               ; <i64> [#uses=2]
132   %exitcond = icmp ne i64 %indvar.next, %tmp      ; <i1> [#uses=1]
133   br i1 %exitcond, label %bb, label %bb1.bb2_crit_edge
135 bb1.bb2_crit_edge:                                ; preds = %bb1
136   %.lcssa = phi i32 [ %2, %bb1 ]                  ; <i32> [#uses=1]
137   br label %bb2
139 bb2:                                              ; preds = %bb1.bb2_crit_edge, %entry
140   %s.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ 0, %entry ] ; <i32> [#uses=1]
141   ret i32 %s.0.lcssa
144 ; Check phi update for loop with an early-exit.
146 define i32 @test3(i1 %arg) nounwind uwtable ssp align 2 {
148 ; CHECK-LABEL: @test3(
149 ; CHECK-NEXT:  entry:
150 ; CHECK-NEXT:    [[COND1:%.*]] = call zeroext i1 @check()
151 ; CHECK-NEXT:    br i1 [[COND1]], label [[RETURN:%.*]], label [[IF_END:%.*]]
152 ; CHECK:       if.end:
153 ; CHECK-NEXT:    br label [[DO_BODY:%.*]]
154 ; CHECK:       do.body:
155 ; CHECK-NEXT:    [[COND2:%.*]] = call zeroext i1 @check()
156 ; CHECK-NEXT:    br i1 [[COND2]], label [[EXIT:%.*]], label [[DO_COND:%.*]]
157 ; CHECK:       exit:
158 ; CHECK-NEXT:    [[TMP7_I:%.*]] = load i32, ptr undef, align 8
159 ; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[DO_COND]], label [[LAND_LHS_TRUE:%.*]]
160 ; CHECK:       land.lhs.true:
161 ; CHECK-NEXT:    br i1 [[ARG]], label [[RETURN_LOOPEXIT:%.*]], label [[DO_COND]]
162 ; CHECK:       do.cond:
163 ; CHECK-NEXT:    [[COND3:%.*]] = call zeroext i1 @check()
164 ; CHECK-NEXT:    br i1 [[COND3]], label [[DO_END:%.*]], label [[DO_BODY_1:%.*]]
165 ; CHECK:       do.body.1:
166 ; CHECK-NEXT:    [[COND2_1:%.*]] = call zeroext i1 @check()
167 ; CHECK-NEXT:    br i1 [[COND2_1]], label [[EXIT_1:%.*]], label [[DO_COND_1:%.*]]
168 ; CHECK:       exit.1:
169 ; CHECK-NEXT:    [[TMP7_I_1:%.*]] = load i32, ptr undef, align 8
170 ; CHECK-NEXT:    br i1 [[ARG]], label [[DO_COND_1]], label [[LAND_LHS_TRUE_1:%.*]]
171 ; CHECK:       land.lhs.true.1:
172 ; CHECK-NEXT:    br i1 [[ARG]], label [[RETURN_LOOPEXIT]], label [[DO_COND_1]]
173 ; CHECK:       do.cond.1:
174 ; CHECK-NEXT:    [[COND3_1:%.*]] = call zeroext i1 @check()
175 ; CHECK-NEXT:    br i1 [[COND3_1]], label [[DO_END]], label [[DO_BODY_2:%.*]]
176 ; CHECK:       do.body.2:
177 ; CHECK-NEXT:    [[COND2_2:%.*]] = call zeroext i1 @check()
178 ; CHECK-NEXT:    br i1 [[COND2_2]], label [[EXIT_2:%.*]], label [[DO_COND_2:%.*]]
179 ; CHECK:       exit.2:
180 ; CHECK-NEXT:    [[TMP7_I_2:%.*]] = load i32, ptr undef, align 8
181 ; CHECK-NEXT:    br i1 [[ARG]], label [[DO_COND_2]], label [[LAND_LHS_TRUE_2:%.*]]
182 ; CHECK:       land.lhs.true.2:
183 ; CHECK-NEXT:    br i1 [[ARG]], label [[RETURN_LOOPEXIT]], label [[DO_COND_2]]
184 ; CHECK:       do.cond.2:
185 ; CHECK-NEXT:    [[COND3_2:%.*]] = call zeroext i1 @check()
186 ; CHECK-NEXT:    br i1 [[COND3_2]], label [[DO_END]], label [[DO_BODY_3:%.*]]
187 ; CHECK:       do.body.3:
188 ; CHECK-NEXT:    [[COND2_3:%.*]] = call zeroext i1 @check()
189 ; CHECK-NEXT:    br i1 [[COND2_3]], label [[EXIT_3:%.*]], label [[DO_COND_3:%.*]]
190 ; CHECK:       exit.3:
191 ; CHECK-NEXT:    [[TMP7_I_3:%.*]] = load i32, ptr undef, align 8
192 ; CHECK-NEXT:    br i1 [[ARG]], label [[DO_COND_3]], label [[LAND_LHS_TRUE_3:%.*]]
193 ; CHECK:       land.lhs.true.3:
194 ; CHECK-NEXT:    br i1 [[ARG]], label [[RETURN_LOOPEXIT]], label [[DO_COND_3]]
195 ; CHECK:       do.cond.3:
196 ; CHECK-NEXT:    [[COND3_3:%.*]] = call zeroext i1 @check()
197 ; CHECK-NEXT:    br i1 [[COND3_3]], label [[DO_END]], label [[DO_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
198 ; CHECK:       do.end:
199 ; CHECK-NEXT:    br label [[RETURN]]
200 ; CHECK:       return.loopexit:
201 ; CHECK-NEXT:    [[TMP7_I_LCSSA:%.*]] = phi i32 [ [[TMP7_I]], [[LAND_LHS_TRUE]] ], [ [[TMP7_I_1]], [[LAND_LHS_TRUE_1]] ], [ [[TMP7_I_2]], [[LAND_LHS_TRUE_2]] ], [ [[TMP7_I_3]], [[LAND_LHS_TRUE_3]] ]
202 ; CHECK-NEXT:    br label [[RETURN]]
203 ; CHECK:       return:
204 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 0, [[DO_END]] ], [ 0, [[ENTRY:%.*]] ], [ [[TMP7_I_LCSSA]], [[RETURN_LOOPEXIT]] ]
205 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
207 entry:
208   %cond1 = call zeroext i1 @check()
209   br i1 %cond1, label %return, label %if.end
211 if.end:                                           ; preds = %entry
212   br label %do.body
214 do.body:                                          ; preds = %do.cond, %if.end
215   %cond2 = call zeroext i1 @check()
216   br i1 %cond2, label %exit, label %do.cond
218 exit:                  ; preds = %do.body
219   %tmp7.i = load i32, ptr undef, align 8
220   br i1 %arg, label %do.cond, label %land.lhs.true
222 land.lhs.true:                                    ; preds = %exit
223   br i1 %arg, label %return, label %do.cond
225 do.cond:                                          ; preds = %land.lhs.true, %exit, %do.body
226   %cond3 = call zeroext i1 @check()
227   br i1 %cond3, label %do.end, label %do.body
229 do.end:                                           ; preds = %do.cond
230   br label %return
232 return:                                           ; preds = %do.end, %land.lhs.true, %entry
233   %retval.0 = phi i32 [ 0, %do.end ], [ 0, %entry ], [ %tmp7.i, %land.lhs.true ]
234   ret i32 %retval.0