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 @nocopyprop0() { ret void } 12 define void @nocopyprop1() { ret void } 13 define void @nocopyprop2() { ret void } 14 define void @nocopyprop3() { ret void } 15 define void @nocopyprop4() { ret void } 16 define void @nocopyprop5() { ret void } 17... 18--- 19# The second copy is redundant and will be removed, check that we also remove 20# the kill flag of intermediate instructions. 21# CHECK-LABEL: name: copyprop_remove_kill0 22# CHECK: bb.0: 23# CHECK-NEXT: $rax = COPY $rdi 24# CHECK-NEXT: NOOP implicit $rdi 25# CHECK-NOT: COPY 26# CHECK-NEXT: NOOP implicit $rax, implicit $rdi 27name: copyprop_remove_kill0 28body: | 29 bb.0: 30 $rax = COPY $rdi 31 NOOP implicit killed $rdi 32 $rdi = COPY $rax 33 NOOP implicit $rax, implicit $rdi 34... 35--- 36# The second copy is redundant and will be removed, check that we also remove 37# the kill flag of intermediate instructions. 38# CHECK-LABEL: name: copyprop_remove_kill1 39# CHECK: bb.0: 40# CHECK-NEXT: $rax = COPY $rdi 41# CHECK-NEXT: NOOP implicit $edi 42# CHECK-NOT: COPY 43# CHECK-NEXT: NOOP implicit $rax, implicit $rdi 44name: copyprop_remove_kill1 45body: | 46 bb.0: 47 $rax = COPY $rdi 48 NOOP implicit killed $edi 49 $rdi = COPY $rax 50 NOOP implicit $rax, implicit $rdi 51... 52--- 53# The second copy is redundant and will be removed, check that we also remove 54# the kill flag of intermediate instructions. 55# CHECK-LABEL: name: copyprop_remove_kill2 56# CHECK: bb.0: 57# CHECK-NEXT: $ax = COPY $di 58# CHECK-NEXT: NOOP implicit $rdi 59# CHECK-NOT: COPY 60# CHECK-NEXT: NOOP implicit $rax, implicit $rdi 61name: copyprop_remove_kill2 62body: | 63 bb.0: 64 $ax = COPY $di 65 NOOP implicit killed $rdi 66 $di = COPY $ax 67 NOOP implicit $rax, implicit $rdi 68... 69--- 70# The second copy is redundant; the call preserves the source and dest register. 71# CHECK-LABEL: name: copyprop0 72# CHECK: bb.0: 73# CHECK-NEXT: $rax = COPY $rdi 74# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs 75# CHECK-NEXT: NOOP implicit $edi 76# CHECK-NOT: COPY 77# CHECK-NEXT: NOOP implicit $rax, implicit $rdi 78name: copyprop0 79body: | 80 bb.0: 81 $rax = COPY $rdi 82 CALL64pcrel32 @foo, csr_64_rt_mostregs 83 NOOP implicit killed $edi 84 $rdi = COPY $rax 85 NOOP implicit $rax, implicit $rdi 86... 87--- 88# The 2nd copy is redundant; The call preserves the source and dest register. 89# CHECK-LABEL: name: copyprop1 90# CHECK: bb.0: 91# CHECK-NEXT: $rax = COPY $rdi 92# CHECK-NEXT: NOOP implicit $rax 93# CHECK-NEXT: NOOP implicit $rax, implicit $rdi 94name: copyprop1 95body: | 96 bb.0: 97 $rax = COPY $rdi 98 NOOP implicit killed $rax 99 $rax = COPY $rdi 100 NOOP implicit $rax, implicit $rdi 101... 102--- 103# CHECK-LABEL: name: copyprop2 104# CHECK: bb.0: 105# CHECK-NEXT: $rax = COPY $rdi 106# CHECK-NEXT: NOOP implicit $ax 107# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs 108# CHECK-NOT: $rax = COPY $rdi 109# CHECK-NEXT: NOOP implicit $rax, implicit $rdi 110name: copyprop2 111body: | 112 bb.0: 113 $rax = COPY $rdi 114 NOOP implicit killed $ax 115 CALL64pcrel32 @foo, csr_64_rt_mostregs 116 $rax = COPY $rdi 117 NOOP implicit $rax, implicit $rdi 118... 119--- 120# The second copy is not redundant if the source register ($rax) is clobbered 121# even if the dest ($rbp) is not. 122# CHECK-LABEL: name: nocopyprop0 123# CHECK: bb.0: 124# CHECK-NEXT: $rax = COPY $rbp 125# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 126# CHECK-NEXT: $rbp = COPY $rax 127# CHECK-NEXT: NOOP implicit $rax, implicit $rbp 128name: nocopyprop0 129body: | 130 bb.0: 131 $rax = COPY $rbp 132 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 133 $rbp = COPY $rax 134 NOOP implicit $rax, implicit $rbp 135... 136--- 137# The second copy is not redundant if the dest register ($rax) is clobbered 138# even if the source ($rbp) is not. 139# CHECK-LABEL: name: nocopyprop1 140# CHECK: bb.0: 141# CHECK-NEXT: $rbp = COPY $rax 142# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 143# CHECK-NEXT: $rax = COPY $rbp 144# CHECK-NEXT: NOOP implicit $rax, implicit $rbp 145name: nocopyprop1 146body: | 147 bb.0: 148 $rbp = COPY $rax 149 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 150 $rax = COPY $rbp 151 NOOP implicit $rax, implicit $rbp 152... 153--- 154# The second copy is not redundant if the source register ($rax) is clobbered 155# even if the dest ($rbp) is not. 156# CHECK-LABEL: name: nocopyprop2 157# CHECK: bb.0: 158# CHECK-NEXT: $rax = COPY $rbp 159# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 160# CHECK-NEXT: $rax = COPY $rbp 161# CHECK-NEXT: NOOP implicit $rax, implicit $rbp 162name: nocopyprop2 163body: | 164 bb.0: 165 $rax = COPY $rbp 166 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 167 $rax = COPY $rbp 168 NOOP implicit $rax, implicit $rbp 169... 170--- 171# The second copy is not redundant if the dest register ($rax) is clobbered 172# even if the source ($rbp) is not. 173# CHECK-LABEL: name: nocopyprop3 174# CHECK: bb.0: 175# CHECK-NEXT: $rbp = COPY $rax 176# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 177# CHECK-NEXT: $rbp = COPY $rax 178# CHECK-NEXT: NOOP implicit $rax, implicit $rbp 179name: nocopyprop3 180body: | 181 bb.0: 182 $rbp = COPY $rax 183 CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp 184 $rbp = COPY $rax 185 NOOP implicit $rax, implicit $rbp 186... 187--- 188# A reserved register may change its value so the 2nd copy is not redundant. 189# CHECK-LABEL: name: nocopyprop4 190# CHECK: bb.0: 191# CHECK-NEXT: $rax = COPY $rip 192# CHECK-NEXT: NOOP implicit $rax 193# CHECK-NEXT: $rax = COPY $rip 194# CHECK-NEXT: NOOP implicit $rax 195name: nocopyprop4 196body: | 197 bb.0: 198 $rax = COPY $rip 199 NOOP implicit $rax 200 $rax = COPY $rip 201 NOOP implicit $rax 202... 203--- 204# Writing to a reserved register may have additional effects (slightly illegal 205# testcase because writing to $rip like this should make the instruction a jump) 206# CHECK-LABEL: name: nocopyprop5 207# CHECK: bb.0: 208# CHECK-NEXT: $rip = COPY $rax 209# CHECK-NEXT: $rip = COPY $rax 210name: nocopyprop5 211body: | 212 bb.0: 213 $rip = COPY $rax 214 $rip = COPY $rax 215... 216