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] Force predicates into separate GIMPLE_ASSIGNs


This is a more complete patch to transition GIMPLE to require
gimple vals for GIMPLE_COND and COND_EXPR predicates.  That
unifies code-paths in several optimization passes and makes
the value-numberer able to track the predicate computations
(and PRE to mark jump-threading opportunities by PHI node
insertion for partially redundant predicates ...).

There is still a lot of fallout, mostly in poorly maintained
passes which accumulated a lot of hacks (autopar - ick).
Also some passes do not like separating predicates too much
(like the vectorizer, which can't vectorize pred = A CMP B, sth
that needs some re-org).

The patch bootstraps on x86_64-unknown-linux-gnu if you disable
-Werror (there is one uninitialized variable warning in ira-color.c),
testing shows issues with autopar (ICEs) and the vectorizer mostly.

I'm not sure what to do about this at this point, given that
stage1 is nearing its end and I still have some MEM_REF-related
IL changes pending.  So this will probably be postponed for 4.7
(and eventually split up to tackle the simpler COND_EXPR part
separately).

Richard.

2010-08-30  Richard Guenther  <rguenther@suse.de>

	* gimplify.c (gimplify_pure_cond_expr): Require is_gimple_val
	for the predicate.
	(gimplify_cond_expr): Likewise.
	...

Index: trunk/gcc/cfgloopmanip.c
===================================================================
*** trunk.orig/gcc/cfgloopmanip.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/cfgloopmanip.c	2010-08-30 14:32:23.000000000 +0200
*************** create_empty_if_region_on_edge (edge ent
*** 547,553 ****
    simple_cond =
      force_gimple_operand_gsi (&gsi, condition, true, NULL,
  			      false, GSI_NEW_STMT);
!   cond_stmt = gimple_build_cond_from_tree (simple_cond, NULL_TREE, NULL_TREE);
    gsi = gsi_last_bb (cond_bb);
    gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
  
--- 547,553 ----
    simple_cond =
      force_gimple_operand_gsi (&gsi, condition, true, NULL,
  			      false, GSI_NEW_STMT);
!   cond_stmt = gimple_build_cond (simple_cond, NULL_TREE, NULL_TREE);
    gsi = gsi_last_bb (cond_bb);
    gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
  
*************** create_empty_loop_on_edge (edge entry_ed
*** 681,693 ****
  	     iv_before, iv_after);
  
    /* Insert loop exit condition.  */
!   cond_expr = gimple_build_cond
!     (LT_EXPR, *iv_before, upper_bound, NULL_TREE, NULL_TREE);
! 
!   exit_test = gimple_cond_lhs (cond_expr);
    exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL,
  					false, GSI_NEW_STMT);
!   gimple_cond_set_lhs (cond_expr, exit_test);
    gsi = gsi_last_bb (exit_e->src);
    gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT);
  
--- 681,691 ----
  	     iv_before, iv_after);
  
    /* Insert loop exit condition.  */
!   exit_test = fold_build2 (LT_EXPR, boolean_type_node, *iv_before, upper_bound);
    exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL,
  					false, GSI_NEW_STMT);
!   cond_expr = gimple_build_cond (exit_test, NULL_TREE, NULL_TREE);
! 
    gsi = gsi_last_bb (exit_e->src);
    gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT);
  
Index: trunk/gcc/gimple.c
===================================================================
*** trunk.orig/gcc/gimple.c	2010-08-25 14:47:45.000000000 +0200
--- trunk/gcc/gimple.c	2010-08-30 15:11:34.000000000 +0200
*************** gimplify_assign (tree dst, tree src, gim
*** 417,499 ****
  
  /* Build a GIMPLE_COND statement.
  
!    PRED is the condition used to compare LHS and the RHS.
     T_LABEL is the label to jump to if the condition is true.
     F_LABEL is the label to jump to otherwise.  */
  
  gimple
! gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
! 		   tree t_label, tree f_label)
  {
    gimple p;
  
!   gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
!   p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4);
!   gimple_cond_set_lhs (p, lhs);
!   gimple_cond_set_rhs (p, rhs);
    gimple_cond_set_true_label (p, t_label);
    gimple_cond_set_false_label (p, f_label);
    return p;
  }
  
! 
! /* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND.  */
  
  void
! gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p,
!                                tree *lhs_p, tree *rhs_p)
  {
!   location_t loc = EXPR_LOCATION (cond);
!   gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison
! 	      || TREE_CODE (cond) == TRUTH_NOT_EXPR
! 	      || is_gimple_min_invariant (cond)
! 	      || SSA_VAR_P (cond));
! 
!   extract_ops_from_tree (cond, code_p, lhs_p, rhs_p);
! 
!   /* Canonicalize conditionals of the form 'if (!VAL)'.  */
!   if (*code_p == TRUTH_NOT_EXPR)
!     {
!       *code_p = EQ_EXPR;
!       gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
!       *rhs_p = fold_convert_loc (loc, TREE_TYPE (*lhs_p), integer_zero_node);
!     }
!   /* Canonicalize conditionals of the form 'if (VAL)'  */
!   else if (TREE_CODE_CLASS (*code_p) != tcc_comparison)
      {
!       *code_p = NE_EXPR;
!       gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
!       *rhs_p = fold_convert_loc (loc, TREE_TYPE (*lhs_p), integer_zero_node);
      }
  }
  
  
! /* Build a GIMPLE_COND statement from the conditional expression tree
!    COND.  T_LABEL and F_LABEL are as in gimple_build_cond.  */
  
! gimple
! gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
  {
    enum tree_code code;
    tree lhs, rhs;
! 
!   gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
!   return gimple_build_cond (code, lhs, rhs, t_label, f_label);
  }
  
! /* Set code, lhs, and rhs of a GIMPLE_COND from a suitable
!    boolean expression tree COND.  */
  
  void
! gimple_cond_set_condition_from_tree (gimple stmt, tree cond)
  {
!   enum tree_code code;
!   tree lhs, rhs;
! 
!   gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
!   gimple_cond_set_condition (stmt, code, lhs, rhs);
  }
  
  /* Build a GIMPLE_LABEL statement for LABEL.  */
  
  gimple
--- 417,550 ----
  
  /* Build a GIMPLE_COND statement.
  
!    PRED is the boolean predicate.
     T_LABEL is the label to jump to if the condition is true.
     F_LABEL is the label to jump to otherwise.  */
  
  gimple
! gimple_build_cond (tree pred, tree t_label, tree f_label)
  {
    gimple p;
  
!   gcc_assert (is_gimple_val (pred));
!   p = gimple_build_with_ops (GIMPLE_COND, ERROR_MARK, 3);
!   gimple_cond_set_pred (p, pred);
    gimple_cond_set_true_label (p, t_label);
    gimple_cond_set_false_label (p, f_label);
    return p;
  }
  
! /* From a SSA name predicate PRED extract a comparison
!    *LHS *CODE *RHS that defines it.  */
  
  void
! gimple_pred_extract_comparison (tree pred, enum tree_code *code,
! 				tree *lhs, tree *rhs)
  {
! restart:
!   if (TREE_CODE (pred) == SSA_NAME)
      {
!       gimple def_stmt = SSA_NAME_DEF_STMT (pred);
!       if (is_gimple_assign (def_stmt))
! 	{
! 	  enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
! 	  if (def_code == SSA_NAME)
! 	    {
! 	      pred = gimple_assign_rhs1 (def_stmt);
! 	      goto restart;
! 	    }
! 	  else if (def_code == TRUTH_NOT_EXPR)
! 	    {
! 	      *code = EQ_EXPR;
! 	      *lhs = gimple_assign_rhs1 (def_stmt);
! 	      *rhs = boolean_false_node;
! 	      return;
! 	    }
! 	  else if (TREE_CODE_CLASS (def_code) == tcc_comparison)
! 	    {
! 	      *code = def_code;
! 	      *lhs = gimple_assign_rhs1 (def_stmt);
! 	      *rhs = gimple_assign_rhs2 (def_stmt);
! 	      return;
! 	    }
! 	  else if (CONVERT_EXPR_CODE_P (def_code))
! 	    {
! 	      *code = NE_EXPR;
! 	      *lhs = gimple_assign_rhs1 (def_stmt);
! 	      *rhs = build_int_cst (TREE_TYPE (*lhs), 0);
! 	      return;
! 	    }
! 	}
      }
+ 
+   *code = NE_EXPR;
+   *lhs = pred;
+   *rhs = boolean_false_node;
  }
  
+ /* From the gimple conditional statement COND extract a comparison
+    *LHS *CODE *RHS that defines its predicate.  */
  
! void
! gimple_cond_extract_comparison (gimple cond, enum tree_code *code,
! 				tree *lhs, tree *rhs)
! {
!   gimple_pred_extract_comparison (gimple_cond_pred (cond), code, lhs, rhs);
! }
  
! /* From the gimple conditional statement COND extract a comparison
!    that defines its predicate and return it as a tree.  */
! 
! tree
! gimple_cond_to_tree (gimple cond)
  {
    enum tree_code code;
    tree lhs, rhs;
!   gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
!   return fold_build2_loc (gimple_location (cond),
! 			  code, boolean_type_node, lhs, rhs);
  }
  
! /* Update the gimple conditional statement at GSI to use the
!    predicate computed by the comparison LHS CODE RHS.  */
  
  void
! gimple_update_cond_from_comparison (gimple_stmt_iterator gsi,
! 				    enum tree_code code, tree lhs, tree rhs)
  {
!   gimple cond = gsi_stmt (gsi);
!   tree pred = gimple_cond_pred (cond);
!   gimple pred_stmt;
!   if (TREE_CODE (pred) == SSA_NAME
!       && has_single_use (pred))
!     {
!       gimple def_stmt = SSA_NAME_DEF_STMT (pred);
!       if (is_gimple_assign (def_stmt)
! 	  && (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
! 	      == tcc_comparison))
! 	{
! 	  gimple_assign_set_rhs_code (def_stmt, code);
! 	  gimple_assign_set_rhs1 (def_stmt, lhs);
! 	  gimple_assign_set_rhs2 (def_stmt, rhs);
! 	  return;
! 	}
!       /* Else at least re-use the SSA name.  */
!     }
!   else
!     {
!       if (TREE_CODE (pred) == SSA_NAME)
! 	pred = SSA_NAME_VAR (pred);
!       else
! 	pred = create_tmp_reg (boolean_type_node, NULL);
!       if (gimple_in_ssa_p (cfun))
! 	pred = make_ssa_name (pred, NULL);
!     }
!   pred_stmt = gimple_build_assign_with_ops (code, pred, lhs, rhs);
!   gsi_insert_before (&gsi, pred_stmt, GSI_SAME_STMT);
!   gimple_cond_set_pred (cond, pred);
  }
  
+ 
  /* Build a GIMPLE_LABEL statement for LABEL.  */
  
  gimple
*************** is_gimple_lvalue (tree t)
*** 2590,2595 ****
--- 2641,2648 ----
  bool
  is_gimple_condexpr (tree t)
  {
+   /* ???  This is not the predicate for use of conditionals in valid
+      gimple statements - but it is used in all sort of code.  */
    return (is_gimple_val (t) || (COMPARISON_CLASS_P (t)
  				&& !tree_could_trap_p (t)
  				&& is_gimple_val (TREE_OPERAND (t, 0))
Index: trunk/gcc/gimple.h
===================================================================
*** trunk.orig/gcc/gimple.h	2010-08-25 11:22:16.000000000 +0200
--- trunk/gcc/gimple.h	2010-08-30 15:11:53.000000000 +0200
*************** gimple gimple_build_call_vec (tree, VEC(
*** 821,827 ****
  gimple gimple_build_call (tree, unsigned, ...);
  gimple gimple_build_call_from_tree (tree);
  gimple gimplify_assign (tree, tree, gimple_seq *);
! gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
  gimple gimple_build_label (tree label);
  gimple gimple_build_goto (tree dest);
  gimple gimple_build_nop (void);
--- 821,832 ----
  gimple gimple_build_call (tree, unsigned, ...);
  gimple gimple_build_call_from_tree (tree);
  gimple gimplify_assign (tree, tree, gimple_seq *);
! gimple gimple_build_cond (tree, tree, tree);
! void gimple_pred_extract_comparison (tree, enum tree_code *, tree *, tree *);
! void gimple_cond_extract_comparison (gimple, enum tree_code *, tree *, tree *);
! tree gimple_cond_to_tree (gimple);
! void gimple_update_cond_from_comparison (gimple_stmt_iterator, enum tree_code,
! 					 tree, tree);
  gimple gimple_build_label (tree label);
  gimple gimple_build_goto (tree dest);
  gimple gimple_build_nop (void);
*************** void gimple_set_lhs (gimple, tree);
*** 880,888 ****
  void gimple_replace_lhs (gimple, tree);
  gimple gimple_copy (gimple);
  void gimple_set_modified (gimple, bool);
- void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, tree *);
- gimple gimple_build_cond_from_tree (tree, tree, tree);
- void gimple_cond_set_condition_from_tree (gimple, tree);
  bool gimple_has_side_effects (const_gimple);
  bool gimple_rhs_has_side_effects (const_gimple);
  bool gimple_could_trap_p (gimple);
--- 885,890 ----
*************** gimple_has_lhs (gimple stmt)
*** 2347,2441 ****
  }
  
  
! /* Return the code of the predicate computed by conditional statement GS.  */
! 
! static inline enum tree_code
! gimple_cond_code (const_gimple gs)
! {
!   GIMPLE_CHECK (gs, GIMPLE_COND);
!   return (enum tree_code) gs->gsbase.subcode;
! }
! 
! 
! /* Set CODE to be the predicate code for the conditional statement GS.  */
! 
! static inline void
! gimple_cond_set_code (gimple gs, enum tree_code code)
! {
!   GIMPLE_CHECK (gs, GIMPLE_COND);
!   gs->gsbase.subcode = code;
! }
! 
! 
! /* Return the LHS of the predicate computed by conditional statement GS.  */
  
  static inline tree
! gimple_cond_lhs (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
    return gimple_op (gs, 0);
  }
  
! /* Return the pointer to the LHS of the predicate computed by conditional
!    statement GS.  */
  
  static inline tree *
! gimple_cond_lhs_ptr (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
    return gimple_op_ptr (gs, 0);
  }
  
! /* Set LHS to be the LHS operand of the predicate computed by
!    conditional statement GS.  */
  
  static inline void
! gimple_cond_set_lhs (gimple gs, tree lhs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 0, lhs);
  }
  
  
! /* Return the RHS operand of the predicate computed by conditional GS.  */
  
  static inline tree
! gimple_cond_rhs (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
    return gimple_op (gs, 1);
  }
  
- /* Return the pointer to the RHS operand of the predicate computed by
-    conditional GS.  */
- 
- static inline tree *
- gimple_cond_rhs_ptr (const_gimple gs)
- {
-   GIMPLE_CHECK (gs, GIMPLE_COND);
-   return gimple_op_ptr (gs, 1);
- }
- 
- 
- /* Set RHS to be the RHS operand of the predicate computed by
-    conditional statement GS.  */
  
! static inline void
! gimple_cond_set_rhs (gimple gs, tree rhs)
! {
!   GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 1, rhs);
! }
! 
! 
! /* Return the label used by conditional statement GS when its
     predicate evaluates to true.  */
  
! static inline tree
! gimple_cond_true_label (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   return gimple_op (gs, 2);
  }
  
  
--- 2349,2401 ----
  }
  
  
! /* Return the predicate used by conditional statement GS.  */
  
  static inline tree
! gimple_cond_pred (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
    return gimple_op (gs, 0);
  }
  
! /* Return the pointer to the predicate used by conditional statement GS.  */
  
  static inline tree *
! gimple_cond_pred_ptr (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
    return gimple_op_ptr (gs, 0);
  }
  
! /* Set the predicate of the conditional statement GS to PRED.  */
  
  static inline void
! gimple_cond_set_pred (gimple gs, tree pred)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 0, pred);
  }
  
  
! /* Return the label used by conditional statement GS when its
!    predicate evaluates to true.  */
  
  static inline tree
! gimple_cond_true_label (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
    return gimple_op (gs, 1);
  }
  
  
! /* Return a pointer to the label used by conditional statement GS when its
     predicate evaluates to true.  */
  
! static inline tree *
! gimple_cond_true_label_ptr (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   return gimple_op_ptr (gs, 1);
  }
  
  
*************** static inline void
*** 2446,2452 ****
  gimple_cond_set_true_label (gimple gs, tree label)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 2, label);
  }
  
  
--- 2406,2412 ----
  gimple_cond_set_true_label (gimple gs, tree label)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 1, label);
  }
  
  
*************** static inline void
*** 2457,2463 ****
  gimple_cond_set_false_label (gimple gs, tree label)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 3, label);
  }
  
  
--- 2417,2423 ----
  gimple_cond_set_false_label (gimple gs, tree label)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   gimple_set_op (gs, 2, label);
  }
  
  
*************** static inline tree
*** 2468,2474 ****
  gimple_cond_false_label (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   return gimple_op (gs, 3);
  }
  
  
--- 2428,2445 ----
  gimple_cond_false_label (const_gimple gs)
  {
    GIMPLE_CHECK (gs, GIMPLE_COND);
!   return gimple_op (gs, 2);
! }
! 
! 
! /* Return a pointer to the label used by conditional statement GS when its
!    predicate evaluates to false.  */
! 
! static inline tree *
! gimple_cond_false_label_ptr (const_gimple gs)
! {
!   GIMPLE_CHECK (gs, GIMPLE_COND);
!   return gimple_op_ptr (gs, 2);
  }
  
  
*************** gimple_cond_false_label (const_gimple gs
*** 2477,2485 ****
  static inline void
  gimple_cond_make_false (gimple gs)
  {
!   gimple_cond_set_lhs (gs, boolean_true_node);
!   gimple_cond_set_rhs (gs, boolean_false_node);
!   gs->gsbase.subcode = EQ_EXPR;
  }
  
  
--- 2448,2454 ----
  static inline void
  gimple_cond_make_false (gimple gs)
  {
!   gimple_cond_set_pred (gs, boolean_false_node);
  }
  
  
*************** gimple_cond_make_false (gimple gs)
*** 2488,2496 ****
  static inline void
  gimple_cond_make_true (gimple gs)
  {
!   gimple_cond_set_lhs (gs, boolean_true_node);
!   gimple_cond_set_rhs (gs, boolean_true_node);
!   gs->gsbase.subcode = EQ_EXPR;
  }
  
  /* Check if conditional statemente GS is of the form 'if (1 == 1)',
--- 2457,2463 ----
  static inline void
  gimple_cond_make_true (gimple gs)
  {
!   gimple_cond_set_pred (gs, boolean_true_node);
  }
  
  /* Check if conditional statemente GS is of the form 'if (1 == 1)',
*************** gimple_cond_make_true (gimple gs)
*** 2499,2521 ****
  static inline bool
  gimple_cond_true_p (const_gimple gs)
  {
!   tree lhs = gimple_cond_lhs (gs);
!   tree rhs = gimple_cond_rhs (gs);
!   enum tree_code code = gimple_cond_code (gs);
! 
!   if (lhs != boolean_true_node && lhs != boolean_false_node)
!     return false;
! 
!   if (rhs != boolean_true_node && rhs != boolean_false_node)
!     return false;
! 
!   if (code == NE_EXPR && lhs != rhs)
!     return true;
! 
!   if (code == EQ_EXPR && lhs == rhs)
!       return true;
! 
!   return false;
  }
  
  /* Check if conditional statement GS is of the form 'if (1 != 1)',
--- 2466,2472 ----
  static inline bool
  gimple_cond_true_p (const_gimple gs)
  {
!   return integer_nonzerop (gimple_cond_pred (gs));
  }
  
  /* Check if conditional statement GS is of the form 'if (1 != 1)',
*************** gimple_cond_true_p (const_gimple gs)
*** 2524,2573 ****
  static inline bool
  gimple_cond_false_p (const_gimple gs)
  {
!   tree lhs = gimple_cond_lhs (gs);
!   tree rhs = gimple_cond_rhs (gs);
!   enum tree_code code = gimple_cond_code (gs);
! 
!   if (lhs != boolean_true_node && lhs != boolean_false_node)
!     return false;
! 
!   if (rhs != boolean_true_node && rhs != boolean_false_node)
!     return false;
! 
!   if (code == NE_EXPR && lhs == rhs)
!     return true;
! 
!   if (code == EQ_EXPR && lhs != rhs)
!       return true;
! 
!   return false;
! }
! 
! /* Check if conditional statement GS is of the form 'if (var != 0)' or
!    'if (var == 1)' */
! 
! static inline bool
! gimple_cond_single_var_p (gimple gs)
! {
!   if (gimple_cond_code (gs) == NE_EXPR
!       && gimple_cond_rhs (gs) == boolean_false_node)
!     return true;
! 
!   if (gimple_cond_code (gs) == EQ_EXPR
!       && gimple_cond_rhs (gs) == boolean_true_node)
!     return true;
! 
!   return false;
! }
! 
! /* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS.  */
! 
! static inline void
! gimple_cond_set_condition (gimple stmt, enum tree_code code, tree lhs, tree rhs)
! {
!   gimple_cond_set_code (stmt, code);
!   gimple_cond_set_lhs (stmt, lhs);
!   gimple_cond_set_rhs (stmt, rhs);
  }
  
  /* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS.  */
--- 2475,2481 ----
  static inline bool
  gimple_cond_false_p (const_gimple gs)
  {
!   return integer_zerop (gimple_cond_pred (gs));
  }
  
  /* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS.  */
Index: trunk/gcc/gimplify.c
===================================================================
*** trunk.orig/gcc/gimplify.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/gimplify.c	2010-08-30 14:32:23.000000000 +0200
*************** gimplify_pure_cond_expr (tree *expr_p, g
*** 2859,2865 ****
      TREE_SET_CODE (cond, TRUTH_AND_EXPR);
    else if (code == TRUTH_ORIF_EXPR)
      TREE_SET_CODE (cond, TRUTH_OR_EXPR);
!   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
    COND_EXPR_COND (*expr_p) = cond;
  
    tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
--- 2859,2865 ----
      TREE_SET_CODE (cond, TRUTH_AND_EXPR);
    else if (code == TRUTH_ORIF_EXPR)
      TREE_SET_CODE (cond, TRUTH_OR_EXPR);
!   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
    COND_EXPR_COND (*expr_p) = cond;
  
    tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
*************** gimplify_cond_expr (tree *expr_p, gimple
*** 2914,2925 ****
    tree expr = *expr_p;
    tree type = TREE_TYPE (expr);
    location_t loc = EXPR_LOCATION (expr);
!   tree tmp, arm1, arm2;
    enum gimplify_status ret;
    tree label_true, label_false, label_cont;
    bool have_then_clause_p, have_else_clause_p;
    gimple gimple_cond;
-   enum tree_code pred_code;
    gimple_seq seq = NULL;
  
    /* If this COND_EXPR has a value, copy the values into a temporary within
--- 2914,2924 ----
    tree expr = *expr_p;
    tree type = TREE_TYPE (expr);
    location_t loc = EXPR_LOCATION (expr);
!   tree tmp;
    enum gimplify_status ret;
    tree label_true, label_false, label_cont;
    bool have_then_clause_p, have_else_clause_p;
    gimple gimple_cond;
    gimple_seq seq = NULL;
  
    /* If this COND_EXPR has a value, copy the values into a temporary within
*************** gimplify_cond_expr (tree *expr_p, gimple
*** 3013,3019 ****
    /* Now do the normal gimplification.  */
  
    /* Gimplify condition.  */
!   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
  		       fb_rvalue);
    if (ret == GS_ERROR)
      return GS_ERROR;
--- 3012,3018 ----
    /* Now do the normal gimplification.  */
  
    /* Gimplify condition.  */
!   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_val,
  		       fb_rvalue);
    if (ret == GS_ERROR)
      return GS_ERROR;
*************** gimplify_cond_expr (tree *expr_p, gimple
*** 3059,3068 ****
    else
      label_false = create_artificial_label (UNKNOWN_LOCATION);
  
!   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
! 				 &arm2);
! 
!   gimple_cond = gimple_build_cond (pred_code, arm1, arm2, label_true,
                                     label_false);
  
    gimplify_seq_add_stmt (&seq, gimple_cond);
--- 3058,3064 ----
    else
      label_false = create_artificial_label (UNKNOWN_LOCATION);
  
!   gimple_cond = gimple_build_cond (COND_EXPR_COND (expr), label_true,
                                     label_false);
  
    gimplify_seq_add_stmt (&seq, gimple_cond);
*************** gimplify_init_ctor_eval_range (tree obje
*** 3427,3434 ****
      gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
  
    /* We exit the loop when the index var is equal to the upper bound.  */
    gimplify_seq_add_stmt (pre_p,
! 			 gimple_build_cond (EQ_EXPR, var, upper,
  					    loop_exit_label, fall_thru_label));
  
    gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
--- 3423,3433 ----
      gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
  
    /* We exit the loop when the index var is equal to the upper bound.  */
+   tmp = get_initialized_tmp_var (fold_build2 (EQ_EXPR,
+ 					      boolean_type_node,
+ 					      var, upper), pre_p, NULL);
    gimplify_seq_add_stmt (pre_p,
! 			 gimple_build_cond (tmp,
  					    loop_exit_label, fall_thru_label));
  
    gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 6565,6571 ****
      gcc_assert (fallback & (fb_rvalue | fb_lvalue));
    else if (gimple_test_f == is_gimple_val
             || gimple_test_f == is_gimple_call_addr
-            || gimple_test_f == is_gimple_condexpr
             || gimple_test_f == is_gimple_mem_rhs
             || gimple_test_f == is_gimple_mem_rhs_or_call
             || gimple_test_f == is_gimple_reg_rhs
--- 6564,6569 ----
*************** gimple_regimplify_operands (gimple stmt,
*** 7831,7839 ****
    switch (gimple_code (stmt))
      {
      case GIMPLE_COND:
!       gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
! 		     is_gimple_val, fb_rvalue);
!       gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
  		     is_gimple_val, fb_rvalue);
        break;
      case GIMPLE_SWITCH:
--- 7829,7835 ----
    switch (gimple_code (stmt))
      {
      case GIMPLE_COND:
!       gimplify_expr (gimple_cond_pred_ptr (stmt), &pre, NULL,
  		     is_gimple_val, fb_rvalue);
        break;
      case GIMPLE_SWITCH:
Index: trunk/gcc/lambda-code.c
===================================================================
*** trunk.orig/gcc/lambda-code.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/lambda-code.c	2010-08-30 14:32:23.000000000 +0200
*************** gcc_loop_to_lambda_loop (struct loop *lo
*** 1262,1267 ****
--- 1262,1268 ----
    int stepint;
    int extra = 0;
    tree lboundvar, uboundvar, uboundresult;
+   enum tree_code test_code;
  
    /* Find out induction var and exit condition.  */
    inductionvar = find_induction_var_from_exit_cond (loop);
*************** gcc_loop_to_lambda_loop (struct loop *lo
*** 1392,1399 ****
      }
    /* One part of the test may be a loop invariant tree.  */
    VEC_reserve (tree, heap, *invariants, 1);
!   test_lhs = gimple_cond_lhs (exit_cond);
!   test_rhs = gimple_cond_rhs (exit_cond);
  
    if (TREE_CODE (test_rhs) == SSA_NAME
        && invariant_in_loop_and_outer_loops (loop, test_rhs))
--- 1393,1399 ----
      }
    /* One part of the test may be a loop invariant tree.  */
    VEC_reserve (tree, heap, *invariants, 1);
!   gimple_cond_extract_comparison (exit_cond, &test_code, &test_lhs, &test_rhs);
  
    if (TREE_CODE (test_rhs) == SSA_NAME
        && invariant_in_loop_and_outer_loops (loop, test_rhs))
*************** gcc_loop_to_lambda_loop (struct loop *lo
*** 1417,1429 ****
  
  
    /* We might have some leftover.  */
!   if (gimple_cond_code (exit_cond) == LT_EXPR)
      extra = -1 * stepint;
!   else if (gimple_cond_code (exit_cond) == NE_EXPR)
      extra = -1 * stepint;
!   else if (gimple_cond_code (exit_cond) == GT_EXPR)
      extra = -1 * stepint;
!   else if (gimple_cond_code (exit_cond) == EQ_EXPR)
      extra = 1 * stepint;
  
    ubound = gcc_tree_to_linear_expression (depth, uboundvar,
--- 1417,1429 ----
  
  
    /* We might have some leftover.  */
!   if (test_code == LT_EXPR)
      extra = -1 * stepint;
!   else if (test_code == NE_EXPR)
      extra = -1 * stepint;
!   else if (test_code == GT_EXPR)
      extra = -1 * stepint;
!   else if (test_code == EQ_EXPR)
      extra = 1 * stepint;
  
    ubound = gcc_tree_to_linear_expression (depth, uboundvar,
*************** find_induction_var_from_exit_cond (struc
*** 1458,1469 ****
    gimple expr = get_loop_exit_condition (loop);
    tree ivarop;
    tree test_lhs, test_rhs;
    if (expr == NULL)
      return NULL_TREE;
    if (gimple_code (expr) != GIMPLE_COND)
      return NULL_TREE;
!   test_lhs = gimple_cond_lhs (expr);
!   test_rhs = gimple_cond_rhs (expr);
  
    /* Find the side that is invariant in this loop. The ivar must be the other
       side.  */
--- 1458,1469 ----
    gimple expr = get_loop_exit_condition (loop);
    tree ivarop;
    tree test_lhs, test_rhs;
+   enum tree_code test_code;
    if (expr == NULL)
      return NULL_TREE;
    if (gimple_code (expr) != GIMPLE_COND)
      return NULL_TREE;
!   gimple_cond_extract_comparison (expr, &test_code, &test_lhs, &test_rhs);
  
    /* Find the side that is invariant in this loop. The ivar must be the other
       side.  */
*************** lambda_loopnest_to_gcc_loopnest (struct
*** 1826,1832 ****
        if (exit->flags & EDGE_FALSE_VALUE)
  	testtype = swap_tree_comparison (testtype);
  
!       gimple_cond_set_condition (exitcond, testtype, newupperbound, ivvarinced);
        update_stmt (exitcond);
        VEC_replace (tree, new_ivs, i, ivvar);
  
--- 1826,1833 ----
        if (exit->flags & EDGE_FALSE_VALUE)
  	testtype = swap_tree_comparison (testtype);
  
!       gimple_update_cond_from_comparison (gsi_for_stmt (exitcond), testtype,
! 					  newupperbound, ivvarinced);
        update_stmt (exitcond);
        VEC_replace (tree, new_ivs, i, ivvar);
  
*************** perfect_nest_p (struct loop *loop)
*** 2018,2023 ****
--- 2019,2026 ----
  	  for (bsi = gsi_start_bb (bbs[i]); !gsi_end_p (bsi); gsi_next (&bsi))
  	    {
  	      gimple stmt = gsi_stmt (bsi);
+ 	      use_operand_p use;
+ 	      gimple use_stmt;
  
  	      if (gimple_code (stmt) == GIMPLE_COND
  		  && exit_cond != stmt)
*************** perfect_nest_p (struct loop *loop)
*** 2028,2033 ****
--- 2031,2043 ----
  		  || stmt_is_bumper_for_loop (loop, stmt))
  		continue;
  
+ 	      if (is_gimple_assign (stmt)
+ 		  && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
+ 		  && single_imm_use (gimple_assign_lhs (stmt),
+ 				     &use, &use_stmt)
+ 		  && use_stmt == exit_cond)
+ 		continue;
+ 
  	    non_perfectly_nested:
  	      free (bbs);
  	      return false;
*************** perfect_nestify (struct loop *loop,
*** 2469,2476 ****
    bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
    latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
    make_edge (headerbb, bodybb, EDGE_FALLTHRU);
!   cond_stmt = gimple_build_cond (NE_EXPR, integer_one_node, integer_zero_node,
! 				 NULL_TREE, NULL_TREE);
    bsi = gsi_start_bb (bodybb);
    gsi_insert_after (&bsi, cond_stmt, GSI_NEW_STMT);
    e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
--- 2479,2485 ----
    bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
    latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
    make_edge (headerbb, bodybb, EDGE_FALLTHRU);
!   cond_stmt = gimple_build_cond (boolean_false_node, NULL_TREE, NULL_TREE);
    bsi = gsi_start_bb (bodybb);
    gsi_insert_after (&bsi, cond_stmt, GSI_NEW_STMT);
    e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
*************** perfect_nestify (struct loop *loop,
*** 2516,2522 ****
    else
      gsi_insert_before (&bsi, stmt, GSI_SAME_STMT);
    update_stmt (stmt);
!   gimple_cond_set_condition (exit_condition, GE_EXPR, uboundvar, ivvarinced);
    update_stmt (exit_condition);
    replacements = htab_create_ggc (20, tree_map_hash,
  				  tree_map_eq, NULL);
--- 2525,2532 ----
    else
      gsi_insert_before (&bsi, stmt, GSI_SAME_STMT);
    update_stmt (stmt);
!   gimple_update_cond_from_comparison (gsi_for_stmt (exit_condition),
! 				      GE_EXPR, uboundvar, ivvarinced);
    update_stmt (exit_condition);
    replacements = htab_create_ggc (20, tree_map_hash,
  				  tree_map_eq, NULL);
Index: trunk/gcc/omp-low.c
===================================================================
*** trunk.orig/gcc/omp-low.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/omp-low.c	2010-08-30 14:32:23.000000000 +0200
*************** lower_lastprivate_clauses (tree clauses,
*** 2543,2558 ****
    if (predicate)
      {
        gimple stmt;
!       tree label_true, arm1, arm2;
  
        label = create_artificial_label (UNKNOWN_LOCATION);
        label_true = create_artificial_label (UNKNOWN_LOCATION);
!       arm1 = TREE_OPERAND (predicate, 0);
!       arm2 = TREE_OPERAND (predicate, 1);
!       gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
!       gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
!       stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
! 				label_true, label);
        gimple_seq_add_stmt (stmt_list, stmt);
        gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
      }
--- 2543,2554 ----
    if (predicate)
      {
        gimple stmt;
!       tree label_true;
  
        label = create_artificial_label (UNKNOWN_LOCATION);
        label_true = create_artificial_label (UNKNOWN_LOCATION);
!       gimplify_expr (&predicate, stmt_list, NULL, is_gimple_val, fb_rvalue);
!       stmt = gimple_build_cond (predicate, label_true, label);
        gimple_seq_add_stmt (stmt_list, stmt);
        gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
      }
*************** lower_send_shared_vars (gimple_seq *ilis
*** 2893,2903 ****
  static gimple
  gimple_build_cond_empty (tree cond)
  {
!   enum tree_code pred_code;
!   tree lhs, rhs;
! 
!   gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
!   return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
  }
  
  
--- 2889,2895 ----
  static gimple
  gimple_build_cond_empty (tree cond)
  {
!   return gimple_build_cond (cond, NULL_TREE, NULL_TREE);
  }
  
  
*************** expand_omp_for_generic (struct omp_regio
*** 3867,3874 ****
    if (TREE_TYPE (t) != boolean_type_node)
      t = fold_build2 (NE_EXPR, boolean_type_node,
  		     t, build_int_cst (TREE_TYPE (t), 0));
!   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
! 			       	true, GSI_SAME_STMT);
    gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove the GIMPLE_OMP_FOR statement.  */
--- 3859,3865 ----
    if (TREE_TYPE (t) != boolean_type_node)
      t = fold_build2 (NE_EXPR, boolean_type_node,
  		     t, build_int_cst (TREE_TYPE (t), 0));
!   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
    gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove the GIMPLE_OMP_FOR statement.  */
*************** expand_omp_for_generic (struct omp_regio
*** 3953,3959 ****
        stmt = gimple_build_assign (vback, t);
        gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  
!       t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
        stmt = gimple_build_cond_empty (t);
        gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  
--- 3944,3953 ----
        stmt = gimple_build_assign (vback, t);
        gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  
!       t = force_gimple_operand_gsi (&gsi, build2 (fd->loop.cond_code,
! 						  boolean_type_node, vback,
! 						  iend), true, NULL_TREE,
! 				    true, GSI_SAME_STMT);
        stmt = gimple_build_cond_empty (t);
        gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  
*************** expand_omp_for_generic (struct omp_regio
*** 4005,4012 ****
  		  t = fd->loops[i].n2;
  		  t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  						false, GSI_CONTINUE_LINKING);
! 		  t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
! 				   fd->loops[i].v, t);
  		  stmt = gimple_build_cond_empty (t);
  		  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  		  e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
--- 3999,4009 ----
  		  t = fd->loops[i].n2;
  		  t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  						false, GSI_CONTINUE_LINKING);
! 		  t = force_gimple_operand_gsi
! 		        (&gsi, fold_build2 (fd->loops[i].cond_code,
! 					    boolean_type_node,
! 					    fd->loops[i].v, t), true,
! 			 NULL_TREE, false, GSI_CONTINUE_LINKING);
  		  stmt = gimple_build_cond_empty (t);
  		  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  		  e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
*************** expand_omp_for_generic (struct omp_regio
*** 4027,4034 ****
        t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  				    false, GSI_CONTINUE_LINKING);
        if (TREE_TYPE (t) != boolean_type_node)
! 	t = fold_build2 (NE_EXPR, boolean_type_node,
! 			 t, build_int_cst (TREE_TYPE (t), 0));
        stmt = gimple_build_cond_empty (t);
        gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
      }
--- 4024,4035 ----
        t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  				    false, GSI_CONTINUE_LINKING);
        if (TREE_TYPE (t) != boolean_type_node)
! 	t = force_gimple_operand_gsi (&gsi, fold_build2 (NE_EXPR,
! 							 boolean_type_node,
! 							 t, build_int_cst
! 							     (TREE_TYPE (t), 0)),
! 				      true, NULL_TREE, false,
! 				      GSI_CONTINUE_LINKING);
        stmt = gimple_build_cond_empty (t);
        gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
      }
*************** expand_omp_for_static_nochunk (struct om
*** 4200,4206 ****
    t = fold_build2 (MIN_EXPR, itype, t, n);
    e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
  
!   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
    gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove the GIMPLE_OMP_FOR statement.  */
--- 4201,4209 ----
    t = fold_build2 (MIN_EXPR, itype, t, n);
    e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
  
!   t = force_gimple_operand_gsi (&gsi, build2 (GE_EXPR,
! 					      boolean_type_node, s0, e0),
! 				true, NULL_TREE, true, GSI_SAME_STMT);
    gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove the GIMPLE_OMP_FOR statement.  */
*************** expand_omp_for_static_nochunk (struct om
*** 4249,4255 ****
    stmt = gimple_build_assign (vback, t);
    gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  
!   t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
    gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove the GIMPLE_OMP_CONTINUE statement.  */
--- 4252,4260 ----
    stmt = gimple_build_assign (vback, t);
    gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  
!   t = force_gimple_operand_gsi (&gsi, build2 (fd->loop.cond_code,
! 					      boolean_type_node, vback, e),
! 				true, NULL_TREE, true, GSI_SAME_STMT);
    gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove the GIMPLE_OMP_CONTINUE statement.  */
*************** expand_omp_for_static_chunk (struct omp_
*** 4432,4438 ****
    e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
  				 false, GSI_CONTINUE_LINKING);
  
!   t = build2 (LT_EXPR, boolean_type_node, s0, n);
    gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
  
    /* Setup code for sequential iteration goes in SEQ_START_BB.  */
--- 4437,4444 ----
    e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
  				 false, GSI_CONTINUE_LINKING);
  
!   t = force_gimple_operand_gsi (&si, build2 (LT_EXPR, boolean_type_node, s0, n),
! 				true, NULL_TREE, false, GSI_CONTINUE_LINKING);
    gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
  
    /* Setup code for sequential iteration goes in SEQ_START_BB.  */
*************** expand_omp_for_static_chunk (struct omp_
*** 4476,4482 ****
    stmt = gimple_build_assign (v_back, t);
    gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  
!   t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
    gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove GIMPLE_OMP_CONTINUE.  */
--- 4482,4490 ----
    stmt = gimple_build_assign (v_back, t);
    gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  
!   t = force_gimple_operand_gsi (&si, build2 (fd->loop.cond_code,
! 					     boolean_type_node, v_back, e),
! 				true, NULL_TREE, true, GSI_SAME_STMT);
    gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
  
    /* Remove GIMPLE_OMP_CONTINUE.  */
*************** expand_omp_atomic_pipeline (basic_block
*** 5049,5055 ****
  			    tree addr, tree loaded_val, tree stored_val,
  			    int index)
  {
!   tree loadedi, storedi, initial, new_storedi, old_vali;
    tree type, itype, cmpxchg, iaddr;
    gimple_stmt_iterator si;
    basic_block loop_header = single_succ (load_bb);
--- 5057,5063 ----
  			    tree addr, tree loaded_val, tree stored_val,
  			    int index)
  {
!   tree loadedi, storedi, initial, new_storedi, old_vali, t;
    tree type, itype, cmpxchg, iaddr;
    gimple_stmt_iterator si;
    basic_block loop_header = single_succ (load_bb);
*************** expand_omp_atomic_pipeline (basic_block
*** 5178,5186 ****
    /* Note that we always perform the comparison as an integer, even for
       floating point.  This allows the atomic operation to properly
       succeed even with NaNs and -0.0.  */
!   stmt = gimple_build_cond_empty
!            (build2 (NE_EXPR, boolean_type_node,
! 		    new_storedi, old_vali));
    gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  
    /* Update cfg.  */
--- 5186,5195 ----
    /* Note that we always perform the comparison as an integer, even for
       floating point.  This allows the atomic operation to properly
       succeed even with NaNs and -0.0.  */
!   t = force_gimple_operand_gsi (&si, build2 (NE_EXPR, boolean_type_node,
! 					     new_storedi, old_vali),
! 				true, NULL_TREE, true, GSI_SAME_STMT);
!   stmt = gimple_build_cond_empty (t);
    gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  
    /* Update cfg.  */
*************** lower_omp_single_simple (gimple single_s
*** 5680,5689 ****
    gimple_call_set_lhs (call, lhs);
    gimple_seq_add_stmt (pre_p, call);
  
!   cond = gimple_build_cond (EQ_EXPR, lhs,
! 			    fold_convert_loc (loc, TREE_TYPE (lhs),
! 					      boolean_true_node),
! 			    tlabel, flabel);
    gimple_seq_add_stmt (pre_p, cond);
    gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
    gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
--- 5689,5695 ----
    gimple_call_set_lhs (call, lhs);
    gimple_seq_add_stmt (pre_p, call);
  
!   cond = gimple_build_cond (lhs, tlabel, flabel);
    gimple_seq_add_stmt (pre_p, cond);
    gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
    gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
*************** lower_omp_1 (gimple_stmt_iterator *gsi_p
*** 6594,6603 ****
      {
      case GIMPLE_COND:
        if ((ctx || task_shared_vars)
! 	  && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
! 	      		 ctx ? NULL : &wi, NULL)
! 	      || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
! 			    ctx ? NULL : &wi, NULL)))
  	gimple_regimplify_operands (stmt, gsi_p);
        break;
      case GIMPLE_CATCH:
--- 6600,6607 ----
      {
      case GIMPLE_COND:
        if ((ctx || task_shared_vars)
! 	  && (walk_tree (gimple_cond_pred_ptr (stmt), lower_omp_regimplify_p,
! 	      		 ctx ? NULL : &wi, NULL)))
  	gimple_regimplify_operands (stmt, gsi_p);
        break;
      case GIMPLE_CATCH:
Index: trunk/gcc/tree-call-cdce.c
===================================================================
*** trunk.orig/gcc/tree-call-cdce.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-call-cdce.c	2010-08-30 14:32:23.000000000 +0200
*************** gen_one_condition (tree arg, int lbub,
*** 348,354 ****
    tempcn = make_ssa_name (tempc, stmt2);
    gimple_assign_set_lhs (stmt2, tempcn);
  
!   stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE);
    VEC_quick_push (gimple, conds, stmt1);
    VEC_quick_push (gimple, conds, stmt2);
    VEC_quick_push (gimple, conds, stmt3);
--- 348,354 ----
    tempcn = make_ssa_name (tempc, stmt2);
    gimple_assign_set_lhs (stmt2, tempcn);
  
!   stmt3 = gimple_build_cond (tempcn, NULL_TREE, NULL_TREE);
    VEC_quick_push (gimple, conds, stmt1);
    VEC_quick_push (gimple, conds, stmt2);
    VEC_quick_push (gimple, conds, stmt3);
*************** gen_conditions_for_pow_int_base (tree ba
*** 453,459 ****
    tree base_var, int_type;
    tree temp, tempn;
    tree cst0;
!   gimple stmt1, stmt2;
    int bit_sz, max_exp;
    inp_domain exp_domain;
  
--- 453,459 ----
    tree base_var, int_type;
    tree temp, tempn;
    tree cst0;
!   gimple stmt1, stmt2, stmt3;
    int bit_sz, max_exp;
    inp_domain exp_domain;
  
*************** gen_conditions_for_pow_int_base (tree ba
*** 510,519 ****
    stmt1 = gimple_build_assign (temp, base_val0);
    tempn = make_ssa_name (temp, stmt1);
    gimple_assign_set_lhs (stmt1, tempn);
!   stmt2 = gimple_build_cond (LE_EXPR, tempn, cst0, NULL_TREE, NULL_TREE);
  
    VEC_quick_push (gimple, conds, stmt1);
    VEC_quick_push (gimple, conds, stmt2);
    (*nconds)++;
  }
  
--- 510,525 ----
    stmt1 = gimple_build_assign (temp, base_val0);
    tempn = make_ssa_name (temp, stmt1);
    gimple_assign_set_lhs (stmt1, tempn);
!   temp = create_tmp_var (boolean_type_node, NULL);
!   stmt2 = gimple_build_assign (temp, fold_build2 (LE_EXPR, boolean_type_node,
! 						  tempn, cst0));
!   tempn = make_ssa_name (temp, stmt2);
!   gimple_assign_set_lhs (stmt2, tempn);
!   stmt3 = gimple_build_cond (tempn, NULL_TREE, NULL_TREE);
  
    VEC_quick_push (gimple, conds, stmt1);
    VEC_quick_push (gimple, conds, stmt2);
+   VEC_quick_push (gimple, conds, stmt3);
    (*nconds)++;
  }
  
Index: trunk/gcc/tree-cfg.c
===================================================================
*** trunk.orig/gcc/tree-cfg.c	2010-08-27 11:03:47.000000000 +0200
--- trunk/gcc/tree-cfg.c	2010-08-30 14:32:23.000000000 +0200
*************** create_bb (void *h, void *e, basic_block
*** 470,514 ****
  				 Edge creation
  ---------------------------------------------------------------------------*/
  
- /* Fold COND_EXPR_COND of each COND_EXPR.  */
- 
- void
- fold_cond_expr_cond (void)
- {
-   basic_block bb;
- 
-   FOR_EACH_BB (bb)
-     {
-       gimple stmt = last_stmt (bb);
- 
-       if (stmt && gimple_code (stmt) == GIMPLE_COND)
- 	{
- 	  location_t loc = gimple_location (stmt);
- 	  tree cond;
- 	  bool zerop, onep;
- 
- 	  fold_defer_overflow_warnings ();
- 	  cond = fold_binary_loc (loc, gimple_cond_code (stmt), boolean_type_node,
- 			      gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
- 	  if (cond)
- 	    {
- 	      zerop = integer_zerop (cond);
- 	      onep = integer_onep (cond);
- 	    }
- 	  else
- 	    zerop = onep = false;
- 
- 	  fold_undefer_overflow_warnings (zerop || onep,
- 					  stmt,
- 					  WARN_STRICT_OVERFLOW_CONDITIONAL);
- 	  if (zerop)
- 	    gimple_cond_make_false (stmt);
- 	  else if (onep)
- 	    gimple_cond_make_true (stmt);
- 	}
-     }
- }
- 
  /* Join all the blocks in the flowgraph.  */
  
  static void
--- 470,475 ----
*************** make_edges (void)
*** 690,698 ****
  
    if (root_omp_region)
      free_omp_regions ();
- 
-   /* Fold COND_EXPR_COND of each COND_EXPR.  */
-   fold_cond_expr_cond ();
  }
  
  /* Trivial hash function for a location_t.  ITEM is a pointer to
--- 651,656 ----
*************** verify_expr (tree *tp, int *walk_subtree
*** 2748,2754 ****
  	  error ("non-integral used in condition");
  	  return x;
  	}
!       if (!is_gimple_condexpr (x))
          {
  	  error ("invalid conditional operand");
  	  return x;
--- 2706,2712 ----
  	  error ("non-integral used in condition");
  	  return x;
  	}
!       if (!is_gimple_val (x))
          {
  	  error ("invalid conditional operand");
  	  return x;
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4066,4076 ****
        return verify_gimple_call (stmt);
  
      case GIMPLE_COND:
-       if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
- 	{
- 	  error ("invalid comparison code in gimple cond");
- 	  return true;
- 	}
        if (!(!gimple_cond_true_label (stmt)
  	    || TREE_CODE (gimple_cond_true_label (stmt)) == LABEL_DECL)
  	  || !(!gimple_cond_false_label (stmt)
--- 4024,4029 ----
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4079,4088 ****
  	  error ("invalid labels in gimple cond");
  	  return true;
  	}
! 	  
!       return verify_gimple_comparison (boolean_type_node,
! 				       gimple_cond_lhs (stmt),
! 				       gimple_cond_rhs (stmt));
  
      case GIMPLE_GOTO:
        return verify_gimple_goto (stmt);
--- 4032,4049 ----
  	  error ("invalid labels in gimple cond");
  	  return true;
  	}
!       if (!is_gimple_val (gimple_cond_pred (stmt)))
! 	{
! 	  error ("invalid predicate in gimple cond");
! 	  return true;
! 	}
!       if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_pred (stmt))))
! 	{
! 	  error ("invalid predicate type in gimple cond");
! 	  debug_generic_stmt (TREE_TYPE (gimple_cond_pred (stmt)));
! 	  return true;
! 	}
!       return false;
  
      case GIMPLE_GOTO:
        return verify_gimple_goto (stmt);
*************** gimple_duplicate_sese_region (edge entry
*** 5483,5491 ****
  */
  
  bool
! gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNUSED,
! 			  basic_block *region ATTRIBUTE_UNUSED, unsigned n_region ATTRIBUTE_UNUSED,
! 			  basic_block *region_copy ATTRIBUTE_UNUSED)
  {
    unsigned i;
    bool free_region_copy = false;
--- 5444,5452 ----
  */
  
  bool
! gimple_duplicate_sese_tail (edge entry, edge exit,
! 			    basic_block *region, unsigned n_region,
! 			    basic_block *region_copy)
  {
    unsigned i;
    bool free_region_copy = false;
*************** gimple_duplicate_sese_tail (edge entry A
*** 5500,5510 ****
    gimple cond_stmt;
    edge sorig, snew;
    basic_block exit_bb;
-   basic_block iters_bb;
    tree new_rhs;
    gimple_stmt_iterator psi;
    gimple phi;
    tree def;
  
    gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
    exits[0] = exit;
--- 5461,5472 ----
    gimple cond_stmt;
    edge sorig, snew;
    basic_block exit_bb;
    tree new_rhs;
    gimple_stmt_iterator psi;
    gimple phi;
    tree def;
+   enum tree_code code;
+   tree lhs, rhs;
  
    gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
    exits[0] = exit;
*************** gimple_duplicate_sese_tail (edge entry A
*** 5590,5617 ****
      peel out the last iteration).  If the body is executed after
      the condition, moving the condition to the entry requires
      decrementing one iteration.  */
    if (exits[1]->dest == orig_loop->latch)
!     new_rhs = gimple_cond_rhs (cond_stmt);
    else
!   {
!     new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (gimple_cond_rhs (cond_stmt)),
! 			   gimple_cond_rhs (cond_stmt),
! 			   build_int_cst (TREE_TYPE (gimple_cond_rhs (cond_stmt)), 1));
! 
!     if (TREE_CODE (gimple_cond_rhs (cond_stmt)) == SSA_NAME)
!       {
! 	iters_bb = gimple_bb (SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)));
! 	for (gsi1 = gsi_start_bb (iters_bb); !gsi_end_p (gsi1); gsi_next (&gsi1))
! 	  if (gsi_stmt (gsi1) == SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)))
! 	    break;
! 
! 	new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
! 					    NULL_TREE,false,GSI_CONTINUE_LINKING);
!       }
!   }
!   gimple_cond_set_rhs (cond_stmt, unshare_expr (new_rhs));
!   gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt)));
    gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
  
    sorig = single_succ_edge (switch_bb);
    sorig->flags = exits[1]->flags;
--- 5552,5578 ----
      peel out the last iteration).  If the body is executed after
      the condition, moving the condition to the entry requires
      decrementing one iteration.  */
+   gimple_cond_extract_comparison (cond_stmt, &code, &lhs, &rhs);
    if (exits[1]->dest == orig_loop->latch)
!     new_rhs = rhs;
    else
!     {
!       new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
! 			     rhs,
! 			     build_int_cst (TREE_TYPE (rhs), 1));
! 
!       if (TREE_CODE (rhs) == SSA_NAME)
! 	{
! 	  gsi1 = gsi_for_stmt (SSA_NAME_DEF_STMT (rhs));
! 	  new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
! 					      NULL_TREE, false,
! 					      GSI_CONTINUE_LINKING);
! 	}
!     }
    gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
+   gimple_update_cond_from_comparison (gsi, code, unshare_expr (lhs),
+ 				      unshare_expr (new_rhs));
+   update_stmt (cond_stmt);
  
    sorig = single_succ_edge (switch_bb);
    sorig->flags = exits[1]->flags;
*************** gimple_lv_add_condition_to_bb (basic_blo
*** 7203,7214 ****
    tree cond_expr = (tree) cond_e;
    edge e0;
  
    /* Build new conditional expr */
!   new_cond_expr = gimple_build_cond_from_tree (cond_expr,
! 					       NULL_TREE, NULL_TREE);
  
    /* Add new cond in cond_bb.  */
-   gsi = gsi_last_bb (cond_bb);
    gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
  
    /* Adjust edges appropriately to connect new head with first head
--- 7164,7177 ----
    tree cond_expr = (tree) cond_e;
    edge e0;
  
+   gsi = gsi_last_bb (cond_bb);
+ 
    /* Build new conditional expr */
!   cond_expr = force_gimple_operand_gsi (&gsi, cond_expr, true, NULL,
! 					false, GSI_NEW_STMT);
!   new_cond_expr = gimple_build_cond (cond_expr, NULL_TREE, NULL_TREE);
  
    /* Add new cond in cond_bb.  */
    gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
  
    /* Adjust edges appropriately to connect new head with first head
Index: trunk/gcc/tree-complex.c
===================================================================
*** trunk.orig/gcc/tree-complex.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-complex.c	2010-08-30 14:32:23.000000000 +0200
*************** init_dont_simulate_again (void)
*** 234,244 ****
  		op1 = gimple_assign_rhs2 (stmt);
  	      break;
  
- 	    case GIMPLE_COND:
- 	      op0 = gimple_cond_lhs (stmt);
- 	      op1 = gimple_cond_rhs (stmt);
- 	      break;
- 
  	    default:
  	      break;
  	    }
--- 234,239 ----
*************** expand_complex_div_wide (gimple_stmt_ite
*** 1118,1124 ****
      {
        edge e;
        gimple stmt;
!       tree cond, tmp;
  
        tmp = create_tmp_var (boolean_type_node, NULL);
        stmt = gimple_build_assign (tmp, compare);
--- 1113,1119 ----
      {
        edge e;
        gimple stmt;
!       tree tmp;
  
        tmp = create_tmp_var (boolean_type_node, NULL);
        stmt = gimple_build_assign (tmp, compare);
*************** expand_complex_div_wide (gimple_stmt_ite
*** 1127,1138 ****
  	  tmp = make_ssa_name (tmp,  stmt);
  	  gimple_assign_set_lhs (stmt, tmp);
  	}
- 
        gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
  
!       cond = fold_build2_loc (gimple_location (stmt),
! 			  EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
!       stmt = gimple_build_cond_from_tree (cond, NULL_TREE, NULL_TREE);
        gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
  
        /* Split the original block, and create the TRUE and FALSE blocks.  */
--- 1122,1130 ----
  	  tmp = make_ssa_name (tmp,  stmt);
  	  gimple_assign_set_lhs (stmt, tmp);
  	}
        gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
  
!       stmt = gimple_build_cond (tmp, NULL_TREE, NULL_TREE);
        gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
  
        /* Split the original block, and create the TRUE and FALSE blocks.  */
*************** expand_complex_comparison (gimple_stmt_i
*** 1386,1397 ****
        stmt = gsi_stmt (*gsi);
        break;
  
-     case GIMPLE_COND:
-       gimple_cond_set_code (stmt, EQ_EXPR);
-       gimple_cond_set_lhs (stmt, cc);
-       gimple_cond_set_rhs (stmt, boolean_true_node);
-       break;
- 
      default:
        gcc_unreachable ();
      }
--- 1378,1383 ----
*************** expand_complex_operations_1 (gimple_stmt
*** 1412,1418 ****
    enum tree_code code;
  
    lhs = gimple_get_lhs (stmt);
!   if (!lhs && gimple_code (stmt) != GIMPLE_COND)
      return;
  
    type = TREE_TYPE (gimple_op (stmt, 0));
--- 1398,1404 ----
    enum tree_code code;
  
    lhs = gimple_get_lhs (stmt);
!   if (!lhs)
      return;
  
    type = TREE_TYPE (gimple_op (stmt, 0));
*************** expand_complex_operations_1 (gimple_stmt
*** 1449,1459 ****
        {
  	tree rhs;
  
- 	/* GIMPLE_COND may also fallthru here, but we do not need to
- 	   do anything with it.  */
- 	if (gimple_code (stmt) == GIMPLE_COND)
- 	  return;
- 
  	if (TREE_CODE (type) == COMPLEX_TYPE)
  	  expand_complex_move (gsi, type);
  	else if (is_gimple_assign (stmt)
--- 1435,1440 ----
*************** expand_complex_operations_1 (gimple_stmt
*** 1476,1492 ****
  
    /* Extract the components of the two complex values.  Make sure and
       handle the common case of the same value used twice specially.  */
!   if (is_gimple_assign (stmt))
!     {
!       ac = gimple_assign_rhs1 (stmt);
!       bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
!     }
!   /* GIMPLE_CALL can not get here.  */
!   else
!     {
!       ac = gimple_cond_lhs (stmt);
!       bc = gimple_cond_rhs (stmt);
!     }
  
    ar = extract_component (gsi, ac, false, true);
    ai = extract_component (gsi, ac, true, true);
--- 1457,1464 ----
  
    /* Extract the components of the two complex values.  Make sure and
       handle the common case of the same value used twice specially.  */
!   ac = gimple_assign_rhs1 (stmt);
!   bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
  
    ar = extract_component (gsi, ac, false, true);
    ai = extract_component (gsi, ac, true, true);
Index: trunk/gcc/tree-switch-conversion.c
===================================================================
*** trunk.orig/gcc/tree-switch-conversion.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-switch-conversion.c	2010-08-30 14:32:23.000000000 +0200
*************** gen_inbound_check (gimple swtch)
*** 680,686 ****
    tree cast;
    gimple cast_assign, minus_assign;
    tree ulb, minus;
!   tree bound;
  
    gimple cond_stmt;
  
--- 680,686 ----
    tree cast;
    gimple cast_assign, minus_assign;
    tree ulb, minus;
!   tree bound, cond;
  
    gimple cond_stmt;
  
*************** gen_inbound_check (gimple swtch)
*** 724,730 ****
    update_stmt (minus_assign);
  
    bound = fold_convert_loc (loc, utype, info.range_size);
!   cond_stmt = gimple_build_cond (LE_EXPR, tmp_u_2, bound, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
    update_stmt (cond_stmt);
  
--- 724,732 ----
    update_stmt (minus_assign);
  
    bound = fold_convert_loc (loc, utype, info.range_size);
!   cond = fold_build2 (LE_EXPR, boolean_type_node, tmp_u_2, bound);
!   cond = force_gimple_operand_gsi (&gsi, cond, true, NULL, true, GSI_SAME_STMT);
!   cond_stmt = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
    update_stmt (cond_stmt);
  
Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/cfgexpand.c	2010-08-30 14:32:23.000000000 +0200
*************** expand_gimple_cond (basic_block bb, gimp
*** 1607,1615 ****
    enum tree_code code;
    tree op0, op1;
  
!   code = gimple_cond_code (stmt);
!   op0 = gimple_cond_lhs (stmt);
!   op1 = gimple_cond_rhs (stmt);
    /* We're sometimes presented with such code:
         D.123_1 = x < y;
         if (D.123_1 != 0)
--- 1607,1615 ----
    enum tree_code code;
    tree op0, op1;
  
!   code = NE_EXPR;
!   op0 = gimple_cond_pred (stmt);
!   op1 = boolean_false_node;
    /* We're sometimes presented with such code:
         D.123_1 = x < y;
         if (D.123_1 != 0)
*************** expand_gimple_cond (basic_block bb, gimp
*** 1618,1625 ****
       be cleaned up by combine.  But some pattern matchers like if-conversion
       work better when there's only one compare, so make up for this
       here as special exception if TER would have made the same change.  */
!   if (gimple_cond_single_var_p (stmt)
!       && SA.values
        && TREE_CODE (op0) == SSA_NAME
        && bitmap_bit_p (SA.values, SSA_NAME_VERSION (op0)))
      {
--- 1618,1624 ----
       be cleaned up by combine.  But some pattern matchers like if-conversion
       work better when there's only one compare, so make up for this
       here as special exception if TER would have made the same change.  */
!   if (SA.values
        && TREE_CODE (op0) == SSA_NAME
        && bitmap_bit_p (SA.values, SSA_NAME_VERSION (op0)))
      {
Index: trunk/gcc/gimple-fold.c
===================================================================
*** trunk.orig/gcc/gimple-fold.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/gimple-fold.c	2010-08-30 14:32:23.000000000 +0200
*************** fold_gimple_assign (gimple_stmt_iterator
*** 571,605 ****
          if (TREE_CODE (rhs) == COND_EXPR)
            {
  	    tree op0 = COND_EXPR_COND (rhs);
- 	    tree tem;
- 	    bool set = false;
  	    location_t cond_loc = EXPR_LOCATION (rhs);
  
! 	    if (COMPARISON_CLASS_P (op0))
! 	      {
! 		fold_defer_overflow_warnings ();
! 		tem = fold_binary_loc (cond_loc,
! 				   TREE_CODE (op0), TREE_TYPE (op0),
! 				   TREE_OPERAND (op0, 0),
! 				   TREE_OPERAND (op0, 1));
! 		/* This is actually a conditional expression, not a GIMPLE
! 		   conditional statement, however, the valid_gimple_rhs_p
! 		   test still applies.  */
! 		set = (tem && is_gimple_condexpr (tem)
! 		       && valid_gimple_rhs_p (tem));
! 		fold_undefer_overflow_warnings (set, stmt, 0);
! 	      }
! 	    else if (is_gimple_min_invariant (op0))
! 	      {
! 		tem = op0;
! 		set = true;
! 	      }
! 	    else
  	      return NULL_TREE;
  
! 	    if (set)
! 	      result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), tem,
! 				    COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
            }
  
  	else if (TREE_CODE (rhs) == TARGET_MEM_REF)
--- 571,583 ----
          if (TREE_CODE (rhs) == COND_EXPR)
            {
  	    tree op0 = COND_EXPR_COND (rhs);
  	    location_t cond_loc = EXPR_LOCATION (rhs);
  
! 	    if (!is_gimple_min_invariant (op0))
  	      return NULL_TREE;
  
! 	    result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), op0,
! 				      COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
            }
  
  	else if (TREE_CODE (rhs) == TARGET_MEM_REF)
*************** fold_gimple_assign (gimple_stmt_iterator
*** 783,800 ****
  static bool
  fold_gimple_cond (gimple stmt)
  {
!   tree result = fold_binary_loc (gimple_location (stmt),
! 			     gimple_cond_code (stmt),
!                              boolean_type_node,
!                              gimple_cond_lhs (stmt),
!                              gimple_cond_rhs (stmt));
  
    if (result)
      {
        STRIP_USELESS_TYPE_CONVERSION (result);
!       if (is_gimple_condexpr (result) && valid_gimple_rhs_p (result))
          {
!           gimple_cond_set_condition_from_tree (stmt, result);
            return true;
          }
      }
--- 761,778 ----
  static bool
  fold_gimple_cond (gimple stmt)
  {
!   enum tree_code code;
!   tree lhs, rhs, result;
  
+   gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
+   result = fold_binary_loc (gimple_location (stmt), code,
+ 			    boolean_type_node, lhs, rhs);
    if (result)
      {
        STRIP_USELESS_TYPE_CONVERSION (result);
!       if (is_gimple_val (result))
          {
!           gimple_cond_set_pred (stmt, result);
            return true;
          }
      }
Index: trunk/gcc/gimple-pretty-print.c
===================================================================
*** trunk.orig/gcc/gimple-pretty-print.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/gimple-pretty-print.c	2010-08-30 14:32:23.000000000 +0200
*************** static void
*** 674,692 ****
  dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
  {
    if (flags & TDF_RAW)
!     dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
!                    tree_code_name [gimple_cond_code (gs)],
!                    gimple_cond_lhs (gs), gimple_cond_rhs (gs),
                     gimple_cond_true_label (gs), gimple_cond_false_label (gs));
    else
      {
        if (!(flags & TDF_RHS_ONLY))
  	pp_string (buffer, "if (");
!       dump_generic_node (buffer, gimple_cond_lhs (gs), spc, flags, false);
!       pp_space (buffer);
!       pp_string (buffer, op_symbol_code (gimple_cond_code (gs)));
!       pp_space (buffer);
!       dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags, false);
        if (!(flags & TDF_RHS_ONLY))
  	{
  	  pp_character (buffer, ')');
--- 674,687 ----
  dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
  {
    if (flags & TDF_RAW)
!     dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T, %T>", gs,
!                    gimple_cond_pred (gs),
                     gimple_cond_true_label (gs), gimple_cond_false_label (gs));
    else
      {
        if (!(flags & TDF_RHS_ONLY))
  	pp_string (buffer, "if (");
!       dump_generic_node (buffer, gimple_cond_pred (gs), spc, flags, false);
        if (!(flags & TDF_RHS_ONLY))
  	{
  	  pp_character (buffer, ')');
Index: trunk/gcc/graphite-scop-detection.c
===================================================================
*** trunk.orig/gcc/graphite-scop-detection.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/graphite-scop-detection.c	2010-08-30 14:32:23.000000000 +0200
*************** stmt_has_simple_data_refs_p (loop_p oute
*** 305,314 ****
  
  static bool
  stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop,
! 			gimple stmt, basic_block bb)
  {
-   loop_p loop = bb->loop_father;
- 
    gcc_assert (scop_entry);
  
    /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
--- 305,312 ----
  
  static bool
  stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop,
! 			gimple stmt, basic_block bb ATTRIBUTE_UNUSED)
  {
    gcc_assert (scop_entry);
  
    /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
*************** stmt_simple_for_scop_p (basic_block scop
*** 333,364 ****
        return true;
  
      case GIMPLE_COND:
!       {
! 	tree op;
! 	ssa_op_iter op_iter;
!         enum tree_code code = gimple_cond_code (stmt);
! 
! 	/* We can handle all binary comparisons.  Inequalities are
! 	   also supported as they can be represented with union of
! 	   polyhedra.  */
!         if (!(code == LT_EXPR
! 	      || code == GT_EXPR
! 	      || code == LE_EXPR
! 	      || code == GE_EXPR
! 	      || code == EQ_EXPR
! 	      || code == NE_EXPR))
!           return false;
! 
! 	FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
! 	  if (!graphite_can_represent_expr (scop_entry, loop, outermost_loop,
! 					    op)
! 	      /* We can not handle REAL_TYPE. Failed for pr39260.  */
! 	      || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE)
! 	    return false;
! 
! 	return true;
!       }
! 
      case GIMPLE_ASSIGN:
      case GIMPLE_CALL:
        return true;
--- 331,338 ----
        return true;
  
      case GIMPLE_COND:
!       /* ???  We tested for handled comparisons here but I cannot see
!          a test for comparisons in assignment rhs.  */
      case GIMPLE_ASSIGN:
      case GIMPLE_CALL:
        return true;
Index: trunk/gcc/graphite-sese-to-poly.c
===================================================================
*** trunk.orig/gcc/graphite-sese-to-poly.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/graphite-sese-to-poly.c	2010-08-30 14:32:23.000000000 +0200
*************** find_params_in_bb (sese region, gimple_b
*** 962,972 ****
    /* Find parameters in conditional statements.  */
    FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
      {
!       tree lhs = scalar_evolution_in_region (region, loop,
! 					     gimple_cond_lhs (stmt));
!       tree rhs = scalar_evolution_in_region (region, loop,
! 					     gimple_cond_rhs (stmt));
! 
        scan_tree_for_params (region, lhs, NULL, one);
        scan_tree_for_params (region, rhs, NULL, one);
      }
--- 962,972 ----
    /* Find parameters in conditional statements.  */
    FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
      {
!       enum tree_code code;
!       tree lhs, rhs;
!       gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
!       lhs = scalar_evolution_in_region (region, loop, lhs);
!       rhs = scalar_evolution_in_region (region, loop, rhs);
        scan_tree_for_params (region, lhs, NULL, one);
        scan_tree_for_params (region, rhs, NULL, one);
      }
*************** add_condition_to_domain (ppl_Pointset_Po
*** 1258,1266 ****
    ppl_Linear_Expression_t left, right;
    ppl_Constraint_t cstr;
    enum ppl_enum_Constraint_Type type;
  
!   left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
!   right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
  
    /* If we have < or > expressions convert them to <= or >= by adding 1 to
       the left or the right side of the expression. */
--- 1258,1270 ----
    ppl_Linear_Expression_t left, right;
    ppl_Constraint_t cstr;
    enum ppl_enum_Constraint_Type type;
+   enum tree_code dummy_code;
+   tree lhs, rhs;
+ 
+   gimple_cond_extract_comparison (stmt, &dummy_code, &lhs, &rhs);
  
!   left = create_linear_expr_from_tree (pbb, lhs);
!   right = create_linear_expr_from_tree (pbb, rhs);
  
    /* If we have < or > expressions convert them to <= or >= by adding 1 to
       the left or the right side of the expression. */
*************** add_conditions_to_domain (poly_bb_p pbb)
*** 1340,1346 ****
        {
        case GIMPLE_COND:
  	  {
! 	    enum tree_code code = gimple_cond_code (stmt);
  
  	    /* The conditions for ELSE-branches are inverted.  */
  	    if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
--- 1344,1353 ----
        {
        case GIMPLE_COND:
  	  {
! 	    enum tree_code code;
! 	    tree lhs, rhs;
! 
! 	    gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
  
  	    /* The conditions for ELSE-branches are inverted.  */
  	    if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
Index: trunk/gcc/predict.c
===================================================================
*** trunk.orig/gcc/predict.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/predict.c	2010-08-30 14:32:23.000000000 +0200
*************** tree_predict_by_opcode (basic_block bb)
*** 1358,1366 ****
    FOR_EACH_EDGE (then_edge, ei, bb->succs)
      if (then_edge->flags & EDGE_TRUE_VALUE)
        break;
!   op0 = gimple_cond_lhs (stmt);
!   op1 = gimple_cond_rhs (stmt);
!   cmp = gimple_cond_code (stmt);
    type = TREE_TYPE (op0);
    visited = BITMAP_ALLOC (NULL);
    val = expr_expected_value_1 (boolean_type_node, op0, cmp, op1, visited);
--- 1358,1364 ----
    FOR_EACH_EDGE (then_edge, ei, bb->succs)
      if (then_edge->flags & EDGE_TRUE_VALUE)
        break;
!   gimple_cond_extract_comparison (stmt, &cmp, &op0, &op1);
    type = TREE_TYPE (op0);
    visited = BITMAP_ALLOC (NULL);
    val = expr_expected_value_1 (boolean_type_node, op0, cmp, op1, visited);
Index: trunk/gcc/sese.c
===================================================================
*** trunk.orig/gcc/sese.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/sese.c	2010-08-30 14:32:23.000000000 +0200
*************** set_ifsese_condition (ifsese if_region,
*** 772,778 ****
    gsi = gsi_last_bb (bb);
    condition = force_gimple_operand_gsi (&gsi, condition, true, NULL,
  					false, GSI_NEW_STMT);
!   cond_stmt = gimple_build_cond_from_tree (condition, NULL_TREE, NULL_TREE);
    gsi = gsi_last_bb (bb);
    gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
  }
--- 772,778 ----
    gsi = gsi_last_bb (bb);
    condition = force_gimple_operand_gsi (&gsi, condition, true, NULL,
  					false, GSI_NEW_STMT);
!   cond_stmt = gimple_build_cond (condition, NULL_TREE, NULL_TREE);
    gsi = gsi_last_bb (bb);
    gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
  }
Index: trunk/gcc/tree-cfgcleanup.c
===================================================================
*** trunk.orig/gcc/tree-cfgcleanup.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-cfgcleanup.c	2010-08-30 14:32:23.000000000 +0200
*************** cleanup_control_expr_graph (basic_block
*** 87,131 ****
        edge e;
        edge_iterator ei;
        bool warned;
-       location_t loc;
  
        fold_defer_overflow_warnings ();
-       loc = gimple_location (stmt);
        switch (gimple_code (stmt))
  	{
  	case GIMPLE_COND:
  	  {
! 	    tree lhs = gimple_cond_lhs (stmt);
! 	    tree rhs = gimple_cond_rhs (stmt);
  	    /* For conditions try harder and lookup single-argument
  	       PHI nodes.  Only do so from the same basic-block though
  	       as other basic-blocks may be dead already.  */
! 	    if (TREE_CODE (lhs) == SSA_NAME
! 		&& !name_registered_for_update_p (lhs))
  	      {
! 		gimple def_stmt = SSA_NAME_DEF_STMT (lhs);
  		if (gimple_code (def_stmt) == GIMPLE_PHI
  		    && gimple_phi_num_args (def_stmt) == 1
  		    && gimple_bb (def_stmt) == gimple_bb (stmt)
  		    && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
  			|| !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
  								       0))))
! 		  lhs = PHI_ARG_DEF (def_stmt, 0);
  	      }
- 	    if (TREE_CODE (rhs) == SSA_NAME
- 		&& !name_registered_for_update_p (rhs))
- 	      {
- 		gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
- 		if (gimple_code (def_stmt) == GIMPLE_PHI
- 		    && gimple_phi_num_args (def_stmt) == 1
- 		    && gimple_bb (def_stmt) == gimple_bb (stmt)
- 		    && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
- 			|| !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
- 								       0))))
- 		  rhs = PHI_ARG_DEF (def_stmt, 0);
- 	      }
- 	    val = fold_binary_loc (loc, gimple_cond_code (stmt),
- 				   boolean_type_node, lhs, rhs);
  	    break;
  	  }
  
--- 87,114 ----
        edge e;
        edge_iterator ei;
        bool warned;
  
        fold_defer_overflow_warnings ();
        switch (gimple_code (stmt))
  	{
  	case GIMPLE_COND:
  	  {
! 	    val = gimple_cond_pred (stmt);
  	    /* For conditions try harder and lookup single-argument
  	       PHI nodes.  Only do so from the same basic-block though
  	       as other basic-blocks may be dead already.  */
! 	    if (TREE_CODE (val) == SSA_NAME
! 		&& !name_registered_for_update_p (val))
  	      {
! 		gimple def_stmt = SSA_NAME_DEF_STMT (val);
  		if (gimple_code (def_stmt) == GIMPLE_PHI
  		    && gimple_phi_num_args (def_stmt) == 1
  		    && gimple_bb (def_stmt) == gimple_bb (stmt)
  		    && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
  			|| !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
  								       0))))
! 		  val = PHI_ARG_DEF (def_stmt, 0);
  	      }
  	    break;
  	  }
  
Index: trunk/gcc/tree-flow.h
===================================================================
*** trunk.orig/gcc/tree-flow.h	2010-08-29 16:30:26.000000000 +0200
--- trunk/gcc/tree-flow.h	2010-08-30 14:32:23.000000000 +0200
*************** extern tree gimplify_build3 (gimple_stmt
*** 461,467 ****
  			     tree, tree, tree, tree);
  extern void init_empty_tree_cfg (void);
  extern void init_empty_tree_cfg_for_function (struct function *);
- extern void fold_cond_expr_cond (void);
  extern void make_abnormal_goto_edges (basic_block, bool);
  extern void replace_uses_by (tree, tree);
  extern void start_recording_case_labels (void);
--- 461,466 ----
Index: trunk/gcc/tree-if-conv.c
===================================================================
*** trunk.orig/gcc/tree-if-conv.c	2010-08-25 11:22:16.000000000 +0200
--- trunk/gcc/tree-if-conv.c	2010-08-30 14:32:23.000000000 +0200
*************** predicate_bbs (loop_p loop)
*** 918,927 ****
  		tree c2;
  		edge true_edge, false_edge;
  		location_t loc = gimple_location (stmt);
! 		tree c = fold_build2_loc (loc, gimple_cond_code (stmt),
! 					  boolean_type_node,
! 					  gimple_cond_lhs (stmt),
! 					  gimple_cond_rhs (stmt));
  
  		/* Add new condition into destination's predicate list.  */
  		extract_true_false_edges_from_block (gimple_bb (stmt),
--- 918,924 ----
  		tree c2;
  		edge true_edge, false_edge;
  		location_t loc = gimple_location (stmt);
! 		tree c = gimple_cond_pred (stmt);
  
  		/* Add new condition into destination's predicate list.  */
  		extract_true_false_edges_from_block (gimple_bb (stmt),
Index: trunk/gcc/tree-inline.c
===================================================================
*** trunk.orig/gcc/tree-inline.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-inline.c	2010-08-30 14:32:23.000000000 +0200
*************** estimate_num_insns (gimple stmt, eni_wei
*** 3451,3459 ****
        break;
  
      case GIMPLE_COND:
!       cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights,
!       				         gimple_op (stmt, 0),
! 				         gimple_op (stmt, 1));
        break;
  
      case GIMPLE_SWITCH:
--- 3451,3457 ----
        break;
  
      case GIMPLE_COND:
!       cost = 1;
        break;
  
      case GIMPLE_SWITCH:
*************** optimize_inline_calls (tree fn)
*** 4226,4232 ****
    /* Renumber the lexical scoping (non-code) blocks consecutively.  */
    number_blocks (fn);
  
-   fold_cond_expr_cond ();
    delete_unreachable_blocks_update_callgraph (&id);
  #ifdef ENABLE_CHECKING
    verify_cgraph_node (id.dst_node);
--- 4224,4229 ----
*************** tree_function_versioning (tree old_decl,
*** 5166,5172 ****
  
    fold_marked_statements (0, id.statements_to_fold);
    pointer_set_destroy (id.statements_to_fold);
-   fold_cond_expr_cond ();
    delete_unreachable_blocks_update_callgraph (&id);
    if (id.dst_node->analyzed)
      cgraph_rebuild_references ();
--- 5163,5168 ----
Index: trunk/gcc/tree-optimize.c
===================================================================
*** trunk.orig/gcc/tree-optimize.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-optimize.c	2010-08-30 14:32:23.000000000 +0200
*************** struct gimple_opt_pass pass_cleanup_cfg
*** 189,195 ****
  static unsigned int
  execute_cleanup_cfg_post_optimizing (void)
  {
-   fold_cond_expr_cond ();
    cleanup_tree_cfg ();
    cleanup_dead_labels ();
    group_case_labels ();
--- 189,194 ----
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c	2010-08-30 14:32:23.000000000 +0200
*************** ccp_fold (gimple stmt)
*** 1292,1302 ****
  
      case GIMPLE_COND:
        {
!         /* Handle comparison operators that can appear in GIMPLE form.  */
!         tree op0 = valueize_op (gimple_cond_lhs (stmt));
!         tree op1 = valueize_op (gimple_cond_rhs (stmt));
!         enum tree_code code = gimple_cond_code (stmt);
!         return fold_binary_loc (loc, code, boolean_type_node, op0, op1);
        }
  
      case GIMPLE_SWITCH:
--- 1292,1299 ----
  
      case GIMPLE_COND:
        {
!         /* Return the constant predicate.  */
!         return valueize_op (gimple_cond_pred (stmt));
        }
  
      case GIMPLE_SWITCH:
*************** bit_value_binop_1 (enum tree_code code,
*** 1827,1832 ****
--- 1824,1833 ----
  	if (double_int_negative_p (r1mask) || double_int_negative_p (r2mask))
  	  break;
  
+ 	/* Signedness is determined by the first operand, not the result.  */
+ 	uns = (TREE_CODE (r1type) == INTEGER_TYPE
+ 	       && TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type));
+ 
  	/* If we know the most significant bits we know the values
  	   value ranges by means of treating varying bits as zero
  	   or one.  Do a cross comparison of the max/min pairs.  */
*************** evaluate_stmt (gimple stmt)
*** 2042,2064 ****
  		  || POINTER_TYPE_P (TREE_TYPE (rhs1)))
  		{
  		  tree rhs2 = gimple_assign_rhs2 (stmt);
! 		  val = bit_value_binop (subcode,
! 					 TREE_TYPE (rhs1), rhs1, rhs2);
  		}
  	      break;
  
  	    default:;
  	    }
  	}
-       else if (code == GIMPLE_COND)
- 	{
- 	  enum tree_code code = gimple_cond_code (stmt);
- 	  tree rhs1 = gimple_cond_lhs (stmt);
- 	  tree rhs2 = gimple_cond_rhs (stmt);
- 	  if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
- 	      || POINTER_TYPE_P (TREE_TYPE (rhs1)))
- 	    val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2);
- 	}
        else if (code == GIMPLE_CALL
  	       && (fndecl = gimple_call_fndecl (stmt))
  	       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
--- 2043,2056 ----
  		  || POINTER_TYPE_P (TREE_TYPE (rhs1)))
  		{
  		  tree rhs2 = gimple_assign_rhs2 (stmt);
! 		  val = bit_value_binop (subcode, gimple_expr_type (stmt),
! 					 rhs1, rhs2);
  		}
  	      break;
  
  	    default:;
  	    }
  	}
        else if (code == GIMPLE_CALL
  	       && (fndecl = gimple_call_fndecl (stmt))
  	       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
*************** ccp_fold_stmt (gimple_stmt_iterator *gsi
*** 2132,2146 ****
  	    || !double_int_zero_p (val.mask))
  	  return false;
  
- 	if (dump_file)
- 	  {
- 	    fprintf (dump_file, "Folding predicate ");
- 	    print_gimple_expr (dump_file, stmt, 0, 0);
- 	    fprintf (dump_file, " to ");
- 	    print_generic_expr (dump_file, val.value, 0);
- 	    fprintf (dump_file, "\n");
- 	  }
- 
  	if (integer_zerop (val.value))
  	  gimple_cond_make_false (stmt);
  	else
--- 2124,2129 ----
Index: trunk/gcc/tree-ssa-copy.c
===================================================================
*** trunk.orig/gcc/tree-ssa-copy.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-copy.c	2010-08-30 14:32:23.000000000 +0200
*************** propagate_tree_value_into_stmt (gimple_s
*** 247,258 ****
      }
    else if (gimple_code (stmt) == GIMPLE_COND)
      {
!       tree lhs = NULL_TREE;
!       tree rhs = fold_convert (TREE_TYPE (val), integer_zero_node);
!       propagate_tree_value (&lhs, val);
!       gimple_cond_set_code (stmt, NE_EXPR);
!       gimple_cond_set_lhs (stmt, lhs);
!       gimple_cond_set_rhs (stmt, rhs);
      }
    else if (is_gimple_call (stmt)
             && gimple_call_lhs (stmt) != NULL_TREE)
--- 247,255 ----
      }
    else if (gimple_code (stmt) == GIMPLE_COND)
      {
!       tree pred = NULL_TREE;
!       propagate_tree_value (&pred, val);
!       gimple_cond_set_pred (stmt, pred);
      }
    else if (is_gimple_call (stmt)
             && gimple_call_lhs (stmt) != NULL_TREE)
*************** copy_prop_visit_assignment (gimple stmt,
*** 412,434 ****
    tree lhs, rhs;
  
    lhs = gimple_assign_lhs (stmt);
-   rhs = valueize_val (gimple_assign_rhs1 (stmt));
  
!   if (TREE_CODE (lhs) == SSA_NAME)
      {
!       /* Straight copy between two SSA names.  First, make sure that
! 	 we can propagate the RHS into uses of LHS.  */
!       if (!may_propagate_copy (lhs, rhs))
  	return SSA_PROP_VARYING;
- 
-       *result_p = lhs;
-       if (set_copy_of_val (*result_p, rhs))
- 	return SSA_PROP_INTERESTING;
-       else
- 	return SSA_PROP_NOT_INTERESTING;
      }
  
!   return SSA_PROP_VARYING;
  }
  
  
--- 409,442 ----
    tree lhs, rhs;
  
    lhs = gimple_assign_lhs (stmt);
  
!   if (gimple_assign_single_p (stmt)
!       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
! 	  || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
!     rhs = valueize_val (gimple_assign_rhs1 (stmt));
!   else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
      {
!       tree op0 = valueize_val (gimple_assign_rhs1 (stmt));
!       tree op1 = valueize_val (gimple_assign_rhs2 (stmt));
!       rhs = fold_binary (gimple_assign_rhs_code (stmt),
! 			 boolean_type_node, op0, op1);
!       if (!rhs
! 	  || TREE_CODE (rhs) != INTEGER_CST)
  	return SSA_PROP_VARYING;
      }
+   else
+     return SSA_PROP_VARYING;
  
!   /* Straight copy between two SSA names.  First, make sure that
!      we can propagate the RHS into uses of LHS.  */
!   if (!may_propagate_copy (lhs, rhs))
!     return SSA_PROP_VARYING;
! 
!   *result_p = lhs;
!   if (set_copy_of_val (*result_p, rhs))
!     return SSA_PROP_INTERESTING;
!   else
!     return SSA_PROP_NOT_INTERESTING;
  }
  
  
*************** static enum ssa_prop_result
*** 440,479 ****
  copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
  {
    enum ssa_prop_result retval = SSA_PROP_VARYING;
!   location_t loc = gimple_location (stmt);
! 
!   tree op0 = gimple_cond_lhs (stmt);
!   tree op1 = gimple_cond_rhs (stmt);
  
!   /* The only conditionals that we may be able to compute statically
!      are predicates involving two SSA_NAMEs.  */
!   if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
      {
!       op0 = valueize_val (op0);
!       op1 = valueize_val (op1);
  
!       /* See if we can determine the predicate's value.  */
!       if (dump_file && (dump_flags & TDF_DETAILS))
! 	{
! 	  fprintf (dump_file, "Trying to determine truth value of ");
! 	  fprintf (dump_file, "predicate ");
! 	  print_gimple_stmt (dump_file, stmt, 0, 0);
! 	}
! 
!       /* We can fold COND and get a useful result only when we have
! 	 the same SSA_NAME on both sides of a comparison operator.  */
!       if (op0 == op1)
! 	{
! 	  tree folded_cond = fold_binary_loc (loc, gimple_cond_code (stmt),
!                                           boolean_type_node, op0, op1);
! 	  if (folded_cond)
! 	    {
! 	      basic_block bb = gimple_bb (stmt);
! 	      *taken_edge_p = find_taken_edge (bb, folded_cond);
! 	      if (*taken_edge_p)
! 		retval = SSA_PROP_INTERESTING;
! 	    }
! 	}
      }
  
    if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
--- 448,469 ----
  copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
  {
    enum ssa_prop_result retval = SSA_PROP_VARYING;
!   tree pred = valueize_val (gimple_cond_pred (stmt));
  
!   /* See if we can determine the predicate's value.  */
!   if (dump_file && (dump_flags & TDF_DETAILS))
      {
!       fprintf (dump_file, "Trying to determine truth value of ");
!       fprintf (dump_file, "predicate ");
!       print_gimple_stmt (dump_file, stmt, 0, 0);
!     }
  
!   if (TREE_CODE (pred) == INTEGER_CST)
!     {
!       basic_block bb = gimple_bb (stmt);
!       *taken_edge_p = find_taken_edge (bb, pred);
!       if (*taken_edge_p)
! 	retval = SSA_PROP_INTERESTING;
      }
  
    if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
*************** copy_prop_visit_stmt (gimple stmt, edge
*** 506,515 ****
        fprintf (dump_file, "\n");
      }
  
!   if (gimple_assign_single_p (stmt)
!       && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
!       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
! 	  || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
      {
        /* If the statement is a copy assignment, evaluate its RHS to
  	 see if the lattice value of its output has changed.  */
--- 496,503 ----
        fprintf (dump_file, "\n");
      }
  
!   if (is_gimple_assign (stmt)
!       && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
      {
        /* If the statement is a copy assignment, evaluate its RHS to
  	 see if the lattice value of its output has changed.  */
Index: trunk/gcc/tree-ssa-dom.c
===================================================================
*** trunk.orig/gcc/tree-ssa-dom.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-dom.c	2010-08-30 14:32:23.000000000 +0200
*************** DEF_VEC_ALLOC_O(cond_equivalence,heap);
*** 96,106 ****
  
  struct edge_info
  {
-   /* If this edge creates a simple equivalence, the LHS and RHS of
-      the equivalence will be stored here.  */
-   tree lhs;
-   tree rhs;
- 
    /* Traversing an edge may also indicate one or more particular conditions
       are true or false.  */
    VEC(cond_equivalence, heap) *cond_equivalences;
--- 96,101 ----
*************** initialize_hash_element (gimple stmt, tr
*** 244,253 ****
    else if (code == GIMPLE_COND)
      {
        expr->type = boolean_type_node;
!       expr->kind = EXPR_BINARY;
!       expr->ops.binary.op = gimple_cond_code (stmt);
!       expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
!       expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
      }
    else if (code == GIMPLE_CALL)
      {
--- 239,246 ----
    else if (code == GIMPLE_COND)
      {
        expr->type = boolean_type_node;
!       expr->kind = EXPR_SINGLE;
!       expr->ops.single.rhs = gimple_cond_pred (stmt);
      }
    else if (code == GIMPLE_CALL)
      {
*************** canonicalize_comparison (gimple condstmt
*** 817,828 ****
    tree op1;
    enum tree_code code;
  
!   gcc_assert (gimple_code (condstmt) == GIMPLE_COND);
  
!   op0 = gimple_cond_lhs (condstmt);
!   op1 = gimple_cond_rhs (condstmt);
! 
!   code = gimple_cond_code (condstmt);
  
    /* If it would be profitable to swap the operands, then do so to
       canonicalize the statement, enabling better optimization.
--- 810,819 ----
    tree op1;
    enum tree_code code;
  
!   op0 = gimple_assign_rhs1 (condstmt);
!   op1 = gimple_assign_rhs2 (condstmt);
  
!   code = gimple_assign_rhs_code (condstmt);
  
    /* If it would be profitable to swap the operands, then do so to
       canonicalize the statement, enabling better optimization.
*************** canonicalize_comparison (gimple condstmt
*** 841,849 ****
  	{
            code = swap_tree_comparison (code);
  
!           gimple_cond_set_code (condstmt, code);
!           gimple_cond_set_lhs (condstmt, op1);
!           gimple_cond_set_rhs (condstmt, op0);
  
            update_stmt (condstmt);
  	}
--- 832,840 ----
  	{
            code = swap_tree_comparison (code);
  
!           gimple_assign_set_rhs_code (condstmt, code);
!           gimple_assign_set_rhs1 (condstmt, op1);
!           gimple_assign_set_rhs2 (condstmt, op0);
  
            update_stmt (condstmt);
  	}
*************** dom_thread_across_edge (struct dom_walk_
*** 933,942 ****
  {
    if (! walk_data->global_data)
    {
!     gimple dummy_cond =
!         gimple_build_cond (NE_EXPR,
!                            integer_zero_node, integer_zero_node,
!                            NULL, NULL);
      walk_data->global_data = dummy_cond;
    }
  
--- 924,930 ----
  {
    if (! walk_data->global_data)
    {
!     gimple dummy_cond = gimple_build_cond (boolean_false_node, NULL, NULL);
      walk_data->global_data = dummy_cond;
    }
  
*************** record_equivalences_from_incoming_edge (
*** 1057,1072 ****
  
        if (edge_info)
  	{
- 	  tree lhs = edge_info->lhs;
- 	  tree rhs = edge_info->rhs;
  	  cond_equivalence *eq;
  
- 	  if (lhs)
- 	    record_equality (lhs, rhs);
- 
  	  for (i = 0; VEC_iterate (cond_equivalence,
  				   edge_info->cond_equivalences, i, eq); ++i)
! 	    record_cond (eq);
  	}
      }
  }
--- 1045,1061 ----
  
        if (edge_info)
  	{
  	  cond_equivalence *eq;
  
  	  for (i = 0; VEC_iterate (cond_equivalence,
  				   edge_info->cond_equivalences, i, eq); ++i)
! 	    {
! 	      if (eq->cond.ops.binary.op == EQ_EXPR
! 		  && eq->value == boolean_true_node)
! 		record_equality (eq->cond.ops.binary.opnd0,
! 				 eq->cond.ops.binary.opnd1);
! 	      record_cond (eq);
! 	    }
  	}
      }
  }
*************** static void
*** 1491,1497 ****
  record_edge_info (basic_block bb)
  {
    gimple_stmt_iterator gsi = gsi_last_bb (bb);
-   struct edge_info *edge_info;
  
    if (! gsi_end_p (gsi))
      {
--- 1480,1485 ----
*************** record_edge_info (basic_block bb)
*** 1501,1506 ****
--- 1489,1495 ----
        if (gimple_code (stmt) == GIMPLE_SWITCH)
  	{
  	  tree index = gimple_switch_index (stmt);
+ 	  struct edge_info *edge_info;
  
  	  if (TREE_CODE (index) == SSA_NAME)
  	    {
*************** record_edge_info (basic_block bb)
*** 1532,1539 ****
  		      tree x = fold_convert_loc (loc, TREE_TYPE (index),
  						 CASE_LOW (label));
  		      edge_info = allocate_edge_info (e);
! 		      edge_info->lhs = index;
! 		      edge_info->rhs = x;
  		    }
  		}
  	      free (info);
--- 1521,1528 ----
  		      tree x = fold_convert_loc (loc, TREE_TYPE (index),
  						 CASE_LOW (label));
  		      edge_info = allocate_edge_info (e);
! 		      build_and_record_new_cond (EQ_EXPR, index, x,
! 						 &edge_info->cond_equivalences);
  		    }
  		}
  	      free (info);
*************** record_edge_info (basic_block bb)
*** 1543,1619 ****
        /* A COND_EXPR may create equivalences too.  */
        if (gimple_code (stmt) == GIMPLE_COND)
  	{
  	  edge true_edge;
  	  edge false_edge;
  
!           tree op0 = gimple_cond_lhs (stmt);
!           tree op1 = gimple_cond_rhs (stmt);
!           enum tree_code code = gimple_cond_code (stmt);
! 
  	  extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
  
!           /* Special case comparing booleans against a constant as we
!              know the value of OP0 on both arms of the branch.  i.e., we
!              can record an equivalence for OP0 rather than COND.  */
!           if ((code == EQ_EXPR || code == NE_EXPR)
!               && TREE_CODE (op0) == SSA_NAME
!               && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
!               && is_gimple_min_invariant (op1))
!             {
!               if (code == EQ_EXPR)
!                 {
!                   edge_info = allocate_edge_info (true_edge);
!                   edge_info->lhs = op0;
!                   edge_info->rhs = (integer_zerop (op1)
!                                     ? boolean_false_node
!                                     : boolean_true_node);
! 
!                   edge_info = allocate_edge_info (false_edge);
!                   edge_info->lhs = op0;
!                   edge_info->rhs = (integer_zerop (op1)
!                                     ? boolean_true_node
!                                     : boolean_false_node);
!                 }
!               else
!                 {
!                   edge_info = allocate_edge_info (true_edge);
!                   edge_info->lhs = op0;
!                   edge_info->rhs = (integer_zerop (op1)
!                                     ? boolean_true_node
!                                     : boolean_false_node);
! 
!                   edge_info = allocate_edge_info (false_edge);
!                   edge_info->lhs = op0;
!                   edge_info->rhs = (integer_zerop (op1)
!                                     ? boolean_false_node
!                                     : boolean_true_node);
!                 }
!             }
!           else if (is_gimple_min_invariant (op0)
!                    && (TREE_CODE (op1) == SSA_NAME
!                        || is_gimple_min_invariant (op1)))
              {
                tree cond = build2 (code, boolean_type_node, op0, op1);
                tree inverted = invert_truthvalue_loc (loc, cond);
-               struct edge_info *edge_info;
- 
-               edge_info = allocate_edge_info (true_edge);
-               record_conditions (edge_info, cond, inverted);
  
!               if (code == EQ_EXPR)
!                 {
!                   edge_info->lhs = op1;
!                   edge_info->rhs = op0;
!                 }
! 
!               edge_info = allocate_edge_info (false_edge);
!               record_conditions (edge_info, inverted, cond);
! 
!               if (TREE_CODE (inverted) == EQ_EXPR)
!                 {
!                   edge_info->lhs = op1;
!                   edge_info->rhs = op0;
!                 }
              }
  
            else if (TREE_CODE (op0) == SSA_NAME
--- 1532,1558 ----
        /* A COND_EXPR may create equivalences too.  */
        if (gimple_code (stmt) == GIMPLE_COND)
  	{
+ 	  struct edge_info *t_edge_info = NULL, *f_edge_info = NULL;
  	  edge true_edge;
  	  edge false_edge;
+ 	  enum tree_code code;
+ 	  tree op0, op1;
  
! 	  gimple_cond_extract_comparison (stmt, &code, &op0, &op1);
  	  extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
  
! 	  t_edge_info = allocate_edge_info (true_edge);
! 	  f_edge_info = allocate_edge_info (false_edge);
! 
!           if (is_gimple_min_invariant (op0)
! 	      && (TREE_CODE (op1) == SSA_NAME
! 		  || is_gimple_min_invariant (op1)))
              {
                tree cond = build2 (code, boolean_type_node, op0, op1);
                tree inverted = invert_truthvalue_loc (loc, cond);
  
!               record_conditions (t_edge_info, cond, inverted);
!               record_conditions (f_edge_info, inverted, cond);
              }
  
            else if (TREE_CODE (op0) == SSA_NAME
*************** record_edge_info (basic_block bb)
*** 1622,1647 ****
              {
                tree cond = build2 (code, boolean_type_node, op0, op1);
                tree inverted = invert_truthvalue_loc (loc, cond);
-               struct edge_info *edge_info;
  
!               edge_info = allocate_edge_info (true_edge);
!               record_conditions (edge_info, cond, inverted);
! 
!               if (code == EQ_EXPR)
!                 {
!                   edge_info->lhs = op0;
!                   edge_info->rhs = op1;
!                 }
! 
!               edge_info = allocate_edge_info (false_edge);
!               record_conditions (edge_info, inverted, cond);
! 
!               if (TREE_CODE (inverted) == EQ_EXPR)
!                 {
!                   edge_info->lhs = op0;
!                   edge_info->rhs = op1;
!                 }
              }
          }
  
        /* ??? TRUTH_NOT_EXPR can create an equivalence too.  */
--- 1561,1587 ----
              {
                tree cond = build2 (code, boolean_type_node, op0, op1);
                tree inverted = invert_truthvalue_loc (loc, cond);
  
!               record_conditions (t_edge_info, cond, inverted);
!               record_conditions (f_edge_info, inverted, cond);
              }
+ 
+ 	  /* Record equivalences for the predicate itself.  */
+ 	  if (op0 != gimple_cond_pred (stmt))
+ 	    {
+ 	      build_and_record_new_cond (EQ_EXPR, gimple_cond_pred (stmt),
+ 					 boolean_true_node,
+ 					 &t_edge_info->cond_equivalences);
+ 	      build_and_record_new_cond (NE_EXPR, gimple_cond_pred (stmt),
+ 					 boolean_false_node,
+ 					 &t_edge_info->cond_equivalences);
+ 	      build_and_record_new_cond (EQ_EXPR, gimple_cond_pred (stmt),
+ 					 boolean_false_node,
+ 					 &f_edge_info->cond_equivalences);
+ 	      build_and_record_new_cond (NE_EXPR, gimple_cond_pred (stmt),
+ 					 boolean_true_node,
+ 					 &f_edge_info->cond_equivalences);
+ 	    }
          }
  
        /* ??? TRUTH_NOT_EXPR can create an equivalence too.  */
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1724,1741 ****
  	  if (edge_info)
  	    {
  	      cond_equivalence *eq;
- 	      tree lhs = edge_info->lhs;
- 	      tree rhs = edge_info->rhs;
- 
- 	      /* If we have a simple NAME = VALUE equivalence, record it.  */
- 	      if (lhs && TREE_CODE (lhs) == SSA_NAME)
- 		record_const_or_copy (lhs, rhs);
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
  	      for (i = 0; VEC_iterate (cond_equivalence,
  				       edge_info->cond_equivalences, i, eq); ++i)
! 		record_cond (eq);
  	    }
  
  	  dom_thread_across_edge (walk_data, true_edge);
--- 1664,1683 ----
  	  if (edge_info)
  	    {
  	      cond_equivalence *eq;
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
  	      for (i = 0; VEC_iterate (cond_equivalence,
  				       edge_info->cond_equivalences, i, eq); ++i)
! 		{
! 		  /* If we have a simple NAME = VAL equivalence, record it.  */
! 		  if (eq->cond.ops.binary.op == EQ_EXPR
! 		      && eq->value == boolean_true_node
! 		      && TREE_CODE (eq->cond.ops.binary.opnd0) == SSA_NAME)
! 		    record_const_or_copy (eq->cond.ops.binary.opnd0,
! 					  eq->cond.ops.binary.opnd1);
! 		  record_cond (eq);
! 		}
  	    }
  
  	  dom_thread_across_edge (walk_data, true_edge);
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1759,1776 ****
  	  if (edge_info)
  	    {
  	      cond_equivalence *eq;
- 	      tree lhs = edge_info->lhs;
- 	      tree rhs = edge_info->rhs;
- 
- 	      /* If we have a simple NAME = VALUE equivalence, record it.  */
- 	      if (lhs && TREE_CODE (lhs) == SSA_NAME)
- 		record_const_or_copy (lhs, rhs);
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
  	      for (i = 0; VEC_iterate (cond_equivalence,
  				       edge_info->cond_equivalences, i, eq); ++i)
! 		record_cond (eq);
  	    }
  
  	  /* Now thread the edge.  */
--- 1701,1720 ----
  	  if (edge_info)
  	    {
  	      cond_equivalence *eq;
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
  	      for (i = 0; VEC_iterate (cond_equivalence,
  				       edge_info->cond_equivalences, i, eq); ++i)
! 		{
! 		  /* If we have a simple NAME = VAL equivalence, record it.  */
! 		  if (eq->cond.ops.binary.op == EQ_EXPR
! 		      && eq->value == boolean_true_node
! 		      && TREE_CODE (eq->cond.ops.binary.opnd0) == SSA_NAME)
! 		    record_const_or_copy (eq->cond.ops.binary.opnd0,
! 					  eq->cond.ops.binary.opnd1);
! 		  record_cond (eq);
! 		}
  	    }
  
  	  /* Now thread the edge.  */
*************** optimize_stmt (basic_block bb, gimple_st
*** 2094,2102 ****
  
    old_stmt = stmt = gsi_stmt (si);
  
-   if (gimple_code (stmt) == GIMPLE_COND)
-     canonicalize_comparison (stmt);
- 
    update_stmt_if_modified (stmt);
    opt_stats.num_stmts++;
  
--- 2038,2043 ----
*************** optimize_stmt (basic_block bb, gimple_st
*** 2147,2152 ****
--- 2088,2097 ----
        modified_p = true;
      }
  
+   if (is_gimple_assign (stmt)
+       && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+     canonicalize_comparison (stmt);
+ 
    /* Check for redundant computations.  Do this optimization only
       for assignments that have no volatile ops and conditionals.  */
    may_optimize_p = (!gimple_has_volatile_ops (stmt)
*************** optimize_stmt (basic_block bb, gimple_st
*** 2216,2224 ****
        update_stmt_if_modified (stmt);
  
        if (gimple_code (stmt) == GIMPLE_COND)
!         val = fold_binary_loc (gimple_location (stmt),
! 			   gimple_cond_code (stmt), boolean_type_node,
!                            gimple_cond_lhs (stmt),  gimple_cond_rhs (stmt));
        else if (gimple_code (stmt) == GIMPLE_SWITCH)
  	val = gimple_switch_index (stmt);
  
--- 2161,2167 ----
        update_stmt_if_modified (stmt);
  
        if (gimple_code (stmt) == GIMPLE_COND)
!         val = gimple_cond_pred (stmt);
        else if (gimple_code (stmt) == GIMPLE_SWITCH)
  	val = gimple_switch_index (stmt);
  
*************** propagate_rhs_into_lhs (gimple stmt, tre
*** 2652,2662 ****
  	      tree val;
  
  	      if (gimple_code (use_stmt) == GIMPLE_COND)
!                 val = fold_binary_loc (gimple_location (use_stmt),
! 				   gimple_cond_code (use_stmt),
!                                    boolean_type_node,
!                                    gimple_cond_lhs (use_stmt),
!                                    gimple_cond_rhs (use_stmt));
                else if (gimple_code (use_stmt) == GIMPLE_SWITCH)
  		val = gimple_switch_index (use_stmt);
  	      else
--- 2595,2601 ----
  	      tree val;
  
  	      if (gimple_code (use_stmt) == GIMPLE_COND)
!                 val = gimple_cond_pred (use_stmt);
                else if (gimple_code (use_stmt) == GIMPLE_SWITCH)
  		val = gimple_switch_index (use_stmt);
  	      else
Index: trunk/gcc/tree-ssa-forwprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-forwprop.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-forwprop.c	2010-08-30 14:32:23.000000000 +0200
*************** combine_cond_expr_cond (location_t loc,
*** 387,492 ****
     Returns zero if no statement was changed, one if there were
     changes and two if cfg_cleanup needs to run.
  
!    This must be kept in sync with forward_propagate_into_cond.  */
  
  static int
  forward_propagate_into_gimple_cond (gimple stmt)
  {
!   int did_something = 0;
!   location_t loc = gimple_location (stmt);
! 
!   do {
!     tree tmp = NULL_TREE;
!     tree name = NULL_TREE, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
!     gimple def_stmt;
!     bool single_use0_p = false, single_use1_p = false;
!     enum tree_code code = gimple_cond_code (stmt);
! 
!     /* We can do tree combining on SSA_NAME and comparison expressions.  */
!     if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison)
!       {
! 	/* For comparisons use the first operand, that is likely to
! 	   simplify comparisons against constants.  */
! 	if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
! 	  {
! 	    name = gimple_cond_lhs (stmt);
! 	    def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
! 	    if (def_stmt && can_propagate_from (def_stmt))
! 	      {
! 		tree op1 = gimple_cond_rhs (stmt);
! 		rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
! 		tmp = combine_cond_expr_cond (loc, code, boolean_type_node,
! 					      rhs0, op1, !single_use0_p);
! 	      }
! 	  }
! 	/* If that wasn't successful, try the second operand.  */
! 	if (tmp == NULL_TREE
! 	    && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME)
! 	  {
! 	    tree op0 = gimple_cond_lhs (stmt);
! 	    name = gimple_cond_rhs (stmt);
! 	    def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
! 	    if (!def_stmt || !can_propagate_from (def_stmt))
! 	      return did_something;
! 
! 	    rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
! 	    tmp = combine_cond_expr_cond (loc, code, boolean_type_node, op0,
! 					  rhs1, !single_use1_p);
! 	  }
! 	/* If that wasn't successful either, try both operands.  */
! 	if (tmp == NULL_TREE
! 	    && rhs0 != NULL_TREE
! 	    && rhs1 != NULL_TREE)
! 	  tmp = combine_cond_expr_cond (loc, code, boolean_type_node, rhs0,
! 					fold_convert_loc (loc,
! 							  TREE_TYPE (rhs0),
! 							  rhs1),
! 					!(single_use0_p && single_use1_p));
!       }
! 
!     if (tmp)
!       {
! 	if (dump_file && tmp)
! 	  {
!             tree cond = build2 (gimple_cond_code (stmt),
! 				boolean_type_node,
! 				gimple_cond_lhs (stmt),
! 				gimple_cond_rhs (stmt));
! 	    fprintf (dump_file, "  Replaced '");
! 	    print_generic_expr (dump_file, cond, 0);
! 	    fprintf (dump_file, "' with '");
! 	    print_generic_expr (dump_file, tmp, 0);
! 	    fprintf (dump_file, "'\n");
! 	  }
! 
!         gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
! 	update_stmt (stmt);
  
! 	/* Remove defining statements.  */
! 	remove_prop_source_from_use (name, NULL);
  
! 	if (is_gimple_min_invariant (tmp))
! 	  did_something = 2;
! 	else if (did_something == 0)
! 	  did_something = 1;
  
! 	/* Continue combining.  */
! 	continue;
!       }
  
!     break;
!   } while (1);
  
!   return did_something;
  }
  
  
  /* Propagate from the ssa name definition statements of COND_EXPR
     in the rhs of statement STMT into the conditional if that simplifies it.
     Returns zero if no statement was changed, one if there were
!    changes and two if cfg_cleanup needs to run.
! 
!    This must be kept in sync with forward_propagate_into_gimple_cond.  */
  
  static int
  forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
--- 387,450 ----
     Returns zero if no statement was changed, one if there were
     changes and two if cfg_cleanup needs to run.
  
!    This does simple constant propagation into the predicate.  */
  
  static int
  forward_propagate_into_gimple_cond (gimple stmt)
  {
!   tree cond = gimple_cond_pred (stmt);
!   gimple def_stmt;
  
!   if (TREE_CODE (cond) != SSA_NAME)
!     return 0;
  
!   def_stmt = SSA_NAME_DEF_STMT (cond);
  
!   /* Forward propagate constants.  */
!   if (gimple_assign_single_p (def_stmt))
!     {
!       cond = gimple_assign_rhs1 (def_stmt);
!       if (integer_nonzerop (cond))
! 	{
! 	  gimple_cond_make_true (stmt);
! 	  update_stmt (stmt);
! 	  return 2;
! 	}
!       else if (integer_zerop (cond))
! 	{
! 	  gimple_cond_make_false (stmt);
! 	  update_stmt (stmt);
! 	  return 2;
! 	}
!     }
  
!   /* We can forward propagate !pred into the condition by
!      switching edges.  */
!   if (is_gimple_assign (def_stmt)
!       && gimple_assign_rhs_code (def_stmt) == TRUTH_NOT_EXPR)
!     {
!       edge_iterator ei;
!       edge e; 
!       gimple_cond_set_pred (stmt, gimple_assign_rhs1 (def_stmt));
!       FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
! 	{
! 	  if (e->flags & EDGE_TRUE_VALUE)
! 	    e->flags = (e->flags & ~EDGE_TRUE_VALUE) | EDGE_FALSE_VALUE;
! 	  else
! 	    e->flags = (e->flags & ~EDGE_FALSE_VALUE) | EDGE_TRUE_VALUE;
! 	}
!       update_stmt (stmt);
!       return 1;
!     }
  
!   return 0;
  }
  
  
  /* Propagate from the ssa name definition statements of COND_EXPR
     in the rhs of statement STMT into the conditional if that simplifies it.
     Returns zero if no statement was changed, one if there were
!    changes and two if cfg_cleanup needs to run.  */
  
  static int
  forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
*************** forward_propagate_into_cond (gimple_stmt
*** 497,569 ****
  
    do {
      tree tmp = NULL_TREE;
!     tree cond = gimple_assign_rhs1 (stmt);
      tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
      gimple def_stmt;
      bool single_use0_p = false, single_use1_p = false;
  
      /* We can do tree combining on SSA_NAME and comparison expressions.  */
!     if (COMPARISON_CLASS_P (cond)
! 	&& TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME)
        {
  	/* For comparisons use the first operand, that is likely to
  	   simplify comparisons against constants.  */
! 	name = TREE_OPERAND (cond, 0);
  	def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
  	if (def_stmt && can_propagate_from (def_stmt))
  	  {
! 	    tree op1 = TREE_OPERAND (cond, 1);
! 	    rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
! 	    tmp = combine_cond_expr_cond (loc, TREE_CODE (cond),
! 					  boolean_type_node,
! 					  rhs0, op1, !single_use0_p);
  	  }
  	/* If that wasn't successful, try the second operand.  */
  	if (tmp == NULL_TREE
! 	    && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
  	  {
! 	    tree op0 = TREE_OPERAND (cond, 0);
! 	    name = TREE_OPERAND (cond, 1);
  	    def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
  	    if (!def_stmt || !can_propagate_from (def_stmt))
  	      return did_something;
  
! 	    rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
! 	    tmp = combine_cond_expr_cond (loc, TREE_CODE (cond),
! 					  boolean_type_node,
! 					  op0, rhs1, !single_use1_p);
  	  }
  	/* If that wasn't successful either, try both operands.  */
  	if (tmp == NULL_TREE
  	    && rhs0 != NULL_TREE
  	    && rhs1 != NULL_TREE)
! 	  tmp = combine_cond_expr_cond (loc, TREE_CODE (cond),
! 					boolean_type_node,
  					rhs0,
  					fold_convert_loc (loc,
  							  TREE_TYPE (rhs0),
  							  rhs1),
  					!(single_use0_p && single_use1_p));
        }
-     else if (TREE_CODE (cond) == SSA_NAME)
-       {
- 	name = cond;
- 	def_stmt = get_prop_source_stmt (name, true, NULL);
- 	if (def_stmt || !can_propagate_from (def_stmt))
- 	  return did_something;
- 
- 	rhs0 = gimple_assign_rhs1 (def_stmt);
- 	tmp = combine_cond_expr_cond (loc, NE_EXPR, boolean_type_node, rhs0,
- 				      build_int_cst (TREE_TYPE (rhs0), 0),
- 				      false);
-       }
  
      if (tmp)
        {
  	if (dump_file && tmp)
  	  {
  	    fprintf (dump_file, "  Replaced '");
! 	    print_generic_expr (dump_file, cond, 0);
  	    fprintf (dump_file, "' with '");
  	    print_generic_expr (dump_file, tmp, 0);
  	    fprintf (dump_file, "'\n");
--- 455,514 ----
  
    do {
      tree tmp = NULL_TREE;
!     enum tree_code code = gimple_assign_rhs_code (stmt);
!     tree cond_lhs = gimple_assign_rhs1 (stmt);
!     tree cond_rhs = gimple_assign_rhs2 (stmt);
!     tree type = TREE_TYPE (gimple_assign_lhs (stmt));
      tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
      gimple def_stmt;
      bool single_use0_p = false, single_use1_p = false;
  
      /* We can do tree combining on SSA_NAME and comparison expressions.  */
!     if (TREE_CODE (cond_lhs) == SSA_NAME)
        {
  	/* For comparisons use the first operand, that is likely to
  	   simplify comparisons against constants.  */
! 	name = cond_lhs;
  	def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
  	if (def_stmt && can_propagate_from (def_stmt))
  	  {
! 	    rhs0 = rhs_to_tree (TREE_TYPE (cond_rhs), def_stmt);
! 	    tmp = combine_cond_expr_cond (loc, code, type,
! 					  rhs0, cond_rhs, !single_use0_p);
  	  }
  	/* If that wasn't successful, try the second operand.  */
  	if (tmp == NULL_TREE
! 	    && TREE_CODE (cond_rhs) == SSA_NAME)
  	  {
! 	    name = cond_rhs;
  	    def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
  	    if (!def_stmt || !can_propagate_from (def_stmt))
  	      return did_something;
  
! 	    rhs1 = rhs_to_tree (TREE_TYPE (cond_lhs), def_stmt);
! 	    tmp = combine_cond_expr_cond (loc, code, type,
! 					  cond_lhs, rhs1, !single_use1_p);
  	  }
  	/* If that wasn't successful either, try both operands.  */
  	if (tmp == NULL_TREE
  	    && rhs0 != NULL_TREE
  	    && rhs1 != NULL_TREE)
! 	  tmp = combine_cond_expr_cond (loc, code, type,
  					rhs0,
  					fold_convert_loc (loc,
  							  TREE_TYPE (rhs0),
  							  rhs1),
  					!(single_use0_p && single_use1_p));
        }
  
      if (tmp)
        {
  	if (dump_file && tmp)
  	  {
  	    fprintf (dump_file, "  Replaced '");
! 	    print_generic_expr (dump_file, cond_lhs, 0);
! 	    fprintf (dump_file, " %s ", op_symbol_code (code));
! 	    print_generic_expr (dump_file, cond_rhs, 0);
  	    fprintf (dump_file, "' with '");
  	    print_generic_expr (dump_file, tmp, 0);
  	    fprintf (dump_file, "'\n");
*************** forward_propagate_into_cond (gimple_stmt
*** 581,588 ****
  	else if (did_something == 0)
  	  did_something = 1;
  
! 	/* Continue combining.  */
! 	continue;
        }
  
      break;
--- 526,534 ----
  	else if (did_something == 0)
  	  did_something = 1;
  
! 	/* Continue combining if we can.  */
! 	if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
! 	  continue;
        }
  
      break;
*************** tree_ssa_forward_propagate_single_use_va
*** 1729,1751 ****
  		  simplify_not_neg_expr (&gsi);
  		  gsi_next (&gsi);
  		}
! 	      else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
!                 {
                    /* In this case the entire COND_EXPR is in rhs1. */
  		  int did_something;
  		  fold_defer_overflow_warnings ();
                    did_something = forward_propagate_into_cond (&gsi);
  		  stmt = gsi_stmt (gsi);
- 		  if (did_something == 2)
- 		    cfg_changed = true;
  		  fold_undefer_overflow_warnings (!TREE_NO_WARNING (rhs)
  		    && did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
! 		  gsi_next (&gsi);
!                 }
! 	      else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
! 					== tcc_comparison)
! 		{
! 		  if (forward_propagate_comparison (stmt))
  		    {
  		      release_defs (stmt);
  		      todoflags |= TODO_remove_unused_locals;
--- 1675,1693 ----
  		  simplify_not_neg_expr (&gsi);
  		  gsi_next (&gsi);
  		}
! 	      else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
! 					== tcc_comparison)
! 		{
                    /* In this case the entire COND_EXPR is in rhs1. */
  		  int did_something;
  		  fold_defer_overflow_warnings ();
                    did_something = forward_propagate_into_cond (&gsi);
  		  stmt = gsi_stmt (gsi);
  		  fold_undefer_overflow_warnings (!TREE_NO_WARNING (rhs)
  		    && did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
! 		  if ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
! 		       == tcc_comparison)
! 		      && forward_propagate_comparison (stmt))
  		    {
  		      release_defs (stmt);
  		      todoflags |= TODO_remove_unused_locals;
Index: trunk/gcc/tree-ssa-ifcombine.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ifcombine.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-ifcombine.c	2010-08-30 14:32:23.000000000 +0200
*************** static bool
*** 171,183 ****
  recognize_single_bit_test (gimple cond, tree *name, tree *bit)
  {
    gimple stmt;
  
    /* Get at the definition of the result of the bit test.  */
!   if (gimple_cond_code (cond) != NE_EXPR
!       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
!       || !integer_zerop (gimple_cond_rhs (cond)))
      return false;
!   stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
    if (!is_gimple_assign (stmt))
      return false;
  
--- 171,187 ----
  recognize_single_bit_test (gimple cond, tree *name, tree *bit)
  {
    gimple stmt;
+   enum tree_code code;
+   tree lhs, rhs;
+ 
+   gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
  
    /* Get at the definition of the result of the bit test.  */
!   if (code != NE_EXPR
!       || TREE_CODE (lhs) != SSA_NAME
!       || !integer_zerop (rhs))
      return false;
!   stmt = SSA_NAME_DEF_STMT (lhs);
    if (!is_gimple_assign (stmt))
      return false;
  
*************** static bool
*** 279,291 ****
  recognize_bits_test (gimple cond, tree *name, tree *bits)
  {
    gimple stmt;
  
    /* Get at the definition of the result of the bit test.  */
!   if (gimple_cond_code (cond) != NE_EXPR
!       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
!       || !integer_zerop (gimple_cond_rhs (cond)))
      return false;
!   stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
    if (!is_gimple_assign (stmt)
        || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
      return false;
--- 283,299 ----
  recognize_bits_test (gimple cond, tree *name, tree *bits)
  {
    gimple stmt;
+   enum tree_code code;
+   tree lhs, rhs;
+ 
+   gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
  
    /* Get at the definition of the result of the bit test.  */
!   if (code != NE_EXPR
!       || TREE_CODE (lhs) != SSA_NAME
!       || !integer_zerop (rhs))
      return false;
!   stmt = SSA_NAME_DEF_STMT (lhs);
    if (!is_gimple_assign (stmt)
        || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
      return false;
*************** ifcombine_ifandif (basic_block inner_con
*** 340,353 ****
        t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
  				     true, GSI_SAME_STMT);
        t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
!       t = canonicalize_cond_expr_cond (t);
!       if (!t)
! 	return false;
!       gimple_cond_set_condition_from_tree (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
        update_stmt (outer_cond);
  
        if (dump_file)
--- 348,360 ----
        t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
  				     true, GSI_SAME_STMT);
        t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
!       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
! 				    true, GSI_SAME_STMT);
!       gimple_cond_set_pred (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_make_true (outer_cond);
        update_stmt (outer_cond);
  
        if (dump_file)
*************** ifcombine_ifandif (basic_block inner_con
*** 365,390 ****
      }
  
    /* See if we have two comparisons that we can merge into one.  */
!   else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
! 	   && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
      {
        tree t;
  
!       if (!(t = maybe_fold_and_comparisons (gimple_cond_code (inner_cond),
! 					    gimple_cond_lhs (inner_cond),
! 					    gimple_cond_rhs (inner_cond),
! 					    gimple_cond_code (outer_cond),
! 					    gimple_cond_lhs (outer_cond),
! 					    gimple_cond_rhs (outer_cond))))
  	return false;
        t = canonicalize_cond_expr_cond (t);
        if (!t)
  	return false;
!       gimple_cond_set_condition_from_tree (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
        update_stmt (outer_cond);
  
        if (dump_file)
--- 372,400 ----
      }
  
    /* See if we have two comparisons that we can merge into one.  */
!   else
      {
+       enum tree_code code1, code2;
+       tree lhs1, lhs2, rhs1, rhs2;
        tree t;
+       gimple_stmt_iterator gsi;
+ 
+       gimple_cond_extract_comparison (inner_cond, &code1, &lhs1, &rhs1);
+       gimple_cond_extract_comparison (outer_cond, &code2, &lhs2, &rhs2);
  
!       if (!(t = maybe_fold_and_comparisons (code1, lhs1, rhs1,
! 					    code2, lhs2, rhs2)))
  	return false;
        t = canonicalize_cond_expr_cond (t);
        if (!t)
  	return false;
!       gsi = gsi_for_stmt (inner_cond);
!       t = force_gimple_operand_gsi (&gsi, t, true, NULL, true, GSI_SAME_STMT);
!       gimple_cond_set_pred (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_make_true (outer_cond);
        update_stmt (outer_cond);
  
        if (dump_file)
*************** ifcombine_iforif (basic_block inner_cond
*** 486,499 ****
  				    true, GSI_SAME_STMT);
        t = fold_build2 (NE_EXPR, boolean_type_node, t,
  		       build_int_cst (TREE_TYPE (t), 0));
!       t = canonicalize_cond_expr_cond (t);
!       if (!t)
! 	return false;
!       gimple_cond_set_condition_from_tree (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
        update_stmt (outer_cond);
  
        if (dump_file)
--- 496,508 ----
  				    true, GSI_SAME_STMT);
        t = fold_build2 (NE_EXPR, boolean_type_node, t,
  		       build_int_cst (TREE_TYPE (t), 0));
!       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
! 				    true, GSI_SAME_STMT);
!       gimple_cond_set_pred (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_make_false (outer_cond);
        update_stmt (outer_cond);
  
        if (dump_file)
*************** ifcombine_iforif (basic_block inner_cond
*** 513,538 ****
    /* See if we have two comparisons that we can merge into one.
       This happens for C++ operator overloading where for example
       GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
!     else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
! 	   && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
      {
        tree t;
  
!       if (!(t = maybe_fold_or_comparisons (gimple_cond_code (inner_cond),
! 					   gimple_cond_lhs (inner_cond),
! 					   gimple_cond_rhs (inner_cond),
! 					   gimple_cond_code (outer_cond),
! 					   gimple_cond_lhs (outer_cond),
! 					   gimple_cond_rhs (outer_cond))))
  	return false;
        t = canonicalize_cond_expr_cond (t);
        if (!t)
  	return false;
!       gimple_cond_set_condition_from_tree (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
        update_stmt (outer_cond);
  
        if (dump_file)
--- 522,550 ----
    /* See if we have two comparisons that we can merge into one.
       This happens for C++ operator overloading where for example
       GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
!   else
      {
+       enum tree_code code1, code2;
+       tree lhs1, lhs2, rhs1, rhs2;
        tree t;
+       gimple_stmt_iterator gsi;
  
!       gimple_cond_extract_comparison (inner_cond, &code1, &lhs1, &rhs1);
!       gimple_cond_extract_comparison (outer_cond, &code2, &lhs2, &rhs2);
! 
!       if (!(t = maybe_fold_or_comparisons (code1, lhs1, rhs1,
! 					   code2, lhs2, rhs2)))
  	return false;
        t = canonicalize_cond_expr_cond (t);
        if (!t)
  	return false;
!       gsi = gsi_for_stmt (inner_cond);
!       t = force_gimple_operand_gsi (&gsi, t, true, NULL, true, GSI_SAME_STMT);
!       gimple_cond_set_pred (inner_cond, t);
        update_stmt (inner_cond);
  
        /* Leave CFG optimization to cfg_cleanup.  */
!       gimple_cond_make_false (outer_cond);
        update_stmt (outer_cond);
  
        if (dump_file)
Index: trunk/gcc/tree-ssa-loop-im.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-im.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-ssa-loop-im.c	2010-08-30 14:32:23.000000000 +0200
*************** rewrite_bittest (gimple_stmt_iterator *b
*** 956,967 ****
    /* Verify that the single use of lhs is a comparison against zero.  */
    if (TREE_CODE (lhs) != SSA_NAME
        || !single_imm_use (lhs, &use, &use_stmt)
!       || gimple_code (use_stmt) != GIMPLE_COND)
      return stmt;
!   if (gimple_cond_lhs (use_stmt) != lhs
!       || (gimple_cond_code (use_stmt) != NE_EXPR
! 	  && gimple_cond_code (use_stmt) != EQ_EXPR)
!       || !integer_zerop (gimple_cond_rhs (use_stmt)))
      return stmt;
  
    /* Get at the operands of the shift.  The rhs is TMP1 & 1.  */
--- 956,967 ----
    /* Verify that the single use of lhs is a comparison against zero.  */
    if (TREE_CODE (lhs) != SSA_NAME
        || !single_imm_use (lhs, &use, &use_stmt)
!       || gimple_code (use_stmt) != GIMPLE_ASSIGN)
      return stmt;
!   if ((gimple_assign_rhs_code (use_stmt) != NE_EXPR
!        && gimple_assign_rhs_code (use_stmt) != EQ_EXPR)
!       || gimple_assign_rhs1 (use_stmt) != lhs
!       || !integer_zerop (gimple_assign_rhs2 (use_stmt)))
      return stmt;
  
    /* Get at the operands of the shift.  The rhs is TMP1 & 1.  */
*************** rewrite_bittest (gimple_stmt_iterator *b
*** 1013,1019 ****
        /* Replace the SSA_NAME we compare against zero.  Adjust
  	 the type of zero accordingly.  */
        SET_USE (use, name);
!       gimple_cond_set_rhs (use_stmt, build_int_cst_type (TREE_TYPE (name), 0));
  
        /* Don't use gsi_replace here, none of the new assignments sets
  	 the variable originally set in stmt.  Move bsi to stmt1, and
--- 1013,1020 ----
        /* Replace the SSA_NAME we compare against zero.  Adjust
  	 the type of zero accordingly.  */
        SET_USE (use, name);
!       gimple_assign_set_rhs2 (use_stmt,
! 			      build_int_cst_type (TREE_TYPE (name), 0));
  
        /* Don't use gsi_replace here, none of the new assignments sets
  	 the variable originally set in stmt.  Move bsi to stmt1, and
*************** move_computations_stmt (struct dom_walk_
*** 1250,1259 ****
  	     edges of COND.  */
  	  extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1);
  	  gcc_assert (arg0 && arg1);
- 	  t = build2 (gimple_cond_code (cond), boolean_type_node,
- 		      gimple_cond_lhs (cond), gimple_cond_rhs (cond));
  	  t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)),
! 		      t, arg0, arg1);
  	  new_stmt = gimple_build_assign_with_ops (COND_EXPR,
  						   gimple_phi_result (stmt),
  						   t, NULL_TREE);
--- 1251,1258 ----
  	     edges of COND.  */
  	  extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1);
  	  gcc_assert (arg0 && arg1);
  	  t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)),
! 		      gimple_cond_pred (cond), arg0, arg1);
  	  new_stmt = gimple_build_assign_with_ops (COND_EXPR,
  						   gimple_phi_result (stmt),
  						   t, NULL_TREE);
Index: trunk/gcc/tree-ssa-loop-ivcanon.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-ivcanon.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-ivcanon.c	2010-08-30 14:32:23.000000000 +0200
*************** create_canonical_iv (struct loop *loop,
*** 74,80 ****
    tree type, var;
    gimple cond;
    gimple_stmt_iterator incr_at;
!   enum tree_code cmp;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
--- 74,80 ----
    tree type, var;
    gimple cond;
    gimple_stmt_iterator incr_at;
!   tree cmp;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
*************** create_canonical_iv (struct loop *loop,
*** 103,112 ****
  	     NULL_TREE, loop,
  	     &incr_at, false, NULL, &var);
  
!   cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR;
!   gimple_cond_set_code (cond, cmp);
!   gimple_cond_set_lhs (cond, var);
!   gimple_cond_set_rhs (cond, build_int_cst (type, 0));
    update_stmt (cond);
  }
  
--- 103,114 ----
  	     NULL_TREE, loop,
  	     &incr_at, false, NULL, &var);
  
!   cmp = fold_build2 ((exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR,
! 		     boolean_type_node, var, build_int_cst (type, 0));
!   incr_at = gsi_for_stmt (cond);
!   cmp = force_gimple_operand_gsi (&incr_at, cmp, true, NULL,
! 				  true, GSI_SAME_STMT);
!   gimple_cond_set_pred (cond, cmp);
    update_stmt (cond);
  }
  
*************** tree_estimate_loop_size (struct loop *lo
*** 266,273 ****
  	    }
  	  /* Conditionals.  */
  	  else if (gimple_code (stmt) == GIMPLE_COND
! 		   && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
! 		   && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
  	    {
  	      if (dump_file && (dump_flags & TDF_DETAILS))
  	        fprintf (dump_file, "   Constant conditional.\n");
--- 268,275 ----
  	    }
  	  /* Conditionals.  */
  	  else if (gimple_code (stmt) == GIMPLE_COND
! 		   && constant_after_peeling (gimple_cond_pred (stmt),
! 					      stmt, loop))
  	    {
  	      if (dump_file && (dump_flags & TDF_DETAILS))
  	        fprintf (dump_file, "   Constant conditional.\n");
Index: trunk/gcc/tree-ssa-loop-ivopts.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-ivopts.c	2010-08-29 16:30:58.000000000 +0200
--- trunk/gcc/tree-ssa-loop-ivopts.c	2010-08-30 14:32:23.000000000 +0200
*************** extract_cond_operands (struct ivopts_dat
*** 1299,1314 ****
    struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
    bool ret = false;
  
!   if (gimple_code (stmt) == GIMPLE_COND)
!     {
!       op0 = gimple_cond_lhs_ptr (stmt);
!       op1 = gimple_cond_rhs_ptr (stmt);
!     }
!   else
!     {
!       op0 = gimple_assign_rhs1_ptr (stmt);
!       op1 = gimple_assign_rhs2_ptr (stmt);
!     }
  
    zero = integer_zero_node;
    const_iv.step = integer_zero_node;
--- 1299,1306 ----
    struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
    bool ret = false;
  
!   op0 = gimple_assign_rhs1_ptr (stmt);
!   op1 = gimple_assign_rhs2_ptr (stmt);
  
    zero = integer_zero_node;
    const_iv.step = integer_zero_node;
*************** find_interesting_uses_stmt (struct ivopt
*** 1826,1832 ****
  
    if (gimple_code (stmt) == GIMPLE_COND)
      {
!       find_interesting_uses_cond (data, stmt);
        return;
      }
  
--- 1818,1824 ----
  
    if (gimple_code (stmt) == GIMPLE_COND)
      {
!       find_interesting_uses_op (data, gimple_cond_pred (stmt));
        return;
      }
  
*************** rewrite_use_compare (struct ivopts_data
*** 6071,6079 ****
  		loop_preheader_edge (data->current_loop),
  		stmts);
  
!       gimple_cond_set_lhs (use->stmt, var);
!       gimple_cond_set_code (use->stmt, compare);
!       gimple_cond_set_rhs (use->stmt, op);
        return;
      }
  
--- 6063,6071 ----
  		loop_preheader_edge (data->current_loop),
  		stmts);
  
!       gimple_assign_set_rhs1 (use->stmt, var);
!       gimple_assign_set_rhs_code (use->stmt, compare);
!       gimple_assign_set_rhs2 (use->stmt, op);
        return;
      }
  
Index: trunk/gcc/tree-ssa-loop-manip.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-manip.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-manip.c	2010-08-30 14:32:23.000000000 +0200
*************** tree_transform_and_unroll_loop (struct l
*** 958,966 ****
  				  REG_BR_PROB_BASE - exit->probability);
  
    bsi = gsi_last_bb (exit_bb);
!   exit_if = gimple_build_cond (EQ_EXPR, integer_zero_node,
! 			       integer_zero_node,
! 			       NULL_TREE, NULL_TREE);
  
    gsi_insert_after (&bsi, exit_if, GSI_NEW_STMT);
    new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
--- 958,964 ----
  				  REG_BR_PROB_BASE - exit->probability);
  
    bsi = gsi_last_bb (exit_bb);
!   exit_if = gimple_build_cond (boolean_true_node, NULL_TREE, NULL_TREE);
  
    gsi_insert_after (&bsi, exit_if, GSI_NEW_STMT);
    new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
*************** tree_transform_and_unroll_loop (struct l
*** 1085,1093 ****
    exit_if = gsi_stmt (bsi);
    create_iv (exit_base, exit_step, NULL_TREE, loop,
  	     &bsi, false, &ctr_before, &ctr_after);
!   gimple_cond_set_code (exit_if, exit_cmp);
!   gimple_cond_set_lhs (exit_if, ctr_after);
!   gimple_cond_set_rhs (exit_if, exit_bound);
    update_stmt (exit_if);
  
  #ifdef ENABLE_CHECKING
--- 1083,1090 ----
    exit_if = gsi_stmt (bsi);
    create_iv (exit_base, exit_step, NULL_TREE, loop,
  	     &bsi, false, &ctr_before, &ctr_after);
!   gimple_update_cond_from_comparison (gsi_for_stmt (exit_if),
! 				      exit_cmp, ctr_after, exit_bound);
    update_stmt (exit_if);
  
  #ifdef ENABLE_CHECKING
*************** canonicalize_loop_ivs (struct loop *loop
*** 1233,1241 ****
        te->flags = EDGE_FALSE_VALUE;
        fe->flags = EDGE_TRUE_VALUE;
      }
!   gimple_cond_set_code (stmt, LT_EXPR);
!   gimple_cond_set_lhs (stmt, var_before);
!   gimple_cond_set_rhs (stmt, *nit);
    update_stmt (stmt);
  
    return var_before;
--- 1230,1237 ----
        te->flags = EDGE_FALSE_VALUE;
        fe->flags = EDGE_TRUE_VALUE;
      }
!   gimple_update_cond_from_comparison (gsi_for_stmt (stmt),
! 				      LT_EXPR, var_before, *nit);
    update_stmt (stmt);
  
    return var_before;
Index: trunk/gcc/tree-ssa-loop-niter.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-niter.c	2010-08-29 16:30:26.000000000 +0200
--- trunk/gcc/tree-ssa-loop-niter.c	2010-08-30 14:32:23.000000000 +0200
*************** bound_difference (struct loop *loop, tre
*** 431,439 ****
  	continue;
  
        cond = last_stmt (e->src);
!       c0 = gimple_cond_lhs (cond);
!       cmp = gimple_cond_code (cond);
!       c1 = gimple_cond_rhs (cond);
  
        if (e->flags & EDGE_FALSE_VALUE)
  	cmp = invert_tree_comparison (cmp, false);
--- 431,437 ----
  	continue;
  
        cond = last_stmt (e->src);
!       gimple_cond_extract_comparison (cond, &cmp, &c0, &c1);
  
        if (e->flags & EDGE_FALSE_VALUE)
  	cmp = invert_tree_comparison (cmp, false);
*************** simplify_using_initial_conditions (struc
*** 1661,1672 ****
  	continue;
  
        stmt = last_stmt (e->src);
!       cond = fold_build2 (gimple_cond_code (stmt),
! 			  boolean_type_node,
! 			  gimple_cond_lhs (stmt),
! 			  gimple_cond_rhs (stmt));
!       if (e->flags & EDGE_FALSE_VALUE)
! 	cond = invert_truthvalue (cond);
        expr = tree_simplify_using_condition (cond, expr);
        ++cnt;
      }
--- 1659,1674 ----
  	continue;
  
        stmt = last_stmt (e->src);
!       cond = gimple_cond_pred (stmt);
!       if (TREE_CODE (cond) == SSA_NAME)
! 	{
! 	  enum tree_code code;
! 	  tree lhs, rhs;
! 	  gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
! 	  cond = fold_build2 (code, boolean_type_node, lhs, rhs);
! 	  if (e->flags & EDGE_FALSE_VALUE)
! 	    cond = invert_truthvalue (cond);
! 	}
        expr = tree_simplify_using_condition (cond, expr);
        ++cnt;
      }
*************** number_of_iterations_exit (struct loop *
*** 1791,1797 ****
      return false;
  
    /* We want the condition for staying inside loop.  */
!   code = gimple_cond_code (stmt);
    if (exit->flags & EDGE_TRUE_VALUE)
      code = invert_tree_comparison (code, false);
  
--- 1793,1799 ----
      return false;
  
    /* We want the condition for staying inside loop.  */
!   gimple_cond_extract_comparison (stmt, &code, &op0, &op1);
    if (exit->flags & EDGE_TRUE_VALUE)
      code = invert_tree_comparison (code, false);
  
*************** number_of_iterations_exit (struct loop *
*** 1808,1815 ****
        return false;
      }
  
-   op0 = gimple_cond_lhs (stmt);
-   op1 = gimple_cond_rhs (stmt);
    type = TREE_TYPE (op0);
  
    if (TREE_CODE (type) != INTEGER_TYPE
--- 1810,1815 ----
*************** loop_niter_by_eval (struct loop *loop, e
*** 2169,2175 ****
    if (!cond || gimple_code (cond) != GIMPLE_COND)
      return chrec_dont_know;
  
!   cmp = gimple_cond_code (cond);
    if (exit->flags & EDGE_TRUE_VALUE)
      cmp = invert_tree_comparison (cmp, false);
  
--- 2169,2175 ----
    if (!cond || gimple_code (cond) != GIMPLE_COND)
      return chrec_dont_know;
  
!   gimple_cond_extract_comparison (cond, &cmp, &op[0], &op[1]);
    if (exit->flags & EDGE_TRUE_VALUE)
      cmp = invert_tree_comparison (cmp, false);
  
*************** loop_niter_by_eval (struct loop *loop, e
*** 2181,2188 ****
      case GE_EXPR:
      case LT_EXPR:
      case LE_EXPR:
-       op[0] = gimple_cond_lhs (cond);
-       op[1] = gimple_cond_rhs (cond);
        break;
  
      default:
--- 2181,2186 ----
Index: trunk/gcc/tree-ssa-loop-unswitch.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-unswitch.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-unswitch.c	2010-08-30 14:32:23.000000000 +0200
*************** static tree
*** 120,126 ****
  tree_may_unswitch_on (basic_block bb, struct loop *loop)
  {
    gimple stmt, def;
!   tree cond, use;
    basic_block def_bb;
    ssa_op_iter iter;
  
--- 120,126 ----
  tree_may_unswitch_on (basic_block bb, struct loop *loop)
  {
    gimple stmt, def;
!   tree use;
    basic_block def_bb;
    ssa_op_iter iter;
  
*************** tree_may_unswitch_on (basic_block bb, st
*** 145,154 ****
  	return NULL_TREE;
      }
  
!   cond = build2 (gimple_cond_code (stmt), boolean_type_node,
! 		 gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
! 
!   return cond;
  }
  
  /* Simplifies COND using checks in front of the entry of the LOOP.  Just very
--- 145,151 ----
  	return NULL_TREE;
      }
  
!   return gimple_cond_pred (stmt);
  }
  
  /* Simplifies COND using checks in front of the entry of the LOOP.  Just very
*************** simplify_using_entry_checks (struct loop
*** 166,176 ****
        stmt = last_stmt (e->src);
        if (stmt
  	  && gimple_code (stmt) == GIMPLE_COND
! 	  && gimple_cond_code (stmt) == TREE_CODE (cond)
! 	  && operand_equal_p (gimple_cond_lhs (stmt),
! 			      TREE_OPERAND (cond, 0), 0)
! 	  && operand_equal_p (gimple_cond_rhs (stmt),
! 			      TREE_OPERAND (cond, 1), 0))
  	return (e->flags & EDGE_TRUE_VALUE
  		? boolean_true_node
  		: boolean_false_node);
--- 163,169 ----
        stmt = last_stmt (e->src);
        if (stmt
  	  && gimple_code (stmt) == GIMPLE_COND
! 	  && operand_equal_p (gimple_cond_pred (stmt), cond, 0))
  	return (e->flags & EDGE_TRUE_VALUE
  		? boolean_true_node
  		: boolean_false_node);
*************** tree_unswitch_single_loop (struct loop *
*** 229,241 ****
        if (integer_nonzerop (cond))
  	{
  	  /* Remove false path.  */
! 	  gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
  	  changed = true;
  	}
        else if (integer_zerop (cond))
  	{
  	  /* Remove true path.  */
! 	  gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
  	  changed = true;
  	}
        /* Do not unswitch too much.  */
--- 222,234 ----
        if (integer_nonzerop (cond))
  	{
  	  /* Remove false path.  */
! 	  gimple_cond_make_true (stmt);
  	  changed = true;
  	}
        else if (integer_zerop (cond))
  	{
  	  /* Remove true path.  */
! 	  gimple_cond_make_false (stmt);
  	  changed = true;
  	}
        /* Do not unswitch too much.  */
Index: trunk/gcc/tree-ssa-phiopt.c
===================================================================
*** trunk.orig/gcc/tree-ssa-phiopt.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-phiopt.c	2010-08-30 14:32:23.000000000 +0200
*************** replace_phi_edge_with_variable (basic_bl
*** 401,406 ****
--- 401,408 ----
    basic_block bb = gimple_bb (phi);
    basic_block block_to_remove;
    gimple_stmt_iterator gsi;
+   gimple cond;
+   tree name;
  
    /* Change the PHI argument to new.  */
    SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
*************** replace_phi_edge_with_variable (basic_bl
*** 429,435 ****
--- 431,448 ----
  
    /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
    gsi = gsi_last_bb (cond_block);
+   cond = gsi_stmt (gsi);
+   if (TREE_CODE (name = gimple_cond_pred (cond)) != SSA_NAME
+       || !has_single_use (name)
+       || gimple_has_side_effects (SSA_NAME_DEF_STMT (name)))
+     name = NULL_TREE;
    gsi_remove (&gsi, true);
+   if (name)
+     {
+       gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (name));
+       gsi_remove (&gsi, true);
+       release_defs (SSA_NAME_DEF_STMT (name));
+     }
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file,
*************** conditional_replacement (basic_block con
*** 496,503 ****
    /* To handle special cases like floating point comparison, it is easier and
       less error-prone to build a tree and gimplify it on the fly though it is
       less efficient.  */
!   cond = fold_build2 (gimple_cond_code (stmt), boolean_type_node,
! 		      gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
  
    /* We need to know which is the true edge and which is the false
       edge so that we know when to invert the condition below.  */
--- 509,515 ----
    /* To handle special cases like floating point comparison, it is easier and
       less error-prone to build a tree and gimplify it on the fly though it is
       less efficient.  */
!   cond = gimple_cond_to_tree (stmt);
  
    /* We need to know which is the true edge and which is the false
       edge so that we know when to invert the condition below.  */
*************** value_replacement (basic_block cond_bb,
*** 555,560 ****
--- 567,573 ----
    gimple cond;
    edge true_edge, false_edge;
    enum tree_code code;
+   tree lhs, rhs;
  
    /* If the type says honor signed zeros we cannot do this
       optimization.  */
*************** value_replacement (basic_block cond_bb,
*** 565,571 ****
      return false;
  
    cond = last_stmt (cond_bb);
!   code = gimple_cond_code (cond);
  
    /* This transformation is only valid for equality comparisons.  */
    if (code != NE_EXPR && code != EQ_EXPR)
--- 578,584 ----
      return false;
  
    cond = last_stmt (cond_bb);
!   gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
  
    /* This transformation is only valid for equality comparisons.  */
    if (code != NE_EXPR && code != EQ_EXPR)
*************** value_replacement (basic_block cond_bb,
*** 586,595 ****
       We now need to verify that the two arguments in the PHI node match
       the two arguments to the equality comparison.  */
  
!   if ((operand_equal_for_phi_arg_p (arg0, gimple_cond_lhs (cond))
!        && operand_equal_for_phi_arg_p (arg1, gimple_cond_rhs (cond)))
!       || (operand_equal_for_phi_arg_p (arg1, gimple_cond_lhs (cond))
! 	  && operand_equal_for_phi_arg_p (arg0, gimple_cond_rhs (cond))))
      {
        edge e;
        tree arg;
--- 599,608 ----
       We now need to verify that the two arguments in the PHI node match
       the two arguments to the equality comparison.  */
  
!   if ((operand_equal_for_phi_arg_p (arg0, lhs)
!        && operand_equal_for_phi_arg_p (arg1, rhs))
!       || (operand_equal_for_phi_arg_p (arg1, lhs)
! 	  && operand_equal_for_phi_arg_p (arg0, rhs)))
      {
        edge e;
        tree arg;
*************** minmax_replacement (basic_block cond_bb,
*** 638,643 ****
--- 651,657 ----
    enum tree_code cmp, minmax, ass_code;
    tree smaller, larger, arg_true, arg_false;
    gimple_stmt_iterator gsi, gsi_from;
+   tree lhs, rhs;
  
    type = TREE_TYPE (PHI_RESULT (phi));
  
*************** minmax_replacement (basic_block cond_bb,
*** 646,665 ****
      return false;
  
    cond = last_stmt (cond_bb);
!   cmp = gimple_cond_code (cond);
    result = PHI_RESULT (phi);
  
    /* This transformation is only valid for order comparisons.  Record which
       operand is smaller/larger if the result of the comparison is true.  */
    if (cmp == LT_EXPR || cmp == LE_EXPR)
      {
!       smaller = gimple_cond_lhs (cond);
!       larger = gimple_cond_rhs (cond);
      }
    else if (cmp == GT_EXPR || cmp == GE_EXPR)
      {
!       smaller = gimple_cond_rhs (cond);
!       larger = gimple_cond_lhs (cond);
      }
    else
      return false;
--- 660,679 ----
      return false;
  
    cond = last_stmt (cond_bb);
!   gimple_cond_extract_comparison (cond, &cmp, &lhs, &rhs);
    result = PHI_RESULT (phi);
  
    /* This transformation is only valid for order comparisons.  Record which
       operand is smaller/larger if the result of the comparison is true.  */
    if (cmp == LT_EXPR || cmp == LE_EXPR)
      {
!       smaller = lhs;
!       larger = rhs;
      }
    else if (cmp == GT_EXPR || cmp == GE_EXPR)
      {
!       smaller = rhs;
!       larger = lhs;
      }
    else
      return false;
*************** abs_replacement (basic_block cond_bb, ba
*** 886,892 ****
    edge true_edge, false_edge;
    gimple assign;
    edge e;
!   tree rhs, lhs;
    bool negate;
    enum tree_code cond_code;
  
--- 900,906 ----
    edge true_edge, false_edge;
    gimple assign;
    edge e;
!   tree rhs, lhs, cond_lhs, cond_rhs;
    bool negate;
    enum tree_code cond_code;
  
*************** abs_replacement (basic_block cond_bb, ba
*** 926,943 ****
    result = PHI_RESULT (phi);
  
    /* Only relationals comparing arg[01] against zero are interesting.  */
!   cond_code = gimple_cond_code (cond);
    if (cond_code != GT_EXPR && cond_code != GE_EXPR
        && cond_code != LT_EXPR && cond_code != LE_EXPR)
      return false;
  
    /* Make sure the conditional is arg[01] OP y.  */
!   if (gimple_cond_lhs (cond) != rhs)
      return false;
  
!   if (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_rhs (cond)))
! 	       ? real_zerop (gimple_cond_rhs (cond))
! 	       : integer_zerop (gimple_cond_rhs (cond)))
      ;
    else
      return false;
--- 940,956 ----
    result = PHI_RESULT (phi);
  
    /* Only relationals comparing arg[01] against zero are interesting.  */
!   gimple_cond_extract_comparison (cond, &cond_code, &cond_lhs, &cond_rhs);
    if (cond_code != GT_EXPR && cond_code != GE_EXPR
        && cond_code != LT_EXPR && cond_code != LE_EXPR)
      return false;
  
    /* Make sure the conditional is arg[01] OP y.  */
!   if (cond_lhs != rhs)
      return false;
  
!   if (FLOAT_TYPE_P (TREE_TYPE (cond_rhs))
!       ? real_zerop (cond_rhs) : integer_zerop (cond_rhs))
      ;
    else
      return false;
Index: trunk/gcc/tree-ssa-pre.c
===================================================================
*** trunk.orig/gcc/tree-ssa-pre.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-ssa-pre.c	2010-08-30 14:32:23.000000000 +0200
*************** insert_into_preds_of_block (basic_block
*** 3343,3348 ****
--- 3343,3361 ----
  	}
      }
  
+   /* Make sure we are not inserting PHI nodes for predicates.
+      Those are all marking jump threading opportunities and just
+      will move predicate computations away from jumps and complicate
+      late analysis of uninitialized uses.  */
+   if (expr->kind == NARY
+       && truth_value_p (expr->u.nary->opcode))
+     {
+       if (dump_file && (dump_flags & TDF_DETAILS))
+ 	fprintf (dump_file, "Skipping insertion of phi for partial "
+ 		 "redundancy: Looks like a predicate\n");
+       nophi = true;
+     }
+ 
    /* Make the necessary insertions.  */
    FOR_EACH_EDGE (pred, ei, block->preds)
      {
*************** eliminate (void)
*** 4339,4357 ****
  	     available value-numbers.  */
  	  else if (gimple_code (stmt) == GIMPLE_COND)
  	    {
! 	      tree op0 = gimple_cond_lhs (stmt);
! 	      tree op1 = gimple_cond_rhs (stmt);
! 	      tree result;
! 
! 	      if (TREE_CODE (op0) == SSA_NAME)
! 		op0 = VN_INFO (op0)->valnum;
! 	      if (TREE_CODE (op1) == SSA_NAME)
! 		op1 = VN_INFO (op1)->valnum;
! 	      result = fold_binary (gimple_cond_code (stmt), boolean_type_node,
! 				    op0, op1);
! 	      if (result && TREE_CODE (result) == INTEGER_CST)
  		{
! 		  if (integer_zerop (result))
  		    gimple_cond_make_false (stmt);
  		  else
  		    gimple_cond_make_true (stmt);
--- 4352,4364 ----
  	     available value-numbers.  */
  	  else if (gimple_code (stmt) == GIMPLE_COND)
  	    {
! 	      tree pred = gimple_cond_pred (stmt);
! 
! 	      if (TREE_CODE (pred) == SSA_NAME)
! 		pred = VN_INFO (pred)->valnum;
! 	      if (TREE_CODE (pred) == INTEGER_CST)
  		{
! 		  if (integer_zerop (pred))
  		    gimple_cond_make_false (stmt);
  		  else
  		    gimple_cond_make_true (stmt);
Index: trunk/gcc/tree-ssa-threadedge.c
===================================================================
*** trunk.orig/gcc/tree-ssa-threadedge.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-threadedge.c	2010-08-30 14:32:23.000000000 +0200
*************** record_temporary_equivalence (tree x, tr
*** 162,168 ****
  {
    tree prev_x = SSA_NAME_VALUE (x);
  
!   if (TREE_CODE (y) == SSA_NAME)
      {
        tree tmp = SSA_NAME_VALUE (y);
        y = tmp ? tmp : y;
--- 162,168 ----
  {
    tree prev_x = SSA_NAME_VALUE (x);
  
!   if (y && TREE_CODE (y) == SSA_NAME)
      {
        tree tmp = SSA_NAME_VALUE (y);
        y = tmp ? tmp : y;
*************** record_temporary_equivalences_from_stmts
*** 457,550 ****
  static tree
  simplify_control_stmt_condition (edge e,
  				 gimple stmt,
- 				 gimple dummy_cond,
  				 tree (*simplify) (gimple, gimple),
  				 bool handle_dominating_asserts)
  {
    tree cond, cached_lhs;
    enum gimple_code code = gimple_code (stmt);
  
-   /* For comparisons, we have to update both operands, then try
-      to simplify the comparison.  */
-   if (code == GIMPLE_COND)
-     {
-       tree op0, op1;
-       enum tree_code cond_code;
- 
-       op0 = gimple_cond_lhs (stmt);
-       op1 = gimple_cond_rhs (stmt);
-       cond_code = gimple_cond_code (stmt);
- 
-       /* Get the current value of both operands.  */
-       if (TREE_CODE (op0) == SSA_NAME)
- 	{
-           tree tmp = SSA_NAME_VALUE (op0);
- 	  if (tmp)
- 	    op0 = tmp;
- 	}
- 
-       if (TREE_CODE (op1) == SSA_NAME)
- 	{
- 	  tree tmp = SSA_NAME_VALUE (op1);
- 	  if (tmp)
- 	    op1 = tmp;
- 	}
- 
-       if (handle_dominating_asserts)
- 	{
- 	  /* Now see if the operand was consumed by an ASSERT_EXPR
- 	     which dominates E->src.  If so, we want to replace the
- 	     operand with the LHS of the ASSERT_EXPR.  */
- 	  if (TREE_CODE (op0) == SSA_NAME)
- 	    op0 = lhs_of_dominating_assert (op0, e->src, stmt);
- 
- 	  if (TREE_CODE (op1) == SSA_NAME)
- 	    op1 = lhs_of_dominating_assert (op1, e->src, stmt);
- 	}
- 
-       /* We may need to canonicalize the comparison.  For
- 	 example, op0 might be a constant while op1 is an
- 	 SSA_NAME.  Failure to canonicalize will cause us to
- 	 miss threading opportunities.  */
-       if (tree_swap_operands_p (op0, op1, false))
- 	{
- 	  tree tmp;
- 	  cond_code = swap_tree_comparison (cond_code);
- 	  tmp = op0;
- 	  op0 = op1;
- 	  op1 = tmp;
- 	}
- 
-       /* Stuff the operator and operands into our dummy conditional
- 	 expression.  */
-       gimple_cond_set_code (dummy_cond, cond_code);
-       gimple_cond_set_lhs (dummy_cond, op0);
-       gimple_cond_set_rhs (dummy_cond, op1);
- 
-       /* We absolutely do not care about any type conversions
-          we only care about a zero/nonzero value.  */
-       fold_defer_overflow_warnings ();
- 
-       cached_lhs = fold_binary (cond_code, boolean_type_node, op0, op1);
-       if (cached_lhs)
- 	while (CONVERT_EXPR_P (cached_lhs))
-           cached_lhs = TREE_OPERAND (cached_lhs, 0);
- 
-       fold_undefer_overflow_warnings ((cached_lhs
-                                        && is_gimple_min_invariant (cached_lhs)),
- 				      stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
- 
-       /* If we have not simplified the condition down to an invariant,
- 	 then use the pass specific callback to simplify the condition.  */
-       if (!cached_lhs
-           || !is_gimple_min_invariant (cached_lhs))
-         cached_lhs = (*simplify) (dummy_cond, stmt);
- 
-       return cached_lhs;
-     }
- 
    if (code == GIMPLE_SWITCH)
      cond = gimple_switch_index (stmt);
    else if (code == GIMPLE_GOTO)
      cond = gimple_goto_dest (stmt);
    else
--- 457,472 ----
  static tree
  simplify_control_stmt_condition (edge e,
  				 gimple stmt,
  				 tree (*simplify) (gimple, gimple),
  				 bool handle_dominating_asserts)
  {
    tree cond, cached_lhs;
    enum gimple_code code = gimple_code (stmt);
  
    if (code == GIMPLE_SWITCH)
      cond = gimple_switch_index (stmt);
+   else if (code == GIMPLE_COND)
+     cond = gimple_cond_pred (stmt);
    else if (code == GIMPLE_GOTO)
      cond = gimple_goto_dest (stmt);
    else
*************** simplify_control_stmt_condition (edge e,
*** 610,616 ****
     SIMPLIFY is a pass-specific function used to simplify statements.  */
  
  void
! thread_across_edge (gimple dummy_cond,
  		    edge e,
  		    bool handle_dominating_asserts,
  		    VEC(tree, heap) **stack,
--- 532,538 ----
     SIMPLIFY is a pass-specific function used to simplify statements.  */
  
  void
! thread_across_edge (gimple dummy_cond ATTRIBUTE_UNUSED,
  		    edge e,
  		    bool handle_dominating_asserts,
  		    VEC(tree, heap) **stack,
*************** thread_across_edge (gimple dummy_cond,
*** 628,642 ****
        use_operand_p use_p;
        gimple last = gsi_stmt (gsi_last_bb (e->dest));
  
!       FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
  	{
! 	  tree use = USE_FROM_PTR (use_p);
! 
!           if (TREE_CODE (use) == SSA_NAME
! 	      && gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI
! 	      && gimple_bb (SSA_NAME_DEF_STMT (use)) == e->dest)
  	    goto fail;
  	}
      }
  
    stmt_count = 0;
--- 550,583 ----
        use_operand_p use_p;
        gimple last = gsi_stmt (gsi_last_bb (e->dest));
  
!       if (gimple_code (last) == GIMPLE_COND)
  	{
! 	  enum tree_code code;
! 	  tree op0, op1;
! 	  gimple_cond_extract_comparison (last, &code, &op0, &op1);
! 	  if (TREE_CODE (op0) == SSA_NAME
! 	      && gimple_code (SSA_NAME_DEF_STMT (op0)) != GIMPLE_PHI
! 	      && gimple_bb (SSA_NAME_DEF_STMT (op0)) == e->dest)
  	    goto fail;
+ 	  if (TREE_CODE (op1) == SSA_NAME
+ 	      && gimple_code (SSA_NAME_DEF_STMT (op1)) != GIMPLE_PHI
+ 	      && gimple_bb (SSA_NAME_DEF_STMT (op1)) == e->dest)
+ 	    goto fail;
+ 	  /* Reset any previously known value for the predicate.  */
+ 	  if (TREE_CODE (gimple_cond_pred (last)) == SSA_NAME)
+ 	    record_temporary_equivalence (gimple_cond_pred (last),
+ 					  NULL_TREE, stack);
  	}
+       else
+ 	FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
+ 	  {
+ 	    tree use = USE_FROM_PTR (use_p);
+ 
+ 	    if (TREE_CODE (use) == SSA_NAME
+ 		&& gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI
+ 		&& gimple_bb (SSA_NAME_DEF_STMT (use)) == e->dest)
+ 	      goto fail;
+ 	  }
      }
  
    stmt_count = 0;
*************** thread_across_edge (gimple dummy_cond,
*** 660,666 ****
        tree cond;
  
        /* Extract and simplify the condition.  */
!       cond = simplify_control_stmt_condition (e, stmt, dummy_cond, simplify, handle_dominating_asserts);
  
        if (cond && is_gimple_min_invariant (cond))
  	{
--- 601,608 ----
        tree cond;
  
        /* Extract and simplify the condition.  */
!       cond = simplify_control_stmt_condition (e, stmt, simplify,
! 					      handle_dominating_asserts);
  
        if (cond && is_gimple_min_invariant (cond))
  	{
Index: trunk/gcc/tree-ssa-uncprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-uncprop.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-uncprop.c	2010-08-30 14:32:23.000000000 +0200
*************** associate_equivalences_with_edges (void)
*** 81,96 ****
  	  edge true_edge;
  	  edge false_edge;
  	  struct edge_equivalency *equivalency;
! 	  enum tree_code code = gimple_cond_code (stmt);
  
  	  extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
  
  	  /* Equality tests may create one or two equivalences.  */
  	  if (code == EQ_EXPR || code == NE_EXPR)
  	    {
- 	      tree op0 = gimple_cond_lhs (stmt);
- 	      tree op1 = gimple_cond_rhs (stmt);
- 
  	      /* Special case comparing booleans against a constant as we
  		 know the value of OP0 on both arms of the branch.  i.e., we
  		 can record an equivalence for OP0 rather than COND.  */
--- 81,95 ----
  	  edge true_edge;
  	  edge false_edge;
  	  struct edge_equivalency *equivalency;
! 	  enum tree_code code;
! 	  tree op0, op1;
  
+ 	  gimple_cond_extract_comparison (stmt, &code, &op0, &op1);
  	  extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
  
  	  /* Equality tests may create one or two equivalences.  */
  	  if (code == EQ_EXPR || code == NE_EXPR)
  	    {
  	      /* Special case comparing booleans against a constant as we
  		 know the value of OP0 on both arms of the branch.  i.e., we
  		 can record an equivalence for OP0 rather than COND.  */
Index: trunk/gcc/tree-ssa-uninit.c
===================================================================
*** trunk.orig/gcc/tree-ssa-uninit.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-uninit.c	2010-08-30 14:32:23.000000000 +0200
*************** use_pred_not_overlap_with_undef_path_pre
*** 887,895 ****
  
        cond = the_pred->cond;
        invert = the_pred->invert;
!       cond_lhs = gimple_cond_lhs (cond);
!       cond_rhs = gimple_cond_rhs (cond);
!       cmp_code = gimple_cond_code (cond);
  
        if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
            && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
--- 887,893 ----
  
        cond = the_pred->cond;
        invert = the_pred->invert;
!       gimple_cond_extract_comparison (cond, &cmp_code, &cond_lhs, &cond_rhs);
  
        if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
            && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
*************** normalize_cond_1 (gimple cond,
*** 1012,1017 ****
--- 1010,1017 ----
    enum tree_code cur_cond_code;
    tree rhs1, rhs2;
  
+   /* ???  If we would start to PRE predicates we could unwind to
+      PHI nodes here.  */
    gc = gimple_code (cond);
    if (gc != GIMPLE_ASSIGN)
      {
*************** normalize_cond (gimple cond, norm_cond_t
*** 1066,1086 ****
    norm_cond->invert = false;
    norm_cond->conds = NULL;
    gcc_assert (gimple_code (cond) == GIMPLE_COND);
!   cond_code = gimple_cond_code (cond);
    if (invert)
      cond_code = invert_tree_comparison (cond_code, false);
  
    if (cond_code == NE_EXPR)
      {
!       if (integer_zerop (gimple_cond_rhs (cond))
!           && (TREE_CODE (gimple_cond_lhs (cond)) == SSA_NAME))
          normalize_cond_1 (
!             SSA_NAME_DEF_STMT (gimple_cond_lhs (cond)),
!             norm_cond, ERROR_MARK);
!       else if (integer_zerop (gimple_cond_lhs (cond))
!                && (TREE_CODE (gimple_cond_rhs (cond)) == SSA_NAME))
!         normalize_cond_1 (
!             SSA_NAME_DEF_STMT (gimple_cond_rhs (cond)),
              norm_cond, ERROR_MARK);
        else
          {
--- 1066,1082 ----
    norm_cond->invert = false;
    norm_cond->conds = NULL;
    gcc_assert (gimple_code (cond) == GIMPLE_COND);
!   /* All GIMPLE_CONDs are pred != false.  */
!   cond_code = NE_EXPR;
    if (invert)
      cond_code = invert_tree_comparison (cond_code, false);
  
+   /* ???  It's not clear why we can't handle EQ_EXPR here but also not how.  */
    if (cond_code == NE_EXPR)
      {
!       if (TREE_CODE (gimple_cond_pred (cond)) == SSA_NAME)
          normalize_cond_1 (
!             SSA_NAME_DEF_STMT (gimple_cond_pred (cond)),
              norm_cond, ERROR_MARK);
        else
          {
*************** is_gcond_subset_of (gimple cond1, bool i
*** 1126,1143 ****
  
    gc1 = gimple_code (cond1);
    gc2 = gimple_code (cond2);
  
!   if ((gc1 != GIMPLE_ASSIGN && gc1 != GIMPLE_COND)
!       || (gc2 != GIMPLE_ASSIGN && gc2 != GIMPLE_COND))
      return cond1 == cond2;
  
!   cond1_code = ((gc1 == GIMPLE_ASSIGN)
!                 ? gimple_assign_rhs_code (cond1)
!                 : gimple_cond_code (cond1));
! 
!   cond2_code = ((gc2 == GIMPLE_ASSIGN)
!                 ? gimple_assign_rhs_code (cond2)
!                 : gimple_cond_code (cond2));
  
    if (TREE_CODE_CLASS (cond1_code) != tcc_comparison
        || TREE_CODE_CLASS (cond2_code) != tcc_comparison)
--- 1122,1144 ----
  
    gc1 = gimple_code (cond1);
    gc2 = gimple_code (cond2);
+   if (gc1 == GIMPLE_COND)
+     {
+       if (TREE_CODE (gimple_cond_pred (cond1)) == SSA_NAME)
+ 	cond1 = SSA_NAME_DEF_STMT (gimple_cond_pred (cond1));
+     }
+   if (gc2 == GIMPLE_COND)
+     {
+       if (TREE_CODE (gimple_cond_pred (cond2)) == SSA_NAME)
+ 	cond2 = SSA_NAME_DEF_STMT (gimple_cond_pred (cond2));
+     }
  
!   if (gc1 != GIMPLE_ASSIGN
!       || gc2 != GIMPLE_ASSIGN)
      return cond1 == cond2;
  
!   cond1_code = gimple_assign_rhs_code (cond1);
!   cond2_code = gimple_assign_rhs_code (cond2);
  
    if (TREE_CODE_CLASS (cond1_code) != tcc_comparison
        || TREE_CODE_CLASS (cond2_code) != tcc_comparison)
*************** is_gcond_subset_of (gimple cond1, bool i
*** 1148,1165 ****
    if (invert2)
      cond2_code = invert_tree_comparison (cond2_code, false);
  
!   cond1_lhs = ((gc1 == GIMPLE_ASSIGN)
!                ? gimple_assign_rhs1 (cond1)
!                : gimple_cond_lhs (cond1));
!   cond1_rhs = ((gc1 == GIMPLE_ASSIGN)
!                ? gimple_assign_rhs2 (cond1)
!                : gimple_cond_rhs (cond1));
!   cond2_lhs = ((gc2 == GIMPLE_ASSIGN)
!                ? gimple_assign_rhs1 (cond2)
!                : gimple_cond_lhs (cond2));
!   cond2_rhs = ((gc2 == GIMPLE_ASSIGN)
!                ? gimple_assign_rhs2 (cond2)
!                : gimple_cond_rhs (cond2));
  
    /* Assuming const operands have been swapped to the
       rhs at this point of the analysis.  */
--- 1149,1158 ----
    if (invert2)
      cond2_code = invert_tree_comparison (cond2_code, false);
  
!   cond1_lhs = gimple_assign_rhs1 (cond1);
!   cond1_rhs = gimple_assign_rhs2 (cond1);
!   cond2_lhs = gimple_assign_rhs1 (cond2);
!   cond2_rhs = gimple_assign_rhs2 (cond2);
  
    /* Assuming const operands have been swapped to the
       rhs at this point of the analysis.  */
*************** is_pred_expr_subset_of (use_pred_info_t
*** 1383,1390 ****
  
    cond1 = expr1->cond;
    cond2 = expr2->cond;
!   code1 = gimple_cond_code (cond1);
!   code2 = gimple_cond_code (cond2);
  
    if (expr1->invert)
      code1 = invert_tree_comparison (code1, false);
--- 1376,1383 ----
  
    cond1 = expr1->cond;
    cond2 = expr2->cond;
!   code1 = NE_EXPR;
!   code2 = NE_EXPR;
  
    if (expr1->invert)
      code1 = invert_tree_comparison (code1, false);
*************** is_pred_expr_subset_of (use_pred_info_t
*** 1392,1399 ****
      code2 = invert_tree_comparison (code2, false);
  
    /* Fast path -- match exactly  */
!   if ((gimple_cond_lhs (cond1) == gimple_cond_lhs (cond2))
!       && (gimple_cond_rhs (cond1) == gimple_cond_rhs (cond2))
        && (code1 == code2))
      return true;
  
--- 1385,1391 ----
      code2 = invert_tree_comparison (code2, false);
  
    /* Fast path -- match exactly  */
!   if ((gimple_cond_pred (cond1) == gimple_cond_pred (cond2))
        && (code1 == code2))
      return true;
  
Index: trunk/gcc/tree-vect-loop-manip.c
===================================================================
*** trunk.orig/gcc/tree-vect-loop-manip.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-vect-loop-manip.c	2010-08-30 14:32:23.000000000 +0200
*************** slpeel_make_loop_iterate_ntimes (struct
*** 767,772 ****
--- 767,773 ----
    tree step = build_int_cst (TREE_TYPE (niters), 1);
    LOC loop_loc;
    enum tree_code code;
+   tree cmp;
  
    orig_cond = get_loop_exit_condition (loop);
    gcc_assert (orig_cond);
*************** slpeel_make_loop_iterate_ntimes (struct
*** 783,790 ****
  				     true, GSI_SAME_STMT);
  
    code = (exit_edge->flags & EDGE_TRUE_VALUE) ? GE_EXPR : LT_EXPR;
!   cond_stmt = gimple_build_cond (code, indx_after_incr, niters, NULL_TREE,
! 				 NULL_TREE);
  
    gsi_insert_before (&loop_cond_gsi, cond_stmt, GSI_SAME_STMT);
  
--- 784,793 ----
  				     true, GSI_SAME_STMT);
  
    code = (exit_edge->flags & EDGE_TRUE_VALUE) ? GE_EXPR : LT_EXPR;
!   cmp = fold_build2 (code, boolean_type_node, indx_after_incr, niters);
!   cmp = force_gimple_operand_gsi (&loop_cond_gsi, cmp, true, NULL, true,
! 				  GSI_SAME_STMT);
!   cond_stmt = gimple_build_cond (cmp, NULL_TREE, NULL_TREE);
  
    gsi_insert_before (&loop_cond_gsi, cond_stmt, GSI_SAME_STMT);
  
*************** slpeel_add_loop_guard (basic_block guard
*** 947,955 ****
    cond = force_gimple_operand (cond, &gimplify_stmt_list, true, NULL_TREE);
    if (gimplify_stmt_list)
      gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
!   cond_stmt = gimple_build_cond (NE_EXPR,
! 				 cond, build_int_cst (TREE_TYPE (cond), 0),
! 				 NULL_TREE, NULL_TREE);
    if (cond_expr_stmt_list)
      gsi_insert_seq_after (&gsi, cond_expr_stmt_list, GSI_NEW_STMT);
  
--- 950,956 ----
    cond = force_gimple_operand (cond, &gimplify_stmt_list, true, NULL_TREE);
    if (gimplify_stmt_list)
      gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
!   cond_stmt = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
    if (cond_expr_stmt_list)
      gsi_insert_seq_after (&gsi, cond_expr_stmt_list, GSI_NEW_STMT);
  
*************** set_prologue_iterations (basic_block bb_
*** 1077,1085 ****
    cost_pre_condition =
      force_gimple_operand (cost_pre_condition, &gimplify_stmt_list,
  			  true, NULL_TREE);
!   cond_stmt = gimple_build_cond (NE_EXPR, cost_pre_condition,
! 				 build_int_cst (TREE_TYPE (cost_pre_condition),
! 						0), NULL_TREE, NULL_TREE);
  
    gsi = gsi_last_bb (cond_bb);
    if (gimplify_stmt_list)
--- 1078,1084 ----
    cost_pre_condition =
      force_gimple_operand (cost_pre_condition, &gimplify_stmt_list,
  			  true, NULL_TREE);
!   cond_stmt = gimple_build_cond (cost_pre_condition, NULL_TREE, NULL_TREE);
  
    gsi = gsi_last_bb (cond_bb);
    if (gimplify_stmt_list)
Index: trunk/gcc/cgraphunit.c
===================================================================
*** trunk.orig/gcc/cgraphunit.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/cgraphunit.c	2010-08-30 14:32:23.000000000 +0200
*************** assemble_thunk (struct cgraph_node *node
*** 1397,1415 ****
  	  if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
  	    {
  	      gimple stmt;
  	      /* If the return type is a pointer, we need to
  		 protect against NULL.  We know there will be an
  		 adjustment, because that's why we're emitting a
  		 thunk.  */
  	      then_bb = create_basic_block (NULL, (void *) 0, bb);
  	      return_bb = create_basic_block (NULL, (void *) 0, then_bb);
  	      else_bb = create_basic_block (NULL, (void *) 0, else_bb);
  	      remove_edge (single_succ_edge (bb));
  	      true_label = gimple_block_label (then_bb);
! 	      stmt = gimple_build_cond (NE_EXPR, restmp,
! 	      				fold_convert (TREE_TYPE (restmp),
! 						      integer_zero_node),
! 	      			        NULL_TREE, NULL_TREE);
  	      gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
  	      make_edge (bb, then_bb, EDGE_TRUE_VALUE);
  	      make_edge (bb, else_bb, EDGE_FALSE_VALUE);
--- 1397,1421 ----
  	  if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
  	    {
  	      gimple stmt;
+ 	      tree ctmp;
  	      /* If the return type is a pointer, we need to
  		 protect against NULL.  We know there will be an
  		 adjustment, because that's why we're emitting a
  		 thunk.  */
+ 	      ctmp = create_tmp_var_raw (boolean_type_node, NULL);
  	      then_bb = create_basic_block (NULL, (void *) 0, bb);
  	      return_bb = create_basic_block (NULL, (void *) 0, then_bb);
  	      else_bb = create_basic_block (NULL, (void *) 0, else_bb);
  	      remove_edge (single_succ_edge (bb));
  	      true_label = gimple_block_label (then_bb);
! 	      stmt = gimple_build_assign_with_ops (NE_EXPR, ctmp, restmp,
! 						   fold_convert
! 						     (TREE_TYPE (restmp),
! 						      integer_zero_node));
! 	      ctmp = make_ssa_name (ctmp, stmt);
! 	      gimple_assign_set_lhs (stmt, ctmp);
! 	      gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
! 	      stmt = gimple_build_cond (ctmp, NULL_TREE, NULL_TREE);
  	      gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
  	      make_edge (bb, then_bb, EDGE_TRUE_VALUE);
  	      make_edge (bb, else_bb, EDGE_FALSE_VALUE);
Index: trunk/gcc/ipa-prop.c
===================================================================
*** trunk.orig/gcc/ipa-prop.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/ipa-prop.c	2010-08-30 14:32:23.000000000 +0200
*************** compute_complex_ancestor_jump_func (stru
*** 458,463 ****
--- 458,465 ----
    basic_block phi_bb, assign_bb, cond_bb;
    tree tmp, parm, expr;
    int index, i;
+   enum tree_code code;
+   tree lhs, rhs;
  
    if (gimple_phi_num_args (phi) != 2
        || !integer_zerop (PHI_ARG_DEF (phi, 1)))
*************** compute_complex_ancestor_jump_func (stru
*** 500,511 ****
    cond_bb = single_pred (assign_bb);
    cond = last_stmt (cond_bb);
    if (!cond
!       || gimple_code (cond) != GIMPLE_COND
!       || gimple_cond_code (cond) != NE_EXPR
!       || gimple_cond_lhs (cond) != parm
!       || !integer_zerop (gimple_cond_rhs (cond)))
      return;
- 
  
    phi_bb = gimple_bb (phi);
    for (i = 0; i < 2; i++)
--- 502,514 ----
    cond_bb = single_pred (assign_bb);
    cond = last_stmt (cond_bb);
    if (!cond
!       || gimple_code (cond) != GIMPLE_COND)
!     return;
!   gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
!   if (code != NE_EXPR
!       || lhs != parm
!       || !integer_zerop (rhs))
      return;
  
    phi_bb = gimple_bb (phi);
    for (i = 0; i < 2; i++)
*************** ipa_analyze_indirect_call_uses (struct c
*** 1052,1057 ****
--- 1055,1062 ----
    gimple branch;
    int index;
    basic_block bb, virt_bb, join;
+   enum tree_code code;
+   tree rhs;
  
    if (SSA_NAME_IS_DEFAULT_DEF (target))
      {
*************** ipa_analyze_indirect_call_uses (struct c
*** 1117,1127 ****
    if (!branch || gimple_code (branch) != GIMPLE_COND)
      return;
  
!   if (gimple_cond_code (branch) != NE_EXPR
!       || !integer_zerop (gimple_cond_rhs (branch)))
      return;
  
-   cond = gimple_cond_lhs (branch);
    if (!ipa_is_ssa_with_stmt_def (cond))
      return;
  
--- 1122,1132 ----
    if (!branch || gimple_code (branch) != GIMPLE_COND)
      return;
  
!   gimple_cond_extract_comparison (branch, &code, &cond, &rhs);
!   if (code != NE_EXPR
!       || !integer_zerop (rhs))
      return;
  
    if (!ipa_is_ssa_with_stmt_def (cond))
      return;
  
Index: trunk/gcc/ipa-struct-reorg.c
===================================================================
*** trunk.orig/gcc/ipa-struct-reorg.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/ipa-struct-reorg.c	2010-08-30 14:32:23.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 56,61 ****
--- 56,63 ----
  #include "tree-dump.h"
  #include "gimple.h"
  
+ #if 0
+ 
  /* This optimization implements structure peeling.
  
     For example, given a structure type:
*************** reorg_structs (void)
*** 4023,4037 ****
    free_data_structs ();
  }
  
  /* Struct-reorg optimization entry point function.  */
  
  static unsigned int
  reorg_structs_drive (void)
  {
    /* IPA struct-reorg is completely broken - its analysis phase is
!      non-conservative (which is not the only reason it is broken).  */
    if (0)
!     reorg_structs ();
    return 0;
  }
  
--- 4025,4041 ----
    free_data_structs ();
  }
  
+ #endif
+ 
  /* Struct-reorg optimization entry point function.  */
  
  static unsigned int
  reorg_structs_drive (void)
  {
    /* IPA struct-reorg is completely broken - its analysis phase is
!      non-conservative (which is not the only reason it is broken).
    if (0)
!     reorg_structs ();  */
    return 0;
  }
  
Index: trunk/gcc/tree-mudflap.c
===================================================================
*** trunk.orig/gcc/tree-mudflap.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-mudflap.c	2010-08-30 14:32:23.000000000 +0200
*************** mf_build_check_statement_for (tree base,
*** 641,648 ****
  
    /* Build the conditional jump.  'cond' is just a temporary so we can
       simply build a void COND_EXPR.  We do need labels in both arms though.  */
!   g = gimple_build_cond (NE_EXPR, cond, boolean_false_node, NULL_TREE,
! 			 NULL_TREE);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
  
--- 641,647 ----
  
    /* Build the conditional jump.  'cond' is just a temporary so we can
       simply build a void COND_EXPR.  We do need labels in both arms though.  */
!   g = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
  
Index: trunk/gcc/tree-parloops.c
===================================================================
*** trunk.orig/gcc/tree-parloops.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-parloops.c	2010-08-30 14:32:23.000000000 +0200
*************** transform_to_exit_first_loop (struct loo
*** 1294,1307 ****
    gimple phi, nphi, cond_stmt, stmt, cond_nit;
    gimple_stmt_iterator gsi;
    tree nit_1;
  
    split_block_after_labels (loop->header);
    orig_header = single_succ (loop->header);
    hpred = single_succ_edge (loop->header);
  
    cond_stmt = last_stmt (exit->src);
!   control = gimple_cond_lhs (cond_stmt);
!   gcc_assert (gimple_cond_rhs (cond_stmt) == nit);
  
    /* Make sure that we have phi nodes on exit for all loop header phis
       (create_parallel_loop requires that).  */
--- 1294,1309 ----
    gimple phi, nphi, cond_stmt, stmt, cond_nit;
    gimple_stmt_iterator gsi;
    tree nit_1;
+   enum tree_code code;
+   tree rhs;
  
    split_block_after_labels (loop->header);
    orig_header = single_succ (loop->header);
    hpred = single_succ_edge (loop->header);
  
    cond_stmt = last_stmt (exit->src);
!   gimple_cond_extract_comparison (cond_stmt, &code, &control, &rhs);
!   gcc_assert (rhs == nit);
  
    /* Make sure that we have phi nodes on exit for all loop header phis
       (create_parallel_loop requires that).  */
*************** transform_to_exit_first_loop (struct loo
*** 1317,1323 ****
  
        if (res == control)
  	{
! 	  gimple_cond_set_lhs (cond_stmt, t);
  	  update_stmt (cond_stmt);
  	  control = t;
  	}
--- 1319,1326 ----
  
        if (res == control)
  	{
! 	  gimple_update_cond_from_comparison (gsi_for_stmt (cond_stmt),
! 					      code, t, rhs);
  	  update_stmt (cond_stmt);
  	  control = t;
  	}
*************** transform_to_exit_first_loop (struct loo
*** 1379,1385 ****
       according to the rhs of the exit condition.  */
    gsi = gsi_after_labels (ex_bb);
    cond_nit = last_stmt (exit->src);
!   nit_1 =  gimple_cond_rhs (cond_nit);
    nit_1 = force_gimple_operand_gsi (&gsi,
  				  fold_convert (TREE_TYPE (control_name), nit_1),
  				  false, NULL_TREE, false, GSI_SAME_STMT);
--- 1382,1388 ----
       according to the rhs of the exit condition.  */
    gsi = gsi_after_labels (ex_bb);
    cond_nit = last_stmt (exit->src);
!   gimple_cond_extract_comparison (cond_nit, &code, &rhs, &nit_1);
    nit_1 = force_gimple_operand_gsi (&gsi,
  				  fold_convert (TREE_TYPE (control_name), nit_1),
  				  false, NULL_TREE, false, GSI_SAME_STMT);
*************** create_parallel_loop (struct loop *loop,
*** 1404,1409 ****
--- 1407,1414 ----
    gimple stmt, for_stmt, phi, cond_stmt;
    tree cvar, cvar_init, initvar, cvar_next, cvar_base, type;
    edge exit, nexit, guard, end, e;
+   enum tree_code code;
+   tree rhs;
  
    /* Prepare the GIMPLE_OMP_PARALLEL statement.  */
    bb = loop_preheader_edge (loop)->src;
*************** create_parallel_loop (struct loop *loop,
*** 1442,1448 ****
    gcc_assert (loop->header == single_dom_exit (loop)->src);
    cond_stmt = last_stmt (loop->header);
  
!   cvar = gimple_cond_lhs (cond_stmt);
    cvar_base = SSA_NAME_VAR (cvar);
    phi = SSA_NAME_DEF_STMT (cvar);
    cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
--- 1447,1453 ----
    gcc_assert (loop->header == single_dom_exit (loop)->src);
    cond_stmt = last_stmt (loop->header);
  
!   gimple_cond_extract_comparison (cond_stmt, &code, &cvar, &rhs);
    cvar_base = SSA_NAME_VAR (cvar);
    phi = SSA_NAME_DEF_STMT (cvar);
    cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
*************** create_parallel_loop (struct loop *loop,
*** 1484,1490 ****
    PENDING_STMT (e) = NULL;
  
    /* Emit GIMPLE_OMP_FOR.  */
!   gimple_cond_set_lhs (cond_stmt, cvar_base);
    type = TREE_TYPE (cvar);
    t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_SCHEDULE);
    OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
--- 1489,1502 ----
    PENDING_STMT (e) = NULL;
  
    /* Emit GIMPLE_OMP_FOR.  */
!   if (has_zero_uses (gimple_cond_pred (cond_stmt))
!       && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_pred (cond_stmt)))
!     {
!       gimple def_stmt = SSA_NAME_DEF_STMT (gimple_cond_pred (cond_stmt));
!       gimple_stmt_iterator gsi2 = gsi_for_stmt (def_stmt);
!       gsi_remove (&gsi2, true);
!       release_defs (def_stmt);
!     }
    type = TREE_TYPE (cvar);
    t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_SCHEDULE);
    OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
*************** create_parallel_loop (struct loop *loop,
*** 1492,1499 ****
    for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
    gimple_omp_for_set_index (for_stmt, 0, initvar);
    gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
!   gimple_omp_for_set_final (for_stmt, 0, gimple_cond_rhs (cond_stmt));
!   gimple_omp_for_set_cond (for_stmt, 0, gimple_cond_code (cond_stmt));
    gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
  						cvar_base,
  						build_int_cst (type, 1)));
--- 1504,1511 ----
    for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
    gimple_omp_for_set_index (for_stmt, 0, initvar);
    gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
!   gimple_omp_for_set_final (for_stmt, 0, rhs);
!   gimple_omp_for_set_cond (for_stmt, 0, code);
    gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
  						cvar_base,
  						build_int_cst (type, 1)));
Index: trunk/gcc/tree-vrp.c
===================================================================
*** trunk.orig/gcc/tree-vrp.c	2010-08-29 16:30:26.000000000 +0200
--- trunk/gcc/tree-vrp.c	2010-08-30 14:32:23.000000000 +0200
*************** build_assert_expr_for (tree cond, tree v
*** 3948,3965 ****
  }
  
  
- /* Return false if EXPR is a predicate expression involving floating
-    point values.  */
- 
- static inline bool
- fp_predicate (gimple stmt)
- {
-   GIMPLE_CHECK (stmt, GIMPLE_COND);
- 
-   return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
- }
- 
- 
  /* If the range of values taken by OP can be inferred after STMT executes,
     return the comparison code (COMP_CODE_P) and value (VAL_P) that
     describes the inferred range.  Return true if a range could be
--- 3948,3953 ----
*************** register_edge_assert_for_1 (tree op, enu
*** 4429,4434 ****
--- 4417,4428 ----
    if (TREE_CODE (op) != SSA_NAME)
      return false;
  
+   /* Do not attempt to infer anything in names that flow through
+      abnormal edges.  */
+   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
+     return false;
+ 
+ 
    /* We know that OP will have a zero or nonzero value.  If OP is used
       more than once go ahead and register an assert for OP.
  
*************** register_edge_assert_for_1 (tree op, enu
*** 4457,4462 ****
--- 4451,4460 ----
        tree op0 = gimple_assign_rhs1 (op_def);
        tree op1 = gimple_assign_rhs2 (op_def);
  
+       /* Do not register asserts for floating-point comparisons.  */
+       if (FLOAT_TYPE_P (TREE_TYPE (op0)))
+ 	return retval;
+ 
        if (TREE_CODE (op0) == SSA_NAME)
          retval |= register_edge_assert_for_2 (op0, e, bsi, rhs_code, op0, op1,
  					      invert);
*************** find_conditional_asserts (basic_block bb
*** 4592,4601 ****
  {
    bool need_assert;
    gimple_stmt_iterator bsi;
-   tree op;
    edge_iterator ei;
    edge e;
!   ssa_op_iter iter;
  
    need_assert = false;
    bsi = gsi_for_stmt (last);
--- 4590,4602 ----
  {
    bool need_assert;
    gimple_stmt_iterator bsi;
    edge_iterator ei;
    edge e;
!   tree pred;
! 
!   pred = gimple_cond_pred (last);
!   if (TREE_CODE (pred) != SSA_NAME)
!     return false;
  
    need_assert = false;
    bsi = gsi_for_stmt (last);
*************** find_conditional_asserts (basic_block bb
*** 4609,4623 ****
        if (e->dest == bb)
  	continue;
  
!       /* Register the necessary assertions for each operand in the
! 	 conditional predicate.  */
!       FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
! 	{
! 	  need_assert |= register_edge_assert_for (op, e, bsi,
! 						   gimple_cond_code (last),
! 						   gimple_cond_lhs (last),
! 						   gimple_cond_rhs (last));
! 	}
      }
  
    return need_assert;
--- 4610,4618 ----
        if (e->dest == bb)
  	continue;
  
!       need_assert |= register_edge_assert_for_1 (pred,
! 						 (e->flags & EDGE_FALSE_VALUE)
! 						 ? EQ_EXPR : NE_EXPR, e, bsi);
      }
  
    return need_assert;
*************** find_assert_locations_1 (basic_block bb,
*** 4815,4825 ****
    need_assert = false;
    last = last_stmt (bb);
  
!   /* If BB's last statement is a conditional statement involving integer
!      operands, determine if we need to add ASSERT_EXPRs.  */
    if (last
        && gimple_code (last) == GIMPLE_COND
-       && !fp_predicate (last)
        && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
      need_assert |= find_conditional_asserts (bb, last);
  
--- 4810,4819 ----
    need_assert = false;
    last = last_stmt (bb);
  
!   /* If BB's last statement is a conditional statement, determine if
!      we need to add ASSERT_EXPRs.  */
    if (last
        && gimple_code (last) == GIMPLE_COND
        && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
      need_assert |= find_conditional_asserts (bb, last);
  
*************** vrp_visit_cond_stmt (gimple stmt, edge *
*** 6073,6081 ****
       4 more predicates folded in SPEC.  */
    sop = false;
  
!   val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
! 						 gimple_cond_lhs (stmt),
! 						 gimple_cond_rhs (stmt),
  						 false, &sop, NULL);
    if (val)
      {
--- 6067,6075 ----
       4 more predicates folded in SPEC.  */
    sop = false;
  
!   val = vrp_evaluate_conditional_warnv_with_ops (NE_EXPR,
! 						 gimple_cond_pred (stmt),
! 						 boolean_false_node,
  						 false, &sop, NULL);
    if (val)
      {
*************** test_for_singularity (enum tree_code con
*** 7088,7106 ****
    return NULL;
  }
  
! /* Simplify a conditional using a relational operator to an equality
     test if the range information indicates only one value can satisfy
!    the original conditional.  */
  
  static bool
  simplify_cond_using_ranges (gimple stmt)
  {
!   tree op0 = gimple_cond_lhs (stmt);
!   tree op1 = gimple_cond_rhs (stmt);
!   enum tree_code cond_code = gimple_cond_code (stmt);
  
!   if (cond_code != NE_EXPR
!       && cond_code != EQ_EXPR
        && TREE_CODE (op0) == SSA_NAME
        && INTEGRAL_TYPE_P (TREE_TYPE (op0))
        && is_gimple_min_invariant (op1))
--- 7082,7102 ----
    return NULL;
  }
  
! /* Simplify a comparison using a relational operator to an equality
     test if the range information indicates only one value can satisfy
!    the original comparison.  */
  
  static bool
  simplify_cond_using_ranges (gimple stmt)
  {
!   tree op0 = gimple_assign_rhs1 (stmt);
!   tree op1 = gimple_assign_rhs2 (stmt);
!   enum tree_code cond_code = gimple_assign_rhs_code (stmt);
  
!   if ((cond_code == LT_EXPR
!        || cond_code == LE_EXPR
!        || cond_code == GE_EXPR
!        || cond_code == GT_EXPR)
        && TREE_CODE (op0) == SSA_NAME
        && INTEGRAL_TYPE_P (TREE_TYPE (op0))
        && is_gimple_min_invariant (op1))
*************** simplify_cond_using_ranges (gimple stmt)
*** 7122,7131 ****
  		  fprintf (dump_file, " into ");
  		}
  
! 	      gimple_cond_set_code (stmt, EQ_EXPR);
! 	      gimple_cond_set_lhs (stmt, op0);
! 	      gimple_cond_set_rhs (stmt, new_tree);
! 
  	      update_stmt (stmt);
  
  	      if (dump_file)
--- 7118,7126 ----
  		  fprintf (dump_file, " into ");
  		}
  
! 	      gimple_assign_set_rhs_code (stmt, EQ_EXPR);
! 	      gimple_assign_set_rhs1 (stmt, op0);
! 	      gimple_assign_set_rhs2 (stmt, new_tree);
  	      update_stmt (stmt);
  
  	      if (dump_file)
*************** simplify_cond_using_ranges (gimple stmt)
*** 7152,7161 ****
  		  fprintf (dump_file, " into ");
  		}
  
! 	      gimple_cond_set_code (stmt, NE_EXPR);
! 	      gimple_cond_set_lhs (stmt, op0);
! 	      gimple_cond_set_rhs (stmt, new_tree);
! 
  	      update_stmt (stmt);
  
  	      if (dump_file)
--- 7147,7155 ----
  		  fprintf (dump_file, " into ");
  		}
  
! 	      gimple_assign_set_rhs_code (stmt, NE_EXPR);
! 	      gimple_assign_set_rhs1 (stmt, op0);
! 	      gimple_assign_set_rhs2 (stmt, new_tree);
  	      update_stmt (stmt);
  
  	      if (dump_file)
*************** simplify_stmt_using_ranges (gimple_stmt_
*** 7278,7283 ****
--- 7272,7285 ----
  
        switch (rhs_code)
  	{
+ 	case LT_EXPR:
+ 	case LE_EXPR:
+ 	case GT_EXPR:
+ 	case GE_EXPR:
+ 	  if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ 	    return simplify_cond_using_ranges (stmt);
+ 	  break;
+ 
  	case EQ_EXPR:
  	case NE_EXPR:
  	case TRUTH_NOT_EXPR:
*************** simplify_stmt_using_ranges (gimple_stmt_
*** 7322,7329 ****
  	  break;
  	}
      }
-   else if (gimple_code (stmt) == GIMPLE_COND)
-     return simplify_cond_using_ranges (stmt);
    else if (gimple_code (stmt) == GIMPLE_SWITCH)
      return simplify_switch_using_ranges (stmt);
  
--- 7324,7329 ----
*************** fold_predicate_in (gimple_stmt_iterator
*** 7351,7359 ****
  				      stmt);
      }
    else if (gimple_code (stmt) == GIMPLE_COND)
!     val = vrp_evaluate_conditional (gimple_cond_code (stmt),
! 				    gimple_cond_lhs (stmt),
! 				    gimple_cond_rhs (stmt),
  				    stmt);
    else
      return false;
--- 7351,7359 ----
  				      stmt);
      }
    else if (gimple_code (stmt) == GIMPLE_COND)
!     val = vrp_evaluate_conditional (NE_EXPR,
! 				    gimple_cond_pred (stmt),
! 				    boolean_false_node,
  				    stmt);
    else
      return false;
*************** fold_predicate_in (gimple_stmt_iterator
*** 7361,7375 ****
    if (val)
      {
        if (assignment_p)
-         val = fold_convert (gimple_expr_type (stmt), val);
- 
-       if (dump_file)
  	{
! 	  fprintf (dump_file, "Folding predicate ");
! 	  print_gimple_expr (dump_file, stmt, 0, 0);
! 	  fprintf (dump_file, " to ");
! 	  print_generic_expr (dump_file, val, 0);
! 	  fprintf (dump_file, "\n");
  	}
  
        if (is_gimple_assign (stmt))
--- 7361,7377 ----
    if (val)
      {
        if (assignment_p)
  	{
! 	  val = fold_convert (gimple_expr_type (stmt), val);
! 
! 	  if (dump_file)
! 	    {
! 	      fprintf (dump_file, "Folding predicate ");
! 	      print_gimple_expr (dump_file, stmt, 0, 0);
! 	      fprintf (dump_file, " to ");
! 	      print_generic_expr (dump_file, val, 0);
! 	      fprintf (dump_file, "\n");
! 	    }
  	}
  
        if (is_gimple_assign (stmt))
*************** simplify_stmt_for_jump_threading (gimple
*** 7420,7431 ****
    /* We only use VRP information to simplify conditionals.  This is
       overly conservative, but it's unclear if doing more would be
       worth the compile time cost.  */
!   if (gimple_code (stmt) != GIMPLE_COND)
!     return NULL;
  
!   return vrp_evaluate_conditional (gimple_cond_code (stmt),
! 				   gimple_cond_lhs (stmt),
! 				   gimple_cond_rhs (stmt), within_stmt);
  }
  
  /* Blocks which have more than one predecessor and more than
--- 7422,7436 ----
    /* We only use VRP information to simplify conditionals.  This is
       overly conservative, but it's unclear if doing more would be
       worth the compile time cost.  */
!   if (!is_gimple_assign (stmt))
!     return NULL_TREE;
! 
!   if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
!     return vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
! 				     gimple_assign_rhs1 (stmt),
! 				     gimple_assign_rhs2 (stmt), within_stmt);
  
!   return NULL_TREE;
  }
  
  /* Blocks which have more than one predecessor and more than
*************** identify_jump_threads (void)
*** 7480,7488 ****
    /* To avoid lots of silly node creation, we create a single
       conditional and just modify it in-place when attempting to
       thread jumps.  */
!   dummy = gimple_build_cond (EQ_EXPR,
! 			     integer_zero_node, integer_zero_node,
! 			     NULL, NULL);
  
    /* Walk through all the blocks finding those which present a
       potential jump threading opportunity.  We could set this up
--- 7485,7491 ----
    /* To avoid lots of silly node creation, we create a single
       conditional and just modify it in-place when attempting to
       thread jumps.  */
!   dummy = gimple_build_cond (boolean_true_node, NULL, NULL);
  
    /* Walk through all the blocks finding those which present a
       potential jump threading opportunity.  We could set this up
*************** identify_jump_threads (void)
*** 7493,7498 ****
--- 7496,7502 ----
    FOR_EACH_BB (bb)
      {
        gimple last;
+       edge_iterator ei;
  
        /* If the generic jump threading code does not find this block
  	 interesting, then there is nothing to do.  */
*************** identify_jump_threads (void)
*** 7506,7535 ****
        if (gimple_code (last) != GIMPLE_COND)
  	continue;
  
!       /* We're basically looking for any kind of conditional with
! 	 integral type arguments.  */
!       if (TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
! 	  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
! 	  && (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
! 	      || is_gimple_min_invariant (gimple_cond_rhs (last)))
! 	  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_rhs (last))))
! 	{
! 	  edge_iterator ei;
! 
! 	  /* We've got a block with multiple predecessors and multiple
! 	     successors which also ends in a suitable conditional.  For
! 	     each predecessor, see if we can thread it to a specific
! 	     successor.  */
! 	  FOR_EACH_EDGE (e, ei, bb->preds)
! 	    {
! 	      /* Do not thread across back edges or abnormal edges
! 		 in the CFG.  */
! 	      if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
! 		continue;
  
! 	      thread_across_edge (dummy, e, true, &stack,
! 				  simplify_stmt_for_jump_threading);
! 	    }
  	}
      }
  
--- 7510,7528 ----
        if (gimple_code (last) != GIMPLE_COND)
  	continue;
  
!       /* We've got a block with multiple predecessors and multiple
! 	 successors which also ends in a suitable conditional.  For
! 	 each predecessor, see if we can thread it to a specific
! 	 successor.  */
!       FOR_EACH_EDGE (e, ei, bb->preds)
! 	{
! 	  /* Do not thread across back edges or abnormal edges
! 	     in the CFG.  */
! 	  if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
! 	    continue;
  
! 	  thread_across_edge (dummy, e, true, &stack,
! 			      simplify_stmt_for_jump_threading);
  	}
      }
  
Index: trunk/gcc/value-prof.c
===================================================================
*** trunk.orig/gcc/value-prof.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/value-prof.c	2010-08-30 14:32:23.000000000 +0200
*************** gimple_divmod_fixed_value (gimple stmt,
*** 577,586 ****
    gsi = gsi_for_stmt (stmt);
  
    tmpv = create_tmp_var (optype, "PROF");
!   tmp1 = create_tmp_var (optype, "PROF");
    stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
!   stmt2 = gimple_build_assign (tmp1, op2);
!   stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
--- 577,586 ----
    gsi = gsi_for_stmt (stmt);
  
    tmpv = create_tmp_var (optype, "PROF");
!   tmp1 = create_tmp_var (boolean_type_node, "PROF");
    stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
!   stmt2 = gimple_build_assign_with_ops (NE_EXPR, tmp1, op2, tmpv);
!   stmt3 = gimple_build_cond (tmp1, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
*************** gimple_divmod_fixed_value_transform (gim
*** 710,717 ****
  static tree
  gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
  {
!   gimple stmt1, stmt2, stmt3, stmt4;
!   tree tmp2, tmp3;
    gimple bb1end, bb2end, bb3end;
    basic_block bb, bb2, bb3, bb4;
    tree optype, op1, op2;
--- 710,717 ----
  static tree
  gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
  {
!   gimple stmt1, stmt2, stmt3, stmt4, stmt5;
!   tree tmp2, tmp3, tmp4;
    gimple bb1end, bb2end, bb3end;
    basic_block bb, bb2, bb3, bb4;
    tree optype, op1, op2;
*************** gimple_mod_pow2 (gimple stmt, int prob,
*** 732,745 ****
    result = create_tmp_var (optype, "PROF");
    tmp2 = create_tmp_var (optype, "PROF");
    tmp3 = create_tmp_var (optype, "PROF");
    stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
  					build_int_cst (optype, -1));
    stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
!   stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
! 			     NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
    bb1end = stmt4;
  
    /* tmp2 == op2-1 inherited from previous block.  */
--- 732,748 ----
    result = create_tmp_var (optype, "PROF");
    tmp2 = create_tmp_var (optype, "PROF");
    tmp3 = create_tmp_var (optype, "PROF");
+   tmp4 = create_tmp_var (boolean_type_node, NULL);
    stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
  					build_int_cst (optype, -1));
    stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
!   stmt4 = gimple_build_assign_with_ops (NE_EXPR, tmp4, tmp3,
! 					build_int_cst (optype, 0));
!   stmt5 = gimple_build_cond (tmp4, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
+   gsi_insert_before (&gsi, stmt5, GSI_SAME_STMT);
    bb1end = stmt4;
  
    /* tmp2 == op2-1 inherited from previous block.  */
*************** gimple_mod_subtract (gimple stmt, int pr
*** 882,891 ****
    gsi = gsi_for_stmt (stmt);
  
    result = create_tmp_var (optype, "PROF");
!   tmp1 = create_tmp_var (optype, "PROF");
    stmt1 = gimple_build_assign (result, op1);
!   stmt2 = gimple_build_assign (tmp1, op2);
!   stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
--- 885,894 ----
    gsi = gsi_for_stmt (stmt);
  
    result = create_tmp_var (optype, "PROF");
!   tmp1 = create_tmp_var (boolean_type_node, "PROF");
    stmt1 = gimple_build_assign (result, op1);
!   stmt2 = gimple_build_assign_with_ops (LT_EXPR, tmp1, result, op2);
!   stmt3 = gimple_build_cond (tmp1, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
*************** gimple_mod_subtract (gimple stmt, int pr
*** 893,900 ****
  
    if (ncounts)	/* Assumed to be 0 or 1 */
      {
!       stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
!       stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
        gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
        gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
        bb2end = stmt2;
--- 896,904 ----
  
    if (ncounts)	/* Assumed to be 0 or 1 */
      {
!       stmt1 = gimple_build_assign_with_ops (LT_EXPR, tmp1, result, op2);
!       stmt2 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, op2);
!       stmt3 = gimple_build_cond (tmp1, NULL_TREE, NULL_TREE);
        gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
        gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
        bb2end = stmt2;
*************** gimple_mod_subtract (gimple stmt, int pr
*** 902,908 ****
  
    /* Fallback case. */
    stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
! 					result, tmp1);
    gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    bb3end = stmt1;
  
--- 906,912 ----
  
    /* Fallback case. */
    stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
! 					result, op2);
    gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    bb3end = stmt1;
  
*************** static gimple
*** 1091,1098 ****
  gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
  	   int prob, gcov_type count, gcov_type all)
  {
!   gimple dcall_stmt, load_stmt, cond_stmt;
!   tree tmp1, tmpv, tmp;
    basic_block cond_bb, dcall_bb, icall_bb, join_bb;
    tree optype = build_pointer_type (void_type_node);
    edge e_cd, e_ci, e_di, e_dj, e_ij;
--- 1095,1102 ----
  gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
  	   int prob, gcov_type count, gcov_type all)
  {
!   gimple dcall_stmt, load_stmt, cond_stmt, comp_stmt;
!   tree tmp1, tmpv, tmp, tmp2;
    basic_block cond_bb, dcall_bb, icall_bb, join_bb;
    tree optype = build_pointer_type (void_type_node);
    edge e_cd, e_ci, e_di, e_dj, e_ij;
*************** gimple_ic (gimple icall_stmt, struct cgr
*** 1113,1119 ****
    load_stmt = gimple_build_assign (tmp1, tmp);
    gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
  
!   cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  
    dcall_stmt = gimple_copy (icall_stmt);
--- 1117,1126 ----
    load_stmt = gimple_build_assign (tmp1, tmp);
    gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
  
!   tmp2 = create_tmp_var (boolean_type_node, NULL);
!   comp_stmt = gimple_build_assign_with_ops (EQ_EXPR, tmp2, tmp1, tmpv);
!   gsi_insert_before (&gsi, comp_stmt, GSI_SAME_STMT);
!   cond_stmt = gimple_build_cond (tmp2, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  
    dcall_stmt = gimple_copy (icall_stmt);
*************** static void
*** 1288,1295 ****
  gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
  			     gcov_type count, gcov_type all)
  {
!   gimple tmp_stmt, cond_stmt, icall_stmt;
!   tree tmp1, tmpv, vcall_size, optype;
    basic_block cond_bb, icall_bb, vcall_bb, join_bb;
    edge e_ci, e_cv, e_iv, e_ij, e_vj;
    gimple_stmt_iterator gsi;
--- 1295,1302 ----
  gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
  			     gcov_type count, gcov_type all)
  {
!   gimple tmp_stmt, cond_stmt, icall_stmt, comp_stmt;
!   tree tmp1, tmpv, vcall_size, optype, tmp2;
    basic_block cond_bb, icall_bb, vcall_bb, join_bb;
    edge e_ci, e_cv, e_iv, e_ij, e_vj;
    gimple_stmt_iterator gsi;
*************** gimple_stringop_fixed_value (gimple vcal
*** 1314,1320 ****
    tmp_stmt = gimple_build_assign (tmp1, vcall_size);
    gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
  
!   cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  
    icall_stmt = gimple_copy (vcall_stmt);
--- 1321,1330 ----
    tmp_stmt = gimple_build_assign (tmp1, vcall_size);
    gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
  
!   tmp2 = create_tmp_var (boolean_type_node, NULL);
!   comp_stmt = gimple_build_assign_with_ops (EQ_EXPR, tmp2, tmp1, tmpv);
!   gsi_insert_before (&gsi, comp_stmt, GSI_SAME_STMT);
!   cond_stmt = gimple_build_cond (tmp2, NULL_TREE, NULL_TREE);
    gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  
    icall_stmt = gimple_copy (vcall_stmt);
Index: trunk/gcc/tree-ssa-propagate.c
===================================================================
*** trunk.orig/gcc/tree-ssa-propagate.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-propagate.c	2010-08-30 14:32:23.000000000 +0200
*************** substitute_and_fold (ssa_prop_get_value_
*** 1019,1024 ****
--- 1019,1039 ----
  	gsi = gsi_for_stmt (def_stmt);
  	if (is_gimple_assign (def_stmt))
  	  {
+ 	    if (dump_file
+ 		&& (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
+ 		    == tcc_comparison))
+ 	      {
+ 		fprintf (dump_file, "Folding predicate ");
+ 		print_generic_expr (dump_file,
+ 				    gimple_assign_rhs1 (def_stmt), 0);
+ 		fprintf (dump_file, " %s ",
+ 			 op_symbol_code (gimple_assign_rhs_code (def_stmt)));
+ 		print_generic_expr (dump_file,
+ 				    gimple_assign_rhs2 (def_stmt), 0);
+ 		fprintf (dump_file, " to ");
+ 		print_generic_expr (dump_file, val, 0);
+ 		fprintf (dump_file, "\n");
+ 	      }
  	    gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val),
  					    val, NULL_TREE);
  	    gcc_assert (gsi_stmt (gsi) == def_stmt);
Index: trunk/gcc/tree-eh.c
===================================================================
*** trunk.orig/gcc/tree-eh.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-eh.c	2010-08-30 14:32:23.000000000 +0200
*************** replace_goto_queue_1 (gimple stmt, struc
*** 520,527 ****
        break;
  
      case GIMPLE_COND:
!       replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 2), tf, gsi);
!       replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 3), tf, gsi);
        break;
  
      case GIMPLE_TRY:
--- 520,529 ----
        break;
  
      case GIMPLE_COND:
!       replace_goto_queue_cond_clause (gimple_cond_true_label_ptr (stmt),
! 				      tf, gsi);
!       replace_goto_queue_cond_clause (gimple_cond_false_label_ptr (stmt),
! 				      tf, gsi);
        break;
  
      case GIMPLE_TRY:
*************** maybe_record_in_goto_queue (struct leh_s
*** 661,669 ****
    switch (gimple_code (stmt))
      {
      case GIMPLE_COND:
!       new_stmt.tp = gimple_op_ptr (stmt, 2);
        record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt));
!       new_stmt.tp = gimple_op_ptr (stmt, 3);
        record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt));
        break;
      case GIMPLE_GOTO:
--- 663,671 ----
    switch (gimple_code (stmt))
      {
      case GIMPLE_COND:
!       new_stmt.tp = gimple_cond_true_label_ptr (stmt);
        record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt));
!       new_stmt.tp = gimple_cond_false_label_ptr (stmt);
        record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt));
        break;
      case GIMPLE_GOTO:
*************** lower_eh_dispatch (basic_block src, gimp
*** 3197,3202 ****
--- 3199,3205 ----
        {
  	edge b_e = BRANCH_EDGE (src);
  	edge f_e = FALLTHRU_EDGE (src);
+ 	tree cond;
  
  	fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
  	x = gimple_build_call (fn, 1, build_int_cst (NULL, region_nr));
*************** lower_eh_dispatch (basic_block src, gimp
*** 3206,3215 ****
  	gsi_insert_before (&gsi, x, GSI_SAME_STMT);
  
  	r->u.allowed.label = NULL;
! 	x = gimple_build_cond (EQ_EXPR, filter,
! 			       build_int_cst (TREE_TYPE (filter),
! 					      r->u.allowed.filter),
! 			       NULL_TREE, NULL_TREE);
  	gsi_insert_before (&gsi, x, GSI_SAME_STMT);
  
  	b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
--- 3209,3220 ----
  	gsi_insert_before (&gsi, x, GSI_SAME_STMT);
  
  	r->u.allowed.label = NULL;
! 	cond = fold_build2 (EQ_EXPR, boolean_type_node,
! 			    filter, build_int_cst (TREE_TYPE (filter),
! 						   r->u.allowed.filter));
! 	cond = force_gimple_operand_gsi (&gsi, cond, true, NULL,
! 					 true, GSI_SAME_STMT);
! 	x = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
  	gsi_insert_before (&gsi, x, GSI_SAME_STMT);
  
  	b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
Index: trunk/gcc/cp/cp-gimplify.c
===================================================================
*** trunk.orig/gcc/cp/cp-gimplify.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/cp/cp-gimplify.c	2010-08-30 14:32:23.000000000 +0200
*************** gimplify_cp_loop (tree cond, tree body,
*** 238,245 ****
  	  if (cond != error_mark_node)
  	    { 
  	      gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
! 	      stmt = gimple_build_cond (NE_EXPR, cond,
! 					build_int_cst (TREE_TYPE (cond), 0),
  					gimple_label_label (top),
  					get_bc_label (bc_break));
  	      gimple_seq_add_stmt (&exit_seq, stmt);
--- 238,244 ----
  	  if (cond != error_mark_node)
  	    { 
  	      gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
! 	      stmt = gimple_build_cond (cond,
  					gimple_label_label (top),
  					get_bc_label (bc_break));
  	      gimple_seq_add_stmt (&exit_seq, stmt);
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c	2010-08-30 14:32:23.000000000 +0200
*************** void main (void)
*** 8,12 ****
      f2 ();
  }
  
! /* { dg-final { scan-tree-dump-times "!= 0" 5 "ivopts" } }  */
  /* { dg-final { cleanup-tree-dump "ivopts" } }  */
--- 8,12 ----
      f2 ();
  }
  
! /* { dg-final { scan-tree-dump-times "!= 0" 3 "ivopts" } }  */
  /* { dg-final { cleanup-tree-dump "ivopts" } }  */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-1.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-1.c	2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 7,11 ****
      g ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
--- 7,11 ----
      g ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-2.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-2.c	2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 9,13 ****
      g ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
--- 9,13 ----
      g ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-3.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-3.c	2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 9,13 ****
      b ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
--- 9,13 ----
      b ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-4.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-4.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-4.c	2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 9,13 ****
      b ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
--- 9,13 ----
      b ();
  } 
  
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c	2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 10,15 ****
  } 
  
  /* { dg-final { scan-tree-dump-times { if } 2 "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 0\);\n[^\n]*if} "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 1\);\n[^\n]*if} "forwprop1"} } */
  /* { dg-final { cleanup-tree-dump "forwprop?" } } */
--- 10,15 ----
  } 
  
  /* { dg-final { scan-tree-dump-times { if } 2 "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 1\);\n[^\n;]*;\n[^\n]*if} "forwprop1"} } */
  /* { dg-final { cleanup-tree-dump "forwprop?" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20657.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr20657.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20657.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 3,9 ****
     statement, which was needed to eliminate the second "if" statement.  */
  
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
  
  int
  foo (int a)
--- 3,9 ----
     statement, which was needed to eliminate the second "if" statement.  */
  
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
  
  int
  foo (int a)
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 5,11 ****
     range infomation out of the conditional.  */
  
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
  
  int
  foo (int a)
--- 5,11 ----
     range infomation out of the conditional.  */
  
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
  
  int
  foo (int a)
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c	2010-08-30 14:32:23.000000000 +0200
*************** foo (__SIZE_TYPE__ i, struct s *array)
*** 16,23 ****
      }
    return 0;
  }
! /* We should eliminate two address calculations, and one load.  */
  /* We used to eliminate a cast but that was before POINTER_PLUS_EXPR
     was added.  */
! /* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "fre"} } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 16,24 ----
      }
    return 0;
  }
! /* We should eliminate two address calculations, and one load and
!    simplify the p != q comparison to 0.  */
  /* We used to eliminate a cast but that was before POINTER_PLUS_EXPR
     was added.  */
! /* { dg-final { scan-tree-dump-times "Eliminated: 4" 1 "fre"} } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
  
  foo (int a, int b)
  {
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1" } */
  
  foo (int a, int b)
  {
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
  
  foo (int i, int *p)
  {
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1-details" } */
  
  foo (int i, int *p)
  {
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
  
  foo (int *p)
  {
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1" } */
  
  foo (int *p)
  {
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-fwrapv -O1 -ftree-vrp -fdump-tree-vrp1" } */
  
  extern void abort ();
  extern void exit (int);
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-fwrapv -O1 -fno-tree-fre -ftree-vrp -fdump-tree-vrp1" } */
  
  extern void abort ();
  extern void exit (int);
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp25.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp25.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp25.c	2010-08-30 14:32:23.000000000 +0200
*************** L9:
*** 47,52 ****
  /* The second test of (code1 != 53) and the test (D18670 <= 2) are
     both totally subsumed by earlier tests and thus should be folded
     away using VRP.  */
! /* { dg-final { scan-tree-dump-times "Folding predicate" 2 "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
  
--- 47,53 ----
  /* The second test of (code1 != 53) and the test (D18670 <= 2) are
     both totally subsumed by earlier tests and thus should be folded
     away using VRP.  */
! /* { dg-final { scan-tree-dump "Folding predicate D\[0-9_\]* <= 2 to 0" "vrp1" } } */
! /* { dg-final { scan-tree-dump-times "Folded into: if \\\(0\\\)" 2 "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
  
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c	2010-08-30 14:32:23.000000000 +0200
***************
*** 1,9 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
  
  /* This is from PR14052.  */
  
  int f2(int x) { return x == 1 || x == 3 || x == 1; }
  
! /* { dg-final { scan-tree-dump "Folding predicate.*== 1 to 0" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 1,9 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
  
  /* This is from PR14052.  */
  
  int f2(int x) { return x == 1 || x == 3 || x == 1; }
  
! /* { dg-final { scan-tree-dump "Folded into: if \\\(0\\\)" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c	2010-08-30 14:32:23.000000000 +0200
*************** int test1(int i, int k)
*** 11,15 ****
    return 1;
  }
  
! /* { dg-final { scan-tree-dump-not "j_.* == 10" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 11,15 ----
    return 1;
  }
  
! /* { dg-final { scan-tree-dump "Folding predicate j_\[0-9\]* == 10 to 0" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c	2010-08-30 14:32:23.000000000 +0200
*************** int foo(int i)
*** 8,12 ****
    return 1;
  }
  
! /* { dg-final { scan-tree-dump-not "i_.* == 1" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 8,12 ----
    return 1;
  }
  
! /* { dg-final { scan-tree-dump "Folding predicate i_\[0-9\]* == 1 to 0" "vrp1" } } */
  /* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.c-torture/execute/920612-1.x
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.c-torture/execute/920612-1.x	2010-08-30 14:32:23.000000000 +0200
***************
*** 0 ****
--- 1,2 ----
+ set additional_flags "-fwrapv"
+ return 0
Index: trunk/gcc/tree-ssa-threadupdate.c
===================================================================
*** trunk.orig/gcc/tree-ssa-threadupdate.c	2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-threadupdate.c	2010-08-30 14:32:23.000000000 +0200
*************** redirection_block_p (basic_block bb)
*** 482,487 ****
--- 482,498 ----
    if (gsi_end_p (gsi))
      return true;
  
+   /* The terminating GIMPLE_COND can have a preceding predicate computation.  */
+   if (is_gimple_assign (gsi_stmt (gsi)))
+     {
+       gimple pred = gsi_stmt (gsi);
+       gsi_next (&gsi);
+       if (gsi_end_p (gsi)
+ 	  || gimple_code (gsi_stmt (gsi)) != GIMPLE_COND
+ 	  || gimple_cond_pred (gsi_stmt (gsi)) != gimple_assign_lhs (pred))
+ 	return false;
+     }
+ 
    /* Test that we've reached the terminating control statement.  */
    return gsi_stmt (gsi)
           && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
Index: trunk/gcc/tree-vect-data-refs.c
===================================================================
*** trunk.orig/gcc/tree-vect-data-refs.c	2010-08-24 10:32:38.000000000 +0200
--- trunk/gcc/tree-vect-data-refs.c	2010-08-30 15:26:46.000000000 +0200
*************** tree
*** 64,72 ****
  vect_get_smallest_scalar_type (gimple stmt, HOST_WIDE_INT *lhs_size_unit,
                                 HOST_WIDE_INT *rhs_size_unit)
  {
!   tree scalar_type = gimple_expr_type (stmt);
    HOST_WIDE_INT lhs, rhs;
  
    lhs = rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
  
    if (is_gimple_assign (stmt)
--- 64,77 ----
  vect_get_smallest_scalar_type (gimple stmt, HOST_WIDE_INT *lhs_size_unit,
                                 HOST_WIDE_INT *rhs_size_unit)
  {
!   tree scalar_type;
    HOST_WIDE_INT lhs, rhs;
  
+   if (is_gimple_assign (stmt)
+       && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+     scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+   else
+     scalar_type = gimple_expr_type (stmt);
    lhs = rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
  
    if (is_gimple_assign (stmt)
Index: trunk/gcc/tree-vect-loop.c
===================================================================
*** trunk.orig/gcc/tree-vect-loop.c	2010-08-24 10:32:38.000000000 +0200
--- trunk/gcc/tree-vect-loop.c	2010-08-30 15:21:58.000000000 +0200
*************** vect_determine_vectorization_factor (loo
*** 298,304 ****
  	      gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)
  			  && !is_pattern_stmt_p (stmt_info));
  
! 	      scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
  	      if (vect_print_dump_info (REPORT_DETAILS))
  		{
  		  fprintf (vect_dump, "get vectype for scalar type:  ");
--- 298,308 ----
  	      gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)
  			  && !is_pattern_stmt_p (stmt_info));
  
! 	      if (is_gimple_assign (stmt)
! 		  && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
! 		scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
! 	      else
! 		scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
  	      if (vect_print_dump_info (REPORT_DETAILS))
  		{
  		  fprintf (vect_dump, "get vectype for scalar type:  ");
Index: trunk/gcc/tree-vect-stmts.c
===================================================================
*** trunk.orig/gcc/tree-vect-stmts.c	2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-vect-stmts.c	2010-08-30 15:20:42.000000000 +0200
*************** vectorizable_load (gimple stmt, gimple_s
*** 3945,3982 ****
     condition operands are supportable using vec_is_simple_use.  */
  
  static bool
! vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
  {
-   tree lhs, rhs;
    tree def;
    enum vect_def_type dt;
  
!   if (!COMPARISON_CLASS_P (cond))
!     return false;
! 
!   lhs = TREE_OPERAND (cond, 0);
!   rhs = TREE_OPERAND (cond, 1);
  
!   if (TREE_CODE (lhs) == SSA_NAME)
      {
!       gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
!       if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
                                 &dt))
  	return false;
      }
!   else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
! 	   && TREE_CODE (lhs) != FIXED_CST)
      return false;
  
!   if (TREE_CODE (rhs) == SSA_NAME)
      {
!       gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
!       if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
                                 &dt))
  	return false;
      }
!   else if (TREE_CODE (rhs) != INTEGER_CST  && TREE_CODE (rhs) != REAL_CST
! 	   && TREE_CODE (rhs) != FIXED_CST)
      return false;
  
    return true;
--- 3945,3978 ----
     condition operands are supportable using vec_is_simple_use.  */
  
  static bool
! vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo,
! 		     enum tree_code *code, tree *lhs, tree *rhs)
  {
    tree def;
    enum vect_def_type dt;
  
!   gimple_pred_extract_comparison (cond, code, lhs, rhs);
  
!   if (TREE_CODE (*lhs) == SSA_NAME)
      {
!       gimple lhs_def_stmt = SSA_NAME_DEF_STMT (*lhs);
!       if (!vect_is_simple_use (*lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
                                 &dt))
  	return false;
      }
!   else if (TREE_CODE (*lhs) != INTEGER_CST && TREE_CODE (*lhs) != REAL_CST
! 	   && TREE_CODE (*lhs) != FIXED_CST)
      return false;
  
!   if (TREE_CODE (*rhs) == SSA_NAME)
      {
!       gimple rhs_def_stmt = SSA_NAME_DEF_STMT (*rhs);
!       if (!vect_is_simple_use (*rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
                                 &dt))
  	return false;
      }
!   else if (TREE_CODE (*rhs) != INTEGER_CST  && TREE_CODE (*rhs) != REAL_CST
! 	   && TREE_CODE (*rhs) != FIXED_CST)
      return false;
  
    return true;
*************** vectorizable_condition (gimple stmt, gim
*** 4015,4020 ****
--- 4011,4017 ----
    int nunits = TYPE_VECTOR_SUBPARTS (vectype);
    int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
    enum tree_code code;
+   tree lhs, rhs;
  
    /* FORNOW: unsupported in basic block SLP.  */
    gcc_assert (loop_vinfo);
*************** vectorizable_condition (gimple stmt, gim
*** 4058,4070 ****
    then_clause = TREE_OPERAND (op, 1);
    else_clause = TREE_OPERAND (op, 2);
  
!   if (!vect_is_simple_cond (cond_expr, loop_vinfo))
      return false;
  
    /* We do not handle two different vector types for the condition
       and the values.  */
!   if (!types_compatible_p (TREE_TYPE (TREE_OPERAND (cond_expr, 0)),
! 			   TREE_TYPE (vectype)))
      return false;
  
    if (TREE_CODE (then_clause) == SSA_NAME)
--- 4055,4066 ----
    then_clause = TREE_OPERAND (op, 1);
    else_clause = TREE_OPERAND (op, 2);
  
!   if (!vect_is_simple_cond (cond_expr, loop_vinfo, &code, &lhs, &rhs))
      return false;
  
    /* We do not handle two different vector types for the condition
       and the values.  */
!   if (!types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (vectype)))
      return false;
  
    if (TREE_CODE (then_clause) == SSA_NAME)
*************** vectorizable_condition (gimple stmt, gim
*** 4108,4116 ****
  
    /* Handle cond expr.  */
    vec_cond_lhs =
!     vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL);
    vec_cond_rhs =
!     vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL);
    if (reduc_index == 1)
      vec_then_clause = reduc_def;
    else
--- 4104,4112 ----
  
    /* Handle cond expr.  */
    vec_cond_lhs =
!     vect_get_vec_def_for_operand (lhs, stmt, NULL);
    vec_cond_rhs =
!     vect_get_vec_def_for_operand (rhs, stmt, NULL);
    if (reduc_index == 1)
      vec_then_clause = reduc_def;
    else
*************** vectorizable_condition (gimple stmt, gim
*** 4121,4127 ****
      vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
  
    /* Arguments are ready. Create the new vector stmt.  */
!   vec_compare = build2 (TREE_CODE (cond_expr), vectype,
  			vec_cond_lhs, vec_cond_rhs);
    vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
  			  vec_compare, vec_then_clause, vec_else_clause);
--- 4117,4123 ----
      vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
  
    /* Arguments are ready. Create the new vector stmt.  */
!   vec_compare = build2 (code, vectype,
  			vec_cond_lhs, vec_cond_rhs);
    vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
  			  vec_compare, vec_then_clause, vec_else_clause);


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