Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 197532)
+++ gcc/fold-const.c	(working copy)
@@ -10802,21 +10802,21 @@ fold_binary_loc (location_t loc,
 
       if (! FLOAT_TYPE_P (type))
 	{
 	  if (integer_zerop (arg1))
 	    return omit_one_operand_loc (loc, type, arg1, arg0);
 	  if (integer_onep (arg1))
 	    return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
 	  /* Transform x * -1 into -x.  Make sure to do the negation
 	     on the original operand with conversions not stripped
 	     because we can only strip non-sign-changing conversions.  */
-	  if (integer_all_onesp (arg1))
+	  if (integer_minus_onep (arg1))
 	    return fold_convert_loc (loc, type, negate_expr (op0));
 	  /* Transform x * -C into -x * C if x is easily negatable.  */
 	  if (TREE_CODE (arg1) == INTEGER_CST
 	      && tree_int_cst_sgn (arg1) == -1
 	      && negate_expr_p (arg0)
 	      && (tem = negate_expr (arg1)) != arg1
 	      && !TREE_OVERFLOW (tem))
 	    return fold_build2_loc (loc, MULT_EXPR, type,
 	    			fold_convert_loc (loc, type,
 						  negate_expr (arg0)),
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 197532)
+++ gcc/tree.c	(working copy)
@@ -1774,33 +1774,33 @@ integer_onep (const_tree expr)
 	  if (!integer_onep (VECTOR_CST_ELT (expr, i)))
 	    return false;
 	return true;
       }
     default:
       return false;
     }
 }
 
 /* Return 1 if EXPR is an integer containing all 1's in as much precision as
-   it contains.  Likewise for the corresponding complex constant.  */
+   it contains, or a complex or vector whose subparts are such integers.  */
 
 int
 integer_all_onesp (const_tree expr)
 {
   int prec;
   int uns;
 
   STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) == COMPLEX_CST
       && integer_all_onesp (TREE_REALPART (expr))
-      && integer_zerop (TREE_IMAGPART (expr)))
+      && integer_all_onesp (TREE_IMAGPART (expr)))
     return 1;
 
   else if (TREE_CODE (expr) == VECTOR_CST)
     {
       unsigned i;
       for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
 	if (!integer_all_onesp (VECTOR_CST_ELT (expr, i)))
 	  return 0;
       return 1;
     }
@@ -1832,20 +1832,34 @@ integer_all_onesp (const_tree expr)
       else
 	high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1;
 
       return (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
 	      && TREE_INT_CST_HIGH (expr) == high_value);
     }
   else
     return TREE_INT_CST_LOW (expr) == ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
 }
 
+/* Return 1 if EXPR is the integer constant minus one.  */
+
+int
+integer_minus_onep (const_tree expr)
+{
+  STRIP_NOPS (expr);
+
+  if (TREE_CODE (expr) == COMPLEX_CST)
+    return (integer_all_onesp (TREE_REALPART (expr))
+	    && integer_zerop (TREE_IMAGPART (expr)));
+  else
+    return integer_all_onesp (expr);
+}
+
 /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
    one bit on).  */
 
 int
 integer_pow2p (const_tree expr)
 {
   int prec;
   unsigned HOST_WIDE_INT high, low;
 
   STRIP_NOPS (expr);
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 197532)
+++ gcc/tree.h	(working copy)
@@ -5303,20 +5303,25 @@ extern int integer_zerop (const_tree);
 
 /* integer_onep (tree x) is nonzero if X is an integer constant of value 1.  */
 
 extern int integer_onep (const_tree);
 
 /* integer_all_onesp (tree x) is nonzero if X is an integer constant
    all of whose significant bits are 1.  */
 
 extern int integer_all_onesp (const_tree);
 
+/* integer_minus_onep (tree x) is nonzero if X is an integer constant of
+   value -1.  */
+
+extern int integer_minus_onep (const_tree);
+
 /* integer_pow2p (tree x) is nonzero is X is an integer constant with
    exactly one bit 1.  */
 
 extern int integer_pow2p (const_tree);
 
 /* integer_nonzerop (tree x) is nonzero if X is an integer constant
    with a nonzero value.  */
 
 extern int integer_nonzerop (const_tree);
 
