Combine tries to optimise comparisons involving:
(zero_extract (const_int X)
(const_int 1)
(var Y))
and so on BITS_BIG_ENDIAN targets it tries gamely to work out what mode
X actually has. At the moment it tries reading the mode from operand 1
of extzv, but that doesn't feel right, since we never use extzv itself
with this combination of operands. (We only use it with combinations
in which the first zero_extract operand is variable and the third is
constant.) And extzv isn't necessarily a good indicator of what a
matched zero_extract does, since targets often have matchable zero_extract
insns for more than one mode. E.g. powerpc (a BITS_BIG_ENDIAN target)
has both SImode and DImode patterns.
In practice, all BITS_BIG_ENDIAN targets that have an extzv pattern
either have an explicit word_mode operand (e.g. m68k) or leave it void,
which make_for_extraction treats as word_mode. Since word_mode is also
the default assumption when no extzv pattern is defined, I think it would
be more robust to assume/require word_mode across the board (as much as
anything can be called robust in this sort of situation).
Tested as described in the covering note. OK to install?
Richard
gcc/
* combine.c (simplify_comparison): If BITS_BIG_ENDIAN, always assume
that zero_extracts of const_ints are doing word-sized extractions.
Index: gcc/combine.c
===================================================================
--- gcc/combine.c 2012-10-29 14:14:36.371315725 +0000
+++ gcc/combine.c 2012-10-29 14:29:26.800313546 +0000
@@ -11154,17 +11154,7 @@ simplify_comparison (enum rtx_code code,
&& (i = exact_log2 (UINTVAL (XEXP (op0, 0)))) >= 0)
{
if (BITS_BIG_ENDIAN)
- {
- enum machine_mode new_mode
- = mode_for_extraction (EP_extzv, 1);
- if (new_mode == MAX_MACHINE_MODE)
- i = BITS_PER_WORD - 1 - i;
- else
- {
- mode = new_mode;
- i = (GET_MODE_PRECISION (mode) - 1 - i);
- }
- }
+ i = BITS_PER_WORD - 1 - i;
op0 = XEXP (op0, 2);
op1 = GEN_INT (i);