From: Bernd Schmidt Date: Fri, 10 Mar 2017 21:17:13 +0000 (+0000) Subject: re PR rtl-optimization/78911 (Infinite loop at -O2/O3 optimization levels while tryin... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8f2f63816095c764ff6440e4c44b9cc01a649920;p=gcc.git re PR rtl-optimization/78911 (Infinite loop at -O2/O3 optimization levels while trying to compile server.c from Wine-2.0-rc2) PR rtl-optimization/78911 * lra-assigns.c (must_not_spill_p): New function. (spill_for): Use it. PR rtl-optimization/78911 * gcc.target/i386/pr78911-1.c: New test. * gcc.target/i386/pr78911-2.c: New test. From-SVN: r246059 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3342d777160..82fdef56166 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-03-10 Bernd Schmidt + + PR rtl-optimization/78911 + * lra-assigns.c (must_not_spill_p): New function. + (spill_for): Use it. + 2017-03-10 Jakub Jelinek PR tree-optimization/79981 diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index 0ccd42546b7..226601bf2e6 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -889,6 +889,30 @@ assign_temporarily (int regno, int hard_regno) live_pseudos_reg_renumber[regno] = hard_regno; } +/* Return true iff there is a reason why pseudo SPILL_REGNO should not + be spilled. */ +static bool +must_not_spill_p (unsigned spill_regno) +{ + if ((pic_offset_table_rtx != NULL + && spill_regno == REGNO (pic_offset_table_rtx)) + || ((int) spill_regno >= lra_constraint_new_regno_start + && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno) + && ! bitmap_bit_p (&lra_split_regs, spill_regno) + && ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno) + && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno))) + return true; + /* A reload pseudo that requires a singleton register class should + not be spilled. + FIXME: this mitigates the issue on certain i386 patterns, but + does not solve the general case where existing reloads fully + cover a limited register class. */ + if (!bitmap_bit_p (&non_reload_pseudos, spill_regno) + && reg_class_size [reg_preferred_class (spill_regno)] == 1) + return true; + return false; +} + /* Array used for sorting reload pseudos for subsequent allocation after spilling some pseudo. */ static int *sorted_reload_pseudos; @@ -960,13 +984,7 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p) /* Spill pseudos. */ static_p = false; EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi) - if ((pic_offset_table_rtx != NULL - && spill_regno == REGNO (pic_offset_table_rtx)) - || ((int) spill_regno >= lra_constraint_new_regno_start - && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno) - && ! bitmap_bit_p (&lra_split_regs, spill_regno) - && ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno) - && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno))) + if (must_not_spill_p (spill_regno)) goto fail; else if (non_spilled_static_chain_regno_p (spill_regno)) static_p = true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b23426f0e9c..4453fbbae8b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ +2017-03-10 Bernd Schmidt + + PR rtl-optimization/78911 + * gcc.target/i386/pr78911-1.c: New test. + * gcc.target/i386/pr78911-2.c: New test. + 2017-03-10 Will Schmidt - + PR target/79941 * gcc.target/powerpc/fold-vec-mult-even_odd_misc.c: New test. * gcc.target/powerpc/fold-vec-mult-even_odd_char.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr78911-1.c b/gcc/testsuite/gcc.target/i386/pr78911-1.c new file mode 100644 index 00000000000..6ed086a69ea --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr78911-1.c @@ -0,0 +1,22 @@ +/* PR rtl-optimization/78911 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-strict-aliasing -fno-omit-frame-pointer" } */ +/* { dg-additional-options "-fPIC" { target fpic } } */ +/* { dg-additional-options "-march=pentium-m" { target ia32 } } */ + +int a, b, d, e; +long long *c; + +static int +foo (long long *x) +{ + return __sync_val_compare_and_swap (x, b, a); +} + +void +bar (void) +{ + if (!c) + return; + e = foo (&c[d]); +} diff --git a/gcc/testsuite/gcc.target/i386/pr78911-2.c b/gcc/testsuite/gcc.target/i386/pr78911-2.c new file mode 100644 index 00000000000..aef9eece853 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr78911-2.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-omit-frame-pointer" } */ +/* { dg-additional-options "-fPIC" { target fpic } } */ +/* { dg-additional-options "-march=i686" { target ia32 } } */ + +long long *a, *b, c; +int d, e; +int baz (void); + +static inline long long +foo (long long *x) +{ + return __sync_val_compare_and_swap (x, 0, 0); +} + +void +bar () +{ + int f = baz (); + c = foo (&a[f]); + if (c) + e = d; + a = b; +}