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