This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/52244] [4.5/4.6/4.7 Regression] wrong code for function returning union between int and _Bool at O > 2, with no-early-inlining
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 14 Feb 2012 12:10:10 +0000
- Subject: [Bug middle-end/52244] [4.5/4.6/4.7 Regression] wrong code for function returning union between int and _Bool at O > 2, with no-early-inlining
- Auto-submitted: auto-generated
- References: <bug-52244-4@http.gcc.gnu.org/bugzilla/>
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.