Allow MachineCSE to coalesce trivial subregister copies the same way
that it coalesces normal copies.
Without this, MachineCSE is powerless to handle redundant operations
with truncated source operands.
This required fixing the 2-addr pass to handle tied subregisters. It
isn't clear what combinations of subregisters can legally be tied, but
the simple case of truncated source operands is now safely handled:
%vreg11<def> = COPY %vreg1:sub_32bit; GR32:%vreg11 GR64:%vreg1
%vreg12<def> = COPY %vreg2:sub_32bit; GR32:%vreg12 GR64:%vreg2
%vreg13<def,tied1> = ADD32rr %vreg11<tied0>, %vreg12<kill>, %EFLAGS<imp-def>
llvm-svn: 197414
diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp
index 2e90f74..80982bc 100644
--- a/llvm/lib/CodeGen/MachineCSE.cpp
+++ b/llvm/lib/CodeGen/MachineCSE.cpp
@@ -131,13 +131,18 @@
unsigned SrcReg = DefMI->getOperand(1).getReg();
if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
continue;
- if (DefMI->getOperand(0).getSubReg() || DefMI->getOperand(1).getSubReg())
+ if (DefMI->getOperand(0).getSubReg())
continue;
- if (!MRI->constrainRegClass(SrcReg, MRI->getRegClass(Reg)))
+ unsigned SrcSubReg = DefMI->getOperand(1).getSubReg();
+ const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+ if (SrcSubReg)
+ RC = TRI->getMatchingSuperRegClass(MRI->getRegClass(SrcReg), RC,
+ SrcSubReg);
+ if (!MRI->constrainRegClass(SrcReg, RC))
continue;
DEBUG(dbgs() << "Coalescing: " << *DefMI);
DEBUG(dbgs() << "*** to: " << *MI);
- MO.setReg(SrcReg);
+ MO.substVirtReg(SrcReg, SrcSubReg, *TRI);
MRI->clearKillFlags(SrcReg);
DefMI->eraseFromParent();
++NumCoalesces;