This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Replace build with build2/build3 in fold-const.c


The following patch systematically replaces calls to "build" with
the preferred calls to build2 and build3.  The new buildN APIs that
were introduced by RTH allow better type checking and full conversion
of GCC's sources will allow the removal of the legacy variadic build
function and macro.  To continue this transition the patch below tackles
"fold-const.c" and "tree.c".

The following patch has been tested on i686-pc-linux-gnu, with a full
"make bootstrap", all current languages, and regression tested with a
top-level "make -k check" with no new failures.

Ok for mainline?  If anyone has large patches against fold-const.c
actively in the works, let me know and I'll hold off on this clean-up.


2004-05-18 Roger Sayle  <roger@eyesopen.com>

	* tree.c (array_type_nelts, save_expr, substitute_in_expr,
	get_unwidened, get_narrower): Replace build with build2.
	* fold-const.c (negate_expr, associate_trees, size_binop,
	fold_convert, eval_subst, omit_one_operand, invert_truthvalue,
	pedantic_omit_one_operand, distribute_bit_expr,
	make_bit_field_ref, optimize_bit_field_compare,
	decode_field_reference, range_binop, make_range,
	build_range_check, fold_range_test, fold_truthop,
	optimize_minmax_comparison, extract_muldiv_1,
	fold_binary_op_with_conditional_arg, fold_mathfn_compare,
	fold_inf_compare, fold_single_bit_test, fold,
	fold_relational_hi_lo, nondestructive_fold_binary_to_constant):
	Likewise replace build with either build2 or build3.


Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.371
diff -c -3 -p -r1.371 tree.c
*** tree.c	14 May 2004 02:32:58 -0000	1.371
--- tree.c	18 May 2004 22:08:51 -0000
*************** array_type_nelts (tree type)
*** 1260,1266 ****

    return (integer_zerop (min)
  	  ? max
! 	  : fold (build (MINUS_EXPR, TREE_TYPE (max), max, min)));
  }

  /* Return nonzero if arg is static -- a reference to an object in
--- 1260,1266 ----

    return (integer_zerop (min)
  	  ? max
! 	  : fold (build2 (MINUS_EXPR, TREE_TYPE (max), max, min)));
  }

  /* Return nonzero if arg is static -- a reference to an object in
*************** save_expr (tree expr)
*** 1383,1389 ****
    if (contains_placeholder_p (inner))
      return t;

!   t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL_TREE);

    /* This expression might be placed ahead of a jump to ensure that the
       value was computed on both sides of the jump.  So make sure it isn't
--- 1383,1390 ----
    if (contains_placeholder_p (inner))
      return t;

!   t = build3 (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl,
! 	      NULL_TREE);

    /* This expression might be placed ahead of a jump to ensure that the
       value was computed on both sides of the jump.  So make sure it isn't
*************** substitute_in_expr (tree exp, tree f, tr
*** 1947,1953 ****
       if (op0 == TREE_OPERAND (exp, 0))
         return exp;

!      new = fold (build (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1)));
     }
    else
      switch (TREE_CODE_CLASS (code))
--- 1948,1954 ----
       if (op0 == TREE_OPERAND (exp, 0))
         return exp;

!      new = fold (build2 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1)));
     }
    else
      switch (TREE_CODE_CLASS (code))
*************** get_unwidened (tree op, tree for_type)
*** 4467,4474 ****
  	  && (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)))
  	  && (! uns || final_prec <= innerprec || unsignedp))
  	{
! 	  win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 		       TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
  	}
--- 4468,4475 ----
  	  && (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)))
  	  && (! uns || final_prec <= innerprec || unsignedp))
  	{
! 	  win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
  	}
*************** get_narrower (tree op, int *unsignedp_pt
*** 4556,4563 ****
  	{
  	  if (first)
  	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
! 	  win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 		       TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
  	}
--- 4557,4564 ----
  	{
  	  if (first)
  	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
! 	  win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
  	}
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.375
diff -c -3 -p -r1.375 fold-const.c
*** fold-const.c	13 May 2004 06:39:39 -0000	1.375
--- fold-const.c	18 May 2004 22:08:53 -0000
*************** negate_expr (tree t)
*** 997,1012 ****
  	  if (negate_expr_p (TREE_OPERAND (t, 1))
  	      && reorder_operands_p (TREE_OPERAND (t, 0),
  				     TREE_OPERAND (t, 1)))
! 	    return fold_convert (type,
! 				 fold (build (MINUS_EXPR, TREE_TYPE (t),
! 					      negate_expr (TREE_OPERAND (t, 1)),
! 					      TREE_OPERAND (t, 0))));
  	  /* -(A + B) -> (-A) - B.  */
  	  if (negate_expr_p (TREE_OPERAND (t, 0)))
! 	    return fold_convert (type,
! 				 fold (build (MINUS_EXPR, TREE_TYPE (t),
! 					      negate_expr (TREE_OPERAND (t, 0)),
! 					      TREE_OPERAND (t, 1))));
  	}
        break;

--- 997,1017 ----
  	  if (negate_expr_p (TREE_OPERAND (t, 1))
  	      && reorder_operands_p (TREE_OPERAND (t, 0),
  				     TREE_OPERAND (t, 1)))
! 	    {
! 	      tem = negate_expr (TREE_OPERAND (t, 1));
! 	      tem = fold (build2 (MINUS_EXPR, TREE_TYPE (t),
! 				  tem, TREE_OPERAND (t, 0)));
! 	      return fold_convert (type, tem);
! 	    }
!
  	  /* -(A + B) -> (-A) - B.  */
  	  if (negate_expr_p (TREE_OPERAND (t, 0)))
! 	    {
! 	      tem = negate_expr (TREE_OPERAND (t, 0));
! 	      tem = fold (build2 (MINUS_EXPR, TREE_TYPE (t),
! 				  tem, TREE_OPERAND (t, 1)));
! 	      return fold_convert (type, tem);
! 	    }
  	}
        break;

*************** negate_expr (tree t)
*** 1015,1023 ****
        if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
  	  && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
  	return fold_convert (type,
! 			     fold (build (MINUS_EXPR, TREE_TYPE (t),
! 					  TREE_OPERAND (t, 1),
! 					  TREE_OPERAND (t, 0))));
        break;

      case MULT_EXPR:
--- 1020,1028 ----
        if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
  	  && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
  	return fold_convert (type,
! 			     fold (build2 (MINUS_EXPR, TREE_TYPE (t),
! 					   TREE_OPERAND (t, 1),
! 					   TREE_OPERAND (t, 0))));
        break;

      case MULT_EXPR:
*************** negate_expr (tree t)
*** 1032,1046 ****
  	  tem = TREE_OPERAND (t, 1);
  	  if (negate_expr_p (tem))
  	    return fold_convert (type,
! 				 fold (build (TREE_CODE (t), TREE_TYPE (t),
! 					      TREE_OPERAND (t, 0),
! 					      negate_expr (tem))));
  	  tem = TREE_OPERAND (t, 0);
  	  if (negate_expr_p (tem))
  	    return fold_convert (type,
! 				 fold (build (TREE_CODE (t), TREE_TYPE (t),
! 					      negate_expr (tem),
! 					      TREE_OPERAND (t, 1))));
  	}
        break;

--- 1037,1051 ----
  	  tem = TREE_OPERAND (t, 1);
  	  if (negate_expr_p (tem))
  	    return fold_convert (type,
! 				 fold (build2 (TREE_CODE (t), TREE_TYPE (t),
! 					       TREE_OPERAND (t, 0),
! 					       negate_expr (tem))));
  	  tem = TREE_OPERAND (t, 0);
  	  if (negate_expr_p (tem))
  	    return fold_convert (type,
! 				 fold (build2 (TREE_CODE (t), TREE_TYPE (t),
! 					       negate_expr (tem),
! 					       TREE_OPERAND (t, 1))));
  	}
        break;

*************** associate_trees (tree t1, tree t2, enum
*** 1211,1228 ****
        if (code == PLUS_EXPR)
  	{
  	  if (TREE_CODE (t1) == NEGATE_EXPR)
! 	    return build (MINUS_EXPR, type, fold_convert (type, t2),
! 			  fold_convert (type, TREE_OPERAND (t1, 0)));
  	  else if (TREE_CODE (t2) == NEGATE_EXPR)
! 	    return build (MINUS_EXPR, type, fold_convert (type, t1),
! 			  fold_convert (type, TREE_OPERAND (t2, 0)));
  	}
!       return build (code, type, fold_convert (type, t1),
! 		    fold_convert (type, t2));
      }

!   return fold (build (code, type, fold_convert (type, t1),
! 		      fold_convert (type, t2)));
  }

  /* Combine two integer constants ARG1 and ARG2 under operation CODE
--- 1216,1233 ----
        if (code == PLUS_EXPR)
  	{
  	  if (TREE_CODE (t1) == NEGATE_EXPR)
! 	    return build2 (MINUS_EXPR, type, fold_convert (type, t2),
! 			   fold_convert (type, TREE_OPERAND (t1, 0)));
  	  else if (TREE_CODE (t2) == NEGATE_EXPR)
! 	    return build2 (MINUS_EXPR, type, fold_convert (type, t1),
! 			   fold_convert (type, TREE_OPERAND (t2, 0)));
  	}
!       return build2 (code, type, fold_convert (type, t1),
! 		     fold_convert (type, t2));
      }

!   return fold (build2 (code, type, fold_convert (type, t1),
! 		       fold_convert (type, t2)));
  }

  /* Combine two integer constants ARG1 and ARG2 under operation CODE
*************** size_binop (enum tree_code code, tree ar
*** 1664,1670 ****
    if (arg0 == error_mark_node || arg1 == error_mark_node)
      return error_mark_node;

!   return fold (build (code, type, arg0, arg1));
  }

  /* Given two values, either both of sizetype or both of bitsizetype,
--- 1669,1675 ----
    if (arg0 == error_mark_node || arg1 == error_mark_node)
      return error_mark_node;

!   return fold (build2 (code, type, arg0, arg1));
  }

  /* Given two values, either both of sizetype or both of bitsizetype,
*************** fold_convert (tree type, tree arg)
*** 1947,1955 ****
        if (INTEGRAL_TYPE_P (orig)
  	  || POINTER_TYPE_P (orig)
  	  || TREE_CODE (orig) == REAL_TYPE)
! 	return build (COMPLEX_EXPR, type,
! 		      fold_convert (TREE_TYPE (type), arg),
! 		      fold_convert (TREE_TYPE (type), integer_zero_node));
        if (TREE_CODE (orig) == COMPLEX_TYPE)
  	{
  	  tree rpart, ipart;
--- 1952,1960 ----
        if (INTEGRAL_TYPE_P (orig)
  	  || POINTER_TYPE_P (orig)
  	  || TREE_CODE (orig) == REAL_TYPE)
! 	return build2 (COMPLEX_EXPR, type,
! 		       fold_convert (TREE_TYPE (type), arg),
! 		       fold_convert (TREE_TYPE (type), integer_zero_node));
        if (TREE_CODE (orig) == COMPLEX_TYPE)
  	{
  	  tree rpart, ipart;
*************** fold_convert (tree type, tree arg)
*** 1958,1964 ****
  	    {
  	      rpart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 0));
  	      ipart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 1));
! 	      return fold (build (COMPLEX_EXPR, type, rpart, ipart));
  	    }

  	  arg = save_expr (arg);
--- 1963,1969 ----
  	    {
  	      rpart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 0));
  	      ipart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 1));
! 	      return fold (build2 (COMPLEX_EXPR, type, rpart, ipart));
  	    }

  	  arg = save_expr (arg);
*************** fold_convert (tree type, tree arg)
*** 1966,1972 ****
  	  ipart = fold (build1 (IMAGPART_EXPR, TREE_TYPE (orig), arg));
  	  rpart = fold_convert (TREE_TYPE (type), rpart);
  	  ipart = fold_convert (TREE_TYPE (type), ipart);
! 	  return fold (build (COMPLEX_EXPR, type, rpart, ipart));
  	}
      }
    else if (TREE_CODE (type) == VECTOR_TYPE)
--- 1971,1977 ----
  	  ipart = fold (build1 (IMAGPART_EXPR, TREE_TYPE (orig), arg));
  	  rpart = fold_convert (TREE_TYPE (type), rpart);
  	  ipart = fold_convert (TREE_TYPE (type), ipart);
! 	  return fold (build2 (COMPLEX_EXPR, type, rpart, ipart));
  	}
      }
    else if (TREE_CODE (type) == VECTOR_TYPE)
*************** eval_subst (tree arg, tree old0, tree ne
*** 2555,2565 ****
  				       old0, new0, old1, new1)));

      case '2':
!       return fold (build (code, type,
! 			  eval_subst (TREE_OPERAND (arg, 0),
! 				      old0, new0, old1, new1),
! 			  eval_subst (TREE_OPERAND (arg, 1),
! 				      old0, new0, old1, new1)));

      case 'e':
        switch (code)
--- 2560,2570 ----
  				       old0, new0, old1, new1)));

      case '2':
!       return fold (build2 (code, type,
! 			   eval_subst (TREE_OPERAND (arg, 0),
! 				       old0, new0, old1, new1),
! 			   eval_subst (TREE_OPERAND (arg, 1),
! 				       old0, new0, old1, new1)));

      case 'e':
        switch (code)
*************** eval_subst (tree arg, tree old0, tree ne
*** 2571,2583 ****
  	  return eval_subst (TREE_OPERAND (arg, 1), old0, new0, old1, new1);

  	case COND_EXPR:
! 	  return fold (build (code, type,
! 			      eval_subst (TREE_OPERAND (arg, 0),
! 					  old0, new0, old1, new1),
! 			      eval_subst (TREE_OPERAND (arg, 1),
! 					  old0, new0, old1, new1),
! 			      eval_subst (TREE_OPERAND (arg, 2),
! 					  old0, new0, old1, new1)));
  	default:
  	  break;
  	}
--- 2576,2588 ----
  	  return eval_subst (TREE_OPERAND (arg, 1), old0, new0, old1, new1);

  	case COND_EXPR:
! 	  return fold (build3 (code, type,
! 			       eval_subst (TREE_OPERAND (arg, 0),
! 					   old0, new0, old1, new1),
! 			       eval_subst (TREE_OPERAND (arg, 1),
! 					   old0, new0, old1, new1),
! 			       eval_subst (TREE_OPERAND (arg, 2),
! 					   old0, new0, old1, new1)));
  	default:
  	  break;
  	}
*************** eval_subst (tree arg, tree old0, tree ne
*** 2602,2608 ****
  	else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
  	  arg1 = new1;

! 	return fold (build (code, type, arg0, arg1));
        }

      default:
--- 2607,2613 ----
  	else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
  	  arg1 = new1;

! 	return fold (build2 (code, type, arg0, arg1));
        }

      default:
*************** omit_one_operand (tree type, tree result
*** 2623,2629 ****
    tree t = fold_convert (type, result);

    if (TREE_SIDE_EFFECTS (omitted))
!     return build (COMPOUND_EXPR, type, omitted, t);

    return non_lvalue (t);
  }
--- 2628,2634 ----
    tree t = fold_convert (type, result);

    if (TREE_SIDE_EFFECTS (omitted))
!     return build2 (COMPOUND_EXPR, type, omitted, t);

    return non_lvalue (t);
  }
*************** pedantic_omit_one_operand (tree type, tr
*** 2636,2642 ****
    tree t = fold_convert (type, result);

    if (TREE_SIDE_EFFECTS (omitted))
!     return build (COMPOUND_EXPR, type, omitted, t);

    return pedantic_non_lvalue (t);
  }
--- 2641,2647 ----
    tree t = fold_convert (type, result);

    if (TREE_SIDE_EFFECTS (omitted))
!     return build2 (COMPOUND_EXPR, type, omitted, t);

    return pedantic_non_lvalue (t);
  }
*************** invert_truthvalue (tree arg)
*** 2674,2681 ****
  	       || code == UNGE_EXPR)
  	return build1 (TRUTH_NOT_EXPR, type, arg);
        else
! 	return build (invert_tree_comparison (code), type,
! 		      TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
      }

    switch (code)
--- 2679,2686 ----
  	       || code == UNGE_EXPR)
  	return build1 (TRUTH_NOT_EXPR, type, arg);
        else
! 	return build2 (invert_tree_comparison (code), type,
! 		       TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
      }

    switch (code)
*************** invert_truthvalue (tree arg)
*** 2684,2697 ****
        return fold_convert (type, build_int_2 (integer_zerop (arg), 0));

      case TRUTH_AND_EXPR:
!       return build (TRUTH_OR_EXPR, type,
! 		    invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		    invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_OR_EXPR:
!       return build (TRUTH_AND_EXPR, type,
! 		    invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		    invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_XOR_EXPR:
        /* Here we can invert either operand.  We invert the first operand
--- 2689,2702 ----
        return fold_convert (type, build_int_2 (integer_zerop (arg), 0));

      case TRUTH_AND_EXPR:
!       return build2 (TRUTH_OR_EXPR, type,
! 		     invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		     invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_OR_EXPR:
!       return build2 (TRUTH_AND_EXPR, type,
! 		     invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		     invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_XOR_EXPR:
        /* Here we can invert either operand.  We invert the first operand
*************** invert_truthvalue (tree arg)
*** 2700,2733 ****
  	 negation of the second operand.  */

        if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
! 	return build (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
! 		      TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
        else
! 	return build (TRUTH_XOR_EXPR, type,
! 		      invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		      TREE_OPERAND (arg, 1));

      case TRUTH_ANDIF_EXPR:
!       return build (TRUTH_ORIF_EXPR, type,
! 		    invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		    invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_ORIF_EXPR:
!       return build (TRUTH_ANDIF_EXPR, type,
! 		    invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		    invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_NOT_EXPR:
        return TREE_OPERAND (arg, 0);

      case COND_EXPR:
!       return build (COND_EXPR, type, TREE_OPERAND (arg, 0),
! 		    invert_truthvalue (TREE_OPERAND (arg, 1)),
! 		    invert_truthvalue (TREE_OPERAND (arg, 2)));

      case COMPOUND_EXPR:
!       return build (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
! 		    invert_truthvalue (TREE_OPERAND (arg, 1)));

      case NON_LVALUE_EXPR:
        return invert_truthvalue (TREE_OPERAND (arg, 0));
--- 2705,2738 ----
  	 negation of the second operand.  */

        if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
! 	return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
! 		       TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
        else
! 	return build2 (TRUTH_XOR_EXPR, type,
! 		       invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		       TREE_OPERAND (arg, 1));

      case TRUTH_ANDIF_EXPR:
!       return build2 (TRUTH_ORIF_EXPR, type,
! 		     invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		     invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_ORIF_EXPR:
!       return build2 (TRUTH_ANDIF_EXPR, type,
! 		     invert_truthvalue (TREE_OPERAND (arg, 0)),
! 		     invert_truthvalue (TREE_OPERAND (arg, 1)));

      case TRUTH_NOT_EXPR:
        return TREE_OPERAND (arg, 0);

      case COND_EXPR:
!       return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
! 		     invert_truthvalue (TREE_OPERAND (arg, 1)),
! 		     invert_truthvalue (TREE_OPERAND (arg, 2)));

      case COMPOUND_EXPR:
!       return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
! 		     invert_truthvalue (TREE_OPERAND (arg, 1)));

      case NON_LVALUE_EXPR:
        return invert_truthvalue (TREE_OPERAND (arg, 0));
*************** invert_truthvalue (tree arg)
*** 2744,2751 ****
      case BIT_AND_EXPR:
        if (!integer_onep (TREE_OPERAND (arg, 1)))
  	break;
!       return build (EQ_EXPR, type, arg,
! 		    fold_convert (type, integer_zero_node));

      case SAVE_EXPR:
        return build1 (TRUTH_NOT_EXPR, type, arg);
--- 2749,2756 ----
      case BIT_AND_EXPR:
        if (!integer_onep (TREE_OPERAND (arg, 1)))
  	break;
!       return build2 (EQ_EXPR, type, arg,
! 		     fold_convert (type, integer_zero_node));

      case SAVE_EXPR:
        return build1 (TRUTH_NOT_EXPR, type, arg);
*************** distribute_bit_expr (enum tree_code code
*** 2810,2817 ****
    else
      return 0;

!   return fold (build (TREE_CODE (arg0), type, common,
! 		      fold (build (code, type, left, right))));
  }

  /* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
--- 2815,2822 ----
    else
      return 0;

!   return fold (build2 (TREE_CODE (arg0), type, common,
! 		       fold (build2 (code, type, left, right))));
  }

  /* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
*************** static tree
*** 2821,2828 ****
  make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
  		    int unsignedp)
  {
!   tree result = build (BIT_FIELD_REF, type, inner,
! 		       size_int (bitsize), bitsize_int (bitpos));

    BIT_FIELD_REF_UNSIGNED (result) = unsignedp;

--- 2826,2833 ----
  make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
  		    int unsignedp)
  {
!   tree result = build3 (BIT_FIELD_REF, type, inner,
! 			size_int (bitsize), bitsize_int (bitpos));

    BIT_FIELD_REF_UNSIGNED (result) = unsignedp;

*************** optimize_bit_field_compare (enum tree_co
*** 2927,2941 ****
    if (! const_p)
      /* If not comparing with constant, just rework the comparison
         and return.  */
!     return build (code, compare_type,
! 		  build (BIT_AND_EXPR, unsigned_type,
! 			 make_bit_field_ref (linner, unsigned_type,
! 					     nbitsize, nbitpos, 1),
! 			 mask),
! 		  build (BIT_AND_EXPR, unsigned_type,
! 			 make_bit_field_ref (rinner, unsigned_type,
! 					     nbitsize, nbitpos, 1),
! 			 mask));

    /* Otherwise, we are handling the constant case. See if the constant is too
       big for the field.  Warn and return a tree of for 0 (false) if so.  We do
--- 2932,2946 ----
    if (! const_p)
      /* If not comparing with constant, just rework the comparison
         and return.  */
!     return build2 (code, compare_type,
! 		   build2 (BIT_AND_EXPR, unsigned_type,
! 			   make_bit_field_ref (linner, unsigned_type,
! 					       nbitsize, nbitpos, 1),
! 			   mask),
! 		   build2 (BIT_AND_EXPR, unsigned_type,
! 			   make_bit_field_ref (rinner, unsigned_type,
! 					       nbitsize, nbitpos, 1),
! 			   mask));

    /* Otherwise, we are handling the constant case. See if the constant is too
       big for the field.  Warn and return a tree of for 0 (false) if so.  We do
*************** optimize_bit_field_compare (enum tree_co
*** 2996,3004 ****
  					size_int (lbitpos), 0),
  			   mask, 0));

!   return build (code, compare_type,
! 		build (BIT_AND_EXPR, unsigned_type, lhs, mask),
! 		rhs);
  }

  /* Subroutine for fold_truthop: decode a field reference.
--- 3001,3009 ----
  					size_int (lbitpos), 0),
  			   mask, 0));

!   return build2 (code, compare_type,
! 		 build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
! 		 rhs);
  }

  /* Subroutine for fold_truthop: decode a field reference.
*************** decode_field_reference (tree exp, HOST_W
*** 3085,3092 ****

    /* Merge it with the mask we found in the BIT_AND_EXPR, if any.  */
    if (and_mask != 0)
!     mask = fold (build (BIT_AND_EXPR, unsigned_type,
! 			fold_convert (unsigned_type, and_mask), mask));

    *pmask = mask;
    *pand_mask = and_mask;
--- 3090,3097 ----

    /* Merge it with the mask we found in the BIT_AND_EXPR, if any.  */
    if (and_mask != 0)
!     mask = fold (build2 (BIT_AND_EXPR, unsigned_type,
! 			 fold_convert (unsigned_type, and_mask), mask));

    *pmask = mask;
    *pand_mask = and_mask;
*************** range_binop (enum tree_code code, tree t
*** 3251,3258 ****

    if (arg0 != 0 && arg1 != 0)
      {
!       tem = fold (build (code, type != 0 ? type : TREE_TYPE (arg0),
! 			 arg0, fold_convert (TREE_TYPE (arg0), arg1)));
        STRIP_NOPS (tem);
        return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
      }
--- 3256,3263 ----

    if (arg0 != 0 && arg1 != 0)
      {
!       tem = fold (build2 (code, type != 0 ? type : TREE_TYPE (arg0),
! 			  arg0, fold_convert (TREE_TYPE (arg0), arg1)));
        STRIP_NOPS (tem);
        return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
      }
*************** make_range (tree exp, int *pin_p, tree *
*** 3427,3434 ****

  	case BIT_NOT_EXPR:
  	  /* ~ X -> -X - 1  */
! 	  exp = build (MINUS_EXPR, type, negate_expr (arg0),
! 		       fold_convert (type, integer_one_node));
  	  continue;

  	case PLUS_EXPR:  case MINUS_EXPR:
--- 3432,3439 ----

  	case BIT_NOT_EXPR:
  	  /* ~ X -> -X - 1  */
! 	  exp = build2 (MINUS_EXPR, type, negate_expr (arg0),
! 			fold_convert (type, integer_one_node));
  	  continue;

  	case PLUS_EXPR:  case MINUS_EXPR:
*************** make_range (tree exp, int *pin_p, tree *
*** 3509,3519 ****
  		  : TYPE_MAX_VALUE (type);

  	      if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (exp)))
! 	        high_positive = fold (build (RSHIFT_EXPR, type,
! 					     fold_convert (type,
! 							   high_positive),
! 					     fold_convert (type,
! 							   integer_one_node)));

  	      /* If the low bound is specified, "and" the range with the
  		 range for which the original unsigned value will be
--- 3514,3524 ----
  		  : TYPE_MAX_VALUE (type);

  	      if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (exp)))
! 	        high_positive = fold (build2 (RSHIFT_EXPR, type,
! 					      fold_convert (type,
! 							    high_positive),
! 					      fold_convert (type,
! 							    integer_one_node)));

  	      /* If the low bound is specified, "and" the range with the
  		 range for which the original unsigned value will be
*************** build_range_check (tree type, tree exp,
*** 3586,3598 ****
      return fold_convert (type, integer_one_node);

    if (low == 0)
!     return fold (build (LE_EXPR, type, exp, high));

    if (high == 0)
!     return fold (build (GE_EXPR, type, exp, low));

    if (operand_equal_p (low, high, 0))
!     return fold (build (EQ_EXPR, type, exp, low));

    if (integer_zerop (low))
      {
--- 3591,3603 ----
      return fold_convert (type, integer_one_node);

    if (low == 0)
!     return fold (build2 (LE_EXPR, type, exp, high));

    if (high == 0)
!     return fold (build2 (GE_EXPR, type, exp, low));

    if (operand_equal_p (low, high, 0))
!     return fold (build2 (EQ_EXPR, type, exp, low));

    if (integer_zerop (low))
      {
*************** build_range_check (tree type, tree exp,
*** 3631,3645 ****
  	      etype = lang_hooks.types.signed_type (etype);
  	      exp = fold_convert (etype, exp);
  	    }
! 	  return fold (build (GT_EXPR, type, exp,
! 			      fold_convert (etype, integer_zero_node)));
  	}
      }

    if (0 != (value = const_binop (MINUS_EXPR, high, low, 0))
        && ! TREE_OVERFLOW (value))
      return build_range_check (type,
! 			      fold (build (MINUS_EXPR, etype, exp, low)),
  			      1, fold_convert (etype, integer_zero_node),
  			      value);

--- 3636,3650 ----
  	      etype = lang_hooks.types.signed_type (etype);
  	      exp = fold_convert (etype, exp);
  	    }
! 	  return fold (build2 (GT_EXPR, type, exp,
! 			       fold_convert (etype, integer_zero_node)));
  	}
      }

    if (0 != (value = const_binop (MINUS_EXPR, high, low, 0))
        && ! TREE_OVERFLOW (value))
      return build_range_check (type,
! 			      fold (build2 (MINUS_EXPR, etype, exp, low)),
  			      1, fold_convert (etype, integer_zero_node),
  			      value);

*************** fold_range_test (tree exp)
*** 3828,3837 ****
  	 unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
  	 which cases we can't do this.  */
        if (simple_operand_p (lhs))
! 	return build (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
! 		      ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
! 		      TREE_TYPE (exp), TREE_OPERAND (exp, 0),
! 		      TREE_OPERAND (exp, 1));

        else if (lang_hooks.decls.global_bindings_p () == 0
  	       && ! CONTAINS_PLACEHOLDER_P (lhs))
--- 3833,3842 ----
  	 unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
  	 which cases we can't do this.  */
        if (simple_operand_p (lhs))
! 	return build2 (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
! 		       ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
! 		       TREE_TYPE (exp), TREE_OPERAND (exp, 0),
! 		       TREE_OPERAND (exp, 1));

        else if (lang_hooks.decls.global_bindings_p () == 0
  	       && ! CONTAINS_PLACEHOLDER_P (lhs))
*************** fold_range_test (tree exp)
*** 3844,3852 ****
  	      && (0 != (rhs = build_range_check (TREE_TYPE (exp), common,
  						 or_op ? ! in1_p : in1_p,
  						 low1, high1))))
! 	    return build (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
! 			  ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
! 			  TREE_TYPE (exp), lhs, rhs);
  	}
      }

--- 3849,3857 ----
  	      && (0 != (rhs = build_range_check (TREE_TYPE (exp), common,
  						 or_op ? ! in1_p : in1_p,
  						 low1, high1))))
! 	    return build2 (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
! 			   ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
! 			   TREE_TYPE (exp), lhs, rhs);
  	}
      }

*************** fold_truthop (enum tree_code code, tree
*** 3960,3969 ****
    rcode = TREE_CODE (rhs);

    if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1)))
!     lcode = NE_EXPR, lhs = build (NE_EXPR, truth_type, lhs, integer_zero_node);

    if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1)))
!     rcode = NE_EXPR, rhs = build (NE_EXPR, truth_type, rhs, integer_zero_node);

    if (TREE_CODE_CLASS (lcode) != '<' || TREE_CODE_CLASS (rcode) != '<')
      return 0;
--- 3965,3980 ----
    rcode = TREE_CODE (rhs);

    if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1)))
!     {
!       lhs = build2 (NE_EXPR, truth_type, lhs, integer_zero_node);
!       lcode = NE_EXPR;
!     }

    if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1)))
!     {
!       rhs = build2 (NE_EXPR, truth_type, rhs, integer_zero_node);
!       rcode = NE_EXPR;
!     }

    if (TREE_CODE_CLASS (lcode) != '<' || TREE_CODE_CLASS (rcode) != '<')
      return 0;
*************** fold_truthop (enum tree_code code, tree
*** 4014,4021 ****
        else if (compcode == COMPCODE_FALSE)
  	return fold_convert (truth_type, integer_zero_node);
        else if (compcode != -1)
! 	return build (compcode_to_comparison (compcode),
! 		      truth_type, ll_arg, lr_arg);
      }

    /* If the RHS can be evaluated unconditionally and its operands are
--- 4025,4032 ----
        else if (compcode == COMPCODE_FALSE)
  	return fold_convert (truth_type, integer_zero_node);
        else if (compcode != -1)
! 	return build2 (compcode_to_comparison (compcode),
! 		       truth_type, ll_arg, lr_arg);
      }

    /* If the RHS can be evaluated unconditionally and its operands are
*************** fold_truthop (enum tree_code code, tree
*** 4034,4055 ****
  	  && lcode == NE_EXPR && integer_zerop (lr_arg)
  	  && rcode == NE_EXPR && integer_zerop (rr_arg)
  	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
! 	return build (NE_EXPR, truth_type,
! 		      build (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
! 			     ll_arg, rl_arg),
! 		      integer_zero_node);

        /* Convert (a == 0) && (b == 0) into (a | b) == 0.  */
        if (code == TRUTH_AND_EXPR
  	  && lcode == EQ_EXPR && integer_zerop (lr_arg)
  	  && rcode == EQ_EXPR && integer_zerop (rr_arg)
  	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
! 	return build (EQ_EXPR, truth_type,
! 		      build (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
! 			     ll_arg, rl_arg),
! 		      integer_zero_node);

!       return build (code, truth_type, lhs, rhs);
      }

    /* See if the comparisons can be merged.  Then get all the parameters for
--- 4045,4066 ----
  	  && lcode == NE_EXPR && integer_zerop (lr_arg)
  	  && rcode == NE_EXPR && integer_zerop (rr_arg)
  	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
! 	return build2 (NE_EXPR, truth_type,
! 		       build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
! 			       ll_arg, rl_arg),
! 		       integer_zero_node);

        /* Convert (a == 0) && (b == 0) into (a | b) == 0.  */
        if (code == TRUTH_AND_EXPR
  	  && lcode == EQ_EXPR && integer_zerop (lr_arg)
  	  && rcode == EQ_EXPR && integer_zerop (rr_arg)
  	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
! 	return build2 (EQ_EXPR, truth_type,
! 		       build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
! 			       ll_arg, rl_arg),
! 		       integer_zero_node);

!       return build2 (code, truth_type, lhs, rhs);
      }

    /* See if the comparisons can be merged.  Then get all the parameters for
*************** fold_truthop (enum tree_code code, tree
*** 4240,4253 ****
  	  lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
  				    ll_unsignedp || rl_unsignedp);
  	  if (! all_ones_mask_p (ll_mask, lnbitsize))
! 	    lhs = build (BIT_AND_EXPR, lntype, lhs, ll_mask);

  	  rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
  				    lr_unsignedp || rr_unsignedp);
  	  if (! all_ones_mask_p (lr_mask, rnbitsize))
! 	    rhs = build (BIT_AND_EXPR, rntype, rhs, lr_mask);

! 	  return build (wanted_code, truth_type, lhs, rhs);
  	}

        /* There is still another way we can do something:  If both pairs of
--- 4251,4264 ----
  	  lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
  				    ll_unsignedp || rl_unsignedp);
  	  if (! all_ones_mask_p (ll_mask, lnbitsize))
! 	    lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);

  	  rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
  				    lr_unsignedp || rr_unsignedp);
  	  if (! all_ones_mask_p (lr_mask, rnbitsize))
! 	    rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);

! 	  return build2 (wanted_code, truth_type, lhs, rhs);
  	}

        /* There is still another way we can do something:  If both pairs of
*************** fold_truthop (enum tree_code code, tree
*** 4293,4304 ****
  	    }

  	  if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
! 	    lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);

  	  if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
! 	    rhs = build (BIT_AND_EXPR, type, rhs, lr_mask);

! 	  return build (wanted_code, truth_type, lhs, rhs);
  	}

        return 0;
--- 4304,4315 ----
  	    }

  	  if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
! 	    lhs = build2 (BIT_AND_EXPR, type, lhs, ll_mask);

  	  if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
! 	    rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);

! 	  return build2 (wanted_code, truth_type, lhs, rhs);
  	}

        return 0;
*************** fold_truthop (enum tree_code code, tree
*** 4334,4343 ****

    ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
    if (! all_ones_mask_p (ll_mask, lnbitsize))
!     result = build (BIT_AND_EXPR, lntype, result, ll_mask);

!   return build (wanted_code, truth_type, result,
! 		const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
  }

  /* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
--- 4345,4354 ----

    ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
    if (! all_ones_mask_p (ll_mask, lnbitsize))
!     result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);

!   return build2 (wanted_code, truth_type, result,
! 		 const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
  }

  /* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
*************** optimize_minmax_comparison (tree t)
*** 4381,4400 ****

      case GE_EXPR:
        return
! 	fold (build (TRUTH_ORIF_EXPR, type,
! 		     optimize_minmax_comparison
! 		     (build (EQ_EXPR, type, arg0, comp_const)),
! 		     optimize_minmax_comparison
! 		     (build (GT_EXPR, type, arg0, comp_const))));

      case EQ_EXPR:
        if (op_code == MAX_EXPR && consts_equal)
  	/* MAX (X, 0) == 0  ->  X <= 0  */
! 	return fold (build (LE_EXPR, type, inner, comp_const));

        else if (op_code == MAX_EXPR && consts_lt)
  	/* MAX (X, 0) == 5  ->  X == 5   */
! 	return fold (build (EQ_EXPR, type, inner, comp_const));

        else if (op_code == MAX_EXPR)
  	/* MAX (X, 0) == -1  ->  false  */
--- 4392,4411 ----

      case GE_EXPR:
        return
! 	fold (build2 (TRUTH_ORIF_EXPR, type,
! 		      optimize_minmax_comparison
! 		      (build2 (EQ_EXPR, type, arg0, comp_const)),
! 		      optimize_minmax_comparison
! 		      (build2 (GT_EXPR, type, arg0, comp_const))));

      case EQ_EXPR:
        if (op_code == MAX_EXPR && consts_equal)
  	/* MAX (X, 0) == 0  ->  X <= 0  */
! 	return fold (build2 (LE_EXPR, type, inner, comp_const));

        else if (op_code == MAX_EXPR && consts_lt)
  	/* MAX (X, 0) == 5  ->  X == 5   */
! 	return fold (build2 (EQ_EXPR, type, inner, comp_const));

        else if (op_code == MAX_EXPR)
  	/* MAX (X, 0) == -1  ->  false  */
*************** optimize_minmax_comparison (tree t)
*** 4402,4408 ****

        else if (consts_equal)
  	/* MIN (X, 0) == 0  ->  X >= 0  */
! 	return fold (build (GE_EXPR, type, inner, comp_const));

        else if (consts_lt)
  	/* MIN (X, 0) == 5  ->  false  */
--- 4413,4419 ----

        else if (consts_equal)
  	/* MIN (X, 0) == 0  ->  X >= 0  */
! 	return fold (build2 (GE_EXPR, type, inner, comp_const));

        else if (consts_lt)
  	/* MIN (X, 0) == 5  ->  false  */
*************** optimize_minmax_comparison (tree t)
*** 4410,4422 ****

        else
  	/* MIN (X, 0) == -1  ->  X == -1  */
! 	return fold (build (EQ_EXPR, type, inner, comp_const));

      case GT_EXPR:
        if (op_code == MAX_EXPR && (consts_equal || consts_lt))
  	/* MAX (X, 0) > 0  ->  X > 0
  	   MAX (X, 0) > 5  ->  X > 5  */
! 	return fold (build (GT_EXPR, type, inner, comp_const));

        else if (op_code == MAX_EXPR)
  	/* MAX (X, 0) > -1  ->  true  */
--- 4421,4433 ----

        else
  	/* MIN (X, 0) == -1  ->  X == -1  */
! 	return fold (build2 (EQ_EXPR, type, inner, comp_const));

      case GT_EXPR:
        if (op_code == MAX_EXPR && (consts_equal || consts_lt))
  	/* MAX (X, 0) > 0  ->  X > 0
  	   MAX (X, 0) > 5  ->  X > 5  */
! 	return fold (build2 (GT_EXPR, type, inner, comp_const));

        else if (op_code == MAX_EXPR)
  	/* MAX (X, 0) > -1  ->  true  */
*************** optimize_minmax_comparison (tree t)
*** 4429,4435 ****

        else
  	/* MIN (X, 0) > -1  ->  X > -1  */
! 	return fold (build (GT_EXPR, type, inner, comp_const));

      default:
        return t;
--- 4440,4446 ----

        else
  	/* MIN (X, 0) > -1  ->  X > -1  */
! 	return fold (build2 (GT_EXPR, type, inner, comp_const));

      default:
        return t;
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4564,4571 ****
  	  if (tree_int_cst_sgn (c) < 0)
  	    tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);

! 	  return fold (build (tcode, ctype, fold_convert (ctype, t1),
! 			      fold_convert (ctype, t2)));
  	}
        break;

--- 4575,4582 ----
  	  if (tree_int_cst_sgn (c) < 0)
  	    tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);

! 	  return fold (build2 (tcode, ctype, fold_convert (ctype, t1),
! 			       fold_convert (ctype, t2)));
  	}
        break;

*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4583,4591 ****
  						   size_one_node,
  						   op1, 0)))
  	  && ! TREE_OVERFLOW (t1))
! 	return extract_muldiv (build (tcode == LSHIFT_EXPR
! 				      ? MULT_EXPR : FLOOR_DIV_EXPR,
! 				      ctype, fold_convert (ctype, op0), t1),
  			       c, code, wide_type);
        break;

--- 4594,4602 ----
  						   size_one_node,
  						   op1, 0)))
  	  && ! TREE_OVERFLOW (t1))
! 	return extract_muldiv (build2 (tcode == LSHIFT_EXPR
! 				       ? MULT_EXPR : FLOOR_DIV_EXPR,
! 				       ctype, fold_convert (ctype, op0), t1),
  			       c, code, wide_type);
        break;

*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4602,4609 ****
  		 are divisible by c.  */
  	      || (multiple_of_p (ctype, op0, c)
  	          && multiple_of_p (ctype, op1, c))))
! 	return fold (build (tcode, ctype, fold_convert (ctype, t1),
! 			    fold_convert (ctype, t2)));

        /* If this was a subtraction, negate OP1 and set it to be an addition.
  	 This simplifies the logic below.  */
--- 4613,4620 ----
  		 are divisible by c.  */
  	      || (multiple_of_p (ctype, op0, c)
  	          && multiple_of_p (ctype, op1, c))))
! 	return fold (build2 (tcode, ctype, fold_convert (ctype, t1),
! 			     fold_convert (ctype, t2)));

        /* If this was a subtraction, negate OP1 and set it to be an addition.
  	 This simplifies the logic below.  */
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4653,4669 ****
        /* If we were able to eliminate our operation from the first side,
  	 apply our operation to the second side and reform the PLUS.  */
        if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
! 	return fold (build (tcode, ctype, fold_convert (ctype, t1), op1));

        /* The last case is if we are a multiply.  In that case, we can
  	 apply the distributive law to commute the multiply and addition
  	 if the multiplication of the constants doesn't overflow.  */
        if (code == MULT_EXPR)
! 	return fold (build (tcode, ctype,
! 			    fold (build (code, ctype,
! 					 fold_convert (ctype, op0),
! 					 fold_convert (ctype, c))),
! 			    op1));

        break;

--- 4664,4680 ----
        /* If we were able to eliminate our operation from the first side,
  	 apply our operation to the second side and reform the PLUS.  */
        if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
! 	return fold (build2 (tcode, ctype, fold_convert (ctype, t1), op1));

        /* The last case is if we are a multiply.  In that case, we can
  	 apply the distributive law to commute the multiply and addition
  	 if the multiplication of the constants doesn't overflow.  */
        if (code == MULT_EXPR)
! 	return fold (build2 (tcode, ctype,
! 			     fold (build2 (code, ctype,
! 					   fold_convert (ctype, op0),
! 					   fold_convert (ctype, c))),
! 			     op1));

        break;

*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4685,4696 ****
  	 do something only if the second operand is a constant.  */
        if (same_p
  	  && (t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
! 	return fold (build (tcode, ctype, fold_convert (ctype, t1),
! 			    fold_convert (ctype, op1)));
        else if (tcode == MULT_EXPR && code == MULT_EXPR
  	       && (t1 = extract_muldiv (op1, c, code, wide_type)) != 0)
! 	return fold (build (tcode, ctype, fold_convert (ctype, op0),
! 			    fold_convert (ctype, t1)));
        else if (TREE_CODE (op1) != INTEGER_CST)
  	return 0;

--- 4696,4707 ----
  	 do something only if the second operand is a constant.  */
        if (same_p
  	  && (t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
! 	return fold (build2 (tcode, ctype, fold_convert (ctype, t1),
! 			     fold_convert (ctype, op1)));
        else if (tcode == MULT_EXPR && code == MULT_EXPR
  	       && (t1 = extract_muldiv (op1, c, code, wide_type)) != 0)
! 	return fold (build2 (tcode, ctype, fold_convert (ctype, op0),
! 			     fold_convert (ctype, t1)));
        else if (TREE_CODE (op1) != INTEGER_CST)
  	return 0;

*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4700,4706 ****
  	  && 0 != (t1 = const_binop (MULT_EXPR, fold_convert (ctype, op1),
  				     fold_convert (ctype, c), 0))
  	  && ! TREE_OVERFLOW (t1))
! 	return fold (build (tcode, ctype, fold_convert (ctype, op0), t1));

        /* If these operations "cancel" each other, we have the main
  	 optimizations of this pass, which occur when either constant is a
--- 4711,4717 ----
  	  && 0 != (t1 = const_binop (MULT_EXPR, fold_convert (ctype, op1),
  				     fold_convert (ctype, c), 0))
  	  && ! TREE_OVERFLOW (t1))
! 	return fold (build2 (tcode, ctype, fold_convert (ctype, op0), t1));

        /* If these operations "cancel" each other, we have the main
  	 optimizations of this pass, which occur when either constant is a
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4719,4733 ****
  		  && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
  	{
  	  if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
! 	    return fold (build (tcode, ctype, fold_convert (ctype, op0),
! 				fold_convert (ctype,
! 					      const_binop (TRUNC_DIV_EXPR,
! 							   op1, c, 0))));
  	  else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
! 	    return fold (build (code, ctype, fold_convert (ctype, op0),
! 				fold_convert (ctype,
! 					      const_binop (TRUNC_DIV_EXPR,
! 							   c, op1, 0))));
  	}
        break;

--- 4730,4744 ----
  		  && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
  	{
  	  if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
! 	    return fold (build2 (tcode, ctype, fold_convert (ctype, op0),
! 				 fold_convert (ctype,
! 					       const_binop (TRUNC_DIV_EXPR,
! 							    op1, c, 0))));
  	  else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
! 	    return fold (build2 (code, ctype, fold_convert (ctype, op0),
! 				 fold_convert (ctype,
! 					       const_binop (TRUNC_DIV_EXPR,
! 							    c, op1, 0))));
  	}
        break;

*************** fold_binary_op_with_conditional_arg (enu
*** 4933,4942 ****
  	       || TREE_SIDE_EFFECTS (arg)))
      {
        if (TREE_CODE (true_value) != COND_EXPR)
! 	lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs));

        if (TREE_CODE (false_value) != COND_EXPR)
! 	rhs = fold (build (rhs_code, rhs_type, *false_lhs, *false_rhs));

        if ((lhs == 0 || ! TREE_CONSTANT (lhs))
  	  && (rhs == 0 || !TREE_CONSTANT (rhs)))
--- 4944,4953 ----
  	       || TREE_SIDE_EFFECTS (arg)))
      {
        if (TREE_CODE (true_value) != COND_EXPR)
! 	lhs = fold (build2 (lhs_code, lhs_type, *true_lhs, *true_rhs));

        if (TREE_CODE (false_value) != COND_EXPR)
! 	rhs = fold (build2 (rhs_code, rhs_type, *false_lhs, *false_rhs));

        if ((lhs == 0 || ! TREE_CONSTANT (lhs))
  	  && (rhs == 0 || !TREE_CONSTANT (rhs)))
*************** fold_binary_op_with_conditional_arg (enu
*** 4948,4958 ****
      }

    if (lhs == 0)
!     lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs));
    if (rhs == 0)
!     rhs = fold (build (rhs_code, rhs_type, *false_lhs, *false_rhs));

!   test = fold (build (COND_EXPR, type, test, lhs, rhs));

    /* If ARG involves a SAVE_EXPR, we need to ensure it is evaluated
       ahead of the COND_EXPR we made.  Otherwise we would have it only
--- 4959,4969 ----
      }

    if (lhs == 0)
!     lhs = fold (build2 (lhs_code, lhs_type, *true_lhs, *true_rhs));
    if (rhs == 0)
!     rhs = fold (build2 (rhs_code, rhs_type, *false_lhs, *false_rhs));

!   test = fold (build3 (COND_EXPR, type, test, lhs, rhs));

    /* If ARG involves a SAVE_EXPR, we need to ensure it is evaluated
       ahead of the COND_EXPR we made.  Otherwise we would have it only
*************** fold_binary_op_with_conditional_arg (enu
*** 4961,4969 ****
       above might not return a SAVE_EXPR, so testing the TREE_CODE
       of ARG is not enough to decide here.  */
    if (save)
!     return build (COMPOUND_EXPR, type,
! 		  fold_convert (void_type_node, arg),
! 		  strip_compound_expr (test, arg));
    else
      return fold_convert (type, test);
  }
--- 4972,4980 ----
       above might not return a SAVE_EXPR, so testing the TREE_CODE
       of ARG is not enough to decide here.  */
    if (save)
!     return build2 (COMPOUND_EXPR, type,
! 		   fold_convert (void_type_node, arg),
! 		   strip_compound_expr (test, arg));
    else
      return fold_convert (type, test);
  }
*************** fold_mathfn_compare (enum built_in_funct
*** 5046,5053 ****
  				     arg);

  	  /* sqrt(x) > y is the same as x >= 0, if y is negative.  */
! 	  return fold (build (GE_EXPR, type, arg,
! 			      build_real (TREE_TYPE (arg), dconst0)));
  	}
        else if (code == GT_EXPR || code == GE_EXPR)
  	{
--- 5057,5064 ----
  				     arg);

  	  /* sqrt(x) > y is the same as x >= 0, if y is negative.  */
! 	  return fold (build2 (GE_EXPR, type, arg,
! 			       build_real (TREE_TYPE (arg), dconst0)));
  	}
        else if (code == GT_EXPR || code == GE_EXPR)
  	{
*************** fold_mathfn_compare (enum built_in_funct
*** 5060,5067 ****
  	    {
  	      /* sqrt(x) > y is x == +Inf, when y is very large.  */
  	      if (HONOR_INFINITIES (mode))
! 		return fold (build (EQ_EXPR, type, arg,
! 				    build_real (TREE_TYPE (arg), c2)));

  	      /* sqrt(x) > y is always false, when y is very large
  		 and we don't care about infinities.  */
--- 5071,5078 ----
  	    {
  	      /* sqrt(x) > y is x == +Inf, when y is very large.  */
  	      if (HONOR_INFINITIES (mode))
! 		return fold (build2 (EQ_EXPR, type, arg,
! 				     build_real (TREE_TYPE (arg), c2)));

  	      /* sqrt(x) > y is always false, when y is very large
  		 and we don't care about infinities.  */
*************** fold_mathfn_compare (enum built_in_funct
*** 5071,5078 ****
  	    }

  	  /* sqrt(x) > c is the same as x > c*c.  */
! 	  return fold (build (code, type, arg,
! 			      build_real (TREE_TYPE (arg), c2)));
  	}
        else if (code == LT_EXPR || code == LE_EXPR)
  	{
--- 5082,5089 ----
  	    }

  	  /* sqrt(x) > c is the same as x > c*c.  */
! 	  return fold (build2 (code, type, arg,
! 			       build_real (TREE_TYPE (arg), c2)));
  	}
        else if (code == LT_EXPR || code == LE_EXPR)
  	{
*************** fold_mathfn_compare (enum built_in_funct
*** 5093,5106 ****
  	      /* sqrt(x) < y is x != +Inf when y is very large and we
  		 don't care about NaNs.  */
  	      if (! HONOR_NANS (mode))
! 		return fold (build (NE_EXPR, type, arg,
! 				    build_real (TREE_TYPE (arg), c2)));

  	      /* sqrt(x) < y is x >= 0 when y is very large and we
  		 don't care about Infinities.  */
  	      if (! HONOR_INFINITIES (mode))
! 		return fold (build (GE_EXPR, type, arg,
! 				    build_real (TREE_TYPE (arg), dconst0)));

  	      /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
  	      if (lang_hooks.decls.global_bindings_p () != 0
--- 5104,5117 ----
  	      /* sqrt(x) < y is x != +Inf when y is very large and we
  		 don't care about NaNs.  */
  	      if (! HONOR_NANS (mode))
! 		return fold (build2 (NE_EXPR, type, arg,
! 				     build_real (TREE_TYPE (arg), c2)));

  	      /* sqrt(x) < y is x >= 0 when y is very large and we
  		 don't care about Infinities.  */
  	      if (! HONOR_INFINITIES (mode))
! 		return fold (build2 (GE_EXPR, type, arg,
! 				     build_real (TREE_TYPE (arg), dconst0)));

  	      /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
  	      if (lang_hooks.decls.global_bindings_p () != 0
*************** fold_mathfn_compare (enum built_in_funct
*** 5108,5139 ****
  		return NULL_TREE;

  	      arg = save_expr (arg);
! 	      return fold (build (TRUTH_ANDIF_EXPR, type,
! 				  fold (build (GE_EXPR, type, arg,
! 					       build_real (TREE_TYPE (arg),
! 							   dconst0))),
! 				  fold (build (NE_EXPR, type, arg,
! 					       build_real (TREE_TYPE (arg),
! 							   c2)))));
  	    }

  	  /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs.  */
  	  if (! HONOR_NANS (mode))
! 	    return fold (build (code, type, arg,
! 				build_real (TREE_TYPE (arg), c2)));

  	  /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
  	  if (lang_hooks.decls.global_bindings_p () == 0
  	      && ! CONTAINS_PLACEHOLDER_P (arg))
  	    {
  	      arg = save_expr (arg);
! 	      return fold (build (TRUTH_ANDIF_EXPR, type,
! 				  fold (build (GE_EXPR, type, arg,
! 					       build_real (TREE_TYPE (arg),
! 							   dconst0))),
! 				  fold (build (code, type, arg,
! 					       build_real (TREE_TYPE (arg),
! 							   c2)))));
  	    }
  	}
      }
--- 5119,5150 ----
  		return NULL_TREE;

  	      arg = save_expr (arg);
! 	      return fold (build2 (TRUTH_ANDIF_EXPR, type,
! 				   fold (build2 (GE_EXPR, type, arg,
! 						 build_real (TREE_TYPE (arg),
! 							     dconst0))),
! 				   fold (build2 (NE_EXPR, type, arg,
! 						 build_real (TREE_TYPE (arg),
! 							     c2)))));
  	    }

  	  /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs.  */
  	  if (! HONOR_NANS (mode))
! 	    return fold (build2 (code, type, arg,
! 				 build_real (TREE_TYPE (arg), c2)));

  	  /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
  	  if (lang_hooks.decls.global_bindings_p () == 0
  	      && ! CONTAINS_PLACEHOLDER_P (arg))
  	    {
  	      arg = save_expr (arg);
! 	      return fold (build2 (TRUTH_ANDIF_EXPR, type,
! 				   fold (build2 (GE_EXPR, type, arg,
! 						 build_real (TREE_TYPE (arg),
! 							     dconst0))),
! 				   fold (build2 (code, type, arg,
! 						 build_real (TREE_TYPE (arg),
! 							     c2)))));
  	    }
  	}
      }
*************** fold_inf_compare (enum tree_code code, t
*** 5188,5194 ****
  	  && ! CONTAINS_PLACEHOLDER_P (arg0))
  	{
  	  arg0 = save_expr (arg0);
! 	  return fold (build (EQ_EXPR, type, arg0, arg0));
  	}
        break;

--- 5199,5205 ----
  	  && ! CONTAINS_PLACEHOLDER_P (arg0))
  	{
  	  arg0 = save_expr (arg0);
! 	  return fold (build2 (EQ_EXPR, type, arg0, arg0));
  	}
        break;

*************** fold_inf_compare (enum tree_code code, t
*** 5196,5218 ****
      case GE_EXPR:
        /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX.  */
        real_maxval (&max, neg, mode);
!       return fold (build (neg ? LT_EXPR : GT_EXPR, type,
! 			  arg0, build_real (TREE_TYPE (arg0), max)));

      case LT_EXPR:
        /* x < +Inf is always equal to x <= DBL_MAX.  */
        real_maxval (&max, neg, mode);
!       return fold (build (neg ? GE_EXPR : LE_EXPR, type,
! 			  arg0, build_real (TREE_TYPE (arg0), max)));

      case NE_EXPR:
        /* x != +Inf is always equal to !(x > DBL_MAX).  */
        real_maxval (&max, neg, mode);
        if (! HONOR_NANS (mode))
! 	return fold (build (neg ? GE_EXPR : LE_EXPR, type,
! 			    arg0, build_real (TREE_TYPE (arg0), max)));
!       temp = fold (build (neg ? LT_EXPR : GT_EXPR, type,
! 			  arg0, build_real (TREE_TYPE (arg0), max)));
        return fold (build1 (TRUTH_NOT_EXPR, type, temp));

      default:
--- 5207,5229 ----
      case GE_EXPR:
        /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX.  */
        real_maxval (&max, neg, mode);
!       return fold (build2 (neg ? LT_EXPR : GT_EXPR, type,
! 			   arg0, build_real (TREE_TYPE (arg0), max)));

      case LT_EXPR:
        /* x < +Inf is always equal to x <= DBL_MAX.  */
        real_maxval (&max, neg, mode);
!       return fold (build2 (neg ? GE_EXPR : LE_EXPR, type,
! 			   arg0, build_real (TREE_TYPE (arg0), max)));

      case NE_EXPR:
        /* x != +Inf is always equal to !(x > DBL_MAX).  */
        real_maxval (&max, neg, mode);
        if (! HONOR_NANS (mode))
! 	return fold (build2 (neg ? GE_EXPR : LE_EXPR, type,
! 			     arg0, build_real (TREE_TYPE (arg0), max)));
!       temp = fold (build2 (neg ? LT_EXPR : GT_EXPR, type,
! 			   arg0, build_real (TREE_TYPE (arg0), max)));
        return fold (build1 (TRUTH_NOT_EXPR, type, temp));

      default:
*************** fold_single_bit_test (enum tree_code cod
*** 5416,5424 ****
        if (arg00 != NULL_TREE)
  	{
  	  tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00));
! 	  return fold (build (code == EQ_EXPR ? GE_EXPR : LT_EXPR, result_type,
! 			      fold_convert (stype, arg00),
! 			      fold_convert (stype, integer_zero_node)));
  	}

        /* At this point, we know that arg0 is not testing the sign bit.  */
--- 5427,5435 ----
        if (arg00 != NULL_TREE)
  	{
  	  tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00));
! 	  return fold (build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
! 			       result_type, fold_convert (stype, arg00),
! 			       fold_convert (stype, integer_zero_node)));
  	}

        /* At this point, we know that arg0 is not testing the sign bit.  */
*************** fold_single_bit_test (enum tree_code cod
*** 5457,5472 ****
        inner = fold_convert (intermediate_type, inner);

        if (bitnum != 0)
! 	inner = build (RSHIFT_EXPR, intermediate_type,
! 		       inner, size_int (bitnum));

        if (code == EQ_EXPR)
! 	inner = build (BIT_XOR_EXPR, intermediate_type,
! 		       inner, integer_one_node);

        /* Put the AND last so it can combine with more things.  */
!       inner = build (BIT_AND_EXPR, intermediate_type,
! 		     inner, integer_one_node);

        /* Make sure to return the proper type.  */
        inner = fold_convert (result_type, inner);
--- 5468,5483 ----
        inner = fold_convert (intermediate_type, inner);

        if (bitnum != 0)
! 	inner = build2 (RSHIFT_EXPR, intermediate_type,
! 			inner, size_int (bitnum));

        if (code == EQ_EXPR)
! 	inner = build2 (BIT_XOR_EXPR, intermediate_type,
! 			inner, integer_one_node);

        /* Put the AND last so it can combine with more things.  */
!       inner = build2 (BIT_AND_EXPR, intermediate_type,
! 		      inner, integer_one_node);

        /* Make sure to return the proper type.  */
        inner = fold_convert (result_type, inner);
*************** fold (tree expr)
*** 5656,5663 ****
       to ARG1 to reduce the number of tests below.  */
    if (commutative_tree_code (code)
        && tree_swap_operands_p (arg0, arg1, true))
!     return fold (build (code, type, TREE_OPERAND (t, 1),
! 			TREE_OPERAND (t, 0)));

    /* Now WINS is set as described above,
       ARG0 is the first operand of EXPR,
--- 5667,5674 ----
       to ARG1 to reduce the number of tests below.  */
    if (commutative_tree_code (code)
        && tree_swap_operands_p (arg0, arg1, true))
!     return fold (build2 (code, type, TREE_OPERAND (t, 1),
! 			 TREE_OPERAND (t, 0)));

    /* Now WINS is set as described above,
       ARG0 is the first operand of EXPR,
*************** fold (tree expr)
*** 5688,5698 ****
  		  || (TREE_CODE (arg0) == BIT_AND_EXPR
  		      && integer_onep (TREE_OPERAND (arg0, 1)))))))
      {
!       tem = fold (build (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
! 		       : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
! 		       : TRUTH_XOR_EXPR,
! 		       type, fold_convert (boolean_type_node, arg0),
! 		       fold_convert (boolean_type_node, arg1)));

        if (code == EQ_EXPR)
  	tem = invert_truthvalue (tem);
--- 5699,5709 ----
  		  || (TREE_CODE (arg0) == BIT_AND_EXPR
  		      && integer_onep (TREE_OPERAND (arg0, 1)))))))
      {
!       tem = fold (build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
! 			  : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
! 			  : TRUTH_XOR_EXPR,
! 			  type, fold_convert (boolean_type_node, arg0),
! 			  fold_convert (boolean_type_node, arg1)));

        if (code == EQ_EXPR)
  	tem = invert_truthvalue (tem);
*************** fold (tree expr)
*** 5703,5710 ****
    if (TREE_CODE_CLASS (code) == '1')
      {
        if (TREE_CODE (arg0) == COMPOUND_EXPR)
! 	return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
! 		      fold (build1 (code, type, TREE_OPERAND (arg0, 1))));
        else if (TREE_CODE (arg0) == COND_EXPR)
  	{
  	  tree arg01 = TREE_OPERAND (arg0, 1);
--- 5714,5721 ----
    if (TREE_CODE_CLASS (code) == '1')
      {
        if (TREE_CODE (arg0) == COMPOUND_EXPR)
! 	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
! 		       fold (build1 (code, type, TREE_OPERAND (arg0, 1))));
        else if (TREE_CODE (arg0) == COND_EXPR)
  	{
  	  tree arg01 = TREE_OPERAND (arg0, 1);
*************** fold (tree expr)
*** 5713,5720 ****
  	    arg01 = fold (build1 (code, type, arg01));
  	  if (! VOID_TYPE_P (TREE_TYPE (arg02)))
  	    arg02 = fold (build1 (code, type, arg02));
! 	  tem = fold (build (COND_EXPR, type, TREE_OPERAND (arg0, 0),
! 			     arg01, arg02));

  	  /* If this was a conversion, and all we did was to move into
  	     inside the COND_EXPR, bring it back out.  But leave it if
--- 5724,5731 ----
  	    arg01 = fold (build1 (code, type, arg01));
  	  if (! VOID_TYPE_P (TREE_TYPE (arg02)))
  	    arg02 = fold (build1 (code, type, arg02));
! 	  tem = fold (build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0),
! 			      arg01, arg02));

  	  /* If this was a conversion, and all we did was to move into
  	     inside the COND_EXPR, bring it back out.  But leave it if
*************** fold (tree expr)
*** 5739,5750 ****
  			(TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
  		    && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD))
  	    tem = build1 (code, type,
! 			  build (COND_EXPR,
! 				 TREE_TYPE (TREE_OPERAND
! 					    (TREE_OPERAND (tem, 1), 0)),
! 				 TREE_OPERAND (tem, 0),
! 				 TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
! 				 TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
  	  return tem;
  	}
        else if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
--- 5750,5761 ----
  			(TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
  		    && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD))
  	    tem = build1 (code, type,
! 			  build3 (COND_EXPR,
! 				  TREE_TYPE (TREE_OPERAND
! 					     (TREE_OPERAND (tem, 1), 0)),
! 				  TREE_OPERAND (tem, 0),
! 				  TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
! 				  TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
  	  return tem;
  	}
        else if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
*************** fold (tree expr)
*** 5756,5785 ****
  	      return arg0;
  	    }
  	  else if (TREE_CODE (type) != INTEGER_TYPE)
! 	    return fold (build (COND_EXPR, type, arg0,
! 				fold (build1 (code, type, integer_one_node)),
! 				fold (build1 (code, type, integer_zero_node))));
  	}
     }
    else if (TREE_CODE_CLASS (code) == '<'
  	   && TREE_CODE (arg0) == COMPOUND_EXPR)
!     return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
! 		  fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
    else if (TREE_CODE_CLASS (code) == '<'
  	   && TREE_CODE (arg1) == COMPOUND_EXPR)
!     return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
! 		  fold (build (code, type, arg0, TREE_OPERAND (arg1, 1))));
    else if (TREE_CODE_CLASS (code) == '2'
  	   || TREE_CODE_CLASS (code) == '<')
      {
        if (TREE_CODE (arg0) == COMPOUND_EXPR)
! 	return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
! 		      fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
        if (TREE_CODE (arg1) == COMPOUND_EXPR
  	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
! 	return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
! 		      fold (build (code, type,
! 				   arg0, TREE_OPERAND (arg1, 1))));

        if (TREE_CODE (arg0) == COND_EXPR
  	  || TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
--- 5767,5799 ----
  	      return arg0;
  	    }
  	  else if (TREE_CODE (type) != INTEGER_TYPE)
! 	    return fold (build3 (COND_EXPR, type, arg0,
! 				 fold (build1 (code, type,
! 					       integer_one_node)),
! 				 fold (build1 (code, type,
! 					       integer_zero_node))));
  	}
     }
    else if (TREE_CODE_CLASS (code) == '<'
  	   && TREE_CODE (arg0) == COMPOUND_EXPR)
!     return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
! 		   fold (build2 (code, type, TREE_OPERAND (arg0, 1), arg1)));
    else if (TREE_CODE_CLASS (code) == '<'
  	   && TREE_CODE (arg1) == COMPOUND_EXPR)
!     return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
! 		   fold (build2 (code, type, arg0, TREE_OPERAND (arg1, 1))));
    else if (TREE_CODE_CLASS (code) == '2'
  	   || TREE_CODE_CLASS (code) == '<')
      {
        if (TREE_CODE (arg0) == COMPOUND_EXPR)
! 	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
! 		       fold (build2 (code, type, TREE_OPERAND (arg0, 1),
! 				     arg1)));
        if (TREE_CODE (arg1) == COMPOUND_EXPR
  	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
! 	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
! 		       fold (build2 (code, type,
! 				     arg0, TREE_OPERAND (arg1, 1))));

        if (TREE_CODE (arg0) == COND_EXPR
  	  || TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
*************** fold (tree expr)
*** 5909,5915 ****
  	  tem = copy_node (t);
  	  TREE_OPERAND (tem, 0) = TREE_OPERAND (prev, 1);
  	  /* First do the assignment, then return converted constant.  */
! 	  tem = build (COMPOUND_EXPR, TREE_TYPE (tem), prev, fold (tem));
  	  TREE_NO_WARNING (tem) = 1;
  	  TREE_USED (tem) = 1;
  	  return tem;
--- 5923,5929 ----
  	  tem = copy_node (t);
  	  TREE_OPERAND (tem, 0) = TREE_OPERAND (prev, 1);
  	  /* First do the assignment, then return converted constant.  */
! 	  tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), prev, fold (tem));
  	  TREE_NO_WARNING (tem) = 1;
  	  TREE_USED (tem) = 1;
  	  return tem;
*************** fold (tree expr)
*** 5953,5961 ****
  #endif
  	    }
  	  if (change)
! 	    return fold (build (BIT_AND_EXPR, type,
! 				fold_convert (type, and0),
! 				fold_convert (type, and1)));
  	}

        /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
--- 5967,5975 ----
  #endif
  	    }
  	  if (change)
! 	    return fold (build2 (BIT_AND_EXPR, type,
! 				 fold_convert (type, and0),
! 				 fold_convert (type, and1)));
  	}

        /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
*************** fold (tree expr)
*** 5974,5981 ****
  	  tree s1 = TYPE_SIZE (tt1);

  	  if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
! 	    return build (TREE_CODE (arg0), t0, convert (t0, arg00),
! 		          TREE_OPERAND (arg0, 1));
  	}

        tem = fold_convert_const (code, type, arg0);
--- 5988,5995 ----
  	  tree s1 = TYPE_SIZE (tt1);

  	  if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
! 	    return build2 (TREE_CODE (arg0), t0, convert (t0, arg00),
! 			   TREE_OPERAND (arg0, 1));
  	}

        tem = fold_convert_const (code, type, arg0);
*************** fold (tree expr)
*** 6036,6053 ****
        if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
  	return fold_convert (type, arg0);
        else if (TREE_CODE (arg0) == COMPLEX_EXPR)
! 	return build (COMPLEX_EXPR, type,
! 		      TREE_OPERAND (arg0, 0),
! 		      negate_expr (TREE_OPERAND (arg0, 1)));
        else if (TREE_CODE (arg0) == COMPLEX_CST)
  	return build_complex (type, TREE_REALPART (arg0),
  			      negate_expr (TREE_IMAGPART (arg0)));
        else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build (TREE_CODE (arg0), type,
! 			    fold (build1 (CONJ_EXPR, type,
! 					  TREE_OPERAND (arg0, 0))),
! 			    fold (build1 (CONJ_EXPR,
! 					  type, TREE_OPERAND (arg0, 1)))));
        else if (TREE_CODE (arg0) == CONJ_EXPR)
  	return TREE_OPERAND (arg0, 0);
        return t;
--- 6050,6067 ----
        if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
  	return fold_convert (type, arg0);
        else if (TREE_CODE (arg0) == COMPLEX_EXPR)
! 	return build2 (COMPLEX_EXPR, type,
! 		       TREE_OPERAND (arg0, 0),
! 		       negate_expr (TREE_OPERAND (arg0, 1)));
        else if (TREE_CODE (arg0) == COMPLEX_CST)
  	return build_complex (type, TREE_REALPART (arg0),
  			      negate_expr (TREE_IMAGPART (arg0)));
        else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build2 (TREE_CODE (arg0), type,
! 			     fold (build1 (CONJ_EXPR, type,
! 					   TREE_OPERAND (arg0, 0))),
! 			     fold (build1 (CONJ_EXPR, type,
! 					   TREE_OPERAND (arg0, 1)))));
        else if (TREE_CODE (arg0) == CONJ_EXPR)
  	return TREE_OPERAND (arg0, 0);
        return t;
*************** fold (tree expr)
*** 6070,6080 ****
      case PLUS_EXPR:
        /* A + (-B) -> A - B */
        if (TREE_CODE (arg1) == NEGATE_EXPR)
! 	return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        /* (-A) + B -> B - A */
        if (TREE_CODE (arg0) == NEGATE_EXPR
  	  && reorder_operands_p (TREE_OPERAND (arg0, 0), arg1))
! 	return fold (build (MINUS_EXPR, type, arg1, TREE_OPERAND (arg0, 0)));
        if (! FLOAT_TYPE_P (type))
  	{
  	  if (integer_zerop (arg1))
--- 6084,6094 ----
      case PLUS_EXPR:
        /* A + (-B) -> A - B */
        if (TREE_CODE (arg1) == NEGATE_EXPR)
! 	return fold (build2 (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        /* (-A) + B -> B - A */
        if (TREE_CODE (arg0) == NEGATE_EXPR
  	  && reorder_operands_p (TREE_OPERAND (arg0, 0), arg1))
! 	return fold (build2 (MINUS_EXPR, type, arg1, TREE_OPERAND (arg0, 0)));
        if (! FLOAT_TYPE_P (type))
  	{
  	  if (integer_zerop (arg1))
*************** fold (tree expr)
*** 6117,6134 ****

  	      if (TREE_CODE (parg0) == MULT_EXPR
  		  && TREE_CODE (parg1) != MULT_EXPR)
! 		return fold (build (PLUS_EXPR, type,
! 				    fold (build (PLUS_EXPR, type,
! 						 fold_convert (type, parg0),
! 						 fold_convert (type, marg))),
! 				    fold_convert (type, parg1)));
  	      if (TREE_CODE (parg0) != MULT_EXPR
  		  && TREE_CODE (parg1) == MULT_EXPR)
! 		return fold (build (PLUS_EXPR, type,
! 				    fold (build (PLUS_EXPR, type,
! 						 fold_convert (type, parg1),
! 						 fold_convert (type, marg))),
! 				    fold_convert (type, parg0)));
  	    }

  	  if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR)
--- 6131,6148 ----

  	      if (TREE_CODE (parg0) == MULT_EXPR
  		  && TREE_CODE (parg1) != MULT_EXPR)
! 		return fold (build2 (PLUS_EXPR, type,
! 				     fold (build2 (PLUS_EXPR, type,
! 						   fold_convert (type, parg0),
! 						   fold_convert (type, marg))),
! 				     fold_convert (type, parg1)));
  	      if (TREE_CODE (parg0) != MULT_EXPR
  		  && TREE_CODE (parg1) == MULT_EXPR)
! 		return fold (build2 (PLUS_EXPR, type,
! 				     fold (build2 (PLUS_EXPR, type,
! 						   fold_convert (type, parg1),
! 						   fold_convert (type, marg))),
! 				     fold_convert (type, parg0)));
  	    }

  	  if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR)
*************** fold (tree expr)
*** 6179,6195 ****

  		  if (exact_log2 (int11) > 0 && int01 % int11 == 0)
  		    {
! 		      alt0 = fold (build (MULT_EXPR, type, arg00,
! 					  build_int_2 (int01 / int11, 0)));
  		      alt1 = arg10;
  		      same = arg11;
  		    }
  		}

  	      if (same)
! 		return fold (build (MULT_EXPR, type,
! 				    fold (build (PLUS_EXPR, type, alt0, alt1)),
! 				    same));
  	    }
  	}
        else
--- 6193,6210 ----

  		  if (exact_log2 (int11) > 0 && int01 % int11 == 0)
  		    {
! 		      alt0 = fold (build2 (MULT_EXPR, type, arg00,
! 					   build_int_2 (int01 / int11, 0)));
  		      alt1 = arg10;
  		      same = arg11;
  		    }
  		}

  	      if (same)
! 		return fold (build2 (MULT_EXPR, type,
! 				     fold (build2 (PLUS_EXPR, type,
! 						   alt0, alt1)),
! 				     same));
  	    }
  	}
        else
*************** fold (tree expr)
*** 6205,6212 ****
  	  /* Convert x+x into x*2.0.  */
  	  if (operand_equal_p (arg0, arg1, 0)
  	      && SCALAR_FLOAT_TYPE_P (type))
! 	    return fold (build (MULT_EXPR, type, arg0,
! 				build_real (type, dconst2)));

  	  /* Convert x*c+x into x*(c+1).  */
  	  if (flag_unsafe_math_optimizations
--- 6220,6227 ----
  	  /* Convert x+x into x*2.0.  */
  	  if (operand_equal_p (arg0, arg1, 0)
  	      && SCALAR_FLOAT_TYPE_P (type))
! 	    return fold (build2 (MULT_EXPR, type, arg0,
! 				 build_real (type, dconst2)));

  	  /* Convert x*c+x into x*(c+1).  */
  	  if (flag_unsafe_math_optimizations
*************** fold (tree expr)
*** 6219,6226 ****

  	      c = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
  	      real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
! 	      return fold (build (MULT_EXPR, type, arg1,
! 				  build_real (type, c)));
  	    }

  	  /* Convert x+x*c into x*(c+1).  */
--- 6234,6241 ----

  	      c = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
  	      real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
! 	      return fold (build2 (MULT_EXPR, type, arg1,
! 				   build_real (type, c)));
  	    }

  	  /* Convert x+x*c into x*(c+1).  */
*************** fold (tree expr)
*** 6234,6241 ****

  	      c = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
  	      real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
! 	      return fold (build (MULT_EXPR, type, arg0,
! 				  build_real (type, c)));
  	    }

  	  /* Convert x*c1+x*c2 into x*(c1+c2).  */
--- 6249,6256 ----

  	      c = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
  	      real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
! 	      return fold (build2 (MULT_EXPR, type, arg0,
! 				   build_real (type, c)));
  	    }

  	  /* Convert x*c1+x*c2 into x*(c1+c2).  */
*************** fold (tree expr)
*** 6254,6262 ****
  	      c1 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
  	      c2 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
  	      real_arithmetic (&c1, PLUS_EXPR, &c1, &c2);
! 	      return fold (build (MULT_EXPR, type,
! 				  TREE_OPERAND (arg0, 0),
! 				  build_real (type, c1)));
  	    }
            /* Convert a + (b*c + d*e) into (a + b*c) + d*e */
            if (flag_unsafe_math_optimizations
--- 6269,6277 ----
  	      c1 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
  	      c2 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
  	      real_arithmetic (&c1, PLUS_EXPR, &c1, &c2);
! 	      return fold (build2 (MULT_EXPR, type,
! 				   TREE_OPERAND (arg0, 0),
! 				   build_real (type, c1)));
  	    }
            /* Convert a + (b*c + d*e) into (a + b*c) + d*e */
            if (flag_unsafe_math_optimizations
*************** fold (tree expr)
*** 6269,6276 ****
  		  && TREE_CODE (tree10) == MULT_EXPR)
                  {
                    tree tree0;
!                   tree0 = fold (build (PLUS_EXPR, type, arg0, tree10));
!                   return fold (build (PLUS_EXPR, type, tree0, tree11));
                  }
              }
            /* Convert (b*c + d*e) + a into b*c + (d*e +a) */
--- 6284,6291 ----
  		  && TREE_CODE (tree10) == MULT_EXPR)
                  {
                    tree tree0;
!                   tree0 = fold (build2 (PLUS_EXPR, type, arg0, tree10));
!                   return fold (build2 (PLUS_EXPR, type, tree0, tree11));
                  }
              }
            /* Convert (b*c + d*e) + a into b*c + (d*e +a) */
*************** fold (tree expr)
*** 6284,6291 ****
  		  && TREE_CODE (tree00) == MULT_EXPR)
                  {
                    tree tree0;
!                   tree0 = fold (build (PLUS_EXPR, type, tree01, arg1));
!                   return fold (build (PLUS_EXPR, type, tree00, tree0));
                  }
              }
  	}
--- 6299,6306 ----
  		  && TREE_CODE (tree00) == MULT_EXPR)
                  {
                    tree tree0;
!                   tree0 = fold (build2 (PLUS_EXPR, type, tree01, arg1));
!                   return fold (build2 (PLUS_EXPR, type, tree00, tree0));
                  }
              }
  	}
*************** fold (tree expr)
*** 6320,6327 ****
  		&& TREE_INT_CST_HIGH (tree11) == 0
  		&& ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
  		    == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
! 	      return build (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
! 			    code0 == LSHIFT_EXPR ? tree01 : tree11);
  	    else if (code11 == MINUS_EXPR)
  	      {
  		tree tree110, tree111;
--- 6335,6342 ----
  		&& TREE_INT_CST_HIGH (tree11) == 0
  		&& ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
  		    == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
! 	      return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
! 			     code0 == LSHIFT_EXPR ? tree01 : tree11);
  	    else if (code11 == MINUS_EXPR)
  	      {
  		tree tree110, tree111;
*************** fold (tree expr)
*** 6335,6344 ****
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
  		    && operand_equal_p (tree01, tree111, 0))
! 		  return build ((code0 == LSHIFT_EXPR
! 				 ? LROTATE_EXPR
! 				 : RROTATE_EXPR),
! 				type, TREE_OPERAND (arg0, 0), tree01);
  	      }
  	    else if (code01 == MINUS_EXPR)
  	      {
--- 6350,6359 ----
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
  		    && operand_equal_p (tree01, tree111, 0))
! 		  return build2 ((code0 == LSHIFT_EXPR
! 				  ? LROTATE_EXPR
! 				  : RROTATE_EXPR),
! 				 type, TREE_OPERAND (arg0, 0), tree01);
  	      }
  	    else if (code01 == MINUS_EXPR)
  	      {
*************** fold (tree expr)
*** 6353,6362 ****
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
  		    && operand_equal_p (tree11, tree011, 0))
! 		  return build ((code0 != LSHIFT_EXPR
! 				 ? LROTATE_EXPR
! 				 : RROTATE_EXPR),
! 				type, TREE_OPERAND (arg0, 0), tree11);
  	      }
  	  }
        }
--- 6368,6377 ----
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
  		    && operand_equal_p (tree11, tree011, 0))
! 		  return build2 ((code0 != LSHIFT_EXPR
! 				  ? LROTATE_EXPR
! 				  : RROTATE_EXPR),
! 				 type, TREE_OPERAND (arg0, 0), tree11);
  	      }
  	  }
        }
*************** fold (tree expr)
*** 6459,6473 ****
      case MINUS_EXPR:
        /* A - (-B) -> A + B */
        if (TREE_CODE (arg1) == NEGATE_EXPR)
! 	return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
        if (TREE_CODE (arg0) == NEGATE_EXPR
  	  && (FLOAT_TYPE_P (type)
  	      || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
  	  && negate_expr_p (arg1)
  	  && reorder_operands_p (arg0, arg1))
! 	return fold (build (MINUS_EXPR, type, negate_expr (arg1),
! 			    TREE_OPERAND (arg0, 0)));

        if (! FLOAT_TYPE_P (type))
  	{
--- 6474,6488 ----
      case MINUS_EXPR:
        /* A - (-B) -> A + B */
        if (TREE_CODE (arg1) == NEGATE_EXPR)
! 	return fold (build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
        if (TREE_CODE (arg0) == NEGATE_EXPR
  	  && (FLOAT_TYPE_P (type)
  	      || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
  	  && negate_expr_p (arg1)
  	  && reorder_operands_p (arg0, arg1))
! 	return fold (build2 (MINUS_EXPR, type, negate_expr (arg1),
! 			     TREE_OPERAND (arg0, 0)));

        if (! FLOAT_TYPE_P (type))
  	{
*************** fold (tree expr)
*** 6481,6495 ****
  	      && TREE_CODE (arg1) == BIT_AND_EXPR)
  	    {
  	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
! 		return fold (build (BIT_AND_EXPR, type,
! 				    fold (build1 (BIT_NOT_EXPR, type,
! 						  TREE_OPERAND (arg1, 0))),
! 				    arg0));
  	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
! 		return fold (build (BIT_AND_EXPR, type,
! 				    fold (build1 (BIT_NOT_EXPR, type,
! 						  TREE_OPERAND (arg1, 1))),
! 				    arg0));
  	    }

  	  /* Fold (A & ~B) - (A & B) into (A ^ B) - B, where B is
--- 6496,6510 ----
  	      && TREE_CODE (arg1) == BIT_AND_EXPR)
  	    {
  	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
! 		return fold (build2 (BIT_AND_EXPR, type,
! 				     fold (build1 (BIT_NOT_EXPR, type,
! 						   TREE_OPERAND (arg1, 0))),
! 				     arg0));
  	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
! 		return fold (build2 (BIT_AND_EXPR, type,
! 				     fold (build1 (BIT_NOT_EXPR, type,
! 						   TREE_OPERAND (arg1, 1))),
! 				     arg0));
  	    }

  	  /* Fold (A & ~B) - (A & B) into (A ^ B) - B, where B is
*************** fold (tree expr)
*** 6505,6513 ****

  	      if (operand_equal_p (tem, mask1, 0))
  		{
! 		  tem = fold (build (BIT_XOR_EXPR, type,
! 				     TREE_OPERAND (arg0, 0), mask1));
! 		  return fold (build (MINUS_EXPR, type, tem, mask1));
  		}
  	    }
  	}
--- 6520,6528 ----

  	      if (operand_equal_p (tem, mask1, 0))
  		{
! 		  tem = fold (build2 (BIT_XOR_EXPR, type,
! 				      TREE_OPERAND (arg0, 0), mask1));
! 		  return fold (build2 (MINUS_EXPR, type, tem, mask1));
  		}
  	    }
  	}
*************** fold (tree expr)
*** 6536,6542 ****
        if (!wins && negate_expr_p (arg1)
  	  && (FLOAT_TYPE_P (type)
  	      || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
! 	return fold (build (PLUS_EXPR, type, arg0, negate_expr (arg1)));

        if (TREE_CODE (arg0) == MULT_EXPR
  	  && TREE_CODE (arg1) == MULT_EXPR
--- 6551,6557 ----
        if (!wins && negate_expr_p (arg1)
  	  && (FLOAT_TYPE_P (type)
  	      || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
! 	return fold (build2 (PLUS_EXPR, type, arg0, negate_expr (arg1)));

        if (TREE_CODE (arg0) == MULT_EXPR
  	  && TREE_CODE (arg1) == MULT_EXPR
*************** fold (tree expr)
*** 6545,6563 ****
            /* (A * C) - (B * C) -> (A-B) * C.  */
  	  if (operand_equal_p (TREE_OPERAND (arg0, 1),
  			       TREE_OPERAND (arg1, 1), 0))
! 	    return fold (build (MULT_EXPR, type,
! 				fold (build (MINUS_EXPR, type,
! 					     TREE_OPERAND (arg0, 0),
! 					     TREE_OPERAND (arg1, 0))),
! 				TREE_OPERAND (arg0, 1)));
            /* (A * C1) - (A * C2) -> A * (C1-C2).  */
  	  if (operand_equal_p (TREE_OPERAND (arg0, 0),
  			       TREE_OPERAND (arg1, 0), 0))
! 	    return fold (build (MULT_EXPR, type,
! 				TREE_OPERAND (arg0, 0),
! 				fold (build (MINUS_EXPR, type,
! 					     TREE_OPERAND (arg0, 1),
! 					     TREE_OPERAND (arg1, 1)))));
  	}

        goto associate;
--- 6560,6578 ----
            /* (A * C) - (B * C) -> (A-B) * C.  */
  	  if (operand_equal_p (TREE_OPERAND (arg0, 1),
  			       TREE_OPERAND (arg1, 1), 0))
! 	    return fold (build2 (MULT_EXPR, type,
! 				 fold (build2 (MINUS_EXPR, type,
! 					       TREE_OPERAND (arg0, 0),
! 					       TREE_OPERAND (arg1, 0))),
! 				 TREE_OPERAND (arg0, 1)));
            /* (A * C1) - (A * C2) -> A * (C1-C2).  */
  	  if (operand_equal_p (TREE_OPERAND (arg0, 0),
  			       TREE_OPERAND (arg1, 0), 0))
! 	    return fold (build2 (MULT_EXPR, type,
! 				 TREE_OPERAND (arg0, 0),
! 				 fold (build2 (MINUS_EXPR, type,
! 					       TREE_OPERAND (arg0, 1),
! 					       TREE_OPERAND (arg1, 1)))));
  	}

        goto associate;
*************** fold (tree expr)
*** 6565,6577 ****
      case MULT_EXPR:
        /* (-A) * (-B) -> A * B  */
        if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
! 	return fold (build (MULT_EXPR, type,
! 			    TREE_OPERAND (arg0, 0),
! 			    negate_expr (arg1)));
        if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
! 	return fold (build (MULT_EXPR, type,
! 			    negate_expr (arg0),
! 			    TREE_OPERAND (arg1, 0)));

        if (! FLOAT_TYPE_P (type))
  	{
--- 6580,6592 ----
      case MULT_EXPR:
        /* (-A) * (-B) -> A * B  */
        if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
! 	return fold (build2 (MULT_EXPR, type,
! 			     TREE_OPERAND (arg0, 0),
! 			     negate_expr (arg1)));
        if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
! 	return fold (build2 (MULT_EXPR, type,
! 			     negate_expr (arg0),
! 			     TREE_OPERAND (arg1, 0)));

        if (! FLOAT_TYPE_P (type))
  	{
*************** fold (tree expr)
*** 6583,6594 ****
  	  /* (a * (1 << b)) is (a << b)  */
  	  if (TREE_CODE (arg1) == LSHIFT_EXPR
  	      && integer_onep (TREE_OPERAND (arg1, 0)))
! 	    return fold (build (LSHIFT_EXPR, type, arg0,
! 				TREE_OPERAND (arg1, 1)));
  	  if (TREE_CODE (arg0) == LSHIFT_EXPR
  	      && integer_onep (TREE_OPERAND (arg0, 0)))
! 	    return fold (build (LSHIFT_EXPR, type, arg1,
! 				TREE_OPERAND (arg0, 1)));

  	  if (TREE_CODE (arg1) == INTEGER_CST
  	      && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0),
--- 6598,6609 ----
  	  /* (a * (1 << b)) is (a << b)  */
  	  if (TREE_CODE (arg1) == LSHIFT_EXPR
  	      && integer_onep (TREE_OPERAND (arg1, 0)))
! 	    return fold (build2 (LSHIFT_EXPR, type, arg0,
! 				 TREE_OPERAND (arg1, 1)));
  	  if (TREE_CODE (arg0) == LSHIFT_EXPR
  	      && integer_onep (TREE_OPERAND (arg0, 0)))
! 	    return fold (build2 (LSHIFT_EXPR, type, arg1,
! 				 TREE_OPERAND (arg0, 1)));

  	  if (TREE_CODE (arg1) == INTEGER_CST
  	      && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0),
*************** fold (tree expr)
*** 6626,6633 ****
  	      tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
  				      arg1, 0);
  	      if (tem)
! 		return fold (build (RDIV_EXPR, type, tem,
! 				    TREE_OPERAND (arg0, 1)));
  	    }

  	  if (flag_unsafe_math_optimizations)
--- 6641,6648 ----
  	      tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
  				      arg1, 0);
  	      if (tem)
! 		return fold (build2 (RDIV_EXPR, type, tem,
! 				     TREE_OPERAND (arg0, 1)));
  	    }

  	  if (flag_unsafe_math_optimizations)
*************** fold (tree expr)
*** 6650,6656 ****

  	          /* Optimize root(x)*root(y) as root(x*y).  */
  		  rootfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		  arg = fold (build (MULT_EXPR, type, arg00, arg10));
  		  arglist = build_tree_list (NULL_TREE, arg);
  		  return build_function_call_expr (rootfn, arglist);
  		}
--- 6665,6671 ----

  	          /* Optimize root(x)*root(y) as root(x*y).  */
  		  rootfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		  arg = fold (build2 (MULT_EXPR, type, arg00, arg10));
  		  arglist = build_tree_list (NULL_TREE, arg);
  		  return build_function_call_expr (rootfn, arglist);
  		}
*************** fold (tree expr)
*** 6659,6667 ****
  	      if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0))
  		{
  		  tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		  tree arg = build (PLUS_EXPR, type,
! 				    TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				    TREE_VALUE (TREE_OPERAND (arg1, 1)));
  		  tree arglist = build_tree_list (NULL_TREE, fold (arg));
  		  return build_function_call_expr (expfn, arglist);
  		}
--- 6674,6682 ----
  	      if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0))
  		{
  		  tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		  tree arg = build2 (PLUS_EXPR, type,
! 				     TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				     TREE_VALUE (TREE_OPERAND (arg1, 1)));
  		  tree arglist = build_tree_list (NULL_TREE, fold (arg));
  		  return build_function_call_expr (expfn, arglist);
  		}
*************** fold (tree expr)
*** 6682,6688 ****
  		  if (operand_equal_p (arg01, arg11, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		      tree arg = build (MULT_EXPR, type, arg00, arg10);
  		      tree arglist = tree_cons (NULL_TREE, fold (arg),
  						build_tree_list (NULL_TREE,
  								 arg01));
--- 6697,6703 ----
  		  if (operand_equal_p (arg01, arg11, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		      tree arg = build2 (MULT_EXPR, type, arg00, arg10);
  		      tree arglist = tree_cons (NULL_TREE, fold (arg),
  						build_tree_list (NULL_TREE,
  								 arg01));
*************** fold (tree expr)
*** 6693,6699 ****
  		  if (operand_equal_p (arg00, arg10, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		      tree arg = fold (build (PLUS_EXPR, type, arg01, arg11));
  		      tree arglist = tree_cons (NULL_TREE, arg00,
  						build_tree_list (NULL_TREE,
  								 arg));
--- 6708,6714 ----
  		  if (operand_equal_p (arg00, arg10, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
! 		      tree arg = fold (build2 (PLUS_EXPR, type, arg01, arg11));
  		      tree arglist = tree_cons (NULL_TREE, arg00,
  						build_tree_list (NULL_TREE,
  								 arg));
*************** fold (tree expr)
*** 6808,6816 ****
  	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
  	{
  	  return fold (build1 (BIT_NOT_EXPR, type,
! 			       build (BIT_AND_EXPR, type,
! 				      TREE_OPERAND (arg0, 0),
! 				      TREE_OPERAND (arg1, 0))));
  	}

        /* See if this can be simplified into a rotate first.  If that
--- 6823,6831 ----
  	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
  	{
  	  return fold (build1 (BIT_NOT_EXPR, type,
! 			       build2 (BIT_AND_EXPR, type,
! 				       TREE_OPERAND (arg0, 0),
! 				       TREE_OPERAND (arg1, 0))));
  	}

        /* See if this can be simplified into a rotate first.  If that
*************** fold (tree expr)
*** 6878,6886 ****
  	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
  	{
  	  return fold (build1 (BIT_NOT_EXPR, type,
! 			       build (BIT_IOR_EXPR, type,
! 				      TREE_OPERAND (arg0, 0),
! 				      TREE_OPERAND (arg1, 0))));
  	}

        goto associate;
--- 6893,6901 ----
  	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
  	{
  	  return fold (build1 (BIT_NOT_EXPR, type,
! 			       build2 (BIT_IOR_EXPR, type,
! 				       TREE_OPERAND (arg0, 0),
! 				       TREE_OPERAND (arg1, 0))));
  	}

        goto associate;
*************** fold (tree expr)
*** 6895,6907 ****

        /* (-A) / (-B) -> A / B  */
        if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
! 	return fold (build (RDIV_EXPR, type,
! 			    TREE_OPERAND (arg0, 0),
! 			    negate_expr (arg1)));
        if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
! 	return fold (build (RDIV_EXPR, type,
! 			    negate_expr (arg0),
! 			    TREE_OPERAND (arg1, 0)));

        /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
        if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
--- 6910,6922 ----

        /* (-A) / (-B) -> A / B  */
        if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
! 	return fold (build2 (RDIV_EXPR, type,
! 			     TREE_OPERAND (arg0, 0),
! 			     negate_expr (arg1)));
        if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
! 	return fold (build2 (RDIV_EXPR, type,
! 			     negate_expr (arg0),
! 			     TREE_OPERAND (arg1, 0)));

        /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
        if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
*************** fold (tree expr)
*** 6923,6929 ****
  	  if (flag_unsafe_math_optimizations
  	      && 0 != (tem = const_binop (code, build_real (type, dconst1),
  					  arg1, 0)))
! 	    return fold (build (MULT_EXPR, type, arg0, tem));
  	  /* Find the reciprocal if optimizing and the result is exact.  */
  	  if (optimize)
  	    {
--- 6938,6944 ----
  	  if (flag_unsafe_math_optimizations
  	      && 0 != (tem = const_binop (code, build_real (type, dconst1),
  					  arg1, 0)))
! 	    return fold (build2 (MULT_EXPR, type, arg0, tem));
  	  /* Find the reciprocal if optimizing and the result is exact.  */
  	  if (optimize)
  	    {
*************** fold (tree expr)
*** 6932,6955 ****
  	      if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
  		{
  		  tem = build_real (type, r);
! 		  return fold (build (MULT_EXPR, type, arg0, tem));
  		}
  	    }
  	}
        /* Convert A/B/C to A/(B*C).  */
        if (flag_unsafe_math_optimizations
  	  && TREE_CODE (arg0) == RDIV_EXPR)
! 	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
! 			    fold (build (MULT_EXPR, type,
! 					 TREE_OPERAND (arg0, 1), arg1))));

        /* Convert A/(B/C) to (A/B)*C.  */
        if (flag_unsafe_math_optimizations
  	  && TREE_CODE (arg1) == RDIV_EXPR)
! 	return fold (build (MULT_EXPR, type,
! 			    fold (build (RDIV_EXPR, type, arg0,
! 					 TREE_OPERAND (arg1, 0))),
! 			    TREE_OPERAND (arg1, 1)));

        /* Convert C1/(X*C2) into (C1/C2)/X.  */
        if (flag_unsafe_math_optimizations
--- 6947,6970 ----
  	      if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
  		{
  		  tem = build_real (type, r);
! 		  return fold (build2 (MULT_EXPR, type, arg0, tem));
  		}
  	    }
  	}
        /* Convert A/B/C to A/(B*C).  */
        if (flag_unsafe_math_optimizations
  	  && TREE_CODE (arg0) == RDIV_EXPR)
! 	return fold (build2 (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
! 			     fold (build2 (MULT_EXPR, type,
! 					   TREE_OPERAND (arg0, 1), arg1))));

        /* Convert A/(B/C) to (A/B)*C.  */
        if (flag_unsafe_math_optimizations
  	  && TREE_CODE (arg1) == RDIV_EXPR)
! 	return fold (build2 (MULT_EXPR, type,
! 			     fold (build2 (RDIV_EXPR, type, arg0,
! 					   TREE_OPERAND (arg1, 0))),
! 			     TREE_OPERAND (arg1, 1)));

        /* Convert C1/(X*C2) into (C1/C2)/X.  */
        if (flag_unsafe_math_optimizations
*************** fold (tree expr)
*** 6960,6967 ****
  	  tree tem = const_binop (RDIV_EXPR, arg0,
  				  TREE_OPERAND (arg1, 1), 0);
  	  if (tem)
! 	    return fold (build (RDIV_EXPR, type, tem,
! 				TREE_OPERAND (arg1, 0)));
  	}

        if (flag_unsafe_math_optimizations)
--- 6975,6982 ----
  	  tree tem = const_binop (RDIV_EXPR, arg0,
  				  TREE_OPERAND (arg1, 1), 0);
  	  if (tem)
! 	    return fold (build2 (RDIV_EXPR, type, tem,
! 				 TREE_OPERAND (arg1, 0)));
  	}

        if (flag_unsafe_math_optimizations)
*************** fold (tree expr)
*** 6975,6981 ****
  	      tree arglist = build_tree_list (NULL_TREE,
  					      fold_convert (type, arg));
  	      arg1 = build_function_call_expr (expfn, arglist);
! 	      return fold (build (MULT_EXPR, type, arg0, arg1));
  	    }

  	  /* Optimize x/pow(y,z) into x*pow(y,-z).  */
--- 6990,6996 ----
  	      tree arglist = build_tree_list (NULL_TREE,
  					      fold_convert (type, arg));
  	      arg1 = build_function_call_expr (expfn, arglist);
! 	      return fold (build2 (MULT_EXPR, type, arg0, arg1));
  	    }

  	  /* Optimize x/pow(y,z) into x*pow(y,-z).  */
*************** fold (tree expr)
*** 6990,6996 ****
  	      tree arglist = tree_cons(NULL_TREE, arg10,
  				       build_tree_list (NULL_TREE, neg11));
  	      arg1 = build_function_call_expr (powfn, arglist);
! 	      return fold (build (MULT_EXPR, type, arg0, arg1));
  	    }
  	}

--- 7005,7011 ----
  	      tree arglist = tree_cons(NULL_TREE, arg10,
  				       build_tree_list (NULL_TREE, neg11));
  	      arg1 = build_function_call_expr (powfn, arglist);
! 	      return fold (build2 (MULT_EXPR, type, arg0, arg1));
  	    }
  	}

*************** fold (tree expr)
*** 7026,7034 ****
  		{
  		  tree tmp = TREE_OPERAND (arg0, 1);
  		  tmp = build_function_call_expr (tanfn, tmp);
! 		  return fold (build (RDIV_EXPR, type,
! 				      build_real (type, dconst1),
! 				      tmp));
  		}
  	    }

--- 7041,7048 ----
  		{
  		  tree tmp = TREE_OPERAND (arg0, 1);
  		  tmp = build_function_call_expr (tanfn, tmp);
! 		  return fold (build2 (RDIV_EXPR, type,
! 				       build_real (type, dconst1), tmp));
  		}
  	    }

*************** fold (tree expr)
*** 7082,7088 ****
  	 after the last round to changes to the DIV code in expmed.c.  */
        if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
  	  && multiple_of_p (type, arg0, arg1))
! 	return fold (build (EXACT_DIV_EXPR, type, arg0, arg1));

        if (TREE_CODE (arg1) == INTEGER_CST
  	  && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
--- 7096,7102 ----
  	 after the last round to changes to the DIV code in expmed.c.  */
        if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
  	  && multiple_of_p (type, arg0, arg1))
! 	return fold (build2 (EXACT_DIV_EXPR, type, arg0, arg1));

        if (TREE_CODE (arg1) == INTEGER_CST
  	  && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
*************** fold (tree expr)
*** 7143,7149 ****
  	  tree tem = build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0);
  	  tem = fold_convert (TREE_TYPE (arg1), tem);
  	  tem = const_binop (MINUS_EXPR, tem, arg1, 0);
! 	  return fold (build (RROTATE_EXPR, type, arg0, tem));
  	}

        /* If we have a rotate of a bit operation with the rotate count and
--- 7157,7163 ----
  	  tree tem = build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0);
  	  tem = fold_convert (TREE_TYPE (arg1), tem);
  	  tem = const_binop (MINUS_EXPR, tem, arg1, 0);
! 	  return fold (build2 (RROTATE_EXPR, type, arg0, tem));
  	}

        /* If we have a rotate of a bit operation with the rotate count and
*************** fold (tree expr)
*** 7154,7164 ****
  	      || TREE_CODE (arg0) == BIT_IOR_EXPR
  	      || TREE_CODE (arg0) == BIT_XOR_EXPR)
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
! 	return fold (build (TREE_CODE (arg0), type,
! 			    fold (build (code, type,
! 					 TREE_OPERAND (arg0, 0), arg1)),
! 			    fold (build (code, type,
! 					 TREE_OPERAND (arg0, 1), arg1))));

        /* Two consecutive rotates adding up to the width of the mode can
  	 be ignored.  */
--- 7168,7178 ----
  	      || TREE_CODE (arg0) == BIT_IOR_EXPR
  	      || TREE_CODE (arg0) == BIT_XOR_EXPR)
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
! 	return fold (build2 (TREE_CODE (arg0), type,
! 			     fold (build2 (code, type,
! 					   TREE_OPERAND (arg0, 0), arg1)),
! 			     fold (build2 (code, type,
! 					   TREE_OPERAND (arg0, 1), arg1))));

        /* Two consecutive rotates adding up to the width of the mode can
  	 be ignored.  */
*************** fold (tree expr)
*** 7259,7281 ****
  				 || code == TRUTH_OR_EXPR));

  	  if (operand_equal_p (a00, a10, 0))
! 	    return fold (build (TREE_CODE (arg0), type, a00,
! 				fold (build (code, type, a01, a11))));
  	  else if (commutative && operand_equal_p (a00, a11, 0))
! 	    return fold (build (TREE_CODE (arg0), type, a00,
! 				fold (build (code, type, a01, a10))));
  	  else if (commutative && operand_equal_p (a01, a10, 0))
! 	    return fold (build (TREE_CODE (arg0), type, a01,
! 				fold (build (code, type, a00, a11))));

  	  /* This case if tricky because we must either have commutative
  	     operators or else A10 must not have side-effects.  */

  	  else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
  		   && operand_equal_p (a01, a11, 0))
! 	    return fold (build (TREE_CODE (arg0), type,
! 				fold (build (code, type, a00, a10)),
! 				a01));
  	}

        /* See if we can build a range comparison.  */
--- 7273,7295 ----
  				 || code == TRUTH_OR_EXPR));

  	  if (operand_equal_p (a00, a10, 0))
! 	    return fold (build2 (TREE_CODE (arg0), type, a00,
! 				 fold (build2 (code, type, a01, a11))));
  	  else if (commutative && operand_equal_p (a00, a11, 0))
! 	    return fold (build2 (TREE_CODE (arg0), type, a00,
! 				 fold (build2 (code, type, a01, a10))));
  	  else if (commutative && operand_equal_p (a01, a10, 0))
! 	    return fold (build2 (TREE_CODE (arg0), type, a01,
! 				 fold (build2 (code, type, a00, a11))));

  	  /* This case if tricky because we must either have commutative
  	     operators or else A10 must not have side-effects.  */

  	  else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
  		   && operand_equal_p (a01, a11, 0))
! 	    return fold (build2 (TREE_CODE (arg0), type,
! 				 fold (build2 (code, type, a00, a10)),
! 				 a01));
  	}

        /* See if we can build a range comparison.  */
*************** fold (tree expr)
*** 7288,7294 ****
        if (TREE_CODE (arg0) == code
  	  && 0 != (tem = fold_truthop (code, type,
  				       TREE_OPERAND (arg0, 1), arg1)))
! 	return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));

        if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
  	return tem;
--- 7302,7308 ----
        if (TREE_CODE (arg0) == code
  	  && 0 != (tem = fold_truthop (code, type,
  				       TREE_OPERAND (arg0, 1), arg1)))
! 	return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));

        if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
  	return tem;
*************** fold (tree expr)
*** 7344,7350 ****
      case GE_EXPR:
        /* If one arg is a real or integer constant, put it last.  */
        if (tree_swap_operands_p (arg0, arg1, true))
! 	return fold (build (swap_tree_comparison (code), type, arg1, arg0));

        /* If this is an equality comparison of the address of a non-weak
  	 object against zero, then we know the result.  */
--- 7358,7364 ----
      case GE_EXPR:
        /* If one arg is a real or integer constant, put it last.  */
        if (tree_swap_operands_p (arg0, arg1, true))
! 	return fold (build2 (swap_tree_comparison (code), type, arg1, arg0));

        /* If this is an equality comparison of the address of a non-weak
  	 object against zero, then we know the result.  */
*************** fold (tree expr)
*** 7396,7409 ****

  	  /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
  	  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
! 	    return fold (build (code, type, fold_convert (newtype, targ0),
! 				fold_convert (newtype, targ1)));

  	  /* (-a) CMP (-b) -> b CMP a  */
  	  if (TREE_CODE (arg0) == NEGATE_EXPR
  	      && TREE_CODE (arg1) == NEGATE_EXPR)
! 	    return fold (build (code, type, TREE_OPERAND (arg1, 0),
! 				TREE_OPERAND (arg0, 0)));

  	  if (TREE_CODE (arg1) == REAL_CST)
  	  {
--- 7410,7423 ----

  	  /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
  	  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
! 	    return fold (build2 (code, type, fold_convert (newtype, targ0),
! 				 fold_convert (newtype, targ1)));

  	  /* (-a) CMP (-b) -> b CMP a  */
  	  if (TREE_CODE (arg0) == NEGATE_EXPR
  	      && TREE_CODE (arg1) == NEGATE_EXPR)
! 	    return fold (build2 (code, type, TREE_OPERAND (arg1, 0),
! 				 TREE_OPERAND (arg0, 0)));

  	  if (TREE_CODE (arg1) == REAL_CST)
  	  {
*************** fold (tree expr)
*** 7413,7428 ****
  	    /* (-a) CMP CST -> a swap(CMP) (-CST)  */
  	    if (TREE_CODE (arg0) == NEGATE_EXPR)
  	      return
! 		fold (build (swap_tree_comparison (code), type,
! 			     TREE_OPERAND (arg0, 0),
! 			     build_real (TREE_TYPE (arg1),
! 					 REAL_VALUE_NEGATE (cst))));

  	    /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
  	    /* a CMP (-0) -> a CMP 0  */
  	    if (REAL_VALUE_MINUS_ZERO (cst))
! 	      return fold (build (code, type, arg0,
! 				  build_real (TREE_TYPE (arg1), dconst0)));

  	    /* x != NaN is always true, other ops are always false.  */
  	    if (REAL_VALUE_ISNAN (cst)
--- 7427,7442 ----
  	    /* (-a) CMP CST -> a swap(CMP) (-CST)  */
  	    if (TREE_CODE (arg0) == NEGATE_EXPR)
  	      return
! 		fold (build2 (swap_tree_comparison (code), type,
! 			      TREE_OPERAND (arg0, 0),
! 			      build_real (TREE_TYPE (arg1),
! 					  REAL_VALUE_NEGATE (cst))));

  	    /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
  	    /* a CMP (-0) -> a CMP 0  */
  	    if (REAL_VALUE_MINUS_ZERO (cst))
! 	      return fold (build2 (code, type, arg0,
! 				   build_real (TREE_TYPE (arg1), dconst0)));

  	    /* x != NaN is always true, other ops are always false.  */
  	    if (REAL_VALUE_ISNAN (cst)
*************** fold (tree expr)
*** 7454,7460 ****
  					  ? MINUS_EXPR : PLUS_EXPR,
  					  arg1, TREE_OPERAND (arg0, 1), 0))
  	      && ! TREE_CONSTANT_OVERFLOW (tem))
! 	    return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));

  	  /* Likewise, we can simplify a comparison of a real constant with
  	     a MINUS_EXPR whose first operand is also a real constant, i.e.
--- 7468,7474 ----
  					  ? MINUS_EXPR : PLUS_EXPR,
  					  arg1, TREE_OPERAND (arg0, 1), 0))
  	      && ! TREE_CONSTANT_OVERFLOW (tem))
! 	    return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));

  	  /* Likewise, we can simplify a comparison of a real constant with
  	     a MINUS_EXPR whose first operand is also a real constant, i.e.
*************** fold (tree expr)
*** 7466,7473 ****
  	      && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
  					  arg1, 0))
  	      && ! TREE_CONSTANT_OVERFLOW (tem))
! 	    return fold (build (swap_tree_comparison (code), type,
! 				TREE_OPERAND (arg0, 1), tem));

  	  /* Fold comparisons against built-in math functions.  */
  	  if (TREE_CODE (arg1) == REAL_CST
--- 7480,7487 ----
  	      && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
  					  arg1, 0))
  	      && ! TREE_CONSTANT_OVERFLOW (tem))
! 	    return fold (build2 (swap_tree_comparison (code), type,
! 				 TREE_OPERAND (arg0, 1), tem));

  	  /* Fold comparisons against built-in math functions.  */
  	  if (TREE_CODE (arg1) == REAL_CST
*************** fold (tree expr)
*** 7558,7568 ****
  	    {
  	    case GE_EXPR:
  	      arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 	      return fold (build (GT_EXPR, type, arg0, arg1));

  	    case LT_EXPR:
  	      arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 	      return fold (build (LE_EXPR, type, arg0, arg1));

  	    default:
  	      break;
--- 7572,7582 ----
  	    {
  	    case GE_EXPR:
  	      arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 	      return fold (build2 (GT_EXPR, type, arg0, arg1));

  	    case LT_EXPR:
  	      arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 	      return fold (build2 (LE_EXPR, type, arg0, arg1));

  	    default:
  	      break;
*************** fold (tree expr)
*** 7610,7616 ****
  							 integer_zero_node),
  					   arg0);
  		case GE_EXPR:
! 		  return fold (build (EQ_EXPR, type, arg0, arg1));

  		case LE_EXPR:
  		  return omit_one_operand (type,
--- 7624,7630 ----
  							 integer_zero_node),
  					   arg0);
  		case GE_EXPR:
! 		  return fold (build2 (EQ_EXPR, type, arg0, arg1));

  		case LE_EXPR:
  		  return omit_one_operand (type,
*************** fold (tree expr)
*** 7618,7624 ****
  							 integer_one_node),
  					   arg0);
  		case LT_EXPR:
! 		  return fold (build (NE_EXPR, type, arg0, arg1));

  		/* The GE_EXPR and LT_EXPR cases above are not normally
  		   reached because of previous transformations.  */
--- 7632,7638 ----
  							 integer_one_node),
  					   arg0);
  		case LT_EXPR:
! 		  return fold (build2 (NE_EXPR, type, arg0, arg1));

  		/* The GE_EXPR and LT_EXPR cases above are not normally
  		   reached because of previous transformations.  */
*************** fold (tree expr)
*** 7632,7641 ****
  		{
  		case GT_EXPR:
  		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build (EQ_EXPR, type, arg0, arg1));
  		case LE_EXPR:
  		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build (NE_EXPR, type, arg0, arg1));
  		default:
  		  break;
  		}
--- 7646,7655 ----
  		{
  		case GT_EXPR:
  		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build2 (EQ_EXPR, type, arg0, arg1));
  		case LE_EXPR:
  		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build2 (NE_EXPR, type, arg0, arg1));
  		default:
  		  break;
  		}
*************** fold (tree expr)
*** 7649,7655 ****
  							 integer_zero_node),
  					   arg0);
  		case LE_EXPR:
! 		  return fold (build (EQ_EXPR, type, arg0, arg1));

  		case GE_EXPR:
  		  return omit_one_operand (type,
--- 7663,7669 ----
  							 integer_zero_node),
  					   arg0);
  		case LE_EXPR:
! 		  return fold (build2 (EQ_EXPR, type, arg0, arg1));

  		case GE_EXPR:
  		  return omit_one_operand (type,
*************** fold (tree expr)
*** 7657,7663 ****
  							 integer_one_node),
  					   arg0);
  		case GT_EXPR:
! 		  return fold (build (NE_EXPR, type, arg0, arg1));

  		default:
  		  break;
--- 7671,7677 ----
  							 integer_one_node),
  					   arg0);
  		case GT_EXPR:
! 		  return fold (build2 (NE_EXPR, type, arg0, arg1));

  		default:
  		  break;
*************** fold (tree expr)
*** 7668,7677 ****
  		{
  		case GE_EXPR:
  		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build (NE_EXPR, type, arg0, arg1));
  		case LT_EXPR:
  		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build (EQ_EXPR, type, arg0, arg1));
  		default:
  		  break;
  		}
--- 7682,7691 ----
  		{
  		case GE_EXPR:
  		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build2 (NE_EXPR, type, arg0, arg1));
  		case LT_EXPR:
  		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
! 		  return fold (build2 (EQ_EXPR, type, arg0, arg1));
  		default:
  		  break;
  		}
*************** fold (tree expr)
*** 7691,7699 ****
  		    st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
  		    st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
  		    return fold
! 		      (build (code == LE_EXPR ? GE_EXPR: LT_EXPR,
! 			      type, fold_convert (st0, arg0),
! 			      fold_convert (st1, integer_zero_node)));
  		  }
  	      }
  	  }
--- 7705,7713 ----
  		    st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
  		    st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
  		    return fold
! 		      (build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
! 			       type, fold_convert (st0, arg0),
! 			       fold_convert (st1, integer_zero_node)));
  		  }
  	      }
  	  }
*************** fold (tree expr)
*** 7711,7717 ****
  				      ? MINUS_EXPR : PLUS_EXPR,
  				      arg1, TREE_OPERAND (arg0, 1), 0))
  	  && ! TREE_CONSTANT_OVERFLOW (tem))
! 	return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));

        /* Similarly for a NEGATE_EXPR.  */
        else if ((code == EQ_EXPR || code == NE_EXPR)
--- 7725,7731 ----
  				      ? MINUS_EXPR : PLUS_EXPR,
  				      arg1, TREE_OPERAND (arg0, 1), 0))
  	  && ! TREE_CONSTANT_OVERFLOW (tem))
! 	return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));

        /* Similarly for a NEGATE_EXPR.  */
        else if ((code == EQ_EXPR || code == NE_EXPR)
*************** fold (tree expr)
*** 7720,7733 ****
  	       && 0 != (tem = negate_expr (arg1))
  	       && TREE_CODE (tem) == INTEGER_CST
  	       && ! TREE_CONSTANT_OVERFLOW (tem))
! 	return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));

        /* If we have X - Y == 0, we can convert that to X == Y and similarly
  	 for !=.  Don't do this for ordered comparisons due to overflow.  */
        else if ((code == NE_EXPR || code == EQ_EXPR)
  	       && integer_zerop (arg1) && TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build (code, type,
! 			    TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)));

        /* If we are widening one operand of an integer comparison,
  	 see if the other operand is similarly being widened.  Perhaps we
--- 7734,7747 ----
  	       && 0 != (tem = negate_expr (arg1))
  	       && TREE_CODE (tem) == INTEGER_CST
  	       && ! TREE_CONSTANT_OVERFLOW (tem))
! 	return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));

        /* If we have X - Y == 0, we can convert that to X == Y and similarly
  	 for !=.  Don't do this for ordered comparisons due to overflow.  */
        else if ((code == NE_EXPR || code == EQ_EXPR)
  	       && integer_zerop (arg1) && TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build2 (code, type,
! 			     TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)));

        /* If we are widening one operand of an integer comparison,
  	 see if the other operand is similarly being widened.  Perhaps we
*************** fold (tree expr)
*** 7742,7749 ****
  	       && (TREE_TYPE (t1) == TREE_TYPE (tem)
  		   || (TREE_CODE (t1) == INTEGER_CST
  		       && int_fits_type_p (t1, TREE_TYPE (tem)))))
! 	return fold (build (code, type, tem,
! 			    fold_convert (TREE_TYPE (tem), t1)));

        /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
  	 constant, we can simplify it.  */
--- 7756,7763 ----
  	       && (TREE_TYPE (t1) == TREE_TYPE (tem)
  		   || (TREE_CODE (t1) == INTEGER_CST
  		       && int_fits_type_p (t1, TREE_TYPE (tem)))))
! 	return fold (build2 (code, type, tem,
! 			     fold_convert (TREE_TYPE (tem), t1)));

        /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
  	 constant, we can simplify it.  */
*************** fold (tree expr)
*** 7764,7773 ****
  	       && (0 != (tem = negate_expr (arg1)))
  	       && TREE_CODE (tem) == INTEGER_CST
  	       && ! TREE_CONSTANT_OVERFLOW (tem))
! 	return fold (build (TRUTH_ANDIF_EXPR, type,
! 			    build (GE_EXPR, type, TREE_OPERAND (arg0, 0), tem),
! 			    build (LE_EXPR, type,
! 				   TREE_OPERAND (arg0, 0), arg1)));

        /* If this is an EQ or NE comparison with zero and ARG0 is
  	 (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
--- 7778,7788 ----
  	       && (0 != (tem = negate_expr (arg1)))
  	       && TREE_CODE (tem) == INTEGER_CST
  	       && ! TREE_CONSTANT_OVERFLOW (tem))
! 	return fold (build2 (TRUTH_ANDIF_EXPR, type,
! 			     build2 (GE_EXPR, type,
! 				     TREE_OPERAND (arg0, 0), tem),
! 			     build2 (LE_EXPR, type,
! 				     TREE_OPERAND (arg0, 0), arg1)));

        /* If this is an EQ or NE comparison with zero and ARG0 is
  	 (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
*************** fold (tree expr)
*** 7777,7806 ****
        if (integer_zerop (arg1) && (code == EQ_EXPR || code == NE_EXPR)
  	  && TREE_CODE (arg0) == BIT_AND_EXPR)
  	{
! 	  if (TREE_CODE (TREE_OPERAND (arg0, 0)) == LSHIFT_EXPR
! 	      && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 0), 0)))
  	    return
! 	      fold (build (code, type,
! 			   build (BIT_AND_EXPR, TREE_TYPE (arg0),
! 				  build (RSHIFT_EXPR,
! 					 TREE_TYPE (TREE_OPERAND (arg0, 0)),
! 					 TREE_OPERAND (arg0, 1),
! 					 TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)),
! 				  fold_convert (TREE_TYPE (arg0),
! 						integer_one_node)),
! 			   arg1));
  	  else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
  		   && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
  	    return
! 	      fold (build (code, type,
! 			   build (BIT_AND_EXPR, TREE_TYPE (arg0),
! 				  build (RSHIFT_EXPR,
! 					 TREE_TYPE (TREE_OPERAND (arg0, 1)),
! 					 TREE_OPERAND (arg0, 0),
! 					 TREE_OPERAND (TREE_OPERAND (arg0, 1), 1)),
! 				  fold_convert (TREE_TYPE (arg0),
! 						integer_one_node)),
! 			   arg1));
  	}

        /* If this is an NE or EQ comparison of zero against the result of a
--- 7792,7819 ----
        if (integer_zerop (arg1) && (code == EQ_EXPR || code == NE_EXPR)
  	  && TREE_CODE (arg0) == BIT_AND_EXPR)
  	{
! 	  tree arg00 = TREE_OPERAND (arg0, 0);
! 	  tree arg01 = TREE_OPERAND (arg0, 1);
! 	  if (TREE_CODE (arg00) == LSHIFT_EXPR
! 	      && integer_onep (TREE_OPERAND (arg00, 0)))
  	    return
! 	      fold (build2 (code, type,
! 			    build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
! 				    build2 (RSHIFT_EXPR, TREE_TYPE (arg00),
! 					    arg01, TREE_OPERAND (arg00, 1)),
! 				    fold_convert (TREE_TYPE (arg0),
! 						  integer_one_node)),
! 			    arg1));
  	  else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
  		   && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
  	    return
! 	      fold (build2 (code, type,
! 			    build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
! 				    build2 (RSHIFT_EXPR, TREE_TYPE (arg01),
! 					    arg00, TREE_OPERAND (arg01, 1)),
! 				    fold_convert (TREE_TYPE (arg0),
! 						  integer_one_node)),
! 			    arg1));
  	}

        /* If this is an NE or EQ comparison of zero against the result of a
*************** fold (tree expr)
*** 7816,7828 ****
  	  && integer_pow2p (TREE_OPERAND (arg0, 1)))
  	{
  	  tree newtype = lang_hooks.types.unsigned_type (TREE_TYPE (arg0));
! 	  tree newmod = build (TREE_CODE (arg0), newtype,
! 			       fold_convert (newtype,
! 					     TREE_OPERAND (arg0, 0)),
! 			       fold_convert (newtype,
! 					     TREE_OPERAND (arg0, 1)));

! 	  return build (code, type, newmod, fold_convert (newtype, arg1));
  	}

        /* If this is an NE comparison of zero with an AND of one, remove the
--- 7829,7841 ----
  	  && integer_pow2p (TREE_OPERAND (arg0, 1)))
  	{
  	  tree newtype = lang_hooks.types.unsigned_type (TREE_TYPE (arg0));
! 	  tree newmod = build2 (TREE_CODE (arg0), newtype,
! 				fold_convert (newtype,
! 					      TREE_OPERAND (arg0, 0)),
! 				fold_convert (newtype,
! 					      TREE_OPERAND (arg0, 1)));

! 	  return build2 (code, type, newmod, fold_convert (newtype, arg1));
  	}

        /* If this is an NE comparison of zero with an AND of one, remove the
*************** fold (tree expr)
*** 7838,7845 ****
  	  && TREE_CODE (arg0) == BIT_AND_EXPR
  	  && integer_pow2p (TREE_OPERAND (arg0, 1))
  	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
! 	return fold (build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
! 			    arg0, integer_zero_node));

        /* If we have (A & C) != 0 or (A & C) == 0 and C is a power of
  	 2, then fold the expression into shifts and logical operations.  */
--- 7851,7858 ----
  	  && TREE_CODE (arg0) == BIT_AND_EXPR
  	  && integer_pow2p (TREE_OPERAND (arg0, 1))
  	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
! 	return fold (build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
! 			     arg0, integer_zero_node));

        /* If we have (A & C) != 0 or (A & C) == 0 and C is a power of
  	 2, then fold the expression into shifts and logical operations.  */
*************** fold (tree expr)
*** 7855,7864 ****
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
  	{
  	  tree dandnotc
! 	    = fold (build (BIT_AND_EXPR, TREE_TYPE (arg0),
! 			   arg1, build1 (BIT_NOT_EXPR,
! 					 TREE_TYPE (TREE_OPERAND (arg0, 1)),
! 					 TREE_OPERAND (arg0, 1))));
  	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
  	  if (integer_nonzerop (dandnotc))
  	    return omit_one_operand (type, rslt, arg0);
--- 7868,7877 ----
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
  	{
  	  tree dandnotc
! 	    = fold (build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
! 			    arg1, build1 (BIT_NOT_EXPR,
! 					  TREE_TYPE (TREE_OPERAND (arg0, 1)),
! 					  TREE_OPERAND (arg0, 1))));
  	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
  	  if (integer_nonzerop (dandnotc))
  	    return omit_one_operand (type, rslt, arg0);
*************** fold (tree expr)
*** 7872,7880 ****
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
  	{
  	  tree candnotd
! 	    = fold (build (BIT_AND_EXPR, TREE_TYPE (arg0),
! 			   TREE_OPERAND (arg0, 1),
! 			   build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1)));
  	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
  	  if (integer_nonzerop (candnotd))
  	    return omit_one_operand (type, rslt, arg0);
--- 7885,7893 ----
  	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
  	{
  	  tree candnotd
! 	    = fold (build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
! 			    TREE_OPERAND (arg0, 1),
! 			    build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1)));
  	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
  	  if (integer_nonzerop (candnotd))
  	    return omit_one_operand (type, rslt, arg0);
*************** fold (tree expr)
*** 7886,7895 ****
  	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
  	  && TREE_CODE (arg1) == LSHIFT_EXPR
  	  && integer_onep (TREE_OPERAND (arg1, 0)))
! 	return build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
! 		      build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
! 			     TREE_OPERAND (arg1, 1)),
! 		      fold_convert (TREE_TYPE (arg0), integer_zero_node));

        else if ((code == LT_EXPR || code == GE_EXPR)
  	       && TYPE_UNSIGNED (TREE_TYPE (arg0))
--- 7899,7908 ----
  	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
  	  && TREE_CODE (arg1) == LSHIFT_EXPR
  	  && integer_onep (TREE_OPERAND (arg1, 0)))
! 	return build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
! 		       build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
! 			       TREE_OPERAND (arg1, 1)),
! 		       fold_convert (TREE_TYPE (arg0), integer_zero_node));

        else if ((code == LT_EXPR || code == GE_EXPR)
  	       && TYPE_UNSIGNED (TREE_TYPE (arg0))
*************** fold (tree expr)
*** 7898,7909 ****
  	       && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
  	       && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
  	return
! 	  build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
! 		 fold_convert (TREE_TYPE (arg0),
! 			       build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
! 				      TREE_OPERAND (TREE_OPERAND (arg1, 0),
! 						    1))),
! 		 fold_convert (TREE_TYPE (arg0), integer_zero_node));

        /* Simplify comparison of something with itself.  (For IEEE
  	 floating-point, we can only do some of these simplifications.)  */
--- 7911,7922 ----
  	       && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
  	       && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
  	return
! 	  build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
! 		  fold_convert (TREE_TYPE (arg0),
! 				build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
! 					TREE_OPERAND (TREE_OPERAND (arg1, 0),
! 						      1))),
! 		  fold_convert (TREE_TYPE (arg0), integer_zero_node));

        /* Simplify comparison of something with itself.  (For IEEE
  	 floating-point, we can only do some of these simplifications.)  */
*************** fold (tree expr)
*** 7922,7928 ****
  	      if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
  		  || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
  		return constant_boolean_node (1, type);
! 	      return fold (build (EQ_EXPR, type, arg0, arg1));

  	    case NE_EXPR:
  	      /* For NE, we can only do this simplification if integer
--- 7935,7941 ----
  	      if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
  		  || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
  		return constant_boolean_node (1, type);
! 	      return fold (build2 (EQ_EXPR, type, arg0, arg1));

  	    case NE_EXPR:
  	      /* For NE, we can only do this simplification if integer
*************** fold (tree expr)
*** 7976,7992 ****
  		 was the same as ARG1.  */

  	      tree high_result
! 		= fold (build (code, type,
! 			       eval_subst (arg0, cval1, maxval, cval2, minval),
! 			       arg1));
  	      tree equal_result
! 		= fold (build (code, type,
! 			       eval_subst (arg0, cval1, maxval, cval2, maxval),
! 			       arg1));
  	      tree low_result
! 		= fold (build (code, type,
! 			       eval_subst (arg0, cval1, minval, cval2, maxval),
! 			       arg1));

  	      /* All three of these results should be 0 or 1.  Confirm they
  		 are.  Then use those values to select the proper code
--- 7989,8008 ----
  		 was the same as ARG1.  */

  	      tree high_result
! 		= fold (build2 (code, type,
! 				eval_subst (arg0, cval1, maxval,
! 					    cval2, minval),
! 				arg1));
  	      tree equal_result
! 		= fold (build2 (code, type,
! 				eval_subst (arg0, cval1, maxval,
! 					    cval2, maxval),
! 				arg1));
  	      tree low_result
! 		= fold (build2 (code, type,
! 				eval_subst (arg0, cval1, minval,
! 					    cval2, maxval),
! 				arg1));

  	      /* All three of these results should be 0 or 1.  Confirm they
  		 are.  Then use those values to select the proper code
*************** fold (tree expr)
*** 8031,8037 ****
  		      return omit_one_operand (type, integer_one_node, arg0);
  		    }

! 		  tem = build (code, type, cval1, cval2);
  		  if (save_p)
  		    return save_expr (tem);
  		  else
--- 8047,8053 ----
  		      return omit_one_operand (type, integer_one_node, arg0);
  		    }

! 		  tem = build2 (code, type, cval1, cval2);
  		  if (save_p)
  		    return save_expr (tem);
  		  else
*************** fold (tree expr)
*** 8075,8085 ****
  	  real1 = fold (build1 (REALPART_EXPR, subtype, arg1));
  	  imag1 = fold (build1 (IMAGPART_EXPR, subtype, arg1));

! 	  return fold (build ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
! 			       : TRUTH_ORIF_EXPR),
! 			      type,
! 			      fold (build (code, type, real0, real1)),
! 			      fold (build (code, type, imag0, imag1))));
  	}

        /* Optimize comparisons of strlen vs zero to a compare of the
--- 8091,8101 ----
  	  real1 = fold (build1 (REALPART_EXPR, subtype, arg1));
  	  imag1 = fold (build1 (IMAGPART_EXPR, subtype, arg1));

! 	  return fold (build2 ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
! 				: TRUTH_ORIF_EXPR),
! 			       type,
! 			       fold (build2 (code, type, real0, real1)),
! 			       fold (build2 (code, type, imag0, imag1))));
  	}

        /* Optimize comparisons of strlen vs zero to a compare of the
*************** fold (tree expr)
*** 8102,8111 ****
  	      && (arglist = TREE_OPERAND (arg0, 1))
  	      && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
  	      && ! TREE_CHAIN (arglist))
! 	    return fold (build (code, type,
! 				build1 (INDIRECT_REF, char_type_node,
! 					TREE_VALUE(arglist)),
! 				integer_zero_node));
  	}

        /* We can fold X/C1 op C2 where C1 and C2 are integer constants
--- 8118,8127 ----
  	      && (arglist = TREE_OPERAND (arg0, 1))
  	      && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
  	      && ! TREE_CHAIN (arglist))
! 	    return fold (build2 (code, type,
! 				 build1 (INDIRECT_REF, char_type_node,
! 					 TREE_VALUE(arglist)),
! 				 integer_zero_node));
  	}

        /* We can fold X/C1 op C2 where C1 and C2 are integer constants
*************** fold (tree expr)
*** 8277,8297 ****
  		     corresponding COND_EXPR.  */
  		  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
  		    return pedantic_non_lvalue (fold_convert
! 		      (type, fold (build (MIN_EXPR, comp_type,
! 					  (comp_code == LE_EXPR
! 					   ? comp_op0 : comp_op1),
! 					  (comp_code == LE_EXPR
! 					   ? comp_op1 : comp_op0)))));
  		  break;
  		case GE_EXPR:
  		case GT_EXPR:
  		  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
  		    return pedantic_non_lvalue (fold_convert
! 		      (type, fold (build (MAX_EXPR, comp_type,
! 					  (comp_code == GE_EXPR
! 					   ? comp_op0 : comp_op1),
! 					  (comp_code == GE_EXPR
! 					   ? comp_op1 : comp_op0)))));
  		  break;
  		default:
  		  abort ();
--- 8293,8313 ----
  		     corresponding COND_EXPR.  */
  		  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
  		    return pedantic_non_lvalue (fold_convert
! 		      (type, fold (build2 (MIN_EXPR, comp_type,
! 					   (comp_code == LE_EXPR
! 					    ? comp_op0 : comp_op1),
! 					   (comp_code == LE_EXPR
! 					    ? comp_op1 : comp_op0)))));
  		  break;
  		case GE_EXPR:
  		case GT_EXPR:
  		  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
  		    return pedantic_non_lvalue (fold_convert
! 		      (type, fold (build2 (MAX_EXPR, comp_type,
! 					   (comp_code == GE_EXPR
! 					    ? comp_op0 : comp_op1),
! 					   (comp_code == GE_EXPR
! 					    ? comp_op1 : comp_op0)))));
  		  break;
  		default:
  		  abort ();
*************** fold (tree expr)
*** 8312,8319 ****
  	      case EQ_EXPR:
  		/* We can replace A with C1 in this case.  */
  		arg1 = fold_convert (type, TREE_OPERAND (arg0, 1));
! 		return fold (build (code, type, TREE_OPERAND (t, 0), arg1,
! 				    TREE_OPERAND (t, 2)));

  	      case LT_EXPR:
  		/* If C1 is C2 + 1, this is min(A, C2).  */
--- 8328,8335 ----
  	      case EQ_EXPR:
  		/* We can replace A with C1 in this case.  */
  		arg1 = fold_convert (type, TREE_OPERAND (arg0, 1));
! 		return fold (build3 (code, type, TREE_OPERAND (t, 0), arg1,
! 				     TREE_OPERAND (t, 2)));

  	      case LT_EXPR:
  		/* If C1 is C2 + 1, this is min(A, C2).  */
*************** fold (tree expr)
*** 8324,8330 ****
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build (MIN_EXPR, type, arg1, arg2)));
  		break;

  	      case LE_EXPR:
--- 8340,8346 ----
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build2 (MIN_EXPR, type, arg1, arg2)));
  		break;

  	      case LE_EXPR:
*************** fold (tree expr)
*** 8336,8342 ****
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build (MIN_EXPR, type, arg1, arg2)));
  		break;

  	      case GT_EXPR:
--- 8352,8358 ----
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build2 (MIN_EXPR, type, arg1, arg2)));
  		break;

  	      case GT_EXPR:
*************** fold (tree expr)
*** 8348,8354 ****
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build (MAX_EXPR, type, arg1, arg2)));
  		break;

  	      case GE_EXPR:
--- 8364,8370 ----
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build2 (MAX_EXPR, type, arg1, arg2)));
  		break;

  	      case GE_EXPR:
*************** fold (tree expr)
*** 8360,8366 ****
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build (MAX_EXPR, type, arg1, arg2)));
  		break;
  	      case NE_EXPR:
  		break;
--- 8376,8382 ----
  						     integer_one_node, 0),
  					OEP_ONLY_CONST))
  		  return pedantic_non_lvalue
! 		    (fold (build2 (MAX_EXPR, type, arg1, arg2)));
  		break;
  	      case NE_EXPR:
  		break;
*************** fold (tree expr)
*** 8380,8387 ****
  	  tem = invert_truthvalue (arg0);

  	  if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
! 	    return fold (build (code, type, tem,
! 			 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
  	}

        /* Convert A ? 1 : 0 to simply A.  */
--- 8396,8403 ----
  	  tem = invert_truthvalue (arg0);

  	  if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
! 	    return fold (build3 (code, type, tem,
! 				 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
  	}

        /* Convert A ? 1 : 0 to simply A.  */
*************** fold (tree expr)
*** 8419,8426 ****
        if (integer_zerop (TREE_OPERAND (t, 2))
  	  && truth_value_p (TREE_CODE (arg0))
  	  && truth_value_p (TREE_CODE (arg1)))
! 	return pedantic_non_lvalue (fold (build (TRUTH_ANDIF_EXPR, type,
! 						 arg0, arg1)));

        /* Convert A ? B : 1 into !A || B if A and B are truth values.  */
        if (integer_onep (TREE_OPERAND (t, 2))
--- 8435,8442 ----
        if (integer_zerop (TREE_OPERAND (t, 2))
  	  && truth_value_p (TREE_CODE (arg0))
  	  && truth_value_p (TREE_CODE (arg1)))
! 	return pedantic_non_lvalue (fold (build2 (TRUTH_ANDIF_EXPR, type,
! 						  arg0, arg1)));

        /* Convert A ? B : 1 into !A || B if A and B are truth values.  */
        if (integer_onep (TREE_OPERAND (t, 2))
*************** fold (tree expr)
*** 8430,8437 ****
  	  /* Only perform transformation if ARG0 is easily inverted.  */
  	  tem = invert_truthvalue (arg0);
  	  if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
! 	    return pedantic_non_lvalue (fold (build (TRUTH_ORIF_EXPR, type,
! 						     tem, arg1)));
  	}

        return t;
--- 8446,8453 ----
  	  /* Only perform transformation if ARG0 is easily inverted.  */
  	  tem = invert_truthvalue (arg0);
  	  if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
! 	    return pedantic_non_lvalue (fold (build2 (TRUTH_ORIF_EXPR, type,
! 						      tem, arg1)));
  	}

        return t;
*************** fold (tree expr)
*** 8460,8470 ****
        else if (TREE_CODE (arg0) == COMPLEX_CST)
  	return TREE_REALPART (arg0);
        else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build (TREE_CODE (arg0), type,
! 			    fold (build1 (REALPART_EXPR, type,
! 					  TREE_OPERAND (arg0, 0))),
! 			    fold (build1 (REALPART_EXPR,
! 					  type, TREE_OPERAND (arg0, 1)))));
        return t;

      case IMAGPART_EXPR:
--- 8476,8486 ----
        else if (TREE_CODE (arg0) == COMPLEX_CST)
  	return TREE_REALPART (arg0);
        else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build2 (TREE_CODE (arg0), type,
! 			     fold (build1 (REALPART_EXPR, type,
! 					   TREE_OPERAND (arg0, 0))),
! 			     fold (build1 (REALPART_EXPR, type,
! 					   TREE_OPERAND (arg0, 1)))));
        return t;

      case IMAGPART_EXPR:
*************** fold (tree expr)
*** 8476,8486 ****
        else if (TREE_CODE (arg0) == COMPLEX_CST)
  	return TREE_IMAGPART (arg0);
        else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build (TREE_CODE (arg0), type,
! 			    fold (build1 (IMAGPART_EXPR, type,
! 					  TREE_OPERAND (arg0, 0))),
! 			    fold (build1 (IMAGPART_EXPR, type,
! 					  TREE_OPERAND (arg0, 1)))));
        return t;

        /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where
--- 8492,8502 ----
        else if (TREE_CODE (arg0) == COMPLEX_CST)
  	return TREE_IMAGPART (arg0);
        else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
! 	return fold (build2 (TREE_CODE (arg0), type,
! 			     fold (build1 (IMAGPART_EXPR, type,
! 					   TREE_OPERAND (arg0, 0))),
! 			     fold (build1 (IMAGPART_EXPR, type,
! 					   TREE_OPERAND (arg0, 1)))));
        return t;

        /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where
*************** fold (tree expr)
*** 8510,8524 ****
  	    if (TREE_CONSTANT (arg00)
  		|| ((code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR)
  		    && ! has_cleanups (arg00)))
! 	      return fold (build (code0, type, arg00,
! 				  fold (build1 (CLEANUP_POINT_EXPR,
! 						TREE_TYPE (arg01), arg01))));

  	    if (TREE_CONSTANT (arg01))
! 	      return fold (build (code0, type,
! 				  fold (build1 (CLEANUP_POINT_EXPR,
! 						TREE_TYPE (arg00), arg00)),
! 				  arg01));
  	  }

  	return t;
--- 8526,8540 ----
  	    if (TREE_CONSTANT (arg00)
  		|| ((code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR)
  		    && ! has_cleanups (arg00)))
! 	      return fold (build2 (code0, type, arg00,
! 				   fold (build1 (CLEANUP_POINT_EXPR,
! 						 TREE_TYPE (arg01), arg01))));

  	    if (TREE_CONSTANT (arg01))
! 	      return fold (build2 (code0, type,
! 				   fold (build1 (CLEANUP_POINT_EXPR,
! 						 TREE_TYPE (arg00), arg00)),
! 				   arg01));
  	  }

  	return t;
*************** fold_relational_hi_lo (enum tree_code *c
*** 9375,9384 ****
  	      st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (op0));
  	      st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (op1));

! 	      exp = build (code == LE_EXPR ? GE_EXPR: LT_EXPR,
! 			   type,
! 			   convert (st0, op0),
! 			   convert (st1, integer_zero_node));

  	      retval
  		= nondestructive_fold_binary_to_constant (TREE_CODE (exp),
--- 9391,9400 ----
  	      st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (op0));
  	      st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (op1));

! 	      exp = build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
! 			    type,
! 			    convert (st0, op0),
! 			    convert (st1, integer_zero_node));

  	      retval
  		= nondestructive_fold_binary_to_constant (TREE_CODE (exp),
*************** nondestructive_fold_binary_to_constant (
*** 9465,9472 ****
  		      == ADDR_EXPR)))
  	  && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
  	{
!           return build (PLUS_EXPR, type, TREE_OPERAND (op0, 0),
! 			const_binop (PLUS_EXPR, op1, TREE_OPERAND (op0, 1), 0));
  	}
      case BIT_XOR_EXPR:

--- 9481,9489 ----
  		      == ADDR_EXPR)))
  	  && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
  	{
!           return build2 (PLUS_EXPR, type, TREE_OPERAND (op0, 0),
! 			 const_binop (PLUS_EXPR, op1,
! 				      TREE_OPERAND (op0, 1), 0));
  	}
      case BIT_XOR_EXPR:



Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]