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

--- Comment #26 from Richard Biener <rguenth at gcc dot gnu.org> ---
      /* Match arithmetic done in a different type where we can easily
         substitute the result from some earlier sign-changed or widened
         operation.  */
      if (INTEGRAL_TYPE_P (type)
          && TREE_CODE (rhs1) == SSA_NAME
          /* We only handle sign-changes or zero-extension -> & mask.  */

this is sign-extension...

I think if the inner op has undefined overflow we can widen it(?).  That
fixes the new testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 274670)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -4312,8 +4312,11 @@ visit_nary_op (tree lhs, gassign *stmt)
         operation.  */
       if (INTEGRAL_TYPE_P (type)
          && TREE_CODE (rhs1) == SSA_NAME
-         /* We only handle sign-changes or zero-extension -> & mask.  */
-         && ((TYPE_UNSIGNED (TREE_TYPE (rhs1))
+         /* We only handle sign-changes, zero-extension -> & mask or
+            sign-extension if we know the inner operation doesn't
+            overflow.  */
+         && (((TYPE_UNSIGNED (TREE_TYPE (rhs1))
+               || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1)))
               && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs1)))
              || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))))
        {
@@ -4347,7 +4350,8 @@ visit_nary_op (tree lhs, gassign *stmt)
                    {
                      unsigned lhs_prec = TYPE_PRECISION (type);
                      unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
-                     if (lhs_prec == rhs_prec)
+                     if (lhs_prec == rhs_prec
+                         || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1)))
                        {
                          gimple_match_op match_op (gimple_match_cond::UNCOND,
                                                    NOP_EXPR, type, ops[0]);


for the benchmark PRE inserts the this way redundant code:

Found partial redundancy for expression {nop_expr,maxIdx_31} (0012)
Inserted _72 = (long unsigned int) maxIdx_42;
 in predecessor 4 (0052)

but late FRE can get rid of it again.

Reply via email to