diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4922fa73940c6d54fe5c3c31f4d0fa856f3b93f9..d0ac706f01685bdaa235e13d5fb763040943c5d3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2010-09-04  Richard Guenther  <rguenther@suse.de>
+
+	PR bootstrap/45519
+	* tree-flow.h (force_gimple_operand_1): Declare.
+	(force_gimple_operand_gsi_1): Likewise.
+	* gimplify.c (force_gimple_operand_1): New worker taking a
+	gimple predicate for ...
+	(force_gimple_operand): ... which now wraps it.
+	(force_gimple_operand_gsi_1, force_gimple_operand_gsi): Likewise.
+	* tree-ssa-loop-ivopts.c (find_interesting_uses_address): Revert
+	last change.
+	* tree-ssa-address.c (gimplify_mem_ref_parts): Use
+	force_gimple_operand_gsi_1 with is_gimple_mem_ref_addr.
+	(create_mem_ref): Likewise.
+
 2010-09-04  Uros Bizjak  <ubizjak@gmail.com>
 
 	* config/i386/predicates.md (sse_reg_operand): New predicate.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 1723f42d8a2e76b0d647a94fe5ebdc702f1873fa..be9e22d650c596986ccb5c86bd24199d5c219cc5 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8008,17 +8008,16 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
 }
 
 
-/* Expands EXPR to list of gimple statements STMTS.  If SIMPLE is true,
-   force the result to be either ssa_name or an invariant, otherwise
-   just force it to be a rhs expression.  If VAR is not NULL, make the
+/* Expands EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
+   the predicate that will hold for the result.  If VAR is not NULL, make the
    base variable of the final destination be VAR if suitable.  */
 
 tree
-force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
+force_gimple_operand_1 (tree expr, gimple_seq *stmts,
+			gimple_predicate gimple_test_f, tree var)
 {
   tree t;
   enum gimplify_status ret;
-  gimple_predicate gimple_test_f;
   struct gimplify_ctx gctx;
 
   *stmts = NULL;
@@ -8026,8 +8025,6 @@ force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
   if (is_gimple_val (expr))
     return expr;
 
-  gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
-
   push_gimplify_context (&gctx);
   gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
   gimplify_ctxp->allow_rhs_cond_expr = true;
@@ -8056,20 +8053,34 @@ force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
   return expr;
 }
 
-/* Invokes force_gimple_operand for EXPR with parameters SIMPLE_P and VAR.  If
-   some statements are produced, emits them at GSI.  If BEFORE is true.
-   the statements are appended before GSI, otherwise they are appended after
-   it.  M specifies the way GSI moves after insertion (GSI_SAME_STMT or
-   GSI_CONTINUE_LINKING are the usual values).  */
+/* Expands EXPR to list of gimple statements STMTS.  If SIMPLE is true,
+   force the result to be either ssa_name or an invariant, otherwise
+   just force it to be a rhs expression.  If VAR is not NULL, make the
+   base variable of the final destination be VAR if suitable.  */
 
 tree
-force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
-			  bool simple_p, tree var, bool before,
-			  enum gsi_iterator_update m)
+force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
+{
+  return force_gimple_operand_1 (expr, stmts,
+				 simple ? is_gimple_val : is_gimple_reg_rhs,
+				 var);
+}
+
+/* Invokes force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
+   and VAR.  If some statements are produced, emits them at GSI.
+   If BEFORE is true.  the statements are appended before GSI, otherwise
+   they are appended after it.  M specifies the way GSI moves after
+   insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
+
+tree
+force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
+			    gimple_predicate gimple_test_f,
+			    tree var, bool before,
+			    enum gsi_iterator_update m)
 {
   gimple_seq stmts;
 
-  expr = force_gimple_operand (expr, &stmts, simple_p, var);
+  expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
 
   if (!gimple_seq_empty_p (stmts))
     {
@@ -8090,4 +8101,24 @@ force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
   return expr;
 }
 
+/* Invokes force_gimple_operand_1 for EXPR with parameter VAR.
+   If SIMPLE is true, force the result to be either ssa_name or an invariant,
+   otherwise just force it to be a rhs expression.  If some statements are
+   produced, emits them at GSI.  If BEFORE is true, the statements are
+   appended before GSI, otherwise they are appended after it.  M specifies
+   the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
+   are the usual values).  */
+
+tree
+force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
+			  bool simple_p, tree var, bool before,
+			  enum gsi_iterator_update m)
+{
+  return force_gimple_operand_gsi_1 (gsi, expr,
+				     simple_p
+				     ? is_gimple_val : is_gimple_reg_rhs,
+				     var, before, m);
+}
+
+
 #include "gt-gimplify.h"
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 6b16234136c04022198b3a2ef353e272b2e6225d..da23516fd2b59b4c96612a01c7cf1c7413ee159e 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -824,7 +824,11 @@ extern bool thread_through_all_blocks (bool);
 extern void register_jump_thread (edge, edge);
 
 /* In gimplify.c  */
+tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
 tree force_gimple_operand (tree, gimple_seq *, bool, tree);
+tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
+				 gimple_predicate, tree,
+				 bool, enum gsi_iterator_update);
 tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
 			       bool, enum gsi_iterator_update);
 tree gimple_fold_indirect_ref (tree);
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index 99b87bbd198150b1cdc66373152dfe6b119ad6db..18c0e556220df7949059bcdec4c45486d15f56e4 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -664,8 +664,8 @@ static void
 gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts)
 {
   if (parts->base)
-    parts->base = force_gimple_operand_gsi (gsi, parts->base,
-					    true, NULL_TREE,
+    parts->base = force_gimple_operand_gsi_1 (gsi, parts->base,
+					    is_gimple_mem_ref_addr, NULL_TREE,
 					    true, GSI_SAME_STMT);
   if (parts->index)
     parts->index = force_gimple_operand_gsi (gsi, parts->index,
@@ -724,11 +724,11 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
 	  if (parts.index)
 	    {
 	      atype = TREE_TYPE (tmp);
-	      parts.base = force_gimple_operand_gsi (gsi,
+	      parts.base = force_gimple_operand_gsi_1 (gsi,
 			fold_build2 (POINTER_PLUS_EXPR, atype,
 				     tmp,
 				     fold_convert (sizetype, parts.base)),
-			true, NULL_TREE, true, GSI_SAME_STMT);
+			is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT);
 	    }
 	  else
 	    {
@@ -751,11 +751,11 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
       if (parts.base)
 	{
 	  atype = TREE_TYPE (parts.base);
-	  parts.base = force_gimple_operand_gsi (gsi,
+	  parts.base = force_gimple_operand_gsi_1 (gsi,
 			fold_build2 (POINTER_PLUS_EXPR, atype,
 				     parts.base,
 			    	     parts.index),
-			true, NULL_TREE, true, GSI_SAME_STMT);
+			is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT);
 	}
       else
 	parts.base = parts.index;
@@ -772,11 +772,11 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
       if (parts.base)
 	{
 	  atype = TREE_TYPE (parts.base);
-	  parts.base = force_gimple_operand_gsi (gsi,
+	  parts.base = force_gimple_operand_gsi_1 (gsi,
 			fold_build2 (POINTER_PLUS_EXPR, atype,
 				     parts.base,
 				     fold_convert (sizetype, parts.offset)),
-			true, NULL_TREE, true, GSI_SAME_STMT);
+			is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT);
 	}
       else
 	parts.base = parts.offset;
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 0a1c44ec964019df64a83079d2eb8151578ecfda..9f79615edfcc346406cf0397cdff73af795a8f3b 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1788,14 +1788,9 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
 	    ref = &TREE_OPERAND (*ref, 0);
 	  if (TREE_CODE (*ref) == MEM_REF)
 	    {
-	      tree tem = TREE_OPERAND (*ref, 0);
-	      STRIP_NOPS (tem);
-	      if (tem != TREE_OPERAND (*ref, 0))
-		tem = fold_build2 (MEM_REF, TREE_TYPE (*ref),
-				   tem, TREE_OPERAND (*ref, 1));
-	      else
-		tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
-				   tem, TREE_OPERAND (*ref, 1));
+	      tree tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
+				      TREE_OPERAND (*ref, 0),
+				      TREE_OPERAND (*ref, 1));
 	      if (tem)
 		*ref = tem;
 	    }