summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorEli Friedman <efriedma@codeaurora.org>2018-03-30 00:56:03 +0000
committerEli Friedman <efriedma@codeaurora.org>2018-03-30 00:56:03 +0000
commit208fe67a7861a7db659c3849ab31b9c2e83cbfb9 (patch)
tree905283947cff958a49a09f33160b4e1682e3a2b5 /llvm
parent7fb5d41e449cad3db498a44054a652e0c2955f53 (diff)
downloadbcm5719-llvm-208fe67a7861a7db659c3849ab31b9c2e83cbfb9.tar.gz
bcm5719-llvm-208fe67a7861a7db659c3849ab31b9c2e83cbfb9.zip
[MachineCopyPropagation] Handle COPY with overlapping source/dest.
MachineCopyPropagation::CopyPropagateBlock has a bunch of special handling for COPY instructions. This handling assumes that COPY instructions do not modify the source of the copy; this is wrong if the COPY destination overlaps the source. To fix the bug, check explicitly for this situation, and fall back to the generic instruction handling. This bug can't happen for most register classes because they don't have this sort of overlap, but there are a few register classes where this is possible. The testcase uses the AArch64 QQQQ register class. Differential Revision: https://reviews.llvm.org/D44911 llvm-svn: 328851
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/MachineCopyPropagation.cpp4
-rw-r--r--llvm/test/CodeGen/AArch64/machine-dead-copy.mir32
2 files changed, 35 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 4c1717e1ec3..8b6777f06db 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -399,7 +399,9 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
MachineInstr *MI = &*I;
++I;
- if (MI->isCopy()) {
+ // Analyze copies (which don't overlap themselves).
+ if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(),
+ MI->getOperand(1).getReg())) {
unsigned Def = MI->getOperand(0).getReg();
unsigned Src = MI->getOperand(1).getReg();
diff --git a/llvm/test/CodeGen/AArch64/machine-dead-copy.mir b/llvm/test/CodeGen/AArch64/machine-dead-copy.mir
index a3d7e7cbbf7..09548f3f608 100644
--- a/llvm/test/CodeGen/AArch64/machine-dead-copy.mir
+++ b/llvm/test/CodeGen/AArch64/machine-dead-copy.mir
@@ -6,6 +6,8 @@
define i32 @copyprop2(i32 %a, i32 %b) { ret i32 %a }
define i32 @copyprop3(i32 %a, i32 %b) { ret i32 %a }
define i32 @copyprop4(i32 %a, i32 %b) { ret i32 %a }
+ define i32 @copyprop5(i32 %a, i32 %b) { ret i32 %a }
+ define i32 @copyprop6(i32 %a, i32 %b) { ret i32 %a }
declare i32 @foo(i32)
...
---
@@ -65,3 +67,33 @@ body: |
RET_ReallyLR implicit $w0
...
+# Don't try to erase any COPY which overlaps itself.
+# CHECK-LABEL: name: copyprop5
+# CHECK: bb.0:
+# CHECK: COPY killed $q26_q27_q28_q29
+# CHECK: COPY killed $q28_q29_q30_q31
+name: copyprop5
+body: |
+ bb.0:
+ liveins: $q26_q27_q28_q29
+ $q28_q29_q30_q31 = COPY killed $q26_q27_q28_q29
+ $q26_q27_q28_q29 = COPY killed $q28_q29_q30_q31
+ BL @foo, csr_aarch64_aapcs, implicit killed $q26_q27_q28_q29
+ RET_ReallyLR
+...
+
+# Don't try to analyze any COPY which overlaps itself.
+# CHECK-LABEL: name: copyprop6
+# CHECK: bb.0:
+# CHECK: COPY killed $q26_q27_q28_q29
+# CHECK: $q30 = COPY $q28
+name: copyprop6
+body: |
+ bb.0:
+ liveins: $q26_q27_q28_q29
+ $q28_q29_q30_q31 = COPY killed $q26_q27_q28_q29
+ $q30 = COPY $q28
+ BL @foo, csr_aarch64_aapcs, implicit killed $q28_q29_q30_q31
+ RET_ReallyLR
+...
+
OpenPOWER on IntegriCloud