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.