summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-08-29 01:58:55 +0000
committerAndrew Trick <atrick@apple.com>2012-08-29 01:58:55 +0000
commitbd0073ddd7fffe53b05bfd6c8324c9c6b3e6e7a5 (patch)
tree593c76e9a178dbb6eca993a79535f8eebe3e4775 /llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
parent4cc6949a2bd0b8c7f246d8deee984f9c92fb2490 (diff)
downloadbcm5719-llvm-bd0073ddd7fffe53b05bfd6c8324c9c6b3e6e7a5.tar.gz
bcm5719-llvm-bd0073ddd7fffe53b05bfd6c8324c9c6b3e6e7a5.zip
Fix ARM vector copies of overlapping register tuples.
I have tested the fix, but have not been successfull in generating a robust unit test. This can only be exposed through particular register assignments. llvm-svn: 162821
Diffstat (limited to 'llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 5191c3eabea..f3c9cf4e434 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -710,10 +710,23 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
const TargetRegisterInfo *TRI = &getRegisterInfo();
MachineInstrBuilder Mov;
+
+ // Copy register tuples backward when the first Dest reg overlaps with SrcReg.
+ if (TRI->regsOverlap(SrcReg, TRI->getSubReg(DestReg, BeginIdx))) {
+ BeginIdx = BeginIdx + ((SubRegs-1)*Spacing);
+ Spacing = -Spacing;
+ }
+#ifndef NDEBUG
+ SmallSet<unsigned, 4> DstRegs;
+#endif
for (unsigned i = 0; i != SubRegs; ++i) {
unsigned Dst = TRI->getSubReg(DestReg, BeginIdx + i*Spacing);
unsigned Src = TRI->getSubReg(SrcReg, BeginIdx + i*Spacing);
assert(Dst && Src && "Bad sub-register");
+#ifndef NDEBUG
+ DstRegs.insert(Dst);
+ assert(!DstRegs.count(Src) && "destructive vector copy");
+#endif
Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst)
.addReg(Src);
// VORR takes two source operands.
OpenPOWER on IntegriCloud