aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2016-04-19 02:49:54 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2016-04-19 02:49:54 +0000
commit987b67f17c8759c47f83732b9336fbe0795d2baf (patch)
tree30b07935d39b2b8a32cc74405095ec2c61d3e862
parentcd1c4ba8114115d7568a8e9d292413fd1b2c71a9 (diff)
downloadgcc-987b67f17c8759c47f83732b9336fbe0795d2baf.zip
gcc-987b67f17c8759c47f83732b9336fbe0795d2baf.tar.gz
gcc-987b67f17c8759c47f83732b9336fbe0795d2baf.tar.bz2
re PR middle-end/70689 (ICE on valid code at -O1 in 32-bit mode on x86_64-linux-gnu in curr_insn_transform, at lra-constraints.c:3564)
2016-04-18 Vladimir Makarov <vmakarov@redhat.com> PR middle-end/70689 * lra-constraints.c (equiv_substition_p): New. (process_alt_operands): Use it. (swap_operands): Swap it. (curr_insn_transform): Update it. 2016-04-18 Vladimir Makarov <vmakarov@redhat.com> PR middle-end/70689 * testsuite/gcc.target/i386/pr70689.c: New. From-SVN: r235184
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/lra-constraints.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70689.c27
4 files changed, 51 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 60b327b..458f2cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2016-04-18 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/70689
+ * lra-constraints.c (equiv_substition_p): New.
+ (process_alt_operands): Use it.
+ (swap_operands): Swap it.
+ (curr_insn_transform): Update it.
+
2016-04-18 Michael Matz <matz@suse.de>
* tree.h (TYPE_ALIGN, DECL_ALIGN): Return shifted amount.
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index c00afe7..14d5f1d 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1258,6 +1258,10 @@ static bool goal_alt_swapped;
/* The chosen insn alternative. */
static int goal_alt_number;
+/* True if the corresponding operand is the result of an equivalence
+ substitution. */
+static bool equiv_substition_p[MAX_RECOG_OPERANDS];
+
/* The following five variables are used to choose the best insn
alternative. They reflect final characteristics of the best
alternative. */
@@ -2064,7 +2068,10 @@ process_alt_operands (int only_alternative)
memory, or make other memory by reloading the
address like for 'o'. */
if (CONST_POOL_OK_P (mode, op)
- || MEM_P (op) || REG_P (op))
+ || MEM_P (op) || REG_P (op)
+ /* We can restore the equiv insn by a
+ reload. */
+ || equiv_substition_p[nop])
badop = false;
constmemok = true;
offmemok = true;
@@ -3371,6 +3378,7 @@ swap_operands (int nop)
std::swap (curr_operand_mode[nop], curr_operand_mode[nop + 1]);
std::swap (original_subreg_reg_mode[nop], original_subreg_reg_mode[nop + 1]);
std::swap (*curr_id->operand_loc[nop], *curr_id->operand_loc[nop + 1]);
+ std::swap (equiv_substition_p[nop], equiv_substition_p[nop + 1]);
/* Swap the duplicates too. */
lra_update_dup (curr_id, nop);
lra_update_dup (curr_id, nop + 1);
@@ -3473,8 +3481,10 @@ curr_insn_transform (bool check_only_p)
old = SUBREG_REG (old);
subst = get_equiv_with_elimination (old, curr_insn);
original_subreg_reg_mode[i] = VOIDmode;
+ equiv_substition_p[i] = false;
if (subst != old)
{
+ equiv_substition_p[i] = true;
subst = copy_rtx (subst);
lra_assert (REG_P (old));
if (GET_CODE (op) != SUBREG)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6d9912a..e6bd406 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-18 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/70689
+ * testsuite/gcc.target/i386/pr70689.c: New.
+
2016-04-18 H.J. Lu <hongjiu.lu@intel.com>
PR target/70708
diff --git a/gcc/testsuite/gcc.target/i386/pr70689.c b/gcc/testsuite/gcc.target/i386/pr70689.c
new file mode 100644
index 0000000..0529a00
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70689.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-O1" } */
+
+struct S
+{
+ int f;
+};
+
+double a;
+int c;
+
+static
+void fn1 (struct S *p1)
+{
+ for (; c; )
+ if (p1->f++)
+ a = (int) p1;
+}
+
+int
+main ()
+{
+ struct S b = { 0 };
+ fn1 (&b);
+ return 0;
+}