From 946dc34e1852b73f6db8b608fdd0c1571f42424b Mon Sep 17 00:00:00 2001 From: Zdenek Dvorak Date: Sat, 13 May 2006 21:45:56 +0200 Subject: [PATCH] re PR tree-optimization/27003 (ivcanon bug) 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 | 5 +++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr27003.c | 31 +++++++++++++++++++++++++++++++ gcc/tree.c | 11 +++++++---- 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr27003.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 920b475f1e84..1c19346bed52 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-05-13 Zdenek Dvorak + + PR tree-optimization/27003 + * tree.c (build_int_cst_type): Avoid shift by size of type. + 2006-05-11 Volker Reichelt PR target/27421 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8f09685b5660..654e810fb9ef 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-05-13 Zdenek Dvorak + + PR tree-optimization/27003 + * gcc.dg/pr27003.c: New test. + 2006-05-11 Volker Reichelt PR target/27421 diff --git a/gcc/testsuite/gcc.dg/pr27003.c b/gcc/testsuite/gcc.dg/pr27003.c new file mode 100644 index 000000000000..5e416f4c0cf4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr27003.c @@ -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; +} diff --git a/gcc/tree.c b/gcc/tree.c index 6bcd9a57cfc4..dcc92570be32 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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; } } -- 2.47.2