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);