cse.c (lookup_as_function): Delete mode frobbing code.

* cse.c (lookup_as_function): Delete mode frobbing code.
	(equiv_constant): Re-implement it there for SUBREGs.

Co-Authored-By: Gary Funck <gary@intrepid.com>

From-SVN: r142443
This commit is contained in:
Eric Botcazou 2008-12-04 21:47:13 +00:00 committed by Eric Botcazou
parent f782c65c3d
commit f5f8d79dec
4 changed files with 75 additions and 13 deletions

View File

@ -1,3 +1,9 @@
2008-12-04 Eric Botcazou <ebotcazou@adacore.com>
Gary Funck <gary@intrepid.com>
* cse.c (lookup_as_function): Delete mode frobbing code.
(equiv_constant): Re-implement it there for SUBREGs.
2008-12-04 Richard Guenther <rguenther@suse.de>
PR middle-end/36509

View File

@ -1364,17 +1364,6 @@ lookup_as_function (rtx x, enum rtx_code code)
struct table_elt *p
= lookup (x, SAFE_HASH (x, VOIDmode), GET_MODE (x));
/* If we are looking for a CONST_INT, the mode doesn't really matter, as
long as we are narrowing. So if we looked in vain for a mode narrower
than word_mode before, look for word_mode now. */
if (p == 0 && code == CONST_INT
&& GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (word_mode))
{
x = copy_rtx (x);
PUT_MODE (x, word_mode);
p = lookup (x, SAFE_HASH (x, VOIDmode), word_mode);
}
if (p == 0)
return 0;
@ -3641,6 +3630,8 @@ equiv_constant (rtx x)
if (GET_CODE (x) == SUBREG)
{
enum machine_mode mode = GET_MODE (x);
enum machine_mode imode = GET_MODE (SUBREG_REG (x));
rtx new_rtx;
/* See if we previously assigned a constant value to this SUBREG. */
@ -3649,10 +3640,25 @@ equiv_constant (rtx x)
|| (new_rtx = lookup_as_function (x, CONST_FIXED)) != 0)
return new_rtx;
/* If we didn't and if doing so makes sense, see if we previously
assigned a constant value to the enclosing word mode SUBREG. */
if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode)
&& GET_MODE_SIZE (word_mode) < GET_MODE_SIZE (imode))
{
int byte = SUBREG_BYTE (x) - subreg_lowpart_offset (mode, word_mode);
if (byte >= 0 && (byte % UNITS_PER_WORD) == 0)
{
rtx y = gen_rtx_SUBREG (word_mode, SUBREG_REG (x), byte);
new_rtx = lookup_as_function (y, CONST_INT);
if (new_rtx)
return gen_lowpart (mode, new_rtx);
}
}
/* Otherwise see if we already have a constant for the inner REG. */
if (REG_P (SUBREG_REG (x))
&& (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
return simplify_subreg (GET_MODE (x), new_rtx,
GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x));
return 0;
}

View File

@ -1,3 +1,7 @@
2008-12-04 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/union-5.c: New test.
2008-12-04 Jason Merrill <jason@redhat.com>
PR c++/37906

View File

@ -0,0 +1,46 @@
/* { dg-do run } */
/* { dg-options "-O -fgcse -fno-split-wide-types" } */
extern void abort(void);
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef struct
{
uint16_t thread;
uint16_t phase;
} s32;
typedef union
{
uint32_t i;
s32 s;
} u32;
typedef union
{
uint64_t i;
u32 u;
} u64;
static __attribute__((noinline))
void foo(int val)
{
u64 data;
uint32_t thread;
data.u.i = 0x10000L;
thread = data.u.s.thread;
if (val)
abort ();
if (thread)
abort ();
}
int main(void)
{
foo (0);
return 0;
}