]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/27003 (ivcanon bug)
authorZdenek Dvorak <dvorakz@suse.cz>
Sat, 13 May 2006 19:45:56 +0000 (21:45 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Sat, 13 May 2006 19:45:56 +0000 (19:45 +0000)
PR tree-optimization/27003
* tree.c (build_int_cst_type): Avoid shift by size of type.

* gcc.dg/pr27003.c: New test.

From-SVN: r113742

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr27003.c [new file with mode: 0644]
gcc/tree.c

index 920b475f1e8464a321a35c2392a43ddb58165c42..1c19346bed52b43e1e6ac86e52b79a68bac7b0ba 100644 (file)
@@ -1,3 +1,8 @@
+2005-05-13  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       PR tree-optimization/27003
+       * tree.c (build_int_cst_type): Avoid shift by size of type.
+
 2006-05-11  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR target/27421
index 8f09685b5660b775bdf9898e8b63df232cacebe1..654e810fb9ef3069a72161c9a5f5362135bae9ee 100644 (file)
@@ -1,3 +1,8 @@
+2005-05-13  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       PR tree-optimization/27003
+       * gcc.dg/pr27003.c: New test.
+
 2006-05-11  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR target/27421
diff --git a/gcc/testsuite/gcc.dg/pr27003.c b/gcc/testsuite/gcc.dg/pr27003.c
new file mode 100644 (file)
index 0000000..5e416f4
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+unsigned int
+foo (unsigned int x)
+{
+  unsigned int r = x;
+  while (--x)
+    r *= x;
+  return r;
+}
+
+unsigned long long
+bar (unsigned long long x)
+{
+  unsigned long long r = x;
+  while (--x)
+    r *= x;
+  return r;
+}
+
+extern void abort (void);
+
+int
+main (void)
+{
+  if (foo (5) != 120 || bar (5) != 120)
+    abort ();
+  return 0;
+}
index 6bcd9a57cfc45290293e19d37fb0cecf96579a3b..dcc92570be32065e0804d2a4273f87bc5dbeae03 100644 (file)
@@ -514,7 +514,7 @@ tree
 build_int_cst_type (tree type, HOST_WIDE_INT low)
 {
   unsigned HOST_WIDE_INT val = (unsigned HOST_WIDE_INT) low;
-  unsigned HOST_WIDE_INT hi;
+  unsigned HOST_WIDE_INT hi, mask;
   unsigned bits;
   bool signed_p;
   bool negative;
@@ -534,10 +534,12 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
       negative = ((val >> (bits - 1)) & 1) != 0;
 
       /* Mask out the bits outside of the precision of the constant.  */
+      mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
+
       if (signed_p && negative)
-       val = val | ((~(unsigned HOST_WIDE_INT) 0) << bits);
+       val |= ~mask;
       else
-       val = val & ~((~(unsigned HOST_WIDE_INT) 0) << bits);
+       val &= mask;
     }
 
   /* Determine the high bits.  */
@@ -552,7 +554,8 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
       else
        {
          bits -= HOST_BITS_PER_WIDE_INT;
-         hi = hi & ~((~(unsigned HOST_WIDE_INT) 0) << bits);
+         mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
+         hi &= mask;
        }
     }