diff --git a/lib/Target/ARM/NEONPreAllocPass.cpp b/lib/Target/ARM/NEONPreAllocPass.cpp index d1b1bc87eed..766a9b9e976 100644 --- a/lib/Target/ARM/NEONPreAllocPass.cpp +++ b/lib/Target/ARM/NEONPreAllocPass.cpp @@ -379,6 +379,7 @@ NEONPreAllocPass::FormsRegSequence(MachineInstr *MI, unsigned LastSrcReg = 0; unsigned LastSubIdx = 0; + SmallVector SubIds; for (unsigned R = 0; R < NumRegs; ++R) { const MachineOperand &MO = MI->getOperand(FirstOpnd + R); assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand"); @@ -405,8 +406,33 @@ NEONPreAllocPass::FormsRegSequence(MachineInstr *MI, if (SubIdx != ARM::DSUBREG_0 && SubIdx != ARM::QSUBREG_0) return false; } + SubIds.push_back(SubIdx); LastSubIdx = SubIdx; } + + // FIXME: Update the uses of EXTRACT_SUBREG from REG_SEQUENCE is + // currently required for correctness. e.g. + // %reg1041; = REG_SEQUENCE %reg1040, 5, %reg1035, 6 + // %reg1042 = EXTRACT_SUBREG %reg1041, 6 + // %reg1043 = EXTRACT_SUBREG %reg1041, 5 + // VST1q16 %reg1025, 0, %reg1043, %reg1042, + // reg1025 and reg1043 should be replaced with reg1041:6 and reg1041:5 + // respectively. + // We need to change how we model uses of REG_SEQUENCE. + for (unsigned R = 0; R < NumRegs; ++R) { + MachineOperand &MO = MI->getOperand(FirstOpnd + R); + unsigned OldReg = MO.getReg(); + MachineInstr *DefMI = MRI->getVRegDef(OldReg); + assert(DefMI->isExtractSubreg()); + MO.setReg(LastSrcReg); + MO.setSubReg(SubIds[R]); + if (R != 0) + MO.setIsKill(false); + // Delete the EXTRACT_SUBREG if its result is now dead. + if (MRI->use_empty(OldReg)) + DefMI->eraseFromParent(); + } + return true; }