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

            Bug ID: 92323
           Summary: bogus -Warray-bounds after unrolling despite
                    __builtin_unreachable
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

With the -Warray-bounds enhancement for pr91647, GCC issues a warning for the
unrolled loop in function f() below.  No warning is issued for g().  The loop
in f() is unrolled but it results in pointless tests for the conditions that
the subsequent __builtin_unreachable call should obviate.  The loop in g() is
transformed into a call to memmove which also seems suboptimal.

The code in f() was reduced from try_conditional_simplification() in
gimple-match-head.c.

$ cat z.c && gcc -O2 -S -Wall z.c
struct S { int a[5]; } s;

void sink (void*);

void f (unsigned n, struct S *p)
{ 
  for (unsigned i = 1; i < n - 1; ++i)
    s.a[i - 1] = p->a[i];   // bogus warning

  if (n < 4 || n > 5)
    __builtin_unreachable ();
}

void g (unsigned n, struct S *p)
{ 
  if (n < 4 || n > 5)
    __builtin_unreachable ();

  for (unsigned i = 1; i < n - 1; ++i)
    s.a[i - 1] = p->a[i];
}

z.c: In function ‘f’:
z.c:8:22: warning: array subscript 5 is above array bounds of ‘int[5]’
[-Warray-bounds]
    8 |     s.a[i - 1] = p->a[i];   // bogus warning
      |                  ~~~~^~~
z.c:1:16: note: while referencing ‘a’
    1 | struct S { int a[5]; } s;
      |                ^

Reply via email to