aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2005-02-03 09:09:42 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2005-02-03 09:09:42 +0000
commitaa2d0bc31c2dac0ecde72d92d7d419be5a8f21b3 (patch)
tree2670e900e343f8a26a16c91b8c9efacb96709618 /gcc
parentf1a3e333f0f5c214ed5801ed3546d0f8caf9f5fc (diff)
downloadgcc-aa2d0bc31c2dac0ecde72d92d7d419be5a8f21b3.zip
gcc-aa2d0bc31c2dac0ecde72d92d7d419be5a8f21b3.tar.gz
gcc-aa2d0bc31c2dac0ecde72d92d7d419be5a8f21b3.tar.bz2
combine.c (simplify_comparison, [...]): Do not drop the extend if we'd have to add a paradoxical subreg later.
gcc/ChangeLog: * combine.c (simplify_comparison, case SIGN_EXTEND, ZERO_EXTEND): Do not drop the extend if we'd have to add a paradoxical subreg later. Include optabs.h and insn-codes.h. * Makefile.in (combine.o): Depend on $(OPTABS_H). gcc/testsuite/ChangeLog: * gcc.c-torture/execute/20050203-1.c: New. From-SVN: r94655
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/combine.c37
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20050203-1.c29
5 files changed, 64 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b9a6395..f011c4e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-02-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * combine.c (simplify_comparison, case SIGN_EXTEND, ZERO_EXTEND):
+ Do not drop the extend if we'd have to add a paradoxical subreg
+ later. Include optabs.h and insn-codes.h.
+ * Makefile.in (combine.o): Depend on $(OPTABS_H).
+
2005-02-02 Roger Sayle <roger@eyesopen.com>
PR middle-end/19405
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 288c269..44a954a 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2046,7 +2046,7 @@ et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.
combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) function.h insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h \
- toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H)
+ toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H)
regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \
$(RECOG_H) reload.h real.h toplev.h function.h output.h $(GGC_H) \
diff --git a/gcc/combine.c b/gcc/combine.c
index 6badd28..ae773b9 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -90,6 +90,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "real.h"
#include "toplev.h"
#include "target.h"
+#include "optabs.h"
+#include "insn-codes.h"
#include "rtlhooks-def.h"
/* Include output.h for dump_file. */
#include "output.h"
@@ -10054,16 +10056,22 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
break;
case SIGN_EXTEND:
- /* Can simplify (compare (zero/sign_extend FOO) CONST)
- to (compare FOO CONST) if CONST fits in FOO's mode and we
- are either testing inequality or have an unsigned comparison
- with ZERO_EXTEND or a signed comparison with SIGN_EXTEND. */
- if (! unsigned_comparison_p
- && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
- <= HOST_BITS_PER_WIDE_INT)
+ /* Can simplify (compare (zero/sign_extend FOO) CONST) to
+ (compare FOO CONST) if CONST fits in FOO's mode and we
+ are either testing inequality or have an unsigned
+ comparison with ZERO_EXTEND or a signed comparison with
+ SIGN_EXTEND. But don't do it if we don't have a compare
+ insn of the given mode, since we'd have to revert it
+ later on, and then we wouldn't know whether to sign- or
+ zero-extend. */
+ mode = GET_MODE (XEXP (op0, 0));
+ if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
+ && ! unsigned_comparison_p
+ && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
&& ((unsigned HOST_WIDE_INT) const_op
- < (((unsigned HOST_WIDE_INT) 1
- << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1)))))
+ < (((unsigned HOST_WIDE_INT) 1
+ << (GET_MODE_BITSIZE (mode) - 1))))
+ && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
op0 = XEXP (op0, 0);
continue;
@@ -10139,11 +10147,12 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
/* ... fall through ... */
case ZERO_EXTEND:
- if ((unsigned_comparison_p || equality_comparison_p)
- && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
- <= HOST_BITS_PER_WIDE_INT)
- && ((unsigned HOST_WIDE_INT) const_op
- < GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))))
+ mode = GET_MODE (XEXP (op0, 0));
+ if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
+ && (unsigned_comparison_p || equality_comparison_p)
+ && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ && ((unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode))
+ && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
op0 = XEXP (op0, 0);
continue;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e632b52..3820b90 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-02-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.c-torture/execute/20050203-1.c: New.
+
2005-02-03 Dorit Naishlos <dorit@il.ibm.com>
* gcc.dg/vect/vect-85.c: Remove xfail.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050203-1.c b/gcc/testsuite/gcc.c-torture/execute/20050203-1.c
new file mode 100644
index 0000000..0b38277
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20050203-1.c
@@ -0,0 +1,29 @@
+/* Reduced testcase extracted from Samba source code. */
+
+#include <stdlib.h>
+
+static void __attribute__((__noinline__))
+ foo (unsigned char *p) {
+ *p = 0x81;
+}
+
+static void __attribute__((__noinline__))
+ bar (int x) {
+ asm ("");
+}
+
+int main() {
+ unsigned char b;
+
+ foo(&b);
+ if (b & 0x80)
+ {
+ bar (b & 0x7f);
+ exit (0);
+ }
+ else
+ {
+ bar (b & 1);
+ abort ();
+ }
+}