summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/PeepholeOptimizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/PeepholeOptimizer.cpp')
-rw-r--r--llvm/lib/CodeGen/PeepholeOptimizer.cpp46
1 files changed, 45 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index fb3e6482bb09..e1d39d64e9fb 100644
--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -1203,6 +1203,18 @@ bool PeepholeOptimizer::optimizeCoalescableCopyImpl(Rewriter &&CpyRewriter) {
if (!NewSrc.Reg)
continue;
+ if (NewSrc.SubReg) {
+ // Verify the register class supports the subregister index. ARM's
+ // copy-like queries return register:subreg pairs where the register's
+ // current class does not directly support the subregister index.
+ const TargetRegisterClass *RC = MRI->getRegClass(NewSrc.Reg);
+ const TargetRegisterClass *WithSubRC =
+ TRI->getSubClassWithSubReg(RC, NewSrc.SubReg);
+ if (!MRI->constrainRegClass(NewSrc.Reg, WithSubRC))
+ continue;
+ Changed = true;
+ }
+
// Rewrite source.
if (CpyRewriter.RewriteCurrentSource(NewSrc.Reg, NewSrc.SubReg)) {
// We may have extended the live-range of NewSrc, account for that.
@@ -1275,6 +1287,18 @@ MachineInstr &PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike,
const TargetRegisterClass *DefRC = MRI->getRegClass(Def.Reg);
Register NewVReg = MRI->createVirtualRegister(DefRC);
+ if (NewSrc.SubReg) {
+ const TargetRegisterClass *NewSrcRC = MRI->getRegClass(NewSrc.Reg);
+ const TargetRegisterClass *WithSubRC =
+ TRI->getSubClassWithSubReg(NewSrcRC, NewSrc.SubReg);
+
+ // The new source may not directly support the subregister, but we should be
+ // able to assume it is constrainable to support the subregister (otherwise
+ // ValueTracker was lying and reported a useless value).
+ if (!MRI->constrainRegClass(NewSrc.Reg, WithSubRC))
+ llvm_unreachable("replacement register cannot support subregister");
+ }
+
MachineInstr *NewCopy =
BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(),
TII->get(TargetOpcode::COPY), NewVReg)
@@ -1905,7 +1929,27 @@ ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
const MachineOperand &Src = Def->getOperand(1);
if (Src.isUndef())
return ValueTrackerResult();
- return ValueTrackerResult(Src.getReg(), Src.getSubReg());
+
+ Register SrcReg = Src.getReg();
+ unsigned SubReg = Src.getSubReg();
+ if (DefSubReg) {
+ const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
+ SubReg = TRI->composeSubRegIndices(SubReg, DefSubReg);
+
+ if (SrcReg.isVirtual()) {
+ // TODO: Try constraining on rewrite if we can
+ const TargetRegisterClass *RegRC = MRI.getRegClass(SrcReg);
+ const TargetRegisterClass *SrcWithSubRC =
+ TRI->getSubClassWithSubReg(RegRC, SubReg);
+ if (RegRC != SrcWithSubRC)
+ return ValueTrackerResult();
+ } else {
+ if (!TRI->getSubReg(SrcReg, SubReg))
+ return ValueTrackerResult();
+ }
+ }
+
+ return ValueTrackerResult(SrcReg, SubReg);
}
ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {