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

--- Comment #8 from Jeffrey A. Law <law at redhat dot com> ---
Just to be clear, it's not DOM or threading that introduces any out of bounds
accesses or overflows here.

So the testcase:

/* { dg-do compile } */
/* { dg-additional-options "-Wall -Werror" } */

void foo(char *in, char *out, int num)
{
  int i;
  char ovec[16] = {0};

  for(i = 0; i < num ; ++i)
    out[i] = (ovec[i] = in[i]);
  out[num] = ovec[num/2];
}

Compiled for powerpc64-linux-gnu with:

./cc1 -O3 j.c -I./ -Wall -maltivec -fdump-tree-all-blocks-details
-fno-vect-cost-model


The first warning comes from this statement in block #5:

  ovec[tmp.8_58] = _207;

The block looks like this in the .thread3 (ie, before dom3) dump:


;;   basic block 5, loop depth 0, count 78839494 (estimated locally), maybe hot
;;    prev block 4, next block 6, flags: (NEW, REACHABLE, VISITED)
;;    pred:       4 [93.8% (guessed)]  count:78839494 (estimated locally)
(FALSE_VALUE,EXECUTABLE)
  _205 = (sizetype) tmp.8_58;
[ ... ]
  ovec[tmp.8_58] = _207;
[ ... ]


THe definition of tmp.8_58 comes from bb#4:

;;   basic block 4, loop depth 0, count 84095460 (estimated locally), maybe hot
;;    prev block 3, next block 5, flags: (NEW, REACHABLE, VISITED)
;;    pred:       3 [80.0% (guessed)]  count:84095460 (estimated locally)
(TRUE_VALUE,EXECUTABLE)
  bnd.6_56 = _10 >> 4;
[ ... ]
  niters_vector_mult_vf.7_57 = bnd.6_56 << 4;
  tmp.8_58 = (int) niters_vector_mult_vf.7_57;
  if (_10 == niters_vector_mult_vf.7_57)
    goto <bb 36>; [6.25%]
  else
    goto <bb 5>; [93.75%]


The definition of _10 comes from bb3:

;;   basic block 3, loop depth 0, count 105119324 (estimated locally), maybe
hot
;;    prev block 2, next block 4, flags: (NEW, VISITED)
;;    pred:       2 [89.0% (guessed)]  count:105119324 (estimated locally)
(TRUE_VALUE,EXECUTABLE)
  _10 = (unsigned int) num_13(D);
[ ... ]


So let's compute tmp.8_58 :-) assuming that num_13 is an incoming parameter and
we have no information about it other than its type (int).

Visiting statement:
_10 = (unsigned int) num_13(D);
Intersecting
  unsigned int [1, 2147483647]
and
  unsigned int VARYING

Which feeds into:

Visiting statement:
bnd.6_56 = _10 >> 4;
Intersecting
  unsigned int [1, 134217727]
and
  unsigned int [1, 268435455]
to
  unsigned int [1, 134217727]

So bnd.6_56 can have the value [1, 0x7ffffff] Which makes perfect sense.  That
feeds into:


Visiting statement:
niters_vector_mult_vf.7_57 = bnd.6_56 << 4;
Intersecting
  unsigned int [16, 2147483632]
and
  unsigned int VARYING
to
  unsigned int [16, 2147483632]

So ninters_vector_mult_vf.7_57 can have the values [16, 0x7ffffff0].  Which
also makes perfect sense and feeds into:

Visiting statement:
tmp.8_58 = (int) niters_vector_mult_vf.7_57;
Intersecting
  int [16, 2147483632]
and
  int VARYING
to
  int [16, 2147483632]

So tmp.8_58 also has values in the range [16, 0x7ffffff0]

So when used in this statement:


  ovec[tmp.8_58] = _207;

We get the out of bounds access.  Pretty simple.

THis is caused either by vectorization or loop unrolling or the combination
thereof (most likely loop unrolling).  DOM/threading have nothing to do with
what's going on in here.

Reply via email to