OSDN Git Service

gcc/ChangeLog:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Feb 2005 09:09:42 +0000 (09:09 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Feb 2005 09:09:42 +0000 (09:09 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94655 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20050203-1.c [new file with mode: 0644]

index b9a6395..f011c4e 100644 (file)
@@ -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
index 288c269..44a954a 100644 (file)
@@ -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) \
index 6badd28..ae773b9 100644 (file)
@@ -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;
index e632b52..3820b90 100644 (file)
@@ -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 (file)
index 0000000..0b38277
--- /dev/null
@@ -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 ();
+    }
+}