diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109031-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109031-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..84e1a08be295da4afc751ac5f62ad040796586d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109031-1.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+unsigned char uc;
+unsigned short us;
+
+void testuc() {
+  unsigned int g = 0;
+  unsigned int *p1 = &g;
+  unsigned char *p2 = &uc;
+
+  do {
+    (*p1)++;
+    (*p2)--;
+  } while (uc);
+
+  if (g != 256)
+    __builtin_abort();
+}
+
+void testus() {
+  unsigned int g = 0;
+  unsigned int *p1 = &g;
+  unsigned short *p2 = &us;
+
+  do {
+    (*p1)++;
+    (*p2)--;
+  } while (us);
+
+  if (g != 65536)
+    __builtin_abort();
+}
+
+int main() {
+  testuc();
+  testus();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109031-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109031-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..6f28b3b5ed8abeb26d77c6c709537c3f5c56090b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109031-2.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fwrapv" } */
+signed char sc;
+signed short ss;
+
+void testsc() {
+  unsigned int g = 0;
+  unsigned int *p1 = &g;
+  signed char *p2 = ≻
+
+  do {
+    (*p1)++;
+    (*p2)--;
+  } while (sc);
+
+  if (g != 256)
+    __builtin_abort();
+}
+
+void testss() {
+  unsigned int g = 0;
+  unsigned int *p1 = &g;
+  signed short *p2 = &ss;
+
+  do {
+    (*p1)++;
+    (*p2)--;
+  } while (ss);
+
+  if (g != 65536)
+    __builtin_abort();
+}
+
+int main() {
+  testsc();
+  testss();
+  return 0;
+}
+
diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc
index f93d8dc406c1bc0ac76961018117f33c6e39f6d9..2f67581591a568ef59e9b94ace9966e0434fd3ef 100644
--- a/gcc/tree-chrec.cc
+++ b/gcc/tree-chrec.cc
@@ -623,7 +623,9 @@ chrec_apply (unsigned var,
 	  else if (operand_equal_p (CHREC_LEFT (chrec), chrecr)
 		   && TREE_CODE (x) == PLUS_EXPR
 		   && integer_all_onesp (TREE_OPERAND (x, 1))
-		   && !POINTER_TYPE_P (type))
+		   && !POINTER_TYPE_P (type)
+		   && TYPE_PRECISION (TREE_TYPE (x))
+		      >= TYPE_PRECISION (type))
 	    {
 	      /* We know the number of iterations can't be negative.
 		 So {a, +, a} (x-1) -> "a*x".  */