aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-11-03 23:36:39 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2009-11-03 23:36:39 +0100
commit24d179b4c7717ceeceef16166064bd4a3933cb11 (patch)
tree219b8371e4eb10703f1ef240e27ca85c4e4861a9
parent0b94d8b285da86f4e68c396a285a2846df3bdff7 (diff)
downloadgcc-24d179b4c7717ceeceef16166064bd4a3933cb11.zip
gcc-24d179b4c7717ceeceef16166064bd4a3933cb11.tar.gz
gcc-24d179b4c7717ceeceef16166064bd4a3933cb11.tar.bz2
re PR rtl-optimization/41917 (Strange athrithmetic result with -O3)
PR rtl-optimization/41917 * rtlanal.c (num_sign_bit_copies1) <case UMOD>: If sign bit of second operand isn't known to be 0, return 1. * gcc.c-torture/execute/pr41917.c: New test. From-SVN: r153874
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/rtlanal.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr41917.c21
4 files changed, 42 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 90dcf62..0da48a4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/41917
+ * rtlanal.c (num_sign_bit_copies1) <case UMOD>: If sign bit of second
+ operand isn't known to be 0, return 1.
+
2009-11-03 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.md: Fix typos.
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d14bbe5..120d37a 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4517,8 +4517,16 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
known_x, known_mode, known_ret);
case UMOD:
- /* The result must be <= the second operand. */
- return cached_num_sign_bit_copies (XEXP (x, 1), mode,
+ /* The result must be <= the second operand. If the second operand
+ has (or just might have) the high bit set, we know nothing about
+ the number of sign bit copies. */
+ if (bitwidth > HOST_BITS_PER_WIDE_INT)
+ return 1;
+ else if ((nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
+ return 1;
+ else
+ return cached_num_sign_bit_copies (XEXP (x, 1), mode,
known_x, known_mode, known_ret);
case DIV:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f0d09d0..220a4c3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/41917
+ * gcc.c-torture/execute/pr41917.c: New test.
+
2009-11-03 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/pr41900.c: Make test compile only. Scan assembler
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr41917.c b/gcc/testsuite/gcc.c-torture/execute/pr41917.c
new file mode 100644
index 0000000..4a9ada9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr41917.c
@@ -0,0 +1,21 @@
+/* PR rtl-optimization/41917 */
+
+extern void abort (void);
+unsigned int a = 1;
+
+int
+main (void)
+{
+ unsigned int b, c, d;
+
+ if (sizeof (int) != 4 || (int) 0xc7d24b5e > 0)
+ return 0;
+
+ c = 0xc7d24b5e;
+ d = a | -2;
+ b = (d == 0) ? c : (c % d);
+ if (b != c)
+ abort ();
+
+ return 0;
+}