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

Reply via email to