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

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Corresponding diff -upbd for better readability:
--- gcc/match.pd.jj     2017-11-28 09:40:08.000000000 +0100
+++ gcc/match.pd        2017-12-05 11:36:58.855074420 +0100
@@ -1783,9 +1783,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (bit_not @0))

   /* (T)(P + A) - (T)P -> (T) A */
-  (for add (plus pointer_plus)
    (simplify
-    (minus (convert (add @@0 @1))
+   (minus (convert (plus:c @@0 @1))
      (convert @0))
     (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For integer types, if A has a smaller type
@@ -1796,7 +1795,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
            undefined behavior, we can assume that there
            is no overflow.  */
         || (INTEGRAL_TYPE_P (TREE_TYPE (@0))
-            && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+           && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))))
+    (convert @1)))
+  (simplify
+   (minus (convert (pointer_plus @@0 @1))
+    (convert @0))
+   (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For pointer types, if the conversion of A to the
            final type requires a sign- or zero-extension,
            then we have to punt - it is not defined which
@@ -1804,7 +1808,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         || (POINTER_TYPE_P (TREE_TYPE (@0))
             && TREE_CODE (@1) == INTEGER_CST
             && tree_int_cst_sign_bit (@1) == 0))
-     (convert @1))))
+    (convert @1)))
    (simplify
     (pointer_diff (pointer_plus @@0 @1) @0)
     /* The second argument of pointer_plus must be interpreted as signed, and
@@ -1813,10 +1817,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (convert (convert:stype @1))))

   /* (T)P - (T)(P + A) -> -(T) A */
-  (for add (plus pointer_plus)
    (simplify
     (minus (convert @0)
-     (convert (add @@0 @1)))
+    (convert (plus:c @@0 @1)))
+   (if (INTEGRAL_TYPE_P (type)
+       && TYPE_OVERFLOW_UNDEFINED (type)
+        && element_precision (type) <= element_precision (TREE_TYPE (@1)))
+    (with { tree utype = unsigned_type_for (type); }
+     (convert (negate (convert:utype @1))))
     (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For integer types, if A has a smaller type
            than T the result depends on the possible
@@ -1826,7 +1834,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
            undefined behavior, we can assume that there
            is no overflow.  */
         || (INTEGRAL_TYPE_P (TREE_TYPE (@0))
-            && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+            && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))))
+     (negate (convert @1)))))
+  (simplify
+   (minus (convert @0)
+    (convert (pointer_plus @@0 @1)))
+   (if (INTEGRAL_TYPE_P (type)
+       && TYPE_OVERFLOW_UNDEFINED (type)
+        && element_precision (type) <= element_precision (TREE_TYPE (@1)))
+    (with { tree utype = unsigned_type_for (type); }
+     (convert (negate (convert:utype @1))))
+    (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For pointer types, if the conversion of A to the
            final type requires a sign- or zero-extension,
            then we have to punt - it is not defined which
@@ -1843,10 +1861,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (negate (convert (convert:stype @1)))))

   /* (T)(P + A) - (T)(P + B) -> (T)A - (T)B */
-  (for add (plus pointer_plus)
    (simplify
-    (minus (convert (add @@0 @1))
-     (convert (add @0 @2)))
+   (minus (convert (plus:c @@0 @1))
+    (convert (plus:c @0 @2)))
+   (if (INTEGRAL_TYPE_P (type)
+       && TYPE_OVERFLOW_UNDEFINED (type)
+        && element_precision (type) <= element_precision (TREE_TYPE (@1)))
+    (with { tree utype = unsigned_type_for (type); }
+     (convert (minus (convert:utype @1) (convert:utype @2))))
     (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For integer types, if A has a smaller type
            than T the result depends on the possible
@@ -1856,7 +1878,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
            undefined behavior, we can assume that there
            is no overflow.  */
         || (INTEGRAL_TYPE_P (TREE_TYPE (@0))
-            && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+            && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))))
+     (minus (convert @1) (convert @2)))))
+  (simplify
+   (minus (convert (pointer_plus @@0 @1))
+    (convert (pointer_plus @0 @2)))
+   (if (INTEGRAL_TYPE_P (type)
+       && TYPE_OVERFLOW_UNDEFINED (type)
+        && element_precision (type) <= element_precision (TREE_TYPE (@1)))
+    (with { tree utype = unsigned_type_for (type); }
+     (convert (minus (convert:utype @1) (convert:utype @2))))
+    (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
         /* For pointer types, if the conversion of A to the
            final type requires a sign- or zero-extension,
            then we have to punt - it is not defined which
@@ -1866,13 +1898,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
             && tree_int_cst_sign_bit (@1) == 0
             && TREE_CODE (@2) == INTEGER_CST
             && tree_int_cst_sign_bit (@2) == 0))
-     (minus (convert @1) (convert @2)))))))
+     (minus (convert @1) (convert @2)))))
    (simplify
     (pointer_diff (pointer_plus @@0 @1) (pointer_plus @0 @2))
     /* The second argument of pointer_plus must be interpreted as signed, and
        thus sign-extended if necessary.  */
     (with { tree stype = signed_type_for (TREE_TYPE (@1)); }
-     (minus (convert (convert:stype @1)) (convert (convert:stype @2)))))
+     (minus (convert (convert:stype @1)) (convert (convert:stype @2)))))))


 /* Simplifications of MIN_EXPR, MAX_EXPR, fmin() and fmax().  */

Reply via email to