aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@codesourcery.com>2006-01-30 19:58:57 +0000
committerCarlos O'Donell <carlos@gcc.gnu.org>2006-01-30 19:58:57 +0000
commitf34312c23cde2f7cb65ad7e7a7e996278d4d1566 (patch)
tree871296de6da055e93d32b7275c42ab6acba8cf73
parentb39f98f94d48be5ff106436b5ddc289e77e9d7e5 (diff)
downloadgcc-f34312c23cde2f7cb65ad7e7a7e996278d4d1566.zip
gcc-f34312c23cde2f7cb65ad7e7a7e996278d4d1566.tar.gz
gcc-f34312c23cde2f7cb65ad7e7a7e996278d4d1566.tar.bz2
optabs.c (prepare_cmp_insn): If unbaised and unsigned then bias the comparison routine return.
gcc/ 2006-01-30 Carlos O'Donell <carlos@codesourcery.com> * optabs.c (prepare_cmp_insn): If unbaised and unsigned then bias the comparison routine return. gcc/testsuite/ 2006-01-30 Carlos O'Donell <carlos@codesourcery.com> * gcc.dg/unsigned-long-compare.c: New test. From-SVN: r110409
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/optabs.c24
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/unsigned-long-compare.c24
4 files changed, 48 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8209ec6..ede7d94 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2006-01-30 Carlos O'Donell <carlos@codesourcery.com>
+
+ * optabs.c (prepare_cmp_insn): If unbaised and unsigned then bias
+ the comparison routine return.
+
2006-01-30 Michael Matz <matz@suse.de>
* global.c (find_reg): Only evict for global regs.
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 48a3406..bdbb88c 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3711,18 +3711,24 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
word_mode, 2, x, mode, y, mode);
+ /* There are two kinds of comparison routines. Biased routines
+ return 0/1/2, and unbiased routines return -1/0/1. Other parts
+ of gcc expect that the comparison operation is equivalent
+ to the modified comparison. For signed comparisons compare the
+ result against 1 in the biased case, and zero in the unbiased
+ case. For unsigned comparisons always compare against 1 after
+ biasing the unbased result by adding 1. This gives us a way to
+ represent LTU. */
*px = result;
*pmode = word_mode;
- if (TARGET_LIB_INT_CMP_BIASED)
- /* Integer comparison returns a result that must be compared
- against 1, so that even if we do an unsigned compare
- afterward, there is still a value that can represent the
- result "less than". */
- *py = const1_rtx;
- else
+ *py = const1_rtx;
+
+ if (!TARGET_LIB_INT_CMP_BIASED)
{
- *py = const0_rtx;
- *punsignedp = 1;
+ if (*punsignedp)
+ *px = plus_constant (result, 1);
+ else
+ *py = const0_rtx;
}
return;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3a6d317..1aea281 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2006-01-30 Carlos O'Donell <carlos@codesourcery.com>
+
+ * gcc.dg/unsigned-long-compare.c: New test.
+
2006-01-30 Steve Ellcey <sje@cup.hp.com>
PR testsuite/25318
diff --git a/gcc/testsuite/gcc.dg/unsigned-long-compare.c b/gcc/testsuite/gcc.dg/unsigned-long-compare.c
new file mode 100644
index 0000000..1c5c69c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/unsigned-long-compare.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc. */
+/* Contributed by Carlos O'Donell on 2006-01-30 */
+
+/* Test a division corner case where the expression simplifies
+ to a comparison, and the optab expansion is wrong. The optab
+ expansion emits a function whose return is unbiased and needs
+ adjustment. */
+/* Origin: Carlos O'Donell <carlos@codesourcery.com> */
+/* { dg-do run { target arm-*-*eabi* } } */
+/* { dg-options "" } */
+#include <stdlib.h>
+
+#define BIG_CONSTANT 0xFFFFFFFF80000000ULL
+
+int main (void)
+{
+ unsigned long long OneULL = 1ULL;
+ unsigned long long result;
+
+ result = OneULL / BIG_CONSTANT;
+ if (result)
+ abort ();
+ exit (0);
+}