diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5cb771483e..5582bc20a2c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2003-09-08 Jakub Jelinek + + * toplev.c (rest_of_handle_stack_regs): Call split_all_insns before + regstack if optimizing but not scheduling after reload. + 2003-09-08 Jakub Jelinek * config/sparc/sparc.c (struct machine_function): New type. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3ee1a767ea6..032e09024d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-09-08 Jakub Jelinek + + * gcc.c-torture/compile/20030904-1.c: New test. + 2003-09-07 Eric Botcazou * g++.dg/opt/longbranch2.C: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/20030904-1.c b/gcc/testsuite/gcc.c-torture/compile/20030904-1.c new file mode 100644 index 00000000000..09fd015b115 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20030904-1.c @@ -0,0 +1,94 @@ +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; +} diff --git a/gcc/toplev.c b/gcc/toplev.c index aa04138ca96..bcc9c5046a9 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2082,6 +2082,23 @@ rest_of_handle_delay_slots (tree decl, rtx insns) static void rest_of_handle_stack_regs (tree decl, rtx insns) { +#if defined (HAVE_ATTR_length) + /* If flow2 creates new instructions which need splitting + and scheduling after reload is not done, they might not be + splitten until final which doesn't allow splitting + if HAVE_ATTR_length. */ +#ifdef INSN_SCHEDULING + if (optimize && !flag_schedule_insns_after_reload) +#else + if (optimize) +#endif + { + timevar_push (TV_SHORTEN_BRANCH); + split_all_insns (1); + timevar_pop (TV_SHORTEN_BRANCH); + } +#endif + timevar_push (TV_REG_STACK); open_dump_file (DFI_stack, decl);