On January 15, 2021 7:32:35 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>On the following testcase, handle_builtin_memcmp in the strlen pass
>folds
>the memcmp into comparison of two MEM_REFs.  But nothing triggers
>updating
>of addressable vars afterwards, so even when the parameters are no
>longer
>address taken, we force the parameters to stack and back anyway.
>
>The following patch fixes that.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Hmm, we're currently doing it unconditionally at strategic points in the pass 
pipeline. Is there no such point after the pass?

>2021-01-15  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/96271
>       * tree-ssa-strlen.c (handle_builtin_memcmp): Add UPDATE_ADDRESS_TAKEN
>       argument, set what it points to to true if optimizing memcmp into
>       a simple MEM_REF comparison.
>       (strlen_check_and_optimize_call): Add UPDATE_ADDRESS_TAKEN argument
>       and pass it through to handle_builtin_memcmp.
>       (check_and_optimize_stmt): Add UPDATE_ADDRESS_TAKEN argument
>       and pass it through to strlen_check_and_optimize_call.
>       (strlen_dom_walker): Replace m_cleanup_cfg with todo.
>       (strlen_dom_walker::before_dom_children): Adjust for the above change,
>       adjust check_and_optimize_stmt caller and or in into todo
>       TODO_cleanup_cfg and/or TODO_update_address_taken.
>       (printf_strlen_execute): Return todo instead of conditionally
>       TODO_cleanup_cfg.
>
>       * gcc.target/i386/pr96271.c: New test.
>
>--- gcc/tree-ssa-strlen.c.jj   2021-01-04 10:25:40.000000000 +0100
>+++ gcc/tree-ssa-strlen.c      2021-01-15 15:13:09.847839781 +0100
>@@ -3813,7 +3813,7 @@ use_in_zero_equality (tree res, bool exc
>    return true when call is transformed, return false otherwise.  */
> 
> static bool
>-handle_builtin_memcmp (gimple_stmt_iterator *gsi)
>+handle_builtin_memcmp (gimple_stmt_iterator *gsi, bool
>*update_address_taken)
> {
>   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
>   tree res = gimple_call_lhs (stmt);
>@@ -3858,6 +3858,7 @@ handle_builtin_memcmp (gimple_stmt_itera
>                                                  boolean_type_node,
>                                                  arg1, arg2));
>         gimplify_and_update_call_from_tree (gsi, res);
>+        *update_address_taken = true;
>         return true;
>       }
>     }
>@@ -5110,7 +5111,7 @@ is_char_type (tree type)
> 
> static bool
>strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool
>*zero_write,
>-                              pointer_query &ptr_qry)
>+                              bool *update_address_taken, pointer_query 
>&ptr_qry)
> {
>   gimple *stmt = gsi_stmt (*gsi);
> 
>@@ -5179,7 +5180,7 @@ strlen_check_and_optimize_call (gimple_s
>       return false;
>       break;
>     case BUILT_IN_MEMCMP:
>-      if (handle_builtin_memcmp (gsi))
>+      if (handle_builtin_memcmp (gsi, update_address_taken))
>       return false;
>       break;
>     case BUILT_IN_STRCMP:
>@@ -5341,12 +5342,13 @@ handle_integral_assign (gimple_stmt_iter
>/* Attempt to check for validity of the performed access a single
>statement
>    at *GSI using string length knowledge, and to optimize it.
>    If the given basic block needs clean-up of EH, CLEANUP_EH is set to
>-   true.  Return true to let the caller advance *GSI to the next
>statement
>-   in the basic block and false otherwise.  */
>+   true.  If it is to update addressables at the end of the pass, set
>+   *UPDATE_ADDRESS_TAKEN to true.  Return true to let the caller
>advance *GSI
>+   to the next statement in the basic block and false otherwise.  */
> 
> static bool
> check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
>-                       pointer_query &ptr_qry)
>+                       bool *update_address_taken, pointer_query &ptr_qry)
> {
>   gimple *stmt = gsi_stmt (*gsi);
> 
>@@ -5356,7 +5358,8 @@ check_and_optimize_stmt (gimple_stmt_ite
> 
>   if (is_gimple_call (stmt))
>     {
>-      if (!strlen_check_and_optimize_call (gsi, &zero_write, ptr_qry))
>+      if (!strlen_check_and_optimize_call (gsi, &zero_write,
>+                                         update_address_taken, ptr_qry))
>       return false;
>     }
>   else if (!flag_optimize_strlen || !strlen_optimize)
>@@ -5488,7 +5491,7 @@ public:
>     evrp (false),
>     ptr_qry (&evrp, &var_cache),
>     var_cache (),
>-    m_cleanup_cfg (false)
>+    todo (0)
>   { }
> 
>   virtual edge before_dom_children (basic_block);
>@@ -5503,9 +5506,8 @@ public:
>   pointer_query ptr_qry;
>   pointer_query::cache_type var_cache;
> 
>-  /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
>-     execute function.  */
>-  bool m_cleanup_cfg;
>+  /* TODO_* flags for the pass.  */
>+  int todo;
> };
> 
> /* Callback for walk_dominator_tree.  Attempt to optimize various
>@@ -5586,6 +5588,7 @@ strlen_dom_walker::before_dom_children (
>     }
> 
>   bool cleanup_eh = false;
>+  bool update_address_taken = false;
> 
>   /* Attempt to optimize individual statements.  */
> for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
>@@ -5599,12 +5602,15 @@ strlen_dom_walker::before_dom_children (
>       /* Reset search depth preformance counter.  */
>       ptr_qry.depth = 0;
> 
>-      if (check_and_optimize_stmt (&gsi, &cleanup_eh, ptr_qry))
>+      if (check_and_optimize_stmt (&gsi, &cleanup_eh,
>&update_address_taken,
>+                                 ptr_qry))
>       gsi_next (&gsi);
>     }
> 
>   if (cleanup_eh && gimple_purge_dead_eh_edges (bb))
>-      m_cleanup_cfg = true;
>+    todo |= TODO_cleanup_cfg;
>+  if (update_address_taken)
>+    todo |= TODO_update_address_taken;
> 
>   bb->aux = stridx_to_strinfo;
>   if (vec_safe_length (stridx_to_strinfo) && !strinfo_shared ())
>@@ -5715,7 +5721,7 @@ printf_strlen_execute (function *fun, bo
>       loop_optimizer_finalize ();
>     }
> 
>-  return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0;
>+  return walker.todo;
> }
> 
> /* This file defines two passes: one for warnings that runs only when
>--- gcc/testsuite/gcc.target/i386/pr96271.c.jj 2021-01-15
>15:17:42.001780947 +0100
>+++ gcc/testsuite/gcc.target/i386/pr96271.c    2021-01-15
>15:17:25.447967002 +0100
>@@ -0,0 +1,11 @@
>+/* PR tree-optimization/96271 */
>+/* { dg-do compile } */
>+/* { dg-options "-O2 -mtune=intel -msse2 -masm=att" } */
>+/* { dg-final { scan-assembler "movq\t%xmm0, %r" { target { ! ia32 } }
>} } */
>+/* { dg-final { scan-assembler "movq\t%xmm1, %r" { target { ! ia32 } }
>} } */
>+
>+int
>+foo (double a, double b)
>+{
>+  return __builtin_memcmp (&a, &b, sizeof (double)) == 0;
>+}
>
>       Jakub

Reply via email to