This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Canonicalize ((X & -X) - 1) --> (~X & (X - 1)) (PR51784)
ClosedPublic

Authored by RKSimon on Sep 25 2021, 1:15 PM.

Diff Detail

Event Timeline

RKSimon created this revision.Sep 25 2021, 1:15 PM
RKSimon requested review of this revision.Sep 25 2021, 1:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 25 2021, 1:15 PM

An alternative would be to decide if (~x & (x - 1)) or ((x & -x ) - 1) should be the canonical pattern?

https://alive2.llvm.org/ce/z/WA_cmX

An alternative would be to decide if (~x & (x - 1)) or ((x & -x ) - 1) should be the canonical pattern?

https://alive2.llvm.org/ce/z/WA_cmX

Yeah I was thinking about some more general pattern too. @spatel?

An alternative would be to decide if (~x & (x - 1)) or ((x & -x ) - 1) should be the canonical pattern?

https://alive2.llvm.org/ce/z/WA_cmX

Yeah I was thinking about some more general pattern too. @spatel?

I'd go with the 'not' pattern since that is likely better for known bits - and that's what we were already expecting here.
But if either of the 'and' or 'sub' ops has an extra use, then we can't do the 'not' canonicalization, so we'd want this fold too.

So this patch might be made less important with the 'not' canonicalization, but it could still fire.
I expect this has no detectable compile-time cost and it's a one-line patch, so seems fine to keep it.
But please add tests with extra uses on the preceding ops, so we have motivating (even if they are contrived) regression tests for this patch. That would still show the value of this patch whether we do the other transform or not.

Having spoken to @spatel offline, I'm going to add a fold for ((x & -x ) - 1) -> (~x & (x - 1)) as well as the ctpop fold - this will require single/multiuse tests for the inner fold (where it shouldn't fold multiuses) and for the ctpop case (where it should always fold to cttz).

RKSimon planned changes to this revision.Sep 28 2021, 12:53 AM
RKSimon updated this revision to Diff 455168.Aug 24 2022, 5:10 AM
RKSimon retitled this revision from [InstCombine] Fold ctpop((x & -x ) - 1) -> cttz(x, false) (PR51784) to [InstCombine] Canonicalize ((X & -X) - 1) --> (~X & (X - 1)) (PR51784).
RKSimon edited the summary of this revision. (Show Details)
RKSimon added a reviewer: nikic.

Replaced the ctpop fold with a generic ((X & -X) - 1) --> (~X & (X - 1)) canonicalization

Herald added a project: Restricted Project. · View Herald TranscriptAug 24 2022, 5:10 AM
RKSimon edited the summary of this revision. (Show Details)Aug 24 2022, 5:11 AM
spatel added inline comments.Aug 24 2022, 6:07 AM
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
1420 ↗(On Diff #455168)

The -1 constant should always be canonicalized to operand 1 (RHS), so this doesn't really need to match m_c_Add. You could match each of LHS and RHS instead.

spatel added inline comments.Aug 24 2022, 6:10 AM
llvm/test/Transforms/InstCombine/add-mask-neg.ll
29 ↗(On Diff #455168)

This test gets canonicalized by complexity, so it's not testing the pattern that was intended. Needs another instruction to thwart that transform.

RKSimon updated this revision to Diff 455183.Aug 24 2022, 6:25 AM

Use m_Add instead of m_c_Add as it'll canonicalise to RHS constant anyway

RKSimon marked 2 inline comments as done.Aug 24 2022, 6:41 AM
spatel accepted this revision.Aug 24 2022, 6:58 AM

LGTM

This revision is now accepted and ready to land.Aug 24 2022, 6:58 AM
This revision was landed with ongoing or failed builds.Aug 24 2022, 7:31 AM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Aug 24 2022, 8:17 AM

This breaks check-llvm on non-win afaict: http://45.33.8.238/linux/84811/step_12.txt

Please take a look and revert for now if it takes a while to fix.

xbolva00 added inline comments.Aug 24 2022, 8:21 AM
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
1424 ↗(On Diff #455205)

Nondet output? Different evaluation order of args between compilers

spatel added inline comments.Aug 24 2022, 8:29 AM
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
1424 ↗(On Diff #455205)

Good catch - yeah, use local variables to ensure that the xor and add are inserted in a fixed order.

RKSimon added inline comments.Aug 24 2022, 8:30 AM
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
1424 ↗(On Diff #455205)

yup - I've reverted and have a fix testing on wsl2 now