aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2015-12-04 19:23:21 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2015-12-04 19:23:21 +0000
commit18c8f1a812865bbd0f07b29910c54ab8c0632c54 (patch)
tree9fa2dc2b4803b9e2a57fc353b8d1eeecee987348
parent4ff3145ae198ae8f4e2c9c60e2df0267ac52329b (diff)
downloadgcc-18c8f1a812865bbd0f07b29910c54ab8c0632c54.zip
gcc-18c8f1a812865bbd0f07b29910c54ab8c0632c54.tar.gz
gcc-18c8f1a812865bbd0f07b29910c54ab8c0632c54.tar.bz2
re PR rtl-optimization/68349 (ice in decompose_normal_address with -O2 at rtlanal.c:6086)
2015-12-04 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/68349 * lra-eliminations.c (move_plus_up): New function. (lra_eliminate_regs_1): Use the function. 2015-12-04 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/68349 * gcc.target/i386/pr68349.c: New test. From-SVN: r231300
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-eliminations.c25
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr68349.c30
4 files changed, 66 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 96e0c46..81eb73f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-12-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/68349
+ * lra-eliminations.c (move_plus_up): New function.
+ (lra_eliminate_regs_1): Use the function.
+
2015-12-04 Nathan Sidwell <nathan@acm.org>
* config/nvptx/nvptx.c (nvptx_assemble_decl_begin): New,
diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 38b1fbb..c639d36 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -279,6 +279,29 @@ get_elimination (rtx reg)
return &self_elim_table;
}
+/* Transform (subreg (plus reg const)) to (plus (subreg reg) const)
+ when it is possible. Return X or the transformation result if the
+ transformation is done. */
+static rtx
+move_plus_up (rtx x)
+{
+ rtx subreg_reg;
+ enum machine_mode x_mode, subreg_reg_mode;
+
+ if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x))
+ return x;
+ subreg_reg = SUBREG_REG (x);
+ x_mode = GET_MODE (x);
+ subreg_reg_mode = GET_MODE (subreg_reg);
+ if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
+ && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
+ && CONSTANT_P (XEXP (subreg_reg, 1)))
+ return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, subreg_reg,
+ subreg_reg_mode),
+ XEXP (subreg_reg, 1));
+ return x;
+}
+
/* Scan X and replace any eliminable registers (such as fp) with a
replacement (such as sp) if SUBST_P, plus an offset. The offset is
a change in the offset between the eliminable register and its
@@ -407,6 +430,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
subst_p, update_p,
update_sp_offset, full_p);
+ new0 = move_plus_up (new0);
+ new1 = move_plus_up (new1);
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
return form_sum (new0, new1);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 40ae4fb..d5f0ce0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/68349
+ * gcc.target/i386/pr68349.c: New test.
+
2015-12-04 Nathan Sidwell <nathan@acm.org>
* gcc.target/nvptx/ary-init.c: New.
@@ -288,7 +293,6 @@
* gfortran.dg/graphite/pr68550-1.f90: New.
* gfortran.dg/graphite/pr68550-2.f90: New.
->>>>>>> .r231221
2015-12-02 Marek Polacek <polacek@redhat.com>
PR c/68513
diff --git a/gcc/testsuite/gcc.target/i386/pr68349.c b/gcc/testsuite/gcc.target/i386/pr68349.c
new file mode 100644
index 0000000..4eae053
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr68349.c
@@ -0,0 +1,30 @@
+/* PR target/68483 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int a, b;
+unsigned long strlen();
+typedef struct sHyphenNode {
+ char sepcnts[0];
+ struct sHyphenNode *Daughters[];
+} * PHyphenNode;
+int GetIndex();
+PHyphenNode c;
+void DoHyphens_Field_1() {
+ char d[300], e[300];
+ int z, f, l = strlen();
+ for (; z;)
+ ;
+ for (; l; z++) {
+ f = z;
+ for (; f < l; f++) {
+ c = c->Daughters[GetIndex(d[f])];
+ a = 0;
+ for (; a <= f - z; a++)
+ if (e[z + a])
+ e[z] = c->sepcnts[a];
+ }
+ }
+ if (e[z])
+ b = 1;
+}