[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2023-04-09 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #17 from Andrew Pinski  ---
(In reply to Christian Prochaska from comment #16)
> (In reply to Andrew Pinski from comment #14)
> > 
> > There was a deferencing of myself before:
> > Nova::Utcb  = *(Nova::Utcb *)myself->utcb();
> 
> I see. The 'Thread::utcb()' function handles the null pointer case
> internally with a 'this == 0' check and a local
> '-fno-delete-null-pointer-checks' attribute:
> 
> https://github.com/genodelabs/genode/blob/
> a84af9a9606450471b8038a35f9b55057efa0850/repos/base-nova/src/lib/base/stack.
> cc#L110
> 
> So, the elimination of the 'myself' null pointer check is basically a result
> of undefined behavior with the 'Thread::utcb()' function?

That only handles one side of where it is undefined. Newer GCC uses it as being
undefined even on the calling side. So you need to use
-fno-delete-null-pointer-checks really on the command line or better yet fixes
all of the places which use ->utcb() .

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2023-04-09 Thread christian.prochaska--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #16 from Christian Prochaska  
---
(In reply to Andrew Pinski from comment #14)
> 
> There was a deferencing of myself before:
> Nova::Utcb  = *(Nova::Utcb *)myself->utcb();

I see. The 'Thread::utcb()' function handles the null pointer case internally
with a 'this == 0' check and a local '-fno-delete-null-pointer-checks'
attribute:

https://github.com/genodelabs/genode/blob/a84af9a9606450471b8038a35f9b55057efa0850/repos/base-nova/src/lib/base/stack.cc#L110

So, the elimination of the 'myself' null pointer check is basically a result of
undefined behavior with the 'Thread::utcb()' function?

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2023-04-08 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #15 from Andrew Pinski  ---
(In reply to Andrew Pinski from comment #14)
> (In reply to Christian Prochaska from comment #13)
> > I found the "Register non-null side effects properly." commit with git
> > bisect while debugging a page fault in the Genode OS framework built with
> > GCC 12.2.0. It turned out that a null pointer check which was present before
> > this commit is now not present anymore. The C++ code with the null pointer
> > check can be found on GitHub:
> > 
> > https://github.com/genodelabs/genode/blob/
> > a84af9a9606450471b8038a35f9b55057efa0850/repos/base-nova/src/lib/base/ipc.
> > cc#L71
> > 
> > This is the implementation of the 'Thread::myself()' function which returns
> > a null pointer in some conditions:
> > 
> > https://github.com/genodelabs/genode/blob/
> > a84af9a9606450471b8038a35f9b55057efa0850/repos/base/src/lib/base/
> > thread_myself.cc#L22
> > 
> > I compared the disassembled code from objdump and this part is missing when
> > the commit is applied:
> > 
> > Genode::ipc_call(Genode::Native_capability, Genode::Msgbuf_base&,
> > Genode::Msgbuf_base&, unsigned long):
> > /.../repos/base-nova/src/lib/base/ipc.cc:71
> > addr_t const manual_rcv_sel = myself ?
> > myself->native_thread().client_rcv_sel
> >85f78:   48 83 bd 50 ff ff ffcmpq   $0x0,-0xb0(%rbp)
> >85f7f:   00
> >85f80:   48 c7 c3 ff ff ff ffmov$0x,%rbx
> >85f87:   74 1d   je 85fa6
> >  > Genode::Msgbuf_base&, unsigned long)
> > /.../repos/base-nova/src/lib/base/ipc.cc:71 (discriminator 1)
> > 
> > Now I'm not sure if the problem is in the Genode code or in GCC. Any ideas?
> 
> There was a deferencing of myself before:
> Nova::Utcb  = *(Nova::Utcb *)myself->utcb();

Line 59 so it is definitely not a bug in gcc.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2023-04-08 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #14 from Andrew Pinski  ---
(In reply to Christian Prochaska from comment #13)
> I found the "Register non-null side effects properly." commit with git
> bisect while debugging a page fault in the Genode OS framework built with
> GCC 12.2.0. It turned out that a null pointer check which was present before
> this commit is now not present anymore. The C++ code with the null pointer
> check can be found on GitHub:
> 
> https://github.com/genodelabs/genode/blob/
> a84af9a9606450471b8038a35f9b55057efa0850/repos/base-nova/src/lib/base/ipc.
> cc#L71
> 
> This is the implementation of the 'Thread::myself()' function which returns
> a null pointer in some conditions:
> 
> https://github.com/genodelabs/genode/blob/
> a84af9a9606450471b8038a35f9b55057efa0850/repos/base/src/lib/base/
> thread_myself.cc#L22
> 
> I compared the disassembled code from objdump and this part is missing when
> the commit is applied:
> 
> Genode::ipc_call(Genode::Native_capability, Genode::Msgbuf_base&,
> Genode::Msgbuf_base&, unsigned long):
> /.../repos/base-nova/src/lib/base/ipc.cc:71
> addr_t const manual_rcv_sel = myself ?
> myself->native_thread().client_rcv_sel
>85f78:   48 83 bd 50 ff ff ffcmpq   $0x0,-0xb0(%rbp)
>85f7f:   00
>85f80:   48 c7 c3 ff ff ff ffmov$0x,%rbx
>85f87:   74 1d   je 85fa6
>  Genode::Msgbuf_base&, unsigned long)
> /.../repos/base-nova/src/lib/base/ipc.cc:71 (discriminator 1)
> 
> Now I'm not sure if the problem is in the Genode code or in GCC. Any ideas?

There was a deferencing of myself before:
Nova::Utcb  = *(Nova::Utcb *)myself->utcb();

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2023-04-08 Thread christian.prochaska--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

Christian Prochaska  changed:

   What|Removed |Added

 CC||christian.prochaska@genode-
   ||labs.com

--- Comment #13 from Christian Prochaska  
---
I found the "Register non-null side effects properly." commit with git bisect
while debugging a page fault in the Genode OS framework built with GCC 12.2.0.
It turned out that a null pointer check which was present before this commit is
now not present anymore. The C++ code with the null pointer check can be found
on GitHub:

https://github.com/genodelabs/genode/blob/a84af9a9606450471b8038a35f9b55057efa0850/repos/base-nova/src/lib/base/ipc.cc#L71

This is the implementation of the 'Thread::myself()' function which returns a
null pointer in some conditions:

https://github.com/genodelabs/genode/blob/a84af9a9606450471b8038a35f9b55057efa0850/repos/base/src/lib/base/thread_myself.cc#L22

I compared the disassembled code from objdump and this part is missing when the
commit is applied:

Genode::ipc_call(Genode::Native_capability, Genode::Msgbuf_base&,
Genode::Msgbuf_base&, unsigned long):
/.../repos/base-nova/src/lib/base/ipc.cc:71
addr_t const manual_rcv_sel = myself ?
myself->native_thread().client_rcv_sel
   85f78:   48 83 bd 50 ff ff ffcmpq   $0x0,-0xb0(%rbp)
   85f7f:   00
   85f80:   48 c7 c3 ff ff ff ffmov$0x,%rbx
   85f87:   74 1d   je 85fa6


[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-02-09 Thread amacleod at redhat dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

Andrew Macleod  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #12 from Andrew Macleod  ---
fixed.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-02-09 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #11 from CVS Commits  ---
The master branch has been updated by Andrew Macleod :

https://gcc.gnu.org/g:c6bb1db76b3ac127aff7dacf391fc1798a94bb7d

commit r12-7128-gc6bb1db76b3ac127aff7dacf391fc1798a94bb7d
Author: Andrew MacLeod 
Date:   Mon Feb 7 15:52:16 2022 -0500

Register non-null side effects properly.

This patch adjusts uses of nonnull to accurately reflect "somewhere in
block".
It also adds the ability to register statement side effects within a block
for ranger which will apply for the rest of the block.

PR tree-optimization/104288
gcc/
* gimple-range-cache.cc (non_null_ref::set_nonnull): New.
(non_null_ref::adjust_range): Move to header.
(ranger_cache::range_of_def): Don't check non-null.
(ranger_cache::entry_range): Don't check non-null.
(ranger_cache::range_on_edge): Check for nonnull on normal edges.
(ranger_cache::update_to_nonnull): New.
(non_null_loadstore): New.
(ranger_cache::block_apply_nonnull): New.
* gimple-range-cache.h (class non_null_ref): Update prototypes.
(non_null_ref::adjust_range): Move to here and inline.
(class ranger_cache): Update prototypes.
* gimple-range-path.cc (path_range_query::range_defined_in_block):
Do
not search dominators.
(path_range_query::adjust_for_non_null_uses): Ditto.
* gimple-range.cc (gimple_ranger::range_of_expr): Check on-entry
for
def overrides.  Do not check nonnull.
(gimple_ranger::range_on_entry): Check dominators for nonnull.
(gimple_ranger::range_on_edge): Check for nonnull on normal edges..
(gimple_ranger::register_side_effects): New.
* gimple-range.h (gimple_ranger::register_side_effects): New.
* tree-vrp.cc (rvrp_folder::fold_stmt): Call register_side_effects.

gcc/testsuite/
* gcc.dg/pr104288.c: New.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-02-08 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #10 from CVS Commits  ---
The releases/gcc-11 branch has been updated by Andrew Macleod
:

https://gcc.gnu.org/g:ed35d4205e8c139d27d3d47c528aaa9f82f0ac1b

commit r11-9543-ged35d4205e8c139d27d3d47c528aaa9f82f0ac1b
Author: Andrew MacLeod 
Date:   Mon Jan 31 11:37:16 2022 -0500

Range on entry should only check dominators for non-null.

Range-on-entry checks should no check the state of non-null within the
current
block.   If dominators are present, use the dominator.

PR tree-optimization/104288
gcc/
* gimple-range-cache.cc (ssa_range_in_bb): Only use non-null from
the
dominator entry ranges.
* gimple-range.cc (gimple_ranger::range_of_expr): Ditto.
gcc/testsuite/
* gcc.dg/pr104288.c: New.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-02-02 Thread amacleod at redhat dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #9 from Andrew Macleod  ---
 risk/churn.
> >  At least that is what I'M currently trying.  would this be OK?
> 
> Let's see what you can come up with.


> (which is why I really did like to have the old EVRP since conceptually
> it's easy to have a very fine-grained "context")
> 
> Practically I think it's OK for true on-demand users to have the
> less precise per-BB non-NULL data.  But the value-range passes
> should really be able to keep a precise per-stmt "context".
> 
> Did I say I liked the old EVRP way of doing things? ;)

Intention has always been to introduce a range_after_stmt to the API for
side-effects, which would merge some aspects of the way EVRP did things.

I have a patchset which I will submit shortly.. once everything passes mustard.
Its actually not that significant of a change.

Ranger currently tracks non-null for an ssa-name in blocks with a single bit. 
I change that to 2 bits so we can tell if all uses in the block have the
non-null property, or if there are some uses which do not have the property.

range-on-entry is changed to only check the dominators, and range-of-expr is
changed to only apply the non-null property if the entire block has only uses
with the non-null property.

After trying to simply/fold each statement in the domwalk, I now check if the
statement sets the non-null property. If so, then mark this block as non-null
throughout, and any further queries through range_of_expr within this block
will now pick up the non-null property. 

This allows us the flexibility of EVRPs granular walk, while remaining
conservative with any on demand clients.  This also solves the problematic
testcase I showed earlier, producing the desired:
  _1 = p_3(D) == 0B;
  _2 = (int) _1;
  h (_2);
  foo (p_3(D));
  return;

Anyway, patch coming soon. I believe it to be low risk as the changes are all
localized, and results should always be more conservative with the additonal 
granularity.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-02-01 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #8 from rguenther at suse dot de  ---
On Mon, 31 Jan 2022, amacleod at redhat dot com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288
> 
> --- Comment #7 from Andrew Macleod  ---
> I'm contemplating the situation.  The trick is to find something with minimal
> change that is functionally acceptable.   I think the goal for this release
> would be to continue to get vrp111.c, and simply not get it in the problematic
> case..  ie, if the first use in the block is unknown and then LATER in the
> block we figure out that it is non-null, we will miss that case through-out 
> the block for now.  
> 
> Effectively: if no dominator block contains non-null then whatever the first
> use in a block determines will apply to the whole block, for the duration of
> the block.. but upon exit to the block, if it was non-null anywhere, then all
> following blocks get that knowledge.  
> 
> I think this could be done reasonably efficiently with a minimum of 
> risk/churn.
>  At least that is what I'M currently trying.  would this be OK?

Let's see what you can come up with.

For ranges derived from stmts that are not the last in a BB (in which case
they apply to outgoing edges) you have to strictly adhere to the notion
that you have ranges incoming into a stmt and ranges outgoing so each
stmt is the source of new ranges.  That applies to divisions
(nonzero divisor) or shifts (no out of range shift operand).  But you
may not apply the range to all stmts of a block (including the stmt
producing the range itself).  With the old EVRP scheme I failed to
nicely support deriving non-zero divisor ranges for this reason for
example.

That makes it complicated to handle in an on-demand fashion of course
since you'd need a per stmt cache that is much more difficult to manage
and look up.

(which is why I really did like to have the old EVRP since conceptually
it's easy to have a very fine-grained "context")

Practically I think it's OK for true on-demand users to have the
less precise per-BB non-NULL data.  But the value-range passes
should really be able to keep a precise per-stmt "context".

Did I say I liked the old EVRP way of doing things? ;)

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-01-31 Thread amacleod at redhat dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #7 from Andrew Macleod  ---
its a bit more tightly intertwined than that unfortunately.  I had plans to
replace the current non-null processing with a range_after_stmt side-effect API
which would work in conjunction with dominator walks, but never got to it in
this release.

So ranger makes the assumption currently that if the non-null property is found
anywhere in the BB, it applies to the entire BB, unless
can_throw_non_call_exceptions is true, then it just bails.

The unfortunate side effect of this is we can no longer determine the
difference between this test case and (vrp111.c):


void foo (void *p) __attribute__((nonnull(1)));
void bar (void *p)
{
  foo (p);
  if (!p)
__builtin_abort ();
}

where the use determining non-null happens first, and then we can eliminate
branches safely.  ie,so a problematic test case would be a combination:

void h(int result)
{
if (result)
__builtin_exit(0);
}
void foo (void *p) __attribute__((nonnull(1)));
void bar (void *p)
{
  h(p == 0);// can't eliminate this
  foo (p);  // this makes p non=null
  if (!p)   // should be able to eliminate this
__builtin_abort ();
}



I'm contemplating the situation.  The trick is to find something with minimal
change that is functionally acceptable.   I think the goal for this release
would be to continue to get vrp111.c, and simply not get it in the problematic
case..  ie, if the first use in the block is unknown and then LATER in the
block we figure out that it is non-null, we will miss that case through-out 
the block for now.  

Effectively: if no dominator block contains non-null then whatever the first
use in a block determines will apply to the whole block, for the duration of
the block.. but upon exit to the block, if it was non-null anywhere, then all
following blocks get that knowledge.  

I think this could be done reasonably efficiently with a minimum of risk/churn.
 At least that is what I'M currently trying.  would this be OK?

And for GCC 11 it is not much of an issue. Since it runs in hybrid mode, I can
simply switch ranger to be more pessimistic and deal with just dominators if
they are available, EVRP picks up the slack,  and it still pass all the
testsuite cases.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-01-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #6 from Jakub Jelinek  ---
Pedantically, even in the same bb the non-NULLness applies, but only for the
stmt with the non-NULL access (e.g. dereference or strcmp call like in this
testcase) or in stmts before it unless there is a stmt that might not return
(exit/abort/loop forever), might throw externally (internal throw would mean
different bbs), might longjmp out of it etc. or, depending on the recent
discussions perhaps volatile accesses.
But most passes that use the ranger don't track easily which stmt comes before
another one in the same bb (with the exception of say reassoc), so maybe what
you talk about is the only thing ranger can do at least for now.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-01-31 Thread amacleod at redhat dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

--- Comment #5 from Andrew Macleod  ---
The issue is that the routine to determine non-nullness is being called to
check for range-on-entry of the current block instead of just the dominators. 

The trace shows:
24   range_on_entry (value_1_7(D)) to BB 2
25 range_of_stmt (value_1_7(D)) at stmt GIMPLE_NOP
   TRUE : (25) range_of_stmt (value_1_7(D)) const char * VARYING
 TRUE : (24) range_on_entry (value_1_7(D)) const char * [1B, +INF]

so it correctly determines that the range of value_1_7 is VARYING, but
range-on-entry to bb2 is adjusted to be non-null.  Ultimately,this is because
then routine in question answers the question "is there a non-null reference in
block BB".

Range on entry should not consider the current block, it should instead start
looking at the dominator to this block.

That section of code has changed between gcc11 and 12, so there will be 2
slightly different patches coming.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-01-31 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P1

--- Comment #4 from Richard Biener  ---
strcmp has a nonnull attribute which means all pointer parameters are not NULL
which probably makes ranger conclude that on all paths they cannot be NULL,
bogously eliding the asserts (note s/exit/__builtin_unreachable()/ would make
this conclusion OK I think).

IMHO this is a security issue, making P1 even though we already released 11.1
and 11.2 with this bug.

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-01-30 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

Jakub Jelinek  changed:

   What|Removed |Added

 CC||aldyh at gcc dot gnu.org,
   ||amacleod at redhat dot com,
   ||jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek  ---
Started with r11-3685-gfcae5121154d1c3382b056bcc2c563cedac28e74

[Bug tree-optimization/104288] [11/12 Regression] EVRP null pointer check removal for strcmp (and maybe others) is not flow senative

2022-01-30 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104288

Andrew Pinski  changed:

   What|Removed |Added

   Keywords||needs-bisection
  Component|middle-end  |tree-optimization

--- Comment #2 from Andrew Pinski  ---
EVRP is removing the null pointer check. I suspect the ranger code is not
taking into account where we are in the IR and it thinks the arguments to
strcmp will be null pointers but before we have other function calls which
might not return.