aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2017-01-27 18:08:14 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2017-01-27 18:08:14 +0000
commitd8321b33d3b2d74c90d70ebdddc57bd6c86361ee (patch)
treee97490e51e4d447019a918c2a75043329221c38d /gcc
parent9e2ea13ec2a6d210520b87ffe8d44c30ede42994 (diff)
downloadgcc-d8321b33d3b2d74c90d70ebdddc57bd6c86361ee.zip
gcc-d8321b33d3b2d74c90d70ebdddc57bd6c86361ee.tar.gz
gcc-d8321b33d3b2d74c90d70ebdddc57bd6c86361ee.tar.bz2
re PR rtl-optimization/71374 (ICE on valid code at -O1 and above on x86_64-linux-gnu: in extract_constrain_insn, at recog.c:2190)
2017-01-27 Vladimir Makarov <vmakarov@redhat.com> PR tree-optimization/71374 * lra-constraints.c (check_conflict_input_operands): New. (match_reload): Use it. 2017-01-27 Vladimir Makarov <vmakarov@redhat.com> PR tree-optimization/71374 * testsuite/gcc.target/i386/pr71374.c: New. From-SVN: r244991
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-constraints.c34
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr71374.c8
4 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2c90d06..4de9c02 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2017-01-27 Vladimir Makarov <vmakarov@redhat.com>
+ PR tree-optimization/71374
+ * lra-constraints.c (check_conflict_input_operands): New.
+ (match_reload): Use it.
+
+2017-01-27 Vladimir Makarov <vmakarov@redhat.com>
+
PR target/79131
* lra-assigns.c (find_hard_regno_for_1): Take endianess for into
account to calculate conflict_set.
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 2586913..22323b2 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -878,6 +878,29 @@ regno_val_use_in (unsigned int regno, rtx x)
return NULL_RTX;
}
+/* Return true if all current insn non-output operands except INS (it
+ has a negaitve end marker) do not use pseudos with the same value
+ as REGNO. */
+static bool
+check_conflict_input_operands (int regno, signed char *ins)
+{
+ int in;
+ int n_operands = curr_static_id->n_operands;
+
+ for (int nop = 0; nop < n_operands; nop++)
+ if (! curr_static_id->operand[nop].is_operator
+ && curr_static_id->operand[nop].type != OP_OUT)
+ {
+ for (int i = 0; (in = ins[i]) >= 0; i++)
+ if (in == nop)
+ break;
+ if (in < 0
+ && regno_val_use_in (regno, *curr_id->operand_loc[nop]) != NULL_RTX)
+ return false;
+ }
+ return true;
+}
+
/* Generate reloads for matching OUT and INS (array of input operand
numbers with end marker -1) with reg class GOAL_CLASS, considering
output operands OUTS (similar array to INS) needing to be in different
@@ -917,7 +940,9 @@ match_reload (signed char out, signed char *ins, signed char *outs,
pseudos as reload pseudos can die although original
pseudos still live where reload pseudos dies. */
if (REG_P (in_rtx) && (int) REGNO (in_rtx) < lra_new_regno_start
- && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx)))
+ && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))
+ && (!early_clobber_p
+ || check_conflict_input_operands(REGNO (in_rtx), ins)))
lra_assign_reg_val (REGNO (in_rtx), REGNO (reg));
}
else
@@ -947,7 +972,10 @@ match_reload (signed char out, signed char *ins, signed char *outs,
&& (int) REGNO (subreg_reg) < lra_new_regno_start
&& GET_MODE (subreg_reg) == outmode
&& SUBREG_BYTE (in_rtx) == SUBREG_BYTE (new_in_reg)
- && find_regno_note (curr_insn, REG_DEAD, REGNO (subreg_reg)))
+ && find_regno_note (curr_insn, REG_DEAD, REGNO (subreg_reg))
+ && (! early_clobber_p
+ || check_conflict_input_operands (REGNO (subreg_reg),
+ ins)))
lra_assign_reg_val (REGNO (subreg_reg), REGNO (reg));
}
}
@@ -1002,6 +1030,8 @@ match_reload (signed char out, signed char *ins, signed char *outs,
= (! early_clobber_p && ins[1] < 0 && REG_P (in_rtx)
&& (int) REGNO (in_rtx) < lra_new_regno_start
&& find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))
+ && (! early_clobber_p
+ || check_conflict_input_operands (REGNO (in_rtx), ins))
&& (out < 0
|| regno_val_use_in (REGNO (in_rtx), out_rtx) == NULL_RTX)
&& !out_conflict
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 39f148f..f2d9dfb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-01-27 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR tree-optimization/71374
+ * testsuite/gcc.target/i386/pr71374.c: New.
+
2017-01-27 Martin Sebor <msebor@redhat.com>
PR c++/71290
diff --git a/gcc/testsuite/gcc.target/i386/pr71374.c b/gcc/testsuite/gcc.target/i386/pr71374.c
new file mode 100644
index 0000000..73e8072
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71374.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int a, b, c;
+void
+foo (void *x, void *y)
+{
+ __asm__ ("": "=&c" (a), "=&D" (b), "=&S" (c): "r" (y), "2" (y));
+}