Consider the following function from gcc.dg/vect/bb-slp-layout-5.c: int a[4], b[4], c[4]; void f1() { a[0] = b[3] - c[3]; a[1] = b[2] + c[2]; a[2] = b[1] - c[1]; a[3] = b[0] + c[0]; } This is vectorized by slp2: vector(4) int vect__1.5; vector(4) int vect__2.8; vector(4) int vect__12.10; vector(4) int vect__3.9; vector(4) int _22; vect__1.5_18 = MEM <vector(4) int> [(int *)&b]; vect__2.8_19 = MEM <vector(4) int> [(int *)&c]; vect__12.10_21 = vect__1.5_18 + vect__2.8_19; vect__3.9_20 = vect__1.5_18 - vect__2.8_19; _22 = VEC_PERM_EXPR <vect__3.9_20, vect__12.10_21, { 3, 6, 1, 4 }>; MEM <vector(4) int> [(int *)&a] = _22; But this introduces new calculations in the temporary vectors of the unused elements: b[0] - c[0]; b[1] + c[1]; b[2] - c[2]; b[3] + c[3]; and these calculations may wrap for input where the original program did not wrap.
I thought we decided that vector types don't apply the overflow rules and always just wrap ...
>these calculations may wrap You mean overflow rather than wrap. Wrapping is a defined behavior while overflow is what is considered undefined ...
(In reply to Andrew Pinski from comment #1) > I thought we decided that vector types don't apply the overflow rules and > always just wrap ... That makes sense. But on the other hand, PR 110495 is a similar issue, and that was fixed... And TYPE_OVERFLOW_WRAPS should return true for integer vectors if they always wrap (or is it only valid for scalars? But ANY_INTEGRAL_TYPE_P is careful to handle vectors and complex numbers too, so I thought the ANY_INTEGRAL_TYPE_CHECK in TYPE_OVERFLOW_WRAPS means that it work for vectors too).
(In reply to Krister Walfridsson from comment #3) > (In reply to Andrew Pinski from comment #1) > > I thought we decided that vector types don't apply the overflow rules and > > always just wrap ... > > That makes sense. But on the other hand, PR 110495 is a similar issue, and > that was fixed... > > And TYPE_OVERFLOW_WRAPS should return true for integer vectors if they > always wrap (or is it only valid for scalars? But ANY_INTEGRAL_TYPE_P is > careful to handle vectors and complex numbers too, so I thought the > ANY_INTEGRAL_TYPE_CHECK in TYPE_OVERFLOW_WRAPS means that it work for > vectors too). That is slightly different, it was introducing -2(OVF) too.
Vector types follow the same rules as scalar types because we eventually lower them to scalar ops. So yes, I think this is a bug. Now, it will be difficult to exploit since the values are not actually used. One trick would be to CSE with a later tem = (unsigned)b[1] - (unsigned)c[1]; where for scalar code FRE would eliminate the above with the earlier a[2] doing tem = (unsigned)a[2]; but it currently doesn't do that for vectors and as the vectorizer introduces the wrong behavior we are not going to decompose that to scalars either. The particular case in question should be easy to fix though.