This is the mail archive of the gcc@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] |
| Other format: | [Raw text] | |
> The problem seems to arise in make_compound_operation/make_extraction.
> We start with (sign_extend:DI (reg:SI 32)). make_compound_operation
> converts this to (ashiftrt:DI (ashift:DI (reg:DI 32) 32) 32). Then
> make_extraction converts this to (sign_extend:DI (subreg:SI (reg:DI
> 32))). We should have gotten back the same register RTL at the end
> that we had at the beginning. Thus assuming that combine is supposed to
> work for hard registers, one of these two routines is broken. I am
> wondering if perhaps make_compound_operation broke as a side-effect of
> simplify_gen_subreg related changes. Or it may be that this has been
> broken for a long time.
Thanks for the analysis.
> There is curious code in make_extraction which deliberately avoids
> calling gen_lowpart, and instead explicitly makes a SUBREG. There is a
> comment that claims we must have a SUBREG here. Perhaps this is out
> dated. We could try using gen_lowpart here to see if it works. This
> will have unpredicable effect though, so it isn't clear if it is safe.
> This needs to be investigated.
This comment, I presume:
else if (GET_CODE (inner) == REG)
{
/* We can't call gen_lowpart_for_combine here since we always want
a SUBREG and it would sometimes return a new hard register. */
> An alternative solution would be for combine to try to notice when it it
> has changed the size of a register, and adjust the REG_DEAD note, but I
> suspect this will be hard because we don't have easy access to the info
> we need.
Would it be sufficient anyway? Pseudo 33 would then be live on entry but not
on exit, without being mentioned in-between.
> I looked at make_extraction more closely. The call to
> gen_lowpart_for_combine was removed here:
>
> Sat Jun 20 06:32:11 1992 Richard Kenner (kenner at vlsi1.ultra.nyu.edu)
>
>
> * combine.c (make_extraction): Always ensure we have a SUBREG
> when we make a STRICT_LOW_PART.
>
> However, this code is used for both when the operand is !in_dest, and
> for the case when STRICT_LOW_PART is available. So it looks like this
> might have been broken since the beginning. If !in_dest is true, we
> should be able to use gen_lowpart_for_combine here, and that will fix
> the sparc build problem. Hopefully without causing other build problems.
Clever. The attached patch indeed fixes the problem, by folding the former
(sign_extend:DI (subreg:SI (reg:DI 32))).
Is it what you intended? If so, I'll test the patch on x86, SPARC32 and
SPARC64 tomorrow.
--
Eric Botcazou
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.360
diff -c -r1.360 combine.c
*** combine.c 5 Jun 2003 13:00:14 -0000 1.360
--- combine.c 11 Jun 2003 20:15:11 -0000
***************
*** 6185,6214 ****
}
else if (GET_CODE (inner) == REG)
{
- /* We can't call gen_lowpart_for_combine here since we always want
- a SUBREG and it would sometimes return a new hard register. */
if (tmode != inner_mode)
{
! HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
! if (WORDS_BIG_ENDIAN
! && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
! final_word = ((GET_MODE_SIZE (inner_mode)
! - GET_MODE_SIZE (tmode))
! / UNITS_PER_WORD) - final_word;
! final_word *= UNITS_PER_WORD;
! if (BYTES_BIG_ENDIAN &&
! GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
! final_word += (GET_MODE_SIZE (inner_mode)
! - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
! /* Avoid creating invalid subregs, for example when
! simplifying (x>>32)&255. */
! if (final_word >= GET_MODE_SIZE (inner_mode))
! return NULL_RTX;
! new = gen_rtx_SUBREG (tmode, inner, final_word);
}
else
new = inner;
--- 6185,6219 ----
}
else if (GET_CODE (inner) == REG)
{
if (tmode != inner_mode)
{
! if (in_dest)
! {
! /* We can't call gen_lowpart_for_combine here since we always want
! a SUBREG and it would sometimes return a new hard register. */
! HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
! if (WORDS_BIG_ENDIAN
! && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
! final_word = ((GET_MODE_SIZE (inner_mode)
! - GET_MODE_SIZE (tmode))
! / UNITS_PER_WORD) - final_word;
! final_word *= UNITS_PER_WORD;
! if (BYTES_BIG_ENDIAN &&
! GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
! final_word += (GET_MODE_SIZE (inner_mode)
! - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
! /* Avoid creating invalid subregs, for example when
! simplifying (x>>32)&255. */
! if (final_word >= GET_MODE_SIZE (inner_mode))
! return NULL_RTX;
! new = gen_rtx_SUBREG (tmode, inner, final_word);
! }
! else
! new = gen_lowpart_for_combine (tmode, inner);
}
else
new = inner;
Attachment:
natFloat.cc.21.combine
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |