Do not pre-allocate references of D registers pairs if they are extracted from the...
authorEvan Cheng <evan.cheng@apple.com>
Wed, 5 May 2010 22:15:40 +0000 (22:15 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 5 May 2010 22:15:40 +0000 (22:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103124 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/NEONPreAllocPass.cpp

index ef6bf3a132bbb37cf5e875e4fdafba6c869e25d0..59e3280434d9db438d3369c1cb3127d25412cfe4 100644 (file)
@@ -341,20 +341,40 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
 bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
                                         unsigned FirstOpnd, unsigned NumRegs) {
   MachineInstr *RegSeq = 0;
+  unsigned LastSrcReg = 0;
+  unsigned LastSubIdx = 0;
   for (unsigned R = 0; R < NumRegs; ++R) {
     MachineOperand &MO = MI->getOperand(FirstOpnd + R);
     assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
     unsigned VirtReg = MO.getReg();
     assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
            "expected a virtual register");
-    if (!MRI->hasOneNonDBGUse(VirtReg))
-      return false;
-    MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
-    if (UseMI->getOpcode() != TargetOpcode::REG_SEQUENCE)
-      return false;
-    if (RegSeq && RegSeq != UseMI)
-      return false;
-    RegSeq = UseMI;
+    if (MO.isDef()) {
+      // Feeding into a REG_SEQUENCE.
+      if (!MRI->hasOneNonDBGUse(VirtReg))
+        return false;
+      MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
+      if (!UseMI->isRegSequence())
+        return false;
+      if (RegSeq && RegSeq != UseMI)
+        return false;
+      RegSeq = UseMI;
+    } else {
+      // Extracting from a Q register.
+      MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
+      if (!DefMI || !DefMI->isExtractSubreg())
+        return false;
+      VirtReg = DefMI->getOperand(1).getReg();
+      if (LastSrcReg && LastSrcReg != VirtReg)
+        return false;
+      const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
+      if (RC != ARM::QPRRegisterClass)
+        return false;
+      unsigned SubIdx = DefMI->getOperand(2).getImm();
+      if (LastSubIdx && LastSubIdx != SubIdx-1)
+        return false;
+      LastSubIdx = SubIdx;
+    }
   }
   return true;
 }