@@ -205,3 +205,174 @@ bb5: ; preds = %bb2, %bb
205
205
%i6 = phi i32 [ %i4 , %bb2 ], [ 13 , %bb ]
206
206
ret i32 %i6
207
207
}
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