This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PING: [PATCH] Fix PR 20972
- From: James E Wilson <wilson at specifixinc dot com>
- To: Bernd Schmidt <bernds_cb1 at t-online dot de>
- Cc: gcc-patches at gcc dot gnu dot org, vmakarov at redhat dot com
- Date: Mon, 02 May 2005 19:30:53 -0700
- Subject: Re: PING: [PATCH] Fix PR 20972
- References: <462537f9a30826ca0c44da37a11f4273@apple.com> <426F6C25.9040408@t-online.de> <b1d5ed2fca0a54947c660ca4722e902d@apple.com> <4270D3DC.4000700@t-online.de> <4271637B.5080608@specifixinc.com> <427214DE.2000100@t-online.de>
On Fri, 2005-04-29 at 04:05, Bernd Schmidt wrote:
> Can you think of a way of doing that which wouldn't effectively disable
> what Vlad was trying to do with his patch?
My day job interfered with my attempt to look at this. I am not very
familiar with Vlad's patch, but from what I understand of what it does,
my suggestion won't effect Vlad's patch except to make it unnecessary in
some cases.
E.g. currently we get RTL like this
function start:
...
bitfield insert into r100 (r100 used uninitialized)
...
function end
since r100 is used uninitialized, it is considered live from the program
start. Vlad's patch changes the lifetime to start at the point where it
is first initialized.
My suggestion is to change this to
function start:
...
r100 = 0
bitfield insert into r100 (r100 used uninitialized)
...
function end
Now, Vlad's patch is no longer necessary, because the register is
initialized, and it is obvious where its lifetime starts. This change
has two benefits
1) Combine can optimize away the bitfield insert, giving shorter and
faster code.
2) We can avoid uninitialized register reads, which on IA-64 can lead to
an illegal instruction fault if the NaT bit is set.
We still need Vlad's patch for the case explained in the comment before
make_accurate_live_analysis, where we have a variable defined inside a
loop and used after the loop. We would not be inserting extra code in
this case.
The bit-field insert case is effectively the same as the case in PR
20972, in both cases, we have a value that is both used and set in the
same expression, and this expression is performing an uninitialized
read. It should be possible to detect this and fix it without
interfering with other cases, such as the loop case that Vlad was trying
to fix.
The bit-field problem can be seen with simple testcases if you look at
the assembly output. Consider this testcase
struct baz { int : 24; int bar : 8; };
void sub2 (struct baz);
void
sub (int i)
{
struct baz foo;
foo.bar = i;
sub2 (foo);
}
if I compile this for x86 with -O, I get
movzbl 8(%ebp), %eax
sall $24, %eax
andl $16777215, %edx
orl %eax, %edx
movl %edx, (%esp)
Note that %edx is being used uninitialized. Also notice that we could
do this 3 instructions trivially.
If we emit a
movl 0, %edx
during global immediately before the andl, then combine will optimize
away the zero init, the andl, and the orl, giving a 3 instruction
sequence with no uninitialized register reads.
We could actually do this with one instruction if we don't mind the risk
of some uninitialized memory reads, but that might be more trouble than
it is worth. I'd be happy with the 3 instruction sequence.
--
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com