public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "rguenth at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/108306] false-positive -Warray-bounds warning emitted with -fsanitize=shift
Date: Mon, 16 Jan 2023 09:43:50 +0000	[thread overview]
Message-ID: <bug-108306-4-paympJXSM8@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-108306-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108306

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |NEW
                 CC|                            |amacleod at redhat dot com

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Kees Cook from comment #7)
> (In reply to Kees Cook from comment #6)
> > Sorry, I forgot to include those details fully! Here's how I'm seeing it:
> > 
> > $ gcc --version
> > gcc (GCC) 13.0.0 20230105 (experimental)
> > ...
> > $ gcc -O2 -fno-strict-overflow -fsanitize=shift -Warray-bounds -c -o
> > /dev/null poc.c
> 
> In function 'psi_group_change',
>     inlined from 'psi_task_switch' at poc.c:25:2:
> poc.c:15:30: warning: array subscript 32 is above array bounds of 'unsigned
> int[4]' [-Warray-bounds=]
>    15 |                         tasks[t]++;
>       |                         ~~~~~^~~
> poc.c: In function 'psi_task_switch':
> poc.c:6:14: note: while referencing 'tasks'
>     6 | unsigned int tasks[NR_PSI_TASK_COUNTS];
>       |              ^~~~~
> 
> (mispaste)

we diagnose

<bb 5> [local count: 8687547547]:
if (t_6 > 31)
  goto <bb 9>; [0.00%]

<bb 9> [count: 0]:
_7 = (unsigned long) t_6;
__builtin___ubsan_handle_shift_out_of_bounds (&*.Lubsan_data1, 1, _7);
_8 = 1 << t_6;
_9 = (unsigned int) _8;
_35 = _8 & 1;
_11 = (unsigned int) _35;
if (_35 != 0)
  goto <bb 10>; [50.00%]

<bb 10> [local count: 0]:
_12 = tasks[t_6];
_13 = _12 + 1;
tasks[t_6] = _13;

clearly t_6 is > 31 and thus the access is out-of-bounds [in the IL].
What we miss is the fact that we can rely on t_6 being in bounds for
the 1 << t_6 shift and thus this is unreachable code plus the fact
that for 1 << t_6 with t_6 > 31 bit zero is always zero.  That's something
for ranger to see - why doesn't it?  We have

=========== BB 5 ============
Imports: t_6
Exports: t_6
t_6     [irange] unsigned int VARYING
    <bb 5> [local count: 8687547547]:
    if (t_6 > 31)
      goto <bb 9>; [0.00%]
    else
      goto <bb 6>; [100.00%]

5->9  (T) t_6 :         [irange] unsigned int [32, +INF]
5->6  (F) t_6 :         [irange] unsigned int [0, 31] NONZERO 0x1f

=========== BB 9 ============
Imports: t_6  set_10
Exports: t_6  _8  _9  set_10  _11
         _7 : t_6(I)
         _8 : t_6(I)
         _9 : t_6(I)  _8
         _11 : t_6(I)  _8  _9  set_10(I)
         _35 : t_6(I)  _8
t_6     [irange] unsigned int [32, +INF]
set_10  [irange] unsigned int [1, 1] NONZERO 0x1
Partial equiv (_7 pe32 t_6)
Partial equiv (_9 pe32 _8)
    <bb 9> [count: 0]:
    _7 = (unsigned long) t_6;
    __builtin___ubsan_handle_shift_out_of_bounds (&*.Lubsan_data1, 1, _7);
    _8 = 1 << t_6;
    _9 = (unsigned int) _8;
    _35 = _8 & 1;
    _11 = (unsigned int) _35;
    if (_35 != 0)
      goto <bb 10>; [50.00%]
      goto <bb 10>; [50.00%]
    else
      goto <bb 11>; [50.00%]

_7 : [irange] unsigned long [32, 4294967295] NONZERO 0xffffffff
_11 : [irange] unsigned int [0, 1] NONZERO 0x1
9->10  (T) t_6 :        [irange] unsigned int [32, +INF]
9->10  (T) _7 :         [irange] unsigned long [32, 4294967295] NONZERO
0xffffffff
9->10  (T) _8 :         [irange] int [-INF, -1][1, +INF]
9->10  (T) set_10 :     [irange] unsigned int [1, 1] NONZERO 0x1
9->10  (T) _11 :        [irange] unsigned int [0, 1] NONZERO 0x1
9->10  (T) _35 :        [irange] int [0, 1] NONZERO 0x1
9->11  (F) t_6 :        [irange] unsigned int [32, +INF]
9->11  (F) _7 :         [irange] unsigned long [32, 4294967295] NONZERO
0xffffffff
9->11  (F) _8 :         [irange] int [-INF, -2][0, +INF] NONZERO 0xfffffffe
9->11  (F) set_10 :     [irange] unsigned int [1, 1] NONZERO 0x1
9->11  (F) _11 :        [irange] unsigned int [0, 1] NONZERO 0x1
9->11  (F) _35 :        [irange] int [0, 0] NONZERO 0x0

even without -fwrapv we don't seem to know that 1 << [32, +INF] resolves
to zero?!

6->7  (T) _31 :         [irange] int [-INF, -1][1, +INF]
6->8  (F) _31 :         [irange] int [-INF, -2][0, +INF] NONZERO 0xfffffffe

we seem to fall into

  else
    // Otherwise, invoke the generic fold routine.
    return range_operator::fold_range (r, type, op1, shift_range, rel);

and that oddly enough receives

(gdb) p debug (rh)
[irange] unsigned int [0, 31] NONZERO 0x1f

?!

#0  range_operator::fold_range (this=0x42f4ef0 <op_lshift>, r=..., 
    type=<integer_type 0x7ffff62855e8 int>, lh=..., rh=..., trio=...)
    at /home/rguenther/src/trunk/gcc/range-op.cc:244
#1  0x0000000002e26152 in operator_lshift::fold_range (
    this=0x42f4ef0 <op_lshift>, r=..., type=<integer_type 0x7ffff62855e8 int>, 
    op1=..., op2=..., rel=...)
    at /home/rguenther/src/trunk/gcc/range-op.cc:2192
#2  0x0000000002e3043d in range_op_handler::fold_range (this=0x7fffffff2c90, 
    r=..., type=<integer_type 0x7ffff62855e8 int>, lh=..., rh=..., rel=...)
    at /home/rguenther/src/trunk/gcc/range-op.cc:4506
#3  0x0000000002cb07e2 in fold_using_range::range_of_range_op (
    this=0x7fffffff2d3f, r=..., handler=..., src=...)
    at /home/rguenther/src/trunk/gcc/gimple-range-fold.cc:589
#4  0x0000000002caff11 in fold_using_range::fold_stmt (this=0x7fffffff2d3f, 
    r=..., s=<gimple_assign 0x7ffff607e630>, src=..., 
    name=<ssa_name 0x7ffff607cc18 8>)
    at /home/rguenther/src/trunk/gcc/gimple-range-fold.cc:489
#5  0x0000000002caf425 in fold_range (r=..., s=<gimple_assign 0x7ffff607e630>, 
    on_edge=<edge 0x7ffff60842d0 (11 -> 13)>, q=0x4352c88)
    at /home/rguenther/src/trunk/gcc/gimple-range-fold.cc:326
#6  0x0000000002cb89d0 in gori_compute::outgoing_edge_range_p (this=0x4352ca0, 
    r=..., e=<edge 0x7ffff60842d0 (11 -> 13)>, 
    name=<ssa_name 0x7ffff607cc18 8>, q=...)
    at /home/rguenther/src/trunk/gcc/gimple-range-gori.cc:1400
#7  0x0000000002ca8193 in ranger_cache::edge_range (this=0x4352c88, r=..., 
    e=<edge 0x7ffff60842d0 (11 -> 13)>, name=<ssa_name 0x7ffff607cc18 8>, 
    mode=ranger_cache::RFD_NONE)
    at /home/rguenther/src/trunk/gcc/gimple-range-cache.cc:964
#8  0x0000000002ca831c in ranger_cache::range_on_edge (this=0x4352c88, r=..., 
    e=<edge 0x7ffff60842d0 (11 -> 13)>, expr=<ssa_name 0x7ffff607cc18 8>)
    at /home/rguenther/src/trunk/gcc/gimple-range-cache.cc:1001
#9  0x0000000002ca256f in gimple_ranger::range_on_edge (this=0x4352c60, r=..., 
    e=<edge 0x7ffff60842d0 (11 -> 13)>, name=<ssa_name 0x7ffff607cc18 8>)
    at /home/rguenther/src/trunk/gcc/gimple-range.cc:241
#10 0x0000000002caedc8 in fur_edge::get_operand (this=0x7fffffff6030, r=..., 
    expr=<ssa_name 0x7ffff607cc18 8>)
    at /home/rguenther/src/trunk/gcc/gimple-range-fold.cc:131
#11 0x0000000002caeefc in fur_stmt::get_phi_operand (this=0x7fffffff9350, 
    r=..., expr=<ssa_name 0x7ffff607cc18 8>, 
    e=<edge 0x7ffff60842d0 (11 -> 13)>)
    at /home/rguenther/src/trunk/gcc/gimple-range-fold.cc:168
...

maybe I didn't capture the "correct" call (there are too many).  Still
something
goes wrong here.

A small testcase like

int foo (int n)
{
  if (n > 31)
    {
      int tem = 1 << n;
      if ((unsigned)tem & 1)
        bar ();
    }
}

is optimized just fine.

  parent reply	other threads:[~2023-01-16  9:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-05 20:46 [Bug c/108306] New: " kees at outflux dot net
2023-01-05 20:50 ` [Bug c/108306] " kees at outflux dot net
2023-01-05 20:52 ` kees at outflux dot net
2023-01-05 21:25 ` kees at outflux dot net
2023-01-06  6:31 ` [Bug tree-optimization/108306] " pinskia at gcc dot gnu.org
2023-01-09 11:24 ` rguenth at gcc dot gnu.org
2023-01-14  0:15 ` kees at outflux dot net
2023-01-14  0:16 ` kees at outflux dot net
2023-01-16  9:43 ` rguenth at gcc dot gnu.org [this message]
2023-01-16  9:47 ` [Bug tree-optimization/108306] [12/13 Regression] " rguenth at gcc dot gnu.org
2023-01-16 19:36 ` amacleod at redhat dot com
2023-01-16 20:26 ` amacleod at redhat dot com
2023-01-17  8:47 ` rguenth at gcc dot gnu.org
2023-01-27 14:38 ` cvs-commit at gcc dot gnu.org
2023-01-27 14:39 ` amacleod at redhat dot com
2023-01-27 15:16 ` [Bug tree-optimization/108306] [12 " rguenth at gcc dot gnu.org
2023-01-27 16:31 ` amacleod at redhat dot com
2023-01-30  7:02 ` rguenther at suse dot de
2023-01-30 21:12 ` cvs-commit at gcc dot gnu.org
2023-01-30 21:12 ` amacleod at redhat dot com

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=bug-108306-4-paympJXSM8@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /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).