mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 15:41:09 +08:00
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:
parent
f782c65c3d
commit
f5f8d79dec
@ -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
|
||||
|
32
gcc/cse.c
32
gcc/cse.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
46
gcc/testsuite/gcc.dg/union-5.c
Normal file
46
gcc/testsuite/gcc.dg/union-5.c
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user