blob: cf6ce3d6c821ad8d31faa3f8bf3af0567a648506 [file] [log] [blame]
# RUN: llc -mtriple=i686-- -run-pass machine-cp -verify-machineinstrs -o - %s | FileCheck %s
--- |
declare void @foo()
define void @copyprop_remove_kill0() { ret void }
define void @copyprop_remove_kill1() { ret void }
define void @copyprop_remove_kill2() { ret void }
define void @copyprop0() { ret void }
define void @copyprop1() { ret void }
define void @copyprop2() { ret void }
define void @nocopyprop0() { ret void }
define void @nocopyprop1() { ret void }
define void @nocopyprop2() { ret void }
define void @nocopyprop3() { ret void }
define void @nocopyprop4() { ret void }
define void @nocopyprop5() { ret void }
...
---
# The second copy is redundant and will be removed, check that we also remove
# the kill flag of intermediate instructions.
# CHECK-LABEL: name: copyprop_remove_kill0
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rdi
# CHECK-NEXT: NOOP implicit $rdi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
name: copyprop_remove_kill0
body: |
bb.0:
$rax = COPY $rdi
NOOP implicit killed $rdi
$rdi = COPY $rax
NOOP implicit $rax, implicit $rdi
...
---
# The second copy is redundant and will be removed, check that we also remove
# the kill flag of intermediate instructions.
# CHECK-LABEL: name: copyprop_remove_kill1
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rdi
# CHECK-NEXT: NOOP implicit $edi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
name: copyprop_remove_kill1
body: |
bb.0:
$rax = COPY $rdi
NOOP implicit killed $edi
$rdi = COPY $rax
NOOP implicit $rax, implicit $rdi
...
---
# The second copy is redundant and will be removed, check that we also remove
# the kill flag of intermediate instructions.
# CHECK-LABEL: name: copyprop_remove_kill2
# CHECK: bb.0:
# CHECK-NEXT: $ax = COPY $di
# CHECK-NEXT: NOOP implicit $rdi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
name: copyprop_remove_kill2
body: |
bb.0:
$ax = COPY $di
NOOP implicit killed $rdi
$di = COPY $ax
NOOP implicit $rax, implicit $rdi
...
---
# The second copy is redundant; the call preserves the source and dest register.
# CHECK-LABEL: name: copyprop0
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rdi
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
# CHECK-NEXT: NOOP implicit $edi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
name: copyprop0
body: |
bb.0:
$rax = COPY $rdi
CALL64pcrel32 @foo, csr_64_rt_mostregs
NOOP implicit killed $edi
$rdi = COPY $rax
NOOP implicit $rax, implicit $rdi
...
---
# The 2nd copy is redundant; The call preserves the source and dest register.
# CHECK-LABEL: name: copyprop1
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rdi
# CHECK-NEXT: NOOP implicit $rax
# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
name: copyprop1
body: |
bb.0:
$rax = COPY $rdi
NOOP implicit killed $rax
$rax = COPY $rdi
NOOP implicit $rax, implicit $rdi
...
---
# CHECK-LABEL: name: copyprop2
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rdi
# CHECK-NEXT: NOOP implicit $ax
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
# CHECK-NOT: $rax = COPY $rdi
# CHECK-NEXT: NOOP implicit $rax, implicit $rdi
name: copyprop2
body: |
bb.0:
$rax = COPY $rdi
NOOP implicit killed $ax
CALL64pcrel32 @foo, csr_64_rt_mostregs
$rax = COPY $rdi
NOOP implicit $rax, implicit $rdi
...
---
# The second copy is not redundant if the source register ($rax) is clobbered
# even if the dest ($rbp) is not.
# CHECK-LABEL: name: nocopyprop0
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rbp
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
# CHECK-NEXT: $rbp = COPY $rax
# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
name: nocopyprop0
body: |
bb.0:
$rax = COPY $rbp
CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
$rbp = COPY $rax
NOOP implicit $rax, implicit $rbp
...
---
# The second copy is not redundant if the dest register ($rax) is clobbered
# even if the source ($rbp) is not.
# CHECK-LABEL: name: nocopyprop1
# CHECK: bb.0:
# CHECK-NEXT: $rbp = COPY $rax
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
# CHECK-NEXT: $rax = COPY $rbp
# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
name: nocopyprop1
body: |
bb.0:
$rbp = COPY $rax
CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
$rax = COPY $rbp
NOOP implicit $rax, implicit $rbp
...
---
# The second copy is not redundant if the source register ($rax) is clobbered
# even if the dest ($rbp) is not.
# CHECK-LABEL: name: nocopyprop2
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rbp
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
# CHECK-NEXT: $rax = COPY $rbp
# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
name: nocopyprop2
body: |
bb.0:
$rax = COPY $rbp
CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
$rax = COPY $rbp
NOOP implicit $rax, implicit $rbp
...
---
# The second copy is not redundant if the dest register ($rax) is clobbered
# even if the source ($rbp) is not.
# CHECK-LABEL: name: nocopyprop3
# CHECK: bb.0:
# CHECK-NEXT: $rbp = COPY $rax
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
# CHECK-NEXT: $rbp = COPY $rax
# CHECK-NEXT: NOOP implicit $rax, implicit $rbp
name: nocopyprop3
body: |
bb.0:
$rbp = COPY $rax
CALL64pcrel32 @foo, csr_64, implicit $rax, implicit $rbp
$rbp = COPY $rax
NOOP implicit $rax, implicit $rbp
...
---
# A reserved register may change its value so the 2nd copy is not redundant.
# CHECK-LABEL: name: nocopyprop4
# CHECK: bb.0:
# CHECK-NEXT: $rax = COPY $rip
# CHECK-NEXT: NOOP implicit $rax
# CHECK-NEXT: $rax = COPY $rip
# CHECK-NEXT: NOOP implicit $rax
name: nocopyprop4
body: |
bb.0:
$rax = COPY $rip
NOOP implicit $rax
$rax = COPY $rip
NOOP implicit $rax
...
---
# Writing to a reserved register may have additional effects (slightly illegal
# testcase because writing to $rip like this should make the instruction a jump)
# CHECK-LABEL: name: nocopyprop5
# CHECK: bb.0:
# CHECK-NEXT: $rip = COPY $rax
# CHECK-NEXT: $rip = COPY $rax
name: nocopyprop5
body: |
bb.0:
$rip = COPY $rax
$rip = COPY $rax
...