This is an archive of the discontinued LLVM Phabricator instance.

[AArch64InstrInfo] Ignore debug insts in areCFlagsAccessedBetweenInstrs [6/10]
ClosedPublic

Authored by vsk on Apr 14 2020, 2:53 PM.

Details

Summary

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

In test/CodeGen/AArch64/arm64-csel.ll, the issue was found in the
function @foo5, in which the first compare could successfully be
optimized but not the second.

Diff Detail

Event Timeline

vsk created this revision.Apr 14 2020, 2:53 PM
This revision is now accepted and ready to land.Apr 15 2020, 1:56 AM
vsk updated this revision to Diff 257843.Apr 15 2020, 2:15 PM
vsk added a subscriber: fhahn.

Update to use range helper from D78151 (as suggested by @fhahn)

aprantl accepted this revision.Apr 15 2020, 4:45 PM
vsk updated this revision to Diff 257929.Apr 15 2020, 6:24 PM
vsk retitled this revision from [AArch64InstrInfo] Ignore debug insts in areCFlagsAccessedBetweenInstrs to [AArch64InstrInfo] Ignore debug insts in areCFlagsAccessedBetweenInstrs [6/10].
vsk edited the summary of this revision. (Show Details)
vsk removed reviewers: danielkiss, aprantl.
vsk removed a subscriber: fhahn.

retitle

This revision now requires review to proceed.Apr 15 2020, 6:24 PM
vsk accepted this revision.Apr 15 2020, 6:29 PM
vsk added reviewers: danielkiss, aprantl, fhahn.

Undo changes made by Arcanist

This revision is now accepted and ready to land.Apr 15 2020, 6:29 PM
fhahn accepted this revision.Apr 16 2020, 3:09 AM

LGTM, thanks

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

nit: could be reversedInstructionsWithoutDebug(std::prev(To), From).

vsk marked 2 inline comments as done.Apr 16 2020, 1:02 PM
vsk added inline comments.
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
1187

Thanks, I'll fold this into the change before committing if there aren't any further comments.

This revision was automatically updated to reflect the committed changes.
vsk marked an inline comment as done.

This caused a misoptimization for me. With https://martin.st/temp/scene_sad-preproc.c as reproducible source for the issue, I have the following case:

$ clang-good -target aarch64-w64-mingw32 scene_sad-preproc.c -O3 -S -o good
$ clang-bad -target aarch64-w64-mingw32 scene_sad-preproc.c -O3 -S -o bad
$ diff -u good bad
--- good        2020-04-24 11:46:41.372102971 +0300
+++ bad 2020-04-24 11:46:28.440377143 +0300
@@ -156,17 +156,16 @@
        ldrb    w14, [x14, #1]
        add     x12, x12, #2            // =2
        subs    w15, w15, w16
-       sub     w13, w13, w14
+       subs    w13, w13, w14
        cneg    w14, w15, mi
-       cmp     w13, #0                 // =0
        cneg    w13, w13, mi

(With two other unrelated benign differences removed from the diff for clarity.)

In this case, the comparison can't be hoisted into subs past the cneg, as that does use the condition flags.

vsk added a comment.Apr 24 2020, 10:03 AM

This caused a misoptimization for me. With https://martin.st/temp/scene_sad-preproc.c as reproducible source for the issue, I have the following case:

$ clang-good -target aarch64-w64-mingw32 scene_sad-preproc.c -O3 -S -o good
$ clang-bad -target aarch64-w64-mingw32 scene_sad-preproc.c -O3 -S -o bad
$ diff -u good bad
--- good        2020-04-24 11:46:41.372102971 +0300
+++ bad 2020-04-24 11:46:28.440377143 +0300
@@ -156,17 +156,16 @@
        ldrb    w14, [x14, #1]
        add     x12, x12, #2            // =2
        subs    w15, w15, w16
-       sub     w13, w13, w14
+       subs    w13, w13, w14
        cneg    w14, w15, mi
-       cmp     w13, #0                 // =0
        cneg    w13, w13, mi

(With two other unrelated benign differences removed from the diff for clarity.)

In this case, the comparison can't be hoisted into subs past the cneg, as that does use the condition flags.

@mstorsjo thanks for reporting this, and sorry about the breakage. The problem is that explicit conversion in MachineInstrBundleIterator for reverse iterators increments the reverse iterator (MachineInstrBundleIterator(++I.getReverse())), and I missed this fact. Actually the comment there explains "resulting iterator will dereference ... to the previous node, which is somewhat unexpected; but converting the two endpoints in a range will give the same range in reverse". This sort of thing seems easy to mess up, and it means 'reversedInstructionsWithoutDebug' will not behave as advertised. I plan to get rid of that helper and check in a regression test.

vsk added a comment.Apr 24 2020, 11:29 AM

I've removed reversedInstructionsWithoutDebug and added a regression test in c0fa447e02c4cd8c53c3ab03efa6391175e3d56e.