re PR rtl-optimization/25703 (ACATS cxa4024 failure)

PR rtl-optimization/25703
	* combine.c (try_combine): Handle zero_extract and strict_low_part
	of non-lowpart SUBREGs for constant reg_subword_p set optimization.

	* gcc.target/i386/20060125-1.c: New test case.
	* gcc.target/i386/20060125-2.c: New test case.

From-SVN: r110242
This commit is contained in:
Roger Sayle 2006-01-26 02:48:01 +00:00
parent 51302a4168
commit d89b36e1a2
5 changed files with 91 additions and 20 deletions

View File

@ -1,3 +1,9 @@
2006-01-25 Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/25703
* combine.c (try_combine): Handle zero_extract and strict_low_part
of non-lowpart SUBREGs for constant reg_subword_p set optimization.
2006-01-25 Peter Bergner <bergner@vnet.ibm.com> 2006-01-25 Peter Bergner <bergner@vnet.ibm.com>
* global.c: Fix comment typos. * global.c: Fix comment typos.

View File

@ -1951,40 +1951,38 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
int offset = -1; int offset = -1;
int width = 0; int width = 0;
if (GET_CODE (dest) == STRICT_LOW_PART) if (GET_CODE (dest) == ZERO_EXTRACT)
{
width = GET_MODE_BITSIZE (GET_MODE (XEXP (dest, 0)));
offset = 0;
}
else if (GET_CODE (dest) == ZERO_EXTRACT)
{ {
if (GET_CODE (XEXP (dest, 1)) == CONST_INT if (GET_CODE (XEXP (dest, 1)) == CONST_INT
&& GET_CODE (XEXP (dest, 2)) == CONST_INT) && GET_CODE (XEXP (dest, 2)) == CONST_INT)
{ {
width = INTVAL (XEXP (dest, 1)); width = INTVAL (XEXP (dest, 1));
offset = INTVAL (XEXP (dest, 2)); offset = INTVAL (XEXP (dest, 2));
dest = XEXP (dest, 0);
if (BITS_BIG_ENDIAN) if (BITS_BIG_ENDIAN)
offset = GET_MODE_BITSIZE (GET_MODE (XEXP (dest, 0))) offset = GET_MODE_BITSIZE (GET_MODE (dest)) - width - offset;
- width - offset;
} }
} }
else if (subreg_lowpart_p (dest)) else
{ {
if (GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
width = GET_MODE_BITSIZE (GET_MODE (dest)); width = GET_MODE_BITSIZE (GET_MODE (dest));
offset = 0; offset = 0;
} }
/* ??? Preserve the original logic to handle setting the high word
of double-word pseudos, where inner is half the size of outer if (offset >= 0)
but not the lowpart. This could be generalized by handling
SUBREG_BYTE, WORDS_BIG_ENDIAN and BYTES_BIG_ENDIAN ourselves.
Unfortunately this logic is tricky to get right and probably
not worth the effort. */
else if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (temp)))
== 2 * GET_MODE_BITSIZE (GET_MODE (dest)))
{ {
width = GET_MODE_BITSIZE (GET_MODE (dest)); /* If this is the low part, we're done. */
offset = width; if (subreg_lowpart_p (dest))
;
/* Handle the case where inner is twice the size of outer. */
else if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (temp)))
== 2 * GET_MODE_BITSIZE (GET_MODE (dest)))
offset += GET_MODE_BITSIZE (GET_MODE (dest));
/* Otherwise give up for now. */
else
offset = -1;
} }
if (offset >= 0) if (offset >= 0)

View File

@ -1,3 +1,10 @@
2006-01-25 Jan Hubicka <jh@suse.cz>
Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/25703
* gcc.target/i386/20060125-1.c: New test case.
* gcc.target/i386/20060125-2.c: New test case.
2006-01-25 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de> 2006-01-25 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/18540 PR fortran/18540

View File

@ -0,0 +1,30 @@
/* PR rtl-optimization/25703 */
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -mtune=i486" } */
extern void abort (void);
struct a
{
int a;
char b,c,d,e;
};
__attribute__ ((noinline))
__attribute__ ((regparm(1))) t(struct a a)
{
if (a.a!=1 || a.b!=1 || a.c!=1)
abort();
}
int main()
{
struct a a;
a.c=1;
a.a=1;
a.b=1;
t(a);
return 0;
}

View File

@ -0,0 +1,30 @@
/* PR rtl-optimization/25703 */
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -mtune=pentiumpro" } */
extern void abort (void);
struct a
{
int a;
char b,c,d,e;
};
__attribute__ ((noinline))
__attribute__ ((regparm(1))) t(struct a a)
{
if (a.a!=1 || a.b!=1 || a.c!=1)
abort();
}
int main()
{
struct a a;
a.c=1;
a.a=1;
a.b=1;
t(a);
return 0;
}