https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119103

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #7)
> So first of all the range info on the shift is lost, so
> vect_recog_over_widening_pattern cannot do its work.  The info is lost when
> PRE moves the invariant (int) amount cast out of the loop - we've dropped
> the unreachable() at that point, so we can't recover the lost info then.

PRE has no good way to preserve the info, it would need to get ranges
(and points-to info) attached to its expression representation.

LIMs cost modeling is off here (given PRE will do all hoisting anyway).

_6 = (int) amount_11(D);
  invariant up to level 1, cost 1.

and we only hoist when cost is at least 20 (we accumulate this for a series
of invariant stmts).  We could do

diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 225964c6215..5bc2898d5f4 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -687,6 +687,12 @@ stmt_cost (gimple *stmt)
       /* Comparisons are usually expensive.  */
       if (TREE_CODE_CLASS (code) == tcc_comparison)
        return LIM_EXPENSIVE;
+      /* Hoist all stmts with range info here if PRE would do so later
+        anyway.  */
+      if (flag_tree_pre
+         && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+         && SSA_NAME_RANGE_INFO (gimple_assign_lhs (stmt)))
+       return LIM_EXPENSIVE;
       return 1;
     }
 }

or alternatively

diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 225964c6215..9d27afedc33 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -264,7 +264,7 @@ static bool ref_always_accessed_p (class loop *, im_mem_ref
*, bool);
 static bool refs_independent_p (im_mem_ref *, im_mem_ref *, bool = true);

 /* Minimum cost of an expensive expression.  */
-#define LIM_EXPENSIVE ((unsigned) param_lim_expensive)
+#define LIM_EXPENSIVE (flag_tree_pre ? 1u : (unsigned) param_lim_expensive)

 /* The outermost loop for which execution of the header guarantees that the
    block will be executed.  */

Reply via email to