// defined registers.
if (RegMask) {
// Erase any MaybeDeadCopies whose destination register is clobbered.
- for (MachineInstr *MaybeDead : MaybeDeadCopies) {
+ for (SmallSetVector<MachineInstr *, 8>::iterator DI =
+ MaybeDeadCopies.begin();
+ DI != MaybeDeadCopies.end();) {
+ MachineInstr *MaybeDead = *DI;
unsigned Reg = MaybeDead->getOperand(0).getReg();
assert(!MRI->isReserved(Reg));
- if (!RegMask->clobbersPhysReg(Reg))
+
+ if (!RegMask->clobbersPhysReg(Reg)) {
+ ++DI;
continue;
+ }
+
DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: ";
MaybeDead->dump());
+
+ // erase() will return the next valid iterator pointing to the next
+ // element after the erased one.
+ DI = MaybeDeadCopies.erase(DI);
MaybeDead->eraseFromParent();
Changed = true;
++NumDeletes;
}
- MaybeDeadCopies.clear();
removeClobberedRegsFromMap(AvailCopyMap, *RegMask);
removeClobberedRegsFromMap(CopyMap, *RegMask);
return Changed;
}
+
--- /dev/null
+
+# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass machine-cp -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+ define i32 @copyprop1(i32 %a, i32 %b) { ret i32 %a }
+ define i32 @copyprop2(i32 %a, i32 %b) { ret i32 %a }
+ define i32 @copyprop3(i32 %a, i32 %b) { ret i32 %a }
+ define i32 @copyprop4(i32 %a, i32 %b) { ret i32 %a }
+ declare i32 @foo(i32)
+...
+---
+# The first copy is dead copy which is not used.
+# CHECK-LABEL: name: copyprop1
+# CHECK: bb.0:
+# CHECK-NOT: %w20 = COPY
+name: copyprop1
+body: |
+ bb.0:
+ liveins: %w0, %w1
+ %w20 = COPY %w1
+ BL @foo, csr_aarch64_aapcs, implicit %w0, implicit-def %w0
+ RET_ReallyLR implicit %w0
+...
+---
+# The first copy is not a dead copy which is used in the second copy after the
+# call.
+# CHECK-LABEL: name: copyprop2
+# CHECK: bb.0:
+# CHECK: %w20 = COPY
+name: copyprop2
+body: |
+ bb.0:
+ liveins: %w0, %w1
+ %w20 = COPY %w1
+ BL @foo, csr_aarch64_aapcs, implicit %w0, implicit-def %w0
+ %w0 = COPY %w20
+ RET_ReallyLR implicit %w0
+...
+---
+# Both the first and second copy are dead copies which are not used.
+# CHECK-LABEL: name: copyprop3
+# CHECK: bb.0:
+# CHECK-NOT: COPY
+name: copyprop3
+body: |
+ bb.0:
+ liveins: %w0, %w1
+ %w20 = COPY %w1
+ BL @foo, csr_aarch64_aapcs, implicit %w0, implicit-def %w0
+ %w20 = COPY %w0
+ RET_ReallyLR implicit %w0
+...
+# The second copy is removed as a NOP copy, after then the first copy become
+# dead which should be removed as well.
+# CHECK-LABEL: name: copyprop4
+# CHECK: bb.0:
+# CHECK-NOT: COPY
+name: copyprop4
+body: |
+ bb.0:
+ liveins: %w0, %w1
+ %w20 = COPY %w0
+ %w0 = COPY %w20
+ BL @foo, csr_aarch64_aapcs, implicit %w0, implicit-def %w0
+ RET_ReallyLR implicit %w0
+...
+