1 # RUN: llc -mtriple=i686-- -run-pass machine-cp -verify-machineinstrs -o - %s | FileCheck %s
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 }
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
25 # CHECK-NEXT: $rax = COPY $rdi
26 # CHECK-NEXT: NOOP implicit $rdi
28 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
29 name: copyprop_remove_kill0
33 NOOP implicit killed $rdi
35 NOOP implicit $rax, implicit $rdi
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
42 # CHECK-NEXT: $rax = COPY $rdi
43 # CHECK-NEXT: NOOP implicit $edi
45 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
46 name: copyprop_remove_kill1
50 NOOP implicit killed $edi
52 NOOP implicit $rax, implicit $rdi
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
59 # CHECK-NEXT: $ax = COPY $di
60 # CHECK-NEXT: NOOP implicit $rdi
62 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
63 name: copyprop_remove_kill2
67 NOOP implicit killed $rdi
69 NOOP implicit $rax, implicit $rdi
72 # The second copy is redundant; the call preserves the source and dest register.
73 # CHECK-LABEL: name: copyprop0
75 # CHECK-NEXT: $rax = COPY $rdi
76 # CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
77 # CHECK-NEXT: NOOP implicit $edi
79 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
84 CALL64pcrel32 @foo, csr_64_rt_mostregs
85 NOOP implicit killed $edi
87 NOOP implicit $rax, implicit $rdi
90 # The 2nd copy is redundant; The call preserves the source and dest register.
91 # CHECK-LABEL: name: copyprop1
93 # CHECK-NEXT: $rax = COPY $rdi
94 # CHECK-NEXT: NOOP implicit $rax
95 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
100 NOOP implicit killed $rax
102 NOOP implicit $rax, implicit $rdi
105 # CHECK-LABEL: name: copyprop2
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
116 NOOP implicit killed $ax
117 CALL64pcrel32 @foo, csr_64_rt_mostregs
119 NOOP implicit $rax, implicit $rdi
122 # Check that undef is removed from the remaining copy because
123 # the deleted COPY did not have it.
124 # CHECK-LABEL: name: copyprop3
126 # CHECK: $rax = COPY $rdi
127 # CHECK-NEXT: NOOP implicit $rax
128 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
130 tracksRegLiveness: true
135 $rax = COPY undef $rdi
136 NOOP implicit killed $rax
138 NOOP implicit $rax, implicit $rdi
141 # Check that undef is NOT removed from the remaining copy because
142 # the deleted COPY also had it.
143 # CHECK-LABEL: name: copyprop4
145 # CHECK: $rax = COPY undef $rdi
146 # CHECK-NEXT: NOOP implicit $rax
147 # CHECK-NEXT: NOOP implicit $rax, implicit $rdi
149 tracksRegLiveness: true
154 $rax = COPY undef $rdi
155 NOOP implicit killed $rax
156 $rax = COPY undef $rdi
157 NOOP implicit $rax, implicit $rdi
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
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
172 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
174 NOOP implicit $rax, implicit $rbp
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
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
189 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
191 NOOP implicit $rax, implicit $rbp
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
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
206 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
208 NOOP implicit $rax, implicit $rbp
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
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
223 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
225 NOOP implicit $rax, implicit $rbp
228 # A reserved register may change its value so the 2nd copy is not redundant.
229 # CHECK-LABEL: name: nocopyprop4
231 # CHECK-NEXT: $rax = COPY $rip
232 # CHECK-NEXT: NOOP implicit $rax
233 # CHECK-NEXT: $rax = COPY $rip
234 # CHECK-NEXT: NOOP implicit $rax
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
248 # CHECK-NEXT: $rip = COPY $rax
249 # CHECK-NEXT: $rip = COPY $rax