This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [patch] combine.c if_then_else_cond() subreg modes



> 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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]