aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
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/combine.c
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/combine.c')
-rw-r--r--gcc/combine.c37
1 files changed, 23 insertions, 14 deletions
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;