This is an archive of the discontinued LLVM Phabricator instance.

[Codegen][SelectionDAG] X u% C == 0 fold: non-splat vectors, accept urem-by-one lines too
AbandonedPublic

Authored by lebedev.ri on Jun 28 2019, 11:54 AM.

Details

Summary

No integer exists for which there is remainder after division by 1.
Incidentally, this fold is only valid for D u> 1. (power-of-two is ok.)
While we could just bailout and let it constant-fold for scalars and
splat vectors, we *do* want to handle non-splat vectors where at least
one divisor happens to be 1.

We know that

  • (X u% 1) == 0 can be constant-folded to 1,
  • (X u% 1) != 0 can be constant-folded to 0,

Also, we know that

  • X u<= -1 can be constant-folded to 1,
  • X u> -1 can be constant-folded to 0,

https://godbolt.org/z/7jnZJX https://rise4fun.com/Alive/oF6p

We know will end up with the following:
(setule/setugt (rotr (mul N, P), K), Q)

Therefore, for given new DAG nodes and comparison predicates (ule/ugt),
we will still produce the correct answer if: Q is a all-ones constant;
and both P and K are *anything* other than undef, let's pick 0,
because there's no point in rotating, and because (X * 0) most
obviously "discards" of the value of X.

Diff Detail

Repository
rL LLVM

Event Timeline

lebedev.ri created this revision.Jun 28 2019, 11:54 AM

Actually, either i'm missing something damningly obvious, or Hacker's Delight is misleading here.
Even without special-casing, we'd still get Q=-1 from the algorithm, and we don't care about P/K.
So there is no real need to special-case D=1 case.
Let me redo all this..

lebedev.ri abandoned this revision.Jun 28 2019, 4:14 PM

Superseded by D63963