diff mbox series

Add divide by zero side effect.

Message ID c511febf-7a4d-1754-1893-ac77602a18d5@redhat.com
State New
Headers show
Series Add divide by zero side effect. | expand

Commit Message

Andrew MacLeod May 17, 2022, 6:39 p.m. UTC
I haven't checked this patch in yet.  This implements a side effect that 
the divisor cannot be 0 after a divide executes. This allows us to fold 
the divide away:

a = b / c;
if (c == 0)
   dead();

This bootstraps on x86_64-pc-linux-gnu with no regressions, but I first 
wanted to check to see if there are some flags or conditions that should 
e checked in order NOT to do this optimization.  I am guessing there is 
probably something :-)    Anyway, this is how we straightforwardly add 
side effects now.

Does the patch conditions need tweaking to apply the side effect?

Andrew

Comments

Richard Biener May 18, 2022, 6:28 a.m. UTC | #1
On Tue, May 17, 2022 at 8:40 PM Andrew MacLeod via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> I haven't checked this patch in yet.  This implements a side effect that
> the divisor cannot be 0 after a divide executes. This allows us to fold
> the divide away:
>
> a = b / c;
> if (c == 0)
>    dead();
>
> This bootstraps on x86_64-pc-linux-gnu with no regressions, but I first
> wanted to check to see if there are some flags or conditions that should
> e checked in order NOT to do this optimization.  I am guessing there is
> probably something :-)    Anyway, this is how we straightforwardly add
> side effects now.
>
> Does the patch conditions need tweaking to apply the side effect?

What does "after the stmt" mean?  If the stmt throws internally then on
the EH edge the divisor can be zero.

How do you fold away the divide in your above example?

Richard.

>
> Andrew
>
Andrew MacLeod May 18, 2022, 1:20 p.m. UTC | #2
On 5/18/22 02:28, Richard Biener wrote:
> On Tue, May 17, 2022 at 8:40 PM Andrew MacLeod via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>> I haven't checked this patch in yet.  This implements a side effect that
>> the divisor cannot be 0 after a divide executes. This allows us to fold
>> the divide away:
>>
>> a = b / c;
>> if (c == 0)
>>     dead();
>>
>> This bootstraps on x86_64-pc-linux-gnu with no regressions, but I first
>> wanted to check to see if there are some flags or conditions that should
>> e checked in order NOT to do this optimization.  I am guessing there is
>> probably something :-)    Anyway, this is how we straightforwardly add
>> side effects now.
>>
>> Does the patch conditions need tweaking to apply the side effect?
> What does "after the stmt" mean?  If the stmt throws internally then on
> the EH edge the divisor can be zero.
>
> How do you fold away the divide in your above example?
>
We dont fold anyway the divide, just the condition checking if c == 0.. 
this would be identical in function to

b= *ptr;
if (ptr == 0)
   dead();

after the b = *ptr stmt is done, ptr is known to be non-zero. likewise,  
after a = b / c, all subsequent stmts know c is non-zero

Any outgoing EH edge from the block will not have this side effect 
applied (ie ptr and c will still be varying, or whatever they were to 
start).  All other edges will have the non-zero effect, as will any 
stmts in this block which occur after the initial one that triggers the 
side effect.

Andrew
Segher Boessenkool May 18, 2022, 6:13 p.m. UTC | #3
On Tue, May 17, 2022 at 02:39:11PM -0400, Andrew MacLeod via Gcc-patches wrote:
> I haven't checked this patch in yet.  This implements a side effect that 
> the divisor cannot be 0 after a divide executes. This allows us to fold 
> the divide away:

"Side effect" already has a meaning, very commonly used in language
theory, and even in the C standard itself: a function has a side effect
if it does something more than just return a value: if it changes state.
This can be some I/O, or it can just be writing to some non-local data.

Side effects are crucial to what a compiler does, and they are used all
over the place (the gcc/ dir has some thousand mentions of it for
example).

Please don't make life hard for everyone by overloading this term.


Segher
Andrew MacLeod May 18, 2022, 8:24 p.m. UTC | #4
On 5/18/22 14:13, Segher Boessenkool wrote:
> On Tue, May 17, 2022 at 02:39:11PM -0400, Andrew MacLeod via Gcc-patches wrote:
>> I haven't checked this patch in yet.  This implements a side effect that
>> the divisor cannot be 0 after a divide executes. This allows us to fold
>> the divide away:
> "Side effect" already has a meaning, very commonly used in language
> theory, and even in the C standard itself: a function has a side effect
> if it does something more than just return a value: if it changes state.
> This can be some I/O, or it can just be writing to some non-local data.
>
> Side effects are crucial to what a compiler does, and they are used all
> over the place (the gcc/ dir has some thousand mentions of it for
> example).
>
> Please don't make life hard for everyone by overloading this term.
>
I'm open to suggestions for a better term!

Is there a commonly used alternate term to describe an observable effect 
on the value of an input operand?

Andrew
Segher Boessenkool May 18, 2022, 8:40 p.m. UTC | #5
On Wed, May 18, 2022 at 04:24:06PM -0400, Andrew MacLeod wrote:
> On 5/18/22 14:13, Segher Boessenkool wrote:
> >"Side effect" already has a meaning, very commonly used in language
> >theory, and even in the C standard itself: a function has a side effect
> >if it does something more than just return a value: if it changes state.
> >This can be some I/O, or it can just be writing to some non-local data.
> >
> >Side effects are crucial to what a compiler does, and they are used all
> >over the place (the gcc/ dir has some thousand mentions of it for
> >example).
> >
> >Please don't make life hard for everyone by overloading this term.
> >
> I'm open to suggestions for a better term!

Glad to hear that, and this isn't set in stione yet!

> Is there a commonly used alternate term to describe an observable effect 
> on the value of an input operand?

I'd use something with "known" in the name.  But:

As far as I understand what you are doing this is not an effect on the
operand at all!  It cannot be one even, the operand is an input only
after all.  Instead, it changes what is known about the value of that
input: it cannot be 0 in this case, it is known to not be 0.

This is similar to other known value things we have in GCC already.  Can
you not just use one of those, even?  What are the benefit to this new
abstraction?


Segher
Andrew MacLeod May 19, 2022, 1:22 p.m. UTC | #6
On 5/18/22 16:40, Segher Boessenkool wrote:
> On Wed, May 18, 2022 at 04:24:06PM -0400, Andrew MacLeod wrote:
>> On 5/18/22 14:13, Segher Boessenkool wrote:
>>> "Side effect" already has a meaning, very commonly used in language
>>> theory, and even in the C standard itself: a function has a side effect
>>> if it does something more than just return a value: if it changes state.
>>> This can be some I/O, or it can just be writing to some non-local data.
>>>
>>> Side effects are crucial to what a compiler does, and they are used all
>>> over the place (the gcc/ dir has some thousand mentions of it for
>>> example).
>>>
>>> Please don't make life hard for everyone by overloading this term.
>>>
>> I'm open to suggestions for a better term!
> Glad to hear that, and this isn't set in stione yet!
>
>> Is there a commonly used alternate term to describe an observable effect
>> on the value of an input operand?
> I'd use something with "known" in the name.  But:
>
> As far as I understand what you are doing this is not an effect on the
> operand at all!  It cannot be one even, the operand is an input only
> after all.  Instead, it changes what is known about the value of that
> input: it cannot be 0 in this case, it is known to not be 0.
>
> This is similar to other known value things we have in GCC already.  Can
> you not just use one of those, even?  What are the benefit to this new
> abstraction?

Well, This is a component of ranger tracking value ranges..  it is 
recording the "side-effect" of the stmt on the known range of an object. 
The file is called  "gimple-range-side-effect.h"

Its a generalization of how ranger tracks non-null pointer values, 
enabling it to track arbitrary observable ranges values. (The old 
mechanism also utilized immediate-use chains, which prevented it from 
being utilized in gimple-folding)

WIth this change, we can also track things like a = b / c causing the 
effect that c is known non-zero after the statement if there were no 
traps, or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31178 , which 
after 15 years, we can now simply indicate that for  a = b >> c , its 
only defined behaviour if c is in the range [0, PRECISION(b)]

So its basically just a generalization of how we track known values 
within the range system.

Andrew
Segher Boessenkool May 19, 2022, 10:23 p.m. UTC | #7
On Thu, May 19, 2022 at 09:22:32AM -0400, Andrew MacLeod wrote:
> On 5/18/22 16:40, Segher Boessenkool wrote:
> >On Wed, May 18, 2022 at 04:24:06PM -0400, Andrew MacLeod wrote:
> >>On 5/18/22 14:13, Segher Boessenkool wrote:
> >>>"Side effect" already has a meaning, very commonly used in language
> >>>theory, and even in the C standard itself: a function has a side effect
> >>>if it does something more than just return a value: if it changes state.
> >>>This can be some I/O, or it can just be writing to some non-local data.
> >>>
> >>>Side effects are crucial to what a compiler does, and they are used all
> >>>over the place (the gcc/ dir has some thousand mentions of it for
> >>>example).
> >>>
> >>>Please don't make life hard for everyone by overloading this term.
> >>>
> >>I'm open to suggestions for a better term!
> >Glad to hear that, and this isn't set in stione yet!
> >
> >>Is there a commonly used alternate term to describe an observable effect
> >>on the value of an input operand?
> >I'd use something with "known" in the name.  But:
> >
> >As far as I understand what you are doing this is not an effect on the
> >operand at all!  It cannot be one even, the operand is an input only
> >after all.  Instead, it changes what is known about the value of that
> >input: it cannot be 0 in this case, it is known to not be 0.
> >
> >This is similar to other known value things we have in GCC already.  Can
> >you not just use one of those, even?  What are the benefit to this new
> >abstraction?
> 
> Well, This is a component of ranger tracking value ranges..  it is 
> recording the "side-effect" of the stmt on the known range of an object. 
> The file is called  "gimple-range-side-effect.h"

So the file name is confusingly wrong as well.

> Its a generalization of how ranger tracks non-null pointer values, 
> enabling it to track arbitrary observable ranges values. (The old 
> mechanism also utilized immediate-use chains, which prevented it from 
> being utilized in gimple-folding)
> 
> WIth this change, we can also track things like a = b / c causing the 
> effect that c is known non-zero after the statement if there were no 
> traps, or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31178 , which 
> after 15 years, we can now simply indicate that for  a = b >> c , its 
> only defined behaviour if c is in the range [0, PRECISION(b)]
> 
> So its basically just a generalization of how we track known values 
> within the range system.

Sure.  Just the name is harmful :-(


Segher
Andrew MacLeod May 20, 2022, 2:14 a.m. UTC | #8
On 5/19/22 18:23, Segher Boessenkool wrote:
> On Thu, May 19, 2022 at 09:22:32AM -0400, Andrew MacLeod wrote:
>> On 5/18/22 16:40, Segher Boessenkool wrote:
>>> On Wed, May 18, 2022 at 04:24:06PM -0400, Andrew MacLeod wrote:
>>>> On 5/18/22 14:13, Segher Boessenkool wrote:
>>>>> "Side effect" already has a meaning, very commonly used in language
>>>>> theory, and even in the C standard itself: a function has a side effect
>>>>> if it does something more than just return a value: if it changes state.
>>>>> This can be some I/O, or it can just be writing to some non-local data.
>>>>>
>>>>> Side effects are crucial to what a compiler does, and they are used all
>>>>> over the place (the gcc/ dir has some thousand mentions of it for
>>>>> example).
>>>>>
>>>>> Please don't make life hard for everyone by overloading this term.
>>>>>
>>>> I'm open to suggestions for a better term!
>>> Glad to hear that, and this isn't set in stione yet!
>>>
>>>> Is there a commonly used alternate term to describe an observable effect
>>>> on the value of an input operand?
>>> I'd use something with "known" in the name.  But:
>>>
>>> As far as I understand what you are doing this is not an effect on the
>>> operand at all!  It cannot be one even, the operand is an input only
>>> after all.  Instead, it changes what is known about the value of that
>>> input: it cannot be 0 in this case, it is known to not be 0.
>>>
>>> This is similar to other known value things we have in GCC already.  Can
>>> you not just use one of those, even?  What are the benefit to this new
>>> abstraction?
>> Well, This is a component of ranger tracking value ranges..  it is
>> recording the "side-effect" of the stmt on the known range of an object.
>> The file is called  "gimple-range-side-effect.h"
> So the file name is confusingly wrong as well.
>
>> Its a generalization of how ranger tracks non-null pointer values,
>> enabling it to track arbitrary observable ranges values. (The old
>> mechanism also utilized immediate-use chains, which prevented it from
>> being utilized in gimple-folding)
>>
>> WIth this change, we can also track things like a = b / c causing the
>> effect that c is known non-zero after the statement if there were no
>> traps, or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31178 , which
>> after 15 years, we can now simply indicate that for  a = b >> c , its
>> only defined behaviour if c is in the range [0, PRECISION(b)]
>>
>> So its basically just a generalization of how we track known values
>> within the range system.
> Sure.  Just the name is harmful :-(
>
Still waiting for a suggestion, since "side effect" is the description 
that made sense to me :-)

Andrew
Richard Biener May 20, 2022, 6:25 a.m. UTC | #9
On Fri, May 20, 2022 at 4:15 AM Andrew MacLeod via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On 5/19/22 18:23, Segher Boessenkool wrote:
> > On Thu, May 19, 2022 at 09:22:32AM -0400, Andrew MacLeod wrote:
> >> On 5/18/22 16:40, Segher Boessenkool wrote:
> >>> On Wed, May 18, 2022 at 04:24:06PM -0400, Andrew MacLeod wrote:
> >>>> On 5/18/22 14:13, Segher Boessenkool wrote:
> >>>>> "Side effect" already has a meaning, very commonly used in language
> >>>>> theory, and even in the C standard itself: a function has a side effect
> >>>>> if it does something more than just return a value: if it changes state.
> >>>>> This can be some I/O, or it can just be writing to some non-local data.
> >>>>>
> >>>>> Side effects are crucial to what a compiler does, and they are used all
> >>>>> over the place (the gcc/ dir has some thousand mentions of it for
> >>>>> example).
> >>>>>
> >>>>> Please don't make life hard for everyone by overloading this term.
> >>>>>
> >>>> I'm open to suggestions for a better term!
> >>> Glad to hear that, and this isn't set in stione yet!
> >>>
> >>>> Is there a commonly used alternate term to describe an observable effect
> >>>> on the value of an input operand?
> >>> I'd use something with "known" in the name.  But:
> >>>
> >>> As far as I understand what you are doing this is not an effect on the
> >>> operand at all!  It cannot be one even, the operand is an input only
> >>> after all.  Instead, it changes what is known about the value of that
> >>> input: it cannot be 0 in this case, it is known to not be 0.
> >>>
> >>> This is similar to other known value things we have in GCC already.  Can
> >>> you not just use one of those, even?  What are the benefit to this new
> >>> abstraction?
> >> Well, This is a component of ranger tracking value ranges..  it is
> >> recording the "side-effect" of the stmt on the known range of an object.
> >> The file is called  "gimple-range-side-effect.h"
> > So the file name is confusingly wrong as well.
> >
> >> Its a generalization of how ranger tracks non-null pointer values,
> >> enabling it to track arbitrary observable ranges values. (The old
> >> mechanism also utilized immediate-use chains, which prevented it from
> >> being utilized in gimple-folding)
> >>
> >> WIth this change, we can also track things like a = b / c causing the
> >> effect that c is known non-zero after the statement if there were no
> >> traps, or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31178 , which
> >> after 15 years, we can now simply indicate that for  a = b >> c , its
> >> only defined behaviour if c is in the range [0, PRECISION(b)]
> >>
> >> So its basically just a generalization of how we track known values
> >> within the range system.
> > Sure.  Just the name is harmful :-(
> >
> Still waiting for a suggestion, since "side effect" is the description
> that made sense to me :-)

I think side-effect captures it quite well even if it overlaps with a term
used in language standards.  Doing c = a << b has the side-effect on
imposing a range on 'b' rather than just affecting 'c' (and its range).
You could call it 'alternate effect' but that sounds just awkward ;)

Richard.

> Andrew
>
Alexander Monakov May 20, 2022, 6:38 a.m. UTC | #10
On Fri, 20 May 2022, Richard Biener via Gcc-patches wrote:

> > Still waiting for a suggestion, since "side effect" is the description
> > that made sense to me :-)
> 
> I think side-effect captures it quite well even if it overlaps with a term
> used in language standards.  Doing c = a << b has the side-effect on
> imposing a range on 'b' rather than just affecting 'c' (and its range).
> You could call it 'alternate effect' but that sounds just awkward ;)

I suggest 'deduce', 'deduction', 'deducing a range'. What the code is actually
doing is deducing that 'b' in 'a / b' cannot be zero. Function in GCC might be
called like 'deduce_ranges_from_stmt'.

Please don't overload 'side effect' if possible.

Alexander
Richard Biener May 20, 2022, 8:04 a.m. UTC | #11
On Fri, May 20, 2022 at 8:38 AM Alexander Monakov <amonakov@ispras.ru> wrote:
>
> On Fri, 20 May 2022, Richard Biener via Gcc-patches wrote:
>
> > > Still waiting for a suggestion, since "side effect" is the description
> > > that made sense to me :-)
> >
> > I think side-effect captures it quite well even if it overlaps with a term
> > used in language standards.  Doing c = a << b has the side-effect on
> > imposing a range on 'b' rather than just affecting 'c' (and its range).
> > You could call it 'alternate effect' but that sounds just awkward ;)
>
> I suggest 'deduce', 'deduction', 'deducing a range'. What the code is actually
> doing is deducing that 'b' in 'a / b' cannot be zero. Function in GCC might be
> called like 'deduce_ranges_from_stmt'.

So how would you call determining the range of 'c' from the ranges of
'a' and 'b',
isn't that 'deduction' as well?

> Please don't overload 'side effect' if possible.
>
> Alexander
Eric Botcazou May 20, 2022, 8:11 a.m. UTC | #12
> I suggest 'deduce', 'deduction', 'deducing a range'. What the code is
> actually doing is deducing that 'b' in 'a / b' cannot be zero. Function in
> GCC might be called like 'deduce_ranges_from_stmt'.

Or "infer", "inference", "inferring a range".

> Please don't overload 'side effect' if possible.

Agreed, "side effect" is something precisely defined in the compiler context.
Eric Botcazou May 20, 2022, 8:13 a.m. UTC | #13
> I think side-effect captures it quite well even if it overlaps with a term
> used in language standards.

IMO it's very confusing, see the subject: "Add divide by zero side effect".
The only side effect of dividing by zero is (possibly) raising a trap.
Alexander Monakov May 20, 2022, 8:17 a.m. UTC | #14
On Fri, 20 May 2022, Richard Biener wrote:

> On Fri, May 20, 2022 at 8:38 AM Alexander Monakov <amonakov@ispras.ru> wrote:
> >
> > On Fri, 20 May 2022, Richard Biener via Gcc-patches wrote:
> >
> > > > Still waiting for a suggestion, since "side effect" is the description
> > > > that made sense to me :-)
> > >
> > > I think side-effect captures it quite well even if it overlaps with a term
> > > used in language standards.  Doing c = a << b has the side-effect on
> > > imposing a range on 'b' rather than just affecting 'c' (and its range).
> > > You could call it 'alternate effect' but that sounds just awkward ;)
> >
> > I suggest 'deduce', 'deduction', 'deducing a range'. What the code is actually
> > doing is deducing that 'b' in 'a / b' cannot be zero. Function in GCC might be
> > called like 'deduce_ranges_from_stmt'.
> 
> So how would you call determining the range of 'c' from the ranges of
> 'a' and 'b', isn't that 'deduction' as well?

Kind of, yes, but for this sort of forward inference I imagine you're already
using 'propagate [ranges through a stmt]', like in 'value range propagation'.

If you'd like to avoid 'propagate'/'deduce' asymmetry, I could suggest
'forward inference' / 'backward inference', but I like it a bit less.

Alexander
Richard Biener May 20, 2022, 11:49 a.m. UTC | #15
On Fri, May 20, 2022 at 10:17 AM Alexander Monakov <amonakov@ispras.ru> wrote:
>
> On Fri, 20 May 2022, Richard Biener wrote:
>
> > On Fri, May 20, 2022 at 8:38 AM Alexander Monakov <amonakov@ispras.ru> wrote:
> > >
> > > On Fri, 20 May 2022, Richard Biener via Gcc-patches wrote:
> > >
> > > > > Still waiting for a suggestion, since "side effect" is the description
> > > > > that made sense to me :-)
> > > >
> > > > I think side-effect captures it quite well even if it overlaps with a term
> > > > used in language standards.  Doing c = a << b has the side-effect on
> > > > imposing a range on 'b' rather than just affecting 'c' (and its range).
> > > > You could call it 'alternate effect' but that sounds just awkward ;)
> > >
> > > I suggest 'deduce', 'deduction', 'deducing a range'. What the code is actually
> > > doing is deducing that 'b' in 'a / b' cannot be zero. Function in GCC might be
> > > called like 'deduce_ranges_from_stmt'.
> >
> > So how would you call determining the range of 'c' from the ranges of
> > 'a' and 'b', isn't that 'deduction' as well?
>
> Kind of, yes, but for this sort of forward inference I imagine you're already
> using 'propagate [ranges through a stmt]', like in 'value range propagation'.
>
> If you'd like to avoid 'propagate'/'deduce' asymmetry, I could suggest
> 'forward inference' / 'backward inference', but I like it a bit less.

Hmm, maybe "guarantees" - if the stmt executed (without traps) then
it's guaranteed that the divisor isn't zero.  I've almost said 'assertions'
but then asserts also have separate meanings, not to mention ASSERT_EXPR
as currently used by the old-style VRP.

Richard.

>
> Alexander
Alexandre Oliva May 20, 2022, 12:09 p.m. UTC | #16
On May 18, 2022, Andrew MacLeod via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:

> I'm open to suggestions for a better term!

How about inference?
Segher Boessenkool May 20, 2022, 2:39 p.m. UTC | #17
On Fri, May 20, 2022 at 10:11:32AM +0200, Eric Botcazou wrote:
> > I suggest 'deduce', 'deduction', 'deducing a range'. What the code is
> > actually doing is deducing that 'b' in 'a / b' cannot be zero. Function in
> > GCC might be called like 'deduce_ranges_from_stmt'.
> 
> Or "infer", "inference", "inferring a range".

"Infer" is great here, yes!

infer (verb):
  deduce or conclude (something) from evidence and reasoning rather than
  from explicit statements

It has exactly the connotation wanted here, I would say.


Segher
Bernhard Reutner-Fischer May 20, 2022, 7:18 p.m. UTC | #18
On 20 May 2022 16:39:20 CEST, Segher Boessenkool <segher@kernel.crashing.org> wrote:
>On Fri, May 20, 2022 at 10:11:32AM +0200, Eric Botcazou wrote:
>> > I suggest 'deduce', 'deduction', 'deducing a range'. What the code is
>> > actually doing is deducing that 'b' in 'a / b' cannot be zero. Function in
>> > GCC might be called like 'deduce_ranges_from_stmt'.
>> 
>> Or "infer", "inference", "inferring a range".
>
>"Infer" is great here, yes!
>
>infer (verb):
>  deduce or conclude (something) from evidence and reasoning rather than
>  from explicit statements
>
>It has exactly the connotation wanted here, I would say.

Infer, deduct, refine
Sound all plausible, a native speaker should probably help decide the bikeshed :-)
thanks,
Alexander Monakov May 22, 2022, 6:55 p.m. UTC | #19
On Fri, 20 May 2022, Richard Biener wrote:

> > > > I suggest 'deduce', 'deduction', 'deducing a range'. What the code is actually
> > > > doing is deducing that 'b' in 'a / b' cannot be zero. Function in GCC might be
> > > > called like 'deduce_ranges_from_stmt'.
> > >
> > > So how would you call determining the range of 'c' from the ranges of
> > > 'a' and 'b', isn't that 'deduction' as well?
> >
> > Kind of, yes, but for this sort of forward inference I imagine you're already
> > using 'propagate [ranges through a stmt]', like in 'value range propagation'.
> >
> > If you'd like to avoid 'propagate'/'deduce' asymmetry, I could suggest
> > 'forward inference' / 'backward inference', but I like it a bit less.
> 
> Hmm, maybe "guarantees" - if the stmt executed (without traps) then
> it's guaranteed that the divisor isn't zero.  I've almost said 'assertions'
> but then asserts also have separate meanings, not to mention ASSERT_EXPR
> as currently used by the old-style VRP.

I feel the word 'assumptions' captures that nicely.

Alexander
Andi Kleen May 27, 2022, 7:33 p.m. UTC | #20
Andrew MacLeod via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
>
> diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
> index 2c8c77dc569..548e4bea313 100644
> --- a/gcc/gimple-range-side-effect.cc
> +++ b/gcc/gimple-range-side-effect.cc
> @@ -116,6 +116,23 @@ stmt_side_effects::stmt_side_effects (gimple *s)
>      walk_stmt_load_store_ops (s, (void *)this, non_null_loadstore,
>  			      non_null_loadstore);
>  
> +  if (is_a<gassign *> (s))
> +    {
> +      switch (gimple_assign_rhs_code (s))
> +	{
> +	case TRUNC_DIV_EXPR:
> +	case CEIL_DIV_EXPR:
> +	case FLOOR_DIV_EXPR:
> +	case ROUND_DIV_EXPR:
> +	case EXACT_DIV_EXPR:
> +	  // Divide means operand 2 is not zero after this stmt.
> +	  if (gimple_range_ssa_p (gimple_assign_rhs2 (s)))
> +	    add_nonzero (gimple_assign_rhs2 (s));

Sorry I'm late, but how does this ensure the value is a integer?
I believe for floating point the assumption is not correct because
division by zero doesn't necessarily fault.

-Andi
Andrew MacLeod May 27, 2022, 7:56 p.m. UTC | #21
On 5/27/22 15:33, Andi Kleen wrote:
> Andrew MacLeod via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
>> diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
>> index 2c8c77dc569..548e4bea313 100644
>> --- a/gcc/gimple-range-side-effect.cc
>> +++ b/gcc/gimple-range-side-effect.cc
>> @@ -116,6 +116,23 @@ stmt_side_effects::stmt_side_effects (gimple *s)
>>       walk_stmt_load_store_ops (s, (void *)this, non_null_loadstore,
>>   			      non_null_loadstore);
>>   
>> +  if (is_a<gassign *> (s))
>> +    {
>> +      switch (gimple_assign_rhs_code (s))
>> +	{
>> +	case TRUNC_DIV_EXPR:
>> +	case CEIL_DIV_EXPR:
>> +	case FLOOR_DIV_EXPR:
>> +	case ROUND_DIV_EXPR:
>> +	case EXACT_DIV_EXPR:
>> +	  // Divide means operand 2 is not zero after this stmt.
>> +	  if (gimple_range_ssa_p (gimple_assign_rhs2 (s)))
>> +	    add_nonzero (gimple_assign_rhs2 (s));
> Sorry I'm late, but how does this ensure the value is a integer?
> I believe for floating point the assumption is not correct because
> division by zero doesn't necessarily fault.
>
> -Andi
>
gimple_range_ssa_p() only returns non-zero when the value is an ssa_name 
whose type is supported by the range calculators... currently only 
integrals values.  When we support floating points we will have to add 
additional logic.

Andrew
Eric Gallager May 28, 2022, 11:52 a.m. UTC | #22
On Fri, May 27, 2022 at 3:57 PM Andrew MacLeod via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On 5/27/22 15:33, Andi Kleen wrote:
> > Andrew MacLeod via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> >> diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
> >> index 2c8c77dc569..548e4bea313 100644
> >> --- a/gcc/gimple-range-side-effect.cc
> >> +++ b/gcc/gimple-range-side-effect.cc
> >> @@ -116,6 +116,23 @@ stmt_side_effects::stmt_side_effects (gimple *s)
> >>       walk_stmt_load_store_ops (s, (void *)this, non_null_loadstore,
> >>                            non_null_loadstore);
> >>
> >> +  if (is_a<gassign *> (s))
> >> +    {
> >> +      switch (gimple_assign_rhs_code (s))
> >> +    {
> >> +    case TRUNC_DIV_EXPR:
> >> +    case CEIL_DIV_EXPR:
> >> +    case FLOOR_DIV_EXPR:
> >> +    case ROUND_DIV_EXPR:
> >> +    case EXACT_DIV_EXPR:
> >> +      // Divide means operand 2 is not zero after this stmt.
> >> +      if (gimple_range_ssa_p (gimple_assign_rhs2 (s)))
> >> +        add_nonzero (gimple_assign_rhs2 (s));
> > Sorry I'm late, but how does this ensure the value is a integer?
> > I believe for floating point the assumption is not correct because
> > division by zero doesn't necessarily fault.
> >
> > -Andi
> >
> gimple_range_ssa_p() only returns non-zero when the value is an ssa_name
> whose type is supported by the range calculators... currently only
> integrals values.  When we support floating points we will have to add
> additional logic.
>

Maybe add a comment to that effect, then? As a reminder...

> Andrew
>
Richard Biener May 30, 2022, 12:24 p.m. UTC | #23
On Fri, May 27, 2022 at 9:34 PM Andi Kleen via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Andrew MacLeod via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> >
> > diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
> > index 2c8c77dc569..548e4bea313 100644
> > --- a/gcc/gimple-range-side-effect.cc
> > +++ b/gcc/gimple-range-side-effect.cc
> > @@ -116,6 +116,23 @@ stmt_side_effects::stmt_side_effects (gimple *s)
> >      walk_stmt_load_store_ops (s, (void *)this, non_null_loadstore,
> >                             non_null_loadstore);
> >
> > +  if (is_a<gassign *> (s))
> > +    {
> > +      switch (gimple_assign_rhs_code (s))
> > +     {
> > +     case TRUNC_DIV_EXPR:
> > +     case CEIL_DIV_EXPR:
> > +     case FLOOR_DIV_EXPR:
> > +     case ROUND_DIV_EXPR:
> > +     case EXACT_DIV_EXPR:
> > +       // Divide means operand 2 is not zero after this stmt.
> > +       if (gimple_range_ssa_p (gimple_assign_rhs2 (s)))
> > +         add_nonzero (gimple_assign_rhs2 (s));
>
> Sorry I'm late, but how does this ensure the value is a integer?
> I believe for floating point the assumption is not correct because
> division by zero doesn't necessarily fault.

non-integer divisions use a different TREE_CODE (RDIV_EXPR).

>
> -Andi
diff mbox series

Patch

commit 3bbcccf2ddd4d50cc5febf630bd8b55a45688352
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Mon Apr 4 16:13:57 2022 -0400

    Add divide by zero side effect.
    
    After a divide, we know the divisor is not zero.
    
            gcc/
            * gimple-range-side-effect.cc (stmt_side_effects::stmt_side_effects):
            Add support for all divides.
    
            gcc/testsuite/
            * gcc.dg/tree-ssa/evrp-zero.c: New.

diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
index 2c8c77dc569..548e4bea313 100644
--- a/gcc/gimple-range-side-effect.cc
+++ b/gcc/gimple-range-side-effect.cc
@@ -116,6 +116,23 @@  stmt_side_effects::stmt_side_effects (gimple *s)
     walk_stmt_load_store_ops (s, (void *)this, non_null_loadstore,
 			      non_null_loadstore);
 
+  if (is_a<gassign *> (s))
+    {
+      switch (gimple_assign_rhs_code (s))
+	{
+	case TRUNC_DIV_EXPR:
+	case CEIL_DIV_EXPR:
+	case FLOOR_DIV_EXPR:
+	case ROUND_DIV_EXPR:
+	case EXACT_DIV_EXPR:
+	  // Divide means operand 2 is not zero after this stmt.
+	  if (gimple_range_ssa_p (gimple_assign_rhs2 (s)))
+	    add_nonzero (gimple_assign_rhs2 (s));
+	  break;
+	default:
+	  break;
+	}
+    }
 }
 
 // -------------------------------------------------------------------------
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp-zero.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp-zero.c
new file mode 100644
index 00000000000..2b76e449c9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp-zero.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp " } */
+
+/* Side effects of divide are that the divisor cannot be 0. */
+
+void dead (int);
+
+void
+f1 (int a, int c) {
+  int b = a;
+  if (a / c > 10)
+    b = c;
+
+  if (c == 0)
+    dead (b);
+}
+
+
+void
+f2 (int a, int c) {
+  int nz = c == 0;
+  int b = a / c;
+  if (nz)
+    dead (0);
+}
+
+
+/* { dg-final { scan-tree-dump-not "dead" "evrp" } } */