summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-01-09 21:38:17 +0000
committerMatthias Braun <matze@braunis.de>2017-01-09 21:38:17 +0000
commitba7d95d425d62dc2c9245cf46592bdeaba1c3725 (patch)
treefe0df6ca89efe1cc2ba3e9d9284f788b6b1a0030
parentc612891cc5caaa1d124e04bfe7b2b7b2eceb50c4 (diff)
downloadbcm5719-llvm-ba7d95d425d62dc2c9245cf46592bdeaba1c3725.tar.gz
bcm5719-llvm-ba7d95d425d62dc2c9245cf46592bdeaba1c3725.zip
PeepholeOptimizer: Do not replace SubregToReg(bitcast like)
While we can usually replace bitcast like instructions (MachineInstr::isBitcast()) with a COPY this is not legal if any of the users uses SUBREG_TO_REG to assert the upper bits of the result are zero. Differential Revision: https://reviews.llvm.org/D28474 llvm-svn: 291483
-rw-r--r--llvm/lib/CodeGen/PeepholeOptimizer.cpp11
-rw-r--r--llvm/test/CodeGen/X86/peephole.mir40
2 files changed, 50 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index 11af50fe577..6d643457e9a 100644
--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -1715,7 +1715,8 @@ ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
// Bitcasts with more than one def are not supported.
if (Def->getDesc().getNumDefs() != 1)
return ValueTrackerResult();
- if (Def->getOperand(DefIdx).getSubReg() != DefSubReg)
+ const MachineOperand DefOp = Def->getOperand(DefIdx);
+ if (DefOp.getSubReg() != DefSubReg)
// If we look for a different subreg, it means we want a subreg of the src.
// Bails as we do not support composing subregs yet.
return ValueTrackerResult();
@@ -1735,6 +1736,14 @@ ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
return ValueTrackerResult();
SrcIdx = OpIdx;
}
+
+ // Stop when any user of the bitcast is a SUBREG_TO_REG, replacing with a COPY
+ // will break the assumed guarantees for the upper bits.
+ for (const MachineInstr &UseMI : MRI.use_nodbg_instructions(DefOp.getReg())) {
+ if (UseMI.isSubregToReg())
+ return ValueTrackerResult();
+ }
+
const MachineOperand &Src = Def->getOperand(SrcIdx);
return ValueTrackerResult(Src.getReg(), Src.getSubReg());
}
diff --git a/llvm/test/CodeGen/X86/peephole.mir b/llvm/test/CodeGen/X86/peephole.mir
new file mode 100644
index 00000000000..6391836e9ca
--- /dev/null
+++ b/llvm/test/CodeGen/X86/peephole.mir
@@ -0,0 +1,40 @@
+# RUN: llc -mtriple=x86_64-- -run-pass=peephole-opt %s -o - | FileCheck %s
+--- |
+ define void @func() { ret void }
+...
+---
+# Check that instructions with MI.isBitcast() are only replaced by COPY if there
+# are no SUBREG_TO_REG users.
+# CHECK-LABEL: name: func
+name: func
+registers:
+ - { id: 0, class: gr32 }
+ - { id: 1, class: fr32 }
+ - { id: 2, class: gr32 }
+
+ - { id: 3, class: gr32 }
+ - { id: 4, class: fr32 }
+ - { id: 5, class: gr32 }
+ - { id: 6, class: gr64 }
+
+body: |
+ bb.0:
+ ; CHECK: %1 = VMOVDI2SSrr %0
+ ; CHECK: %7 = COPY %0
+ ; CHECK: NOOP implicit %7
+ %0 = MOV32ri 42
+ %1 = VMOVDI2SSrr %0
+ %2 = MOVSS2DIrr %1
+ NOOP implicit %2
+
+ ; CHECK: %4 = VMOVDI2SSrr %3
+ ; CHECK-NOT: COPY
+ ; CHECK: %5 = MOVSS2DIrr %4
+ ; CHECK: %6 = SUBREG_TO_REG %5, 0
+ ; CHECK: NOOP implicit %6
+ %3 = MOV32ri 42
+ %4 = VMOVDI2SSrr %3
+ %5 = MOVSS2DIrr %4
+ %6 = SUBREG_TO_REG %5, 0, %subreg.sub_32bit
+ NOOP implicit %6
+...
OpenPOWER on IntegriCloud