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