xref: /llvm-project/llvm/test/CodeGen/X86/peephole-test-after-add.mir (revision 2d6a5ab5ebd4907fe3bb2ee67574fd672ad80bd8)
1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -o - %s -mtriple=x86_64-unknown-linux-gnu --run-pass=peephole-opt | FileCheck %s
3
4# Test that TEST64rr is erased in `test_erased`, and kept in `test_not_erased_when_sf_used`
5# and `test_not_erased_when_eflags_change`.
6
7--- |
8  ; ModuleID = 'tmp.ll'
9  source_filename = "tmp.ll"
10  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
11
12  define i64 @test_erased(ptr %0, i64 %1, i64 %2) {
13    %4 = load i64, ptr %0, align 8
14    %5 = and i64 %4, 3
15    %6 = icmp eq i64 %5, 0
16    %7 = select i1 %6, i64 %1, i64 %5
17    store i64 %7, ptr %0, align 8
18    ret i64 %5
19  }
20
21  define i64 @test_not_erased_when_sf_used(ptr %0, i64 %1, i64 %2, i64 %3) {
22    %5 = load i64, ptr %0, align 8
23    %6 = and i64 %5, 3
24    %7 = icmp slt i64 %6, 0
25    %8 = select i1 %7, i64 %1, i64 %6
26    store i64 %8, ptr %0, align 8
27    ret i64 %5
28  }
29
30  define void @test_not_erased_when_eflags_change(ptr %0, i64 %1, i64 %2, i64 %3, ptr %4) {
31    %6 = load i64, ptr %0, align 8
32    %7 = and i64 %6, 3
33    %8 = xor i64 %3, 5
34    %9 = icmp eq i64 %7, 0
35    %10 = select i1 %9, i64 %1, i64 %7
36    store i64 %10, ptr %0, align 8
37    store i64 %8, ptr %4, align 8
38    ret void
39  }
40
41  define i16 @erase_test16(i16 %0, i16 %1, ptr nocapture %2) {
42  entry:
43    %3 = icmp ne i16 %0, 0
44    %4 = and i16 %1, 123
45    %5 = icmp eq i16 %4, 0
46    %6 = select i1 %3, i1 %5, i1 false
47    br i1 %6, label %if.then, label %if.end
48
49  if.then:                                          ; preds = %entry
50    store i16 %0, ptr %2, align 4
51    br label %if.end
52
53  if.end:                                           ; preds = %if.then, %entry
54    ret i16 0
55  }
56
57  define i16 @erase_test16_bigimm(i16 %0, i32 %1, ptr nocapture %2) {
58  entry:
59    %3 = icmp ne i16 %0, 0
60    %4 = and i32 %1, 123456
61    %trunc = trunc i32 %4 to i16
62    %5 = icmp eq i16 %trunc, 0
63    %6 = select i1 %3, i1 %5, i1 false
64    br i1 %6, label %if.then, label %if.end
65
66  if.then:                                          ; preds = %entry
67    store i32 %4, ptr %2, align 4
68    br label %if.end
69
70  if.end:                                           ; preds = %if.then, %entry
71    ret i16 0
72  }
73
74  define i16 @erase_test16_sf(i16 %0, i16 %1, ptr nocapture %2) {
75  entry:
76    %3 = icmp ne i16 %0, 0
77    %4 = and i16 %1, 1234
78    %5 = icmp slt i16 %4, 0
79    %6 = select i1 %3, i1 %5, i1 false
80    br i1 %6, label %if.then, label %if.end
81
82  if.then:                                          ; preds = %entry
83    store i16 %4, ptr %2, align 4
84    br label %if.end
85
86  if.end:                                           ; preds = %if.then, %entry
87    ret i16 0
88  }
89...
90---
91name:            test_erased
92alignment:       16
93tracksDebugUserValues: false
94registers:
95  - { id: 0, class: gr64, preferred-register: '' }
96  - { id: 1, class: gr64, preferred-register: '' }
97  - { id: 2, class: gr64, preferred-register: '' }
98  - { id: 3, class: gr64, preferred-register: '' }
99  - { id: 4, class: gr32, preferred-register: '' }
100  - { id: 5, class: gr32, preferred-register: '' }
101  - { id: 6, class: gr64, preferred-register: '' }
102  - { id: 7, class: gr64, preferred-register: '' }
103liveins:
104  - { reg: '$rdi', virtual-reg: '%0' }
105  - { reg: '$rsi', virtual-reg: '%1' }
106frameInfo:
107  maxAlignment:    1
108machineFunctionInfo: {}
109body:             |
110  bb.0 (%ir-block.3):
111    liveins: $rdi, $rsi
112
113    ; CHECK-LABEL: name: test_erased
114    ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
115    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi
116    ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY1]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.0)
117    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[MOV64rm]].sub_32bit
118    ; CHECK-NEXT: [[AND32ri8_:%[0-9]+]]:gr32 = AND32ri8 [[COPY2]], 3, implicit-def $eflags
119    ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[AND32ri8_]], %subreg.sub_32bit
120    ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[SUBREG_TO_REG]], [[COPY]], 4, implicit $eflags
121    ; CHECK-NEXT: MOV64mr [[COPY1]], 1, $noreg, 0, $noreg, killed [[CMOV64rr]] :: (store (s64) into %ir.0)
122    ; CHECK-NEXT: $rax = COPY [[SUBREG_TO_REG]]
123    ; CHECK-NEXT: RET 0, $rax
124    %1:gr64 = COPY $rsi
125    %0:gr64 = COPY $rdi
126    %3:gr64 = MOV64rm %0, 1, $noreg, 0, $noreg :: (load (s64) from %ir.0)
127    %4:gr32 = COPY %3.sub_32bit
128    %5:gr32 = AND32ri8 %4, 3, implicit-def dead $eflags
129    %6:gr64 = SUBREG_TO_REG 0, killed %5, %subreg.sub_32bit
130    TEST64rr %6, %6, implicit-def $eflags
131    %7:gr64 = CMOV64rr %6, %1, 4, implicit $eflags
132    MOV64mr %0, 1, $noreg, 0, $noreg, killed %7 :: (store (s64) into %ir.0)
133    $rax = COPY %6
134    RET 0, $rax
135
136...
137---
138name:            test_not_erased_when_sf_used
139alignment:       16
140tracksDebugUserValues: false
141registers:
142  - { id: 0, class: gr64, preferred-register: '' }
143  - { id: 1, class: gr64, preferred-register: '' }
144  - { id: 2, class: gr64, preferred-register: '' }
145  - { id: 3, class: gr64, preferred-register: '' }
146  - { id: 4, class: gr64, preferred-register: '' }
147  - { id: 5, class: gr32, preferred-register: '' }
148  - { id: 6, class: gr32, preferred-register: '' }
149  - { id: 7, class: gr64, preferred-register: '' }
150  - { id: 8, class: gr64, preferred-register: '' }
151liveins:
152  - { reg: '$rdi', virtual-reg: '%0' }
153  - { reg: '$rsi', virtual-reg: '%1' }
154frameInfo:
155  maxAlignment:    1
156machineFunctionInfo: {}
157body:             |
158  bb.0 (%ir-block.4):
159    liveins: $rdi, $rsi
160
161    ; CHECK-LABEL: name: test_not_erased_when_sf_used
162    ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
163    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi
164    ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY1]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.0)
165    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[MOV64rm]].sub_32bit
166    ; CHECK-NEXT: [[AND32ri8_:%[0-9]+]]:gr32 = AND32ri8 [[COPY2]], 3, implicit-def dead $eflags
167    ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[AND32ri8_]], %subreg.sub_32bit
168    ; CHECK-NEXT: TEST64rr [[SUBREG_TO_REG]], [[SUBREG_TO_REG]], implicit-def $eflags
169    ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[SUBREG_TO_REG]], [[COPY]], 8, implicit $eflags
170    ; CHECK-NEXT: MOV64mr [[COPY1]], 1, $noreg, 0, $noreg, killed [[CMOV64rr]] :: (store (s64) into %ir.0)
171    ; CHECK-NEXT: $rax = COPY [[MOV64rm]]
172    ; CHECK-NEXT: RET 0, $rax
173    %1:gr64 = COPY $rsi
174    %0:gr64 = COPY $rdi
175    %4:gr64 = MOV64rm %0, 1, $noreg, 0, $noreg :: (load (s64) from %ir.0)
176    %5:gr32 = COPY %4.sub_32bit
177    %6:gr32 = AND32ri8 %5, 3, implicit-def dead $eflags
178    %7:gr64 = SUBREG_TO_REG 0, killed %6, %subreg.sub_32bit
179    TEST64rr %7, %7, implicit-def $eflags
180    %8:gr64 = CMOV64rr %7, %1, 8, implicit $eflags
181    MOV64mr %0, 1, $noreg, 0, $noreg, killed %8 :: (store (s64) into %ir.0)
182    $rax = COPY %4
183    RET 0, $rax
184
185...
186---
187name:            test_not_erased_when_eflags_change
188alignment:       16
189tracksDebugUserValues: false
190registers:
191  - { id: 0, class: gr64, preferred-register: '' }
192  - { id: 1, class: gr64, preferred-register: '' }
193  - { id: 2, class: gr64, preferred-register: '' }
194  - { id: 3, class: gr64, preferred-register: '' }
195  - { id: 4, class: gr64, preferred-register: '' }
196  - { id: 5, class: gr64, preferred-register: '' }
197  - { id: 6, class: gr32, preferred-register: '' }
198  - { id: 7, class: gr32, preferred-register: '' }
199  - { id: 8, class: gr64, preferred-register: '' }
200  - { id: 9, class: gr64, preferred-register: '' }
201  - { id: 10, class: gr64, preferred-register: '' }
202liveins:
203  - { reg: '$rdi', virtual-reg: '%0' }
204  - { reg: '$rsi', virtual-reg: '%1' }
205  - { reg: '$rcx', virtual-reg: '%3' }
206  - { reg: '$r8', virtual-reg: '%4' }
207frameInfo:
208  maxAlignment:    1
209machineFunctionInfo: {}
210body:             |
211  bb.0 (%ir-block.5):
212    liveins: $rdi, $rsi, $rcx, $r8
213
214    ; CHECK-LABEL: name: test_not_erased_when_eflags_change
215    ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $r8
216    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rcx
217    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY $rsi
218    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr64 = COPY $rdi
219    ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY3]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.0)
220    ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr32 = COPY [[MOV64rm]].sub_32bit
221    ; CHECK-NEXT: [[AND32ri8_:%[0-9]+]]:gr32 = AND32ri8 [[COPY4]], 3, implicit-def dead $eflags
222    ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[AND32ri8_]], %subreg.sub_32bit
223    ; CHECK-NEXT: [[XOR64ri8_:%[0-9]+]]:gr64 = XOR64ri8 [[COPY1]], 5, implicit-def dead $eflags
224    ; CHECK-NEXT: TEST64rr [[SUBREG_TO_REG]], [[SUBREG_TO_REG]], implicit-def $eflags
225    ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[SUBREG_TO_REG]], [[COPY2]], 4, implicit $eflags
226    ; CHECK-NEXT: MOV64mr [[COPY3]], 1, $noreg, 0, $noreg, killed [[CMOV64rr]] :: (store (s64) into %ir.0)
227    ; CHECK-NEXT: MOV64mr [[COPY]], 1, $noreg, 0, $noreg, killed [[XOR64ri8_]] :: (store (s64) into %ir.4)
228    ; CHECK-NEXT: RET 0
229    %4:gr64 = COPY $r8
230    %3:gr64 = COPY $rcx
231    %1:gr64 = COPY $rsi
232    %0:gr64 = COPY $rdi
233    %5:gr64 = MOV64rm %0, 1, $noreg, 0, $noreg :: (load (s64) from %ir.0)
234    %6:gr32 = COPY %5.sub_32bit
235    %7:gr32 = AND32ri8 %6, 3, implicit-def dead $eflags
236    %8:gr64 = SUBREG_TO_REG 0, killed %7, %subreg.sub_32bit
237    %9:gr64 = XOR64ri8 %3, 5, implicit-def dead $eflags
238    TEST64rr %8, %8, implicit-def $eflags
239    %10:gr64 = CMOV64rr %8, %1, 4, implicit $eflags
240    MOV64mr %0, 1, $noreg, 0, $noreg, killed %10 :: (store (s64) into %ir.0)
241    MOV64mr %4, 1, $noreg, 0, $noreg, killed %9 :: (store (s64) into %ir.4)
242    RET 0
243
244...
245---
246name:            erase_test16
247alignment:       16
248exposesReturnsTwice: false
249legalized:       false
250regBankSelected: false
251selected:        false
252failedISel:      false
253tracksRegLiveness: true
254hasWinCFI:       false
255callsEHReturn:   false
256callsUnwindInit: false
257hasEHCatchret:   false
258hasEHScopes:     false
259hasEHFunclets:   false
260isOutlined:      false
261debugInstrRef:   true
262failsVerification: false
263tracksDebugUserValues: false
264registers:
265  - { id: 0, class: gr32, preferred-register: '' }
266  - { id: 1, class: gr32, preferred-register: '' }
267  - { id: 2, class: gr64, preferred-register: '' }
268  - { id: 3, class: gr16, preferred-register: '' }
269  - { id: 4, class: gr16, preferred-register: '' }
270  - { id: 5, class: gr32, preferred-register: '' }
271  - { id: 6, class: gr32, preferred-register: '' }
272  - { id: 7, class: gr16, preferred-register: '' }
273liveins:
274  - { reg: '$edi', virtual-reg: '%0' }
275  - { reg: '$esi', virtual-reg: '%1' }
276  - { reg: '$rdx', virtual-reg: '%2' }
277frameInfo:
278  isFrameAddressTaken: false
279  isReturnAddressTaken: false
280  hasStackMap:     false
281  hasPatchPoint:   false
282  stackSize:       0
283  offsetAdjustment: 0
284  maxAlignment:    1
285  adjustsStack:    false
286  hasCalls:        false
287  stackProtector:  ''
288  functionContext: ''
289  maxCallFrameSize: 4294967295
290  cvBytesOfCalleeSavedRegisters: 0
291  hasOpaqueSPAdjustment: false
292  hasVAStart:      false
293  hasMustTailInVarArgFunc: false
294  hasTailCall:     false
295  localFrameSize:  0
296  savePoint:       ''
297  restorePoint:    ''
298fixedStack:      []
299stack:           []
300entry_values:    []
301callSites:       []
302debugValueSubstitutions: []
303constants:       []
304machineFunctionInfo: {}
305body:             |
306  ; CHECK-LABEL: name: erase_test16
307  ; CHECK: bb.0.entry:
308  ; CHECK-NEXT:   successors: %bb.1(0x60000000), %bb.3(0x20000000)
309  ; CHECK-NEXT:   liveins: $edi, $esi, $rdx
310  ; CHECK-NEXT: {{  $}}
311  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64 = COPY $rdx
312  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY $esi
313  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gr32 = COPY $edi
314  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit
315  ; CHECK-NEXT:   TEST16rr [[COPY3]], [[COPY3]], implicit-def $eflags
316  ; CHECK-NEXT:   JCC_1 %bb.3, 4, implicit $eflags
317  ; CHECK-NEXT:   JMP_1 %bb.1
318  ; CHECK-NEXT: {{  $}}
319  ; CHECK-NEXT: bb.1.entry:
320  ; CHECK-NEXT:   successors: %bb.2(0x55555555), %bb.3(0x2aaaaaab)
321  ; CHECK-NEXT: {{  $}}
322  ; CHECK-NEXT:   [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY1]], 123, implicit-def $eflags
323  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gr16 = COPY [[AND32ri]].sub_16bit
324  ; CHECK-NEXT:   JCC_1 %bb.3, 5, implicit $eflags
325  ; CHECK-NEXT:   JMP_1 %bb.2
326  ; CHECK-NEXT: {{  $}}
327  ; CHECK-NEXT: bb.2.if.then:
328  ; CHECK-NEXT:   successors: %bb.3(0x80000000)
329  ; CHECK-NEXT: {{  $}}
330  ; CHECK-NEXT:   MOV16mr [[COPY]], 1, $noreg, 0, $noreg, [[COPY3]] :: (store (s16) into %ir.2, align 4)
331  ; CHECK-NEXT: {{  $}}
332  ; CHECK-NEXT: bb.3.if.end:
333  ; CHECK-NEXT:   [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
334  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gr16 = COPY [[MOV32r0_]].sub_16bit
335  ; CHECK-NEXT:   $ax = COPY [[COPY5]]
336  ; CHECK-NEXT:   RET 0, $ax
337  bb.0.entry:
338    successors: %bb.3(0x60000000), %bb.2(0x20000000)
339    liveins: $edi, $esi, $rdx
340
341    %2:gr64 = COPY $rdx
342    %1:gr32 = COPY $esi
343    %0:gr32 = COPY $edi
344    %3:gr16 = COPY %0.sub_16bit
345    TEST16rr %3, %3, implicit-def $eflags
346    JCC_1 %bb.2, 4, implicit $eflags
347    JMP_1 %bb.3
348
349  bb.3.entry:
350    successors: %bb.1(0x55555555), %bb.2(0x2aaaaaab)
351
352    %5:gr32 = AND32ri %1, 123, implicit-def dead $eflags
353    %4:gr16 = COPY %5.sub_16bit
354    TEST16rr %4, %4, implicit-def $eflags
355    JCC_1 %bb.2, 5, implicit $eflags
356    JMP_1 %bb.1
357
358  bb.1.if.then:
359    successors: %bb.2(0x80000000)
360
361    MOV16mr %2, 1, $noreg, 0, $noreg, %3 :: (store (s16) into %ir.2, align 4)
362
363  bb.2.if.end:
364    %6:gr32 = MOV32r0 implicit-def dead $eflags
365    %7:gr16 = COPY %6.sub_16bit
366    $ax = COPY %7
367    RET 0, $ax
368
369...
370---
371name:            erase_test16_bigimm
372alignment:       16
373exposesReturnsTwice: false
374legalized:       false
375regBankSelected: false
376selected:        false
377failedISel:      false
378tracksRegLiveness: true
379hasWinCFI:       false
380callsEHReturn:   false
381callsUnwindInit: false
382hasEHCatchret:   false
383hasEHScopes:     false
384hasEHFunclets:   false
385isOutlined:      false
386debugInstrRef:   true
387failsVerification: false
388tracksDebugUserValues: false
389registers:
390  - { id: 0, class: gr32, preferred-register: '' }
391  - { id: 1, class: gr32, preferred-register: '' }
392  - { id: 2, class: gr32, preferred-register: '' }
393  - { id: 3, class: gr64, preferred-register: '' }
394  - { id: 4, class: gr16, preferred-register: '' }
395  - { id: 5, class: gr16, preferred-register: '' }
396  - { id: 6, class: gr32, preferred-register: '' }
397  - { id: 7, class: gr16, preferred-register: '' }
398liveins:
399  - { reg: '$edi', virtual-reg: '%1' }
400  - { reg: '$esi', virtual-reg: '%2' }
401  - { reg: '$rdx', virtual-reg: '%3' }
402frameInfo:
403  isFrameAddressTaken: false
404  isReturnAddressTaken: false
405  hasStackMap:     false
406  hasPatchPoint:   false
407  stackSize:       0
408  offsetAdjustment: 0
409  maxAlignment:    1
410  adjustsStack:    false
411  hasCalls:        false
412  stackProtector:  ''
413  functionContext: ''
414  maxCallFrameSize: 4294967295
415  cvBytesOfCalleeSavedRegisters: 0
416  hasOpaqueSPAdjustment: false
417  hasVAStart:      false
418  hasMustTailInVarArgFunc: false
419  hasTailCall:     false
420  localFrameSize:  0
421  savePoint:       ''
422  restorePoint:    ''
423fixedStack:      []
424stack:           []
425entry_values:    []
426callSites:       []
427debugValueSubstitutions: []
428constants:       []
429machineFunctionInfo: {}
430body:             |
431  ; CHECK-LABEL: name: erase_test16_bigimm
432  ; CHECK: bb.0.entry:
433  ; CHECK-NEXT:   successors: %bb.1(0x60000000), %bb.3(0x20000000)
434  ; CHECK-NEXT:   liveins: $edi, $esi, $rdx
435  ; CHECK-NEXT: {{  $}}
436  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64 = COPY $rdx
437  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY $esi
438  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gr32 = COPY $edi
439  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit
440  ; CHECK-NEXT:   TEST16rr [[COPY3]], [[COPY3]], implicit-def $eflags
441  ; CHECK-NEXT:   JCC_1 %bb.3, 4, implicit $eflags
442  ; CHECK-NEXT:   JMP_1 %bb.1
443  ; CHECK-NEXT: {{  $}}
444  ; CHECK-NEXT: bb.1.entry:
445  ; CHECK-NEXT:   successors: %bb.2(0x55555555), %bb.3(0x2aaaaaab)
446  ; CHECK-NEXT: {{  $}}
447  ; CHECK-NEXT:   [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY1]], 123456, implicit-def dead $eflags
448  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gr16 = COPY [[AND32ri]].sub_16bit
449  ; CHECK-NEXT:   TEST16rr [[COPY4]], [[COPY4]], implicit-def $eflags
450  ; CHECK-NEXT:   JCC_1 %bb.3, 5, implicit $eflags
451  ; CHECK-NEXT:   JMP_1 %bb.2
452  ; CHECK-NEXT: {{  $}}
453  ; CHECK-NEXT: bb.2.if.then:
454  ; CHECK-NEXT:   successors: %bb.3(0x80000000)
455  ; CHECK-NEXT: {{  $}}
456  ; CHECK-NEXT:   MOV32mr [[COPY]], 1, $noreg, 0, $noreg, [[AND32ri]] :: (store (s32) into %ir.2)
457  ; CHECK-NEXT: {{  $}}
458  ; CHECK-NEXT: bb.3.if.end:
459  ; CHECK-NEXT:   [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
460  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gr16 = COPY [[MOV32r0_]].sub_16bit
461  ; CHECK-NEXT:   $ax = COPY [[COPY5]]
462  ; CHECK-NEXT:   RET 0, $ax
463  bb.0.entry:
464    successors: %bb.3(0x60000000), %bb.2(0x20000000)
465    liveins: $edi, $esi, $rdx
466
467    %3:gr64 = COPY $rdx
468    %2:gr32 = COPY $esi
469    %1:gr32 = COPY $edi
470    %5:gr16 = COPY %1.sub_16bit
471    TEST16rr %5, %5, implicit-def $eflags
472    JCC_1 %bb.2, 4, implicit $eflags
473    JMP_1 %bb.3
474
475  bb.3.entry:
476    successors: %bb.1(0x55555555), %bb.2(0x2aaaaaab)
477
478    %0:gr32 = AND32ri %2, 123456, implicit-def dead $eflags
479    %4:gr16 = COPY %0.sub_16bit
480    TEST16rr %4, %4, implicit-def $eflags
481    JCC_1 %bb.2, 5, implicit $eflags
482    JMP_1 %bb.1
483
484  bb.1.if.then:
485    successors: %bb.2(0x80000000)
486
487    MOV32mr %3, 1, $noreg, 0, $noreg, %0 :: (store (s32) into %ir.2)
488
489  bb.2.if.end:
490    %6:gr32 = MOV32r0 implicit-def dead $eflags
491    %7:gr16 = COPY %6.sub_16bit
492    $ax = COPY %7
493    RET 0, $ax
494
495...
496---
497name:            erase_test16_sf
498alignment:       16
499exposesReturnsTwice: false
500legalized:       false
501regBankSelected: false
502selected:        false
503failedISel:      false
504tracksRegLiveness: true
505hasWinCFI:       false
506callsEHReturn:   false
507callsUnwindInit: false
508hasEHCatchret:   false
509hasEHScopes:     false
510hasEHFunclets:   false
511isOutlined:      false
512debugInstrRef:   true
513failsVerification: false
514tracksDebugUserValues: false
515registers:
516  - { id: 0, class: gr16, preferred-register: '' }
517  - { id: 1, class: gr32, preferred-register: '' }
518  - { id: 2, class: gr32, preferred-register: '' }
519  - { id: 3, class: gr64, preferred-register: '' }
520  - { id: 4, class: gr16, preferred-register: '' }
521  - { id: 5, class: gr32, preferred-register: '' }
522  - { id: 6, class: gr32, preferred-register: '' }
523  - { id: 7, class: gr16, preferred-register: '' }
524liveins:
525  - { reg: '$edi', virtual-reg: '%1' }
526  - { reg: '$esi', virtual-reg: '%2' }
527  - { reg: '$rdx', virtual-reg: '%3' }
528frameInfo:
529  isFrameAddressTaken: false
530  isReturnAddressTaken: false
531  hasStackMap:     false
532  hasPatchPoint:   false
533  stackSize:       0
534  offsetAdjustment: 0
535  maxAlignment:    1
536  adjustsStack:    false
537  hasCalls:        false
538  stackProtector:  ''
539  functionContext: ''
540  maxCallFrameSize: 4294967295
541  cvBytesOfCalleeSavedRegisters: 0
542  hasOpaqueSPAdjustment: false
543  hasVAStart:      false
544  hasMustTailInVarArgFunc: false
545  hasTailCall:     false
546  localFrameSize:  0
547  savePoint:       ''
548  restorePoint:    ''
549fixedStack:      []
550stack:           []
551entry_values:    []
552callSites:       []
553debugValueSubstitutions: []
554constants:       []
555machineFunctionInfo: {}
556body:             |
557  ; CHECK-LABEL: name: erase_test16_sf
558  ; CHECK: bb.0.entry:
559  ; CHECK-NEXT:   successors: %bb.1(0x60000000), %bb.3(0x20000000)
560  ; CHECK-NEXT:   liveins: $edi, $esi, $rdx
561  ; CHECK-NEXT: {{  $}}
562  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64 = COPY $rdx
563  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY $esi
564  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gr32 = COPY $edi
565  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit
566  ; CHECK-NEXT:   TEST16rr [[COPY3]], [[COPY3]], implicit-def $eflags
567  ; CHECK-NEXT:   JCC_1 %bb.3, 4, implicit $eflags
568  ; CHECK-NEXT:   JMP_1 %bb.1
569  ; CHECK-NEXT: {{  $}}
570  ; CHECK-NEXT: bb.1.entry:
571  ; CHECK-NEXT:   successors: %bb.2(0x55555555), %bb.3(0x2aaaaaab)
572  ; CHECK-NEXT: {{  $}}
573  ; CHECK-NEXT:   [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY1]], 1234, implicit-def dead $eflags
574  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gr16 = COPY [[AND32ri]].sub_16bit
575  ; CHECK-NEXT:   TEST16rr [[COPY4]], [[COPY4]], implicit-def $eflags
576  ; CHECK-NEXT:   JCC_1 %bb.3, 9, implicit $eflags
577  ; CHECK-NEXT:   JMP_1 %bb.2
578  ; CHECK-NEXT: {{  $}}
579  ; CHECK-NEXT: bb.2.if.then:
580  ; CHECK-NEXT:   successors: %bb.3(0x80000000)
581  ; CHECK-NEXT: {{  $}}
582  ; CHECK-NEXT:   MOV16mr [[COPY]], 1, $noreg, 0, $noreg, [[COPY4]] :: (store (s16) into %ir.2, align 4)
583  ; CHECK-NEXT: {{  $}}
584  ; CHECK-NEXT: bb.3.if.end:
585  ; CHECK-NEXT:   [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
586  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gr16 = COPY [[MOV32r0_]].sub_16bit
587  ; CHECK-NEXT:   $ax = COPY [[COPY5]]
588  ; CHECK-NEXT:   RET 0, $ax
589  bb.0.entry:
590    successors: %bb.3(0x60000000), %bb.2(0x20000000)
591    liveins: $edi, $esi, $rdx
592
593    %3:gr64 = COPY $rdx
594    %2:gr32 = COPY $esi
595    %1:gr32 = COPY $edi
596    %4:gr16 = COPY %1.sub_16bit
597    TEST16rr %4, %4, implicit-def $eflags
598    JCC_1 %bb.2, 4, implicit $eflags
599    JMP_1 %bb.3
600
601  bb.3.entry:
602    successors: %bb.1(0x55555555), %bb.2(0x2aaaaaab)
603
604    %5:gr32 = AND32ri %2, 1234, implicit-def dead $eflags
605    %0:gr16 = COPY %5.sub_16bit
606    TEST16rr %0, %0, implicit-def $eflags
607    JCC_1 %bb.2, 9, implicit $eflags
608    JMP_1 %bb.1
609
610  bb.1.if.then:
611    successors: %bb.2(0x80000000)
612
613    MOV16mr %3, 1, $noreg, 0, $noreg, %0 :: (store (s16) into %ir.2, align 4)
614
615  bb.2.if.end:
616    %6:gr32 = MOV32r0 implicit-def dead $eflags
617    %7:gr16 = COPY %6.sub_16bit
618    $ax = COPY %7
619    RET 0, $ax
620
621...
622