Message ID | c511febf-7a4d-1754-1893-ac77602a18d5@redhat.com |
---|---|
State | New |
Headers | show |
Series | Add divide by zero side effect. | expand |
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 >
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
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
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
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
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
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
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
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 >
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
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
> 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.
> 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.
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
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
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?
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
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,
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
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
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
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 >
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
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" } } */