This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[testcase] IA-32 ICE due to not splitted insn
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 25 Aug 2003 17:43:32 +0200
- Subject: [testcase] IA-32 ICE due to not splitted insn
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcase causes ICE on gcc-3_3-branch (as of today) and
gcc-3_3-rhl-branch.
The problem is that at -O scheduling is not done after reload and thus also
split_all_insns is not called after reload.
If reload creates a splittable instruction and HAVE_attr_length, nothing
until final_scan_insns splits it and final_scan_insns aborts:
/* If the template is the string "#", it means that this insn must
be split. */
if (template[0] == '#' && template[1] == '\0')
{
rtx new = try_split (body, insn, 0);
/* If we didn't split the insn, go away. */
if (new == insn && PATTERN (new) == body)
fatal_insn ("could not split insn", insn);
#ifdef HAVE_ATTR_length
/* This instruction should have been split in shorten_branches,
to ensure that we would have valid length info for the
splitees. */
abort ();
#endif
Should shorten_branches call split_all_insns, or call it only when toplev.c
did not do it:
#ifdef INSN_SCHEDULING
if (optimize == 0 || !flag_schedule_insns_after_reload)
#else
if (1)
#endif
split_all_insns (0)
or look at insn templates and try_split only if template[0] == '#'?
2003-08-25 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/20030825-1.c: New test.
--- gcc/testsuite/gcc.dg/20030825-1.c.jj 2003-01-30 05:24:37.000000000 -0500
+++ gcc/testsuite/gcc.dg/20030825-1.c 2003-08-25 13:34:39.000000000 -0400
@@ -0,0 +1,97 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A
+{
+ long a1;
+ double *a2;
+};
+
+struct B
+{
+ void *b1;
+ double b2, b3;
+ struct
+ {
+ int d1;
+ double d2;
+ } b4;
+};
+
+struct C
+{
+ struct A *c1;
+ void *c2;
+};
+
+long fn1 (struct A *, double);
+void fn2 (void *, const char *);
+double fn3 (double);
+double fn4 (double);
+int fn5 (void *, double, double);
+
+int
+foo (struct B *x)
+{
+ struct C *e = x->b1;
+ struct A *f = e->c1;
+ long g, h, i;
+ double *j, k;
+ g = fn1 (f, 0.5 * (x->b2 + x->b3)), h = g + 1, i = f->a1;
+ j = f->a2, k = x->b4.d2;
+ fn2 (x, "something");
+ if (g <= 0)
+ {
+ double l = j[2] - j[1];
+ if (l > 0.0 && l <= 0.02)
+ k = (x->b4.d1 == 1
+ ? ((1.0 / l) < 25 ? 25 : (1.0 / l))
+ : fn3 ((1.0 / l) < 25 ? 25 : (1.0 / l)));
+ }
+ else
+ {
+ double m = j[h] - j[g], n = 0.0, l = 0.0;
+ if (g > 1)
+ n = j[g] - j[g - 1];
+ if (h < i)
+ l = j[h + 1] - j[h];
+ if (n > 0.02)
+ n = 0;
+ if (m > 0.02)
+ m = 0;
+ if (l > 0.02)
+ l = 0;
+ if (m < n)
+ {
+ double o = m;
+ m = n;
+ n = o;
+ }
+ if (l < n)
+ {
+ double o = l;
+ l = n;
+ n = o;
+ }
+ if (l < m)
+ {
+ double o = l;
+ l = m;
+ m = o;
+ }
+ if (n != 0.0)
+ k = (x->b4.d1 == 1
+ ? ((1 / m) < 25 ? 25 : (1 / m))
+ : fn3 ((1 / m) < 25 ? 25 : (1 / m)));
+ else if (m != 0.0)
+ k = (x->b4.d1 == 1
+ ? ((2 / (m + l)) < 25 ? 25 : (2 / (m + l)))
+ : fn3 ((2 / (m + l)) < 25 ? 25 : (2 / (m + l))));
+ else if (l != 0.0)
+ k = (x->b4.d1 == 1
+ ? ((1 / l) < 25 ? 25 : (1 / l))
+ : fn3 ((1 / l) < 25 ? 25 : (1 / l)));
+ }
+ fn5 (e->c2, 0.5 * (x->b2 + x->b3), (x->b4.d1 == 1 ? k : fn4 (k)));
+ return 1;
+}
Jakub