Skip to content

Commit 4b493ea

Browse files
committed
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. rdar://27994304 Differential Revision: https://reviews.llvm.org/D28474 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291483 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3144129 commit 4b493ea

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

lib/CodeGen/PeepholeOptimizer.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1688,7 +1688,8 @@ ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
16881688
// Bitcasts with more than one def are not supported.
16891689
if (Def->getDesc().getNumDefs() != 1)
16901690
return ValueTrackerResult();
1691-
if (Def->getOperand(DefIdx).getSubReg() != DefSubReg)
1691+
const MachineOperand DefOp = Def->getOperand(DefIdx);
1692+
if (DefOp.getSubReg() != DefSubReg)
16921693
// If we look for a different subreg, it means we want a subreg of the src.
16931694
// Bails as we do not support composing subregs yet.
16941695
return ValueTrackerResult();
@@ -1708,6 +1709,14 @@ ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
17081709
return ValueTrackerResult();
17091710
SrcIdx = OpIdx;
17101711
}
1712+
1713+
// Stop when any user of the bitcast is a SUBREG_TO_REG, replacing with a COPY
1714+
// will break the assumed guarantees for the upper bits.
1715+
for (const MachineInstr &UseMI : MRI.use_nodbg_instructions(DefOp.getReg())) {
1716+
if (UseMI.isSubregToReg())
1717+
return ValueTrackerResult();
1718+
}
1719+
17111720
const MachineOperand &Src = Def->getOperand(SrcIdx);
17121721
return ValueTrackerResult(Src.getReg(), Src.getSubReg());
17131722
}

test/CodeGen/X86/peephole.mir

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# RUN: llc -mtriple=x86_64-- -run-pass=peephole-opt %s -o - | FileCheck %s
2+
--- |
3+
define void @func() { ret void }
4+
...
5+
---
6+
# Check that instructions with MI.isBitcast() are only replaced by COPY if there
7+
# are no SUBREG_TO_REG users.
8+
# CHECK-LABEL: name: func
9+
name: func
10+
registers:
11+
- { id: 0, class: gr32 }
12+
- { id: 1, class: fr32 }
13+
- { id: 2, class: gr32 }
14+
15+
- { id: 3, class: gr32 }
16+
- { id: 4, class: fr32 }
17+
- { id: 5, class: gr32 }
18+
- { id: 6, class: gr64 }
19+
20+
body: |
21+
bb.0:
22+
; CHECK: %1 = VMOVDI2SSrr %0
23+
; CHECK: %7 = COPY %0
24+
; CHECK: NOOP implicit %7
25+
%0 = MOV32ri 42
26+
%1 = VMOVDI2SSrr %0
27+
%2 = MOVSS2DIrr %1
28+
NOOP implicit %2
29+
30+
; CHECK: %4 = VMOVDI2SSrr %3
31+
; CHECK-NOT: COPY
32+
; CHECK: %5 = MOVSS2DIrr %4
33+
; CHECK: %6 = SUBREG_TO_REG %5, 0
34+
; CHECK: NOOP implicit %6
35+
%3 = MOV32ri 42
36+
%4 = VMOVDI2SSrr %3
37+
%5 = MOVSS2DIrr %4
38+
%6 = SUBREG_TO_REG %5, 0, %subreg.sub_32bit
39+
NOOP implicit %6
40+
...

0 commit comments

Comments
 (0)