re PR c/7284 (incorrectly simplifies leftshift followed by signed power-of-2 division)
authorJoseph Myers <jsm@polyomino.org.uk>
Thu, 22 Jul 2004 20:33:34 +0000 (21:33 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Thu, 22 Jul 2004 20:33:34 +0000 (21:33 +0100)
PR c/7284
* fold-const.c (extract_muldiv_1): Do not treat signed left shift
as multiplication.

testsuite:
* gcc.c-torture/execute/pr7284-1.c: New test.

From-SVN: r85059

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

index 5041b3f09f4e094213cf1738fe72e364fcc19b4f..43770e9d8221a74265ee7754d8b7a7934b92c893 100644 (file)
@@ -1,3 +1,9 @@
+2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+       PR c/7284
+       * fold-const.c (extract_muldiv_1): Do not treat signed left shift
+       as multiplication.
+
 2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * doc/implement-c.texi: New file.
index e976117d133a1f4a14030e0d4767c8a1f7a25416..a0d63237a22a0b4b58dbbe9846430ff339054a0d 100644 (file)
@@ -5139,8 +5139,12 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
     case LSHIFT_EXPR:  case RSHIFT_EXPR:
       /* If the second operand is constant, this is a multiplication
         or floor division, by a power of two, so we can treat it that
-        way unless the multiplier or divisor overflows.  */
+        way unless the multiplier or divisor overflows.  Signed
+        left-shift overflow is implementation-defined rather than
+        undefined in C90, so do not convert signed left shift into
+        multiplication.  */
       if (TREE_CODE (op1) == INTEGER_CST
+         && (tcode == RSHIFT_EXPR || TYPE_UNSIGNED (TREE_TYPE (op0)))
          /* const_binop may not detect overflow correctly,
             so check for it explicitly here.  */
          && TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
index 9003d1387842e21696d0b321043dca73172ea158..c28a819d563f562ba9502ec609ce5ddea8dfa71d 100644 (file)
@@ -1,3 +1,8 @@
+2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+       PR c/7284
+       * gcc.c-torture/execute/pr7284-1.c: New test.
+
 2004-07-22  Brian Booth  <bbooth@redhat.com>
 
        * gcc.dg/tree-ssa/20040721-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr7284-1.c b/gcc/testsuite/gcc.c-torture/execute/pr7284-1.c
new file mode 100644 (file)
index 0000000..de0057c
--- /dev/null
@@ -0,0 +1,24 @@
+/* Signed left-shift is implementation-defined in C89 (and see
+   DR#081), not undefined.  Bug 7284 from Al Grant (AlGrant at
+   myrealbox.com).  */
+
+/* { dg-options "-std=c89" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+f (int n)
+{
+  return (n << 24) / (1 << 23);
+}
+
+volatile int x = 128;
+
+int
+main (void)
+{
+  if (f(x) != -256)
+    abort ();
+  exit (0);
+}