http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52244
--- Comment #6 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-02-14 12:10:10 UTC --- The issue is that SRA thinks u.b = 1; is access { base = (1716)'u', offset = 0, size = 8, expr = u.b, type = _Bool, ... note 'size = 8'. That is what get_ref_base_and_extent says, but it in the end boils down to the question of how we handle type precision vs. mode precision. For example we happily fold VIEW_CONVERT_EXPR<_Bool>(18) to 0. So, as SRA will create value replacements it cannot consider u.b an access of size 8. OTOH aliasing has to assume that a store to u.b conflicts with any other QImode store at the same location, so it cannot simply say "well, it's only one bit". With a patch SRA to make SRA not assume size 8 but size 1 in this case we generate <bb 2>: u.b = 1; u$b_6 = MEM[(_Bool *)&1].b; SR.3_8 = 18; u = VIEW_CONVERT_EXPR<union u_t>(SR.3_8); u$b_9 = MEM[(union u_r *)&u].b; MEM[(union u_r *)&u].b = u$b_9; D.1729 = u; u ={v} {CLOBBER}; return D.1729; instead which happens to work (double-ugh for the MEM[(_Bool *)&1].b though, fortunately it's unused). With a patch that makes SRA generate replacements that cover the whole size with their replacements we generate foo () { unsigned char SR.3; <unnamed-unsigned:8> u; union u_t D.1741; union u_t u; union u_t D.1729; <bb 2>: u_7 = 1; SR.3_6 = 18; u_2 = SR.3_6; MEM[(union u_r *)&D.1729] = u_2; return D.1729; Another alternative would be to somehow disqualify the whole aggregate when the situation (scalar field with size != precision and parent that does not have all fields scalarized) happens. I'm testing the replacement change.