RegisterCoalescer: Don't rematerialize subregister definitions.
authorMatthias Braun <matze@braunis.de>
Mon, 16 Feb 2015 22:05:17 +0000 (22:05 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 16 Feb 2015 22:05:17 +0000 (22:05 +0000)
We cannot simply rematerialize instructions which only defining a
subregister, as the final value also depends on the previous
instructions.

This fixes test/CodeGen/R600/subreg-coalescer-bug.ll with subreg
liveness enabled.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229444 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegisterCoalescer.cpp

index edcd7b22d3cbc9e2b19d7c15e2183129e0896ce7..a8afd48bdf5a8349577af42e9c85dc1627047924 100644 (file)
@@ -815,6 +815,22 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
   return true;
 }
 
+/// Returns true if @p MI defines the full vreg @p Reg, as opposed to just
+/// defining a subregister.
+static bool definesFullReg(const MachineInstr &MI, unsigned Reg) {
+  assert(!TargetRegisterInfo::isPhysicalRegister(Reg) &&
+         "This code cannot handle physreg aliasing");
+  for (const MachineOperand &Op : MI.operands()) {
+    if (!Op.isReg() || !Op.isDef() || Op.getReg() != Reg)
+      continue;
+    // Return true if we define the full register or don't care about the value
+    // inside other subregisters.
+    if (Op.getSubReg() == 0 || Op.isUndef())
+      return true;
+  }
+  return false;
+}
+
 bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
                                                 MachineInstr *CopyMI,
                                                 bool &IsDefCopy) {
@@ -843,6 +859,8 @@ bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
     return false;
   if (!TII->isTriviallyReMaterializable(DefMI, AA))
     return false;
+  if (!definesFullReg(*DefMI, SrcReg))
+    return false;
   bool SawStore = false;
   if (!DefMI->isSafeToMove(TII, AA, SawStore))
     return false;