diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2012-09-01 16:29:45 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2012-09-01 16:29:45 +0200 |
commit | 2caf633d4f8d4281dd428a1cfeac28b92bc9b6f8 (patch) | |
tree | dba1efc348dffe842ca69a7e9dd21dbcd409dafe | |
parent | 78e4f1ad4e4842af9897bd6ee6fb19fc33fe7762 (diff) | |
download | gcc-2caf633d4f8d4281dd428a1cfeac28b92bc9b6f8.zip gcc-2caf633d4f8d4281dd428a1cfeac28b92bc9b6f8.tar.gz gcc-2caf633d4f8d4281dd428a1cfeac28b92bc9b6f8.tar.bz2 |
re PR target/46829 (ICE: in spill_failure, at reload1.c:2105 with -fschedule-insns -fsched-pressure and variadic function)
PR target/46829
PR target/46843
* config/i386/i386.c (ix86_legitimate_combined_insn): New function.
(TARGET_LEGITIMATE_COMBINED_INSN): New macro.
testsuite/ChangeLog:
PR target/46829
PR target/46843
* gcc.target/i386/pr46829.c: New test.
* gcc.target/i386/pr46843.c: Ditto.
From-SVN: r190847
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 75 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr46829.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr46843.c | 12 |
5 files changed, 119 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 545fee0..14b923c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2012-09-01 Uros Bizjak <ubizjak@gmail.com> + PR target/46829 + PR target/46843 + * config/i386/i386.c (ix86_legitimate_combined_insn): New function. + (TARGET_LEGITIMATE_COMBINED_INSN): New macro. + +2012-09-01 Uros Bizjak <ubizjak@gmail.com> + * target.def (legitimate_combined_insn): New target hook. * doc/tm.texi.in (TARGET_LEGITIMATE_COMBINED_INSN): New hook. * doc/tm.texi: Regenerated. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c7be001..e2e1d22 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5545,6 +5545,78 @@ ix86_return_pops_args (tree fundecl, tree funtype, int size) return 0; } + +/* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook. */ + +static bool +ix86_legitimate_combined_insn (rtx insn) +{ + /* Check operand constraints in case hard registers were propagated + into insn pattern. This check prevents combine pass from + generating insn patterns with invalid hard register operands. + These invalid insns can eventually confuse reload to error out + with a spill failure. See also PRs 46829 and 46843. */ + if ((INSN_CODE (insn) = recog (PATTERN (insn), insn, 0)) >= 0) + { + int i; + + extract_insn (insn); + preprocess_constraints (); + + for (i = 0; i < recog_data.n_operands; i++) + { + rtx op = recog_data.operand[i]; + enum machine_mode mode = GET_MODE (op); + struct operand_alternative *op_alt; + int offset = 0; + bool win; + int j; + + /* A unary operator may be accepted by the predicate, but it + is irrelevant for matching constraints. */ + if (UNARY_P (op)) + op = XEXP (op, 0); + + if (GET_CODE (op) == SUBREG) + { + if (REG_P (SUBREG_REG (op)) + && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER) + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)), + GET_MODE (SUBREG_REG (op)), + SUBREG_BYTE (op), + GET_MODE (op)); + op = SUBREG_REG (op); + } + + if (!(REG_P (op) && HARD_REGISTER_P (op))) + continue; + + op_alt = recog_op_alt[i]; + + /* Operand has no constraints, anything is OK. */ + win = !recog_data.n_alternatives; + + for (j = 0; j < recog_data.n_alternatives; j++) + { + if (op_alt[j].anything_ok + || (op_alt[j].matches != -1 + && operands_match_p + (recog_data.operand[i], + recog_data.operand[op_alt[j].matches])) + || reg_fits_class_p (op, op_alt[j].cl, offset, mode)) + { + win = true; + break; + } + } + + if (!win) + return false; + } + } + + return true; +} /* Argument support functions. */ @@ -40707,6 +40779,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val) #undef TARGET_RETURN_POPS_ARGS #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args +#undef TARGET_LEGITIMATE_COMBINED_INSN +#define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn + #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 22fcd06..c5f88b7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2012-09-01 Uros Bizjak <ubizjak@gmail.com> + + PR target/46829 + PR target/46843 + * gcc.target/i386/pr46829.c: New test. + * gcc.target/i386/pr46843.c: Ditto. + 2012-08-31 Paolo Carlini <paolo.carlini@oracle.com> Jason Merrill <jason@redhat.com> diff --git a/gcc/testsuite/gcc.target/i386/pr46829.c b/gcc/testsuite/gcc.target/i386/pr46829.c new file mode 100644 index 0000000..d4c04d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr46829.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fschedule-insns" } */ + +struct S +{ + int i, j; +}; + +extern struct S s[]; + +extern void bar (int, ...); + +void +foo (int n) +{ + while (s[n].i) + bar (0, n, s[n].j, s, s[n].i / s[n].j); +} diff --git a/gcc/testsuite/gcc.target/i386/pr46843.c b/gcc/testsuite/gcc.target/i386/pr46843.c new file mode 100644 index 0000000..3b0d76d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr46843.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fschedule-insns" } */ + +void foo (double *d1, double *u1, double *u2, double *d2, int s, int j, int i) +{ + int n = 1 << s; + double x = 0; + + for (; j < n; j++) + x += d1[j] * d2[i]; + d1[i] = x; +} |