Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 254399)
+++ gcc/fold-const.c	(working copy)
@@ -421,34 +421,34 @@ negate_expr_p (tree t)
     case COMPLEX_EXPR:
       return negate_expr_p (TREE_OPERAND (t, 0))
 	     && negate_expr_p (TREE_OPERAND (t, 1));
 
     case CONJ_EXPR:
       return negate_expr_p (TREE_OPERAND (t, 0));
 
     case PLUS_EXPR:
       if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
 	  || HONOR_SIGNED_ZEROS (element_mode (type))
-	  || (INTEGRAL_TYPE_P (type)
+	  || (ANY_INTEGRAL_TYPE_P (type)
 	      && ! TYPE_OVERFLOW_WRAPS (type)))
 	return false;
       /* -(A + B) -> (-B) - A.  */
       if (negate_expr_p (TREE_OPERAND (t, 1)))
 	return true;
       /* -(A + B) -> (-A) - B.  */
       return negate_expr_p (TREE_OPERAND (t, 0));
 
     case MINUS_EXPR:
       /* We can't turn -(A-B) into B-A when we honor signed zeros.  */
       return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
 	     && !HONOR_SIGNED_ZEROS (element_mode (type))
-	     && (! INTEGRAL_TYPE_P (type)
+	     && (! ANY_INTEGRAL_TYPE_P (type)
 		 || TYPE_OVERFLOW_WRAPS (type));
 
     case MULT_EXPR:
       if (TYPE_UNSIGNED (type))
 	break;
       /* INT_MIN/n * n doesn't overflow while negating one operand it does
          if n is a (negative) power of two.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (t))
 	  && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
 	  && ! ((TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 254399)
+++ gcc/match.pd	(working copy)
@@ -951,35 +951,50 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (negate @0)
  (if (!TYPE_OVERFLOW_SANITIZED (type))))
 (match negate_expr_p
  REAL_CST
  (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (t)))))
 /* VECTOR_CST handling of non-wrapping types would recurse in unsupported
    ways.  */
 (match negate_expr_p
  VECTOR_CST
  (if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))))
+(match negate_expr_p
+ (minus @0 @1)
+ (if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
+      || (FLOAT_TYPE_P (type)
+	  && !HONOR_SIGN_DEPENDENT_ROUNDING (type)
+	  && !HONOR_SIGNED_ZEROS (type)))))
 
 /* (-A) * (-B) -> A * B  */
 (simplify
  (mult:c (convert1? (negate @0)) (convert2? negate_expr_p@1))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
        && tree_nop_conversion_p (type, TREE_TYPE (@1)))
    (mult (convert @0) (convert (negate @1)))))
  
 /* -(A + B) -> (-B) - A.  */
 (simplify
  (negate (plus:c @0 negate_expr_p@1))
  (if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
       && !HONOR_SIGNED_ZEROS (element_mode (type)))
   (minus (negate @1) @0)))
 
+/* -(A - B) -> B - A.  */
+(simplify
+ (negate (minus @0 @1))
+ (if ((ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_SANITIZED (type))
+      || (FLOAT_TYPE_P (type)
+	  && !HONOR_SIGN_DEPENDENT_ROUNDING (type)
+	  && !HONOR_SIGNED_ZEROS (type)))
+  (minus @1 @0)))
+
 /* A - B -> A + (-B) if B is easily negatable.  */
 (simplify
  (minus @0 negate_expr_p@1)
  (if (!FIXED_POINT_TYPE_P (type))
  (plus @0 (negate @1))))
 
 /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
    when profitable.
    For bitwise binary operations apply operand conversions to the
    binary operation result instead of to the operands.  This allows
@@ -1075,20 +1090,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (bit_not (bit_not @0))
   @0)
 
 /* Convert ~ (-A) to A - 1.  */
 (simplify
  (bit_not (convert? (negate @0)))
  (if (element_precision (type) <= element_precision (TREE_TYPE (@0))
       || !TYPE_UNSIGNED (TREE_TYPE (@0)))
   (convert (minus @0 { build_each_one_cst (TREE_TYPE (@0)); }))))
 
+/* Convert - (~A) to A + 1.  */
+(simplify
+ (negate (nop_convert (bit_not @0)))
+ (plus (view_convert @0) { build_each_one_cst (type); }))
+
 /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
 (simplify
  (bit_not (convert? (minus @0 integer_each_onep)))
  (if (element_precision (type) <= element_precision (TREE_TYPE (@0))
       || !TYPE_UNSIGNED (TREE_TYPE (@0)))
   (convert (negate @0))))
 (simplify
  (bit_not (convert? (plus @0 integer_all_onesp)))
  (if (element_precision (type) <= element_precision (TREE_TYPE (@0))
       || !TYPE_UNSIGNED (TREE_TYPE (@0)))
Index: gcc/testsuite/gcc.dg/tree-ssa/negminus.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/negminus.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/negminus.c	(working copy)
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-rounding-math -fno-signed-zeros -fdump-tree-optimized-raw" } */
+
+double f(double a, double b){
+    double c = a - b;
+    return -c;
+}
+
+int g(unsigned x){
+    unsigned y = ~x;
+    int z = (int) y;
+    return -z;
+}
+
+unsigned h(unsigned a, unsigned b, unsigned c){
+    unsigned d = b - c;
+    unsigned e = a + d;
+    return -e;
+}
+
+/* { dg-final { scan-tree-dump-not "negate_expr" "optimized"} } */
