summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-11 07:33:23 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-11 07:33:23 +0000
commit171557e8ce0106d9cc0321be218b42bbaaefeec0 (patch)
tree654aa05676a650f4bfb708a7c200e82d0a1e39c8 /gcc
parent96efe7138202a220c3f6168a4e7f3fc9f4e93a83 (diff)
downloadgcc-171557e8ce0106d9cc0321be218b42bbaaefeec0.tar.gz
PR target/37382
* expmed.c (extract_low_bits): Avoid creating invalid subregs. * dse.c (find_shift_sequence): Use extract_low_bits instead of simplify_gen_subreg. * gcc.c-torture/compile/pr37382.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140265 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/dse.c12
-rw-r--r--gcc/expmed.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37382.c16
5 files changed, 50 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3be4d03bdd8..5cf27d019e6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2008-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/37382
+ * expmed.c (extract_low_bits): Avoid creating invalid subregs.
+ * dse.c (find_shift_sequence): Use extract_low_bits instead of
+ simplify_gen_subreg.
+
2008-09-11 Ira Rosen <irar@il.ibm.com>
* tree-vect-transform.c (vectorizable_store): Use the rhs vector type
diff --git a/gcc/dse.c b/gcc/dse.c
index 7283bbe67e4..0a3ebb40ffa 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1445,7 +1445,7 @@ find_shift_sequence (int access_size,
new_mode = GET_MODE_WIDER_MODE (new_mode))
{
rtx target, new_reg, shift_seq, insn, new_lhs;
- int cost, offset;
+ int cost;
/* Try a wider mode if truncating the store mode to NEW_MODE
requires a real instruction. */
@@ -1459,11 +1459,6 @@ find_shift_sequence (int access_size,
if (!CONSTANT_P (store_info->rhs)
&& !MODES_TIEABLE_P (new_mode, store_mode))
continue;
- offset = subreg_lowpart_offset (new_mode, store_mode);
- new_lhs = simplify_gen_subreg (new_mode, copy_rtx (store_info->rhs),
- store_mode, offset);
- if (new_lhs == NULL_RTX)
- continue;
new_reg = gen_reg_rtx (new_mode);
@@ -1496,6 +1491,11 @@ find_shift_sequence (int access_size,
if (cost > COSTS_N_INSNS (1))
continue;
+ new_lhs = extract_low_bits (new_mode, store_mode,
+ copy_rtx (store_info->rhs));
+ if (new_lhs == NULL_RTX)
+ continue;
+
/* We found an acceptable shift. Generate a move to
take the value from the store and put it into the
shift pseudo, then shift it, then generate another
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 0daf7fa31f0..6099c4b6839 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1991,8 +1991,22 @@ extract_low_bits (enum machine_mode mode, enum machine_mode src_mode, rtx src)
return src;
if (CONSTANT_P (src))
- return simplify_gen_subreg (mode, src, src_mode,
- subreg_lowpart_offset (mode, src_mode));
+ {
+ /* simplify_gen_subreg can't be used here, as if simplify_subreg
+ fails, it will happily create (subreg (symbol_ref)) or similar
+ invalid SUBREGs. */
+ unsigned int byte = subreg_lowpart_offset (mode, src_mode);
+ rtx ret = simplify_subreg (mode, src, src_mode, byte);
+ if (ret)
+ return ret;
+
+ if (GET_MODE (src) == VOIDmode
+ || !validate_subreg (mode, src_mode, src, byte))
+ return NULL_RTX;
+
+ src = force_reg (GET_MODE (src), src);
+ return gen_rtx_SUBREG (mode, src, byte);
+ }
if (GET_MODE_CLASS (mode) == MODE_CC || GET_MODE_CLASS (src_mode) == MODE_CC)
return NULL_RTX;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b42b5dfc2ed..1d3dc0a09d3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/37382
+ * gcc.c-torture/compile/pr37382.c: New test.
+
2008-09-11 Daniel Kraft <d@domob.eu>
PR fortran/36214
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37382.c b/gcc/testsuite/gcc.c-torture/compile/pr37382.c
new file mode 100644
index 00000000000..47525bcf956
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37382.c
@@ -0,0 +1,16 @@
+/* PR target/37382 */
+
+void baz (char *);
+int c;
+
+void
+bar (void)
+{
+ char a[2];
+ int *ip = &c;
+ char *p = a, *q = (char *) &ip;
+ const char *r = q + 2;
+ for (; q != r; p++, q++)
+ *p = *q;
+ baz (a);
+}