@@ -205,3 +205,174 @@ bb5: ; preds = %bb2, %bb
205205 %i6 = phi i32 [ %i4 , %bb2 ], [ 13 , %bb ]
206206 ret i32 %i6
207207}
208+
209+
210+ ; For switches, the values feeding the phi are always sunk into the
211+ ; target blocks as the IR syntax requires the intermediate block and
212+ ; DAG lowers it in the immediate predecessor of the phi.
213+ define signext i32 @switch_dispatch (i8 %a ) {
214+ ; CHECK-LABEL: switch_dispatch:
215+ ; CHECK: # %bb.0: # %bb
216+ ; CHECK-NEXT: addi sp, sp, -16
217+ ; CHECK-NEXT: .cfi_def_cfa_offset 16
218+ ; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
219+ ; CHECK-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
220+ ; CHECK-NEXT: .cfi_offset ra, -8
221+ ; CHECK-NEXT: .cfi_offset s0, -16
222+ ; CHECK-NEXT: andi a0, a0, 255
223+ ; CHECK-NEXT: li a1, 31
224+ ; CHECK-NEXT: blt a1, a0, .LBB2_5
225+ ; CHECK-NEXT: # %bb.1: # %bb
226+ ; CHECK-NEXT: beqz a0, .LBB2_10
227+ ; CHECK-NEXT: # %bb.2: # %bb
228+ ; CHECK-NEXT: li a1, 12
229+ ; CHECK-NEXT: beq a0, a1, .LBB2_11
230+ ; CHECK-NEXT: # %bb.3: # %bb
231+ ; CHECK-NEXT: li a1, 13
232+ ; CHECK-NEXT: bne a0, a1, .LBB2_9
233+ ; CHECK-NEXT: # %bb.4: # %case.4
234+ ; CHECK-NEXT: li s0, 644
235+ ; CHECK-NEXT: j .LBB2_13
236+ ; CHECK-NEXT: .LBB2_5: # %bb
237+ ; CHECK-NEXT: li a1, 234
238+ ; CHECK-NEXT: beq a0, a1, .LBB2_9
239+ ; CHECK-NEXT: # %bb.6: # %bb
240+ ; CHECK-NEXT: li a1, 70
241+ ; CHECK-NEXT: beq a0, a1, .LBB2_12
242+ ; CHECK-NEXT: # %bb.7: # %bb
243+ ; CHECK-NEXT: li a1, 32
244+ ; CHECK-NEXT: bne a0, a1, .LBB2_9
245+ ; CHECK-NEXT: # %bb.8: # %case.0
246+ ; CHECK-NEXT: li s0, 13
247+ ; CHECK-NEXT: j .LBB2_13
248+ ; CHECK-NEXT: .LBB2_9: # %case.default
249+ ; CHECK-NEXT: li s0, 23
250+ ; CHECK-NEXT: j .LBB2_13
251+ ; CHECK-NEXT: .LBB2_10: # %case.5
252+ ; CHECK-NEXT: li s0, 54
253+ ; CHECK-NEXT: j .LBB2_13
254+ ; CHECK-NEXT: .LBB2_11: # %case.1
255+ ; CHECK-NEXT: li s0, 53
256+ ; CHECK-NEXT: j .LBB2_13
257+ ; CHECK-NEXT: .LBB2_12: # %case.2
258+ ; CHECK-NEXT: li s0, 33
259+ ; CHECK-NEXT: .LBB2_13: # %merge
260+ ; CHECK-NEXT: mv a0, s0
261+ ; CHECK-NEXT: call use
262+ ; CHECK-NEXT: mv a0, s0
263+ ; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
264+ ; CHECK-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
265+ ; CHECK-NEXT: .cfi_restore ra
266+ ; CHECK-NEXT: .cfi_restore s0
267+ ; CHECK-NEXT: addi sp, sp, 16
268+ ; CHECK-NEXT: .cfi_def_cfa_offset 0
269+ ; CHECK-NEXT: ret
270+ bb:
271+ switch i8 %a , label %case.default [
272+ i8 32 , label %case.0
273+ i8 12 , label %case.1
274+ i8 70 , label %case.2
275+ i8 -22 , label %case.3
276+ i8 13 , label %case.4
277+ i8 0 , label %case.5
278+ ]
279+
280+ case.0 :
281+ br label %merge
282+ case.1 :
283+ br label %merge
284+ case.2 :
285+ br label %merge
286+ case.3 :
287+ br label %merge
288+ case.4 :
289+ br label %merge
290+ case.5 :
291+ br label %merge
292+ case.default:
293+ br label %merge
294+
295+ merge:
296+ %res = phi i32 [ 23 , %case.default ], [ 13 , %case.0 ], [ 53 , %case.1 ], [ 33 , %case.2 ], [ 23 , %case.3 ], [ 644 , %case.4 ], [ 54 , %case.5 ]
297+ call void @use (i32 %res )
298+ ret i32 %res
299+ }
300+
301+ ; Same as for the switch, but written via manual branching.
302+ define signext i32 @branch_dispatch (i8 %a ) {
303+ ; CHECK-LABEL: branch_dispatch:
304+ ; CHECK: # %bb.0: # %case.0
305+ ; CHECK-NEXT: addi sp, sp, -16
306+ ; CHECK-NEXT: .cfi_def_cfa_offset 16
307+ ; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
308+ ; CHECK-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
309+ ; CHECK-NEXT: .cfi_offset ra, -8
310+ ; CHECK-NEXT: .cfi_offset s0, -16
311+ ; CHECK-NEXT: andi a0, a0, 255
312+ ; CHECK-NEXT: li a1, 32
313+ ; CHECK-NEXT: li s0, 13
314+ ; CHECK-NEXT: beq a0, a1, .LBB3_8
315+ ; CHECK-NEXT: # %bb.1: # %case.1
316+ ; CHECK-NEXT: li a1, 12
317+ ; CHECK-NEXT: li s0, 53
318+ ; CHECK-NEXT: beq a0, a1, .LBB3_8
319+ ; CHECK-NEXT: # %bb.2: # %case.2
320+ ; CHECK-NEXT: li a1, 70
321+ ; CHECK-NEXT: li s0, 33
322+ ; CHECK-NEXT: beq a0, a1, .LBB3_8
323+ ; CHECK-NEXT: # %bb.3: # %case.3
324+ ; CHECK-NEXT: li a1, 234
325+ ; CHECK-NEXT: li s0, 23
326+ ; CHECK-NEXT: beq a0, a1, .LBB3_8
327+ ; CHECK-NEXT: # %bb.4: # %case.4
328+ ; CHECK-NEXT: beqz a0, .LBB3_7
329+ ; CHECK-NEXT: # %bb.5: # %case.5
330+ ; CHECK-NEXT: li a1, 5
331+ ; CHECK-NEXT: li s0, 54
332+ ; CHECK-NEXT: beq a0, a1, .LBB3_8
333+ ; CHECK-NEXT: # %bb.6: # %case.default
334+ ; CHECK-NEXT: li s0, 23
335+ ; CHECK-NEXT: j .LBB3_8
336+ ; CHECK-NEXT: .LBB3_7:
337+ ; CHECK-NEXT: li s0, 644
338+ ; CHECK-NEXT: .LBB3_8: # %merge
339+ ; CHECK-NEXT: mv a0, s0
340+ ; CHECK-NEXT: call use
341+ ; CHECK-NEXT: mv a0, s0
342+ ; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
343+ ; CHECK-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
344+ ; CHECK-NEXT: .cfi_restore ra
345+ ; CHECK-NEXT: .cfi_restore s0
346+ ; CHECK-NEXT: addi sp, sp, 16
347+ ; CHECK-NEXT: .cfi_def_cfa_offset 0
348+ ; CHECK-NEXT: ret
349+ case.0 :
350+ %c0 = icmp ne i8 %a , 32
351+ br i1 %c0 , label %case.1 , label %merge
352+ case.1 :
353+ %c1 = icmp ne i8 %a , 12
354+ br i1 %c1 , label %case.2 , label %merge
355+ case.2 :
356+ %c2 = icmp ne i8 %a , 70
357+ br i1 %c2 , label %case.3 , label %merge
358+ case.3 :
359+ %c3 = icmp ne i8 %a , -22
360+ br i1 %c3 , label %case.4 , label %merge
361+ case.4 :
362+ %c4 = icmp ne i8 %a , 0
363+ br i1 %c4 , label %case.5 , label %merge
364+ case.5 :
365+ %c5 = icmp ne i8 %a , 5
366+ br i1 %c5 , label %case.default , label %merge
367+ case.default:
368+ br label %merge
369+
370+ merge:
371+ %res = phi i32 [ 23 , %case.default ], [ 13 , %case.0 ], [ 53 , %case.1 ], [ 33 , %case.2 ], [ 23 , %case.3 ], [ 644 , %case.4 ], [ 54 , %case.5 ]
372+ call void @use (i32 %res )
373+ ret i32 %res
374+ }
375+
376+
377+ declare void @use (i32 )
378+
0 commit comments