https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121334
--- Comment #3 from Robin Dapp <rdapp at gcc dot gnu.org> --- (In reply to Richard Biener from comment #2) > Possibly some place in the vectorizer doesn't properly check a constant it > expands? But this is a VLS mode vector, so it should be loadable from > memory? > OTOH it seems to be another case of a "const" that isn't really constant > because of the poly components? > > Still, you can expand this by storing elementwise to the stack and loading > from there? Or by shift-right/left inserting elementwise? Yes, that's what I ended up doing, building the two vectors elementwise and then permute the elements into their proper position. What's a bit unfortunate from a testing perspective is that the code is not even executed with any vector size I tried. If I'm not mistaken that's due to us first checking for a vector size > 7 and later (on the same path) vector size <= 2 for it to be hit. Still testing a patch now. The example can be minimized a bit more even: char arr[64]; void init () { for (int i = 8; i >= 0; i--) arr[i] = i; } The gimple looks like this ("beautiful" VLA code): ... <bb 4> [local count: 96636765]: vectp_arr.9_32 = &arr + POLY_INT_CST [1, 18446744073709551608]; vect__1.10_35 = VEC_PERM_EXPR <{ 8, 7, 6, ... }, { 8, 7, 6, ... }, { POLY_INT_CST [7, 8], POLY_INT_CST [6, 8], POLY_INT_CST [5, 8], ... }>; MEM <vector([8,8]) char> [(char *)vectp_arr.9_32] = vect__1.10_35; if (POLY_INT_CST [2, 8] <= 2) goto <bb 9>; [11.27%] else goto <bb 5>; [88.73%] <bb 5> [local count: 75027711]: bnd.12_55 = POLY_INT_CST [1, 4294967288] >> 2; _66 = (sizetype) POLY_INT_CST [8, 8]; _67 = 5 - _66; vectp_arr.19_65 = &arr + _67; MEM <vector(4) char> [(char *)vectp_arr.19_65] = { POLY_INT_CST [253, 248], POLY_INT_CST [254, 248], POLY_INT_CST [255, 248], POLY_INT_CST [0, 248] }; if (bnd.12_55 != 1) goto <bb 6>; [42.84%] else goto <bb 7>; [57.16%] <bb 6> [local count: 32145146]: vectp_arr.18_80 = vectp_arr.19_65 + 18446744073709551612; MEM <vector(4) char> [(char *)vectp_arr.18_80] = { POLY_INT_CST [249, 248], POLY_INT_CST [250, 248], POLY_INT_CST [251, 248], POLY_INT_CST [252, 248] }; Those vector constants don't get created during vectorization but later. vect just has one: vect__1.7_31 = (vector([8,8]) char) vect_vec_iv_.6_29; _1 = (char) i_9; vect__1.10_35 = VEC_PERM_EXPR <vect__1.7_31, vect__1.7_31, { POLY_INT_CST [7, 8], POLY_INT_CST [6, 8], POLY_INT_CST [5, 8], ... }>; MEM <vector([8,8]) char> [(char *)vectp_arr.8_33] = vect__1.10_35; which is also more intelligible ;)