--- gcc/tree-ssa-loop-niter.c.jj	2012-11-21 16:00:09.000000000 +0100
+++ gcc/tree-ssa-loop-niter.c	2012-12-11 10:56:49.890396498 +0100
@@ -3011,7 +3011,12 @@ discover_iteration_bound_by_body_walk (s
       /* Exit terminates loop at given iteration, while non-exits produce undefined
 	 effect on the next iteration.  */
       if (!elt->is_exit)
-	bound += double_int_one;
+	{
+	  bound += double_int_one;
+	  /* If an overflow occurred, ignore the result.  */
+	  if (bound.is_zero ())
+	    continue;
+	}
 
       if (!loop->any_upper_bound
 	  || bound.ult (loop->nb_iterations_upper_bound))
@@ -3037,7 +3042,12 @@ discover_iteration_bound_by_body_walk (s
     {
       double_int bound = elt->bound;
       if (!elt->is_exit)
-	bound += double_int_one;
+	{
+	  bound += double_int_one;
+	  /* If an overflow occurred, ignore the result.  */
+	  if (bound.is_zero ())
+	    continue;
+	}
 
       if (!loop->any_upper_bound
 	  || bound.ult (loop->nb_iterations_upper_bound))
--- gcc/testsuite/gcc.dg/torture/pr55633.c.jj	2012-12-11 11:12:19.567069030 +0100
+++ gcc/testsuite/gcc.dg/torture/pr55633.c	2012-12-11 11:12:04.000000000 +0100
@@ -0,0 +1,39 @@
+/* PR fortran/55633 */
+/* { dg-do run { target int128 } } */
+
+extern void abort (void);
+
+__attribute__((noinline, noclone)) void
+bar (__int128_t *x)
+{
+  int c = sizeof (__int128_t) * __CHAR_BIT__;
+  if (c > 127)
+    c = 127;
+  if (*x != c)
+    abort ();
+}
+
+__attribute__((noinline)) void
+foo (void)
+{
+  __int128_t m, ma;
+  ma = 0;
+  m = 0;
+  m = ~m;
+  do
+    {
+      if (m == 0 || ma > 126)
+	break;
+      ma = ma + 1;
+      m = ((__uint128_t) m) >> 1;
+    }
+  while (1);
+  bar (&ma);
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
