Skip to content

Commit 08abcac

Browse files
committed
PeepholeOptimizer: Do not form PHI with subreg arguments
When replacing a PHI the PeepholeOptimizer currently takes the register class of the register at the first operand. This however is not correct if this argument has a subregister index. As there is currently no API to query the register class resulting from applying a subregister index to all registers in a class, we can only abort in these cases and not perform the transformation. This changes findNextSource() to require the end of all copy chains to not use a subregister if there is any PHI in the chain. I had to rewrite the overly complicated inner loop there to have a good place to insert the new check. This fixes https://llvm.org/PR33071 (aka rdar://32262041) Differential Revision: https://reviews.llvm.org/D40758 llvm-svn: 322313
1 parent 5223b5d commit 08abcac

File tree

2 files changed

+86
-22
lines changed

2 files changed

+86
-22
lines changed

llvm/lib/CodeGen/PeepholeOptimizer.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -719,15 +719,14 @@ bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg,
719719
CurSrcPair = Pair;
720720
ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI,
721721
!DisableAdvCopyOpt, TII);
722-
ValueTrackerResult Res;
723-
bool ShouldRewrite = false;
724722

725-
do {
726-
// Follow the chain of copies until we reach the top of the use-def chain
727-
// or find a more suitable source.
728-
Res = ValTracker.getNextSource();
723+
// Follow the chain of copies until we find a more suitable source, a phi
724+
// or have to abort.
725+
while (true) {
726+
ValueTrackerResult Res = ValTracker.getNextSource();
727+
// Abort at the end of a chain (without finding a suitable source).
729728
if (!Res.isValid())
730-
break;
729+
return false;
731730

732731
// Insert the Def -> Use entry for the recently found source.
733732
ValueTrackerResult CurSrcRes = RewriteMap.lookup(CurSrcPair);
@@ -763,24 +762,19 @@ bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg,
763762
if (TargetRegisterInfo::isPhysicalRegister(CurSrcPair.Reg))
764763
return false;
765764

765+
// Keep following the chain if the value isn't any better yet.
766766
const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg);
767-
ShouldRewrite = TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC,
768-
CurSrcPair.SubReg);
769-
} while (!ShouldRewrite);
770-
771-
// Continue looking for new sources...
772-
if (Res.isValid())
773-
continue;
767+
if (!TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC, CurSrcPair.SubReg))
768+
continue;
774769

775-
// Do not continue searching for a new source if the there's at least
776-
// one use-def which cannot be rewritten.
777-
if (!ShouldRewrite)
778-
return false;
779-
}
770+
// We currently cannot deal with subreg operands on PHI instructions
771+
// (see insertPHI()).
772+
if (PHICount > 0 && CurSrcPair.SubReg != 0)
773+
continue;
780774

781-
if (PHICount >= RewritePHILimit) {
782-
DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
783-
return false;
775+
// We found a suitable source, and are done with this chain.
776+
break;
777+
}
784778
}
785779

786780
// If we did not find a more suitable source, there is nothing to optimize.
@@ -799,6 +793,9 @@ insertPHI(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
799793
assert(!SrcRegs.empty() && "No sources to create a PHI instruction?");
800794

801795
const TargetRegisterClass *NewRC = MRI->getRegClass(SrcRegs[0].Reg);
796+
// NewRC is only correct if no subregisters are involved. findNextSource()
797+
// should have rejected those cases already.
798+
assert(SrcRegs[0].SubReg == 0 && "should not have subreg operand");
802799
unsigned NewVR = MRI->createVirtualRegister(NewRC);
803800
MachineBasicBlock *MBB = OrigPHI->getParent();
804801
MachineInstrBuilder MIB = BuildMI(*MBB, OrigPHI, OrigPHI->getDebugLoc(),
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# RUN: llc -o - %s -mtriple=armv7-- -verify-machineinstrs -run-pass=peephole-opt | FileCheck %s
2+
#
3+
# Make sure we do not crash on this input.
4+
# Note that this input could in principle be optimized, but right now we don't
5+
# have this case implemented so the output should simply be unchanged.
6+
#
7+
# CHECK-LABEL: name: func
8+
# CHECK: body: |
9+
# CHECK: bb.0:
10+
# CHECK: Bcc %bb.2, 1, undef %cpsr
11+
#
12+
# CHECK: bb.1:
13+
# CHECK: %0:dpr = IMPLICIT_DEF
14+
# CHECK: %1:gpr, %2:gpr = VMOVRRD %0, 14, %noreg
15+
# CHECK: B %bb.3
16+
#
17+
# CHECK: bb.2:
18+
# CHECK: %3:spr = IMPLICIT_DEF
19+
# CHECK: %4:gpr = VMOVRS %3, 14, %noreg
20+
#
21+
# CHECK: bb.3:
22+
# CHECK: %5:gpr = PHI %1, %bb.1, %4, %bb.2
23+
# CHECK: %6:spr = VMOVSR %5, 14, %noreg
24+
---
25+
name: func0
26+
tracksRegLiveness: true
27+
body: |
28+
bb.0:
29+
Bcc %bb.2, 1, undef %cpsr
30+
31+
bb.1:
32+
%0:dpr = IMPLICIT_DEF
33+
%1:gpr, %2:gpr = VMOVRRD %0:dpr, 14, %noreg
34+
B %bb.3
35+
36+
bb.2:
37+
%3:spr = IMPLICIT_DEF
38+
%4:gpr = VMOVRS %3:spr, 14, %noreg
39+
40+
bb.3:
41+
%5:gpr = PHI %1, %bb.1, %4, %bb.2
42+
%6:spr = VMOVSR %5, 14, %noreg
43+
...
44+
45+
# CHECK-LABEL: name: func1
46+
# CHECK: %6:spr = PHI %0, %bb.1, %2, %bb.2
47+
# CHEKC: %7:spr = COPY %6
48+
---
49+
name: func1
50+
tracksRegLiveness: true
51+
body: |
52+
bb.0:
53+
Bcc %bb.2, 1, undef %cpsr
54+
55+
bb.1:
56+
%1:spr = IMPLICIT_DEF
57+
%0:gpr = VMOVRS %1, 14, %noreg
58+
B %bb.3
59+
60+
bb.2:
61+
%3:spr = IMPLICIT_DEF
62+
%2:gpr = VMOVRS %3:spr, 14, %noreg
63+
64+
bb.3:
65+
%4:gpr = PHI %0, %bb.1, %2, %bb.2
66+
%5:spr = VMOVSR %4, 14, %noreg
67+
...

0 commit comments

Comments
 (0)