llvm.org GIT mirror llvm / 57ed2ef
Merging r322313: ------------------------------------------------------------------------ r322313 | matze | 2018-01-11 13:57:03 -0800 (Thu, 11 Jan 2018) | 18 lines 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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@322684 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 2 years ago
2 changed file(s) with 89 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
718718 CurSrcPair = Pair;
719719 ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI,
720720 !DisableAdvCopyOpt, TII);
721 ValueTrackerResult Res;
722 bool ShouldRewrite = false;
723
724 do {
725 // Follow the chain of copies until we reach the top of the use-def chain
726 // or find a more suitable source.
727 Res = ValTracker.getNextSource();
721
722 // Follow the chain of copies until we find a more suitable source, a phi
723 // or have to abort.
724 while (true) {
725 ValueTrackerResult Res = ValTracker.getNextSource();
726 // Abort at the end of a chain (without finding a suitable source).
728727 if (!Res.isValid())
729 break;
728 return false;
730729
731730 // Insert the Def -> Use entry for the recently found source.
732731 ValueTrackerResult CurSrcRes = RewriteMap.lookup(CurSrcPair);
762761 if (TargetRegisterInfo::isPhysicalRegister(CurSrcPair.Reg))
763762 return false;
764763
764 // Keep following the chain if the value isn't any better yet.
765765 const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg);
766 ShouldRewrite = TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC,
767 CurSrcPair.SubReg);
768 } while (!ShouldRewrite);
769
770 // Continue looking for new sources...
771 if (Res.isValid())
772 continue;
773
774 // Do not continue searching for a new source if the there's at least
775 // one use-def which cannot be rewritten.
776 if (!ShouldRewrite)
777 return false;
778 }
779
780 if (PHICount >= RewritePHILimit) {
781 DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
782 return false;
766 if (!TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC, CurSrcPair.SubReg))
767 continue;
768
769 // We currently cannot deal with subreg operands on PHI instructions
770 // (see insertPHI()).
771 if (PHICount > 0 && CurSrcPair.SubReg != 0)
772 continue;
773
774 // We found a suitable source, and are done with this chain.
775 break;
776 }
783777 }
784778
785779 // If we did not find a more suitable source, there is nothing to optimize.
798792 assert(!SrcRegs.empty() && "No sources to create a PHI instruction?");
799793
800794 const TargetRegisterClass *NewRC = MRI->getRegClass(SrcRegs[0].Reg);
795 // NewRC is only correct if no subregisters are involved. findNextSource()
796 // should have rejected those cases already.
797 assert(SrcRegs[0].SubReg == 0 && "should not have subreg operand");
801798 unsigned NewVR = MRI->createVirtualRegister(NewRC);
802799 MachineBasicBlock *MBB = OrigPHI->getParent();
803800 MachineInstrBuilder MIB = BuildMI(*MBB, OrigPHI, OrigPHI->getDebugLoc(),
0 # RUN: llc -o - %s -mtriple=armv7-- -verify-machineinstrs -run-pass=peephole-opt | FileCheck %s
1 #
2 # Make sure we do not crash on this input.
3 # Note that this input could in principle be optimized, but right now we don't
4 # have this case implemented so the output should simply be unchanged.
5 #
6 # CHECK-LABEL: name: func
7 # CHECK: body: |
8 # CHECK: bb.0:
9 # CHECK: Bcc %bb.2, 1, undef %cpsr
10 #
11 # CHECK: bb.1:
12 # CHECK: %0:dpr = IMPLICIT_DEF
13 # CHECK: %1:gpr, %2:gpr = VMOVRRD %0, 14, %noreg
14 # CHECK: B %bb.3
15 #
16 # CHECK: bb.2:
17 # CHECK: %3:spr = IMPLICIT_DEF
18 # CHECK: %4:gpr = VMOVRS %3, 14, %noreg
19 #
20 # CHECK: bb.3:
21 # CHECK: %5:gpr = PHI %1, %bb.1, %4, %bb.2
22 # CHECK: %6:spr = VMOVSR %5, 14, %noreg
23 ---
24 name: func0
25 tracksRegLiveness: true
26 body: |
27 bb.0:
28 Bcc %bb.2, 1, undef %cpsr
29
30 bb.1:
31 %0:dpr = IMPLICIT_DEF
32 %1:gpr, %2:gpr = VMOVRRD %0:dpr, 14, %noreg
33 B %bb.3
34
35 bb.2:
36 %3:spr = IMPLICIT_DEF
37 %4:gpr = VMOVRS %3:spr, 14, %noreg
38
39 bb.3:
40 %5:gpr = PHI %1, %bb.1, %4, %bb.2
41 %6:spr = VMOVSR %5, 14, %noreg
42 ...
43
44 # CHECK-LABEL: name: func1
45 # CHECK: %6:spr = PHI %0, %bb.1, %2, %bb.2
46 # CHEKC: %7:spr = COPY %6
47 ---
48 name: func1
49 tracksRegLiveness: true
50 body: |
51 bb.0:
52 Bcc %bb.2, 1, undef %cpsr
53
54 bb.1:
55 %1:spr = IMPLICIT_DEF
56 %0:gpr = VMOVRS %1, 14, %noreg
57 B %bb.3
58
59 bb.2:
60 %3:spr = IMPLICIT_DEF
61 %2:gpr = VMOVRS %3:spr, 14, %noreg
62
63 bb.3:
64 %4:gpr = PHI %0, %bb.1, %2, %bb.2
65 %5:spr = VMOVSR %4, 14, %noreg
66 ...