Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	(revision 184428)
+++ gcc/gimplify.c	(working copy)
@@ -7061,15 +7061,23 @@ gimplify_expr (tree *expr_p, gimple_seq
 	      ret = GS_OK;
 	      break;
 	    }
-	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
-			       is_gimple_mem_ref_addr, fb_rvalue);
-	  if (ret == GS_ERROR)
-	    break;
+	  /* Avoid re-gimplifying the address operand if it is already
+	     in suitable form.  Re-gimplifying would mark the address
+	     operand addressable.  Always gimplify when not in SSA form
+	     as we still may have to gimplify decls with value-exprs.  */
+	  if (!gimplify_ctxp || !gimplify_ctxp->into_ssa
+	      || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
+	    {
+	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+				   is_gimple_mem_ref_addr, fb_rvalue);
+	      if (ret == GS_ERROR)
+		break;
+	    }
 	  recalculate_side_effects (*expr_p);
 	  ret = GS_ALL_DONE;
 	  break;
 
-	  /* Constants need not be gimplified.  */
+	/* Constants need not be gimplified.  */
 	case INTEGER_CST:
 	case REAL_CST:
 	case FIXED_CST:
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c	(revision 0)
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lim1-details" } */
+
+int *l, *r;
+int test_func(void)
+{
+  int i;
+  int direction;
+  static int pos;
+
+  pos = 0;
+  direction = 1;
+
+  for ( i = 0; i <= 400; i++ )
+    {
+      if ( direction == 0 )
+	pos = l[pos];
+      else
+	pos = r[pos];
+
+      if ( pos == -1 )
+	{
+	  pos = 0;
+	  direction = !direction;
+	}
+    }
+  return i;
+}
+
+/* { dg-final { scan-tree-dump "Executing store motion of pos" "lim1" } } */
+/* { dg-final { cleanup-tree-dump "lim1" } } */
