xref: /llvm-project/llvm/test/CodeGen/X86/switch-jmp-edge-split.mir (revision b8817825b9dcb45f204d3a3a9056f929e12c7a3b)
1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -mtriple=x86_64-- -run-pass=machine-sink -verify-machineinstrs  -o - %s | FileCheck %s
3
4---
5name:            func_no_pic
6tracksRegLiveness: true
7jumpTable:
8  kind:            block-address
9  entries:
10    - id:              0
11      blocks:          [ '%bb.4', '%bb.1', '%bb.2', '%bb.3' ]
12body:             |
13  ; CHECK-LABEL: name: func_no_pic
14  ; CHECK: bb.0:
15  ; CHECK-NEXT:   successors: %bb.5(0x20000000), %bb.1(0x20000000), %bb.2(0x20000000), %bb.3(0x20000000)
16  ; CHECK-NEXT:   liveins: $edi
17  ; CHECK-NEXT: {{  $}}
18  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64_nosp = COPY $rdi
19  ; CHECK-NEXT:   JMP64m $noreg, 8, [[COPY]], %jump-table.0, $noreg :: (load (s64) from jump-table)
20  ; CHECK-NEXT: {{  $}}
21  ; CHECK-NEXT: bb.5:
22  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
23  ; CHECK-NEXT: {{  $}}
24  ; CHECK-NEXT:   [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
25  ; CHECK-NEXT:   JMP_1 %bb.4
26  ; CHECK-NEXT: {{  $}}
27  ; CHECK-NEXT: bb.1:
28  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
29  ; CHECK-NEXT: {{  $}}
30  ; CHECK-NEXT:   [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 6
31  ; CHECK-NEXT:   JMP_1 %bb.4
32  ; CHECK-NEXT: {{  $}}
33  ; CHECK-NEXT: bb.2:
34  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
35  ; CHECK-NEXT: {{  $}}
36  ; CHECK-NEXT:   [[MOV32ri2:%[0-9]+]]:gr32 = MOV32ri 1
37  ; CHECK-NEXT:   JMP_1 %bb.4
38  ; CHECK-NEXT: {{  $}}
39  ; CHECK-NEXT: bb.3:
40  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
41  ; CHECK-NEXT: {{  $}}
42  ; CHECK-NEXT:   [[MOV32ri3:%[0-9]+]]:gr32 = MOV32ri 92
43  ; CHECK-NEXT:   JMP_1 %bb.4
44  ; CHECK-NEXT: {{  $}}
45  ; CHECK-NEXT: bb.4:
46  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gr32 = PHI [[MOV32ri]], %bb.5, [[MOV32ri1]], %bb.1, [[MOV32ri2]], %bb.2, [[MOV32ri3]], %bb.3
47  ; CHECK-NEXT:   $eax = COPY [[PHI]]
48  ; CHECK-NEXT:   RET 0
49  bb.0:
50    successors: %bb.4, %bb.1, %bb.2, %bb.3
51    liveins: $edi
52
53    %0:gr64_nosp = COPY $rdi
54    ; MachineSink should split the critical edges and sink the next two
55    ; insns out of the switch-jump header into new less frequently executed
56    ; blocks.
57    %1:gr32 = MOV32ri 42
58    JMP64m $noreg, 8, %0, %jump-table.0, $noreg :: (load (s64) from jump-table)
59
60  bb.1:
61    %2:gr32 = MOV32ri 6
62    JMP_1 %bb.4
63
64  bb.2:
65    %3:gr32 = MOV32ri 1
66    JMP_1 %bb.4
67
68  bb.3:
69    %4:gr32 = MOV32ri 92
70    JMP_1 %bb.4
71
72  bb.4:
73    %5:gr32 = PHI %1, %bb.0, %2, %bb.1, %3, %bb.2, %4, %bb.3
74    $eax = COPY %5
75    RET 0
76
77...
78---
79name:            func_pic
80tracksRegLiveness: true
81jumpTable:
82  kind:            label-difference32
83  entries:
84    - id:              0
85      blocks:          [ '%bb.4', '%bb.1', '%bb.2', '%bb.3' ]
86body:             |
87  ; CHECK-LABEL: name: func_pic
88  ; CHECK: bb.0:
89  ; CHECK-NEXT:   successors: %bb.5(0x20000000), %bb.1(0x20000000), %bb.2(0x20000000), %bb.3(0x20000000)
90  ; CHECK-NEXT:   liveins: $edi
91  ; CHECK-NEXT: {{  $}}
92  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64_nosp = COPY $rdi
93  ; CHECK-NEXT:   [[LEA64r:%[0-9]+]]:gr64 = LEA64r $rip, 1, $noreg, %jump-table.0, $noreg
94  ; CHECK-NEXT:   [[MOVSX64rm32_:%[0-9]+]]:gr64 = MOVSX64rm32 [[LEA64r]], 4, [[COPY]], 0, $noreg :: (load (s32) from jump-table)
95  ; CHECK-NEXT:   [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[MOVSX64rm32_]], [[LEA64r]], implicit-def dead $eflags
96  ; CHECK-NEXT:   JMP64r killed [[ADD64rr]]
97  ; CHECK-NEXT: {{  $}}
98  ; CHECK-NEXT: bb.5:
99  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
100  ; CHECK-NEXT: {{  $}}
101  ; CHECK-NEXT:   [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
102  ; CHECK-NEXT:   JMP_1 %bb.4
103  ; CHECK-NEXT: {{  $}}
104  ; CHECK-NEXT: bb.1:
105  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
106  ; CHECK-NEXT: {{  $}}
107  ; CHECK-NEXT:   [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 6
108  ; CHECK-NEXT:   JMP_1 %bb.4
109  ; CHECK-NEXT: {{  $}}
110  ; CHECK-NEXT: bb.2:
111  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
112  ; CHECK-NEXT: {{  $}}
113  ; CHECK-NEXT:   [[MOV32ri2:%[0-9]+]]:gr32 = MOV32ri 1
114  ; CHECK-NEXT:   JMP_1 %bb.4
115  ; CHECK-NEXT: {{  $}}
116  ; CHECK-NEXT: bb.3:
117  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
118  ; CHECK-NEXT: {{  $}}
119  ; CHECK-NEXT:   [[MOV32ri3:%[0-9]+]]:gr32 = MOV32ri 92
120  ; CHECK-NEXT:   JMP_1 %bb.4
121  ; CHECK-NEXT: {{  $}}
122  ; CHECK-NEXT: bb.4:
123  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gr32 = PHI [[MOV32ri]], %bb.5, [[MOV32ri1]], %bb.1, [[MOV32ri2]], %bb.2, [[MOV32ri3]], %bb.3
124  ; CHECK-NEXT:   $eax = COPY [[PHI]]
125  ; CHECK-NEXT:   RET 0
126  bb.0:
127    successors: %bb.4, %bb.1, %bb.2, %bb.3
128    liveins: $edi
129
130    %0:gr64_nosp = COPY $rdi
131    ; MachineSink should split the critical edges and sink the next two
132    ; insns out of the switch-jump header into new less frequently executed
133    ; blocks.
134    %1:gr32 = MOV32ri 42
135    %2:gr64 = LEA64r $rip, 1, $noreg, %jump-table.0, $noreg
136    %3:gr64 = MOVSX64rm32 %2, 4, %0, 0, $noreg :: (load (s32) from jump-table)
137    %4:gr64 = ADD64rr %3, %2, implicit-def dead $eflags
138    JMP64r killed %4
139
140  bb.1:
141    %5:gr32 = MOV32ri 6
142    JMP_1 %bb.4
143
144  bb.2:
145    %6:gr32 = MOV32ri 1
146    JMP_1 %bb.4
147
148  bb.3:
149    %7:gr32 = MOV32ri 92
150    JMP_1 %bb.4
151
152  bb.4:
153    %8:gr32 = PHI %1, %bb.0, %5, %bb.1, %6, %bb.2, %7, %bb.3
154    $eax = COPY %8
155    RET 0
156
157...
158---
159name:            multiple_jump_table_users
160tracksRegLiveness: true
161jumpTable:
162  kind:            block-address
163  entries:
164    - id:              0
165      blocks:          [ '%bb.6', '%bb.3', '%bb.4', '%bb.5' ]
166body:             |
167  ; CHECK-LABEL: name: multiple_jump_table_users
168  ; CHECK: bb.0:
169  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
170  ; CHECK-NEXT:   liveins: $edi
171  ; CHECK-NEXT: {{  $}}
172  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64_nosp = COPY $rdi
173  ; CHECK-NEXT:   CMP64ri8 [[COPY]], 42, implicit-def $eflags
174  ; CHECK-NEXT:   JCC_1 %bb.1, 15, implicit $eflags
175  ; CHECK-NEXT:   JMP_1 %bb.2
176  ; CHECK-NEXT: {{  $}}
177  ; CHECK-NEXT: bb.1:
178  ; CHECK-NEXT:   successors: %bb.6(0x20000000), %bb.3(0x20000000), %bb.4(0x20000000), %bb.5(0x20000000)
179  ; CHECK-NEXT: {{  $}}
180  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */
181  ; CHECK-NEXT:   [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 13
182  ; CHECK-NEXT:   JMP64m $noreg, 8, [[COPY]], %jump-table.0, $noreg :: (load (s64) from jump-table)
183  ; CHECK-NEXT: {{  $}}
184  ; CHECK-NEXT: bb.2:
185  ; CHECK-NEXT:   successors: %bb.6(0x20000000), %bb.3(0x20000000), %bb.4(0x20000000), %bb.5(0x20000000)
186  ; CHECK-NEXT: {{  $}}
187  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */
188  ; CHECK-NEXT:   [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 42
189  ; CHECK-NEXT:   JMP64m $noreg, 8, [[COPY]], %jump-table.0, $noreg :: (load (s64) from jump-table)
190  ; CHECK-NEXT: {{  $}}
191  ; CHECK-NEXT: bb.3:
192  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
193  ; CHECK-NEXT: {{  $}}
194  ; CHECK-NEXT:   [[MOV32ri2:%[0-9]+]]:gr32 = MOV32ri 6
195  ; CHECK-NEXT:   JMP_1 %bb.6
196  ; CHECK-NEXT: {{  $}}
197  ; CHECK-NEXT: bb.4:
198  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
199  ; CHECK-NEXT: {{  $}}
200  ; CHECK-NEXT:   [[MOV32ri3:%[0-9]+]]:gr32 = MOV32ri 1
201  ; CHECK-NEXT:   JMP_1 %bb.6
202  ; CHECK-NEXT: {{  $}}
203  ; CHECK-NEXT: bb.5:
204  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
205  ; CHECK-NEXT: {{  $}}
206  ; CHECK-NEXT:   [[MOV32ri4:%[0-9]+]]:gr32 = MOV32ri 92
207  ; CHECK-NEXT:   JMP_1 %bb.6
208  ; CHECK-NEXT: {{  $}}
209  ; CHECK-NEXT: bb.6:
210  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gr32 = PHI [[MOV32ri]], %bb.1, [[MOV32ri1]], %bb.2, [[MOV32ri2]], %bb.3, [[MOV32ri3]], %bb.4, [[MOV32ri4]], %bb.5
211  ; CHECK-NEXT:   $eax = COPY [[PHI]]
212  ; CHECK-NEXT:   RET 0
213  bb.0:
214    liveins: $edi
215    %0:gr64_nosp = COPY $rdi
216
217    CMP64ri8 %0:gr64_nosp, 42, implicit-def $eflags
218    JCC_1 %bb.1, 15, implicit $eflags
219    JMP_1 %bb.2
220
221  bb.1:
222    successors: %bb.6, %bb.3, %bb.4, %bb.5
223    INLINEASM &"", 1 /* sideeffect attdialect */
224    %1:gr32 = MOV32ri 13
225    JMP64m $noreg, 8, %0, %jump-table.0, $noreg :: (load (s64) from jump-table)
226
227  bb.2:
228    successors: %bb.6, %bb.3, %bb.4, %bb.5
229    INLINEASM &"", 1 /* sideeffect attdialect */
230    %2:gr32 = MOV32ri 42
231    ; This is a 2d user of jump-table.0 . This case is not supported yet;
232    ; Should not attempt edge splitting.
233    JMP64m $noreg, 8, %0, %jump-table.0, $noreg :: (load (s64) from jump-table)
234
235  bb.3:
236    %3:gr32 = MOV32ri 6
237    JMP_1 %bb.6
238
239  bb.4:
240    %4:gr32 = MOV32ri 1
241    JMP_1 %bb.6
242
243  bb.5:
244    %5:gr32 = MOV32ri 92
245    JMP_1 %bb.6
246
247  bb.6:
248    %6:gr32 = PHI %1, %bb.1, %2, %bb.2, %3, %bb.3, %4, %bb.4, %5, %bb.5
249    $eax = COPY %6
250    RET 0
251...
252