This is an archive of the discontinued LLVM Phabricator instance.

[TargetLowering] x s% C == 0 fold: vector divisor with INT_MIN handling
ClosedPublic

Authored by lebedev.ri on Aug 15 2019, 8:25 AM.

Details

Summary

The general fold is only valid for positive divisors.
Which effectively means, it is invalid for INT_MIN divisors,
and we currently bailout if we see them.

But that is too strict, we can just fix-up the results.
For that, let's do a second computation 'in parallel':

Name: srem -> and
Pre: isPowerOf2(C)
%o = srem i8 %X, C
%r = icmp eq %o, 0
  =>
%n = and i8 %X, C-1
%r = icmp eq %n, 0

https://rise4fun.com/Alive/Sup

And then just blend results: if the divisor was INT_MIN,
pick the value we got via bit-test,
else pick the value from general fold.

There's interesting observation - ISD::ROTR is set to
LegalizeAction::Expand before AVX512, so we should not
treat INT_MIN divisor as even; and as it can be seen
while @test_srem_odd_even_one improves on all run-lines,
@test_srem_odd_even_INT_MIN only improves for AVX512.

Diff Detail

Event Timeline

lebedev.ri created this revision.Aug 15 2019, 8:25 AM

a couple of minor comments

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
5137

typo: we don't care about

5232

(style) early out for non HadIntMinDivisor:

if (!HadIntMinDivisor)
  return Res;
lebedev.ri marked 2 inline comments as done.

Nits adderessed, thanks for taking a look.

RKSimon accepted this revision.Aug 19 2019, 7:53 AM

LGTM with more minor I noticed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
5231

(nit) channels -> lanes ?

This revision is now accepted and ready to land.Aug 19 2019, 7:53 AM

LGTM with more minor I noticed

Thank you for the review.

This revision was automatically updated to reflect the committed changes.