Patchwork all_ones vs minus_one (was: [PATCH] Loop distribution improvements)

login
register
mail settings
Submitter Marc Glisse
Date May 7, 2013, 6:14 a.m.
Message ID <alpine.DEB.2.02.1305070749480.3867@laptop-mg.saclay.inria.fr>
Download mbox | patch
Permalink /patch/241993/
State New
Headers show

Comments

Marc Glisse - May 7, 2013, 6:14 a.m.
On Thu, 2 May 2013, Richard Biener wrote:

> Can you followup with a patch to do
> s/integer_all_onesp/integer_minus_onep/ where it makes sense?

This passes bootstrap+testsuite on x86_64-linux-gnu. I kept all_ones for 
bitmask type of operations (BIT_*_EXPR, VEC_COND_EXPR) and used minus_one 
for the maximal unsigned value. A few cases were not very clear and chosen 
rather randomly. There is one place in fold-const where we would actually 
want instead an integer_zero_or_all_onesp which checks whether each 
element of a vector (or complex) is 0 or -1, which would accept 
{-1,0,0,-1} for instance, but I didn't add that.

2013-05-07  Marc Glisse  <marc.glisse@inria.fr>

 	* convert.c (convert_to_integer): Replace integer_all_onesp with
 	integer_minus_onep.
 	* tree-ssa-loop-niter.c (number_of_iterations_lt,
 	number_of_iterations_exit): Likewise.
 	* predict.c (tree_predict_by_opcode): Likewise.
 	* builtins.c (expand_builtin_memory_chk, maybe_emit_chk_warning,
 	maybe_emit_sprintf_chk_warning, fold_builtin_memory_chk,
 	fold_builtin_stxcpy_chk, fold_builtin_stxncpy_chk,
 	fold_builtin_strcat_chk, fold_builtin_strncat_chk,
 	fold_builtin_sprintf_chk_1, fold_builtin_snprintf_chk_1): Likewise.
 	* fold-const.c (optimize_bit_field_compare, fold_unary_loc,
 	fold_binary_loc): Likewise.
 	* expr.c (do_store_flag): Likewise.
 	* tree-ssa-phiopt.c (conditional_replacement): Likewise.
Marc Glisse - May 7, 2013, 6:31 a.m.
On Tue, 7 May 2013, Marc Glisse wrote:

> On Thu, 2 May 2013, Richard Biener wrote:
>
>> Can you followup with a patch to do
>> s/integer_all_onesp/integer_minus_onep/ where it makes sense?
>
> This passes bootstrap+testsuite on x86_64-linux-gnu. I kept all_ones for 
> bitmask type of operations (BIT_*_EXPR, VEC_COND_EXPR) and used minus_one for 
> the maximal unsigned value. A few cases were not very clear and chosen rather 
> randomly. There is one place in fold-const where we would actually want 
> instead an integer_zero_or_all_onesp which checks whether each element of a 
> vector (or complex) is 0 or -1, which would accept {-1,0,0,-1} for instance, 
> but I didn't add that.

Forgot to say: there are a few more uses in the C and C++ front-ends, that 
I'll change next if this first patch is ok.
Richard Guenther - May 7, 2013, 8:45 a.m.
On Tue, 7 May 2013, Marc Glisse wrote:

> On Thu, 2 May 2013, Richard Biener wrote:
> 
> > Can you followup with a patch to do
> > s/integer_all_onesp/integer_minus_onep/ where it makes sense?
> 
> This passes bootstrap+testsuite on x86_64-linux-gnu. I kept all_ones for
> bitmask type of operations (BIT_*_EXPR, VEC_COND_EXPR) and used minus_one for
> the maximal unsigned value. A few cases were not very clear and chosen rather
> randomly. There is one place in fold-const where we would actually want
> instead an integer_zero_or_all_onesp which checks whether each element of a
> vector (or complex) is 0 or -1, which would accept {-1,0,0,-1} for instance,
> but I didn't add that.

Hmm, just that I notice now - will integer_minus_onep () return true
for -1U?  Maybe that's confusing?

Richard.

> 2013-05-07  Marc Glisse  <marc.glisse@inria.fr>
> 
> 	* convert.c (convert_to_integer): Replace integer_all_onesp with
> 	integer_minus_onep.
> 	* tree-ssa-loop-niter.c (number_of_iterations_lt,
> 	number_of_iterations_exit): Likewise.
> 	* predict.c (tree_predict_by_opcode): Likewise.
> 	* builtins.c (expand_builtin_memory_chk, maybe_emit_chk_warning,
> 	maybe_emit_sprintf_chk_warning, fold_builtin_memory_chk,
> 	fold_builtin_stxcpy_chk, fold_builtin_stxncpy_chk,
> 	fold_builtin_strcat_chk, fold_builtin_strncat_chk,
> 	fold_builtin_sprintf_chk_1, fold_builtin_snprintf_chk_1): Likewise.
> 	* fold-const.c (optimize_bit_field_compare, fold_unary_loc,
> 	fold_binary_loc): Likewise.
> 	* expr.c (do_store_flag): Likewise.
> 	* tree-ssa-phiopt.c (conditional_replacement): Likewise.
> 
>
Marc Glisse - May 7, 2013, 10:41 a.m.
On Tue, 7 May 2013, Richard Biener wrote:

> On Tue, 7 May 2013, Marc Glisse wrote:
>
>> On Thu, 2 May 2013, Richard Biener wrote:
>>
>>> Can you followup with a patch to do
>>> s/integer_all_onesp/integer_minus_onep/ where it makes sense?
>>
>> This passes bootstrap+testsuite on x86_64-linux-gnu. I kept all_ones for
>> bitmask type of operations (BIT_*_EXPR, VEC_COND_EXPR) and used minus_one for
>> the maximal unsigned value. A few cases were not very clear and chosen rather
>> randomly. There is one place in fold-const where we would actually want
>> instead an integer_zero_or_all_onesp which checks whether each element of a
>> vector (or complex) is 0 or -1, which would accept {-1,0,0,-1} for instance,
>> but I didn't add that.
>
> Hmm, just that I notice now - will integer_minus_onep () return true
> for -1U?  Maybe that's confusing?

Yes, integer_minus_onep returns true for -1U. It is equivalent to 
integer_all_onesp except for complex numbers, where it checks for (-1,0) 
instead of (-1,-1). We could keep using integer_all_onesp for cases that 
cannot be complex (the current situation). Or would you prefer a renaming 
of some functions?

Patch

Index: gcc/convert.c

===================================================================
--- gcc/convert.c	(revision 198662)

+++ gcc/convert.c	(working copy)

@@ -643,21 +643,21 @@  convert_to_integer (tree type, tree expr

 		   we can't necessarily find a type to compare them in.  */
 		&& (TYPE_UNSIGNED (TREE_TYPE (arg0))
 		    == TYPE_UNSIGNED (TREE_TYPE (arg1)))
 		/* Do not change the sign of the division.  */
 		&& (TYPE_UNSIGNED (TREE_TYPE (expr))
 		    == TYPE_UNSIGNED (TREE_TYPE (arg0)))
 		/* Either require unsigned division or a division by
 		   a constant that is not -1.  */
 		&& (TYPE_UNSIGNED (TREE_TYPE (arg0))
 		    || (TREE_CODE (arg1) == INTEGER_CST
-			&& !integer_all_onesp (arg1))))

+			&& !integer_minus_onep (arg1))))

 	      goto trunc1;
 	    break;
 	  }
 
 	case MAX_EXPR:
 	case MIN_EXPR:
 	case MULT_EXPR:
 	  {
 	    tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
 	    tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
Index: gcc/tree-ssa-loop-niter.c

===================================================================
--- gcc/tree-ssa-loop-niter.c	(revision 198662)

+++ gcc/tree-ssa-loop-niter.c	(working copy)

@@ -1033,21 +1033,21 @@  number_of_iterations_lt (tree type, affi

       niter->cmp = GT_EXPR;
       niter->bound = iv0->base;
     }
 
   delta = fold_build2 (MINUS_EXPR, niter_type,
 		       fold_convert (niter_type, iv1->base),
 		       fold_convert (niter_type, iv0->base));
 
   /* First handle the special case that the step is +-1.  */
   if ((integer_onep (iv0->step) && integer_zerop (iv1->step))
-      || (integer_all_onesp (iv1->step) && integer_zerop (iv0->step)))

+      || (integer_minus_onep (iv1->step) && integer_zerop (iv0->step)))

     {
       /* for (i = iv0->base; i < iv1->base; i++)
 
 	 or
 
 	 for (i = iv1->base; i > iv0->base; i--).
 
 	 In both cases # of iterations is iv1->base - iv0->base, assuming that
 	 iv1->base >= iv0->base.
 
@@ -1911,22 +1911,22 @@  number_of_iterations_exit (struct loop *

 
   if (warn)
     {
       const char *wording;
       location_t loc = gimple_location (stmt);
 
       /* We can provide a more specific warning if one of the operator is
 	 constant and the other advances by +1 or -1.  */
       if (!integer_zerop (iv1.step)
 	  ? (integer_zerop (iv0.step)
-	     && (integer_onep (iv1.step) || integer_all_onesp (iv1.step)))

-	  : (integer_onep (iv0.step) || integer_all_onesp (iv0.step)))

+	     && (integer_onep (iv1.step) || integer_minus_onep (iv1.step)))

+	  : (integer_onep (iv0.step) || integer_minus_onep (iv0.step)))

         wording =
           flag_unsafe_loop_optimizations
           ? N_("assuming that the loop is not infinite")
           : N_("cannot optimize possibly infinite loops");
       else
 	wording =
 	  flag_unsafe_loop_optimizations
 	  ? N_("assuming that the loop counter does not overflow")
 	  : N_("cannot optimize loop, the loop counter may overflow");
 
Index: gcc/predict.c

===================================================================
--- gcc/predict.c	(revision 198662)

+++ gcc/predict.c	(working copy)

@@ -2025,32 +2025,32 @@  tree_predict_by_opcode (basic_block bb)

 	break;
 
       case UNORDERED_EXPR:
 	predict_edge_def (then_edge, PRED_TREE_FPOPCODE, NOT_TAKEN);
 	break;
 
       case LE_EXPR:
       case LT_EXPR:
 	if (integer_zerop (op1)
 	    || integer_onep (op1)
-	    || integer_all_onesp (op1)

+	    || integer_minus_onep (op1)

 	    || real_zerop (op1)
 	    || real_onep (op1)
 	    || real_minus_onep (op1))
 	  predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, NOT_TAKEN);
 	break;
 
       case GE_EXPR:
       case GT_EXPR:
 	if (integer_zerop (op1)
 	    || integer_onep (op1)
-	    || integer_all_onesp (op1)

+	    || integer_minus_onep (op1)

 	    || real_zerop (op1)
 	    || real_onep (op1)
 	    || real_minus_onep (op1))
 	  predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, TAKEN);
 	break;
 
       default:
 	break;
       }
 }
Index: gcc/builtins.c

===================================================================
--- gcc/builtins.c	(revision 198662)

+++ gcc/builtins.c	(working copy)

@@ -12475,25 +12475,25 @@  expand_builtin_memory_chk (tree exp, rtx

     return NULL_RTX;
 
   dest = CALL_EXPR_ARG (exp, 0);
   src = CALL_EXPR_ARG (exp, 1);
   len = CALL_EXPR_ARG (exp, 2);
   size = CALL_EXPR_ARG (exp, 3);
 
   if (! host_integerp (size, 1))
     return NULL_RTX;
 
-  if (host_integerp (len, 1) || integer_all_onesp (size))

+  if (host_integerp (len, 1) || integer_minus_onep (size))

     {
       tree fn;
 
-      if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))

+      if (! integer_minus_onep (size) && tree_int_cst_lt (size, len))

 	{
 	  warning_at (tree_nonartificial_location (exp),
 		      0, "%Kcall to %D will always overflow destination buffer",
 		      exp, get_callee_fndecl (exp));
 	  return NULL_RTX;
 	}
 
       fn = NULL_TREE;
       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
 	 mem{cpy,pcpy,move,set} is available.  */
@@ -12606,21 +12606,21 @@  maybe_emit_chk_warning (tree exp, enum b

       len = CALL_EXPR_ARG (exp, 1);
       size = CALL_EXPR_ARG (exp, 3);
       break;
     default:
       gcc_unreachable ();
     }
 
   if (!len || !size)
     return;
 
-  if (! host_integerp (size, 1) || integer_all_onesp (size))

+  if (! host_integerp (size, 1) || integer_minus_onep (size))

     return;
 
   if (is_strlen)
     {
       len = c_strlen (len, 1);
       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
 	return;
     }
   else if (fcode == BUILT_IN_STRNCAT_CHK)
     {
@@ -12654,21 +12654,21 @@  maybe_emit_sprintf_chk_warning (tree exp

   const char *fmt_str;
   int nargs = call_expr_nargs (exp);
 
   /* Verify the required arguments in the original call.  */
 
   if (nargs < 4)
     return;
   size = CALL_EXPR_ARG (exp, 2);
   fmt = CALL_EXPR_ARG (exp, 3);
 
-  if (! host_integerp (size, 1) || integer_all_onesp (size))

+  if (! host_integerp (size, 1) || integer_minus_onep (size))

     return;
 
   /* Check whether the format is a literal string constant.  */
   fmt_str = c_getstr (fmt);
   if (fmt_str == NULL)
     return;
 
   if (!init_target_chars ())
     return;
 
@@ -12806,21 +12806,21 @@  fold_builtin_memory_chk (location_t loc,

       else
 	{
 	  tree temp = fold_build_pointer_plus_loc (loc, dest, len);
 	  return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
 	}
     }
 
   if (! host_integerp (size, 1))
     return NULL_TREE;
 
-  if (! integer_all_onesp (size))

+  if (! integer_minus_onep (size))

     {
       if (! host_integerp (len, 1))
 	{
 	  /* If LEN is not constant, try MAXLEN too.
 	     For MAXLEN only allow optimizing into non-_ocs function
 	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
 	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
 	    {
 	      if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
 		{
@@ -12888,21 +12888,21 @@  fold_builtin_stxcpy_chk (location_t loc,

       || !validate_arg (size, INTEGER_TYPE))
     return NULL_TREE;
 
   /* If SRC and DEST are the same (and not volatile), return DEST.  */
   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
 
   if (! host_integerp (size, 1))
     return NULL_TREE;
 
-  if (! integer_all_onesp (size))

+  if (! integer_minus_onep (size))

     {
       len = c_strlen (src, 1);
       if (! len || ! host_integerp (len, 1))
 	{
 	  /* If LEN is not constant, try MAXLEN too.
 	     For MAXLEN only allow optimizing into non-_ocs function
 	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
 	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
 	    {
 	      if (fcode == BUILT_IN_STPCPY_CHK)
@@ -12975,21 +12975,21 @@  fold_builtin_stxncpy_chk (location_t loc

        /* If return value of __stpncpy_chk is ignored,
           optimize into __strncpy_chk.  */
        fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
        if (fn)
          return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
     }
 
   if (! host_integerp (size, 1))
     return NULL_TREE;
 
-  if (! integer_all_onesp (size))

+  if (! integer_minus_onep (size))

     {
       if (! host_integerp (len, 1))
 	{
 	  /* If LEN is not constant, try MAXLEN too.
 	     For MAXLEN only allow optimizing into non-_ocs function
 	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
 	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
 	    return NULL_TREE;
 	}
       else
@@ -13021,21 +13021,21 @@  fold_builtin_strcat_chk (location_t loc,

   if (!validate_arg (dest, POINTER_TYPE)
       || !validate_arg (src, POINTER_TYPE)
       || !validate_arg (size, INTEGER_TYPE))
     return NULL_TREE;
 
   p = c_getstr (src);
   /* If the SRC parameter is "", return DEST.  */
   if (p && *p == '\0')
     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
 
-  if (! host_integerp (size, 1) || ! integer_all_onesp (size))

+  if (! host_integerp (size, 1) || ! integer_minus_onep (size))

     return NULL_TREE;
 
   /* If __builtin_strcat_chk is used, assume strcat is available.  */
   fn = builtin_decl_explicit (BUILT_IN_STRCAT);
   if (!fn)
     return NULL_TREE;
 
   return build_call_expr_loc (loc, fn, 2, dest, src);
 }
 
@@ -13058,21 +13058,21 @@  fold_builtin_strncat_chk (location_t loc

   p = c_getstr (src);
   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
   if (p && *p == '\0')
     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
   else if (integer_zerop (len))
     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
 
   if (! host_integerp (size, 1))
     return NULL_TREE;
 
-  if (! integer_all_onesp (size))

+  if (! integer_minus_onep (size))

     {
       tree src_len = c_strlen (src, 1);
       if (src_len
 	  && host_integerp (src_len, 1)
 	  && host_integerp (len, 1)
 	  && ! tree_int_cst_lt (len, src_len))
 	{
 	  /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
 	  fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
 	  if (!fn)
@@ -13150,21 +13150,21 @@  fold_builtin_sprintf_chk_1 (location_t l

 	      if (validate_arg (arg, POINTER_TYPE))
 		{
 		  len = c_strlen (arg, 1);
 		  if (! len || ! host_integerp (len, 1))
 		    len = NULL_TREE;
 		}
 	    }
 	}
     }
 
-  if (! integer_all_onesp (size))

+  if (! integer_minus_onep (size))

     {
       if (! len || ! tree_int_cst_lt (len, size))
 	return NULL_TREE;
     }
 
   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
      or if format doesn't contain % chars or is "%s".  */
   if (! integer_zerop (flag))
     {
       if (fmt_str == NULL)
@@ -13223,21 +13223,21 @@  fold_builtin_snprintf_chk_1 (location_t

   size = args[3];
   if (!validate_arg (size, INTEGER_TYPE))
     return NULL_TREE;
   fmt = args[4];
   if (!validate_arg (fmt, POINTER_TYPE))
     return NULL_TREE;
 
   if (! host_integerp (size, 1))
     return NULL_TREE;
 
-  if (! integer_all_onesp (size))

+  if (! integer_minus_onep (size))

     {
       if (! host_integerp (len, 1))
 	{
 	  /* If LEN is not constant, try MAXLEN too.
 	     For MAXLEN only allow optimizing into non-_ocs function
 	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
 	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
 	    return NULL_TREE;
 	}
       else
Index: gcc/fold-const.c

===================================================================
--- gcc/fold-const.c	(revision 198662)

+++ gcc/fold-const.c	(working copy)

@@ -3509,21 +3509,21 @@  optimize_bit_field_compare (location_t l

 	  warning (0, "comparison is always %d due to width of bit-field",
 		   code == NE_EXPR);
 	  return constant_boolean_node (code == NE_EXPR, compare_type);
 	}
     }
   else
     {
       tree tem = const_binop (RSHIFT_EXPR,
 			      fold_convert_loc (loc, signed_type, rhs),
 			      size_int (lbitsize - 1));
-      if (! integer_zerop (tem) && ! integer_all_onesp (tem))

+      if (! integer_zerop (tem) && ! integer_minus_onep (tem))

 	{
 	  warning (0, "comparison is always %d due to width of bit-field",
 		   code == NE_EXPR);
 	  return constant_boolean_node (code == NE_EXPR, compare_type);
 	}
     }
 
   /* Single-bit compares should always be against zero.  */
   if (lbitsize == 1 && ! integer_zerop (rhs))
     {
@@ -8235,21 +8235,21 @@  fold_unary_loc (location_t loc, enum tre

       /* Convert ~ (-A) to A - 1.  */
       else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
 	return fold_build2_loc (loc, MINUS_EXPR, type,
 			    fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)),
 			    build_int_cst (type, 1));
       /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
       else if (INTEGRAL_TYPE_P (type)
 	       && ((TREE_CODE (arg0) == MINUS_EXPR
 		    && integer_onep (TREE_OPERAND (arg0, 1)))
 		   || (TREE_CODE (arg0) == PLUS_EXPR
-		       && integer_all_onesp (TREE_OPERAND (arg0, 1)))))

+		       && integer_minus_onep (TREE_OPERAND (arg0, 1)))))

 	return fold_build1_loc (loc, NEGATE_EXPR, type,
 			    fold_convert_loc (loc, type,
 					      TREE_OPERAND (arg0, 0)));
       /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
       else if (TREE_CODE (arg0) == BIT_XOR_EXPR
 	       && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
 			       	     fold_convert_loc (loc, type,
 						       TREE_OPERAND (arg0, 0)))))
 	return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem,
 			    fold_convert_loc (loc, type,
@@ -10654,21 +10654,21 @@  fold_binary_loc (location_t loc,

       if (INTEGRAL_TYPE_P (type)
 	  && TREE_CODE (arg0) == NEGATE_EXPR
 	  && integer_onep (arg1)
 	  && !TYPE_OVERFLOW_TRAPS (type))
 	return fold_build1_loc (loc, BIT_NOT_EXPR, type,
 			    fold_convert_loc (loc, type,
 					      TREE_OPERAND (arg0, 0)));
 
       /* Convert -1 - A to ~A.  */
       if (INTEGRAL_TYPE_P (type)
-	  && integer_all_onesp (arg0))

+	  && integer_minus_onep (arg0))

 	return fold_build1_loc (loc, BIT_NOT_EXPR, type, op1);
 
 
       /* X - (X / CST) * CST is X % CST.  */
       if (INTEGRAL_TYPE_P (type)
 	  && TREE_CODE (arg1) == MULT_EXPR
 	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
 	  && operand_equal_p (arg0,
 			      TREE_OPERAND (TREE_OPERAND (arg1, 0), 0), 0)
 	  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg1, 0), 1),
@@ -12390,21 +12390,21 @@  fold_binary_loc (location_t loc,

       return NULL_TREE;
 
     case LROTATE_EXPR:
     case RROTATE_EXPR:
       if (integer_all_onesp (arg0))
 	return omit_one_operand_loc (loc, type, arg0, arg1);
       goto shift;
 
     case RSHIFT_EXPR:
       /* Optimize -1 >> x for arithmetic right shifts.  */
-      if (integer_all_onesp (arg0) && !TYPE_UNSIGNED (type)

+      if (integer_minus_onep (arg0) && !TYPE_UNSIGNED (type)

 	  && tree_expr_nonnegative_p (arg1))
 	return omit_one_operand_loc (loc, type, arg0, arg1);
       /* ... fall through ...  */
 
     case LSHIFT_EXPR:
     shift:
       if (integer_zerop (arg1))
 	return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
       if (integer_zerop (arg0))
 	return omit_one_operand_loc (loc, type, arg0, arg1);
Index: gcc/expr.c

===================================================================
--- gcc/expr.c	(revision 198662)

+++ gcc/expr.c	(working copy)

@@ -10771,27 +10771,27 @@  do_store_flag (sepops ops, rtx target, e

     case NE_EXPR:
       code = NE;
       break;
     case LT_EXPR:
       if (integer_onep (arg1))
 	arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
       else
 	code = unsignedp ? LTU : LT;
       break;
     case LE_EXPR:
-      if (! unsignedp && integer_all_onesp (arg1))

+      if (! unsignedp && integer_minus_onep (arg1))

 	arg1 = integer_zero_node, code = LT;
       else
 	code = unsignedp ? LEU : LE;
       break;
     case GT_EXPR:
-      if (! unsignedp && integer_all_onesp (arg1))

+      if (! unsignedp && integer_minus_onep (arg1))

 	arg1 = integer_zero_node, code = GE;
       else
 	code = unsignedp ? GTU : GT;
       break;
     case GE_EXPR:
       if (integer_onep (arg1))
 	arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
       else
 	code = unsignedp ? GEU : GE;
       break;
Index: gcc/tree-ssa-phiopt.c

===================================================================
--- gcc/tree-ssa-phiopt.c	(revision 198662)

+++ gcc/tree-ssa-phiopt.c	(working copy)

@@ -603,22 +603,22 @@  conditional_replacement (basic_block con

 	|| POINTER_TYPE_P (TREE_TYPE (arg0)))
       || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
 	   || POINTER_TYPE_P (TREE_TYPE (arg1))))
     return false;
 
   /* The PHI arguments have the constants 0 and 1, or 0 and -1, then
      convert it to the conditional.  */
   if ((integer_zerop (arg0) && integer_onep (arg1))
       || (integer_zerop (arg1) && integer_onep (arg0)))
     neg = false;
-  else if ((integer_zerop (arg0) && integer_all_onesp (arg1))

-	   || (integer_zerop (arg1) && integer_all_onesp (arg0)))

+  else if ((integer_zerop (arg0) && integer_minus_onep (arg1))

+	   || (integer_zerop (arg1) && integer_minus_onep (arg0)))

     neg = true;
   else
     return false;
 
   if (!empty_block_p (middle_bb))
     return false;
 
   /* At this point we know we have a GIMPLE_COND with two successors.
      One successor is BB, the other successor is an empty block which
      falls through into BB.