diff mbox

[loop-invariant] Fix PR67043: -fcompare-debug failure with -O3

Message ID 000001d0cb72$ea66f2b0$bf34d810$@arm.com
State New
Headers show

Commit Message

Thomas Preud'homme July 31, 2015, 9:25 a.m. UTC
Hi,

Since commit r223113, loop-invariant pass rely on luids to determine if an invariant can be hoisted out of a loop without introducing temporaries. However, nothing is made to ensure luids are up-to-date. This patch adds a DF_LIVE problem and mark all blocks as dirty before using luids to ensure these will be recomputed.

ChangeLog entries are as follows:


2015-07-31  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        PR tree-optimization/67043
        * loop-invariant.c (find_defs): Force recomputation of all luids.


2015-07-29  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        PR tree-optimization/67043
        * gcc.dg/pr67043.c: New test.

Note: the testcase was heavily reduced from the Linux kernel sources by Markus Trippelsdorf and formatted to follow GNU code style.




Patch was tested by running the testsuite against a bootstrapped native x86_64-linux-gnu GCC and against an arm-none-eabi GCC cross-compiler without any regression.

Is this ok for trunk?

Best regards,

Thomas Preud'homme

Comments

Jeff Law July 31, 2015, 3:51 p.m. UTC | #1
On 07/31/2015 03:25 AM, Thomas Preud'homme wrote:
> Hi,
>
> Since commit r223113, loop-invariant pass rely on luids to determine if an invariant can be hoisted out of a loop without introducing temporaries. However, nothing is made to ensure luids are up-to-date. This patch adds a DF_LIVE problem and mark all blocks as dirty before using luids to ensure these will be recomputed.
>
> ChangeLog entries are as follows:
>
>
> 2015-07-31  Thomas Preud'homme  <thomas.preudhomme@arm.com>
>
>          PR tree-optimization/67043
>          * loop-invariant.c (find_defs): Force recomputation of all luids.
>
>
> 2015-07-29  Thomas Preud'homme  <thomas.preudhomme@arm.com>
>
>          PR tree-optimization/67043
>          * gcc.dg/pr67043.c: New test.
>
> Note: the testcase was heavily reduced from the Linux kernel sources by Markus Trippelsdorf and formatted to follow GNU code style.
>
>
> diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
> index 1fdb84d..fc53e09 100644
> --- a/gcc/loop-invariant.c
> +++ b/gcc/loop-invariant.c
> @@ -676,6 +676,8 @@ find_defs (struct loop *loop)
>     df_remove_problem (df_chain);
>     df_process_deferred_rescans ();
>     df_chain_add_problem (DF_UD_CHAIN);
> +  df_live_add_problem ();
> +  df_live_set_all_dirty ();
>     df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
>     df_analyze_loop (loop);
>     check_invariant_table_size ();
> diff --git a/gcc/testsuite/gcc.dg/pr67043.c b/gcc/testsuite/gcc.dg/pr67043.c
> new file mode 100644
> index 0000000..36aa686
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr67043.c
> @@ -0,0 +1,32 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -fcompare-debug -w" } */
> +
> +extern void rt_mutex_owner (void);
> +extern void rt_mutex_deadlock_account_lock (int);
> +extern void signal_pending (void);
> +__typeof__ (int *) a;
> +int b;
> +
> +int
> +try_to_take_rt_mutex (int p1) {
> +  rt_mutex_owner ();
> +  if (b)
> +    return 0;
> +  rt_mutex_deadlock_account_lock (p1);
> +  return 1;
> +}
> +
> +void
> +__rt_mutex_slowlock (int p1) {
> +  int c;
> +  for (;;) {
> +    c = ({
> +      asm ("" : "=r"(a));
> +      a;
> +    });
> +    if (try_to_take_rt_mutex (c))
> +      break;
> +    if (__builtin_expect (p1 == 0, 0))
> +      signal_pending ();
> +  }
> +}
>
>
> Patch was tested by running the testsuite against a bootstrapped native x86_64-linux-gnu GCC and against an arm-none-eabi GCC cross-compiler without any regression.
>
> Is this ok for trunk?
So if we're relying on LUIDs, don't they get out-of-date each time we 
move an invariant?   Or is there some call back into the DF routines 
after we move an invariant to fix the LUIDs?


jeff
diff mbox

Patch

diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 1fdb84d..fc53e09 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -676,6 +676,8 @@  find_defs (struct loop *loop)
   df_remove_problem (df_chain);
   df_process_deferred_rescans ();
   df_chain_add_problem (DF_UD_CHAIN);
+  df_live_add_problem ();
+  df_live_set_all_dirty ();
   df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
   df_analyze_loop (loop);
   check_invariant_table_size ();
diff --git a/gcc/testsuite/gcc.dg/pr67043.c b/gcc/testsuite/gcc.dg/pr67043.c
new file mode 100644
index 0000000..36aa686
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr67043.c
@@ -0,0 +1,32 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcompare-debug -w" } */
+
+extern void rt_mutex_owner (void);
+extern void rt_mutex_deadlock_account_lock (int);
+extern void signal_pending (void);
+__typeof__ (int *) a;
+int b;
+
+int
+try_to_take_rt_mutex (int p1) {
+  rt_mutex_owner ();
+  if (b)
+    return 0;
+  rt_mutex_deadlock_account_lock (p1);
+  return 1;
+}
+
+void
+__rt_mutex_slowlock (int p1) {
+  int c;
+  for (;;) {
+    c = ({
+      asm ("" : "=r"(a));
+      a;
+    });
+    if (try_to_take_rt_mutex (c))
+      break;
+    if (__builtin_expect (p1 == 0, 0))
+      signal_pending ();
+  }
+}