@@ -78,3 +78,250 @@ final_right:
7878
7979declare void @sideeffect0 ()
8080declare void @sideeffect1 ()
81+
82+ define i1 @speculate_empty_bb (i32 %x , i32 %y ) {
83+ ; YES-LABEL: define i1 @speculate_empty_bb
84+ ; YES-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
85+ ; YES-NEXT: start:
86+ ; YES-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
87+ ; YES-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
88+ ; YES: bb6:
89+ ; YES-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
90+ ; YES-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
91+ ; YES: bb5:
92+ ; YES-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
93+ ; YES-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
94+ ; YES: bb2:
95+ ; YES-NEXT: br label [[BB3]]
96+ ; YES: bb3:
97+ ; YES-NEXT: [[RET:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[BB6]] ], [ false, [[BB5]] ]
98+ ; YES-NEXT: ret i1 [[RET]]
99+ ;
100+ ; NO-LABEL: define i1 @speculate_empty_bb
101+ ; NO-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
102+ ; NO-NEXT: start:
103+ ; NO-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
104+ ; NO-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
105+ ; NO: bb6:
106+ ; NO-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
107+ ; NO-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
108+ ; NO: bb5:
109+ ; NO-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
110+ ; NO-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
111+ ; NO: bb2:
112+ ; NO-NEXT: br label [[BB3]]
113+ ; NO: bb3:
114+ ; NO-NEXT: [[RET:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[BB6]] ], [ false, [[BB5]] ]
115+ ; NO-NEXT: ret i1 [[RET]]
116+ ;
117+ start:
118+ %cmp1 = icmp eq i32 %x , 0
119+ br i1 %cmp1 , label %bb6 , label %bb5
120+
121+ bb6:
122+ %cmp2 = icmp eq i32 %y , 0
123+ br i1 %cmp2 , label %bb2 , label %bb3
124+
125+ bb5:
126+ %cmp3 = icmp ult i32 %x , %y
127+ br i1 %cmp3 , label %bb3 , label %bb2
128+
129+ bb2:
130+ br label %bb3
131+
132+ bb3:
133+ %ret = phi i1 [ true , %bb2 ], [ false , %bb6 ], [ false , %bb5 ]
134+ ret i1 %ret
135+ }
136+
137+ define i32 @speculate_empty_bb_not_simplifiable (i32 %x , i32 %y ) {
138+ ; YES-LABEL: define i32 @speculate_empty_bb_not_simplifiable
139+ ; YES-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
140+ ; YES-NEXT: start:
141+ ; YES-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
142+ ; YES-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
143+ ; YES: bb6:
144+ ; YES-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
145+ ; YES-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
146+ ; YES: bb5:
147+ ; YES-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
148+ ; YES-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
149+ ; YES: bb2:
150+ ; YES-NEXT: br label [[BB3]]
151+ ; YES: bb3:
152+ ; YES-NEXT: [[RET:%.*]] = phi i32 [ 10, [[BB2]] ], [ 20, [[BB6]] ], [ 30, [[BB5]] ]
153+ ; YES-NEXT: ret i32 [[RET]]
154+ ;
155+ ; NO-LABEL: define i32 @speculate_empty_bb_not_simplifiable
156+ ; NO-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
157+ ; NO-NEXT: start:
158+ ; NO-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
159+ ; NO-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
160+ ; NO: bb6:
161+ ; NO-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
162+ ; NO-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
163+ ; NO: bb5:
164+ ; NO-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
165+ ; NO-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
166+ ; NO: bb2:
167+ ; NO-NEXT: br label [[BB3]]
168+ ; NO: bb3:
169+ ; NO-NEXT: [[RET:%.*]] = phi i32 [ 10, [[BB2]] ], [ 20, [[BB6]] ], [ 30, [[BB5]] ]
170+ ; NO-NEXT: ret i32 [[RET]]
171+ ;
172+ start:
173+ %cmp1 = icmp eq i32 %x , 0
174+ br i1 %cmp1 , label %bb6 , label %bb5
175+
176+ bb6:
177+ %cmp2 = icmp eq i32 %y , 0
178+ br i1 %cmp2 , label %bb2 , label %bb3
179+
180+ bb5:
181+ %cmp3 = icmp ult i32 %x , %y
182+ br i1 %cmp3 , label %bb3 , label %bb2
183+
184+ bb2:
185+ br label %bb3
186+
187+ bb3:
188+ %ret = phi i32 [ 10 , %bb2 ], [ 20 , %bb6 ], [ 30 , %bb5 ]
189+ ret i32 %ret
190+ }
191+
192+ define i1 @speculate_nonempty_bb (i32 %x , i32 %y ) {
193+ ; YES-LABEL: define i1 @speculate_nonempty_bb
194+ ; YES-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
195+ ; YES-NEXT: start:
196+ ; YES-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
197+ ; YES-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
198+ ; YES: bb6:
199+ ; YES-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
200+ ; YES-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
201+ ; YES: bb5:
202+ ; YES-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
203+ ; YES-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
204+ ; YES: bb2:
205+ ; YES-NEXT: [[PHI:%.*]] = phi i32 [ [[X]], [[BB6]] ], [ [[Y]], [[BB5]] ]
206+ ; YES-NEXT: [[CMP4:%.*]] = icmp eq i32 [[PHI]], 0
207+ ; YES-NEXT: br label [[BB3]]
208+ ; YES: bb3:
209+ ; YES-NEXT: [[RET:%.*]] = phi i1 [ [[CMP4]], [[BB2]] ], [ false, [[BB6]] ], [ false, [[BB5]] ]
210+ ; YES-NEXT: ret i1 [[RET]]
211+ ;
212+ ; NO-LABEL: define i1 @speculate_nonempty_bb
213+ ; NO-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
214+ ; NO-NEXT: start:
215+ ; NO-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
216+ ; NO-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
217+ ; NO: bb6:
218+ ; NO-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
219+ ; NO-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
220+ ; NO: bb5:
221+ ; NO-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
222+ ; NO-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
223+ ; NO: bb2:
224+ ; NO-NEXT: [[PHI:%.*]] = phi i32 [ [[X]], [[BB6]] ], [ [[Y]], [[BB5]] ]
225+ ; NO-NEXT: [[CMP4:%.*]] = icmp eq i32 [[PHI]], 0
226+ ; NO-NEXT: br label [[BB3]]
227+ ; NO: bb3:
228+ ; NO-NEXT: [[RET:%.*]] = phi i1 [ [[CMP4]], [[BB2]] ], [ false, [[BB6]] ], [ false, [[BB5]] ]
229+ ; NO-NEXT: ret i1 [[RET]]
230+ ;
231+ start:
232+ %cmp1 = icmp eq i32 %x , 0
233+ br i1 %cmp1 , label %bb6 , label %bb5
234+
235+ bb6:
236+ %cmp2 = icmp eq i32 %y , 0
237+ br i1 %cmp2 , label %bb2 , label %bb3
238+
239+ bb5:
240+ %cmp3 = icmp ult i32 %x , %y
241+ br i1 %cmp3 , label %bb3 , label %bb2
242+
243+ bb2:
244+ %phi = phi i32 [ %x , %bb6 ], [ %y , %bb5 ]
245+ %cmp4 = icmp eq i32 %phi , 0
246+ br label %bb3
247+
248+ bb3:
249+ %ret = phi i1 [ %cmp4 , %bb2 ], [ false , %bb6 ], [ false , %bb5 ]
250+ ret i1 %ret
251+ }
252+
253+ define i1 @speculate_empty_bb_too_many_select (i32 %x , i32 %y ) {
254+ ; YES-LABEL: define i1 @speculate_empty_bb_too_many_select
255+ ; YES-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
256+ ; YES-NEXT: start:
257+ ; YES-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
258+ ; YES-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
259+ ; YES: bb6:
260+ ; YES-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
261+ ; YES-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
262+ ; YES: bb5:
263+ ; YES-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
264+ ; YES-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
265+ ; YES: bb2:
266+ ; YES-NEXT: br label [[BB3]]
267+ ; YES: bb3:
268+ ; YES-NEXT: [[RET:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[BB6]] ], [ false, [[BB5]] ]
269+ ; YES-NEXT: [[RET2:%.*]] = phi i32 [ [[X]], [[BB2]] ], [ [[Y]], [[BB6]] ], [ [[X]], [[BB5]] ]
270+ ; YES-NEXT: [[RET3:%.*]] = phi i32 [ [[Y]], [[BB2]] ], [ [[X]], [[BB6]] ], [ [[X]], [[BB5]] ]
271+ ; YES-NEXT: [[RET4:%.*]] = phi i32 [ 0, [[BB2]] ], [ 3, [[BB6]] ], [ 5, [[BB5]] ]
272+ ; YES-NEXT: [[ADD:%.*]] = add i32 [[RET2]], [[RET3]]
273+ ; YES-NEXT: [[ADD2:%.*]] = add i32 [[ADD]], [[RET4]]
274+ ; YES-NEXT: [[CMP4:%.*]] = icmp eq i32 [[ADD2]], 0
275+ ; YES-NEXT: [[AND:%.*]] = and i1 [[RET]], [[CMP4]]
276+ ; YES-NEXT: ret i1 [[AND]]
277+ ;
278+ ; NO-LABEL: define i1 @speculate_empty_bb_too_many_select
279+ ; NO-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
280+ ; NO-NEXT: start:
281+ ; NO-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 0
282+ ; NO-NEXT: br i1 [[CMP1]], label [[BB6:%.*]], label [[BB5:%.*]]
283+ ; NO: bb6:
284+ ; NO-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
285+ ; NO-NEXT: br i1 [[CMP2]], label [[BB2:%.*]], label [[BB3:%.*]]
286+ ; NO: bb5:
287+ ; NO-NEXT: [[CMP3:%.*]] = icmp ult i32 [[X]], [[Y]]
288+ ; NO-NEXT: br i1 [[CMP3]], label [[BB3]], label [[BB2]]
289+ ; NO: bb2:
290+ ; NO-NEXT: br label [[BB3]]
291+ ; NO: bb3:
292+ ; NO-NEXT: [[RET:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[BB6]] ], [ false, [[BB5]] ]
293+ ; NO-NEXT: [[RET2:%.*]] = phi i32 [ [[X]], [[BB2]] ], [ [[Y]], [[BB6]] ], [ [[X]], [[BB5]] ]
294+ ; NO-NEXT: [[RET3:%.*]] = phi i32 [ [[Y]], [[BB2]] ], [ [[X]], [[BB6]] ], [ [[X]], [[BB5]] ]
295+ ; NO-NEXT: [[RET4:%.*]] = phi i32 [ 0, [[BB2]] ], [ 3, [[BB6]] ], [ 5, [[BB5]] ]
296+ ; NO-NEXT: [[ADD:%.*]] = add i32 [[RET2]], [[RET3]]
297+ ; NO-NEXT: [[ADD2:%.*]] = add i32 [[ADD]], [[RET4]]
298+ ; NO-NEXT: [[CMP4:%.*]] = icmp eq i32 [[ADD2]], 0
299+ ; NO-NEXT: [[AND:%.*]] = and i1 [[RET]], [[CMP4]]
300+ ; NO-NEXT: ret i1 [[AND]]
301+ ;
302+ start:
303+ %cmp1 = icmp eq i32 %x , 0
304+ br i1 %cmp1 , label %bb6 , label %bb5
305+
306+ bb6:
307+ %cmp2 = icmp eq i32 %y , 0
308+ br i1 %cmp2 , label %bb2 , label %bb3
309+
310+ bb5:
311+ %cmp3 = icmp ult i32 %x , %y
312+ br i1 %cmp3 , label %bb3 , label %bb2
313+
314+ bb2:
315+ br label %bb3
316+
317+ bb3:
318+ %ret = phi i1 [ true , %bb2 ], [ false , %bb6 ], [ false , %bb5 ]
319+ %ret2 = phi i32 [ %x , %bb2 ], [ %y , %bb6 ], [ %x , %bb5 ]
320+ %ret3 = phi i32 [ %y , %bb2 ], [ %x , %bb6 ], [ %x , %bb5 ]
321+ %ret4 = phi i32 [ 0 , %bb2 ], [ 3 , %bb6 ], [ 5 , %bb5 ]
322+ %add = add i32 %ret2 , %ret3
323+ %add2 = add i32 %add , %ret4
324+ %cmp4 = icmp eq i32 %add2 , 0
325+ %and = and i1 %ret , %cmp4
326+ ret i1 %and
327+ }
0 commit comments