This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] canonicalize 'not' ops before logical shifts
ClosedPublic

Authored by spatel on Aug 19 2020, 1:13 PM.

Details

Summary

This reverses the existing transform that would uniformly canonicalize any 'xor' after any shift. In the case of logical shifts, that turns a 'not' into an arbitrary 'xor' with constant, and that's probably not as good for analysis, SCEV, or codegen.

The SCEV motivating case is discussed in:
http://bugs.llvm.org/PR47136

There's an analysis motivating case at:
http://bugs.llvm.org/PR38781

I did draft a patch that would do the same for 'ashr' but that's questionable because it's just swapping the position of a 'not' and uncovers at least 2 missing folds that we would probably need to deal with as preliminary steps.

Alive proofs:
https://rise4fun.com/Alive/BBV

Name: shift right of 'not'
Pre: C2 == (-1 u>> C1)
%a = lshr i8 %x, C1
%r = xor i8 %a, C2
  =>
%n = xor i8 %x, -1
%r = lshr i8 %n, C1

Name: shift left of 'not'
Pre: C2 == (-1 << C1)
%a = shl i8 %x, C1
%r = xor i8 %a, C2
  =>
%n = xor i8 %x, -1
%r = shl i8 %n, C1

Name: ashr of 'not'
%a = ashr i8 %x, 1
%r = xor i8 %a, -1
  =>
%n = xor i8 %x, -1
%r = ashr i8 %n, 1

Diff Detail

Event Timeline

spatel created this revision.Aug 19 2020, 1:13 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2020, 1:13 PM
spatel requested review of this revision.Aug 19 2020, 1:13 PM
bjope added a comment.Aug 20 2020, 6:55 AM

I've verified that this resolves https://bugs.llvm.org/show_bug.cgi?id=47136 in the sense that our downstream benchmark result is back to the original result for the tests that had a regression. And without any new regressions. So that is perfect!

bjope added a comment.Aug 20 2020, 6:59 AM

Some SCEV/pipeline tests?

Maybe from https://reviews.llvm.org/D85969#change-8DkHYel6Y1JK ?

I figure we want to move forward with D85969 and land that as well. Right?
I mean, can't ScalarEvolution analysis be used by some pass before instcombine in the pass pipeline. Then I assume it is nice if SCEV treats the two different forms of the equivalent expressions the same way.

Some SCEV/pipeline tests?

Maybe from https://reviews.llvm.org/D85969#change-8DkHYel6Y1JK ?

I think if we are going to add tests to show that instcombine and SCEV are cooperating as expected, that would go in PhaseOrdering. But we need a larger example than what we have in D85969 to show that the IR for some loop is better with this change?

Some SCEV/pipeline tests?

Maybe from https://reviews.llvm.org/D85969#change-8DkHYel6Y1JK ?

I figure we want to move forward with D85969 and land that as well. Right?
I mean, can't ScalarEvolution analysis be used by some pass before instcombine in the pass pipeline. Then I assume it is nice if SCEV treats the two different forms of the equivalent expressions the same way.

I don't know the answer. I agree that making SCEV handle more patterns makes it less brittle, but how much redundancy is needed?

lebedev.ri accepted this revision.Aug 20 2020, 1:57 PM

LGTM

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
3279

// (X l>> C) ^ RHSC --> ~X l>> C

This revision is now accepted and ready to land.Aug 20 2020, 1:57 PM
This revision was automatically updated to reflect the committed changes.
spatel marked an inline comment as done.