xref: /llvm-project/llvm/test/CodeGen/X86/machine-copy-prop.mir (revision c59f9eada1abe369c0470aa2dad8b20ac5269020)
1# RUN: llc -mtriple=i686-- -run-pass machine-cp -verify-machineinstrs -o - %s | FileCheck %s
2
3--- |
4  declare void @foo()
5  define void @copyprop_remove_kill0() { ret void }
6  define void @copyprop_remove_kill1() { ret void }
7  define void @copyprop_remove_kill2() { ret void }
8  define void @copyprop0() { ret void }
9  define void @copyprop1() { ret void }
10  define void @copyprop2() { ret void }
11  define void @copyprop3() { ret void }
12  define void @copyprop4() { ret void }
13  define void @nocopyprop0() { ret void }
14  define void @nocopyprop1() { ret void }
15  define void @nocopyprop2() { ret void }
16  define void @nocopyprop3() { ret void }
17  define void @nocopyprop4() { ret void }
18  define void @nocopyprop5() { ret void }
19...
20---
21# The second copy is redundant and will be removed, check that we also remove
22# the kill flag of intermediate instructions.
23# CHECK-LABEL: name: copyprop_remove_kill0
24# CHECK: bb.0:
25# CHECK-NEXT: $rax = COPY $rdi
26# CHECK-NEXT: NOOP implicit $rdi
27# CHECK-NOT: COPY
28# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
29name: copyprop_remove_kill0
30body: |
31  bb.0:
32    $rax = COPY $rdi
33    NOOP implicit killed $rdi
34    $rdi = COPY $rax
35    NOOP implicit $rax, implicit $rdi
36...
37---
38# The second copy is redundant and will be removed, check that we also remove
39# the kill flag of intermediate instructions.
40# CHECK-LABEL: name: copyprop_remove_kill1
41# CHECK: bb.0:
42# CHECK-NEXT: $rax = COPY $rdi
43# CHECK-NEXT: NOOP implicit $edi
44# CHECK-NOT: COPY
45# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
46name: copyprop_remove_kill1
47body: |
48  bb.0:
49    $rax = COPY $rdi
50    NOOP implicit killed $edi
51    $rdi = COPY $rax
52    NOOP implicit $rax, implicit $rdi
53...
54---
55# The second copy is redundant and will be removed, check that we also remove
56# the kill flag of intermediate instructions.
57# CHECK-LABEL: name: copyprop_remove_kill2
58# CHECK: bb.0:
59# CHECK-NEXT: $ax = COPY $di
60# CHECK-NEXT: NOOP implicit $rdi
61# CHECK-NOT: COPY
62# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
63name: copyprop_remove_kill2
64body: |
65  bb.0:
66    $ax = COPY $di
67    NOOP implicit killed $rdi
68    $di = COPY $ax
69    NOOP implicit $rax, implicit $rdi
70...
71---
72# The second copy is redundant; the call preserves the source and dest register.
73# CHECK-LABEL: name: copyprop0
74# CHECK: bb.0:
75# CHECK-NEXT: $rax = COPY $rdi
76# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
77# CHECK-NEXT: NOOP implicit $edi
78# CHECK-NOT: COPY
79# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
80name: copyprop0
81body: |
82  bb.0:
83    $rax = COPY $rdi
84    CALL64pcrel32 @foo, csr_64_rt_mostregs
85    NOOP implicit killed $edi
86    $rdi = COPY $rax
87    NOOP implicit $rax, implicit $rdi
88...
89---
90# The 2nd copy is redundant; The call preserves the source and dest register.
91# CHECK-LABEL: name: copyprop1
92# CHECK: bb.0:
93# CHECK-NEXT: $rax = COPY $rdi
94# CHECK-NEXT: NOOP implicit $rax
95# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
96name: copyprop1
97body: |
98  bb.0:
99    $rax = COPY $rdi
100    NOOP implicit killed $rax
101    $rax = COPY $rdi
102    NOOP implicit $rax, implicit $rdi
103...
104---
105# CHECK-LABEL: name: copyprop2
106# CHECK: bb.0:
107# CHECK-NEXT: $rax = COPY $rdi
108# CHECK-NEXT: NOOP implicit $ax
109# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
110# CHECK-NOT: $rax = COPY $rdi
111# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
112name: copyprop2
113body: |
114  bb.0:
115    $rax = COPY $rdi
116    NOOP implicit killed $ax
117    CALL64pcrel32 @foo, csr_64_rt_mostregs
118    $rax = COPY $rdi
119    NOOP implicit $rax, implicit $rdi
120...
121---
122# Check that undef is removed from the remaining copy because
123# the deleted COPY did not have it.
124# CHECK-LABEL: name: copyprop3
125# CHECK: bb.0:
126# CHECK:      $rax = COPY $rdi
127# CHECK-NEXT: NOOP implicit $rax
128# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
129name: copyprop3
130tracksRegLiveness: true
131body: |
132  bb.0:
133    liveins: $rdi
134
135    $rax = COPY undef $rdi
136    NOOP implicit killed $rax
137    $rax = COPY $rdi
138    NOOP implicit $rax, implicit $rdi
139...
140---
141# Check that undef is NOT removed from the remaining copy because
142# the deleted COPY also had it.
143# CHECK-LABEL: name: copyprop4
144# CHECK: bb.0:
145# CHECK:      $rax = COPY undef $rdi
146# CHECK-NEXT: NOOP implicit $rax
147# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
148name: copyprop4
149tracksRegLiveness: true
150body: |
151  bb.0:
152    liveins: $rdi
153
154    $rax = COPY undef $rdi
155    NOOP implicit killed $rax
156    $rax = COPY undef $rdi
157    NOOP implicit $rax, implicit $rdi
158...
159---
160# The second copy is not redundant if the source register ($rax) is clobbered
161# even if the dest ($rbp) is not.
162# CHECK-LABEL: name: nocopyprop0
163# CHECK: bb.0:
164# CHECK-NEXT: $rax = COPY $rbp
165# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
166# CHECK-NEXT: $rbp = COPY $rax
167# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
168name: nocopyprop0
169body: |
170  bb.0:
171    $rax = COPY $rbp
172    CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
173    $rbp = COPY $rax
174    NOOP implicit $rax, implicit $rbp
175...
176---
177# The second copy is not redundant if the dest register ($rax) is clobbered
178# even if the source ($rbp) is not.
179# CHECK-LABEL: name: nocopyprop1
180# CHECK: bb.0:
181# CHECK-NEXT: $rbp = COPY $rax
182# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
183# CHECK-NEXT: $rax = COPY $rbp
184# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
185name: nocopyprop1
186body: |
187  bb.0:
188    $rbp = COPY $rax
189    CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
190    $rax = COPY $rbp
191    NOOP implicit $rax, implicit $rbp
192...
193---
194# The second copy is not redundant if the source register ($rax) is clobbered
195# even if the dest ($rbp) is not.
196# CHECK-LABEL: name: nocopyprop2
197# CHECK: bb.0:
198# CHECK-NEXT: $rax = COPY $rbp
199# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
200# CHECK-NEXT: $rax = COPY $rbp
201# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
202name: nocopyprop2
203body: |
204  bb.0:
205    $rax = COPY $rbp
206    CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
207    $rax = COPY $rbp
208    NOOP implicit $rax, implicit $rbp
209...
210---
211# The second copy is not redundant if the dest register ($rax) is clobbered
212# even if the source ($rbp) is not.
213# CHECK-LABEL: name: nocopyprop3
214# CHECK: bb.0:
215# CHECK-NEXT: $rbp = COPY $rax
216# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
217# CHECK-NEXT: $rbp = COPY $rax
218# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
219name: nocopyprop3
220body: |
221  bb.0:
222    $rbp = COPY $rax
223    CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
224    $rbp = COPY $rax
225    NOOP implicit $rax, implicit $rbp
226...
227---
228# A reserved register may change its value so the 2nd copy is not redundant.
229# CHECK-LABEL: name: nocopyprop4
230# CHECK: bb.0:
231# CHECK-NEXT: $rax = COPY $rip
232# CHECK-NEXT: NOOP implicit $rax
233# CHECK-NEXT: $rax = COPY $rip
234# CHECK-NEXT: NOOP implicit $rax
235name: nocopyprop4
236body: |
237  bb.0:
238    $rax = COPY $rip
239    NOOP implicit $rax
240    $rax = COPY $rip
241    NOOP implicit $rax
242...
243---
244# Writing to a reserved register may have additional effects (slightly illegal
245# testcase because writing to $rip like this should make the instruction a jump)
246# CHECK-LABEL: name: nocopyprop5
247# CHECK: bb.0:
248# CHECK-NEXT: $rip = COPY $rax
249# CHECK-NEXT: $rip = COPY $rax
250name: nocopyprop5
251body: |
252  bb.0:
253    $rip = COPY $rax
254    $rip = COPY $rax
255...
256