This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] combine.c if_then_else_cond() subreg modes
- To: law at redhat dot com
- Subject: Re: [patch] combine.c if_then_else_cond() subreg modes
- From: DJ Delorie <dj at redhat dot com>
- Date: Tue, 9 Jan 2001 23:31:45 -0500
- CC: gcc-patches at gcc dot gnu dot org
- References: <13801.979099904@upchuck>
> What we're trying to do in this code is narrow the the true/false values,
> so we want to use "mode" as-is instead of the mode of the inner part of
> the subreg. Why? Because "mode" will always be smaller due to this
> condition:
But, if you look in operand_subword, it only uses the mode to restrict
the parts of the const_int it can take a subreg of (because const_ints
don't have their own modes). We narrow the mode just after that, with
force_to_mode().
> Presumably you're looking at this code for a reason :-) Can you give more
> details about what's going wrong?
gcc/testsuite/gcc.c-torture/execute/20000314-2.c (in gnupro, at least)
if_then_else_cond returns (const_int 0x400000000) as one of the
branches (true0 in this case). That would be wrapped in a (subreg:SI
... 1) to pull off the upper 32 bits in the failing case. When you
call operand_subword with a mode of SI, it refuses to let you extract
bits outside of the 32 LSBs (because we just told it the const_int is
a 32-bit SImode). You can't extract the upper 32 bits unless the mode
passed to operand_subword is a 64-bit mode.
So,
operand_subword( 0x400000000, 1, 0, SImode)
Sees the big constant as a 32-bit value (SImode) and thus will never
be able to pass back the "0x4" part, so returns zero. This causes a
misoptimization (because both true and false result in zero).
The constant is *not* SImode. It is DImode, and we need to tell
operand_subword mode that, so that it knows how many bits it is
allowed to extract from. The value *after* extraction can be narrowed
to SImode, which force_to_mode does.