diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2017-01-27 18:08:14 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2017-01-27 18:08:14 +0000 |
commit | d8321b33d3b2d74c90d70ebdddc57bd6c86361ee (patch) | |
tree | e97490e51e4d447019a918c2a75043329221c38d /gcc | |
parent | 9e2ea13ec2a6d210520b87ffe8d44c30ede42994 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr71374.c | 8 |
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)); +} |