https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88064
Bug ID: 88064 Summary: [9 Regression] Incorrect vectorizer over_widening pattern handling Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- Something I've discovered by code inspection: int a[64], b[64], c[64]; void foo () { int i; for (i = 0; i < 64; i++) { long long d = a[i]; long long e = b[i]; d += e; c[i] = d; } } with -O3 -fno-tree-forwprop -fno-tree-vrp might introduce UB into the source where there was none. In *.ifcvt we have: _1 = a[i_14]; d_7 = (long long int) _1; _2 = b[i_14]; e_8 = (long long int) _2; d_9 = d_7 + e_8; _3 = (int) d_9; c[i_14] = _3; suppose int is 32-bit, long long 64-bit and a[i] is always INT_MAX and b[i] 1. The original program doesn't invoke UB, because the addition is done in long long int type. Now, GCC 9 vectorizes this as: vector(4) int vect__1.6; vector(4) int vect__2.9; vector(4) signed int vect_patt_25.10; vector(4) int vect_patt_23.11; vect__1.6_19 = MEM[(int *)vectp_a.4_21]; vect__2.9_16 = MEM[(int *)vectp_b.7_18]; vect_patt_25.10_13 = vect__1.6_19 + vect__2.9_16; vect_patt_23.11_12 = VIEW_CONVERT_EXPR<vector(4) int>(vect_patt_25.10_13); MEM[(int *)vectp_c.12_5] = vect_patt_23.11_12; The VCE is weird, why do we have special vectors of signed int vs. int? But, more importantly, of course the addition in this case needs to be done in in vector(4) unsigned int type, because we've demoted it from the original (unless we can prove e.g. through ranges that undefined behavior will not be triggered).