https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96135
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2020-07-10 Keywords| |missed-optimization Target Milestone|--- |9.4 Ever confirmed|0 |1 Priority|P3 |P2 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- The bswap pass doesn't handle these patterns at all (it doesn't look at stores). What does handle this case is store-merging which - on trunk - figures bswap in f() but not in g() likely because of the BIT_FIELD_REF -> cast folding which makes the stores appear inhomogenous: _3 = VIEW_CONVERT_EXPR<long long int>(x_2(D)); _4 = BIT_FIELD_REF <x_2(D), 8, 56>; v.c[0] = _4; ... _11 = (char) _3; v.c[7] = _11; store-merging already handles the cast vs. BIT_FIELD_REF case for f() but it appearantly doesn't consider to look through a VIEW_CONVERT. With -O3 we vectorize this in an inconvenient way and fully elide the store so store-merging isn't the correct pass to handle this: _3 = BIT_FIELD_REF <i_2(D), 8, 56>; _4 = BIT_FIELD_REF <i_2(D), 8, 48>; _5 = BIT_FIELD_REF <i_2(D), 8, 40>; _6 = BIT_FIELD_REF <i_2(D), 8, 32>; _7 = BIT_FIELD_REF <i_2(D), 8, 24>; _8 = BIT_FIELD_REF <i_2(D), 8, 16>; _9 = BIT_FIELD_REF <i_2(D), 8, 8>; _10 = (char) i_2(D); _21 = {_3, _4, _5, _6, _7, _8, _9, _10}; _18 = VIEW_CONVERT_EXPR<long long int>(_21); v ={v} {CLOBBER}; return _18; the vectorizer is also confused about BIT_FIELD_REF vs. cast here (I repeatedly thought of removing that simplification ... but the user could have written it as well :/). And it would look for a vector function argument but that's something that could be fixed. The above is all for GCC 10. GCC 8 possibly was lucky and did not have that BIT_FIELD_REF -> cast simplification.