The following should fix PR37242.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2019-08-20  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/37242
        * tree-ssa-sccvn.c (visit_nary_op): Also CSE (T)(a + b)
        to (T)a + (T)b if we know that a + b does not overflow.

        * gcc.dg/tree-ssa/ssa-fre-80.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 274672)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -4312,8 +4312,12 @@ 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))
+               || (INTEGRAL_TYPE_P (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 +4351,9 @@ 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
+                         || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+                             && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
                        {
                          gimple_match_op match_op (gimple_match_cond::UNCOND,
                                                    NOP_EXPR, type, ops[0]);
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-80.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-80.c  (nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-80.c  (working copy)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+unsigned long a, b;
+void foo (int m, int f)
+{
+  unsigned long tem = (unsigned long)m;
+  a = tem + 1;
+  if (f)
+    {
+      int tem2 = m + 1;
+      b = (unsigned long)tem2;  /* Eliminated to a.  */
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "\\(long unsigned int\\)" 1 "fre1" } } */

Reply via email to