diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-12-04 21:47:13 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-12-04 21:47:13 +0000 |
commit | f5f8d79dec035521d9c869e65b37636d934f66a3 (patch) | |
tree | 77e1652f735ed18f6ab1eb91f6bcdb8d0f99468b | |
parent | f782c65c3da796b4eb907daa55a160f1203ee5e6 (diff) | |
download | gcc-f5f8d79dec035521d9c869e65b37636d934f66a3.zip gcc-f5f8d79dec035521d9c869e65b37636d934f66a3.tar.gz gcc-f5f8d79dec035521d9c869e65b37636d934f66a3.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cse.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/union-5.c | 46 |
4 files changed, 75 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d9b81fe..e46adae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c9d674..715ecd6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/union-5.c b/gcc/testsuite/gcc.dg/union-5.c new file mode 100644 index 0000000..ac5322b --- /dev/null +++ b/gcc/testsuite/gcc.dg/union-5.c @@ -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; +} |