fold-const.c (build_range_check): Optimize (c>=1) && (c<=127) into the equivalent...
authorRoger Sayle <roger@eyesopen.com>
Fri, 10 May 2002 22:24:13 +0000 (22:24 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 10 May 2002 22:24:13 +0000 (22:24 +0000)
* fold-const.c (build_range_check): Optimize (c>=1) && (c<=127)
into the equivalent (signed char)c > 0.

* gcc.c-torture/execute/20020510-1.c: New test case.

From-SVN: r53373

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20020510-1.c [new file with mode: 0644]

index bc20fd32eba547040725605654effdc5561b0d0c..192b2be851dede7fc341562ef8b6c71c8b6e46a5 100644 (file)
@@ -1,3 +1,8 @@
+2002-05-10  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (build_range_check): Optimize (c>=1) && (c<=127)
+       into the equivalent (signed char)c > 0.
+
 2002-05-10  Janis Johnson  <janis187@us.ibm.com>
 
        * loop.c: (PREFETCH_EXTREME_DIFFERENCE, PREFETCH_BEFORE_LOOP): New.
index 6b4982aad751b52437bf5f44bfe12de0893a175d..2a9f6c6ee7cc462fa971f3deb272d223b63cb1ab 100644 (file)
@@ -3091,41 +3091,73 @@ build_range_check (type, exp, in_p, low, high)
      tree low, high;
 {
   tree etype = TREE_TYPE (exp);
-  tree utype, value;
+  tree value;
 
   if (! in_p
       && (0 != (value = build_range_check (type, exp, 1, low, high))))
     return invert_truthvalue (value);
 
-  else if (low == 0 && high == 0)
+  if (low == 0 && high == 0)
     return convert (type, integer_one_node);
 
-  else if (low == 0)
+  if (low == 0)
     return fold (build (LE_EXPR, type, exp, high));
 
-  else if (high == 0)
+  if (high == 0)
     return fold (build (GE_EXPR, type, exp, low));
 
-  else if (operand_equal_p (low, high, 0))
+  if (operand_equal_p (low, high, 0))
     return fold (build (EQ_EXPR, type, exp, low));
 
-  else if (TREE_UNSIGNED (etype) && integer_zerop (low))
-    return build_range_check (type, exp, 1, 0, high);
+  if (integer_zerop (low))
+    {
+      if (! TREE_UNSIGNED (etype))
+        {
+          etype = (*lang_hooks.types.unsigned_type) (etype);
+          high = convert (etype, high);
+          exp = convert (etype, exp);
+        }
+      return build_range_check (type, exp, 1, 0, high);
+    }
 
-  else if (integer_zerop (low))
+  /* Optimize (c>=1) && (c<=127) into (signed char)c > 0.  */
+  if (integer_onep (low) && TREE_CODE (high) == INTEGER_CST)
     {
-      utype = (*lang_hooks.types.unsigned_type) (etype);
-      return build_range_check (type, convert (utype, exp), 1, 0,
-                               convert (utype, high));
+      unsigned HOST_WIDE_INT lo;
+      HOST_WIDE_INT hi;
+      int prec;
+
+      prec = TYPE_PRECISION (etype);
+      if (prec <= HOST_BITS_PER_WIDE_INT)
+        {
+          hi = 0;
+          lo = ((unsigned HOST_WIDE_INT) 1 << (prec - 1)) - 1;
+        }
+      else
+        {
+          hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1;
+          lo = (unsigned HOST_WIDE_INT) -1;
+        }
+
+      if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo)
+        {
+          if (TREE_UNSIGNED (etype))
+            {
+              etype = (*lang_hooks.types.signed_type) (etype);
+              exp = convert (etype, exp);
+            }
+          return fold (build (GT_EXPR, type, exp,
+                              convert (etype, integer_zero_node)));
+        }
     }
 
-  else if (0 != (value = const_binop (MINUS_EXPR, high, low, 0))
-          && ! TREE_OVERFLOW (value))
+  if (0 != (value = const_binop (MINUS_EXPR, high, low, 0))
+      && ! TREE_OVERFLOW (value))
     return build_range_check (type,
                              fold (build (MINUS_EXPR, etype, exp, low)),
                              1, convert (etype, integer_zero_node), value);
-  else
-    return 0;
+
+  return 0;
 }
 \f
 /* Given two ranges, see if we can merge them into one.  Return 1 if we
index c66c70f16b253214db32870c8a384e5694a0d39e..d0f2142e0876581ad397903ef59ba8d692e6fb7e 100644 (file)
@@ -1,3 +1,7 @@
+2002-05-10  Roger Sayle  <roger@eyesopen.com>
+
+       * gcc.c-torture/execute/20020510-1.c: New test case.
+
 2002-05-10  David S. Miller  <davem@redhat.com>
 
        * gcc.c-torture/execute/conversion.c: Test long double too.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020510-1.c b/gcc/testsuite/gcc.c-torture/execute/20020510-1.c
new file mode 100644 (file)
index 0000000..90fb277
--- /dev/null
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002  Free Software Foundation.
+
+   Test that optimizing ((c>=1) && (c<=127)) into (signed char)c < 0
+   doesn't cause any problems for the compiler and behaves correctly.
+
+   Written by Roger Sayle, 8th May 2002.  */
+
+#include <limits.h>
+
+extern void abort (void);
+
+void
+testc (unsigned char c, int ok)
+{
+  if ((c>=1) && (c<=SCHAR_MAX))
+    {
+      if (!ok) abort ();
+    }
+  else
+    if (ok) abort ();
+}
+
+void
+tests (unsigned short s, int ok)
+{
+  if ((s>=1) && (s<=SHRT_MAX))
+    {
+      if (!ok) abort ();
+    }
+  else
+    if (ok) abort ();
+}
+
+void
+testi (unsigned int i, int ok)
+{
+  if ((i>=1) && (i<=INT_MAX))
+    {
+      if (!ok) abort ();
+    }
+  else
+    if (ok) abort ();
+}
+
+void
+testl (unsigned long l, int ok)
+{
+  if ((l>=1) && (l<=LONG_MAX))
+    {
+      if (!ok) abort ();
+    }
+  else
+    if (ok) abort ();
+}
+
+int
+main ()
+{
+  testc (0, 0);
+  testc (1, 1);
+  testc (SCHAR_MAX, 1);
+  testc (SCHAR_MAX+1, 0);
+  testc (UCHAR_MAX, 0);
+
+  tests (0, 0);
+  tests (1, 1);
+  tests (SHRT_MAX, 1);
+  tests (SHRT_MAX+1, 0);
+  tests (USHRT_MAX, 0);
+
+  testi (0, 0);
+  testi (1, 1);
+  testi (INT_MAX, 1);
+  testi (INT_MAX+1U, 0);
+  testi (UINT_MAX, 0);
+
+  testl (0, 0);
+  testl (1, 1);
+  testl (LONG_MAX, 1);
+  testl (LONG_MAX+1UL, 0);
+  testl (ULONG_MAX, 0);
+
+  return 0;
+}
+