diff options
author | Matthias Braun <matze@braunis.de> | 2017-01-09 21:38:17 +0000 |
---|---|---|
committer | Matthias Braun <matze@braunis.de> | 2017-01-09 21:38:17 +0000 |
commit | ba7d95d425d62dc2c9245cf46592bdeaba1c3725 (patch) | |
tree | fe0df6ca89efe1cc2ba3e9d9284f788b6b1a0030 | |
parent | c612891cc5caaa1d124e04bfe7b2b7b2eceb50c4 (diff) | |
download | bcm5719-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.cpp | 11 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/peephole.mir | 40 |
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 +... |