public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Joern Wolfgang Rennecke <gnu@amylaar.uk>
To: Marc Glisse <marc.glisse@inria.fr>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: Simplify X * C1 == C2 with undefined overflow
Date: Fri, 07 Aug 2020 21:30:29 +0100	[thread overview]
Message-ID: <5F2DB9E5.7070104@amylaar.uk> (raw)
In-Reply-To: <alpine.DEB.2.23.453.2008071939450.6903@stedding.saclay.inria.fr>


On 07/08/20 19:21, Marc Glisse wrote:
>
> If we are going to handle the wrapping case, we shouldn't limit to the 
> non-wrapping meaning of multiplicity. 3*X==5 should become 
> X==1431655767 (for a 32 bit type), etc.
>
> Do we have an extended gcd somewhere in gcc, to help compute 1431655767?
I don't quite see yet how this relates to gcd, but how how about this:

First, we divide the right hand side of the comparison by the constant 
factor.  5 divided by 3
is one, with rest 2.  Now we want to express this rest two by wrapping 
overflow.
0x100000000 divided by 3 is 0x55555555 rest 1.  When we multiply 
0x55555555 again by three,
the rest is missing, so we get -1 in 32 bit.  So we try to express 2 as 
a multiple of -1:
2/-1 = -2

Thus, the quotient is 1 + 0x55555555 * -2 , which, using 32 bit wrapping 
arithmetic,
is 0x55555557, i.e. 1431655767 .
Again, because the constant factor (3) is odd, there can be no other 
solution.

However, there are cases were the second division will not be possible 
without rest.
Consider : 7*X == 3
3/7 is 0 rest 3.
0x100000000 / 7 is 0x24924924 rest 4
Since 3 cannot be represented as an integer multiple of -4, we can 
conclude that the predicate
is always false.

Also: 14*X == 28
has a non-zero power of two in the constant factor, so we have to factor 
out the power of two
(if the right hand side has a lower power of two, the predicate is 
always false) and consider
in modulo arithmetic with a number of bits less by the factored out 
power of two, i.e. 31 bit here:
7*X == 14
which is solved as above - but in 32 bit arithmetic - to
X == 2
and to convert back to 32 bit arithmetic, we get:
X & 0x7fffffff == 2
or
2*x == 4


Likewise, 14*X == 30 would be reduced to 7*X == 15 in 31 bit arithmetic, 
then we find that
we can't express the rest of 1 as an integer multiple of -2, so the 
predicate is always false.
  .
>
>> (Even if the variable factor is wider than equality comparison, that 
>> is not a problem as long as the comparison is not widened by the 
>> transformation.)
>>
>> On the other hand, the following generalizations would work only 
>> without overflow:
>> - handling of inequality-comparisons - merely have to account for the 
>> sign of the factor reversing the sense of
>>  the inequality, e.g. -3*X >= 15 ---> X <= 5
>
> And again for this one, we have to be careful how we round the 
> division, but we don't have to limit to the case where 15 is a 
> multiple of 3. 3*X>7 can be replaced with X>2.
>
>
> Those are two nice suggestions. Do you intend to write a patch?
No, I just couldn't resist applying a smidge of number theory to a 
compiler problem.
I still have to herd other patches.
> Otherwise I'll try to do it eventually (no promise).
Would be nice.

  reply	other threads:[~2020-08-07 20:30 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-07 13:05 Joern Wolfgang Rennecke
2020-08-07 18:21 ` Marc Glisse
2020-08-07 20:30   ` Joern Wolfgang Rennecke [this message]
2020-08-07 20:57     ` Marc Glisse
2020-08-07 21:02       ` Jakub Jelinek
2020-08-07 21:36         ` Marc Glisse
2020-08-08  6:55           ` Jakub Jelinek
2020-08-07 21:58       ` Joern Wolfgang Rennecke
  -- strict thread matches above, loose matches on Subject: below --
2020-08-01  7:28 Marc Glisse
2020-08-03  8:51 ` Richard Biener
2020-08-04 15:38   ` Marc Glisse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5F2DB9E5.7070104@amylaar.uk \
    --to=gnu@amylaar.uk \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=marc.glisse@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).