This is an archive of the discontinued LLVM Phabricator instance.

[AArch64InstrInfo] Ignore debug insts in canInstrSubstituteCmpInstr [5/10]
ClosedPublic

Authored by vsk on Apr 14 2020, 1:44 PM.

Details

Summary

Fix an issue where the presence of debug info could disable a peephole
optimization in optimizeCompareInstr due to canInstrSubstituteCmpInstr
returning the wrong result.

Depends on D78137.

Diff Detail

Event Timeline

vsk created this revision.Apr 14 2020, 1:44 PM
This revision is now accepted and ready to land.Apr 14 2020, 3:15 PM
fhahn added a subscriber: fhahn.Apr 15 2020, 2:17 AM
fhahn added inline comments.
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
1447

It seems like a few similar changes popped up recently. It might be worth making it a bit easier to iterate over a range of MIs while skipping debug instructions automatically. It's quite easy to construct iterator ranges that skip debug instructions (see snippet below). It might be worth adding a helpers like that. They could also naturally be used for the existing skipDebugInstructionsBackward/skipDebugInstructionsForward

+  auto MIsWithoutDbg =
+      make_filter_range(make_range(std::next(CmpInstr->getIterator()),
+                                   CmpInstr->getParent()->instr_end()),
+                        [](MachineInstr &I) { return !I.isDebugInstr(); });
+  for (const MachineInstr &Instr : MIsWithoutDbg) {
paquette added inline comments.Apr 15 2020, 1:49 PM
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
1447

+1, it seems like this is an extremely easy mistake to make, and it's probably peppered around basically everywhere.

vsk marked an inline comment as done.Apr 15 2020, 2:11 PM
vsk added a subscriber: jmorse.
vsk added inline comments.
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
1447

Thanks for bringing this up. It's not always feasible to use the range-loop idiom, but I agree that it's a good fit here. In cases where the loop iterator is either initialized before the for-init, or modified inside the for-body -- maybe not.

I experimented with some different approaches. Adding 'nodbg' filter_iterator variants for the various MachineBasicBlock iterators did not seem good to me, as it's quite intrusive: a lot of code has to change to adopt the new iterators. Adding helpers that replace std::{next, prev} (but skip debug instructions) could work, but adopting these turned out to be messier than I would've liked. In the end I chose to adapt what we have at the IR-level, but to allow for existing iterators to be passed in.

Zooming way out, I think the long-term plan should be to remove debug instructions from the instruction stream entirely. The recent callSiteInfo work proves this can work. A prerequisite step might be to have DBG_VALUE point to a MachineInstr, like @jmorse proposed in http://lists.llvm.org/pipermail/llvm-dev/2020-February/139440.html.

vsk updated this revision to Diff 257842.Apr 15 2020, 2:12 PM

Introduce a range helper to visit instructions (skipping debug insts)

vsk updated this revision to Diff 257927.Apr 15 2020, 6:20 PM
vsk retitled this revision from [AArch64InstrInfo] Ignore debug insts in canInstrSubstituteCmpInstr to [AArch64InstrInfo] Ignore debug insts in canInstrSubstituteCmpInstr [5/10].
vsk removed subscribers: jmorse, fhahn.

retitle, split out helpers into https://reviews.llvm.org/D78260

vsk added subscribers: jmorse, fhahn.Apr 15 2020, 6:21 PM
fhahn accepted this revision.Apr 16 2020, 3:11 AM

LGTM, thanks

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
1447

I experimented with some different approaches. Adding 'nodbg' filter_iterator variants for the various MachineBasicBlock iterators did not seem good to me, as it's quite intrusive: a lot of code has to change to adopt the new iterators. Adding helpers that replace std::{next, prev} (but skip debug instructions) could work, but adopting these turned out to be messier than I would've liked. In the end I chose to adapt what we have at the IR-level, but to allow for existing iterators to be passed in.

That seems reasonable to me. Having custom start/end points for iterators seems much more common in the backend than in the middle end,

This revision was automatically updated to reflect the committed changes.