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

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I meant something like:
--- gcc/match.pd.jj     2019-09-21 23:53:52.108385196 +0200
+++ gcc/match.pd        2019-09-24 10:18:58.804114496 +0200
@@ -2265,8 +2265,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
                          max_ovf = wi::OVF_OVERFLOW;
         tree inner_type = TREE_TYPE (@0);

-        wide_int w1 = wide_int::from (wi::to_wide (@1), TYPE_PRECISION
(inner_type),
-           TYPE_SIGN (inner_type));
+        wide_int w1
+         = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
+                           TYPE_SIGN (inner_type));

         wide_int wmin0, wmax0;
         if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE)
@@ -2280,6 +2281,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      )))
 #endif

+/* ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2  */
+#if GIMPLE
+  (for op (plus minus)
+   (simplify
+    (plus (convert:s (op:s @0 INTEGER_CST@1)) INTEGER_CST@2)
+     (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE
+         && TREE_CODE (type) == INTEGER_TYPE
+         && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
+         && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+         && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+         && TYPE_OVERFLOW_WRAPS (type))
+       (plus (convert @0) (op @2 (convert @1))))))
+#endif
+
   /* ~A + A -> -1 */
   (simplify
    (plus:c (bit_not @0) @0)

i.e. just handle the case where undefined overflow in the inner op rules out
all problematic cases, with :s to make sure the optimization is actually
beneficial,  that we either replace two original additions with one or with
zero, because it has the drawback that we loose information about the undefined
cases.

Reply via email to