aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2012-09-01 16:29:45 +0200
committerUros Bizjak <uros@gcc.gnu.org>2012-09-01 16:29:45 +0200
commit2caf633d4f8d4281dd428a1cfeac28b92bc9b6f8 (patch)
treedba1efc348dffe842ca69a7e9dd21dbcd409dafe /gcc
parent78e4f1ad4e4842af9897bd6ee6fb19fc33fe7762 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c75
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46829.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46843.c12
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;
+}