diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f2b2f54e377249d7cb67073d002a2c01cd5852a9..64a4297da81a9810cf3c78305f6e10a4c9024a9f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-11-02  Andrew Pinski  <pinskia@physics.uc.edu>
+
+	PR 22429
+	* fold-const.c (build_range_check): Use unsigned when signed
+	overflow is undefined also.  If etype is subtype, make sure that
+	the subtraction is in the supertype.
+
 2005-11-02  Richard Henderson  <rth@redhat.com>
 
 	PR target/24178
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 16e7eb30b307587b576f2dd8b91f9c9a6ba17f62..6f829adfa7714a6772cc49a549c14ece905a5460 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4014,7 +4014,8 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
     }
 
   value = const_binop (MINUS_EXPR, high, low, 0);
-  if (value != 0 && TREE_OVERFLOW (value) && ! TYPE_UNSIGNED (etype))
+  if (value != 0 && (!flag_wrapv || TREE_OVERFLOW (value))
+      && ! TYPE_UNSIGNED (etype))
     {
       tree utype, minv, maxv;
 
@@ -4025,6 +4026,11 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
 	case INTEGER_TYPE:
 	case ENUMERAL_TYPE:
 	case CHAR_TYPE:
+	  /* There is no requirement that LOW be within the range of ETYPE
+	     if the latter is a subtype.  It must, however, be within the base
+	     type of ETYPE.  So be sure we do the subtraction in that type.  */
+	  if (TREE_TYPE (etype))
+	    etype = TREE_TYPE (etype);
 	  utype = lang_hooks.types.unsigned_type (etype);
 	  maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
 	  maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22429.c b/gcc/testsuite/gcc.c-torture/execute/pr22429.c
new file mode 100644
index 0000000000000000000000000000000000000000..aa55b6e88acc6fdbbf7520aaf39cbc402b9aa219
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr22429.c
@@ -0,0 +1,17 @@
+extern void abort (void);
+
+#define N	(1 << (sizeof(int) * __CHAR_BIT__ - 2))
+
+int f(int n)
+{
+  if (-N <= n && n <= N-1)
+    return 1;
+  return 0;
+}
+
+int main ()
+{
+  if (f (N))
+    abort ();
+  return 0;
+}