LCOV - code coverage report
Current view: top level - gcc - simplify-rtx.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.9 % 4873 4333
Test Date: 2026-06-20 15:32:29 Functions: 100.0 % 81 81
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* RTL simplification functions for GNU compiler.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "target.h"
      26              : #include "rtl.h"
      27              : #include "tree.h"
      28              : #include "predict.h"
      29              : #include "memmodel.h"
      30              : #include "optabs.h"
      31              : #include "emit-rtl.h"
      32              : #include "recog.h"
      33              : #include "diagnostic-core.h"
      34              : #include "varasm.h"
      35              : #include "flags.h"
      36              : #include "selftest.h"
      37              : #include "selftest-rtl.h"
      38              : #include "rtx-vector-builder.h"
      39              : #include "rtlanal.h"
      40              : 
      41              : /* Simplification and canonicalization of RTL.  */
      42              : 
      43              : /* Much code operates on (low, high) pairs; the low value is an
      44              :    unsigned wide int, the high value a signed wide int.  We
      45              :    occasionally need to sign extend from low to high as if low were a
      46              :    signed wide int.  */
      47              : #define HWI_SIGN_EXTEND(low) \
      48              :   ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
      49              : 
      50              : static bool plus_minus_operand_p (const_rtx);
      51              : 
      52              : /* Negate I, which satisfies poly_int_rtx_p.  MODE is the mode of I.  */
      53              : 
      54              : static rtx
      55      8774464 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
      56              : {
      57      8774464 :   return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
      58              : }
      59              : 
      60              : /* Test whether expression, X, is an immediate constant that represents
      61              :    the most significant bit of machine mode MODE.  */
      62              : 
      63              : bool
      64      6182755 : mode_signbit_p (machine_mode mode, const_rtx x)
      65              : {
      66      6182755 :   unsigned HOST_WIDE_INT val;
      67      6182755 :   unsigned int width;
      68      6182755 :   scalar_int_mode int_mode;
      69              : 
      70      6182755 :   if (!is_int_mode (mode, &int_mode))
      71              :     return false;
      72              : 
      73      6182747 :   width = GET_MODE_PRECISION (int_mode);
      74      6182747 :   if (width == 0)
      75              :     return false;
      76              : 
      77      6182747 :   if (width <= HOST_BITS_PER_WIDE_INT
      78      6181200 :       && CONST_INT_P (x))
      79      6029745 :     val = INTVAL (x);
      80              : #if TARGET_SUPPORTS_WIDE_INT
      81       153002 :   else if (CONST_WIDE_INT_P (x))
      82              :     {
      83          483 :       unsigned int i;
      84          483 :       unsigned int elts = CONST_WIDE_INT_NUNITS (x);
      85          483 :       if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
      86              :         return false;
      87          906 :       for (i = 0; i < elts - 1; i++)
      88          483 :         if (CONST_WIDE_INT_ELT (x, i) != 0)
      89              :           return false;
      90          423 :       val = CONST_WIDE_INT_ELT (x, elts - 1);
      91          423 :       width %= HOST_BITS_PER_WIDE_INT;
      92          423 :       if (width == 0)
      93              :         width = HOST_BITS_PER_WIDE_INT;
      94              :     }
      95              : #else
      96              :   else if (width <= HOST_BITS_PER_DOUBLE_INT
      97              :            && CONST_DOUBLE_AS_INT_P (x)
      98              :            && CONST_DOUBLE_LOW (x) == 0)
      99              :     {
     100              :       val = CONST_DOUBLE_HIGH (x);
     101              :       width -= HOST_BITS_PER_WIDE_INT;
     102              :     }
     103              : #endif
     104              :   else
     105              :     /* X is not an integer constant.  */
     106              :     return false;
     107              : 
     108      6029745 :   if (width < HOST_BITS_PER_WIDE_INT)
     109      5466452 :     val &= (HOST_WIDE_INT_1U << width) - 1;
     110      6030168 :   return val == (HOST_WIDE_INT_1U << (width - 1));
     111              : }
     112              : 
     113              : /* Test whether VAL is equal to the most significant bit of mode MODE
     114              :    (after masking with the mode mask of MODE).  Returns false if the
     115              :    precision of MODE is too large to handle.  */
     116              : 
     117              : bool
     118      3592638 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     119              : {
     120      3592638 :   unsigned int width;
     121      3592638 :   scalar_int_mode int_mode;
     122              : 
     123      3592638 :   if (!is_int_mode (mode, &int_mode))
     124              :     return false;
     125              : 
     126      3592602 :   width = GET_MODE_PRECISION (int_mode);
     127      3592602 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     128              :     return false;
     129              : 
     130      3587752 :   val &= GET_MODE_MASK (int_mode);
     131      3587752 :   return val == (HOST_WIDE_INT_1U << (width - 1));
     132              : }
     133              : 
     134              : /* Test whether the most significant bit of mode MODE is set in VAL.
     135              :    Returns false if the precision of MODE is too large to handle.  */
     136              : bool
     137      2620970 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     138              : {
     139      2620970 :   unsigned int width;
     140              : 
     141      2620970 :   scalar_int_mode int_mode;
     142      2620970 :   if (!is_int_mode (mode, &int_mode))
     143              :     return false;
     144              : 
     145      2587825 :   width = GET_MODE_PRECISION (int_mode);
     146      2587825 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     147              :     return false;
     148              : 
     149      2587825 :   val &= HOST_WIDE_INT_1U << (width - 1);
     150      2587825 :   return val != 0;
     151              : }
     152              : 
     153              : /* Test whether the most significant bit of mode MODE is clear in VAL.
     154              :    Returns false if the precision of MODE is too large to handle.  */
     155              : bool
     156      7518023 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     157              : {
     158      7518023 :   unsigned int width;
     159              : 
     160      7518023 :   scalar_int_mode int_mode;
     161      7518023 :   if (!is_int_mode (mode, &int_mode))
     162              :     return false;
     163              : 
     164      7179316 :   width = GET_MODE_PRECISION (int_mode);
     165      7179316 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     166              :     return false;
     167              : 
     168      7068589 :   val &= HOST_WIDE_INT_1U << (width - 1);
     169      7068589 :   return val == 0;
     170              : }
     171              : 
     172              : /* Make a binary operation by properly ordering the operands and
     173              :    seeing if the expression folds.  */
     174              : 
     175              : rtx
     176    117962888 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
     177              :                                        rtx op0, rtx op1)
     178              : {
     179    117962888 :   rtx tem;
     180              : 
     181              :   /* If this simplifies, do it.  */
     182    117962888 :   tem = simplify_binary_operation (code, mode, op0, op1);
     183    117962888 :   if (tem)
     184              :     return tem;
     185              : 
     186              :   /* Put complex operands first and constants second if commutative.  */
     187     74898733 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
     188     74898733 :       && swap_commutative_operands_p (op0, op1))
     189              :     std::swap (op0, op1);
     190              : 
     191     74898733 :   return gen_rtx_fmt_ee (code, mode, op0, op1);
     192              : }
     193              : 
     194              : /* If X is a MEM referencing the constant pool, return the real value.
     195              :    Otherwise return X.  */
     196              : rtx
     197   2704407062 : avoid_constant_pool_reference (rtx x)
     198              : {
     199   2704407062 :   rtx c, tmp, addr;
     200   2704407062 :   machine_mode cmode;
     201   2704407062 :   poly_int64 offset = 0;
     202              : 
     203   2704407062 :   switch (GET_CODE (x))
     204              :     {
     205    256405647 :     case MEM:
     206    256405647 :       break;
     207              : 
     208       917087 :     case FLOAT_EXTEND:
     209              :       /* Handle float extensions of constant pool references.  */
     210       917087 :       tmp = XEXP (x, 0);
     211       917087 :       c = avoid_constant_pool_reference (tmp);
     212       917087 :       if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
     213       123483 :         return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
     214       123483 :                                              GET_MODE (x));
     215              :       return x;
     216              : 
     217              :     default:
     218              :       return x;
     219              :     }
     220              : 
     221    256405647 :   if (GET_MODE (x) == BLKmode)
     222              :     return x;
     223              : 
     224    252350181 :   addr = XEXP (x, 0);
     225              : 
     226              :   /* Call target hook to avoid the effects of -fpic etc....  */
     227    252350181 :   addr = targetm.delegitimize_address (addr);
     228              : 
     229              :   /* Split the address into a base and integer offset.  */
     230    252350181 :   addr = strip_offset (addr, &offset);
     231              : 
     232    252350181 :   if (GET_CODE (addr) == LO_SUM)
     233            0 :     addr = XEXP (addr, 1);
     234              : 
     235              :   /* If this is a constant pool reference, we can turn it into its
     236              :      constant and hope that simplifications happen.  */
     237    252350181 :   if (GET_CODE (addr) == SYMBOL_REF
     238    252350181 :       && CONSTANT_POOL_ADDRESS_P (addr))
     239              :     {
     240      5323723 :       c = get_pool_constant (addr);
     241      5323723 :       cmode = get_pool_mode (addr);
     242              : 
     243              :       /* If we're accessing the constant in a different mode than it was
     244              :          originally stored, attempt to fix that up via subreg simplifications.
     245              :          If that fails we have no choice but to return the original memory.  */
     246      5323723 :       if (known_eq (offset, 0) && cmode == GET_MODE (x))
     247              :         return c;
     248        26050 :       else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
     249              :         {
     250        13025 :           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
     251        13025 :           if (tem && CONSTANT_P (tem))
     252              :             return tem;
     253              :         }
     254              :     }
     255              : 
     256              :   return x;
     257              : }
     258              : 
     259              : /* Simplify a MEM based on its attributes.  This is the default
     260              :    delegitimize_address target hook, and it's recommended that every
     261              :    overrider call it.  */
     262              : 
     263              : rtx
     264   3534622840 : delegitimize_mem_from_attrs (rtx x)
     265              : {
     266              :   /* MEMs without MEM_OFFSETs may have been offset, so we can't just
     267              :      use their base addresses as equivalent.  */
     268   3534622840 :   if (MEM_P (x)
     269     61798783 :       && MEM_EXPR (x)
     270   3572524536 :       && MEM_OFFSET_KNOWN_P (x))
     271              :     {
     272     35059594 :       tree decl = MEM_EXPR (x);
     273     35059594 :       machine_mode mode = GET_MODE (x);
     274     35059594 :       poly_int64 offset = 0;
     275              : 
     276     35059594 :       switch (TREE_CODE (decl))
     277              :         {
     278              :         default:
     279              :           decl = NULL;
     280              :           break;
     281              : 
     282              :         case VAR_DECL:
     283              :           break;
     284              : 
     285      9981973 :         case ARRAY_REF:
     286      9981973 :         case ARRAY_RANGE_REF:
     287      9981973 :         case COMPONENT_REF:
     288      9981973 :         case BIT_FIELD_REF:
     289      9981973 :         case REALPART_EXPR:
     290      9981973 :         case IMAGPART_EXPR:
     291      9981973 :         case VIEW_CONVERT_EXPR:
     292      9981973 :           {
     293      9981973 :             poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
     294      9981973 :             tree toffset;
     295      9981973 :             int unsignedp, reversep, volatilep = 0;
     296              : 
     297      9981973 :             decl
     298      9981973 :               = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
     299              :                                      &unsignedp, &reversep, &volatilep);
     300     19963946 :             if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
     301     10269709 :                 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
     302     19524326 :                 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
     303              :               decl = NULL;
     304              :             else
     305      9254617 :               offset += bytepos + toffset_val;
     306      9981973 :             break;
     307              :           }
     308              :         }
     309              : 
     310       727356 :       if (decl
     311     20634296 :           && mode == GET_MODE (x)
     312     20363716 :           && VAR_P (decl)
     313     13254709 :           && (TREE_STATIC (decl)
     314     12039349 :               || DECL_THREAD_LOCAL_P (decl))
     315      1251393 :           && DECL_RTL_SET_P (decl)
     316     10505510 :           && MEM_P (DECL_RTL (decl)))
     317              :         {
     318      1250893 :           rtx newx;
     319              : 
     320      1250893 :           offset += MEM_OFFSET (x);
     321              : 
     322      1250893 :           newx = DECL_RTL (decl);
     323              : 
     324      1250893 :           if (MEM_P (newx))
     325              :             {
     326      1250893 :               rtx n = XEXP (newx, 0), o = XEXP (x, 0);
     327      1250893 :               poly_int64 n_offset, o_offset;
     328              : 
     329              :               /* Avoid creating a new MEM needlessly if we already had
     330              :                  the same address.  We do if there's no OFFSET and the
     331              :                  old address X is identical to NEWX, or if X is of the
     332              :                  form (plus NEWX OFFSET), or the NEWX is of the form
     333              :                  (plus Y (const_int Z)) and X is that with the offset
     334              :                  added: (plus Y (const_int Z+OFFSET)).  */
     335      1250893 :               n = strip_offset (n, &n_offset);
     336      1250893 :               o = strip_offset (o, &o_offset);
     337      2474105 :               if (!(known_eq (o_offset, n_offset + offset)
     338      1223212 :                     && rtx_equal_p (o, n)))
     339       211528 :                 x = adjust_address_nv (newx, mode, offset);
     340              :             }
     341            0 :           else if (GET_MODE (x) == GET_MODE (newx)
     342            0 :                    && known_eq (offset, 0))
     343              :             x = newx;
     344              :         }
     345              :     }
     346              : 
     347   3534622840 :   return x;
     348              : }
     349              : 
     350              : /* Make a unary operation by first seeing if it folds and otherwise making
     351              :    the specified operation.  */
     352              : 
     353              : rtx
     354      6300191 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
     355              :                                       machine_mode op_mode)
     356              : {
     357      6300191 :   rtx tem;
     358              : 
     359              :   /* If this simplifies, use it.  */
     360      6300191 :   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
     361              :     return tem;
     362              : 
     363      2276187 :   return gen_rtx_fmt_e (code, mode, op);
     364              : }
     365              : 
     366              : /* Likewise for ternary operations.  */
     367              : 
     368              : rtx
     369      2230487 : simplify_context::simplify_gen_ternary (rtx_code code, machine_mode mode,
     370              :                                         machine_mode op0_mode,
     371              :                                         rtx op0, rtx op1, rtx op2)
     372              : {
     373      2230487 :   rtx tem;
     374              : 
     375              :   /* If this simplifies, use it.  */
     376      2230487 :   if ((tem = simplify_ternary_operation (code, mode, op0_mode,
     377              :                                          op0, op1, op2)) != 0)
     378              :     return tem;
     379              : 
     380      1984879 :   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
     381              : }
     382              : 
     383              : /* Likewise, for relational operations.
     384              :    CMP_MODE specifies mode comparison is done in.  */
     385              : 
     386              : rtx
     387     21151110 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
     388              :                                            machine_mode cmp_mode,
     389              :                                            rtx op0, rtx op1)
     390              : {
     391     21151110 :   rtx tem;
     392              : 
     393     21151110 :   if ((tem = simplify_relational_operation (code, mode, cmp_mode,
     394              :                                             op0, op1)) != 0)
     395              :     return tem;
     396              : 
     397     18987723 :   return gen_rtx_fmt_ee (code, mode, op0, op1);
     398              : }
     399              : 
     400              : /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
     401              :    and simplify the result.  If FN is non-NULL, call this callback on each
     402              :    X, if it returns non-NULL, replace X with its return value and simplify the
     403              :    result.  */
     404              : 
     405              : rtx
     406    474807824 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
     407              :                          rtx (*fn) (rtx, const_rtx, void *), void *data)
     408              : {
     409    474807824 :   enum rtx_code code = GET_CODE (x);
     410    474807824 :   machine_mode mode = GET_MODE (x);
     411    474807824 :   machine_mode op_mode;
     412    474807824 :   const char *fmt;
     413    474807824 :   rtx op0, op1, op2, newx, op;
     414    474807824 :   rtvec vec, newvec;
     415    474807824 :   int i, j;
     416              : 
     417    474807824 :   if (UNLIKELY (fn != NULL))
     418              :     {
     419    412018006 :       newx = fn (x, old_rtx, data);
     420    412018006 :       if (newx)
     421              :         return newx;
     422              :     }
     423     62789818 :   else if (rtx_equal_p (x, old_rtx))
     424      5171280 :     return copy_rtx ((rtx) data);
     425              : 
     426    372485149 :   switch (GET_RTX_CLASS (code))
     427              :     {
     428      1968568 :     case RTX_UNARY:
     429      1968568 :       op0 = XEXP (x, 0);
     430      1968568 :       op_mode = GET_MODE (op0);
     431      1968568 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     432      1968568 :       if (op0 == XEXP (x, 0))
     433              :         return x;
     434       643975 :       return simplify_gen_unary (code, mode, op0, op_mode);
     435              : 
     436     73739434 :     case RTX_BIN_ARITH:
     437     73739434 :     case RTX_COMM_ARITH:
     438     73739434 :       op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     439     73739434 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     440     73739434 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     441              :         return x;
     442     22660917 :       return simplify_gen_binary (code, mode, op0, op1);
     443              : 
     444      9702391 :     case RTX_COMPARE:
     445      9702391 :     case RTX_COMM_COMPARE:
     446      9702391 :       op0 = XEXP (x, 0);
     447      9702391 :       op1 = XEXP (x, 1);
     448      9702391 :       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
     449      9702391 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     450      9702391 :       op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
     451      9702391 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     452              :         return x;
     453      2345103 :       return simplify_gen_relational (code, mode, op_mode, op0, op1);
     454              : 
     455      5664344 :     case RTX_TERNARY:
     456      5664344 :     case RTX_BITFIELD_OPS:
     457      5664344 :       op0 = XEXP (x, 0);
     458      5664344 :       op_mode = GET_MODE (op0);
     459      5664344 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     460      5664344 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     461      5664344 :       op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
     462      5664344 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
     463              :         return x;
     464      1650165 :       if (op_mode == VOIDmode)
     465      1628782 :         op_mode = GET_MODE (op0);
     466      1650165 :       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
     467              : 
     468     80644537 :     case RTX_EXTRA:
     469     80644537 :       if (code == SUBREG)
     470              :         {
     471       621334 :           op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
     472       621334 :           if (op0 == SUBREG_REG (x))
     473              :             return x;
     474       128988 :           op0 = simplify_gen_subreg (GET_MODE (x), op0,
     475        64494 :                                      GET_MODE (SUBREG_REG (x)),
     476        64494 :                                      SUBREG_BYTE (x));
     477        64494 :           return op0 ? op0 : x;
     478              :         }
     479              :       break;
     480              : 
     481     60485413 :     case RTX_OBJ:
     482     60485413 :       if (code == MEM)
     483              :         {
     484     10680103 :           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     485     10680103 :           if (op0 == XEXP (x, 0))
     486              :             return x;
     487       158815 :           return replace_equiv_address_nv (x, op0);
     488              :         }
     489     49805310 :       else if (code == LO_SUM)
     490              :         {
     491            0 :           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     492            0 :           op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     493              : 
     494              :           /* (lo_sum (high x) y) -> y where x and y have the same base.  */
     495            0 :           if (GET_CODE (op0) == HIGH)
     496              :             {
     497            0 :               rtx base0, base1, offset0, offset1;
     498            0 :               split_const (XEXP (op0, 0), &base0, &offset0);
     499            0 :               split_const (op1, &base1, &offset1);
     500            0 :               if (rtx_equal_p (base0, base1))
     501            0 :                 return op1;
     502              :             }
     503              : 
     504            0 :           if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     505              :             return x;
     506            0 :           return gen_rtx_LO_SUM (mode, op0, op1);
     507              :         }
     508              :       break;
     509              : 
     510              :     default:
     511              :       break;
     512              :     }
     513              : 
     514    270108975 :   newx = x;
     515    270108975 :   fmt = GET_RTX_FORMAT (code);
     516    583178355 :   for (i = 0; fmt[i]; i++)
     517    313069380 :     switch (fmt[i])
     518              :       {
     519      3128598 :       case 'E':
     520      3128598 :         vec = XVEC (x, i);
     521      3128598 :         newvec = XVEC (newx, i);
     522     12998982 :         for (j = 0; j < GET_NUM_ELEM (vec); j++)
     523              :           {
     524      9870384 :             op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
     525              :                                           old_rtx, fn, data);
     526      9870384 :             if (op != RTVEC_ELT (vec, j))
     527              :               {
     528       343455 :                 if (newvec == vec)
     529              :                   {
     530       332919 :                     newvec = shallow_copy_rtvec (vec);
     531       332919 :                     if (x == newx)
     532       332919 :                       newx = shallow_copy_rtx (x);
     533       332919 :                     XVEC (newx, i) = newvec;
     534              :                   }
     535       343455 :                 RTVEC_ELT (newvec, j) = op;
     536              :               }
     537              :           }
     538              :         break;
     539              : 
     540     72938755 :       case 'e':
     541     72938755 :         if (XEXP (x, i))
     542              :           {
     543     72938755 :             op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
     544     72938755 :             if (op != XEXP (x, i))
     545              :               {
     546      4128109 :                 if (x == newx)
     547      4124846 :                   newx = shallow_copy_rtx (x);
     548      4128109 :                 XEXP (newx, i) = op;
     549              :               }
     550              :           }
     551              :         break;
     552              :       }
     553              :   return newx;
     554              : }
     555              : 
     556              : /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
     557              :    resulting RTX.  Return a new RTX which is as simplified as possible.  */
     558              : 
     559              : rtx
     560     12905953 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
     561              : {
     562     12905953 :   return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
     563              : }
     564              : 
     565              : /* Try to simplify a MODE truncation of OP, which has OP_MODE.
     566              :    Only handle cases where the truncated value is inherently an rvalue.
     567              : 
     568              :    RTL provides two ways of truncating a value:
     569              : 
     570              :    1. a lowpart subreg.  This form is only a truncation when both
     571              :       the outer and inner modes (here MODE and OP_MODE respectively)
     572              :       are scalar integers, and only then when the subreg is used as
     573              :       an rvalue.
     574              : 
     575              :       It is only valid to form such truncating subregs if the
     576              :       truncation requires no action by the target.  The onus for
     577              :       proving this is on the creator of the subreg -- e.g. the
     578              :       caller to simplify_subreg or simplify_gen_subreg -- and typically
     579              :       involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
     580              : 
     581              :    2. a TRUNCATE.  This form handles both scalar and compound integers.
     582              : 
     583              :    The first form is preferred where valid.  However, the TRUNCATE
     584              :    handling in simplify_unary_operation turns the second form into the
     585              :    first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
     586              :    so it is generally safe to form rvalue truncations using:
     587              : 
     588              :       simplify_gen_unary (TRUNCATE, ...)
     589              : 
     590              :    and leave simplify_unary_operation to work out which representation
     591              :    should be used.
     592              : 
     593              :    Because of the proof requirements on (1), simplify_truncation must
     594              :    also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
     595              :    regardless of whether the outer truncation came from a SUBREG or a
     596              :    TRUNCATE.  For example, if the caller has proven that an SImode
     597              :    truncation of:
     598              : 
     599              :       (and:DI X Y)
     600              : 
     601              :    is a no-op and can be represented as a subreg, it does not follow
     602              :    that SImode truncations of X and Y are also no-ops.  On a target
     603              :    like 64-bit MIPS that requires SImode values to be stored in
     604              :    sign-extended form, an SImode truncation of:
     605              : 
     606              :       (and:DI (reg:DI X) (const_int 63))
     607              : 
     608              :    is trivially a no-op because only the lower 6 bits can be set.
     609              :    However, X is still an arbitrary 64-bit number and so we cannot
     610              :    assume that truncating it too is a no-op.  */
     611              : 
     612              : rtx
     613     20509438 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
     614              :                                        machine_mode op_mode)
     615              : {
     616     20509438 :   unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
     617     20509438 :   unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
     618     20509438 :   scalar_int_mode int_mode, int_op_mode, subreg_mode;
     619              : 
     620     20509438 :   gcc_assert (precision <= op_precision);
     621              : 
     622              :   /* Optimize truncations of zero and sign extended values.  */
     623     20509438 :   if (GET_CODE (op) == ZERO_EXTEND
     624     20509438 :       || GET_CODE (op) == SIGN_EXTEND)
     625              :     {
     626              :       /* There are three possibilities.  If MODE is the same as the
     627              :          origmode, we can omit both the extension and the subreg.
     628              :          If MODE is not larger than the origmode, we can apply the
     629              :          truncation without the extension.  Finally, if the outermode
     630              :          is larger than the origmode, we can just extend to the appropriate
     631              :          mode.  */
     632       273460 :       machine_mode origmode = GET_MODE (XEXP (op, 0));
     633       273460 :       if (mode == origmode)
     634              :         return XEXP (op, 0);
     635        20894 :       else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
     636         7677 :         return simplify_gen_unary (TRUNCATE, mode,
     637         7677 :                                    XEXP (op, 0), origmode);
     638              :       else
     639         2770 :         return simplify_gen_unary (GET_CODE (op), mode,
     640         2770 :                                    XEXP (op, 0), origmode);
     641              :     }
     642              : 
     643              :   /* If the machine can perform operations in the truncated mode, distribute
     644              :      the truncation, i.e. simplify (truncate:QI (op:SI (x:SI) (y:SI))) into
     645              :      (op:QI (truncate:QI (x:SI)) (truncate:QI (y:SI))).  */
     646     20235978 :   if (1
     647              :       && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
     648              :       && (GET_CODE (op) == PLUS
     649              :           || GET_CODE (op) == MINUS
     650     20235978 :           || GET_CODE (op) == MULT))
     651              :     {
     652      1161198 :       rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
     653      1161198 :       if (op0)
     654              :         {
     655      1161198 :           rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
     656      1161198 :           if (op1)
     657      1161198 :             return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
     658              :         }
     659              :     }
     660              : 
     661              :   /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
     662              :      to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
     663              :      the outer subreg is effectively a truncation to the original mode.  */
     664     19074780 :   if ((GET_CODE (op) == LSHIFTRT
     665     19074780 :        || GET_CODE (op) == ASHIFTRT)
     666              :       /* Ensure that OP_MODE is at least twice as wide as MODE
     667              :          to avoid the possibility that an outer LSHIFTRT shifts by more
     668              :          than the sign extension's sign_bit_copies and introduces zeros
     669              :          into the high bits of the result.  */
     670      1688111 :       && 2 * precision <= op_precision
     671      1688111 :       && CONST_INT_P (XEXP (op, 1))
     672      1591314 :       && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
     673           31 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     674           28 :       && UINTVAL (XEXP (op, 1)) < precision)
     675           24 :     return simplify_gen_binary (ASHIFTRT, mode,
     676           24 :                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
     677              : 
     678              :   /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
     679              :      to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
     680              :      the outer subreg is effectively a truncation to the original mode.  */
     681     19074756 :   if ((GET_CODE (op) == LSHIFTRT
     682              :        || GET_CODE (op) == ASHIFTRT)
     683      1688087 :       && CONST_INT_P (XEXP (op, 1))
     684      1591290 :       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     685          732 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     686          732 :       && UINTVAL (XEXP (op, 1)) < precision)
     687          722 :     return simplify_gen_binary (LSHIFTRT, mode,
     688          722 :                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
     689              : 
     690              :   /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
     691              :      to (ashift:QI (x:QI) C), where C is a suitable small constant and
     692              :      the outer subreg is effectively a truncation to the original mode.  */
     693     19074034 :   if (GET_CODE (op) == ASHIFT
     694       702956 :       && CONST_INT_P (XEXP (op, 1))
     695       643289 :       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     696       643289 :           || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
     697          772 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     698          759 :       && UINTVAL (XEXP (op, 1)) < precision)
     699          714 :     return simplify_gen_binary (ASHIFT, mode,
     700          714 :                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
     701              : 
     702              :   /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into
     703              :      (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C
     704              :      and C2.  */
     705     19073320 :   if (GET_CODE (op) == AND
     706       734375 :       && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
     707       734375 :           || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
     708        31243 :       && CONST_INT_P (XEXP (XEXP (op, 0), 1))
     709        31128 :       && CONST_INT_P (XEXP (op, 1)))
     710              :     {
     711        31128 :       rtx op0 = (XEXP (XEXP (op, 0), 0));
     712        31128 :       rtx shift_op = XEXP (XEXP (op, 0), 1);
     713        31128 :       rtx mask_op = XEXP (op, 1);
     714        31128 :       unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
     715        31128 :       unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
     716              : 
     717        31128 :       if (shift < precision
     718              :           /* If doing this transform works for an X with all bits set,
     719              :              it works for any X.  */
     720        17867 :           && ((GET_MODE_MASK (mode) >> shift) & mask)
     721        17867 :              == ((GET_MODE_MASK (op_mode) >> shift) & mask)
     722         3211 :           && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
     723        34339 :           && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
     724              :         {
     725         3211 :           mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
     726         3211 :           return simplify_gen_binary (AND, mode, op0, mask_op);
     727              :         }
     728              :     }
     729              : 
     730              :   /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
     731              :      (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
     732              :      changing len.  */
     733     19070109 :   if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
     734       368142 :       && REG_P (XEXP (op, 0))
     735       253166 :       && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
     736       252320 :       && CONST_INT_P (XEXP (op, 1))
     737       252320 :       && CONST_INT_P (XEXP (op, 2)))
     738              :     {
     739       220702 :       rtx op0 = XEXP (op, 0);
     740       220702 :       unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
     741       220702 :       unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
     742       220702 :       if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
     743              :         {
     744              :           op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     745              :           if (op0)
     746              :             {
     747              :               pos -= op_precision - precision;
     748              :               return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     749              :                                            XEXP (op, 1), GEN_INT (pos));
     750              :             }
     751              :         }
     752       220702 :       else if (!BITS_BIG_ENDIAN && precision >= len + pos)
     753              :         {
     754         7751 :           op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     755         7751 :           if (op0)
     756         7751 :             return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     757         7751 :                                          XEXP (op, 1), XEXP (op, 2));
     758              :         }
     759              :     }
     760              : 
     761              :   /* Recognize a word extraction from a multi-word subreg.  */
     762     19062358 :   if ((GET_CODE (op) == LSHIFTRT
     763     19062358 :        || GET_CODE (op) == ASHIFTRT)
     764      1687365 :       && SCALAR_INT_MODE_P (mode)
     765      1684206 :       && SCALAR_INT_MODE_P (op_mode)
     766      1819841 :       && precision >= BITS_PER_WORD
     767        60471 :       && 2 * precision <= op_precision
     768        60471 :       && CONST_INT_P (XEXP (op, 1))
     769        51644 :       && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
     770         1829 :       && UINTVAL (XEXP (op, 1)) < op_precision)
     771              :     {
     772         1829 :       poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
     773         1829 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     774         1829 :       return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
     775              :                                   (WORDS_BIG_ENDIAN
     776         1829 :                                    ? byte - shifted_bytes
     777         1829 :                                    : byte + shifted_bytes));
     778              :     }
     779              : 
     780              :   /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
     781              :      and try replacing the TRUNCATE and shift with it.  Don't do this
     782              :      if the MEM has a mode-dependent address.  */
     783     19060529 :   if ((GET_CODE (op) == LSHIFTRT
     784              :        || GET_CODE (op) == ASHIFTRT)
     785      1682377 :       && is_a <scalar_int_mode> (mode, &int_mode)
     786     20741691 :       && is_a <scalar_int_mode> (op_mode, &int_op_mode)
     787      1682377 :       && MEM_P (XEXP (op, 0))
     788        11536 :       && CONST_INT_P (XEXP (op, 1))
     789        21356 :       && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
     790         1258 :       && INTVAL (XEXP (op, 1)) > 0
     791         2516 :       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
     792         1258 :       && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
     793         1258 :                                      MEM_ADDR_SPACE (XEXP (op, 0)))
     794         1258 :       && ! MEM_VOLATILE_P (XEXP (op, 0))
     795     19060529 :       && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
     796              :           || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
     797              :     {
     798         1215 :       poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
     799         1215 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     800         1215 :       return adjust_address_nv (XEXP (op, 0), int_mode,
     801              :                                 (WORDS_BIG_ENDIAN
     802              :                                  ? byte - shifted_bytes
     803              :                                  : byte + shifted_bytes));
     804              :     }
     805              : 
     806              :   /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
     807              :      (OP:SI foo:SI) if OP is NEG or ABS.  */
     808     19059314 :   if ((GET_CODE (op) == ABS
     809     19059314 :        || GET_CODE (op) == NEG)
     810        20879 :       && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
     811        20879 :           || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
     812           17 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
     813            1 :     return simplify_gen_unary (GET_CODE (op), mode,
     814            1 :                                XEXP (XEXP (op, 0), 0), mode);
     815              : 
     816              :   /* Simplifications of (truncate:A (subreg:B X 0)).  */
     817     19059313 :   if (GET_CODE (op) == SUBREG
     818     19059490 :       && is_a <scalar_int_mode> (mode, &int_mode)
     819        28427 :       && SCALAR_INT_MODE_P (op_mode)
     820        28427 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
     821     19087600 :       && subreg_lowpart_p (op))
     822              :     {
     823              :       /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X).  */
     824        28284 :       if (GET_CODE (SUBREG_REG (op)) == TRUNCATE)
     825              :         {
     826            0 :           rtx inner = XEXP (SUBREG_REG (op), 0);
     827            0 :           if (GET_MODE_PRECISION (int_mode)
     828            0 :               <= GET_MODE_PRECISION (subreg_mode))
     829            0 :             return simplify_gen_unary (TRUNCATE, int_mode, inner,
     830            0 :                                        GET_MODE (inner));
     831              :           else
     832              :             /* If subreg above is paradoxical and C is narrower
     833              :                than A, return (subreg:A (truncate:C X) 0).  */
     834            0 :             return simplify_gen_subreg (int_mode, SUBREG_REG (op),
     835              :                                         subreg_mode, 0);
     836              :         }
     837              : 
     838              :       /* Simplifications of (truncate:A (subreg:B X:C 0)) with
     839              :          paradoxical subregs (B is wider than C).  */
     840        28284 :       if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
     841              :         {
     842        28284 :           unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
     843        28284 :           unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
     844        28284 :           if (int_op_prec > subreg_prec)
     845              :             {
     846         1489 :               if (int_mode == subreg_mode)
     847              :                 return SUBREG_REG (op);
     848           61 :               if (GET_MODE_PRECISION (int_mode) < subreg_prec)
     849           27 :                 return simplify_gen_unary (TRUNCATE, int_mode,
     850           27 :                                            SUBREG_REG (op), subreg_mode);
     851              :             }
     852              :           /* Simplification of (truncate:A (subreg:B X:C 0)) where
     853              :              A is narrower than B and B is narrower than C.  */
     854        26795 :           else if (int_op_prec < subreg_prec
     855        26795 :                    && GET_MODE_PRECISION (int_mode) < int_op_prec)
     856        26795 :             return simplify_gen_unary (TRUNCATE, int_mode,
     857        26795 :                                        SUBREG_REG (op), subreg_mode);
     858              :         }
     859              :     }
     860              : 
     861              :   /* (truncate:A (truncate:B X)) is (truncate:A X).  */
     862     19031063 :   if (GET_CODE (op) == TRUNCATE)
     863            0 :     return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
     864            0 :                                GET_MODE (XEXP (op, 0)));
     865              : 
     866              :   /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
     867              :      in mode A.  */
     868     19031063 :   if (GET_CODE (op) == IOR
     869        34995 :       && SCALAR_INT_MODE_P (mode)
     870        34995 :       && SCALAR_INT_MODE_P (op_mode)
     871        34995 :       && CONST_INT_P (XEXP (op, 1))
     872     19039849 :       && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
     873           42 :     return constm1_rtx;
     874              : 
     875              :   return NULL_RTX;
     876              : }
     877              : 
     878              : /* Try to simplify a unary operation CODE whose output mode is to be
     879              :    MODE with input operand OP whose mode was originally OP_MODE.
     880              :    Return zero if no simplification can be made.  */
     881              : rtx
     882     28092245 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
     883              :                                             rtx op, machine_mode op_mode)
     884              : {
     885     28092245 :   rtx trueop, tem;
     886              : 
     887     28092245 :   trueop = avoid_constant_pool_reference (op);
     888              : 
     889     28092245 :   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
     890     28092245 :   if (tem)
     891              :     return tem;
     892              : 
     893     22877478 :   return simplify_unary_operation_1 (code, mode, op);
     894              : }
     895              : 
     896              : /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
     897              :    to be exact.  */
     898              : 
     899              : static bool
     900         2684 : exact_int_to_float_conversion_p (const_rtx op)
     901              : {
     902         2684 :   machine_mode op0_mode = GET_MODE (XEXP (op, 0));
     903              :   /* Constants can reach here with -frounding-math, if they do then
     904              :      the conversion isn't exact.  */
     905         2684 :   if (op0_mode == VOIDmode)
     906              :     return false;
     907         5366 :   int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
     908         2683 :   int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
     909         2683 :   int in_bits = in_prec;
     910         2683 :   if (HWI_COMPUTABLE_MODE_P (op0_mode))
     911              :     {
     912         2593 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
     913         2593 :       if (GET_CODE (op) == FLOAT)
     914         2469 :         in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
     915          124 :       else if (GET_CODE (op) == UNSIGNED_FLOAT)
     916          124 :         in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
     917              :       else
     918            0 :         gcc_unreachable ();
     919         2593 :       in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
     920              :     }
     921         2683 :   return in_bits <= out_bits;
     922              : }
     923              : 
     924              : /* Perform some simplifications we can do even if the operands
     925              :    aren't constant.  */
     926              : rtx
     927     22877478 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
     928              :                                               rtx op)
     929              : {
     930     22877478 :   enum rtx_code reversed;
     931     22877478 :   rtx temp, elt, base, step;
     932     22877478 :   scalar_int_mode inner, int_mode, op_mode, op0_mode;
     933              : 
     934     22877478 :   switch (code)
     935              :     {
     936      2165665 :     case NOT:
     937              :       /* (not (not X)) == X.  */
     938      2165665 :       if (GET_CODE (op) == NOT)
     939         3085 :         return XEXP (op, 0);
     940              : 
     941              :       /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
     942              :          comparison is all ones.   */
     943      2162580 :       if (COMPARISON_P (op)
     944        13788 :           && (mode == BImode || STORE_FLAG_VALUE == -1)
     945      2162580 :           && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
     946            0 :         return simplify_gen_relational (reversed, mode, VOIDmode,
     947            0 :                                         XEXP (op, 0), XEXP (op, 1));
     948              : 
     949              :       /* (not (plus X -1)) can become (neg X).  */
     950      2162580 :       if (GET_CODE (op) == PLUS
     951       287984 :           && XEXP (op, 1) == constm1_rtx)
     952         4537 :         return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
     953              : 
     954              :       /* Similarly, (not (neg X)) is (plus X -1).  Only do this for
     955              :          modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
     956              :          and MODE_VECTOR_INT.  */
     957      2158043 :       if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
     958        70604 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
     959        70604 :                                     CONSTM1_RTX (mode));
     960              : 
     961              :       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
     962      2087439 :       if (GET_CODE (op) == XOR
     963        16078 :           && CONST_INT_P (XEXP (op, 1))
     964      2091453 :           && (temp = simplify_unary_operation (NOT, mode,
     965              :                                                XEXP (op, 1), mode)) != 0)
     966         4014 :         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
     967              : 
     968              :       /* (not (plus X C)) for signbit C is (xor X D) with D = ~C.  */
     969      2083425 :       if (GET_CODE (op) == PLUS
     970       283447 :           && CONST_INT_P (XEXP (op, 1))
     971       165517 :           && mode_signbit_p (mode, XEXP (op, 1))
     972      2087120 :           && (temp = simplify_unary_operation (NOT, mode,
     973              :                                                XEXP (op, 1), mode)) != 0)
     974         3695 :         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
     975              : 
     976              : 
     977              :       /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for
     978              :          operands other than 1, but that is not valid.  We could do a
     979              :          similar simplification for (not (lshiftrt C X)) where C is
     980              :          just the sign bit, but this doesn't seem common enough to
     981              :          bother with.  */
     982      2079730 :       if (GET_CODE (op) == ASHIFT
     983        36543 :           && XEXP (op, 0) == const1_rtx)
     984              :         {
     985         1031 :           temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
     986         1031 :           return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
     987              :         }
     988              : 
     989              :       /* (not (ashiftrt foo C)) where C is the number of bits in FOO
     990              :          minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
     991              :          so we can perform the above simplification.  */
     992      2078699 :       if (STORE_FLAG_VALUE == -1
     993              :           && is_a <scalar_int_mode> (mode, &int_mode)
     994              :           && GET_CODE (op) == ASHIFTRT
     995              :           && CONST_INT_P (XEXP (op, 1))
     996              :           && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
     997              :         return simplify_gen_relational (GE, int_mode, VOIDmode,
     998              :                                         XEXP (op, 0), const0_rtx);
     999              : 
    1000              : 
    1001      2078699 :       if (partial_subreg_p (op)
    1002       438449 :           && subreg_lowpart_p (op)
    1003       438141 :           && GET_CODE (SUBREG_REG (op)) == ASHIFT
    1004       458366 :           && XEXP (SUBREG_REG (op), 0) == const1_rtx)
    1005              :         {
    1006          163 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
    1007          163 :           rtx x;
    1008              : 
    1009          163 :           x = gen_rtx_ROTATE (inner_mode,
    1010              :                               simplify_gen_unary (NOT, inner_mode, const1_rtx,
    1011              :                                                   inner_mode),
    1012              :                               XEXP (SUBREG_REG (op), 1));
    1013          163 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
    1014          163 :           if (temp)
    1015              :             return temp;
    1016              :         }
    1017              : 
    1018              :       /* Apply De Morgan's laws to reduce number of patterns for machines
    1019              :          with negating logical insns (and-not, nand, etc.).  If result has
    1020              :          only one NOT, put it first, since that is how the patterns are
    1021              :          coded.  */
    1022      2078536 :       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
    1023              :         {
    1024        12120 :           rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
    1025        12120 :           machine_mode op_mode;
    1026              : 
    1027        12120 :           op_mode = GET_MODE (in1);
    1028        12120 :           in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
    1029              : 
    1030        12120 :           op_mode = GET_MODE (in2);
    1031        12120 :           if (op_mode == VOIDmode)
    1032         5351 :             op_mode = mode;
    1033        12120 :           in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
    1034              : 
    1035        12120 :           if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
    1036              :             std::swap (in1, in2);
    1037              : 
    1038        24240 :           return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
    1039              :                                  mode, in1, in2);
    1040              :         }
    1041              : 
    1042              :       /* (not (bswap x)) -> (bswap (not x)).  */
    1043      2066416 :       if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
    1044              :         {
    1045            0 :           rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1046            0 :           return simplify_gen_unary (GET_CODE (op), mode, x, mode);
    1047              :         }
    1048              :       break;
    1049              : 
    1050      1718242 :     case NEG:
    1051              :       /* (neg (neg X)) == X.  */
    1052      1718242 :       if (GET_CODE (op) == NEG)
    1053         6280 :         return XEXP (op, 0);
    1054              : 
    1055              :       /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
    1056              :          If comparison is not reversible use
    1057              :          x ? y : (neg y).  */
    1058      1711962 :       if (GET_CODE (op) == IF_THEN_ELSE)
    1059              :         {
    1060         3089 :           rtx cond = XEXP (op, 0);
    1061         3089 :           rtx true_rtx = XEXP (op, 1);
    1062         3089 :           rtx false_rtx = XEXP (op, 2);
    1063              : 
    1064         3089 :           if ((GET_CODE (true_rtx) == NEG
    1065            0 :                && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
    1066         3089 :                || (GET_CODE (false_rtx) == NEG
    1067            0 :                    && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
    1068              :             {
    1069            0 :               if (reversed_comparison_code (cond, NULL) != UNKNOWN)
    1070            0 :                 temp = reversed_comparison (cond, mode);
    1071              :               else
    1072              :                 {
    1073              :                   temp = cond;
    1074              :                   std::swap (true_rtx, false_rtx);
    1075              :                 }
    1076            0 :               return simplify_gen_ternary (IF_THEN_ELSE, mode,
    1077            0 :                                             mode, temp, true_rtx, false_rtx);
    1078              :             }
    1079              :         }
    1080              : 
    1081              :       /* (neg (plus X 1)) can become (not X).  */
    1082      1711962 :       if (GET_CODE (op) == PLUS
    1083       137572 :           && XEXP (op, 1) == const1_rtx)
    1084        52954 :         return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1085              : 
    1086              :       /* Similarly, (neg (not X)) is (plus X 1).  */
    1087      1659008 :       if (GET_CODE (op) == NOT)
    1088          375 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
    1089          375 :                                     CONST1_RTX (mode));
    1090              : 
    1091              :       /* (neg (minus X Y)) can become (minus Y X).  This transformation
    1092              :          isn't safe for modes with signed zeros, since if X and Y are
    1093              :          both +0, (minus Y X) is the same as (minus X Y).  If the
    1094              :          rounding mode is towards +infinity (or -infinity) then the two
    1095              :          expressions will be rounded differently.  */
    1096      1658633 :       if (GET_CODE (op) == MINUS
    1097        24159 :           && !HONOR_SIGNED_ZEROS (mode)
    1098      1681410 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1099        22777 :         return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
    1100              : 
    1101      1635856 :       if (GET_CODE (op) == PLUS
    1102        84618 :           && !HONOR_SIGNED_ZEROS (mode)
    1103      1720050 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1104              :         {
    1105              :           /* (neg (plus A C)) is simplified to (minus -C A).  */
    1106        84194 :           if (CONST_SCALAR_INT_P (XEXP (op, 1))
    1107         6326 :               || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
    1108              :             {
    1109        77868 :               temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
    1110        77868 :               if (temp)
    1111        77868 :                 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
    1112              :             }
    1113              : 
    1114              :           /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
    1115         6326 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
    1116         6326 :           return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
    1117              :         }
    1118              : 
    1119              :       /* (neg (mult A B)) becomes (mult A (neg B)).
    1120              :          This works even for floating-point values.  */
    1121      1551662 :       if (GET_CODE (op) == MULT
    1122      1551662 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1123              :         {
    1124        20066 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
    1125        20066 :           return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
    1126              :         }
    1127              : 
    1128              :       /* NEG commutes with ASHIFT since it is multiplication.  Only do
    1129              :          this if we can then eliminate the NEG (e.g., if the operand
    1130              :          is a constant).  */
    1131      1531596 :       if (GET_CODE (op) == ASHIFT)
    1132              :         {
    1133        53312 :           temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
    1134        53312 :           if (temp)
    1135        12556 :             return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
    1136              :         }
    1137              : 
    1138              :       /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
    1139              :          C is equal to the width of MODE minus 1.  */
    1140      1519040 :       if (GET_CODE (op) == ASHIFTRT
    1141        28613 :           && CONST_INT_P (XEXP (op, 1))
    1142      1576170 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1143          691 :         return simplify_gen_binary (LSHIFTRT, mode,
    1144          691 :                                     XEXP (op, 0), XEXP (op, 1));
    1145              : 
    1146              :       /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
    1147              :          C is equal to the width of MODE minus 1.  */
    1148      1518349 :       if (GET_CODE (op) == LSHIFTRT
    1149         8733 :           && CONST_INT_P (XEXP (op, 1))
    1150      1535647 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1151         3358 :         return simplify_gen_binary (ASHIFTRT, mode,
    1152         3358 :                                     XEXP (op, 0), XEXP (op, 1));
    1153              : 
    1154              :       /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
    1155      1514991 :       if (GET_CODE (op) == XOR
    1156        10385 :           && XEXP (op, 1) == const1_rtx
    1157      1515102 :           && nonzero_bits (XEXP (op, 0), mode) == 1)
    1158           32 :         return plus_constant (mode, XEXP (op, 0), -1);
    1159              : 
    1160              :       /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1.  */
    1161              :       /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1.  */
    1162      1514959 :       if (GET_CODE (op) == LT
    1163         2726 :           && XEXP (op, 1) == const0_rtx
    1164      1516903 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
    1165              :         {
    1166          355 :           int_mode = as_a <scalar_int_mode> (mode);
    1167          355 :           int isize = GET_MODE_PRECISION (inner);
    1168          355 :           if (STORE_FLAG_VALUE == 1)
    1169              :             {
    1170          355 :               temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
    1171              :                                           gen_int_shift_amount (inner,
    1172          355 :                                                                 isize - 1));
    1173          355 :               if (int_mode == inner)
    1174              :                 return temp;
    1175          190 :               if (GET_MODE_PRECISION (int_mode) > isize)
    1176          129 :                 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
    1177           61 :               return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
    1178              :             }
    1179              :           else if (STORE_FLAG_VALUE == -1)
    1180              :             {
    1181              :               temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
    1182              :                                           gen_int_shift_amount (inner,
    1183              :                                                                 isize - 1));
    1184              :               if (int_mode == inner)
    1185              :                 return temp;
    1186              :               if (GET_MODE_PRECISION (int_mode) > isize)
    1187              :                 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
    1188              :               return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
    1189              :             }
    1190              :         }
    1191              : 
    1192      1514604 :       if (vec_series_p (op, &base, &step))
    1193              :         {
    1194              :           /* Only create a new series if we can simplify both parts.  In other
    1195              :              cases this isn't really a simplification, and it's not necessarily
    1196              :              a win to replace a vector operation with a scalar operation.  */
    1197          276 :           scalar_mode inner_mode = GET_MODE_INNER (mode);
    1198          276 :           base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
    1199          276 :           if (base)
    1200              :             {
    1201          276 :               step = simplify_unary_operation (NEG, inner_mode,
    1202              :                                                step, inner_mode);
    1203          276 :               if (step)
    1204          276 :                 return gen_vec_series (mode, base, step);
    1205              :             }
    1206              :         }
    1207              :       break;
    1208              : 
    1209      1750464 :     case TRUNCATE:
    1210              :       /* Don't optimize (lshiftrt (mult ...)) as it would interfere
    1211              :          with the umulXi3_highpart patterns.  */
    1212      1750464 :       if (GET_CODE (op) == LSHIFTRT
    1213        18910 :           && GET_CODE (XEXP (op, 0)) == MULT)
    1214              :         break;
    1215              : 
    1216      1743134 :       if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
    1217              :         {
    1218           12 :           if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
    1219              :             {
    1220           12 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1221           12 :               if (temp)
    1222              :                 return temp;
    1223              :             }
    1224              :           /* We can't handle truncation to a partial integer mode here
    1225              :              because we don't know the real bitsize of the partial
    1226              :              integer mode.  */
    1227              :           break;
    1228              :         }
    1229              : 
    1230      1743122 :       if (GET_MODE (op) != VOIDmode)
    1231              :         {
    1232      1743122 :           temp = simplify_truncation (mode, op, GET_MODE (op));
    1233      1743122 :           if (temp)
    1234              :             return temp;
    1235              :         }
    1236              : 
    1237              :       /* If we know that the value is already truncated, we can
    1238              :          replace the TRUNCATE with a SUBREG.  */
    1239      1625266 :       if (known_eq (GET_MODE_NUNITS (mode), 1)
    1240      1625266 :           && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
    1241            0 :               || truncated_to_mode (mode, op)))
    1242              :         {
    1243      1612583 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1244      1612583 :           if (temp)
    1245              :             return temp;
    1246              :         }
    1247              : 
    1248              :       /* A truncate of a comparison can be replaced with a subreg if
    1249              :          STORE_FLAG_VALUE permits.  This is like the previous test,
    1250              :          but it works even if the comparison is done in a mode larger
    1251              :          than HOST_BITS_PER_WIDE_INT.  */
    1252        12877 :       if (HWI_COMPUTABLE_MODE_P (mode)
    1253          194 :           && COMPARISON_P (op)
    1254            0 :           && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
    1255        12877 :           && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
    1256              :         {
    1257            0 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1258            0 :           if (temp)
    1259              :             return temp;
    1260              :         }
    1261              : 
    1262              :       /* A truncate of a memory is just loading the low part of the memory
    1263              :          if we are not changing the meaning of the address. */
    1264        12877 :       if (GET_CODE (op) == MEM
    1265          317 :           && !VECTOR_MODE_P (mode)
    1266          192 :           && !MEM_VOLATILE_P (op)
    1267        13063 :           && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
    1268              :         {
    1269          186 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1270          186 :           if (temp)
    1271              :             return temp;
    1272              :         }
    1273              : 
    1274              :       /* Check for useless truncation.  */
    1275        12877 :       if (GET_MODE (op) == mode)
    1276              :         return op;
    1277              :       break;
    1278              : 
    1279       172576 :     case FLOAT_TRUNCATE:
    1280              :       /* Check for useless truncation.  */
    1281       172576 :       if (GET_MODE (op) == mode)
    1282              :         return op;
    1283              : 
    1284       172576 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1285              :         break;
    1286              : 
    1287              :       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
    1288       172422 :       if (GET_CODE (op) == FLOAT_EXTEND
    1289            5 :           && GET_MODE (XEXP (op, 0)) == mode)
    1290              :         return XEXP (op, 0);
    1291              : 
    1292              :       /* (float_truncate:SF (float_truncate:DF foo:XF))
    1293              :          = (float_truncate:SF foo:XF).
    1294              :          This may eliminate double rounding, so it is unsafe.
    1295              : 
    1296              :          (float_truncate:SF (float_extend:XF foo:DF))
    1297              :          = (float_truncate:SF foo:DF).
    1298              : 
    1299              :          (float_truncate:DF (float_extend:XF foo:SF))
    1300              :          = (float_extend:DF foo:SF).  */
    1301       172420 :       if ((GET_CODE (op) == FLOAT_TRUNCATE
    1302          145 :            && flag_unsafe_math_optimizations)
    1303       172416 :           || GET_CODE (op) == FLOAT_EXTEND)
    1304           14 :         return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
    1305            7 :                                    > GET_MODE_UNIT_SIZE (mode)
    1306              :                                    ? FLOAT_TRUNCATE : FLOAT_EXTEND,
    1307              :                                    mode,
    1308           14 :                                    XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1309              : 
    1310              :       /*  (float_truncate (float x)) is (float x)  */
    1311       172413 :       if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1312       172413 :           && (flag_unsafe_math_optimizations
    1313         1401 :               || exact_int_to_float_conversion_p (op)))
    1314         1400 :         return simplify_gen_unary (GET_CODE (op), mode,
    1315              :                                    XEXP (op, 0),
    1316         1400 :                                    GET_MODE (XEXP (op, 0)));
    1317              : 
    1318              :       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
    1319              :          (OP:SF foo:SF) if OP is NEG or ABS.  */
    1320       171013 :       if ((GET_CODE (op) == ABS
    1321       171013 :            || GET_CODE (op) == NEG)
    1322          209 :           && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
    1323           28 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
    1324           28 :         return simplify_gen_unary (GET_CODE (op), mode,
    1325           28 :                                    XEXP (XEXP (op, 0), 0), mode);
    1326              : 
    1327              :       /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
    1328              :          is (float_truncate:SF x).  */
    1329       170985 :       if (GET_CODE (op) == SUBREG
    1330          307 :           && subreg_lowpart_p (op)
    1331       171289 :           && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
    1332              :         return SUBREG_REG (op);
    1333              :       break;
    1334              : 
    1335       592109 :     case FLOAT_EXTEND:
    1336              :       /* Check for useless extension.  */
    1337       592109 :       if (GET_MODE (op) == mode)
    1338              :         return op;
    1339              : 
    1340       592109 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1341              :         break;
    1342              : 
    1343              :       /*  (float_extend (float_extend x)) is (float_extend x)
    1344              : 
    1345              :           (float_extend (float x)) is (float x) assuming that double
    1346              :           rounding can't happen.
    1347              :           */
    1348       592006 :       if (GET_CODE (op) == FLOAT_EXTEND
    1349       592006 :           || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1350         1283 :               && exact_int_to_float_conversion_p (op)))
    1351          569 :         return simplify_gen_unary (GET_CODE (op), mode,
    1352              :                                    XEXP (op, 0),
    1353          569 :                                    GET_MODE (XEXP (op, 0)));
    1354              : 
    1355              :       break;
    1356              : 
    1357       312143 :     case ABS:
    1358              :       /* (abs (neg <foo>)) -> (abs <foo>) */
    1359       312143 :       if (GET_CODE (op) == NEG)
    1360           29 :         return simplify_gen_unary (ABS, mode, XEXP (op, 0),
    1361           29 :                                    GET_MODE (XEXP (op, 0)));
    1362              : 
    1363              :       /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
    1364              :          do nothing.  */
    1365       312114 :       if (GET_MODE (op) == VOIDmode)
    1366              :         break;
    1367              : 
    1368              :       /* If operand is something known to be positive, ignore the ABS.  */
    1369       312114 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1370              :                                      nonzero_bits (op, GET_MODE (op))))
    1371              :         return op;
    1372              : 
    1373              :       /* Using nonzero_bits doesn't (currently) work for modes wider than
    1374              :          HOST_WIDE_INT, so the following transformations help simplify
    1375              :          ABS for TImode and wider.  */
    1376       311896 :       switch (GET_CODE (op))
    1377              :         {
    1378              :         case ABS:
    1379              :         case CLRSB:
    1380              :         case FFS:
    1381              :         case PARITY:
    1382              :         case POPCOUNT:
    1383              :         case SS_ABS:
    1384              :           return op;
    1385              : 
    1386            0 :         case LSHIFTRT:
    1387            0 :           if (CONST_INT_P (XEXP (op, 1))
    1388            0 :               && INTVAL (XEXP (op, 1)) > 0
    1389       311896 :               && is_a <scalar_int_mode> (mode, &int_mode)
    1390            0 :               && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
    1391              :             return op;
    1392              :           break;
    1393              : 
    1394              :         default:
    1395              :           break;
    1396              :         }
    1397              : 
    1398              :       /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
    1399       311896 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    1400        55795 :           && (num_sign_bit_copies (op, int_mode)
    1401        55795 :               == GET_MODE_PRECISION (int_mode)))
    1402           74 :         return gen_rtx_NEG (int_mode, op);
    1403              : 
    1404              :       break;
    1405              : 
    1406            0 :     case FFS:
    1407              :       /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)).  */
    1408            0 :       if (GET_CODE (op) == SIGN_EXTEND
    1409            0 :           || GET_CODE (op) == ZERO_EXTEND)
    1410              :         {
    1411            0 :           temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
    1412            0 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1413            0 :           return simplify_gen_unary (GET_CODE (op), mode, temp,
    1414            0 :                                      GET_MODE (temp));
    1415              :         }
    1416              :       break;
    1417              : 
    1418         3445 :     case POPCOUNT:
    1419         3445 :       switch (GET_CODE (op))
    1420              :         {
    1421            0 :         case BSWAP:
    1422            0 :         case BITREVERSE:
    1423              :           /* (popcount (bswap <X>)) = (popcount <X>).  */
    1424            0 :           return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
    1425            0 :                                      GET_MODE (XEXP (op, 0)));
    1426              : 
    1427           44 :         case ZERO_EXTEND:
    1428              :           /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)).  */
    1429           88 :           temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
    1430           44 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1431           44 :           return simplify_gen_unary (ZERO_EXTEND, mode, temp,
    1432           44 :                                      GET_MODE (temp));
    1433              : 
    1434            0 :         case ROTATE:
    1435            0 :         case ROTATERT:
    1436              :           /* Rotations don't affect popcount.  */
    1437            0 :           if (!side_effects_p (XEXP (op, 1)))
    1438            0 :             return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
    1439            0 :                                        GET_MODE (XEXP (op, 0)));
    1440              :           break;
    1441              : 
    1442              :         default:
    1443              :           break;
    1444              :         }
    1445              :       break;
    1446              : 
    1447            0 :     case PARITY:
    1448            0 :       switch (GET_CODE (op))
    1449              :         {
    1450            0 :         case NOT:
    1451            0 :         case BSWAP:
    1452            0 :         case BITREVERSE:
    1453            0 :           return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
    1454            0 :                                      GET_MODE (XEXP (op, 0)));
    1455              : 
    1456            0 :         case ZERO_EXTEND:
    1457            0 :         case SIGN_EXTEND:
    1458            0 :           temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
    1459            0 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1460            0 :           return simplify_gen_unary (GET_CODE (op), mode, temp,
    1461            0 :                                      GET_MODE (temp));
    1462              : 
    1463            0 :         case ROTATE:
    1464            0 :         case ROTATERT:
    1465              :           /* Rotations don't affect parity.  */
    1466            0 :           if (!side_effects_p (XEXP (op, 1)))
    1467            0 :             return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
    1468            0 :                                        GET_MODE (XEXP (op, 0)));
    1469              :           break;
    1470              : 
    1471              :         case PARITY:
    1472              :           /* (parity (parity x)) -> parity (x).  */
    1473              :           return op;
    1474              : 
    1475              :         default:
    1476              :           break;
    1477              :         }
    1478              :       break;
    1479              : 
    1480        30104 :     case BSWAP:
    1481              :       /* (bswap (bswap x)) -> x.  */
    1482        30104 :       if (GET_CODE (op) == BSWAP)
    1483          184 :         return XEXP (op, 0);
    1484              :       break;
    1485              : 
    1486            0 :     case BITREVERSE:
    1487              :       /* (bitreverse (bitreverse x)) -> x.  */
    1488            0 :       if (GET_CODE (op) == BITREVERSE)
    1489            0 :         return XEXP (op, 0);
    1490              :       break;
    1491              : 
    1492       900051 :     case FLOAT:
    1493              :       /* (float (sign_extend <X>)) = (float <X>).  */
    1494       900051 :       if (GET_CODE (op) == SIGN_EXTEND)
    1495         9352 :         return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
    1496         9352 :                                    GET_MODE (XEXP (op, 0)));
    1497              :       break;
    1498              : 
    1499      2993485 :     case SIGN_EXTEND:
    1500              :       /* Check for useless extension.  */
    1501      2993485 :       if (GET_MODE (op) == mode)
    1502              :         return op;
    1503              : 
    1504              :       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
    1505              :          becomes just the MINUS if its mode is MODE.  This allows
    1506              :          folding switch statements on machines using casesi (such as
    1507              :          the VAX).  */
    1508      2993445 :       if (GET_CODE (op) == TRUNCATE
    1509           62 :           && GET_MODE (XEXP (op, 0)) == mode
    1510           62 :           && GET_CODE (XEXP (op, 0)) == MINUS
    1511            0 :           && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
    1512            0 :           && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
    1513              :         return XEXP (op, 0);
    1514              : 
    1515              :       /* Extending a widening multiplication should be canonicalized to
    1516              :          a wider widening multiplication.  */
    1517      2993445 :       if (GET_CODE (op) == MULT)
    1518              :         {
    1519        67394 :           rtx lhs = XEXP (op, 0);
    1520        67394 :           rtx rhs = XEXP (op, 1);
    1521        67394 :           enum rtx_code lcode = GET_CODE (lhs);
    1522        67394 :           enum rtx_code rcode = GET_CODE (rhs);
    1523              : 
    1524              :           /* Widening multiplies usually extend both operands, but sometimes
    1525              :              they use a shift to extract a portion of a register.  */
    1526        67394 :           if ((lcode == SIGN_EXTEND
    1527        67245 :                || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1528          880 :               && (rcode == SIGN_EXTEND
    1529          836 :                   || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1530              :             {
    1531          165 :               machine_mode lmode = GET_MODE (lhs);
    1532          165 :               machine_mode rmode = GET_MODE (rhs);
    1533          165 :               int bits;
    1534              : 
    1535          165 :               if (lcode == ASHIFTRT)
    1536              :                 /* Number of bits not shifted off the end.  */
    1537          125 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1538          125 :                         - INTVAL (XEXP (lhs, 1)));
    1539              :               else /* lcode == SIGN_EXTEND */
    1540              :                 /* Size of inner mode.  */
    1541           80 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1542              : 
    1543          165 :               if (rcode == ASHIFTRT)
    1544          121 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1545          121 :                          - INTVAL (XEXP (rhs, 1)));
    1546              :               else /* rcode == SIGN_EXTEND */
    1547           88 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1548              : 
    1549              :               /* We can only widen multiplies if the result is mathematiclly
    1550              :                  equivalent.  I.e. if overflow was impossible.  */
    1551          330 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1552          108 :                 return simplify_gen_binary
    1553          108 :                          (MULT, mode,
    1554              :                           simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
    1555          108 :                           simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
    1556              :             }
    1557              :         }
    1558              : 
    1559              :       /* Check for a sign extension of a subreg of a promoted
    1560              :          variable, where the promotion is sign-extended, and the
    1561              :          target mode is the same as the variable's promotion.  */
    1562      2993337 :       if (GET_CODE (op) == SUBREG
    1563       150046 :           && SUBREG_PROMOTED_VAR_P (op)
    1564      2999004 :           && SUBREG_PROMOTED_SIGNED_P (op))
    1565              :         {
    1566            0 :           rtx subreg = SUBREG_REG (op);
    1567            0 :           machine_mode subreg_mode = GET_MODE (subreg);
    1568            0 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1569              :             {
    1570            0 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1571            0 :               if (temp)
    1572              :                 {
    1573              :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1574            0 :                   if (partial_subreg_p (temp))
    1575              :                     {
    1576            0 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1577            0 :                       SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
    1578              :                     }
    1579            0 :                   return temp;
    1580              :                 }
    1581              :             }
    1582              :           else
    1583              :             /* Sign-extending a sign-extended subreg.  */
    1584            0 :             return simplify_gen_unary (SIGN_EXTEND, mode,
    1585            0 :                                        subreg, subreg_mode);
    1586              :         }
    1587              : 
    1588              :       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
    1589              :          (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1590      2993337 :       if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
    1591              :         {
    1592        20250 :           gcc_assert (GET_MODE_UNIT_PRECISION (mode)
    1593              :                       > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
    1594         6750 :           return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
    1595         6750 :                                      GET_MODE (XEXP (op, 0)));
    1596              :         }
    1597              : 
    1598              :       /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1599              :          is (sign_extend:M (subreg:O <X>)) if there is mode with
    1600              :          GET_MODE_BITSIZE (N) - I bits.
    1601              :          (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1602              :          is similarly (zero_extend:M (subreg:O <X>)).  */
    1603      2986587 :       if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
    1604        88469 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1605      2989108 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1606         5198 :           && CONST_INT_P (XEXP (op, 1))
    1607         5198 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1608      2991661 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1609         5074 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1610              :         {
    1611         5074 :           scalar_int_mode tmode;
    1612         5074 :           gcc_assert (GET_MODE_PRECISION (int_mode)
    1613              :                       > GET_MODE_PRECISION (op_mode));
    1614         5074 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1615         7471 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1616              :             {
    1617         2677 :               rtx inner =
    1618         2677 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1619         2677 :               if (inner)
    1620         2677 :                 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
    1621              :                                            ? SIGN_EXTEND : ZERO_EXTEND,
    1622         2677 :                                            int_mode, inner, tmode);
    1623              :             }
    1624              :         }
    1625              : 
    1626              :       /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
    1627              :          (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0.  */
    1628      2983910 :       if (GET_CODE (op) == LSHIFTRT
    1629          186 :           && CONST_INT_P (XEXP (op, 1))
    1630          186 :           && XEXP (op, 1) != const0_rtx)
    1631          186 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1632              : 
    1633              :       /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
    1634              :          I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
    1635              :          (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
    1636              :          (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
    1637              :          O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
    1638              :          wider than O.  */
    1639      2983724 :       if (GET_CODE (op) == TRUNCATE
    1640           62 :           && GET_CODE (XEXP (op, 0)) == LSHIFTRT
    1641            0 :           && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
    1642              :         {
    1643            0 :           scalar_int_mode m_mode, n_mode, o_mode;
    1644            0 :           rtx old_shift = XEXP (op, 0);
    1645            0 :           if (is_a <scalar_int_mode> (mode, &m_mode)
    1646            0 :               && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
    1647            0 :               && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
    1648            0 :               && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
    1649            0 :                  == INTVAL (XEXP (old_shift, 1)))
    1650              :             {
    1651            0 :               rtx new_shift = simplify_gen_binary (ASHIFTRT,
    1652              :                                                    GET_MODE (old_shift),
    1653              :                                                    XEXP (old_shift, 0),
    1654              :                                                    XEXP (old_shift, 1));
    1655            0 :               if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
    1656            0 :                 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
    1657            0 :                                            GET_MODE (new_shift));
    1658            0 :               if (mode != GET_MODE (new_shift))
    1659            0 :                 return simplify_gen_unary (TRUNCATE, mode, new_shift,
    1660            0 :                                            GET_MODE (new_shift));
    1661              :               return new_shift;
    1662              :             }
    1663              :         }
    1664              : 
    1665              :       /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
    1666              :          we know the sign bit of OP must be clear.  */
    1667      2983724 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1668      2983724 :                                      nonzero_bits (op, GET_MODE (op))))
    1669        38036 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1670              : 
    1671              :       /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1672      2945688 :       if (GET_CODE (op) == SUBREG
    1673       149794 :           && subreg_lowpart_p (op)
    1674       149698 :           && GET_MODE (SUBREG_REG (op)) == mode
    1675      3075126 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1676       136216 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1677       136216 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1678       134347 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1679      3080035 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1680       134347 :               & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
    1681         6778 :         return SUBREG_REG (op);
    1682              : 
    1683              : #if defined(POINTERS_EXTEND_UNSIGNED)
    1684              :       /* As we do not know which address space the pointer is referring to,
    1685              :          we can do this only if the target does not support different pointer
    1686              :          or address modes depending on the address space.  */
    1687      2938910 :       if (target_default_pointer_address_modes_p ()
    1688              :           && ! POINTERS_EXTEND_UNSIGNED
    1689              :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1690              :           && (CONSTANT_P (op)
    1691              :               || (GET_CODE (op) == SUBREG
    1692              :                   && REG_P (SUBREG_REG (op))
    1693              :                   && REG_POINTER (SUBREG_REG (op))
    1694              :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1695              :           && !targetm.have_ptr_extend ())
    1696              :         {
    1697              :           temp
    1698              :             = convert_memory_address_addr_space_1 (Pmode, op,
    1699              :                                                    ADDR_SPACE_GENERIC, false,
    1700              :                                                    true);
    1701              :           if (temp)
    1702              :             return temp;
    1703              :         }
    1704              : #endif
    1705              :       break;
    1706              : 
    1707     11363057 :     case ZERO_EXTEND:
    1708              :       /* Check for useless extension.  */
    1709     11363057 :       if (GET_MODE (op) == mode)
    1710              :         return op;
    1711              : 
    1712              :       /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
    1713              :          where const does not sign bit set. */
    1714     11363015 :       if (GET_CODE (op) == AND
    1715       118526 :           && CONST_INT_P (XEXP (op, 1))
    1716        92003 :           && INTVAL (XEXP (op, 1)) > 0)
    1717              :         {
    1718        85004 :           rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
    1719        85004 :           if (tem)
    1720        68847 :             return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
    1721              :         }
    1722              : 
    1723              :       /* Check for a zero extension of a subreg of a promoted
    1724              :          variable, where the promotion is zero-extended, and the
    1725              :          target mode is the same as the variable's promotion.  */
    1726     11294168 :       if (GET_CODE (op) == SUBREG
    1727      1468644 :           && SUBREG_PROMOTED_VAR_P (op)
    1728     11294645 :           && SUBREG_PROMOTED_UNSIGNED_P (op))
    1729              :         {
    1730          477 :           rtx subreg = SUBREG_REG (op);
    1731          477 :           machine_mode subreg_mode = GET_MODE (subreg);
    1732          477 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1733              :             {
    1734          291 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1735          291 :               if (temp)
    1736              :                 {
    1737              :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1738          291 :                   if (partial_subreg_p (temp))
    1739              :                     {
    1740          129 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1741          129 :                       SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
    1742              :                     }
    1743          291 :                   return temp;
    1744              :                 }
    1745              :             }
    1746              :           else
    1747              :             /* Zero-extending a zero-extended subreg.  */
    1748          186 :             return simplify_gen_unary (ZERO_EXTEND, mode,
    1749          186 :                                        subreg, subreg_mode);
    1750              :         }
    1751              : 
    1752              :       /* Extending a widening multiplication should be canonicalized to
    1753              :          a wider widening multiplication.  */
    1754     11293691 :       if (GET_CODE (op) == MULT)
    1755              :         {
    1756       165944 :           rtx lhs = XEXP (op, 0);
    1757       165944 :           rtx rhs = XEXP (op, 1);
    1758       165944 :           enum rtx_code lcode = GET_CODE (lhs);
    1759       165944 :           enum rtx_code rcode = GET_CODE (rhs);
    1760              : 
    1761              :           /* Widening multiplies usually extend both operands, but sometimes
    1762              :              they use a shift to extract a portion of a register.  */
    1763       165944 :           if ((lcode == ZERO_EXTEND
    1764       165172 :                || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1765          862 :               && (rcode == ZERO_EXTEND
    1766          750 :                   || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1767              :             {
    1768          112 :               machine_mode lmode = GET_MODE (lhs);
    1769          112 :               machine_mode rmode = GET_MODE (rhs);
    1770          112 :               int bits;
    1771              : 
    1772          112 :               if (lcode == LSHIFTRT)
    1773              :                 /* Number of bits not shifted off the end.  */
    1774            0 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1775            0 :                         - INTVAL (XEXP (lhs, 1)));
    1776              :               else /* lcode == ZERO_EXTEND */
    1777              :                 /* Size of inner mode.  */
    1778          224 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1779              : 
    1780          112 :               if (rcode == LSHIFTRT)
    1781            0 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1782            0 :                          - INTVAL (XEXP (rhs, 1)));
    1783              :               else /* rcode == ZERO_EXTEND */
    1784          224 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1785              : 
    1786              :               /* We can only widen multiplies if the result is mathematiclly
    1787              :                  equivalent.  I.e. if overflow was impossible.  */
    1788          224 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1789          112 :                 return simplify_gen_binary
    1790          112 :                          (MULT, mode,
    1791              :                           simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
    1792          112 :                           simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
    1793              :             }
    1794              :         }
    1795              : 
    1796              :       /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1797     11293579 :       if (GET_CODE (op) == ZERO_EXTEND)
    1798        21781 :         return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
    1799        21781 :                                    GET_MODE (XEXP (op, 0)));
    1800              : 
    1801              :       /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1802              :          is (zero_extend:M (subreg:O <X>)) if there is mode with
    1803              :          GET_MODE_PRECISION (N) - I bits.  */
    1804     11271798 :       if (GET_CODE (op) == LSHIFTRT
    1805        69567 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1806     11271821 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1807           23 :           && CONST_INT_P (XEXP (op, 1))
    1808           18 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1809     11271798 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1810            0 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1811              :         {
    1812            0 :           scalar_int_mode tmode;
    1813            0 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1814            0 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1815              :             {
    1816            0 :               rtx inner =
    1817            0 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1818            0 :               if (inner)
    1819            0 :                 return simplify_gen_unary (ZERO_EXTEND, int_mode,
    1820            0 :                                            inner, tmode);
    1821              :             }
    1822              :         }
    1823              : 
    1824              :       /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
    1825              :          (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
    1826              :          of mode N.  E.g.
    1827              :          (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
    1828              :          (and:SI (reg:SI) (const_int 63)).  */
    1829     11271798 :       if (partial_subreg_p (op)
    1830     12702602 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1831      1449480 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
    1832      1448989 :           && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
    1833      1135811 :           && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
    1834      1113638 :           && subreg_lowpart_p (op)
    1835      2249048 :           && (nonzero_bits (SUBREG_REG (op), op0_mode)
    1836       780881 :               & ~GET_MODE_MASK (GET_MODE (op))) == 0)
    1837              :         {
    1838        18676 :           if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
    1839        11540 :             return SUBREG_REG (op);
    1840         7136 :           return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
    1841         7136 :                                      op0_mode);
    1842              :         }
    1843              : 
    1844              :       /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1845     11253122 :       if (GET_CODE (op) == SUBREG
    1846      1449491 :           && subreg_lowpart_p (op)
    1847       865525 :           && GET_MODE (SUBREG_REG (op)) == mode
    1848     12029070 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1849       775948 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1850       775948 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1851       714770 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1852     11967892 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1853       714770 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1854            0 :         return SUBREG_REG (op);
    1855              : 
    1856              :       /* Trying to optimize:
    1857              :          (zero_extend:M (subreg:N (not:M (X:M)))) ->
    1858              :          (xor:M (zero_extend:M (subreg:N (X:M)), mask))
    1859              :          where the mask is GET_MODE_MASK (N).
    1860              :          For the cases when X:M doesn't have any non-zero bits
    1861              :          outside of mode N, (zero_extend:M (subreg:N (X:M))
    1862              :          will be simplified to just (X:M)
    1863              :          and whole optimization will be -> (xor:M (X:M, mask)).  */
    1864     11253122 :       if (partial_subreg_p (op)
    1865      1430804 :           && GET_CODE (XEXP (op, 0)) == NOT
    1866         1468 :           && GET_MODE (XEXP (op, 0)) == mode
    1867         1450 :           && subreg_lowpart_p (op)
    1868     11253536 :           && HWI_COMPUTABLE_MODE_P (mode)
    1869          418 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1870      1449909 :           && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
    1871          418 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1872              :       {
    1873            4 :         unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
    1874            8 :         return simplify_gen_binary (XOR, mode,
    1875            4 :                                     XEXP (XEXP (op, 0), 0),
    1876            4 :                                     gen_int_mode (mask, mode));
    1877              :       }
    1878              : 
    1879              : #if defined(POINTERS_EXTEND_UNSIGNED)
    1880              :       /* As we do not know which address space the pointer is referring to,
    1881              :          we can do this only if the target does not support different pointer
    1882              :          or address modes depending on the address space.  */
    1883     11253118 :       if (target_default_pointer_address_modes_p ()
    1884              :           && POINTERS_EXTEND_UNSIGNED > 0
    1885     12655213 :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1886          687 :           && (CONSTANT_P (op)
    1887          666 :               || (GET_CODE (op) == SUBREG
    1888            0 :                   && REG_P (SUBREG_REG (op))
    1889            0 :                   && REG_POINTER (SUBREG_REG (op))
    1890            0 :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1891     11253139 :           && !targetm.have_ptr_extend ())
    1892              :         {
    1893           21 :           temp
    1894           21 :             = convert_memory_address_addr_space_1 (Pmode, op,
    1895              :                                                    ADDR_SPACE_GENERIC, false,
    1896              :                                                    true);
    1897           21 :           if (temp)
    1898              :             return temp;
    1899              :         }
    1900              : #endif
    1901              :       break;
    1902              : 
    1903       507671 :     case VEC_DUPLICATE:
    1904       507671 :       if (GET_CODE (op) == VEC_DUPLICATE)
    1905            2 :         return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
    1906            2 :                                    GET_MODE (XEXP (op, 0)));
    1907              :       break;
    1908              : 
    1909              :     default:
    1910              :       break;
    1911              :     }
    1912              : 
    1913     19136393 :   if (VECTOR_MODE_P (mode)
    1914      1531221 :       && vec_duplicate_p (op, &elt)
    1915     20673490 :       && code != VEC_DUPLICATE)
    1916              :     {
    1917         5876 :       if (code == SIGN_EXTEND || code == ZERO_EXTEND)
    1918              :         /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
    1919              :            operations by promoting VEC_DUPLICATE to the root of the expression
    1920              :            (as far as possible).  */
    1921         4820 :         temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
    1922         9640 :                                    elt, GET_MODE_INNER (GET_MODE (op)));
    1923              :       else
    1924              :         /* Try applying the operator to ELT and see if that simplifies.
    1925              :            We can duplicate the result if so.
    1926              : 
    1927              :            The reason we traditionally haven't used simplify_gen_unary
    1928              :            for these codes is that it didn't necessarily seem to be a
    1929              :            win to convert things like:
    1930              : 
    1931              :              (neg:V (vec_duplicate:V (reg:S R)))
    1932              : 
    1933              :            to:
    1934              : 
    1935              :              (vec_duplicate:V (neg:S (reg:S R)))
    1936              : 
    1937              :            The first might be done entirely in vector registers while the
    1938              :            second might need a move between register files.
    1939              : 
    1940              :            However, there also cases where promoting the vec_duplicate is
    1941              :            more efficient, and there is definite value in having a canonical
    1942              :            form when matching instruction patterns.  We should consider
    1943              :            extending the simplify_gen_unary code above to more cases.  */
    1944         1056 :         temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
    1945         2112 :                                          elt, GET_MODE_INNER (GET_MODE (op)));
    1946         5876 :       if (temp)
    1947         5400 :         return gen_vec_duplicate (mode, temp);
    1948              :     }
    1949              : 
    1950              :   return 0;
    1951              : }
    1952              : 
    1953              : /* Try to compute the value of a unary operation CODE whose output mode is to
    1954              :    be MODE with input operand OP whose mode was originally OP_MODE.
    1955              :    Return zero if the value cannot be computed.  */
    1956              : rtx
    1957     28093203 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
    1958              :                                 rtx op, machine_mode op_mode)
    1959              : {
    1960     28093203 :   scalar_int_mode result_mode;
    1961              : 
    1962     28093203 :   if (code == VEC_DUPLICATE)
    1963              :     {
    1964      1627974 :       gcc_assert (VECTOR_MODE_P (mode));
    1965      1627974 :       if (GET_MODE (op) != VOIDmode)
    1966              :       {
    1967       546666 :         if (!VECTOR_MODE_P (GET_MODE (op)))
    1968      1080054 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
    1969              :         else
    1970        19917 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
    1971              :                                                 (GET_MODE (op)));
    1972              :       }
    1973      1627974 :       if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
    1974      1119548 :         return gen_const_vec_duplicate (mode, op);
    1975       508426 :       if (GET_CODE (op) == CONST_VECTOR
    1976       508426 :           && (CONST_VECTOR_DUPLICATE_P (op)
    1977              :               || CONST_VECTOR_NUNITS (op).is_constant ()))
    1978              :         {
    1979          755 :           unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
    1980          755 :                                     ? CONST_VECTOR_NPATTERNS (op)
    1981         1509 :                                     : CONST_VECTOR_NUNITS (op).to_constant ());
    1982         2265 :           gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
    1983          755 :           rtx_vector_builder builder (mode, npatterns, 1);
    1984         3130 :           for (unsigned i = 0; i < npatterns; i++)
    1985         2375 :             builder.quick_push (CONST_VECTOR_ELT (op, i));
    1986          755 :           return builder.build ();
    1987          755 :         }
    1988              :     }
    1989              : 
    1990     25723009 :   if (VECTOR_MODE_P (mode)
    1991      1571935 :       && GET_CODE (op) == CONST_VECTOR
    1992     27072911 :       && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
    1993              :     {
    1994        33337 :       gcc_assert (GET_MODE (op) == op_mode);
    1995              : 
    1996        33337 :       rtx_vector_builder builder;
    1997        33337 :       if (!builder.new_unary_operation (mode, op, false))
    1998              :         return 0;
    1999              : 
    2000        33337 :       unsigned int count = builder.encoded_nelts ();
    2001       148653 :       for (unsigned int i = 0; i < count; i++)
    2002              :         {
    2003       231670 :           rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
    2004              :                                             CONST_VECTOR_ELT (op, i),
    2005       231670 :                                             GET_MODE_INNER (op_mode));
    2006       115835 :           if (!x || !valid_for_const_vector_p (mode, x))
    2007          519 :             return 0;
    2008       115316 :           builder.quick_push (x);
    2009              :         }
    2010        32818 :       return builder.build ();
    2011        33337 :     }
    2012              : 
    2013              :   /* The order of these tests is critical so that, for example, we don't
    2014              :      check the wrong mode (input vs. output) for a conversion operation,
    2015              :      such as FIX.  At some point, this should be simplified.  */
    2016              : 
    2017     26939563 :   if (code == FLOAT && CONST_SCALAR_INT_P (op))
    2018              :     {
    2019         7400 :       REAL_VALUE_TYPE d;
    2020              : 
    2021         7400 :       if (op_mode == VOIDmode)
    2022              :         {
    2023              :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2024              :              the bits of the constant are significant, though, this is
    2025              :              a dangerous assumption as many times CONST_INTs are
    2026              :              created and used with garbage in the bits outside of the
    2027              :              precision of the implied mode of the const_int.  */
    2028           64 :           op_mode = MAX_MODE_INT;
    2029              :         }
    2030              : 
    2031         7400 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
    2032              : 
    2033              :       /* Avoid the folding if flag_signaling_nans is on and
    2034              :          operand is a signaling NaN.  */
    2035         7400 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2036              :         return 0;
    2037              : 
    2038         7400 :       d = real_value_truncate (mode, d);
    2039              : 
    2040              :       /* Avoid the folding if flag_rounding_math is on and the
    2041              :          conversion is not exact.  */
    2042         7400 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2043              :         {
    2044         1011 :           bool fail = false;
    2045         1011 :           wide_int w = real_to_integer (&d, &fail,
    2046              :                                         GET_MODE_PRECISION
    2047         1011 :                                           (as_a <scalar_int_mode> (op_mode)));
    2048         2022 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2049          905 :             return 0;
    2050         1011 :         }
    2051              : 
    2052         6495 :       return const_double_from_real_value (d, mode);
    2053              :     }
    2054     26932163 :   else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
    2055              :     {
    2056         2139 :       REAL_VALUE_TYPE d;
    2057              : 
    2058         2139 :       if (op_mode == VOIDmode)
    2059              :         {
    2060              :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2061              :              the bits of the constant are significant, though, this is
    2062              :              a dangerous assumption as many times CONST_INTs are
    2063              :              created and used with garbage in the bits outside of the
    2064              :              precision of the implied mode of the const_int.  */
    2065            8 :           op_mode = MAX_MODE_INT;
    2066              :         }
    2067              : 
    2068         2139 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
    2069              : 
    2070              :       /* Avoid the folding if flag_signaling_nans is on and
    2071              :          operand is a signaling NaN.  */
    2072         2139 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2073              :         return 0;
    2074              : 
    2075         2139 :       d = real_value_truncate (mode, d);
    2076              : 
    2077              :       /* Avoid the folding if flag_rounding_math is on and the
    2078              :          conversion is not exact.  */
    2079         2139 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2080              :         {
    2081           16 :           bool fail = false;
    2082           16 :           wide_int w = real_to_integer (&d, &fail,
    2083              :                                         GET_MODE_PRECISION
    2084           16 :                                           (as_a <scalar_int_mode> (op_mode)));
    2085           28 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2086           16 :             return 0;
    2087           16 :         }
    2088              : 
    2089         2123 :       return const_double_from_real_value (d, mode);
    2090              :     }
    2091              : 
    2092     26930024 :   if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
    2093              :     {
    2094      3639250 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2095      3639250 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2096              :         return 0;
    2097              : 
    2098      3639250 :       wide_int result;
    2099      3639250 :       scalar_int_mode imode = (op_mode == VOIDmode
    2100      3639250 :                                ? result_mode
    2101      3639026 :                                : as_a <scalar_int_mode> (op_mode));
    2102      3639250 :       rtx_mode_t op0 = rtx_mode_t (op, imode);
    2103      3639250 :       int int_value;
    2104              : 
    2105              : #if TARGET_SUPPORTS_WIDE_INT == 0
    2106              :       /* This assert keeps the simplification from producing a result
    2107              :          that cannot be represented in a CONST_DOUBLE but a lot of
    2108              :          upstream callers expect that this function never fails to
    2109              :          simplify something and so you if you added this to the test
    2110              :          above the code would die later anyway.  If this assert
    2111              :          happens, you just need to make the port support wide int.  */
    2112              :       gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
    2113              : #endif
    2114              : 
    2115      3639250 :       switch (code)
    2116              :         {
    2117       176797 :         case NOT:
    2118       176797 :           result = wi::bit_not (op0);
    2119       176797 :           break;
    2120              : 
    2121      1856541 :         case NEG:
    2122      1856541 :           result = wi::neg (op0);
    2123      1856541 :           break;
    2124              : 
    2125         7062 :         case ABS:
    2126         7062 :           result = wi::abs (op0);
    2127         7062 :           break;
    2128              : 
    2129            0 :         case FFS:
    2130            0 :           result = wi::shwi (wi::ffs (op0), result_mode);
    2131            0 :           break;
    2132              : 
    2133          168 :         case CLZ:
    2134          168 :           if (wi::ne_p (op0, 0))
    2135           38 :             int_value = wi::clz (op0);
    2136          260 :           else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2137              :             return NULL_RTX;
    2138           38 :           result = wi::shwi (int_value, result_mode);
    2139           38 :           break;
    2140              : 
    2141            0 :         case CLRSB:
    2142            0 :           result = wi::shwi (wi::clrsb (op0), result_mode);
    2143            0 :           break;
    2144              : 
    2145            0 :         case CTZ:
    2146            0 :           if (wi::ne_p (op0, 0))
    2147            0 :             int_value = wi::ctz (op0);
    2148            0 :           else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2149              :             return NULL_RTX;
    2150            0 :           result = wi::shwi (int_value, result_mode);
    2151            0 :           break;
    2152              : 
    2153          160 :         case POPCOUNT:
    2154          160 :           result = wi::shwi (wi::popcount (op0), result_mode);
    2155          160 :           break;
    2156              : 
    2157            0 :         case PARITY:
    2158            0 :           result = wi::shwi (wi::parity (op0), result_mode);
    2159            0 :           break;
    2160              : 
    2161         1765 :         case BSWAP:
    2162         1765 :           result = wi::bswap (op0);
    2163         1765 :           break;
    2164              : 
    2165            0 :         case BITREVERSE:
    2166            0 :           result = wi::bitreverse (op0);
    2167            0 :           break;
    2168              : 
    2169      1418646 :         case TRUNCATE:
    2170      1418646 :         case ZERO_EXTEND:
    2171      1418646 :           result = wide_int::from (op0, width, UNSIGNED);
    2172      1418646 :           break;
    2173              : 
    2174        14342 :         case US_TRUNCATE:
    2175        14342 :         case SS_TRUNCATE:
    2176        14342 :           {
    2177        14342 :             signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
    2178        14342 :             wide_int nmax
    2179        14342 :               = wide_int::from (wi::max_value (width, sgn),
    2180        28684 :                                 GET_MODE_PRECISION (imode), sgn);
    2181        14342 :             wide_int nmin
    2182        14342 :               = wide_int::from (wi::min_value (width, sgn),
    2183        28684 :                                 GET_MODE_PRECISION (imode), sgn);
    2184        14342 :             result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
    2185        14342 :             result = wide_int::from (result, width, sgn);
    2186        14342 :             break;
    2187        14342 :           }
    2188       163769 :         case SIGN_EXTEND:
    2189       163769 :           result = wide_int::from (op0, width, SIGNED);
    2190       163769 :           break;
    2191              : 
    2192            0 :         case SS_NEG:
    2193            0 :           if (wi::only_sign_bit_p (op0))
    2194            0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2195              :           else
    2196            0 :             result = wi::neg (op0);
    2197              :           break;
    2198              : 
    2199            0 :         case SS_ABS:
    2200            0 :           if (wi::only_sign_bit_p (op0))
    2201            0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2202              :           else
    2203            0 :             result = wi::abs (op0);
    2204              :           break;
    2205              : 
    2206              :         case SQRT:
    2207              :         default:
    2208              :           return 0;
    2209              :         }
    2210              : 
    2211      3639120 :       return immed_wide_int_const (result, result_mode);
    2212      3639250 :     }
    2213              : 
    2214     23290774 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2215       417629 :            && SCALAR_FLOAT_MODE_P (mode)
    2216       415596 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
    2217              :     {
    2218       415596 :       REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
    2219       415596 :       switch (code)
    2220              :         {
    2221              :         case SQRT:
    2222              :           return 0;
    2223          350 :         case ABS:
    2224          350 :           d = real_value_abs (&d);
    2225          350 :           break;
    2226        15707 :         case NEG:
    2227        15707 :           d = real_value_negate (&d);
    2228        15707 :           break;
    2229         2284 :         case FLOAT_TRUNCATE:
    2230              :           /* Don't perform the operation if flag_signaling_nans is on
    2231              :              and the operand is a signaling NaN.  */
    2232         2284 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2233              :             return NULL_RTX;
    2234              :           /* Or if flag_rounding_math is on and the truncation is not
    2235              :              exact.  */
    2236         2284 :           if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    2237         2284 :               && !exact_real_truncate (mode, &d))
    2238          231 :             return NULL_RTX;
    2239         2053 :           d = real_value_truncate (mode, d);
    2240         2053 :           break;
    2241       390779 :         case FLOAT_EXTEND:
    2242              :           /* Don't perform the operation if flag_signaling_nans is on
    2243              :              and the operand is a signaling NaN.  */
    2244       390779 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2245              :             return NULL_RTX;
    2246              :           /* All this does is change the mode, unless changing
    2247              :              mode class.  */
    2248       390777 :           if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
    2249            0 :             real_convert (&d, mode, &d);
    2250              :           break;
    2251            0 :         case FIX:
    2252              :           /* Don't perform the operation if flag_signaling_nans is on
    2253              :              and the operand is a signaling NaN.  */
    2254            0 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2255              :             return NULL_RTX;
    2256            0 :           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
    2257            0 :           break;
    2258         5871 :         case NOT:
    2259         5871 :           {
    2260         5871 :             long tmp[4];
    2261         5871 :             int i;
    2262              : 
    2263         5871 :             real_to_target (tmp, &d, GET_MODE (op));
    2264        29355 :             for (i = 0; i < 4; i++)
    2265        23484 :               tmp[i] = ~tmp[i];
    2266         5871 :             real_from_target (&d, tmp, mode);
    2267         5871 :             break;
    2268              :           }
    2269            0 :         default:
    2270            0 :           gcc_unreachable ();
    2271              :         }
    2272       414758 :       return const_double_from_real_value (d, mode);
    2273              :     }
    2274         2033 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2275         2033 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op))
    2276     22877211 :            && is_int_mode (mode, &result_mode))
    2277              :     {
    2278         2033 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2279         2033 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2280              :         return 0;
    2281              : 
    2282              :       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
    2283              :          operators are intentionally left unspecified (to ease implementation
    2284              :          by target backends), for consistency, this routine implements the
    2285              :          same semantics for constant folding as used by the middle-end.  */
    2286              : 
    2287              :       /* This was formerly used only for non-IEEE float.
    2288              :          eggert@twinsun.com says it is safe for IEEE also.  */
    2289         2033 :       REAL_VALUE_TYPE t;
    2290         2033 :       const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
    2291         2033 :       wide_int wmax, wmin;
    2292              :       /* This is part of the abi to real_to_integer, but we check
    2293              :          things before making this call.  */
    2294         2033 :       bool fail;
    2295              : 
    2296         2033 :       switch (code)
    2297              :         {
    2298         2025 :         case FIX:
    2299              :           /* According to IEEE standard, for conversions from floating point to
    2300              :              integer. When a NaN or infinite operand cannot be represented in
    2301              :              the destination format and this cannot otherwise be indicated, the
    2302              :              invalid operation exception shall be signaled. When a numeric
    2303              :              operand would convert to an integer outside the range of the
    2304              :              destination format, the invalid operation exception shall be
    2305              :              signaled if this situation cannot otherwise be indicated.  */
    2306         2025 :           if (REAL_VALUE_ISNAN (*x))
    2307          955 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2308              : 
    2309         1070 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2310              :             return NULL_RTX;
    2311              : 
    2312              :           /* Test against the signed upper bound.  */
    2313          110 :           wmax = wi::max_value (width, SIGNED);
    2314          110 :           real_from_integer (&t, VOIDmode, wmax, SIGNED);
    2315          110 :           if (real_less (&t, x))
    2316            3 :             return (flag_trapping_math
    2317            3 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2318              : 
    2319              :           /* Test against the signed lower bound.  */
    2320          107 :           wmin = wi::min_value (width, SIGNED);
    2321          107 :           real_from_integer (&t, VOIDmode, wmin, SIGNED);
    2322          107 :           if (real_less (x, &t))
    2323            8 :             return immed_wide_int_const (wmin, mode);
    2324              : 
    2325           99 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2326              :                                        mode);
    2327              : 
    2328            8 :         case UNSIGNED_FIX:
    2329            8 :           if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
    2330            6 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2331              : 
    2332            2 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2333              :             return NULL_RTX;
    2334              : 
    2335              :           /* Test against the unsigned upper bound.  */
    2336            0 :           wmax = wi::max_value (width, UNSIGNED);
    2337            0 :           real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
    2338            0 :           if (real_less (&t, x))
    2339            0 :             return (flag_trapping_math
    2340            0 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2341              : 
    2342            0 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2343              :                                        mode);
    2344              : 
    2345            0 :         default:
    2346            0 :           gcc_unreachable ();
    2347              :         }
    2348         2033 :     }
    2349              : 
    2350              :   /* Handle polynomial integers.  */
    2351              :   else if (CONST_POLY_INT_P (op))
    2352              :     {
    2353              :       poly_wide_int result;
    2354              :       switch (code)
    2355              :         {
    2356              :         case NEG:
    2357              :           result = -const_poly_int_value (op);
    2358              :           break;
    2359              : 
    2360              :         case NOT:
    2361              :           result = ~const_poly_int_value (op);
    2362              :           break;
    2363              : 
    2364              :         default:
    2365              :           return NULL_RTX;
    2366              :         }
    2367              :       return immed_wide_int_const (result, mode);
    2368              :     }
    2369              : 
    2370              :   return NULL_RTX;
    2371              : }
    2372              : 
    2373              : /* Subroutine of simplify_binary_operation to simplify a binary operation
    2374              :    CODE that can commute with byte swapping, with result mode MODE and
    2375              :    operating on OP0 and OP1.  CODE is currently one of AND, IOR or XOR.
    2376              :    Return zero if no simplification or canonicalization is possible.  */
    2377              : 
    2378              : rtx
    2379     36684869 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
    2380              :                                                     machine_mode mode,
    2381              :                                                     rtx op0, rtx op1)
    2382              : {
    2383     36684869 :   rtx tem;
    2384              : 
    2385              :   /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped.  */
    2386     36684869 :   if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
    2387              :     {
    2388          254 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
    2389              :                                  simplify_gen_unary (BSWAP, mode, op1, mode));
    2390          254 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2391              :     }
    2392              : 
    2393              :   /* (op (bswap x) (bswap y)) -> (bswap (op x y)).  */
    2394     36684615 :   if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
    2395              :     {
    2396            0 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
    2397            0 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2398              :     }
    2399              : 
    2400              :   return NULL_RTX;
    2401              : }
    2402              : 
    2403              : /* Subroutine of simplify_binary_operation to simplify a commutative,
    2404              :    associative binary operation CODE with result mode MODE, operating
    2405              :    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
    2406              :    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
    2407              :    canonicalization is possible.  */
    2408              : 
    2409              : rtx
    2410     46573138 : simplify_context::simplify_associative_operation (rtx_code code,
    2411              :                                                   machine_mode mode,
    2412              :                                                   rtx op0, rtx op1)
    2413              : {
    2414     46573138 :   rtx tem;
    2415              : 
    2416              :   /* Normally expressions simplified by simplify-rtx.cc are combined
    2417              :      at most from a few machine instructions and therefore the
    2418              :      expressions should be fairly small.  During var-tracking
    2419              :      we can see arbitrarily large expressions though and reassociating
    2420              :      those can be quadratic, so punt after encountering max_assoc_count
    2421              :      simplify_associative_operation calls during outermost simplify_*
    2422              :      call.  */
    2423     46573138 :   if (++assoc_count >= max_assoc_count)
    2424              :     return NULL_RTX;
    2425              : 
    2426              :   /* Linearize the operator to the left.  */
    2427     46569287 :   if (GET_CODE (op1) == code)
    2428              :     {
    2429              :       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
    2430        18472 :       if (GET_CODE (op0) == code)
    2431              :         {
    2432         4759 :           tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
    2433         4759 :           return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
    2434              :         }
    2435              : 
    2436              :       /* "a op (b op c)" becomes "(b op c) op a".  */
    2437        13713 :       if (! swap_commutative_operands_p (op1, op0))
    2438        13713 :         return simplify_gen_binary (code, mode, op1, op0);
    2439              : 
    2440              :       std::swap (op0, op1);
    2441              :     }
    2442              : 
    2443     46550815 :   if (GET_CODE (op0) == code)
    2444              :     {
    2445              :       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
    2446      1282013 :       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
    2447              :         {
    2448       262016 :           tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
    2449       262016 :           return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2450              :         }
    2451              : 
    2452              :       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
    2453      1019997 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
    2454      1019997 :       if (tem != 0)
    2455        76185 :         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
    2456              : 
    2457              :       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
    2458       943812 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
    2459       943812 :       if (tem != 0)
    2460        30419 :         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2461              :     }
    2462              : 
    2463              :   return 0;
    2464              : }
    2465              : 
    2466              : /* If COMPARISON can be treated as an unsigned comparison, return a mask
    2467              :    that represents it (8 if it includes <, 4 if it includes > and 2
    2468              :    if it includes ==).  Return 0 otherwise.  */
    2469              : static int
    2470        18906 : unsigned_comparison_to_mask (rtx_code comparison)
    2471              : {
    2472            0 :   switch (comparison)
    2473              :     {
    2474              :     case LTU:
    2475              :       return 8;
    2476              :     case GTU:
    2477              :       return 4;
    2478              :     case EQ:
    2479              :       return 2;
    2480              : 
    2481              :     case LEU:
    2482              :       return 10;
    2483              :     case GEU:
    2484              :       return 6;
    2485              : 
    2486              :     case NE:
    2487              :       return 12;
    2488              : 
    2489              :     default:
    2490              :       return 0;
    2491              :     }
    2492              : }
    2493              : 
    2494              : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
    2495              :    to comparisons.  */
    2496              : static rtx_code
    2497         6616 : mask_to_unsigned_comparison (int mask)
    2498              : {
    2499         6616 :   switch (mask)
    2500              :     {
    2501              :     case 8:
    2502              :       return LTU;
    2503          160 :     case 4:
    2504          160 :       return GTU;
    2505         2593 :     case 2:
    2506         2593 :       return EQ;
    2507              : 
    2508          160 :     case 10:
    2509          160 :       return LEU;
    2510          160 :     case 6:
    2511          160 :       return GEU;
    2512              : 
    2513         3383 :     case 12:
    2514         3383 :       return NE;
    2515              : 
    2516            0 :     default:
    2517            0 :       gcc_unreachable ();
    2518              :     }
    2519              : }
    2520              : 
    2521              : /* Return a mask describing the COMPARISON.  */
    2522              : static int
    2523         2666 : comparison_to_mask (enum rtx_code comparison)
    2524              : {
    2525         2666 :   switch (comparison)
    2526              :     {
    2527              :     case LT:
    2528              :       return 8;
    2529          472 :     case GT:
    2530          472 :       return 4;
    2531          419 :     case EQ:
    2532          419 :       return 2;
    2533           19 :     case UNORDERED:
    2534           19 :       return 1;
    2535              : 
    2536            0 :     case LTGT:
    2537            0 :       return 12;
    2538          441 :     case LE:
    2539          441 :       return 10;
    2540          441 :     case GE:
    2541          441 :       return 6;
    2542            0 :     case UNLT:
    2543            0 :       return 9;
    2544            0 :     case UNGT:
    2545            0 :       return 5;
    2546            0 :     case UNEQ:
    2547            0 :       return 3;
    2548              : 
    2549            0 :     case ORDERED:
    2550            0 :       return 14;
    2551          400 :     case NE:
    2552          400 :       return 13;
    2553            0 :     case UNLE:
    2554            0 :       return 11;
    2555            0 :     case UNGE:
    2556            0 :       return 7;
    2557              : 
    2558            0 :     default:
    2559            0 :       gcc_unreachable ();
    2560              :     }
    2561              : }
    2562              : 
    2563              : /* Return a comparison corresponding to the MASK.  */
    2564              : static enum rtx_code
    2565         1014 : mask_to_comparison (int mask)
    2566              : {
    2567         1014 :   switch (mask)
    2568              :     {
    2569              :     case 8:
    2570              :       return LT;
    2571              :     case 4:
    2572              :       return GT;
    2573              :     case 2:
    2574              :       return EQ;
    2575              :     case 1:
    2576              :       return UNORDERED;
    2577              : 
    2578              :     case 12:
    2579              :       return LTGT;
    2580              :     case 10:
    2581              :       return LE;
    2582              :     case 6:
    2583              :       return GE;
    2584              :     case 9:
    2585              :       return UNLT;
    2586              :     case 5:
    2587              :       return UNGT;
    2588              :     case 3:
    2589              :       return UNEQ;
    2590              : 
    2591              :     case 14:
    2592              :       return ORDERED;
    2593              :     case 13:
    2594              :       return NE;
    2595              :     case 11:
    2596              :       return UNLE;
    2597              :     case 7:
    2598              :       return UNGE;
    2599              : 
    2600            0 :     default:
    2601            0 :       gcc_unreachable ();
    2602              :     }
    2603              : }
    2604              : 
    2605              : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
    2606              :    false/true value of comparison with MODE where comparison operands
    2607              :    have CMP_MODE.  */
    2608              : 
    2609              : static rtx
    2610       779211 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
    2611              : {
    2612       779211 :   if (SCALAR_FLOAT_MODE_P (mode))
    2613              :     {
    2614          197 :       if (res == const0_rtx)
    2615          193 :         return CONST0_RTX (mode);
    2616              : #ifdef FLOAT_STORE_FLAG_VALUE
    2617              :       REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
    2618              :       return const_double_from_real_value (val, mode);
    2619              : #else
    2620              :       return NULL_RTX;
    2621              : #endif
    2622              :     }
    2623       779014 :   if (VECTOR_MODE_P (mode))
    2624              :     {
    2625          377 :       if (res == const0_rtx)
    2626           63 :         return CONST0_RTX (mode);
    2627              : #ifdef VECTOR_STORE_FLAG_VALUE
    2628          314 :       rtx val = VECTOR_STORE_FLAG_VALUE (mode);
    2629          304 :       if (val == NULL_RTX)
    2630              :         return NULL_RTX;
    2631          304 :       if (val == const1_rtx)
    2632            0 :         return CONST1_RTX (mode);
    2633              : 
    2634          304 :       return gen_const_vec_duplicate (mode, val);
    2635              : #else
    2636              :       return NULL_RTX;
    2637              : #endif
    2638              :     }
    2639              :   /* For vector comparison with scalar int result, it is unknown
    2640              :      if the target means here a comparison into an integral bitmask,
    2641              :      or comparison where all comparisons true mean const_true_rtx
    2642              :      whole result, or where any comparisons true mean const_true_rtx
    2643              :      whole result.  For const0_rtx all the cases are the same.  */
    2644       778637 :   if (VECTOR_MODE_P (cmp_mode)
    2645            0 :       && SCALAR_INT_MODE_P (mode)
    2646            0 :       && res == const_true_rtx)
    2647            0 :     return NULL_RTX;
    2648              : 
    2649              :   return res;
    2650              : }
    2651              : 
    2652              : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
    2653              :    and OP1, in the case where both are relational operations.  Assume that
    2654              :    OP0 is inverted if INVERT0_P is true.
    2655              : 
    2656              :    Return 0 if no such simplification is possible.  */
    2657              : rtx
    2658     13170527 : simplify_context::simplify_logical_relational_operation (rtx_code code,
    2659              :                                                          machine_mode mode,
    2660              :                                                          rtx op0, rtx op1,
    2661              :                                                          bool invert0_p)
    2662              : {
    2663     13170527 :   if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
    2664              :     return 0;
    2665              : 
    2666        21457 :   if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2667         9879 :         && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
    2668         2125 :     return 0;
    2669              : 
    2670         9453 :   if (side_effects_p (op0))
    2671              :     return 0;
    2672              : 
    2673         9453 :   enum rtx_code code0 = GET_CODE (op0);
    2674         9453 :   enum rtx_code code1 = GET_CODE (op1);
    2675         9453 :   machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
    2676         9453 :   if (cmp_mode == VOIDmode)
    2677            0 :     cmp_mode = GET_MODE (XEXP (op0, 1));
    2678              : 
    2679              :   /* Assume at first that the comparisons are on integers, and that the
    2680              :      operands are therefore ordered.  */
    2681         9453 :   int all = 14;
    2682         9453 :   int mask0 = unsigned_comparison_to_mask (code0);
    2683         9453 :   int mask1 = unsigned_comparison_to_mask (code1);
    2684        18906 :   bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
    2685         9453 :                      || IN_RANGE (mask1 & 12, 4, 8));
    2686         1333 :   if (unsigned_p)
    2687              :     {
    2688              :       /* We only reach here when comparing integers.  Reject mixtures of signed
    2689              :          and unsigned comparisons.  */
    2690         8120 :       if (mask0 == 0 || mask1 == 0)
    2691              :         return 0;
    2692              :     }
    2693              :   else
    2694              :     {
    2695              :       /* See whether the operands might be unordered.  Assume that all
    2696              :          results are possible for CC modes, and punt later if we don't get an
    2697              :          always-true or always-false answer.  */
    2698         1333 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
    2699              :         all = 15;
    2700         1333 :       mask0 = comparison_to_mask (code0) & all;
    2701         1333 :       mask1 = comparison_to_mask (code1) & all;
    2702              :     }
    2703              : 
    2704         8173 :   if (invert0_p)
    2705         4661 :     mask0 = mask0 ^ all;
    2706              : 
    2707         8173 :   int mask;
    2708         8173 :   if (code == AND)
    2709          960 :     mask = mask0 & mask1;
    2710         7213 :   else if (code == IOR)
    2711          948 :     mask = mask0 | mask1;
    2712         6265 :   else if (code == XOR)
    2713         6265 :     mask = mask0 ^ mask1;
    2714              :   else
    2715              :     return 0;
    2716              : 
    2717         8173 :   if (mask == all)
    2718          232 :     return relational_result (mode, GET_MODE (op0), const_true_rtx);
    2719              : 
    2720         7941 :   if (mask == 0)
    2721          232 :     return relational_result (mode, GET_MODE (op0), const0_rtx);
    2722              : 
    2723         7709 :   if (unsigned_p)
    2724         6616 :     code = mask_to_unsigned_comparison (mask);
    2725              :   else
    2726              :     {
    2727         1093 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    2728              :         return 0;
    2729              : 
    2730         1014 :       code = mask_to_comparison (mask);
    2731              :       /* LTGT and NE are arithmetically equivalent for ordered operands,
    2732              :          with NE being the canonical choice.  */
    2733         1014 :       if (code == LTGT && all == 14)
    2734          184 :         code = NE;
    2735              :     }
    2736              : 
    2737         7630 :   op0 = XEXP (op1, 0);
    2738         7630 :   op1 = XEXP (op1, 1);
    2739              : 
    2740         7630 :   return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
    2741              : }
    2742              : 
    2743              : /* We are going to IOR together OP0/OP1.  If there is a common term in OP0/OP1
    2744              :    then we may be able to simplify the expression.  We're primarily trying to
    2745              :    simplify down to IOR/XOR expression right now, but there may be other
    2746              :    simplifications we can do in the future.
    2747              : 
    2748              :    Return the simplified expression or NULL_RTX if no simplification was
    2749              :    possible.  */
    2750              : rtx
    2751     26862535 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
    2752              : {
    2753              :   /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
    2754              :      X and C have no bits in common.  */
    2755     26862535 :   if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
    2756       228920 :       && rtx_equal_p (op0, XEXP (op1, 0))
    2757         8318 :       && ((nonzero_bits (op0, GET_MODE (op0))
    2758         8318 :           & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
    2759     26862535 :       && !side_effects_p (op1))
    2760            0 :     return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
    2761              : 
    2762              :   /* (ior (and A C1) (and (not A) C2)) can be converted
    2763              :      into (and (xor A C2) (C1 + C2)) when there are no bits
    2764              :      in common between C1 and C2.  */
    2765     26862535 :   if (GET_CODE (op0) == AND
    2766      3945552 :       && GET_CODE (op1) == AND
    2767       392057 :       && GET_CODE (XEXP (op1, 0)) == NOT
    2768        24167 :       && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
    2769          751 :       && CONST_INT_P (XEXP (op0, 1))
    2770           93 :       && CONST_INT_P (XEXP (op1, 1))
    2771     26862628 :       && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
    2772              :     {
    2773           93 :       rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
    2774              : 
    2775           93 :       rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
    2776           93 :       if (tem)
    2777              :         {
    2778           93 :           tem = simplify_gen_binary (AND, mode, tem, c);
    2779              : 
    2780           93 :           if (tem)
    2781              :             return tem;
    2782              :         }
    2783              :     }
    2784              : 
    2785              :   /* Another variant seen on some target particularly those with
    2786              :      sub-word operations.
    2787              : 
    2788              :      (ior (and A C1) (plus (and A C2) C2)) can be simplified into
    2789              :      (and (xor (A C2) (C1 + C2).
    2790              : 
    2791              :      Where C2 is the sign bit for A's mode.  So 0x80 for QI,
    2792              :      0x8000 for HI, etc.  In this case we know there is no carry
    2793              :      from the PLUS into relevant bits of the output.  */
    2794     26862442 :   if (GET_CODE (op0) == AND
    2795      3945459 :       && GET_CODE (op1) == PLUS
    2796         5797 :       && GET_CODE (XEXP (op1, 0)) == AND
    2797          288 :       && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
    2798          276 :       && CONST_INT_P (XEXP (op0, 1))
    2799          276 :       && CONST_INT_P (XEXP (op1, 1))
    2800          276 :       && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
    2801          276 :       && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
    2802           72 :       && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
    2803          144 :       && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
    2804          144 :           == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
    2805     26862442 :       && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
    2806              :     {
    2807            0 :       rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
    2808              : 
    2809            0 :       rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
    2810            0 :       if (tem)
    2811              :         {
    2812            0 :           tem = simplify_gen_binary (AND, mode, tem, c);
    2813            0 :           if (tem)
    2814              :             return tem;
    2815              :         }
    2816              :     }
    2817              :   return NULL_RTX;
    2818              : }
    2819              : 
    2820              : 
    2821              : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
    2822              :    and OP1.  Return 0 if no simplification is possible.
    2823              : 
    2824              :    Don't use this for relational operations such as EQ or LT.
    2825              :    Use simplify_relational_operation instead.  */
    2826              : rtx
    2827    475808628 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
    2828              :                                              rtx op0, rtx op1)
    2829              : {
    2830    475808628 :   rtx trueop0, trueop1;
    2831    475808628 :   rtx tem;
    2832              : 
    2833              :   /* Relational operations don't work here.  We must know the mode
    2834              :      of the operands in order to do the comparison correctly.
    2835              :      Assuming a full word can give incorrect results.
    2836              :      Consider comparing 128 with -128 in QImode.  */
    2837    475808628 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
    2838    475808628 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
    2839              : 
    2840              :   /* Make sure the constant is second.  */
    2841    475808628 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    2842    475808628 :       && swap_commutative_operands_p (op0, op1))
    2843              :     std::swap (op0, op1);
    2844              : 
    2845    475808628 :   trueop0 = avoid_constant_pool_reference (op0);
    2846    475808628 :   trueop1 = avoid_constant_pool_reference (op1);
    2847              : 
    2848    475808628 :   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
    2849    475808628 :   if (tem)
    2850              :     return tem;
    2851    446429538 :   tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
    2852              : 
    2853    446429538 :   if (tem)
    2854              :     return tem;
    2855              : 
    2856              :   /* If the above steps did not result in a simplification and op0 or op1
    2857              :      were constant pool references, use the referenced constants directly.  */
    2858    383468086 :   if (trueop0 != op0 || trueop1 != op1)
    2859       584665 :     return simplify_gen_binary (code, mode, trueop0, trueop1);
    2860              : 
    2861              :   return NULL_RTX;
    2862              : }
    2863              : 
    2864              : /* Subroutine of simplify_binary_operation_1 that looks for cases in
    2865              :    which OP0 and OP1 are both vector series or vector duplicates
    2866              :    (which are really just series with a step of 0).  If so, try to
    2867              :    form a new series by applying CODE to the bases and to the steps.
    2868              :    Return null if no simplification is possible.
    2869              : 
    2870              :    MODE is the mode of the operation and is known to be a vector
    2871              :    integer mode.  */
    2872              : 
    2873              : rtx
    2874      2482626 : simplify_context::simplify_binary_operation_series (rtx_code code,
    2875              :                                                     machine_mode mode,
    2876              :                                                     rtx op0, rtx op1)
    2877              : {
    2878      2482626 :   rtx base0, step0;
    2879      2482626 :   if (vec_duplicate_p (op0, &base0))
    2880        71116 :     step0 = const0_rtx;
    2881      2411510 :   else if (!vec_series_p (op0, &base0, &step0))
    2882              :     return NULL_RTX;
    2883              : 
    2884        71834 :   rtx base1, step1;
    2885        71834 :   if (vec_duplicate_p (op1, &base1))
    2886          421 :     step1 = const0_rtx;
    2887        71413 :   else if (!vec_series_p (op1, &base1, &step1))
    2888              :     return NULL_RTX;
    2889              : 
    2890              :   /* Only create a new series if we can simplify both parts.  In other
    2891              :      cases this isn't really a simplification, and it's not necessarily
    2892              :      a win to replace a vector operation with a scalar operation.  */
    2893         5657 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    2894         5657 :   rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
    2895         5657 :   if (!new_base)
    2896              :     return NULL_RTX;
    2897              : 
    2898         4719 :   rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
    2899         4719 :   if (!new_step)
    2900              :     return NULL_RTX;
    2901              : 
    2902         4719 :   return gen_vec_series (mode, new_base, new_step);
    2903              : }
    2904              : 
    2905              : /* Subroutine of simplify_binary_operation_1.  Un-distribute a binary
    2906              :    operation CODE with result mode MODE, operating on OP0 and OP1.
    2907              :    e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
    2908              :    Returns NULL_RTX if no simplification is possible.  */
    2909              : 
    2910              : rtx
    2911      1315310 : simplify_context::simplify_distributive_operation (rtx_code code,
    2912              :                                                    machine_mode mode,
    2913              :                                                    rtx op0, rtx op1)
    2914              : {
    2915      1315310 :   enum rtx_code op = GET_CODE (op0);
    2916      1315310 :   gcc_assert (GET_CODE (op1) == op);
    2917              : 
    2918      1315310 :   if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
    2919      1315310 :       && ! side_effects_p (XEXP (op0, 1)))
    2920       339243 :     return simplify_gen_binary (op, mode,
    2921              :                                 simplify_gen_binary (code, mode,
    2922              :                                                      XEXP (op0, 0),
    2923              :                                                      XEXP (op1, 0)),
    2924       339243 :                                 XEXP (op0, 1));
    2925              : 
    2926       976067 :   if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
    2927              :     {
    2928       957303 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2929       957303 :           && ! side_effects_p (XEXP (op0, 0)))
    2930       470610 :         return simplify_gen_binary (op, mode,
    2931              :                                     simplify_gen_binary (code, mode,
    2932              :                                                          XEXP (op0, 1),
    2933              :                                                          XEXP (op1, 1)),
    2934       470610 :                                     XEXP (op0, 0));
    2935       486693 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
    2936       486693 :           && ! side_effects_p (XEXP (op0, 0)))
    2937           55 :         return simplify_gen_binary (op, mode,
    2938              :                                     simplify_gen_binary (code, mode,
    2939              :                                                          XEXP (op0, 1),
    2940              :                                                          XEXP (op1, 0)),
    2941           55 :                                     XEXP (op0, 0));
    2942       486638 :       if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
    2943       486638 :           && ! side_effects_p (XEXP (op0, 1)))
    2944       246314 :         return simplify_gen_binary (op, mode,
    2945              :                                     simplify_gen_binary (code, mode,
    2946              :                                                          XEXP (op0, 0),
    2947              :                                                          XEXP (op1, 1)),
    2948       246314 :                                     XEXP (op0, 1));
    2949              :     }
    2950              : 
    2951              :   return NULL_RTX;
    2952              : }
    2953              : 
    2954              : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
    2955              :    should be reversed.
    2956              : 
    2957              :    If the rotate should not be reversed, return FALSE.
    2958              : 
    2959              :    LEFT indicates if this is a rotate left or a rotate right.  */
    2960              : 
    2961              : bool
    2962       136012 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
    2963              : {
    2964       136012 :   if (!CONST_INT_P (op1))
    2965              :     return false;
    2966              : 
    2967              :   /* Some targets may only be able to rotate by a constant
    2968              :      in one direction.  So we need to query the optab interface
    2969              :      to see what is possible.  */
    2970       104470 :   optab binoptab = left ? rotl_optab : rotr_optab;
    2971        45580 :   optab re_binoptab = left ? rotr_optab : rotl_optab;
    2972       104470 :   enum insn_code icode = optab_handler (binoptab, mode);
    2973       104470 :   enum insn_code re_icode = optab_handler (re_binoptab, mode);
    2974              : 
    2975              :   /* If the target can not support the reversed optab, then there
    2976              :      is nothing to do.  */
    2977       104470 :   if (re_icode == CODE_FOR_nothing)
    2978              :     return false;
    2979              : 
    2980              :   /* If the target does not support the requested rotate-by-immediate,
    2981              :      then we want to try reversing the rotate.  We also want to try
    2982              :      reversing to minimize the count.  */
    2983       102012 :   if ((icode == CODE_FOR_nothing)
    2984       102012 :       || (!insn_operand_matches (icode, 2, op1))
    2985       510060 :       || (IN_RANGE (INTVAL (op1),
    2986              :                     GET_MODE_UNIT_PRECISION (mode) / 2 + left,
    2987              :                     GET_MODE_UNIT_PRECISION (mode) - 1)))
    2988        14289 :     return (insn_operand_matches (re_icode, 2, op1));
    2989              :   return false;
    2990              : }
    2991              : 
    2992              : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
    2993              :    and return the expression to be shifted in SHIFT_OPND and the shift amount
    2994              :    in SHIFT_AMNT.  This is primarily used to group handling of ASHIFT (X, CST)
    2995              :    and (PLUS (X, X)) in one place.  If the expression is not equivalent to an
    2996              :    ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL.  */
    2997              : 
    2998              : static bool
    2999    529406151 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
    3000              : {
    3001    529406151 :   if (GET_CODE (x) == ASHIFT)
    3002              :     {
    3003     13721580 :       *shift_opnd = XEXP (x, 0);
    3004     13721580 :       *shift_amnt = XEXP (x, 1);
    3005     13721580 :       return true;
    3006              :     }
    3007    515684571 :   if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
    3008              :     {
    3009        11687 :       *shift_opnd = XEXP (x, 0);
    3010        11687 :       *shift_amnt = CONST1_RTX (GET_MODE (x));
    3011        11687 :       return true;
    3012              :     }
    3013    515672884 :   *shift_opnd = NULL_RTX;
    3014    515672884 :   *shift_amnt = NULL_RTX;
    3015    515672884 :   return false;
    3016              : }
    3017              : 
    3018              : /* OP0 and OP1 are combined under an operation of mode MODE that can
    3019              :    potentially result in a ROTATE expression.  Analyze the OP0 and OP1
    3020              :    and return the resulting ROTATE expression if so.  Return NULL otherwise.
    3021              :    This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
    3022              :    C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
    3023              :    (X << C1) and (C >> C2) would be OP0 and OP1.  */
    3024              : 
    3025              : static rtx
    3026    267255590 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
    3027              : {
    3028              :   /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3029              :      mode size to (rotate A CX).  */
    3030              : 
    3031    267255590 :   rtx opleft = op0;
    3032    267255590 :   rtx opright = op1;
    3033    267255590 :   rtx ashift_opnd, ashift_amnt;
    3034              :   /* In some cases the ASHIFT is not a direct ASHIFT.  Look deeper and extract
    3035              :      the relevant operands here.  */
    3036    267255590 :   bool ashift_op_p
    3037    267255590 :     = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
    3038              : 
    3039    267255590 :   if (ashift_op_p
    3040    265640581 :      || GET_CODE (op1) == SUBREG)
    3041              :     {
    3042              :       opleft = op1;
    3043              :       opright = op0;
    3044              :     }
    3045              :   else
    3046              :     {
    3047    262150561 :       opright = op1;
    3048    262150561 :       opleft = op0;
    3049    262150561 :       ashift_op_p
    3050    262150561 :         = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
    3051              :     }
    3052              : 
    3053     13733267 :   if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
    3054    265678044 :       && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
    3055              :     {
    3056         9423 :       rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
    3057         9423 :       rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
    3058              : 
    3059         5611 :       if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
    3060        15034 :           && (INTVAL (leftcst) + INTVAL (rightcst)
    3061         5611 :               == GET_MODE_UNIT_PRECISION (mode)))
    3062         5084 :         return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
    3063              :     }
    3064              : 
    3065              :   /* Same, but for ashift that has been "simplified" to a wider mode
    3066              :      by simplify_shift_const.  */
    3067    267250506 :   scalar_int_mode int_mode, inner_mode;
    3068              : 
    3069    267250506 :   if (GET_CODE (opleft) == SUBREG
    3070    272177565 :       && is_a <scalar_int_mode> (mode, &int_mode)
    3071      4921975 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
    3072              :                                  &inner_mode)
    3073      4890787 :       && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
    3074       163890 :       && GET_CODE (opright) == LSHIFTRT
    3075         1105 :       && GET_CODE (XEXP (opright, 0)) == SUBREG
    3076          237 :       && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
    3077          470 :       && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
    3078          221 :       && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
    3079          221 :                       SUBREG_REG (XEXP (opright, 0)))
    3080            5 :       && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
    3081            5 :       && CONST_INT_P (XEXP (opright, 1))
    3082    267250506 :       && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
    3083            5 :             + INTVAL (XEXP (opright, 1))
    3084            5 :          == GET_MODE_PRECISION (int_mode)))
    3085            1 :         return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
    3086              :                                XEXP (SUBREG_REG (opleft), 1));
    3087              :   return NULL_RTX;
    3088              : }
    3089              : 
    3090              : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
    3091              :    and the pattern can be simplified (there are no side effects).  */
    3092              : 
    3093              : static bool
    3094     38703036 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
    3095              : {
    3096              :   /* Remove SUBREG from OP0 and OP1, if needed.  */
    3097     38703036 :   if (GET_CODE (op0) == SUBREG
    3098      7150842 :       && GET_CODE (op1) == SUBREG
    3099       306695 :       && subreg_lowpart_p (op0)
    3100     39008327 :       && subreg_lowpart_p (op1))
    3101              :     {
    3102       305282 :       op0 = XEXP (op0, 0);
    3103       305282 :       op1 = XEXP (op1, 0);
    3104              :     }
    3105              : 
    3106              :   /* Check for the pattern (OP (plus (A - 1)) (neg A)).  */
    3107     38703036 :   if (((GET_CODE (op1) == NEG
    3108         3744 :         && GET_CODE (op0) == PLUS
    3109         2199 :         && XEXP (op0, 1) == CONSTM1_RTX (mode))
    3110     38702378 :        || (GET_CODE (op0) == NEG
    3111        80410 :            && GET_CODE (op1) == PLUS
    3112            0 :            && XEXP (op1, 1) == CONSTM1_RTX (mode)))
    3113          658 :       && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3114     38703038 :       && !side_effects_p (XEXP (op0, 0)))
    3115              :     return true;
    3116              :   return false;
    3117              : }
    3118              : 
    3119              : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
    3120              :    non-paradoxical.  */
    3121              : 
    3122              : static bool
    3123     73372018 : non_paradoxical_subreg_not_p (rtx op)
    3124              : {
    3125     73372018 :   return GET_CODE (op) == SUBREG
    3126      8676402 :          && !paradoxical_subreg_p (op)
    3127     76282896 :          && GET_CODE (SUBREG_REG (op)) == NOT;
    3128              : }
    3129              : 
    3130              : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
    3131              :    (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
    3132              :    opportunities to combine another binary logical operation with NOT.  */
    3133              : 
    3134              : static rtx
    3135     36687181 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
    3136              : {
    3137     36687181 :   rtx opn = NULL_RTX;
    3138     36687181 :   if (non_paradoxical_subreg_not_p (op0))
    3139              :     opn = op0;
    3140     36684837 :   else if (non_paradoxical_subreg_not_p (op1))
    3141              :     opn = op1;
    3142              : 
    3143         2367 :   if (opn == NULL_RTX)
    3144              :     return NULL_RTX;
    3145              : 
    3146         4734 :   rtx new_subreg = simplify_gen_subreg (mode,
    3147              :                                         XEXP (SUBREG_REG (opn), 0),
    3148         2367 :                                         GET_MODE (SUBREG_REG (opn)),
    3149         2367 :                                         SUBREG_BYTE (opn));
    3150              : 
    3151         2367 :   if (!new_subreg)
    3152              :     return NULL_RTX;
    3153              : 
    3154         2312 :   rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
    3155         2312 :   if (opn == op0)
    3156         2289 :     return simplify_gen_binary (binop, mode, new_not, op1);
    3157              :   else
    3158           23 :     return simplify_gen_binary (binop, mode, op0, new_not);
    3159              : }
    3160              : 
    3161              : /* Return TRUE iff NOP is a negated form of OP, or vice-versa.  */
    3162              : static bool
    3163      6592322 : negated_ops_p (rtx nop, rtx op)
    3164              : {
    3165              :   /* Explicit negation.  */
    3166      6592322 :   if (GET_CODE (nop) == NOT
    3167      6592322 :       && rtx_equal_p (XEXP (nop, 0), op))
    3168              :     return true;
    3169      6588948 :   if (GET_CODE (op) == NOT
    3170      6588948 :       && rtx_equal_p (XEXP (op, 0), nop))
    3171              :     return true;
    3172              : 
    3173              :   /* (~C <r A) is a negated form of (C << A) if C == 1.  */
    3174      6588362 :   if (GET_CODE (op) == ASHIFT
    3175      1392745 :       && GET_CODE (nop) == ROTATE
    3176            0 :       && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
    3177            0 :       && CONST_INT_P (XEXP (nop, 0))
    3178            0 :       && INTVAL (XEXP (nop, 0)) == -2
    3179      6588362 :       && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
    3180              :     return true;
    3181      6588362 :   if (GET_CODE (nop) == ASHIFT
    3182       156842 :       && GET_CODE (op) == ROTATE
    3183            0 :       && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
    3184            0 :       && CONST_INT_P (XEXP (nop, 0))
    3185            0 :       && INTVAL (XEXP (nop, 0)) == -2
    3186      6588362 :       && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
    3187              :     return true;
    3188              : 
    3189              :   /* ??? Should we consider rotations of C and ~C by the same amount?  */
    3190              : 
    3191              :   return false;
    3192              : }
    3193              : 
    3194              : /* Subroutine of simplify_binary_operation.  Simplify a binary operation
    3195              :    CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
    3196              :    OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
    3197              :    actual constants.  */
    3198              : 
    3199              : rtx
    3200    446429538 : simplify_context::simplify_binary_operation_1 (rtx_code code,
    3201              :                                                machine_mode mode,
    3202              :                                                rtx op0, rtx op1,
    3203              :                                                rtx trueop0, rtx trueop1)
    3204              : {
    3205    446429538 :   rtx tem, reversed, elt0, elt1;
    3206    446429538 :   HOST_WIDE_INT val;
    3207    446429538 :   scalar_int_mode int_mode, inner_mode;
    3208    446429538 :   poly_int64 offset;
    3209              : 
    3210              :   /* Even if we can't compute a constant result,
    3211              :      there are some cases worth simplifying.  */
    3212              : 
    3213    446429538 :   switch (code)
    3214              :     {
    3215    257246637 :     case PLUS:
    3216              :       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
    3217              :          when x is NaN, infinite, or finite and nonzero.  They aren't
    3218              :          when x is -0 and the rounding mode is not towards -infinity,
    3219              :          since (-0) + 0 is then 0.  */
    3220    510591408 :       if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
    3221    510591396 :           && trueop1 == CONST0_RTX (mode))
    3222              :         return op0;
    3223              : 
    3224              :       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
    3225              :          transformations are safe even for IEEE.  */
    3226    255784005 :       if (GET_CODE (op0) == NEG)
    3227        55583 :         return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
    3228    255728422 :       else if (GET_CODE (op1) == NEG)
    3229         7542 :         return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
    3230              : 
    3231              :       /* (~a) + 1 -> -a */
    3232    255720880 :       if (INTEGRAL_MODE_P (mode)
    3233    250911701 :           && GET_CODE (op0) == NOT
    3234      1169401 :           && trueop1 == const1_rtx)
    3235         3803 :         return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
    3236              : 
    3237              :       /* Handle both-operands-constant cases.  We can only add
    3238              :          CONST_INTs to constants since the sum of relocatable symbols
    3239              :          can't be handled by most assemblers.  Don't add CONST_INT
    3240              :          to CONST_INT since overflow won't be computed properly if wider
    3241              :          than HOST_BITS_PER_WIDE_INT.  */
    3242              : 
    3243    255717077 :       if ((GET_CODE (op0) == CONST
    3244    255717077 :            || GET_CODE (op0) == SYMBOL_REF
    3245    253133889 :            || GET_CODE (op0) == LABEL_REF)
    3246    255717077 :           && poly_int_rtx_p (op1, &offset))
    3247      2582219 :         return plus_constant (mode, op0, offset);
    3248    253134858 :       else if ((GET_CODE (op1) == CONST
    3249    253134858 :                 || GET_CODE (op1) == SYMBOL_REF
    3250    248897384 :                 || GET_CODE (op1) == LABEL_REF)
    3251    253134858 :                && poly_int_rtx_p (op0, &offset))
    3252            0 :         return plus_constant (mode, op1, offset);
    3253              : 
    3254              :       /* See if this is something like X * C - X or vice versa or
    3255              :          if the multiplication is written as a shift.  If so, we can
    3256              :          distribute and make a new multiply, shift, or maybe just
    3257              :          have X (if C is 2 in the example above).  But don't make
    3258              :          something more expensive than we had before.  */
    3259              : 
    3260    253134858 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3261              :         {
    3262    246162011 :           rtx lhs = op0, rhs = op1;
    3263              : 
    3264    246162011 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3265    246162011 :           wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3266              : 
    3267    246162011 :           if (GET_CODE (lhs) == NEG)
    3268              :             {
    3269            0 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3270            0 :               lhs = XEXP (lhs, 0);
    3271              :             }
    3272    246162011 :           else if (GET_CODE (lhs) == MULT
    3273      9818289 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3274              :             {
    3275      8710721 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3276      8710721 :               lhs = XEXP (lhs, 0);
    3277              :             }
    3278    237451290 :           else if (GET_CODE (lhs) == ASHIFT
    3279     11086791 :                    && CONST_INT_P (XEXP (lhs, 1))
    3280     11015040 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3281    248466318 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3282              :             {
    3283     11015028 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3284     22030056 :                                             GET_MODE_PRECISION (int_mode));
    3285     11015028 :               lhs = XEXP (lhs, 0);
    3286              :             }
    3287              : 
    3288    246162011 :           if (GET_CODE (rhs) == NEG)
    3289              :             {
    3290            0 :               coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3291            0 :               rhs = XEXP (rhs, 0);
    3292              :             }
    3293    246162011 :           else if (GET_CODE (rhs) == MULT
    3294       294478 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3295              :             {
    3296       190015 :               coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
    3297       190015 :               rhs = XEXP (rhs, 0);
    3298              :             }
    3299    245971996 :           else if (GET_CODE (rhs) == ASHIFT
    3300       532273 :                    && CONST_INT_P (XEXP (rhs, 1))
    3301       522496 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3302    246494492 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3303              :             {
    3304       522496 :               coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3305      1044992 :                                             GET_MODE_PRECISION (int_mode));
    3306       522496 :               rhs = XEXP (rhs, 0);
    3307              :             }
    3308              : 
    3309              :           /* Keep PLUS of 2 volatile memory references.  */
    3310    246162011 :           if (rtx_equal_p (lhs, rhs)
    3311    246162011 :               && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
    3312              :             {
    3313       821538 :               rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
    3314       821538 :               rtx coeff;
    3315       821538 :               bool speed = optimize_function_for_speed_p (cfun);
    3316              : 
    3317       821538 :               coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
    3318              : 
    3319       821538 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3320       821538 :               return (set_src_cost (tem, int_mode, speed)
    3321       821538 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3322              :             }
    3323              : 
    3324              :           /* Optimize (X - 1) * Y + Y to X * Y.  */
    3325    245340473 :           lhs = op0;
    3326    245340473 :           rhs = op1;
    3327    245340473 :           if (GET_CODE (op0) == MULT)
    3328              :             {
    3329      9764659 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3330       644231 :                     && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
    3331      9720428 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3332        53525 :                        && XEXP (XEXP (op0, 0), 1) == const1_rtx))
    3333      9808890 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3334           46 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3335      9764613 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3336         1342 :                          && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
    3337      9764547 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3338          339 :                             && XEXP (XEXP (op0, 1), 1) == const1_rtx))
    3339      9764679 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3340            0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3341              :             }
    3342    235575814 :           else if (GET_CODE (op1) == MULT)
    3343              :             {
    3344       122591 :               if (((GET_CODE (XEXP (op1, 0)) == PLUS
    3345           46 :                     && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
    3346       122587 :                    || (GET_CODE (XEXP (op1, 0)) == MINUS
    3347           27 :                        && XEXP (XEXP (op1, 0), 1) == const1_rtx))
    3348       122595 :                   && rtx_equal_p (XEXP (op1, 1), op0))
    3349            0 :                 rhs = XEXP (XEXP (op1, 0), 0);
    3350       122591 :               else if (((GET_CODE (XEXP (op1, 1)) == PLUS
    3351            0 :                          && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
    3352       122591 :                         || (GET_CODE (XEXP (op1, 1)) == MINUS
    3353            0 :                             && XEXP (XEXP (op1, 1), 1) == const1_rtx))
    3354       122591 :                        && rtx_equal_p (XEXP (op1, 0), op0))
    3355            0 :                 rhs = XEXP (XEXP (op1, 1), 0);
    3356              :             }
    3357    245340473 :           if (lhs != op0 || rhs != op1)
    3358           46 :             return simplify_gen_binary (MULT, int_mode, lhs, rhs);
    3359    246162011 :         }
    3360              : 
    3361              :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
    3362    252313274 :       if (CONST_SCALAR_INT_P (op1)
    3363    191450020 :           && GET_CODE (op0) == XOR
    3364        18653 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3365    252323429 :           && mode_signbit_p (mode, op1))
    3366          121 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3367              :                                     simplify_gen_binary (XOR, mode, op1,
    3368          121 :                                                          XEXP (op0, 1)));
    3369              : 
    3370              :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
    3371              :          2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
    3372    252313153 :       if (CONST_SCALAR_INT_P (op1)
    3373    191449899 :           && GET_CODE (op0) == XOR
    3374        18532 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3375        10034 :           && nonzero_bits (XEXP (op0, 0), mode) == 1
    3376          189 :           && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
    3377    252313153 :           && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
    3378            0 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3379              :                                     simplify_gen_binary (XOR, mode, op1,
    3380            0 :                                                          XEXP (op0, 1)));
    3381              : 
    3382              :       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
    3383    252313153 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3384    252310673 :           && GET_CODE (op0) == MULT
    3385    262445892 :           && GET_CODE (XEXP (op0, 0)) == NEG)
    3386              :         {
    3387         5538 :           rtx in1, in2;
    3388              : 
    3389         5538 :           in1 = XEXP (XEXP (op0, 0), 0);
    3390         5538 :           in2 = XEXP (op0, 1);
    3391         5538 :           return simplify_gen_binary (MINUS, mode, op1,
    3392              :                                       simplify_gen_binary (MULT, mode,
    3393         5538 :                                                            in1, in2));
    3394              :         }
    3395              : 
    3396              :       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
    3397              :          C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
    3398              :          is 1.  */
    3399    252307615 :       if (COMPARISON_P (op0)
    3400      1248507 :           && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
    3401      1248507 :               || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
    3402    252364337 :           && (reversed = reversed_comparison (op0, mode)))
    3403        56373 :         return
    3404        56373 :           simplify_gen_unary (NEG, mode, reversed, mode);
    3405              : 
    3406              :       /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3407              :          mode size to (rotate A CX).  */
    3408    252251242 :       if ((tem = simplify_rotate_op (op0, op1, mode)))
    3409              :         return tem;
    3410              : 
    3411              :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3412              :          simplify this by the associative law.
    3413              :          Don't use the associative law for floating point.
    3414              :          The inaccuracy makes it nonassociative,
    3415              :          and subtle programs can break if operations are associated.  */
    3416              : 
    3417    252249772 :       if (INTEGRAL_MODE_P (mode)
    3418    247440642 :           && (plus_minus_operand_p (op0)
    3419    213764988 :               || plus_minus_operand_p (op1))
    3420     34778982 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3421              :         return tem;
    3422              : 
    3423              :       /* Reassociate floating point addition only when the user
    3424              :          specifies associative math operations.  */
    3425    218184747 :       if (FLOAT_MODE_P (mode)
    3426      4809130 :           && flag_associative_math)
    3427              :         {
    3428       907263 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3429       907263 :           if (tem)
    3430              :             return tem;
    3431              :         }
    3432              : 
    3433              :       /* Handle vector series.  */
    3434    218170914 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3435              :         {
    3436      1998407 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3437      1998407 :           if (tem)
    3438              :             return tem;
    3439              :         }
    3440              :       break;
    3441              : 
    3442              :     case COMPARE:
    3443              :       break;
    3444              : 
    3445     42998041 :     case MINUS:
    3446              :       /* We can't assume x-x is 0 even with non-IEEE floating point,
    3447              :          but since it is zero except in very strange circumstances, we
    3448              :          will treat it as zero with -ffinite-math-only.  */
    3449     42998041 :       if (rtx_equal_p (trueop0, trueop1)
    3450       217204 :           && ! side_effects_p (op0)
    3451     43214003 :           && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
    3452       213507 :         return CONST0_RTX (mode);
    3453              : 
    3454              :       /* Change subtraction from zero into negation.  (0 - x) is the
    3455              :          same as -x when x is NaN, infinite, or finite and nonzero.
    3456              :          But if the mode has signed zeros, and does not round towards
    3457              :          -infinity, then 0 - 0 is 0, not -0.  */
    3458     42784534 :       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
    3459       339767 :         return simplify_gen_unary (NEG, mode, op1, mode);
    3460              : 
    3461              :       /* (-1 - a) is ~a, unless the expression contains symbolic
    3462              :          constants, in which case not retaining additions and
    3463              :          subtractions could cause invalid assembly to be produced.  */
    3464     42444767 :       if (trueop0 == CONSTM1_RTX (mode)
    3465     42444767 :           && !contains_symbolic_reference_p (op1))
    3466       542373 :         return simplify_gen_unary (NOT, mode, op1, mode);
    3467              : 
    3468              :       /* Subtracting 0 has no effect unless the mode has signalling NaNs,
    3469              :          or has signed zeros and supports rounding towards -infinity.
    3470              :          In such a case, 0 - 0 is -0.  */
    3471     42629754 :       if (!(HONOR_SIGNED_ZEROS (mode)
    3472       727360 :             && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    3473     41901244 :           && !HONOR_SNANS (mode)
    3474     83803602 :           && trueop1 == CONST0_RTX (mode))
    3475              :         return op0;
    3476              : 
    3477              :       /* See if this is something like X * C - X or vice versa or
    3478              :          if the multiplication is written as a shift.  If so, we can
    3479              :          distribute and make a new multiply, shift, or maybe just
    3480              :          have X (if C is 2 in the example above).  But don't make
    3481              :          something more expensive than we had before.  */
    3482              : 
    3483     40958008 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3484              :         {
    3485     39602765 :           rtx lhs = op0, rhs = op1;
    3486              : 
    3487     39602765 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3488     39602765 :           wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3489              : 
    3490     39602765 :           if (GET_CODE (lhs) == NEG)
    3491              :             {
    3492        70587 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3493        70587 :               lhs = XEXP (lhs, 0);
    3494              :             }
    3495     39532178 :           else if (GET_CODE (lhs) == MULT
    3496       192123 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3497              :             {
    3498        73016 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3499        73016 :               lhs = XEXP (lhs, 0);
    3500              :             }
    3501     39459162 :           else if (GET_CODE (lhs) == ASHIFT
    3502       333708 :                    && CONST_INT_P (XEXP (lhs, 1))
    3503       330506 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3504     39789647 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3505              :             {
    3506       330485 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3507       660970 :                                             GET_MODE_PRECISION (int_mode));
    3508       330485 :               lhs = XEXP (lhs, 0);
    3509              :             }
    3510              : 
    3511     39602765 :           if (GET_CODE (rhs) == NEG)
    3512              :             {
    3513        11068 :               negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3514        11068 :               rhs = XEXP (rhs, 0);
    3515              :             }
    3516     39591697 :           else if (GET_CODE (rhs) == MULT
    3517       150758 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3518              :             {
    3519        97543 :               negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
    3520        97543 :               rhs = XEXP (rhs, 0);
    3521              :             }
    3522     39494154 :           else if (GET_CODE (rhs) == ASHIFT
    3523       381931 :                    && CONST_INT_P (XEXP (rhs, 1))
    3524       381424 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3525     39875578 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3526              :             {
    3527       381424 :               negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3528       762848 :                                                GET_MODE_PRECISION (int_mode));
    3529       381424 :               negcoeff1 = -negcoeff1;
    3530       381424 :               rhs = XEXP (rhs, 0);
    3531              :             }
    3532              : 
    3533     39602765 :           if (rtx_equal_p (lhs, rhs))
    3534              :             {
    3535       101656 :               rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
    3536       101656 :               rtx coeff;
    3537       101656 :               bool speed = optimize_function_for_speed_p (cfun);
    3538              : 
    3539       101656 :               coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
    3540              : 
    3541       101656 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3542       101656 :               return (set_src_cost (tem, int_mode, speed)
    3543       101656 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3544              :             }
    3545              : 
    3546              :           /* Optimize (X + 1) * Y - Y to X * Y.  */
    3547     39501109 :           lhs = op0;
    3548     39501109 :           if (GET_CODE (op0) == MULT)
    3549              :             {
    3550       191649 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3551         4821 :                     && XEXP (XEXP (op0, 0), 1) == const1_rtx)
    3552       190101 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3553         1641 :                        && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
    3554       193197 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3555            2 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3556       191647 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3557           30 :                          && XEXP (XEXP (op0, 1), 1) == const1_rtx)
    3558       191641 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3559           84 :                             && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
    3560       191653 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3561            0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3562              :             }
    3563     39501109 :           if (lhs != op0)
    3564            2 :             return simplify_gen_binary (MULT, int_mode, lhs, op1);
    3565     39602765 :         }
    3566              : 
    3567              :       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
    3568     40856350 :       if (GET_CODE (op1) == NEG)
    3569        11030 :         return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
    3570              : 
    3571              :       /* (-x - c) may be simplified as (-c - x).  */
    3572     40845320 :       if (GET_CODE (op0) == NEG
    3573        74713 :           && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
    3574              :         {
    3575          617 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    3576          617 :           if (tem)
    3577          617 :             return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
    3578              :         }
    3579              : 
    3580     40844703 :       if ((GET_CODE (op0) == CONST
    3581     40844703 :            || GET_CODE (op0) == SYMBOL_REF
    3582     35887771 :            || GET_CODE (op0) == LABEL_REF)
    3583     40844703 :           && poly_int_rtx_p (op1, &offset))
    3584        51522 :         return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
    3585              : 
    3586              :       /* Don't let a relocatable value get a negative coeff.  */
    3587     40793181 :       if (is_a <scalar_int_mode> (mode)
    3588     39437969 :           && poly_int_rtx_p (op1)
    3589     47711249 :           && GET_MODE (op0) != VOIDmode)
    3590      6918068 :         return simplify_gen_binary (PLUS, mode,
    3591              :                                     op0,
    3592      6918068 :                                     neg_poly_int_rtx (mode, op1));
    3593              : 
    3594              :       /* (x - (x & y)) -> (x & ~y) */
    3595     33875113 :       if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
    3596              :         {
    3597       264829 :           if (rtx_equal_p (op0, XEXP (op1, 0)))
    3598              :             {
    3599          512 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
    3600          256 :                                         GET_MODE (XEXP (op1, 1)));
    3601          256 :               return simplify_gen_binary (AND, mode, op0, tem);
    3602              :             }
    3603       264573 :           if (rtx_equal_p (op0, XEXP (op1, 1)))
    3604              :             {
    3605         2266 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
    3606         1133 :                                         GET_MODE (XEXP (op1, 0)));
    3607         1133 :               return simplify_gen_binary (AND, mode, op0, tem);
    3608              :             }
    3609              :         }
    3610              : 
    3611              :       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
    3612              :          by reversing the comparison code if valid.  */
    3613     33873724 :       if (STORE_FLAG_VALUE == 1
    3614     33873724 :           && trueop0 == const1_rtx
    3615      1114639 :           && COMPARISON_P (op1)
    3616     33979575 :           && (reversed = reversed_comparison (op1, mode)))
    3617              :         return reversed;
    3618              : 
    3619              :       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
    3620     33767896 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3621     33766545 :           && GET_CODE (op1) == MULT
    3622     34018362 :           && GET_CODE (XEXP (op1, 0)) == NEG)
    3623              :         {
    3624          165 :           rtx in1, in2;
    3625              : 
    3626          165 :           in1 = XEXP (XEXP (op1, 0), 0);
    3627          165 :           in2 = XEXP (op1, 1);
    3628          165 :           return simplify_gen_binary (PLUS, mode,
    3629              :                                       simplify_gen_binary (MULT, mode,
    3630              :                                                            in1, in2),
    3631          165 :                                       op0);
    3632              :         }
    3633              : 
    3634              :       /* Canonicalize (minus (neg A) (mult B C)) to
    3635              :          (minus (mult (neg B) C) A).  */
    3636     33767731 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3637     33766380 :           && GET_CODE (op1) == MULT
    3638     34018032 :           && GET_CODE (op0) == NEG)
    3639              :         {
    3640          663 :           rtx in1, in2;
    3641              : 
    3642          663 :           in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
    3643          663 :           in2 = XEXP (op1, 1);
    3644          663 :           return simplify_gen_binary (MINUS, mode,
    3645              :                                       simplify_gen_binary (MULT, mode,
    3646              :                                                            in1, in2),
    3647          663 :                                       XEXP (op0, 0));
    3648              :         }
    3649              : 
    3650              :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3651              :          simplify this by the associative law.  This will, for example,
    3652              :          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
    3653              :          Don't use the associative law for floating point.
    3654              :          The inaccuracy makes it nonassociative,
    3655              :          and subtle programs can break if operations are associated.  */
    3656              : 
    3657     33767068 :       if (INTEGRAL_MODE_P (mode)
    3658     32919173 :           && (plus_minus_operand_p (op0)
    3659     30153942 :               || plus_minus_operand_p (op1))
    3660      3960445 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3661              :         return tem;
    3662              : 
    3663              :       /* Handle vector series.  */
    3664     29952065 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3665              :         {
    3666       484219 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3667       484219 :           if (tem)
    3668              :             return tem;
    3669              :         }
    3670              :       break;
    3671              : 
    3672     12195858 :     case MULT:
    3673     12195858 :       if (trueop1 == constm1_rtx)
    3674        33372 :         return simplify_gen_unary (NEG, mode, op0, mode);
    3675              : 
    3676     12162486 :       if (GET_CODE (op0) == NEG)
    3677              :         {
    3678        34322 :           rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
    3679              :           /* If op1 is a MULT as well and simplify_unary_operation
    3680              :              just moved the NEG to the second operand, simplify_gen_binary
    3681              :              below could through simplify_associative_operation move
    3682              :              the NEG around again and recurse endlessly.  */
    3683        34322 :           if (temp
    3684         2547 :               && GET_CODE (op1) == MULT
    3685            0 :               && GET_CODE (temp) == MULT
    3686            0 :               && XEXP (op1, 0) == XEXP (temp, 0)
    3687            0 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3688            0 :               && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
    3689              :             temp = NULL_RTX;
    3690              :           if (temp)
    3691         2547 :             return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
    3692              :         }
    3693     12159939 :       if (GET_CODE (op1) == NEG)
    3694              :         {
    3695          904 :           rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
    3696              :           /* If op0 is a MULT as well and simplify_unary_operation
    3697              :              just moved the NEG to the second operand, simplify_gen_binary
    3698              :              below could through simplify_associative_operation move
    3699              :              the NEG around again and recurse endlessly.  */
    3700          904 :           if (temp
    3701          419 :               && GET_CODE (op0) == MULT
    3702          301 :               && GET_CODE (temp) == MULT
    3703          301 :               && XEXP (op0, 0) == XEXP (temp, 0)
    3704            6 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3705            5 :               && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
    3706              :             temp = NULL_RTX;
    3707              :           if (temp)
    3708          414 :             return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
    3709              :         }
    3710              : 
    3711              :       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
    3712              :          x is NaN, since x * 0 is then also NaN.  Nor is it valid
    3713              :          when the mode has signed zeros, since multiplying a negative
    3714              :          number by 0 will give -0, not 0.  */
    3715     12159525 :       if (!HONOR_NANS (mode)
    3716     11198703 :           && !HONOR_SIGNED_ZEROS (mode)
    3717     11198260 :           && trueop1 == CONST0_RTX (mode)
    3718     12201486 :           && ! side_effects_p (op0))
    3719              :         return op1;
    3720              : 
    3721              :       /* In IEEE floating point, x*1 is not equivalent to x for
    3722              :          signalling NaNs.  */
    3723     12118808 :       if (!HONOR_SNANS (mode)
    3724     12118808 :           && trueop1 == CONST1_RTX (mode))
    3725              :         return op0;
    3726              : 
    3727              :       /* Convert multiply by constant power of two into shift.  */
    3728     11603024 :       if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
    3729              :         {
    3730      6280258 :           val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
    3731      6280258 :           if (val >= 0)
    3732      3000758 :             return simplify_gen_binary (ASHIFT, mode, op0,
    3733      3000758 :                                         gen_int_shift_amount (mode, val));
    3734              :         }
    3735              : 
    3736              :       /* x*2 is x+x and x*(-1) is -x */
    3737      8602266 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    3738       167876 :           && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
    3739       167876 :           && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
    3740       167592 :           && GET_MODE (op0) == mode)
    3741              :         {
    3742       167592 :           const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    3743              : 
    3744       167592 :           if (real_equal (d1, &dconst2))
    3745          624 :             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
    3746              : 
    3747       166968 :           if (!HONOR_SNANS (mode)
    3748       166968 :               && real_equal (d1, &dconstm1))
    3749           24 :             return simplify_gen_unary (NEG, mode, op0, mode);
    3750              :         }
    3751              : 
    3752              :       /* Optimize -x * -x as x * x.  */
    3753      8601618 :       if (FLOAT_MODE_P (mode)
    3754      1379490 :           && GET_CODE (op0) == NEG
    3755         7986 :           && GET_CODE (op1) == NEG
    3756            0 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3757            0 :           && !side_effects_p (XEXP (op0, 0)))
    3758            0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3759              : 
    3760              :       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
    3761      8601618 :       if (SCALAR_FLOAT_MODE_P (mode)
    3762      1089954 :           && GET_CODE (op0) == ABS
    3763         1293 :           && GET_CODE (op1) == ABS
    3764            0 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3765      8601618 :           && !side_effects_p (XEXP (op0, 0)))
    3766            0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3767              : 
    3768              :       /* Reassociate multiplication, but for floating point MULTs
    3769              :          only when the user specifies unsafe math optimizations.  */
    3770      8601618 :       if (! FLOAT_MODE_P (mode)
    3771      1379490 :           || flag_unsafe_math_optimizations)
    3772              :         {
    3773      7641918 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3774      7641918 :           if (tem)
    3775              :             return tem;
    3776              :         }
    3777              :       break;
    3778              : 
    3779     14836433 :     case IOR:
    3780     14836433 :       if (trueop1 == CONST0_RTX (mode))
    3781              :         return op0;
    3782     14052571 :       if (INTEGRAL_MODE_P (mode)
    3783     13777935 :           && trueop1 == CONSTM1_RTX (mode)
    3784         9608 :           && !side_effects_p (op0))
    3785              :         return op1;
    3786     14042963 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    3787              :         return op0;
    3788              :       /* A | (~A) -> -1 */
    3789        74585 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    3790     14024316 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    3791           11 :           && ! side_effects_p (op0)
    3792     14024338 :           && GET_MODE_CLASS (mode) != MODE_CC)
    3793           11 :         return CONSTM1_RTX (mode);
    3794              : 
    3795              :       /* IOR of two single bit bitfields extracted from the same object.
    3796              :          Bitfields are represented as an AND based extraction */
    3797     14024316 :       if (GET_CODE (op0) == AND
    3798      3972655 :           && GET_CODE (op1) == AND
    3799              :           /* Verify both AND operands are logical right shifts. */
    3800       283799 :           && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    3801         1588 :           && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
    3802              :           /* Verify both bitfields are extracted from the same object. */
    3803           54 :           && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
    3804              :           /* Verify both fields are a single bit (could be generalized). */
    3805           54 :           && XEXP (op0, 1) == CONST1_RTX (mode)
    3806            0 :           && XEXP (op1, 1) == CONST1_RTX (mode)
    3807              :           /* Verify bit positions (for cases with variable bit position). */
    3808            0 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3809            0 :           && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
    3810              :         {
    3811            0 :           unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
    3812            0 :           unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
    3813            0 :           unsigned HOST_WIDE_INT mask
    3814            0 :             = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
    3815              : 
    3816            0 :           rtx m = GEN_INT (mask);
    3817            0 :           rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
    3818            0 :           t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
    3819            0 :           return t;
    3820              :         }
    3821              : 
    3822              :       /* IOR of multiple single bit bitfields extracted from the same object
    3823              :          (building on previous case).
    3824              :          First bitfield is represented as an AND based extraction, as done
    3825              :                 above. Second represented as NE based extraction, from
    3826              :                 output above. */
    3827     14024316 :       if (GET_CODE (op0) == AND
    3828      3972655 :           && GET_CODE (op1) == NE
    3829              :           /* Verify AND operand is logical right shift. */
    3830         3953 :           && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    3831              :           /* Verify NE operand is an AND (based on output above). */
    3832           86 :           && GET_CODE (XEXP (op1, 0)) == AND
    3833              :           /* Verify both bitfields are extracted from the same object. */
    3834            0 :           && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
    3835              :           /* Verify masking is with a single bit and that we have a NE 0
    3836              :              comparison for the other operand.  */
    3837            0 :           && XEXP (op0, 1) == CONST1_RTX (mode)
    3838            0 :           && XEXP (op1, 1) == CONST0_RTX (mode)
    3839              :           /* Verify bit position. */
    3840            0 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    3841              :         {
    3842            0 :           unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
    3843            0 :           unsigned HOST_WIDE_INT mask
    3844            0 :             = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
    3845              : 
    3846            0 :           rtx m = GEN_INT (mask);
    3847            0 :           rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
    3848            0 :           t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
    3849            0 :           return t;
    3850              :         }
    3851              : 
    3852              :       /* Convert (ior (plus (A - 1)) (neg A)) to -1.  */
    3853     14024316 :       if (match_plus_neg_pattern (op0, op1, mode))
    3854            0 :         return CONSTM1_RTX (mode);
    3855              : 
    3856              :       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
    3857     14024316 :       if (CONST_INT_P (op1)
    3858      3470196 :           && HWI_COMPUTABLE_MODE_P (mode)
    3859      3416602 :           && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
    3860     14389191 :           && !side_effects_p (op0))
    3861              :         return op1;
    3862              : 
    3863              :       /* Canonicalize (X & C1) | C2.  */
    3864     13659441 :       if (GET_CODE (op0) == AND
    3865      3964051 :           && CONST_INT_P (trueop1)
    3866       654995 :           && CONST_INT_P (XEXP (op0, 1)))
    3867              :         {
    3868       487465 :           HOST_WIDE_INT mask = GET_MODE_MASK (mode);
    3869       487465 :           HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
    3870       487465 :           HOST_WIDE_INT c2 = INTVAL (trueop1);
    3871              : 
    3872              :           /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2.  */
    3873       487465 :           if ((c1 & c2) == c1
    3874       487465 :               && !side_effects_p (XEXP (op0, 0)))
    3875              :             return trueop1;
    3876              : 
    3877              :           /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
    3878       487445 :           if (((c1|c2) & mask) == mask)
    3879        70760 :             return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
    3880              : 
    3881              :           /* If (C1|C2) has a single bit clear, then adjust C1 so that
    3882              :              when split it'll match a single bit clear style insn.
    3883              : 
    3884              :              This could have been done with a target dependent splitter, but
    3885              :              then every target with single bit manipulation insns would need
    3886              :              to implement such splitters.  */
    3887       416685 :           if (exact_log2 (~(c1 | c2)) >= 0)
    3888              :             {
    3889        59461 :               rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
    3890        59461 :               temp = gen_rtx_IOR (mode, temp, trueop1);
    3891        59461 :               return temp;
    3892              :             }
    3893              :         }
    3894              : 
    3895              :       /* Convert (A & B) | A to A.  */
    3896     13529200 :       if (GET_CODE (op0) == AND
    3897      3833810 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    3898      3833699 :               || rtx_equal_p (XEXP (op0, 1), op1))
    3899         3787 :           && ! side_effects_p (XEXP (op0, 0))
    3900     13532987 :           && ! side_effects_p (XEXP (op0, 1)))
    3901              :         return op1;
    3902              : 
    3903              :       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3904              :          mode size to (rotate A CX).  */
    3905     13525413 :       tem = simplify_rotate_op (op0, op1, mode);
    3906     13525413 :       if (tem)
    3907              :         return tem;
    3908              : 
    3909              :       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
    3910              :          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
    3911              :          the PLUS does not affect any of the bits in OP1: then we can do
    3912              :          the IOR as a PLUS and we can associate.  This is valid if OP1
    3913              :          can be safely shifted left C bits.  */
    3914     13523178 :       if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
    3915         6153 :           && GET_CODE (XEXP (op0, 0)) == PLUS
    3916          141 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3917           87 :           && CONST_INT_P (XEXP (op0, 1))
    3918           87 :           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
    3919              :         {
    3920           87 :           int count = INTVAL (XEXP (op0, 1));
    3921           87 :           HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
    3922              : 
    3923           87 :           if (mask >> count == INTVAL (trueop1)
    3924           80 :               && trunc_int_for_mode (mask, mode) == mask
    3925          154 :               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
    3926            0 :             return simplify_gen_binary (ASHIFTRT, mode,
    3927              :                                         plus_constant (mode, XEXP (op0, 0),
    3928            0 :                                                        mask),
    3929              :                                         XEXP (op0, 1));
    3930              :         }
    3931              : 
    3932              :       /* The following happens with bitfield merging.
    3933              :          (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
    3934     13523178 :       if (GET_CODE (op0) == AND
    3935      3830023 :           && GET_CODE (op1) == AND
    3936       283799 :           && CONST_INT_P (XEXP (op0, 1))
    3937       117023 :           && CONST_INT_P (XEXP (op1, 1))
    3938       111590 :           && (INTVAL (XEXP (op0, 1))
    3939       111590 :               == ~INTVAL (XEXP (op1, 1))))
    3940              :         {
    3941              :           /* The IOR/XOR may be on both sides.  */
    3942        32105 :           rtx top0 = NULL_RTX, top1 = NULL_RTX;
    3943        32105 :           if (GET_CODE (XEXP (op1, 0)) == IOR
    3944        32105 :               || GET_CODE (XEXP (op1, 0)) == XOR)
    3945              :             top0 = op0, top1 = op1;
    3946        31986 :           else if (GET_CODE (XEXP (op0, 0)) == IOR
    3947        31986 :                    || GET_CODE (XEXP (op0, 0)) == XOR)
    3948            3 :             top0 = op1, top1 = op0;
    3949        32105 :           if (top0 && top1)
    3950              :             {
    3951              :               /* X may be on either side of the inner IOR/XOR.  */
    3952          122 :               rtx tem = NULL_RTX;
    3953          122 :               if (rtx_equal_p (XEXP (top0, 0),
    3954          122 :                                XEXP (XEXP (top1, 0), 0)))
    3955           76 :                 tem = XEXP (XEXP (top1, 0), 1);
    3956           46 :               else if (rtx_equal_p (XEXP (top0, 0),
    3957           46 :                                     XEXP (XEXP (top1, 0), 1)))
    3958           13 :                 tem = XEXP (XEXP (top1, 0), 0);
    3959           89 :               if (tem)
    3960           89 :                 return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
    3961              :                                             mode, XEXP (top0, 0),
    3962              :                                             simplify_gen_binary
    3963           89 :                                               (AND, mode, tem, XEXP (top1, 1)));
    3964              :             }
    3965              :         }
    3966              : 
    3967              :       /* Convert (ior (and A C) (and B C)) into (and (ior A B) C).  */
    3968     13523089 :       if (GET_CODE (op0) == GET_CODE (op1)
    3969      3364999 :           && (GET_CODE (op0) == AND
    3970              :               || GET_CODE (op0) == IOR
    3971      3364999 :               || GET_CODE (op0) == LSHIFTRT
    3972      3080341 :               || GET_CODE (op0) == ASHIFTRT
    3973      3080211 :               || GET_CODE (op0) == ASHIFT
    3974      3063132 :               || GET_CODE (op0) == ROTATE
    3975      3063132 :               || GET_CODE (op0) == ROTATERT))
    3976              :         {
    3977       301867 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    3978       301867 :           if (tem)
    3979              :             return tem;
    3980              :         }
    3981              : 
    3982              :       /* Convert (ior (and (not A) B) A) into A | B.  */
    3983     13435256 :       if (GET_CODE (op0) == AND
    3984     13435256 :           && negated_ops_p (XEXP (op0, 0), op1))
    3985         3942 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    3986              : 
    3987              :       /* op0/op1 may have a common term which in turn may allow simplification
    3988              :          of the the outer IOR.  There are likely other cases we should
    3989              :          handle for the outer code as well as the form of the operands.  */
    3990     13431314 :       tem = simplify_ior_with_common_term (mode, op0, op1);
    3991     13431314 :       if (tem)
    3992              :         return tem;
    3993              : 
    3994              :       /* IOR is commutative and we can't rely on canonicalization at this point,
    3995              :          so try again to simplify with the operands reversed.  */
    3996     13431221 :       tem = simplify_ior_with_common_term (mode, op1, op0);
    3997     13431221 :       if (tem)
    3998              :         return tem;
    3999              : 
    4000     13431221 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4001     13431221 :       if (tem)
    4002              :         return tem;
    4003              : 
    4004     13431216 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4005     13431216 :       if (tem)
    4006              :         return tem;
    4007              : 
    4008     13431183 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4009     13431183 :       if (tem)
    4010              :         return tem;
    4011              : 
    4012     13160488 :       tem = simplify_logical_relational_operation (code, mode, op0, op1);
    4013     13160488 :       if (tem)
    4014              :         return tem;
    4015              :       break;
    4016              : 
    4017      1751404 :     case XOR:
    4018      1751404 :       if (trueop1 == CONST0_RTX (mode))
    4019              :         return op0;
    4020      1695105 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4021        25046 :         return simplify_gen_unary (NOT, mode, op0, mode);
    4022      1670059 :       if (rtx_equal_p (trueop0, trueop1)
    4023         2483 :           && ! side_effects_p (op0)
    4024      1672538 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4025         2479 :          return CONST0_RTX (mode);
    4026              : 
    4027              :       /* Canonicalize XOR of the most significant bit to PLUS.  */
    4028      1667580 :       if (CONST_SCALAR_INT_P (op1)
    4029      1667580 :           && mode_signbit_p (mode, op1))
    4030        40030 :         return simplify_gen_binary (PLUS, mode, op0, op1);
    4031              :       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
    4032      1627550 :       if (CONST_SCALAR_INT_P (op1)
    4033       486869 :           && GET_CODE (op0) == PLUS
    4034         2509 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    4035      1629144 :           && mode_signbit_p (mode, XEXP (op0, 1)))
    4036          189 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    4037              :                                     simplify_gen_binary (XOR, mode, op1,
    4038          189 :                                                          XEXP (op0, 1)));
    4039              : 
    4040              :       /* If we are XORing two things that have no bits in common,
    4041              :          convert them into an IOR.  This helps to detect rotation encoded
    4042              :          using those methods and possibly other simplifications.  */
    4043              : 
    4044      1627361 :       if (HWI_COMPUTABLE_MODE_P (mode)
    4045      1334627 :           && (nonzero_bits (op0, mode)
    4046      1334627 :               & nonzero_bits (op1, mode)) == 0)
    4047        10901 :         return (simplify_gen_binary (IOR, mode, op0, op1));
    4048              : 
    4049              :       /* Convert (xor (plus (A - 1)) (neg A)) to -1.  */
    4050      1616460 :       if (match_plus_neg_pattern (op0, op1, mode))
    4051            0 :         return CONSTM1_RTX (mode);
    4052              : 
    4053              :       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
    4054              :          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
    4055              :          (NOT y).  */
    4056      1616460 :       {
    4057      1616460 :         int num_negated = 0;
    4058              : 
    4059      1616460 :         if (GET_CODE (op0) == NOT)
    4060          888 :           num_negated++, op0 = XEXP (op0, 0);
    4061      1616460 :         if (GET_CODE (op1) == NOT)
    4062           64 :           num_negated++, op1 = XEXP (op1, 0);
    4063              : 
    4064           64 :         if (num_negated == 2)
    4065            0 :           return simplify_gen_binary (XOR, mode, op0, op1);
    4066      1616460 :         else if (num_negated == 1)
    4067          952 :           return simplify_gen_unary (NOT, mode,
    4068              :                                      simplify_gen_binary (XOR, mode, op0, op1),
    4069          952 :                                      mode);
    4070              :       }
    4071              : 
    4072              :       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
    4073              :          correspond to a machine insn or result in further simplifications
    4074              :          if B is a constant.  */
    4075              : 
    4076      1615508 :       if (GET_CODE (op0) == AND
    4077       173617 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4078      1640139 :           && ! side_effects_p (op1))
    4079        24631 :         return simplify_gen_binary (AND, mode,
    4080              :                                     simplify_gen_unary (NOT, mode,
    4081              :                                                         XEXP (op0, 0), mode),
    4082        24631 :                                     op1);
    4083              : 
    4084      1590877 :       else if (GET_CODE (op0) == AND
    4085       148986 :                && rtx_equal_p (XEXP (op0, 0), op1)
    4086      1592134 :                && ! side_effects_p (op1))
    4087         1257 :         return simplify_gen_binary (AND, mode,
    4088              :                                     simplify_gen_unary (NOT, mode,
    4089              :                                                         XEXP (op0, 1), mode),
    4090         1257 :                                     op1);
    4091              : 
    4092              :       /* Given (xor (ior (xor A B) C) D), where B, C and D are
    4093              :          constants, simplify to (xor (ior A C) (B&~C)^D), canceling
    4094              :          out bits inverted twice and not set by C.  Similarly, given
    4095              :          (xor (and (xor A B) C) D), simplify without inverting C in
    4096              :          the xor operand: (xor (and A C) (B&C)^D).
    4097              :       */
    4098      1589620 :       else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
    4099       168543 :                && GET_CODE (XEXP (op0, 0)) == XOR
    4100         7181 :                && CONST_INT_P (op1)
    4101          212 :                && CONST_INT_P (XEXP (op0, 1))
    4102          158 :                && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    4103              :         {
    4104           38 :           enum rtx_code op = GET_CODE (op0);
    4105           38 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4106           38 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4107           38 :           rtx c = XEXP (op0, 1);
    4108           38 :           rtx d = op1;
    4109           38 :           HOST_WIDE_INT bval = INTVAL (b);
    4110           38 :           HOST_WIDE_INT cval = INTVAL (c);
    4111           38 :           HOST_WIDE_INT dval = INTVAL (d);
    4112           38 :           HOST_WIDE_INT xcval;
    4113              : 
    4114           38 :           if (op == IOR)
    4115            8 :             xcval = ~cval;
    4116              :           else
    4117              :             xcval = cval;
    4118              : 
    4119           38 :           return simplify_gen_binary (XOR, mode,
    4120              :                                       simplify_gen_binary (op, mode, a, c),
    4121           38 :                                       gen_int_mode ((bval & xcval) ^ dval,
    4122              :                                                     mode));
    4123              :         }
    4124              : 
    4125              :       /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
    4126              :          we can transform like this:
    4127              :             (A&B)^C == ~(A&B)&C | ~C&(A&B)
    4128              :                     == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
    4129              :                     == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
    4130              :          Attempt a few simplifications when B and C are both constants.  */
    4131      1589582 :       if (GET_CODE (op0) == AND
    4132       147699 :           && CONST_INT_P (op1)
    4133        13011 :           && CONST_INT_P (XEXP (op0, 1)))
    4134              :         {
    4135        11241 :           rtx a = XEXP (op0, 0);
    4136        11241 :           rtx b = XEXP (op0, 1);
    4137        11241 :           rtx c = op1;
    4138        11241 :           HOST_WIDE_INT bval = INTVAL (b);
    4139        11241 :           HOST_WIDE_INT cval = INTVAL (c);
    4140              : 
    4141              :           /* Instead of computing ~A&C, we compute its negated value,
    4142              :              ~(A|~C).  If it yields -1, ~A&C is zero, so we can
    4143              :              optimize for sure.  If it does not simplify, we still try
    4144              :              to compute ~A&C below, but since that always allocates
    4145              :              RTL, we don't try that before committing to returning a
    4146              :              simplified expression.  */
    4147        11241 :           rtx n_na_c = simplify_binary_operation (IOR, mode, a,
    4148              :                                                   GEN_INT (~cval));
    4149              : 
    4150        11241 :           if ((~cval & bval) == 0)
    4151              :             {
    4152          620 :               rtx na_c = NULL_RTX;
    4153          620 :               if (n_na_c)
    4154            0 :                 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
    4155              :               else
    4156              :                 {
    4157              :                   /* If ~A does not simplify, don't bother: we don't
    4158              :                      want to simplify 2 operations into 3, and if na_c
    4159              :                      were to simplify with na, n_na_c would have
    4160              :                      simplified as well.  */
    4161          620 :                   rtx na = simplify_unary_operation (NOT, mode, a, mode);
    4162          620 :                   if (na)
    4163            0 :                     na_c = simplify_gen_binary (AND, mode, na, c);
    4164              :                 }
    4165              : 
    4166              :               /* Try to simplify ~A&C | ~B&C.  */
    4167            0 :               if (na_c != NULL_RTX)
    4168            0 :                 return simplify_gen_binary (IOR, mode, na_c,
    4169            0 :                                             gen_int_mode (~bval & cval, mode));
    4170              :             }
    4171              :           else
    4172              :             {
    4173              :               /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
    4174        10621 :               if (n_na_c == CONSTM1_RTX (mode))
    4175              :                 {
    4176            0 :                   rtx a_nc_b = simplify_gen_binary (AND, mode, a,
    4177            0 :                                                     gen_int_mode (~cval & bval,
    4178              :                                                                   mode));
    4179            0 :                   return simplify_gen_binary (IOR, mode, a_nc_b,
    4180            0 :                                               gen_int_mode (~bval & cval,
    4181              :                                                             mode));
    4182              :                 }
    4183              :             }
    4184              :         }
    4185              : 
    4186              :       /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
    4187              :          do (ior (and A ~C) (and B C)) which is a machine instruction on some
    4188              :          machines, and also has shorter instruction path length.  */
    4189      1589582 :       if (GET_CODE (op0) == AND
    4190       147699 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4191         6693 :           && CONST_INT_P (XEXP (op0, 1))
    4192      1593026 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
    4193              :         {
    4194            7 :           rtx a = trueop1;
    4195            7 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4196            7 :           rtx c = XEXP (op0, 1);
    4197            7 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4198            7 :           rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
    4199            7 :           rtx bc = simplify_gen_binary (AND, mode, b, c);
    4200            7 :           return simplify_gen_binary (IOR, mode, a_nc, bc);
    4201              :         }
    4202              :       /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C))  */
    4203      1589575 :       else if (GET_CODE (op0) == AND
    4204       147692 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4205         6686 :           && CONST_INT_P (XEXP (op0, 1))
    4206      1593012 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
    4207              :         {
    4208            8 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4209            8 :           rtx b = trueop1;
    4210            8 :           rtx c = XEXP (op0, 1);
    4211            8 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4212            8 :           rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
    4213            8 :           rtx ac = simplify_gen_binary (AND, mode, a, c);
    4214            8 :           return simplify_gen_binary (IOR, mode, ac, b_nc);
    4215              :         }
    4216              : 
    4217              :       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
    4218              :          comparison if STORE_FLAG_VALUE is 1.  */
    4219      1589567 :       if (STORE_FLAG_VALUE == 1
    4220      1589567 :           && trueop1 == const1_rtx
    4221       200786 :           && COMPARISON_P (op0)
    4222      1595837 :           && (reversed = reversed_comparison (op0, mode)))
    4223              :         return reversed;
    4224              : 
    4225              :       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
    4226              :          is (lt foo (const_int 0)), so we can perform the above
    4227              :          simplification if STORE_FLAG_VALUE is 1.  */
    4228              : 
    4229      1583305 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4230              :           && STORE_FLAG_VALUE == 1
    4231      1294958 :           && trueop1 == const1_rtx
    4232       194524 :           && GET_CODE (op0) == LSHIFTRT
    4233        35348 :           && CONST_INT_P (XEXP (op0, 1))
    4234        35348 :           && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    4235        34509 :         return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
    4236              : 
    4237              :       /* (xor (comparison foo bar) (const_int sign-bit))
    4238              :          when STORE_FLAG_VALUE is the sign bit.  */
    4239      1548796 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4240      1260449 :           && val_signbit_p (int_mode, STORE_FLAG_VALUE)
    4241            0 :           && trueop1 == const_true_rtx
    4242            0 :           && COMPARISON_P (op0)
    4243            0 :           && (reversed = reversed_comparison (op0, int_mode)))
    4244              :         return reversed;
    4245              : 
    4246              :       /* Convert (xor (and A C) (and B C)) into (and (xor A B) C).  */
    4247      1548796 :       if (GET_CODE (op0) == GET_CODE (op1)
    4248       540178 :           && (GET_CODE (op0) == AND
    4249       540178 :               || GET_CODE (op0) == LSHIFTRT
    4250       467700 :               || GET_CODE (op0) == ASHIFTRT
    4251       467604 :               || GET_CODE (op0) == ASHIFT
    4252       467470 :               || GET_CODE (op0) == ROTATE
    4253       467363 :               || GET_CODE (op0) == ROTATERT))
    4254              :         {
    4255        73355 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4256        73355 :           if (tem)
    4257              :             return tem;
    4258              :         }
    4259              : 
    4260              :       /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    4261              :          mode size to (rotate A CX).  */
    4262      1478935 :       tem = simplify_rotate_op (op0, op1, mode);
    4263      1478935 :       if (tem)
    4264              :         return tem;
    4265              : 
    4266              :       /* Convert (xor (and (not A) B) A) into A | B.  */
    4267      1477555 :       if (GET_CODE (op0) == AND
    4268      1477555 :           && negated_ops_p (XEXP (op0, 0), op1))
    4269            1 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4270              : 
    4271              :       /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
    4272              :          into B | (1 << A).  */
    4273      1477554 :       if (SHIFT_COUNT_TRUNCATED
    4274              :           && GET_CODE (op0) == AND
    4275              :           && GET_CODE (XEXP (op0, 0)) == ROTATE
    4276              :           && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4277              :           && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
    4278              :           && GET_CODE (op1) == ASHIFT
    4279              :           && CONST_INT_P (XEXP (op1, 0))
    4280              :           && INTVAL (XEXP (op1, 0)) == 1
    4281              :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
    4282              :           && !side_effects_p (XEXP (op1, 1)))
    4283              :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4284              : 
    4285      1477554 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4286      1477554 :       if (tem)
    4287              :         return tem;
    4288              : 
    4289      1477553 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4290      1477553 :       if (tem)
    4291              :         return tem;
    4292              : 
    4293      1477553 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4294      1477553 :       if (tem)
    4295              :         return tem;
    4296              :       break;
    4297              : 
    4298     24099028 :     case AND:
    4299     24099028 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    4300              :         return trueop1;
    4301     23854999 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4302              :         return op0;
    4303     23471487 :       if (HWI_COMPUTABLE_MODE_P (mode))
    4304              :         {
    4305              :           /* When WORD_REGISTER_OPERATIONS is true, we need to know the
    4306              :              nonzero bits in WORD_MODE rather than MODE.  */
    4307     20583883 :           scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
    4308     20583883 :           if (WORD_REGISTER_OPERATIONS
    4309              :               && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    4310              :             tmode = word_mode;
    4311     20583883 :           HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
    4312     20583883 :           HOST_WIDE_INT nzop1;
    4313     20583883 :           if (CONST_INT_P (trueop1))
    4314              :             {
    4315     17576378 :               HOST_WIDE_INT val1 = INTVAL (trueop1);
    4316              :               /* If we are turning off bits already known off in OP0, we need
    4317              :                  not do an AND.  */
    4318     17576378 :               if ((nzop0 & ~val1) == 0)
    4319       401947 :                 return op0;
    4320              : 
    4321              :               /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
    4322              :                  (and (lshiftrt (subreg X) shift) mask).
    4323              : 
    4324              :                  Keeps shift and AND in the same mode, improving recognition.
    4325              :                  Only applied when subreg is a lowpart, shift is valid,
    4326              :                  and no precision is lost.  */
    4327     17258714 :               if (SUBREG_P (op0)
    4328      6184029 :                   && subreg_lowpart_p (op0)
    4329      6167113 :                   && !paradoxical_subreg_p (op0)
    4330       915909 :                   && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    4331              :                   /* simplify_subreg asserts the object being accessed is not
    4332              :                      VOIDmode or BLKmode.  We may have a REG_EQUAL note which
    4333              :                      is not simplified and the source operand is a constant,
    4334              :                      and thus VOIDmode.  Guard against that.  */
    4335       113811 :                   && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
    4336       113761 :                   && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
    4337       113761 :                   && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4338       113761 :                   && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    4339        93576 :                   && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
    4340        93576 :                   && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
    4341     17352289 :                   && ((INTVAL (XEXP (XEXP (op0, 0), 1))
    4342        93575 :                       + floor_log2 (val1))
    4343     17258714 :                       < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
    4344              :                 {
    4345        10590 :                   tem = XEXP (XEXP (op0, 0), 0);
    4346        10590 :                   if (SUBREG_P (tem))
    4347              :                     {
    4348          265 :                       if (subreg_lowpart_p (tem))
    4349          265 :                         tem = SUBREG_REG (tem);
    4350              :                       else
    4351              :                         tem = NULL_RTX;
    4352              :                     }
    4353          265 :                   if (tem != NULL_RTX)
    4354              :                     {
    4355        10590 :                       offset = subreg_lowpart_offset (mode, GET_MODE (tem));
    4356        10590 :                       tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
    4357        10590 :                                                  offset);
    4358        10590 :                       if (tem)
    4359              :                         {
    4360        10590 :                           unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
    4361        10590 :                           rtx shiftamtrtx = gen_int_shift_amount (mode,
    4362        10590 :                                                                   shiftamt);
    4363        10590 :                           op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
    4364              :                                                      shiftamtrtx);
    4365        10590 :                           return simplify_gen_binary (AND, mode, op0, op1);
    4366              :                         }
    4367              :                     }
    4368              :                 }
    4369              :             }
    4370     20255629 :           nzop1 = nonzero_bits (trueop1, mode);
    4371              :           /* If we are clearing all the nonzero bits, the result is zero.  */
    4372     20255629 :           if ((nzop1 & nzop0) == 0
    4373     20255629 :               && !side_effects_p (op0) && !side_effects_p (op1))
    4374        73693 :             return CONST0_RTX (mode);
    4375              :         }
    4376     23072888 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
    4377     23072884 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4378              :         return op0;
    4379              :       /* A & (~A) -> 0 */
    4380       624189 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    4381     23062305 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    4382         3937 :           && ! side_effects_p (op0)
    4383     23070132 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4384         3936 :         return CONST0_RTX (mode);
    4385              : 
    4386              :       /* Convert (and (plus (A - 1)) (neg A)) to 0.  */
    4387     23062260 :       if (match_plus_neg_pattern (op0, op1, mode))
    4388            2 :         return CONST0_RTX (mode);
    4389              : 
    4390              :       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
    4391              :          there are no nonzero bits of C outside of X's mode.  */
    4392     46124516 :       if ((GET_CODE (op0) == SIGN_EXTEND
    4393     23062258 :            || GET_CODE (op0) == ZERO_EXTEND)
    4394        93862 :           && CONST_SCALAR_INT_P (trueop1)
    4395        79885 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4396        79885 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4397     23142143 :           && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
    4398        79885 :                         GET_MODE_PRECISION (int_mode))
    4399     23142143 :               & rtx_mode_t (trueop1, mode)) == 0)
    4400              :         {
    4401        78041 :           machine_mode imode = GET_MODE (XEXP (op0, 0));
    4402        78041 :           tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
    4403        78041 :           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
    4404        78041 :           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
    4405              :         }
    4406              : 
    4407              :       /* Transform (and (truncate X) C) into (truncate (and X C)).  This way
    4408              :          we might be able to further simplify the AND with X and potentially
    4409              :          remove the truncation altogether.  */
    4410     22984217 :       if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
    4411              :         {
    4412            6 :           rtx x = XEXP (op0, 0);
    4413            6 :           machine_mode xmode = GET_MODE (x);
    4414            6 :           tem = simplify_gen_binary (AND, xmode, x,
    4415            6 :                                      gen_int_mode (INTVAL (trueop1), xmode));
    4416            6 :           return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
    4417              :         }
    4418              : 
    4419              :       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
    4420     22984211 :       if (GET_CODE (op0) == IOR
    4421      1386090 :           && CONST_INT_P (trueop1)
    4422       216974 :           && CONST_INT_P (XEXP (op0, 1)))
    4423              :         {
    4424       133909 :           HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
    4425       133909 :           return simplify_gen_binary (IOR, mode,
    4426              :                                       simplify_gen_binary (AND, mode,
    4427              :                                                            XEXP (op0, 0), op1),
    4428       133909 :                                       gen_int_mode (tmp, mode));
    4429              :         }
    4430              : 
    4431              :       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
    4432              :          insn (and may simplify more).  */
    4433     22850302 :       if (GET_CODE (op0) == XOR
    4434       138991 :           && rtx_equal_p (XEXP (op0, 0), op1)
    4435     22851743 :           && ! side_effects_p (op1))
    4436         1441 :         return simplify_gen_binary (AND, mode,
    4437              :                                     simplify_gen_unary (NOT, mode,
    4438              :                                                         XEXP (op0, 1), mode),
    4439         1441 :                                     op1);
    4440              : 
    4441     22848861 :       if (GET_CODE (op0) == XOR
    4442       137550 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4443     22851882 :           && ! side_effects_p (op1))
    4444         3021 :         return simplify_gen_binary (AND, mode,
    4445              :                                     simplify_gen_unary (NOT, mode,
    4446              :                                                         XEXP (op0, 0), mode),
    4447         3021 :                                     op1);
    4448              : 
    4449              :       /* Similarly for (~(A ^ B)) & A.  */
    4450     22845840 :       if (GET_CODE (op0) == NOT
    4451       620299 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4452         3491 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
    4453     22845894 :           && ! side_effects_p (op1))
    4454           54 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
    4455              : 
    4456     22845786 :       if (GET_CODE (op0) == NOT
    4457       620245 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4458         3437 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
    4459     22845823 :           && ! side_effects_p (op1))
    4460           37 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
    4461              : 
    4462              :       /* Convert (A | B) & A to A.  */
    4463     22845749 :       if (GET_CODE (op0) == IOR
    4464      1252181 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    4465      1251656 :               || rtx_equal_p (XEXP (op0, 1), op1))
    4466          726 :           && ! side_effects_p (XEXP (op0, 0))
    4467     22846475 :           && ! side_effects_p (XEXP (op0, 1)))
    4468              :         return op1;
    4469              : 
    4470              :       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
    4471              :          ((A & N) + B) & M -> (A + B) & M
    4472              :          Similarly if (N & M) == 0,
    4473              :          ((A | N) + B) & M -> (A + B) & M
    4474              :          and for - instead of + and/or ^ instead of |.
    4475              :          Also, if (N & M) == 0, then
    4476              :          (A +- N) & M -> A & M.  */
    4477     22845023 :       if (CONST_INT_P (trueop1)
    4478     17055615 :           && HWI_COMPUTABLE_MODE_P (mode)
    4479     17034666 :           && ~UINTVAL (trueop1)
    4480     17034666 :           && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
    4481     33833482 :           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
    4482              :         {
    4483       968198 :           rtx pmop[2];
    4484       968198 :           int which;
    4485              : 
    4486       968198 :           pmop[0] = XEXP (op0, 0);
    4487       968198 :           pmop[1] = XEXP (op0, 1);
    4488              : 
    4489       968198 :           if (CONST_INT_P (pmop[1])
    4490       511710 :               && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
    4491       167981 :             return simplify_gen_binary (AND, mode, pmop[0], op1);
    4492              : 
    4493      2423820 :           for (which = 0; which < 2; which++)
    4494              :             {
    4495      1615880 :               tem = pmop[which];
    4496      1615880 :               switch (GET_CODE (tem))
    4497              :                 {
    4498        11626 :                 case AND:
    4499        11626 :                   if (CONST_INT_P (XEXP (tem, 1))
    4500        10116 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
    4501              :                       == UINTVAL (trueop1))
    4502         7584 :                     pmop[which] = XEXP (tem, 0);
    4503              :                   break;
    4504         1728 :                 case IOR:
    4505         1728 :                 case XOR:
    4506         1728 :                   if (CONST_INT_P (XEXP (tem, 1))
    4507          699 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
    4508          139 :                     pmop[which] = XEXP (tem, 0);
    4509              :                   break;
    4510              :                 default:
    4511              :                   break;
    4512              :                 }
    4513              :             }
    4514              : 
    4515       807940 :           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
    4516              :             {
    4517         7723 :               tem = simplify_gen_binary (GET_CODE (op0), mode,
    4518              :                                          pmop[0], pmop[1]);
    4519         7723 :               return simplify_gen_binary (code, mode, tem, op1);
    4520              :             }
    4521              :         }
    4522              : 
    4523              :       /* (and X (ior (not X) Y) -> (and X Y) */
    4524     22677042 :       if (GET_CODE (op1) == IOR
    4525       940441 :           && GET_CODE (XEXP (op1, 0)) == NOT
    4526     22682392 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
    4527            0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
    4528              : 
    4529              :       /* (and (ior (not X) Y) X) -> (and X Y) */
    4530     22677042 :       if (GET_CODE (op0) == IOR
    4531      1251455 :           && GET_CODE (XEXP (op0, 0)) == NOT
    4532     22727628 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
    4533            6 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
    4534              : 
    4535              :       /* (and X (ior Y (not X)) -> (and X Y) */
    4536     22677036 :       if (GET_CODE (op1) == IOR
    4537       940441 :           && GET_CODE (XEXP (op1, 1)) == NOT
    4538     22677375 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
    4539            0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
    4540              : 
    4541              :       /* (and (ior Y (not X)) X) -> (and X Y) */
    4542     22677036 :       if (GET_CODE (op0) == IOR
    4543      1251449 :           && GET_CODE (XEXP (op0, 1)) == NOT
    4544     22685862 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
    4545           43 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
    4546              : 
    4547              :       /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
    4548     22676993 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4549     22676993 :           && negated_ops_p (op1, XEXP (op0, 1)))
    4550           13 :         return simplify_gen_binary (AND, mode, XEXP (op0, 0),
    4551              :                                     simplify_gen_unary (NOT, mode,
    4552              :                                                         XEXP (op0, 1),
    4553           13 :                                                         mode));
    4554              :       /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
    4555     22676980 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4556     22676980 :           && negated_ops_p (op1, XEXP (op0, 0)))
    4557            4 :         return simplify_gen_binary (AND, mode, XEXP (op0, 1),
    4558              :                                     simplify_gen_unary (NOT, mode,
    4559              :                                                         XEXP (op0, 0),
    4560            4 :                                                         mode));
    4561              : 
    4562              :       /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C).  */
    4563     22676976 :       if (GET_CODE (op0) == GET_CODE (op1)
    4564      2147630 :           && (GET_CODE (op0) == AND
    4565              :               || GET_CODE (op0) == IOR
    4566      2147630 :               || GET_CODE (op0) == LSHIFTRT
    4567      1207861 :               || GET_CODE (op0) == ASHIFTRT
    4568      1207711 :               || GET_CODE (op0) == ASHIFT
    4569      1207542 :               || GET_CODE (op0) == ROTATE
    4570      1207542 :               || GET_CODE (op0) == ROTATERT))
    4571              :         {
    4572       940088 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4573       940088 :           if (tem)
    4574              :             return tem;
    4575              :         }
    4576              : 
    4577              :       /* (and:v4si
    4578              :            (ashiftrt:v4si A 16)
    4579              :            (const_vector: 0xffff x4))
    4580              :          is just (lshiftrt:v4si A 16).  */
    4581     21778448 :       if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
    4582         4618 :           && (CONST_INT_P (XEXP (op0, 1))
    4583         1948 :               || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
    4584           94 :                   && const_vec_duplicate_p (XEXP (op0, 1))
    4585            0 :                   && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
    4586         2670 :           && GET_CODE (op1) == CONST_VECTOR
    4587     21778473 :           && const_vec_duplicate_p (op1)
    4588     21778515 :           && CONST_INT_P (XVECEXP (op1, 0, 0)))
    4589              :         {
    4590          130 :           unsigned HOST_WIDE_INT shift_count
    4591              :             = (CONST_INT_P (XEXP (op0, 1))
    4592           65 :                ? UINTVAL (XEXP (op0, 1))
    4593            0 :                : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
    4594           65 :           unsigned HOST_WIDE_INT inner_prec
    4595          130 :             = GET_MODE_PRECISION (GET_MODE_INNER (mode));
    4596              : 
    4597              :           /* Avoid UD shift count.  */
    4598           65 :           if (shift_count < inner_prec
    4599           59 :               && (UINTVAL (XVECEXP (op1, 0, 0))
    4600           59 :                   == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
    4601           42 :             return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
    4602              :         }
    4603              : 
    4604     21778406 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4605     21778406 :       if (tem)
    4606              :         return tem;
    4607              : 
    4608     21776100 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4609     21776100 :       if (tem)
    4610              :         return tem;
    4611              : 
    4612     21775879 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4613     21775879 :       if (tem)
    4614              :         return tem;
    4615              :       break;
    4616              : 
    4617       891326 :     case UDIV:
    4618              :       /* 0/x is 0 (or x&0 if x has side-effects).  */
    4619       891326 :       if (trueop0 == CONST0_RTX (mode)
    4620          272 :           && !cfun->can_throw_non_call_exceptions)
    4621              :         {
    4622          272 :           if (side_effects_p (op1))
    4623            0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4624              :           return trueop0;
    4625              :         }
    4626              :       /* x/1 is x.  */
    4627       891054 :       if (trueop1 == CONST1_RTX (mode))
    4628              :         {
    4629       239059 :           tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4630       239059 :           if (tem)
    4631              :             return tem;
    4632              :         }
    4633              :       /* Convert divide by power of two into shift.  */
    4634       651995 :       if (CONST_INT_P (trueop1)
    4635       974535 :           && (val = exact_log2 (UINTVAL (trueop1))) > 0)
    4636       322540 :         return simplify_gen_binary (LSHIFTRT, mode, op0,
    4637       322540 :                                     gen_int_shift_amount (mode, val));
    4638              :       break;
    4639              : 
    4640      1199636 :     case DIV:
    4641              :       /* Handle floating point and integers separately.  */
    4642      1199636 :       if (SCALAR_FLOAT_MODE_P (mode))
    4643              :         {
    4644              :           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
    4645              :              safe for modes with NaNs, since 0.0 / 0.0 will then be
    4646              :              NaN rather than 0.0.  Nor is it safe for modes with signed
    4647              :              zeros, since dividing 0 by a negative number gives -0.0  */
    4648       324910 :           if (trueop0 == CONST0_RTX (mode)
    4649         2800 :               && !HONOR_NANS (mode)
    4650           14 :               && !HONOR_SIGNED_ZEROS (mode)
    4651       324924 :               && ! side_effects_p (op1))
    4652              :             return op0;
    4653              :           /* x/1.0 is x.  */
    4654       324896 :           if (trueop1 == CONST1_RTX (mode)
    4655       324896 :               && !HONOR_SNANS (mode))
    4656              :             return op0;
    4657              : 
    4658       324891 :           if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    4659        26569 :               && trueop1 != CONST0_RTX (mode))
    4660              :             {
    4661        20469 :               const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    4662              : 
    4663              :               /* x/-1.0 is -x.  */
    4664        20469 :               if (real_equal (d1, &dconstm1)
    4665        20469 :                   && !HONOR_SNANS (mode))
    4666            0 :                 return simplify_gen_unary (NEG, mode, op0, mode);
    4667              : 
    4668              :               /* Change FP division by a constant into multiplication.
    4669              :                  Only do this with -freciprocal-math.  */
    4670        20469 :               if (flag_reciprocal_math
    4671        20469 :                   && !real_equal (d1, &dconst0))
    4672              :                 {
    4673            7 :                   REAL_VALUE_TYPE d;
    4674            7 :                   real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
    4675            7 :                   tem = const_double_from_real_value (d, mode);
    4676            7 :                   return simplify_gen_binary (MULT, mode, op0, tem);
    4677              :                 }
    4678              :             }
    4679              :         }
    4680       874726 :       else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    4681              :         {
    4682              :           /* 0/x is 0 (or x&0 if x has side-effects).  */
    4683       852366 :           if (trueop0 == CONST0_RTX (mode)
    4684          979 :               && !cfun->can_throw_non_call_exceptions)
    4685              :             {
    4686          925 :               if (side_effects_p (op1))
    4687            8 :                 return simplify_gen_binary (AND, mode, op1, trueop0);
    4688              :               return trueop0;
    4689              :             }
    4690              :           /* x/1 is x.  */
    4691       851441 :           if (trueop1 == CONST1_RTX (mode))
    4692              :             {
    4693          894 :               tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4694          894 :               if (tem)
    4695              :                 return tem;
    4696              :             }
    4697              :           /* x/-1 is -x.  */
    4698       850547 :           if (trueop1 == CONSTM1_RTX (mode))
    4699              :             {
    4700          503 :               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4701          503 :               if (x)
    4702          503 :                 return simplify_gen_unary (NEG, mode, x, mode);
    4703              :             }
    4704              :         }
    4705              :       break;
    4706              : 
    4707       913446 :     case UMOD:
    4708              :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4709       913446 :       if (trueop0 == CONST0_RTX (mode))
    4710              :         {
    4711          774 :           if (side_effects_p (op1))
    4712            0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4713              :           return trueop0;
    4714              :         }
    4715              :       /* x%1 is 0 (of x&0 if x has side-effects).  */
    4716       912672 :       if (trueop1 == CONST1_RTX (mode))
    4717              :         {
    4718       272644 :           if (side_effects_p (op0))
    4719            0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4720       272644 :           return CONST0_RTX (mode);
    4721              :         }
    4722              :       /* Implement modulus by power of two as AND.  */
    4723       640028 :       if (CONST_INT_P (trueop1)
    4724       946187 :           && exact_log2 (UINTVAL (trueop1)) > 0)
    4725       306159 :         return simplify_gen_binary (AND, mode, op0,
    4726       306159 :                                     gen_int_mode (UINTVAL (trueop1) - 1,
    4727              :                                                   mode));
    4728              :       break;
    4729              : 
    4730       366371 :     case MOD:
    4731              :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4732       366371 :       if (trueop0 == CONST0_RTX (mode))
    4733              :         {
    4734         1205 :           if (side_effects_p (op1))
    4735            8 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4736              :           return trueop0;
    4737              :         }
    4738              :       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
    4739       365166 :       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
    4740              :         {
    4741          744 :           if (side_effects_p (op0))
    4742            0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4743          744 :           return CONST0_RTX (mode);
    4744              :         }
    4745              :       break;
    4746              : 
    4747       128166 :     case ROTATERT:
    4748       128166 :     case ROTATE:
    4749       128166 :       if (trueop1 == CONST0_RTX (mode))
    4750              :         return op0;
    4751              :       /* Canonicalize rotates by constant amount.  If the condition of
    4752              :          reversing direction is met, then reverse the direction. */
    4753              : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
    4754       128076 :       if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
    4755              :         {
    4756        11299 :           int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
    4757        11299 :           rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
    4758        11843 :           return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
    4759              :                                       mode, op0, new_amount_rtx);
    4760              :         }
    4761              : #endif
    4762              :       /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X).  Other combinations
    4763              :          such as SImode with a count of 16 do not correspond to RTL BSWAP
    4764              :          semantics.  */
    4765       116777 :       tem = unwrap_const_vec_duplicate (trueop1);
    4766       116777 :       if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
    4767       116777 :           && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
    4768          504 :         return simplify_gen_unary (BSWAP, mode, op0, mode);
    4769              : 
    4770              :       /* FALLTHRU */
    4771      5248344 :     case ASHIFTRT:
    4772      5248344 :       if (trueop1 == CONST0_RTX (mode))
    4773              :         return op0;
    4774      5246324 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4775              :         return op0;
    4776              :       /* Rotating ~0 always results in ~0.  */
    4777      5246152 :       if (CONST_INT_P (trueop0)
    4778        15044 :           && HWI_COMPUTABLE_MODE_P (mode)
    4779        15016 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4780      5246152 :           && ! side_effects_p (op1))
    4781              :         return op0;
    4782              : 
    4783     31137817 :     canonicalize_shift:
    4784              :       /* Given:
    4785              :          scalar modes M1, M2
    4786              :          scalar constants c1, c2
    4787              :          size (M2) > size (M1)
    4788              :          c1 == size (M2) - size (M1)
    4789              :          optimize:
    4790              :          ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
    4791              :                                  <low_part>)
    4792              :                       (const_int <c2>))
    4793              :          to:
    4794              :          (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
    4795              :                     <low_part>).  */
    4796     31137817 :       if ((code == ASHIFTRT || code == LSHIFTRT)
    4797     11787453 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4798     10995918 :           && SUBREG_P (op0)
    4799      1157367 :           && CONST_INT_P (op1)
    4800      1155147 :           && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
    4801        18537 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
    4802              :                                      &inner_mode)
    4803        18537 :           && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
    4804        36768 :           && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
    4805        18384 :           && (INTVAL (XEXP (SUBREG_REG (op0), 1))
    4806        36768 :               == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
    4807     31155964 :           && subreg_lowpart_p (op0))
    4808              :         {
    4809        18147 :           rtx tmp = gen_int_shift_amount
    4810        18147 :             (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
    4811              : 
    4812              :          /* Combine would usually zero out the value when combining two
    4813              :             local shifts and the range becomes larger or equal to the mode.
    4814              :             However since we fold away one of the shifts here combine won't
    4815              :             see it so we should immediately zero the result if it's out of
    4816              :             range.  */
    4817        18147 :          if (code == LSHIFTRT
    4818        32788 :              && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
    4819            0 :           tmp = const0_rtx;
    4820              :          else
    4821        18147 :            tmp = simplify_gen_binary (code,
    4822              :                                       inner_mode,
    4823        18147 :                                       XEXP (SUBREG_REG (op0), 0),
    4824              :                                       tmp);
    4825              : 
    4826        18147 :           return lowpart_subreg (int_mode, tmp, inner_mode);
    4827              :         }
    4828              : 
    4829     31119670 :       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
    4830              :         {
    4831              :           val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
    4832              :           if (val != INTVAL (op1))
    4833              :             return simplify_gen_binary (code, mode, op0,
    4834              :                                         gen_int_shift_amount (mode, val));
    4835              :         }
    4836              : 
    4837              :       /* Simplify:
    4838              : 
    4839              :            (code:M1
    4840              :              (subreg:M1
    4841              :                ([al]shiftrt:M2
    4842              :                  (subreg:M2
    4843              :                    (ashift:M1 X C1))
    4844              :                  C2))
    4845              :              C3)
    4846              : 
    4847              :          to:
    4848              : 
    4849              :            (code:M1
    4850              :              ([al]shiftrt:M1
    4851              :                (ashift:M1 X C1+N)
    4852              :                C2+N)
    4853              :              C3)
    4854              : 
    4855              :          where M1 is N bits wider than M2.  Optimizing the (subreg:M1 ...)
    4856              :          directly would be arithmetically correct, but restricting the
    4857              :          simplification to shifts by constants is more conservative,
    4858              :          since it is more likely to lead to further simplifications.  */
    4859     31119670 :       if (is_a<scalar_int_mode> (mode, &int_mode)
    4860      5496108 :           && paradoxical_subreg_p (op0)
    4861      5061309 :           && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
    4862      5061223 :           && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
    4863      5061223 :               || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
    4864       141760 :           && CONST_INT_P (op1))
    4865              :         {
    4866       141760 :           auto xcode = GET_CODE (SUBREG_REG (op0));
    4867       141760 :           rtx xop0 = XEXP (SUBREG_REG (op0), 0);
    4868       141760 :           rtx xop1 = XEXP (SUBREG_REG (op0), 1);
    4869       141760 :           if (SUBREG_P (xop0)
    4870        10724 :               && GET_MODE (SUBREG_REG (xop0)) == mode
    4871        10637 :               && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
    4872          594 :               && CONST_INT_P (xop1)
    4873       142354 :               && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
    4874              :             {
    4875          594 :               rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
    4876          594 :               rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
    4877          594 :               if (CONST_INT_P (yop1)
    4878          594 :                   && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
    4879              :                 {
    4880         1188 :                   auto bias = (GET_MODE_BITSIZE (int_mode)
    4881          594 :                                - GET_MODE_BITSIZE (inner_mode));
    4882          594 :                   tem = simplify_gen_binary (ASHIFT, mode, yop0,
    4883          594 :                                              GEN_INT (INTVAL (yop1) + bias));
    4884          594 :                   tem = simplify_gen_binary (xcode, mode, tem,
    4885          594 :                                              GEN_INT (INTVAL (xop1) + bias));
    4886          594 :                   return simplify_gen_binary (code, mode, tem, op1);
    4887              :                 }
    4888              :             }
    4889              :         }
    4890              :       break;
    4891              : 
    4892            0 :     case SS_ASHIFT:
    4893            0 :       if (CONST_INT_P (trueop0)
    4894            0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4895            0 :           && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
    4896            0 :               || mode_signbit_p (mode, trueop0))
    4897            0 :           && ! side_effects_p (op1))
    4898              :         return op0;
    4899            0 :       goto simplify_ashift;
    4900              : 
    4901            0 :     case US_ASHIFT:
    4902            0 :       if (CONST_INT_P (trueop0)
    4903            0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4904            0 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4905            0 :           && ! side_effects_p (op1))
    4906              :         return op0;
    4907              :       /* FALLTHRU */
    4908              : 
    4909     19657728 :     case ASHIFT:
    4910     19657728 : simplify_ashift:
    4911     19657728 :       if (trueop1 == CONST0_RTX (mode))
    4912              :         return op0;
    4913     19498614 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4914              :         return op0;
    4915     19469443 :       if (mem_depth
    4916       235321 :           && code == ASHIFT
    4917       235321 :           && CONST_INT_P (trueop1)
    4918       235313 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4919     19704744 :           && IN_RANGE (UINTVAL (trueop1),
    4920              :                        1, GET_MODE_PRECISION (int_mode) - 1))
    4921              :         {
    4922       235301 :           auto c = (wi::one (GET_MODE_PRECISION (int_mode))
    4923       235301 :                     << UINTVAL (trueop1));
    4924       235301 :           rtx new_op1 = immed_wide_int_const (c, int_mode);
    4925       235301 :           return simplify_gen_binary (MULT, int_mode, op0, new_op1);
    4926       235301 :         }
    4927              : 
    4928              :       /* If we're shifting left a signed bitfield extraction and the
    4929              :          shift count + bitfield size is a natural integral mode and
    4930              :          the field starts at offset 0 (counting from the LSB), then
    4931              :          this can be simplified to a sign extension of a left shift.
    4932              : 
    4933              :          Some ISAs (RISC-V 64-bit) have inherent support for such
    4934              :          instructions and it's better for various optimizations to
    4935              :          express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT.  */
    4936     19234142 :       if (GET_CODE (op0) == SIGN_EXTRACT
    4937           28 :           && REG_P (XEXP (op0, 0))
    4938              :           /* The size of the bitfield, the location of the bitfield and
    4939              :              shift count must be CONST_INTs.  */
    4940           22 :           && CONST_INT_P (op1)
    4941           22 :           && CONST_INT_P (XEXP (op0, 1))
    4942           22 :           && CONST_INT_P (XEXP (op0, 2)))
    4943              :         {
    4944           22 :           int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
    4945           22 :           machine_mode smaller_mode;
    4946              :           /* Now we need to verify the size of the bitfield plus the shift
    4947              :              count is an integral mode and smaller than MODE.  This is
    4948              :              requirement for using SIGN_EXTEND.  We also need to verify the
    4949              :              field starts at bit location 0 and that the subreg lowpart also
    4950              :              starts at zero.  */
    4951           22 :           if (int_mode_for_size (size, size).exists (&smaller_mode)
    4952            3 :               && mode > smaller_mode
    4953           22 :               && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
    4954            3 :                   == UINTVAL (XEXP (op0, 2)))
    4955            1 :               && XEXP (op0, 2) == CONST0_RTX (mode))
    4956              :             {
    4957              :               /* Everything passed.  So we just need to get the subreg of the
    4958              :                  original input, shift it and sign extend the result.  */
    4959            1 :               rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
    4960            1 :               rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
    4961            1 :               return gen_rtx_SIGN_EXTEND (mode, x);
    4962              :             }
    4963              :         }
    4964     19234141 :       goto canonicalize_shift;
    4965              : 
    4966      8467954 :     case LSHIFTRT:
    4967      8467954 :       if (trueop1 == CONST0_RTX (mode))
    4968              :         return op0;
    4969      6659014 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4970              :         return op0;
    4971              :       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
    4972      6657524 :       if (GET_CODE (op0) == CLZ
    4973            0 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4974            0 :           && CONST_INT_P (trueop1)
    4975              :           && STORE_FLAG_VALUE == 1
    4976      6657524 :           && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
    4977              :         {
    4978            0 :           unsigned HOST_WIDE_INT zero_val = 0;
    4979              : 
    4980            0 :           if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
    4981            0 :               && zero_val == GET_MODE_PRECISION (inner_mode)
    4982            0 :               && INTVAL (trueop1) == exact_log2 (zero_val))
    4983            0 :             return simplify_gen_relational (EQ, mode, inner_mode,
    4984            0 :                                             XEXP (op0, 0), const0_rtx);
    4985              :         }
    4986      6657524 :       goto canonicalize_shift;
    4987              : 
    4988       240943 :     case SMIN:
    4989       240943 :       if (HWI_COMPUTABLE_MODE_P (mode)
    4990       220193 :           && mode_signbit_p (mode, trueop1)
    4991            0 :           && ! side_effects_p (op0))
    4992              :         return op1;
    4993       240943 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    4994              :         return op0;
    4995       240787 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4996       240787 :       if (tem)
    4997              :         return tem;
    4998              :       break;
    4999              : 
    5000       494419 :     case SMAX:
    5001       494419 :       if (HWI_COMPUTABLE_MODE_P (mode)
    5002       467193 :           && CONST_INT_P (trueop1)
    5003       434849 :           && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
    5004            0 :           && ! side_effects_p (op0))
    5005              :         return op1;
    5006       494419 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5007              :         return op0;
    5008       494312 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5009       494312 :       if (tem)
    5010              :         return tem;
    5011              :       break;
    5012              : 
    5013       329016 :     case UMIN:
    5014       329016 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    5015              :         return op1;
    5016       329004 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5017              :         return op0;
    5018       328886 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5019       328886 :       if (tem)
    5020              :         return tem;
    5021              :       break;
    5022              : 
    5023       275447 :     case UMAX:
    5024       275447 :       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
    5025              :         return op1;
    5026       275447 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5027              :         return op0;
    5028       275357 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5029       275357 :       if (tem)
    5030              :         return tem;
    5031              :       break;
    5032              : 
    5033        11994 :     case SS_PLUS:
    5034        11994 :     case US_PLUS:
    5035        11994 :     case SS_MINUS:
    5036        11994 :     case US_MINUS:
    5037              :       /* Simplify x +/- 0 to x, if possible.  */
    5038        11994 :       if (trueop1 == CONST0_RTX (mode))
    5039              :         return op0;
    5040              :       return 0;
    5041              : 
    5042            0 :     case SS_MULT:
    5043            0 :     case US_MULT:
    5044              :       /* Simplify x * 0 to 0, if possible.  */
    5045            0 :       if (trueop1 == CONST0_RTX (mode)
    5046            0 :           && !side_effects_p (op0))
    5047              :         return op1;
    5048              : 
    5049              :       /* Simplify x * 1 to x, if possible.  */
    5050            0 :       if (trueop1 == CONST1_RTX (mode))
    5051              :         return op0;
    5052              :       return 0;
    5053              : 
    5054       463627 :     case SMUL_HIGHPART:
    5055       463627 :     case UMUL_HIGHPART:
    5056              :       /* Simplify x * 0 to 0, if possible.  */
    5057       463627 :       if (trueop1 == CONST0_RTX (mode)
    5058       463627 :           && !side_effects_p (op0))
    5059              :         return op1;
    5060              :       return 0;
    5061              : 
    5062            0 :     case SS_DIV:
    5063            0 :     case US_DIV:
    5064              :       /* Simplify x / 1 to x, if possible.  */
    5065            0 :       if (trueop1 == CONST1_RTX (mode))
    5066              :         return op0;
    5067              :       return 0;
    5068              : 
    5069            0 :     case COPYSIGN:
    5070            0 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5071              :         return op0;
    5072            0 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5073              :         {
    5074            0 :           REAL_VALUE_TYPE f1;
    5075            0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
    5076            0 :           rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
    5077            0 :           if (REAL_VALUE_NEGATIVE (f1))
    5078            0 :             tmp = simplify_unary_operation (NEG, mode, tmp, mode);
    5079            0 :           return tmp;
    5080              :         }
    5081            0 :       if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
    5082            0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    5083            0 :       if (GET_CODE (op1) == ABS
    5084            0 :           && ! side_effects_p (op1))
    5085            0 :         return simplify_gen_unary (ABS, mode, op0, mode);
    5086            0 :       if (GET_CODE (op0) == COPYSIGN
    5087            0 :           && ! side_effects_p (XEXP (op0, 1)))
    5088            0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    5089            0 :       if (GET_CODE (op1) == COPYSIGN
    5090            0 :           && ! side_effects_p (XEXP (op1, 0)))
    5091            0 :         return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
    5092              :       return 0;
    5093              : 
    5094         1118 :     case VEC_SERIES:
    5095         2236 :       if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
    5096           92 :         return gen_vec_duplicate (mode, op0);
    5097         1026 :       if (valid_for_const_vector_p (mode, op0)
    5098         1026 :           && valid_for_const_vector_p (mode, op1))
    5099           93 :         return gen_const_vec_series (mode, op0, op1);
    5100              :       return 0;
    5101              : 
    5102      3452378 :     case VEC_SELECT:
    5103      3452378 :       if (!VECTOR_MODE_P (mode))
    5104              :         {
    5105       951151 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    5106      1902302 :           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
    5107       951151 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    5108       951151 :           gcc_assert (XVECLEN (trueop1, 0) == 1);
    5109              : 
    5110              :           /* We can't reason about selections made at runtime.  */
    5111       951151 :           if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5112    446429538 :             return 0;
    5113              : 
    5114       951151 :           if (vec_duplicate_p (trueop0, &elt0))
    5115         2081 :             return elt0;
    5116              : 
    5117       949070 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    5118         7220 :             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
    5119              :                                                       (trueop1, 0, 0)));
    5120              : 
    5121              :           /* Extract a scalar element from a nested VEC_SELECT expression
    5122              :              (with optional nested VEC_CONCAT expression).  Some targets
    5123              :              (i386) extract scalar element from a vector using chain of
    5124              :              nested VEC_SELECT expressions.  When input operand is a memory
    5125              :              operand, this operation can be simplified to a simple scalar
    5126              :              load from an offsetted memory address.  */
    5127       941850 :           int n_elts;
    5128       941850 :           if (GET_CODE (trueop0) == VEC_SELECT
    5129      1012650 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5130        70800 :                   .is_constant (&n_elts)))
    5131              :             {
    5132        70800 :               rtx op0 = XEXP (trueop0, 0);
    5133        70800 :               rtx op1 = XEXP (trueop0, 1);
    5134              : 
    5135        70800 :               int i = INTVAL (XVECEXP (trueop1, 0, 0));
    5136        70800 :               int elem;
    5137              : 
    5138        70800 :               rtvec vec;
    5139        70800 :               rtx tmp_op, tmp;
    5140              : 
    5141        70800 :               gcc_assert (GET_CODE (op1) == PARALLEL);
    5142        70800 :               gcc_assert (i < XVECLEN (op1, 0));
    5143              : 
    5144              :               /* Select element, pointed by nested selector.  */
    5145        70800 :               elem = INTVAL (XVECEXP (op1, 0, i));
    5146              : 
    5147        70800 :               gcc_assert (elem < n_elts);
    5148              : 
    5149              :               /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
    5150        70800 :               if (GET_CODE (op0) == VEC_CONCAT)
    5151              :                 {
    5152        28625 :                   rtx op00 = XEXP (op0, 0);
    5153        28625 :                   rtx op01 = XEXP (op0, 1);
    5154              : 
    5155        28625 :                   machine_mode mode00, mode01;
    5156        28625 :                   int n_elts00, n_elts01;
    5157              : 
    5158        28625 :                   mode00 = GET_MODE (op00);
    5159        28625 :                   mode01 = GET_MODE (op01);
    5160              : 
    5161              :                   /* Find out the number of elements of each operand.
    5162              :                      Since the concatenated result has a constant number
    5163              :                      of elements, the operands must too.  */
    5164        28625 :                   n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
    5165        28625 :                   n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
    5166              : 
    5167        28625 :                   gcc_assert (n_elts == n_elts00 + n_elts01);
    5168              : 
    5169              :                   /* Select correct operand of VEC_CONCAT
    5170              :                      and adjust selector. */
    5171        28625 :                   if (elem < n_elts01)
    5172              :                     tmp_op = op00;
    5173              :                   else
    5174              :                     {
    5175           45 :                       tmp_op = op01;
    5176           45 :                       elem -= n_elts00;
    5177              :                     }
    5178              :                 }
    5179              :               else
    5180              :                 tmp_op = op0;
    5181              : 
    5182        70800 :               vec = rtvec_alloc (1);
    5183        70800 :               RTVEC_ELT (vec, 0) = GEN_INT (elem);
    5184              : 
    5185        70800 :               tmp = gen_rtx_fmt_ee (code, mode,
    5186              :                                     tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
    5187        70800 :               return tmp;
    5188              :             }
    5189              :         }
    5190              :       else
    5191              :         {
    5192      2501227 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    5193      7503681 :           gcc_assert (GET_MODE_INNER (mode)
    5194              :                       == GET_MODE_INNER (GET_MODE (trueop0)));
    5195      2501227 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    5196              : 
    5197      2501227 :           if (vec_duplicate_p (trueop0, &elt0))
    5198              :             /* It doesn't matter which elements are selected by trueop1,
    5199              :                because they are all the same.  */
    5200        15984 :             return gen_vec_duplicate (mode, elt0);
    5201              : 
    5202      2485243 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    5203              :             {
    5204        17259 :               unsigned n_elts = XVECLEN (trueop1, 0);
    5205        17259 :               rtvec v = rtvec_alloc (n_elts);
    5206        17259 :               unsigned int i;
    5207              : 
    5208        34518 :               gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
    5209        80333 :               for (i = 0; i < n_elts; i++)
    5210              :                 {
    5211        63074 :                   rtx x = XVECEXP (trueop1, 0, i);
    5212              : 
    5213        63074 :                   if (!CONST_INT_P (x))
    5214              :                     return 0;
    5215              : 
    5216        63074 :                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
    5217              :                                                        INTVAL (x));
    5218              :                 }
    5219              : 
    5220        17259 :               return gen_rtx_CONST_VECTOR (mode, v);
    5221              :             }
    5222              : 
    5223              :           /* Recognize the identity.  */
    5224      2467984 :           if (GET_MODE (trueop0) == mode)
    5225              :             {
    5226       586001 :               bool maybe_ident = true;
    5227       586001 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5228              :                 {
    5229       585595 :                   rtx j = XVECEXP (trueop1, 0, i);
    5230       585595 :                   if (!CONST_INT_P (j) || INTVAL (j) != i)
    5231              :                     {
    5232              :                       maybe_ident = false;
    5233              :                       break;
    5234              :                     }
    5235              :                 }
    5236       359168 :               if (maybe_ident)
    5237              :                 return trueop0;
    5238              :             }
    5239              : 
    5240              :           /* If we select a low-part subreg, return that.  */
    5241      2467578 :           if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
    5242              :             {
    5243            0 :               rtx new_rtx = lowpart_subreg (mode, trueop0,
    5244            0 :                                             GET_MODE (trueop0));
    5245            0 :               if (new_rtx != NULL_RTX)
    5246              :                 return new_rtx;
    5247              :             }
    5248              : 
    5249              :           /* If we build {a,b} then permute it, build the result directly.  */
    5250      2467578 :           if (XVECLEN (trueop1, 0) == 2
    5251       594097 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5252       594097 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    5253       594097 :               && GET_CODE (trueop0) == VEC_CONCAT
    5254       177857 :               && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
    5255           81 :               && GET_MODE (XEXP (trueop0, 0)) == mode
    5256           81 :               && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
    5257           55 :               && GET_MODE (XEXP (trueop0, 1)) == mode)
    5258              :             {
    5259           55 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5260           55 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5261           55 :               rtx subop0, subop1;
    5262              : 
    5263           55 :               gcc_assert (i0 < 4 && i1 < 4);
    5264           55 :               subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
    5265           55 :               subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
    5266              : 
    5267           55 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5268              :             }
    5269              : 
    5270      2467523 :           if (XVECLEN (trueop1, 0) == 2
    5271       594042 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5272       594042 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    5273       594042 :               && GET_CODE (trueop0) == VEC_CONCAT
    5274       177802 :               && GET_MODE (trueop0) == mode)
    5275              :             {
    5276            2 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5277            2 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5278            2 :               rtx subop0, subop1;
    5279              : 
    5280            2 :               gcc_assert (i0 < 2 && i1 < 2);
    5281            2 :               subop0 = XEXP (trueop0, i0);
    5282            2 :               subop1 = XEXP (trueop0, i1);
    5283              : 
    5284            2 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5285              :             }
    5286              : 
    5287              :           /* If we select one half of a vec_concat, return that.  */
    5288      2467521 :           int l0, l1;
    5289      2467521 :           if (GET_CODE (trueop0) == VEC_CONCAT
    5290      3061480 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5291      1530740 :                   .is_constant (&l0))
    5292      3061480 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
    5293      1530740 :                   .is_constant (&l1))
    5294      3998261 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5295              :             {
    5296      1530740 :               rtx subop0 = XEXP (trueop0, 0);
    5297      1530740 :               rtx subop1 = XEXP (trueop0, 1);
    5298      1530740 :               machine_mode mode0 = GET_MODE (subop0);
    5299      1530740 :               machine_mode mode1 = GET_MODE (subop1);
    5300      1530740 :               int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5301      1530740 :               if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
    5302              :                 {
    5303       973786 :                   bool success = true;
    5304       973786 :                   for (int i = 1; i < l0; ++i)
    5305              :                     {
    5306       973457 :                       rtx j = XVECEXP (trueop1, 0, i);
    5307       973457 :                       if (!CONST_INT_P (j) || INTVAL (j) != i)
    5308              :                         {
    5309              :                           success = false;
    5310              :                           break;
    5311              :                         }
    5312              :                     }
    5313       890362 :                   if (success)
    5314              :                     return subop0;
    5315              :                 }
    5316      1530411 :               if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
    5317              :                 {
    5318          590 :                   bool success = true;
    5319          590 :                   for (int i = 1; i < l1; ++i)
    5320              :                     {
    5321          543 :                       rtx j = XVECEXP (trueop1, 0, i);
    5322          543 :                       if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
    5323              :                         {
    5324              :                           success = false;
    5325              :                           break;
    5326              :                         }
    5327              :                     }
    5328           76 :                   if (success)
    5329              :                     return subop1;
    5330              :                 }
    5331              :             }
    5332              : 
    5333              :           /* Simplify vec_select of a subreg of X to just a vec_select of X
    5334              :              when X has same component mode as vec_select.  */
    5335      2467145 :           unsigned HOST_WIDE_INT subreg_offset = 0;
    5336      2467145 :           if (GET_CODE (trueop0) == SUBREG
    5337       364927 :               && GET_MODE_INNER (mode)
    5338       729854 :                  == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
    5339        29586 :               && GET_MODE_NUNITS (mode).is_constant (&l1)
    5340      2832072 :               && constant_multiple_p (subreg_memory_offset (trueop0),
    5341        29586 :                                       GET_MODE_UNIT_BITSIZE (mode),
    5342              :                                       &subreg_offset))
    5343              :             {
    5344        14793 :               poly_uint64 nunits
    5345        29586 :                 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
    5346        14793 :               bool success = true;
    5347        91529 :               for (int i = 0; i != l1; i++)
    5348              :                 {
    5349        87085 :                   rtx idx = XVECEXP (trueop1, 0, i);
    5350        87085 :                   if (!CONST_INT_P (idx)
    5351        87085 :                       || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
    5352              :                     {
    5353              :                       success = false;
    5354              :                       break;
    5355              :                     }
    5356              :                 }
    5357              : 
    5358        14793 :               if (success)
    5359              :                 {
    5360         4444 :                   rtx par = trueop1;
    5361         4444 :                   if (subreg_offset)
    5362              :                     {
    5363            0 :                       rtvec vec = rtvec_alloc (l1);
    5364            0 :                       for (int i = 0; i < l1; i++)
    5365            0 :                         RTVEC_ELT (vec, i)
    5366            0 :                           = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
    5367              :                                      + subreg_offset);
    5368            0 :                       par = gen_rtx_PARALLEL (VOIDmode, vec);
    5369              :                     }
    5370         4444 :                   return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
    5371              :                 }
    5372              :             }
    5373              :         }
    5374              : 
    5375      3333751 :       if (XVECLEN (trueop1, 0) == 1
    5376       871134 :           && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5377       871134 :           && GET_CODE (trueop0) == VEC_CONCAT)
    5378              :         {
    5379         1288 :           rtx vec = trueop0;
    5380         2576 :           offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
    5381              : 
    5382              :           /* Try to find the element in the VEC_CONCAT.  */
    5383         1288 :           while (GET_MODE (vec) != mode
    5384         2576 :                  && GET_CODE (vec) == VEC_CONCAT)
    5385              :             {
    5386         1288 :               poly_int64 vec_size;
    5387              : 
    5388         1288 :               if (CONST_INT_P (XEXP (vec, 0)))
    5389              :                 {
    5390              :                   /* vec_concat of two const_ints doesn't make sense with
    5391              :                      respect to modes.  */
    5392            3 :                   if (CONST_INT_P (XEXP (vec, 1)))
    5393    382781702 :                     return 0;
    5394              : 
    5395            3 :                   vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
    5396            9 :                              - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
    5397              :                 }
    5398              :               else
    5399         2570 :                 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
    5400              : 
    5401         1288 :               if (known_lt (offset, vec_size))
    5402              :                 vec = XEXP (vec, 0);
    5403          228 :               else if (known_ge (offset, vec_size))
    5404              :                 {
    5405          228 :                   offset -= vec_size;
    5406          228 :                   vec = XEXP (vec, 1);
    5407              :                 }
    5408              :               else
    5409              :                 break;
    5410         1288 :               vec = avoid_constant_pool_reference (vec);
    5411              :             }
    5412              : 
    5413         1288 :           if (GET_MODE (vec) == mode)
    5414              :             return vec;
    5415              :         }
    5416              : 
    5417              :       /* If we select elements in a vec_merge that all come from the same
    5418              :          operand, select from that operand directly.  */
    5419      3332643 :       if (GET_CODE (op0) == VEC_MERGE)
    5420              :         {
    5421         9821 :           rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
    5422         9821 :           if (CONST_INT_P (trueop02))
    5423              :             {
    5424         3003 :               unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
    5425         3003 :               bool all_operand0 = true;
    5426         3003 :               bool all_operand1 = true;
    5427        10933 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5428              :                 {
    5429         7930 :                   rtx j = XVECEXP (trueop1, 0, i);
    5430         7930 :                   if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
    5431              :                     all_operand1 = false;
    5432              :                   else
    5433         3560 :                     all_operand0 = false;
    5434              :                 }
    5435         3003 :               if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
    5436         1458 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
    5437         1545 :               if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
    5438           47 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
    5439              :             }
    5440              :         }
    5441              : 
    5442              :       /* If we have two nested selects that are inverses of each
    5443              :          other, replace them with the source operand.  */
    5444      3331138 :       if (GET_CODE (trueop0) == VEC_SELECT
    5445        69276 :           && GET_MODE (XEXP (trueop0, 0)) == mode)
    5446              :         {
    5447         1030 :           rtx op0_subop1 = XEXP (trueop0, 1);
    5448         1030 :           gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
    5449         2060 :           gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
    5450              :           bool identical_p = true;
    5451              : 
    5452              :           /* Apply the outer ordering vector to the inner one.  (The inner
    5453              :              ordering vector is expressly permitted to be of a different
    5454              :              length than the outer one.)  If the result is { 0, 1, ..., n-1 }
    5455              :              then the two VEC_SELECTs cancel.  */
    5456         8946 :           for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
    5457              :             {
    5458         7916 :               rtx x = XVECEXP (trueop1, 0, i);
    5459         7916 :               if (!CONST_INT_P (x))
    5460              :                 return 0;
    5461         7916 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5462         7916 :               if (!CONST_INT_P (y))
    5463              :                 return 0;
    5464         7916 :               if (i != INTVAL (y))
    5465         5854 :                 identical_p = false;
    5466              :             }
    5467         1030 :           if (identical_p)
    5468              :             return XEXP (trueop0, 0);
    5469              : 
    5470              :           /* Otherwise a permutation of a permutation is a permutation.  */
    5471         1030 :           int len = XVECLEN (trueop1, 0);
    5472         1030 :           rtvec vec = rtvec_alloc (len);
    5473         8946 :           for (int i = 0; i < len; ++i)
    5474              :             {
    5475         7916 :               rtx x = XVECEXP (trueop1, 0, i);
    5476         7916 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5477         7916 :               RTVEC_ELT (vec, i) = y;
    5478              :             }
    5479         1030 :           return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
    5480              :                                  gen_rtx_PARALLEL (VOIDmode, vec));
    5481              :         }
    5482              : 
    5483              :       return 0;
    5484      4116678 :     case VEC_CONCAT:
    5485      4116678 :       {
    5486      4116678 :         machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
    5487      4116678 :                                       ? GET_MODE (trueop0)
    5488      4116678 :                                       : GET_MODE_INNER (mode));
    5489      4116678 :         machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
    5490      4116678 :                                       ? GET_MODE (trueop1)
    5491      4116678 :                                       : GET_MODE_INNER (mode));
    5492              : 
    5493      4116678 :         gcc_assert (VECTOR_MODE_P (mode));
    5494     16466712 :         gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
    5495              :                               + GET_MODE_SIZE (op1_mode),
    5496              :                               GET_MODE_SIZE (mode)));
    5497              : 
    5498      4116678 :         if (VECTOR_MODE_P (op0_mode))
    5499      5729694 :           gcc_assert (GET_MODE_INNER (mode)
    5500              :                       == GET_MODE_INNER (op0_mode));
    5501              :         else
    5502      4413560 :           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
    5503              : 
    5504      4116678 :         if (VECTOR_MODE_P (op1_mode))
    5505      5729694 :           gcc_assert (GET_MODE_INNER (mode)
    5506              :                       == GET_MODE_INNER (op1_mode));
    5507              :         else
    5508      4413560 :           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
    5509              : 
    5510      4116678 :         unsigned int n_elts, in_n_elts;
    5511      4116678 :         if ((GET_CODE (trueop0) == CONST_VECTOR
    5512      4116678 :              || CONST_SCALAR_INT_P (trueop0)
    5513      3957106 :              || CONST_DOUBLE_AS_FLOAT_P (trueop0))
    5514       161232 :             && (GET_CODE (trueop1) == CONST_VECTOR
    5515       161232 :                 || CONST_SCALAR_INT_P (trueop1)
    5516       161232 :                 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5517            0 :             && GET_MODE_NUNITS (mode).is_constant (&n_elts)
    5518      4116678 :             && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
    5519              :           {
    5520            0 :             rtvec v = rtvec_alloc (n_elts);
    5521            0 :             unsigned int i;
    5522            0 :             for (i = 0; i < n_elts; i++)
    5523              :               {
    5524            0 :                 if (i < in_n_elts)
    5525              :                   {
    5526            0 :                     if (!VECTOR_MODE_P (op0_mode))
    5527            0 :                       RTVEC_ELT (v, i) = trueop0;
    5528              :                     else
    5529            0 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
    5530              :                   }
    5531              :                 else
    5532              :                   {
    5533            0 :                     if (!VECTOR_MODE_P (op1_mode))
    5534            0 :                       RTVEC_ELT (v, i) = trueop1;
    5535              :                     else
    5536            0 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
    5537              :                                                            i - in_n_elts);
    5538              :                   }
    5539              :               }
    5540              : 
    5541            0 :             return gen_rtx_CONST_VECTOR (mode, v);
    5542              :           }
    5543              : 
    5544              :         /* Try to merge two VEC_SELECTs from the same vector into a single one.
    5545              :            Restrict the transformation to avoid generating a VEC_SELECT with a
    5546              :            mode unrelated to its operand.  */
    5547      4116678 :         if (GET_CODE (trueop0) == VEC_SELECT
    5548       132141 :             && GET_CODE (trueop1) == VEC_SELECT
    5549        28565 :             && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
    5550      4132751 :             && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
    5551        32146 :                == GET_MODE_INNER(mode))
    5552              :           {
    5553        16073 :             rtx par0 = XEXP (trueop0, 1);
    5554        16073 :             rtx par1 = XEXP (trueop1, 1);
    5555        16073 :             int len0 = XVECLEN (par0, 0);
    5556        16073 :             int len1 = XVECLEN (par1, 0);
    5557        16073 :             rtvec vec = rtvec_alloc (len0 + len1);
    5558        99290 :             for (int i = 0; i < len0; i++)
    5559        83217 :               RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
    5560        99290 :             for (int i = 0; i < len1; i++)
    5561        83217 :               RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
    5562        16073 :             return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
    5563        16073 :                                         gen_rtx_PARALLEL (VOIDmode, vec));
    5564              :           }
    5565              :         /* (vec_concat:
    5566              :              (subreg_lowpart:N OP)
    5567              :              (vec_select:N OP P))  -->  OP when P selects the high half
    5568              :             of the OP.  */
    5569      4100605 :         if (GET_CODE (trueop0) == SUBREG
    5570       491278 :             && subreg_lowpart_p (trueop0)
    5571       491071 :             && GET_CODE (trueop1) == VEC_SELECT
    5572            3 :             && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
    5573            0 :             && !side_effects_p (XEXP (trueop1, 0))
    5574      4100605 :             && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
    5575            0 :           return XEXP (trueop1, 0);
    5576              :       }
    5577              :       return 0;
    5578              : 
    5579            0 :     default:
    5580            0 :       gcc_unreachable ();
    5581              :     }
    5582              : 
    5583    374874485 :   if (mode == GET_MODE (op0)
    5584    322149681 :       && mode == GET_MODE (op1)
    5585    101934190 :       && vec_duplicate_p (op0, &elt0)
    5586    374994420 :       && vec_duplicate_p (op1, &elt1))
    5587              :     {
    5588              :       /* Try applying the operator to ELT and see if that simplifies.
    5589              :          We can duplicate the result if so.
    5590              : 
    5591              :          The reason we don't use simplify_gen_binary is that it isn't
    5592              :          necessarily a win to convert things like:
    5593              : 
    5594              :            (plus:V (vec_duplicate:V (reg:S R1))
    5595              :                    (vec_duplicate:V (reg:S R2)))
    5596              : 
    5597              :          to:
    5598              : 
    5599              :            (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
    5600              : 
    5601              :          The first might be done entirely in vector registers while the
    5602              :          second might need a move between register files.  */
    5603          128 :       tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5604              :                                        elt0, elt1);
    5605           64 :       if (tem)
    5606            2 :         return gen_vec_duplicate (mode, tem);
    5607              :     }
    5608              : 
    5609              :   return 0;
    5610              : }
    5611              : 
    5612              : /* Return true if binary operation OP distributes over addition in operand
    5613              :    OPNO, with the other operand being held constant.  OPNO counts from 1.  */
    5614              : 
    5615              : static bool
    5616         7408 : distributes_over_addition_p (rtx_code op, int opno)
    5617              : {
    5618            0 :   switch (op)
    5619              :     {
    5620              :     case PLUS:
    5621              :     case MINUS:
    5622              :     case MULT:
    5623              :       return true;
    5624              : 
    5625            0 :     case ASHIFT:
    5626            0 :       return opno == 1;
    5627              : 
    5628            0 :     default:
    5629            0 :       return false;
    5630              :     }
    5631              : }
    5632              : 
    5633              : rtx
    5634    479517780 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
    5635              :                                  rtx op0, rtx op1)
    5636              : {
    5637    479517780 :   if (VECTOR_MODE_P (mode)
    5638     14984391 :       && code != VEC_CONCAT
    5639     10855237 :       && GET_CODE (op0) == CONST_VECTOR
    5640       171517 :       && GET_CODE (op1) == CONST_VECTOR)
    5641              :     {
    5642         8116 :       bool step_ok_p;
    5643         8116 :       if (CONST_VECTOR_STEPPED_P (op0)
    5644         8116 :           && CONST_VECTOR_STEPPED_P (op1))
    5645              :         /* We can operate directly on the encoding if:
    5646              : 
    5647              :               a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
    5648              :             implies
    5649              :               (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
    5650              : 
    5651              :            Addition and subtraction are the supported operators
    5652              :            for which this is true.  */
    5653          708 :         step_ok_p = (code == PLUS || code == MINUS);
    5654         7408 :       else if (CONST_VECTOR_STEPPED_P (op0))
    5655              :         /* We can operate directly on stepped encodings if:
    5656              : 
    5657              :              a3 - a2 == a2 - a1
    5658              :            implies:
    5659              :              (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
    5660              : 
    5661              :            which is true if (x -> x op c) distributes over addition.  */
    5662         1280 :         step_ok_p = distributes_over_addition_p (code, 1);
    5663              :       else
    5664              :         /* Similarly in reverse.  */
    5665         6128 :         step_ok_p = distributes_over_addition_p (code, 2);
    5666         8116 :       rtx_vector_builder builder;
    5667         8116 :       if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
    5668              :         return 0;
    5669              : 
    5670         8116 :       unsigned int count = builder.encoded_nelts ();
    5671        52331 :       for (unsigned int i = 0; i < count; i++)
    5672              :         {
    5673        88530 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5674              :                                              CONST_VECTOR_ELT (op0, i),
    5675        44265 :                                              CONST_VECTOR_ELT (op1, i));
    5676        44265 :           if (!x || !valid_for_const_vector_p (mode, x))
    5677           50 :             return 0;
    5678        44215 :           builder.quick_push (x);
    5679              :         }
    5680         8066 :       return builder.build ();
    5681         8116 :     }
    5682              : 
    5683    479509664 :   if (VECTOR_MODE_P (mode)
    5684     14976275 :       && code == VEC_CONCAT
    5685      4129154 :       && (CONST_SCALAR_INT_P (op0)
    5686      3979367 :           || CONST_FIXED_P (op0)
    5687      3979367 :           || CONST_DOUBLE_AS_FLOAT_P (op0)
    5688      3975533 :           || CONST_VECTOR_P (op0))
    5689       173708 :       && (CONST_SCALAR_INT_P (op1)
    5690       171036 :           || CONST_DOUBLE_AS_FLOAT_P (op1)
    5691       168862 :           || CONST_FIXED_P (op1)
    5692       168862 :           || CONST_VECTOR_P (op1)))
    5693              :     {
    5694              :       /* Both inputs have a constant number of elements, so the result
    5695              :          must too.  */
    5696        12476 :       unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
    5697        12476 :       rtvec v = rtvec_alloc (n_elts);
    5698              : 
    5699        12476 :       gcc_assert (n_elts >= 2);
    5700        12476 :       if (n_elts == 2)
    5701              :         {
    5702         4846 :           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
    5703         4846 :           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
    5704              : 
    5705         4846 :           RTVEC_ELT (v, 0) = op0;
    5706         4846 :           RTVEC_ELT (v, 1) = op1;
    5707              :         }
    5708              :       else
    5709              :         {
    5710         7630 :           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
    5711         7630 :           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
    5712         7630 :           unsigned i;
    5713              : 
    5714         7630 :           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
    5715         7630 :           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
    5716         7630 :           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
    5717              : 
    5718        48844 :           for (i = 0; i < op0_n_elts; ++i)
    5719        41214 :             RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
    5720        49036 :           for (i = 0; i < op1_n_elts; ++i)
    5721        41406 :             RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
    5722              :         }
    5723              : 
    5724        12476 :       return gen_rtx_CONST_VECTOR (mode, v);
    5725              :     }
    5726              : 
    5727    467790250 :   if (VECTOR_MODE_P (mode)
    5728     14963799 :       && GET_CODE (op0) == CONST_VECTOR
    5729       175858 :       && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
    5730    479497188 :       && (CONST_VECTOR_DUPLICATE_P (op0)
    5731              :           || CONST_VECTOR_NUNITS (op0).is_constant ()))
    5732              :     {
    5733       116071 :       switch (code)
    5734              :         {
    5735       116071 :         case PLUS:
    5736       116071 :         case MINUS:
    5737       116071 :         case MULT:
    5738       116071 :         case DIV:
    5739       116071 :         case MOD:
    5740       116071 :         case UDIV:
    5741       116071 :         case UMOD:
    5742       116071 :         case AND:
    5743       116071 :         case IOR:
    5744       116071 :         case XOR:
    5745       116071 :         case SMIN:
    5746       116071 :         case SMAX:
    5747       116071 :         case UMIN:
    5748       116071 :         case UMAX:
    5749       116071 :         case LSHIFTRT:
    5750       116071 :         case ASHIFTRT:
    5751       116071 :         case ASHIFT:
    5752       116071 :         case ROTATE:
    5753       116071 :         case ROTATERT:
    5754       116071 :         case SS_PLUS:
    5755       116071 :         case US_PLUS:
    5756       116071 :         case SS_MINUS:
    5757       116071 :         case US_MINUS:
    5758       116071 :         case SS_ASHIFT:
    5759       116071 :         case US_ASHIFT:
    5760       116071 :         case COPYSIGN:
    5761       116071 :           break;
    5762              :         default:
    5763              :           return NULL_RTX;
    5764              :         }
    5765              : 
    5766       116071 :       unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
    5767       116071 :                                 ? CONST_VECTOR_NPATTERNS (op0)
    5768       123838 :                                 : CONST_VECTOR_NUNITS (op0).to_constant ());
    5769       116071 :       rtx_vector_builder builder (mode, npatterns, 1);
    5770       245237 :       for (unsigned i = 0; i < npatterns; i++)
    5771              :         {
    5772       258332 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5773       129166 :                                              CONST_VECTOR_ELT (op0, i), op1);
    5774       129166 :           if (!x || !valid_for_const_vector_p (mode, x))
    5775            0 :             return 0;
    5776       129166 :           builder.quick_push (x);
    5777              :         }
    5778       116071 :       return builder.build ();
    5779              :     }
    5780              : 
    5781    479381117 :   if (SCALAR_FLOAT_MODE_P (mode)
    5782      6406618 :       && CONST_DOUBLE_AS_FLOAT_P (op0)
    5783        75593 :       && CONST_DOUBLE_AS_FLOAT_P (op1)
    5784        11520 :       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
    5785              :     {
    5786        11520 :       if (code == AND
    5787              :           || code == IOR
    5788        11520 :           || code == XOR)
    5789              :         {
    5790         2515 :           long tmp0[4];
    5791         2515 :           long tmp1[4];
    5792         2515 :           REAL_VALUE_TYPE r;
    5793         2515 :           int i;
    5794              : 
    5795         2515 :           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
    5796         2515 :                           GET_MODE (op0));
    5797         2515 :           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
    5798         2515 :                           GET_MODE (op1));
    5799        12575 :           for (i = 0; i < 4; i++)
    5800              :             {
    5801        10060 :               switch (code)
    5802              :               {
    5803         5268 :               case AND:
    5804         5268 :                 tmp0[i] &= tmp1[i];
    5805         5268 :                 break;
    5806         2512 :               case IOR:
    5807         2512 :                 tmp0[i] |= tmp1[i];
    5808         2512 :                 break;
    5809         2280 :               case XOR:
    5810         2280 :                 tmp0[i] ^= tmp1[i];
    5811         2280 :                 break;
    5812              :               default:
    5813              :                 gcc_unreachable ();
    5814              :               }
    5815              :             }
    5816         2515 :            real_from_target (&r, tmp0, mode);
    5817         2515 :            return const_double_from_real_value (r, mode);
    5818              :         }
    5819         9005 :       else if (code == COPYSIGN)
    5820              :         {
    5821            0 :           REAL_VALUE_TYPE f0, f1;
    5822            0 :           real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
    5823            0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
    5824            0 :           real_copysign (&f0, &f1);
    5825            0 :           return const_double_from_real_value (f0, mode);
    5826              :         }
    5827              :       else
    5828              :         {
    5829         9005 :           REAL_VALUE_TYPE f0, f1, value, result;
    5830         9005 :           const REAL_VALUE_TYPE *opr0, *opr1;
    5831         9005 :           bool inexact;
    5832              : 
    5833         9005 :           opr0 = CONST_DOUBLE_REAL_VALUE (op0);
    5834         9005 :           opr1 = CONST_DOUBLE_REAL_VALUE (op1);
    5835              : 
    5836         9005 :           if (HONOR_SNANS (mode)
    5837         9005 :               && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
    5838          803 :                   || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
    5839           10 :             return 0;
    5840              : 
    5841         8995 :           real_convert (&f0, mode, opr0);
    5842         8995 :           real_convert (&f1, mode, opr1);
    5843              : 
    5844         8995 :           if (code == DIV
    5845         4088 :               && real_equal (&f1, &dconst0)
    5846        12619 :               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
    5847         3620 :             return 0;
    5848              : 
    5849        26774 :           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5850         5283 :               && flag_trapping_math
    5851         5205 :               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
    5852              :             {
    5853            9 :               int s0 = REAL_VALUE_NEGATIVE (f0);
    5854            9 :               int s1 = REAL_VALUE_NEGATIVE (f1);
    5855              : 
    5856            9 :               switch (code)
    5857              :                 {
    5858            0 :                 case PLUS:
    5859              :                   /* Inf + -Inf = NaN plus exception.  */
    5860            0 :                   if (s0 != s1)
    5861              :                     return 0;
    5862              :                   break;
    5863            0 :                 case MINUS:
    5864              :                   /* Inf - Inf = NaN plus exception.  */
    5865            0 :                   if (s0 == s1)
    5866              :                     return 0;
    5867              :                   break;
    5868              :                 case DIV:
    5869              :                   /* Inf / Inf = NaN plus exception.  */
    5870              :                   return 0;
    5871              :                 default:
    5872              :                   break;
    5873              :                 }
    5874              :             }
    5875              : 
    5876         7968 :           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5877         1958 :               && flag_trapping_math
    5878         7276 :               && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
    5879         1902 :                   || (REAL_VALUE_ISINF (f1)
    5880           10 :                       && real_equal (&f0, &dconst0))))
    5881              :             /* Inf * 0 = NaN plus exception.  */
    5882           18 :             return 0;
    5883              : 
    5884         5348 :           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
    5885              :                                      &f0, &f1);
    5886         5348 :           real_convert (&result, mode, &value);
    5887              : 
    5888              :           /* Don't constant fold this floating point operation if
    5889              :              the result has overflowed and flag_trapping_math.  */
    5890              : 
    5891         5348 :           if (flag_trapping_math
    5892        20712 :               && MODE_HAS_INFINITIES (mode)
    5893         5178 :               && REAL_VALUE_ISINF (result)
    5894         1104 :               && !REAL_VALUE_ISINF (f0)
    5895         6438 :               && !REAL_VALUE_ISINF (f1))
    5896              :             /* Overflow plus exception.  */
    5897         1090 :             return 0;
    5898              : 
    5899              :           /* Don't constant fold this floating point operation if the
    5900              :              result may dependent upon the run-time rounding mode and
    5901              :              flag_rounding_math is set, or if GCC's software emulation
    5902              :              is unable to accurately represent the result.  */
    5903              : 
    5904         4258 :           if ((flag_rounding_math
    5905        27125 :                || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
    5906         4258 :               && (inexact || !real_identical (&result, &value)))
    5907          378 :             return NULL_RTX;
    5908              : 
    5909         3880 :           return const_double_from_real_value (result, mode);
    5910              :         }
    5911              :     }
    5912              : 
    5913              :   /* We can fold some multi-word operations.  */
    5914    479369597 :   scalar_int_mode int_mode;
    5915    479369597 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    5916    410966938 :       && CONST_SCALAR_INT_P (op0)
    5917     39700277 :       && CONST_SCALAR_INT_P (op1)
    5918     32947663 :       && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
    5919              :     {
    5920     32947663 :       wide_int result;
    5921     32947663 :       wi::overflow_type overflow;
    5922     32947663 :       rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
    5923     32947663 :       rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
    5924              : 
    5925              : #if TARGET_SUPPORTS_WIDE_INT == 0
    5926              :       /* This assert keeps the simplification from producing a result
    5927              :          that cannot be represented in a CONST_DOUBLE but a lot of
    5928              :          upstream callers expect that this function never fails to
    5929              :          simplify something and so you if you added this to the test
    5930              :          above the code would die later anyway.  If this assert
    5931              :          happens, you just need to make the port support wide int.  */
    5932              :       gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
    5933              : #endif
    5934     32947663 :       switch (code)
    5935              :         {
    5936      1078291 :         case MINUS:
    5937      1078291 :           result = wi::sub (pop0, pop1);
    5938      1078291 :           break;
    5939              : 
    5940     25694893 :         case PLUS:
    5941     25694893 :           result = wi::add (pop0, pop1);
    5942     25694893 :           break;
    5943              : 
    5944       320599 :         case MULT:
    5945       320599 :           result = wi::mul (pop0, pop1);
    5946       320599 :           break;
    5947              : 
    5948         6927 :         case DIV:
    5949         6927 :           result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
    5950         6927 :           if (overflow)
    5951              :             return NULL_RTX;
    5952              :           break;
    5953              : 
    5954         1220 :         case MOD:
    5955         1220 :           result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
    5956         1220 :           if (overflow)
    5957              :             return NULL_RTX;
    5958              :           break;
    5959              : 
    5960         6131 :         case UDIV:
    5961         6131 :           result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
    5962         6131 :           if (overflow)
    5963              :             return NULL_RTX;
    5964              :           break;
    5965              : 
    5966        15350 :         case UMOD:
    5967        15350 :           result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
    5968        15350 :           if (overflow)
    5969              :             return NULL_RTX;
    5970              :           break;
    5971              : 
    5972       696248 :         case AND:
    5973       696248 :           result = wi::bit_and (pop0, pop1);
    5974       696248 :           break;
    5975              : 
    5976       275220 :         case IOR:
    5977       275220 :           result = wi::bit_or (pop0, pop1);
    5978       275220 :           break;
    5979              : 
    5980        56371 :         case XOR:
    5981        56371 :           result = wi::bit_xor (pop0, pop1);
    5982        56371 :           break;
    5983              : 
    5984         1761 :         case SMIN:
    5985         1761 :           result = wi::smin (pop0, pop1);
    5986         1761 :           break;
    5987              : 
    5988         1982 :         case SMAX:
    5989         1982 :           result = wi::smax (pop0, pop1);
    5990         1982 :           break;
    5991              : 
    5992         3193 :         case UMIN:
    5993         3193 :           result = wi::umin (pop0, pop1);
    5994         3193 :           break;
    5995              : 
    5996         2850 :         case UMAX:
    5997         2850 :           result = wi::umax (pop0, pop1);
    5998         2850 :           break;
    5999              : 
    6000      4748085 :         case LSHIFTRT:
    6001      4748085 :         case ASHIFTRT:
    6002      4748085 :         case ASHIFT:
    6003      4748085 :         case SS_ASHIFT:
    6004      4748085 :         case US_ASHIFT:
    6005      4748085 :           {
    6006              :             /* The shift count might be in SImode while int_mode might
    6007              :                be narrower.  On IA-64 it is even DImode.  If the shift
    6008              :                count is too large and doesn't fit into int_mode, we'd
    6009              :                ICE.  So, if int_mode is narrower than
    6010              :                HOST_BITS_PER_WIDE_INT, use DImode for the shift count.  */
    6011      4748085 :             if (GET_MODE (op1) == VOIDmode
    6012      4748085 :                 && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
    6013      1789852 :               pop1 = rtx_mode_t (op1, DImode);
    6014              : 
    6015      4748085 :             wide_int wop1 = pop1;
    6016      4748085 :             if (SHIFT_COUNT_TRUNCATED)
    6017              :               wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
    6018      4748085 :             else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
    6019          132 :               return NULL_RTX;
    6020              : 
    6021      4747953 :             switch (code)
    6022              :               {
    6023      2743525 :               case LSHIFTRT:
    6024      2743525 :                 result = wi::lrshift (pop0, wop1);
    6025      2743525 :                 break;
    6026              : 
    6027        73936 :               case ASHIFTRT:
    6028        73936 :                 result = wi::arshift (pop0, wop1);
    6029        73936 :                 break;
    6030              : 
    6031      1930492 :               case ASHIFT:
    6032      1930492 :                 result = wi::lshift (pop0, wop1);
    6033      1930492 :                 break;
    6034              : 
    6035            0 :               case SS_ASHIFT:
    6036            0 :                 if (wi::leu_p (wop1, wi::clrsb (pop0)))
    6037            0 :                   result = wi::lshift (pop0, wop1);
    6038            0 :                 else if (wi::neg_p (pop0))
    6039            0 :                   result = wi::min_value (int_mode, SIGNED);
    6040              :                 else
    6041            0 :                   result = wi::max_value (int_mode, SIGNED);
    6042              :                 break;
    6043              : 
    6044            0 :               case US_ASHIFT:
    6045            0 :                 if (wi::eq_p (pop0, 0))
    6046            0 :                   result = pop0;
    6047            0 :                 else if (wi::leu_p (wop1, wi::clz (pop0)))
    6048            0 :                   result = wi::lshift (pop0, wop1);
    6049              :                 else
    6050            0 :                   result = wi::max_value (int_mode, UNSIGNED);
    6051              :                 break;
    6052              : 
    6053            0 :               default:
    6054            0 :                 gcc_unreachable ();
    6055              :               }
    6056      4747953 :             break;
    6057      4748085 :           }
    6058        29978 :         case ROTATE:
    6059        29978 :         case ROTATERT:
    6060        29978 :           {
    6061              :             /* The rotate count might be in SImode while int_mode might
    6062              :                be narrower.  On IA-64 it is even DImode.  If the shift
    6063              :                count is too large and doesn't fit into int_mode, we'd
    6064              :                ICE.  So, if int_mode is narrower than
    6065              :                HOST_BITS_PER_WIDE_INT, use DImode for the shift count.  */
    6066        29978 :             if (GET_MODE (op1) == VOIDmode
    6067        29978 :                 && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
    6068        23634 :               pop1 = rtx_mode_t (op1, DImode);
    6069              : 
    6070        29978 :             if (wi::neg_p (pop1))
    6071              :               return NULL_RTX;
    6072              : 
    6073        29878 :             switch (code)
    6074              :               {
    6075        10343 :               case ROTATE:
    6076        10343 :                 result = wi::lrotate (pop0, pop1);
    6077        10343 :                 break;
    6078              : 
    6079        19535 :               case ROTATERT:
    6080        19535 :                 result = wi::rrotate (pop0, pop1);
    6081        19535 :                 break;
    6082              : 
    6083            0 :               default:
    6084            0 :                 gcc_unreachable ();
    6085              :               }
    6086              :             break;
    6087              :           }
    6088              : 
    6089         2270 :         case SS_PLUS:
    6090         2270 :           result = wi::add (pop0, pop1, SIGNED, &overflow);
    6091         4484 :  clamp_signed_saturation:
    6092         4484 :           if (overflow == wi::OVF_OVERFLOW)
    6093          314 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
    6094         4170 :           else if (overflow == wi::OVF_UNDERFLOW)
    6095          278 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
    6096         3892 :           else if (overflow != wi::OVF_NONE)
    6097              :             return NULL_RTX;
    6098              :           break;
    6099              : 
    6100         2220 :         case US_PLUS:
    6101         2220 :           result = wi::add (pop0, pop1, UNSIGNED, &overflow);
    6102         2220 :  clamp_unsigned_saturation:
    6103         2220 :           if (overflow != wi::OVF_NONE)
    6104          461 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    6105              :           break;
    6106              : 
    6107         2214 :         case SS_MINUS:
    6108         2214 :           result = wi::sub (pop0, pop1, SIGNED, &overflow);
    6109         2214 :           goto clamp_signed_saturation;
    6110              : 
    6111         1852 :         case US_MINUS:
    6112         1852 :           result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
    6113         1852 :           if (overflow != wi::OVF_NONE)
    6114         1203 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    6115              :           break;
    6116              : 
    6117            0 :         case SS_MULT:
    6118            0 :           result = wi::mul (pop0, pop1, SIGNED, &overflow);
    6119            0 :           goto clamp_signed_saturation;
    6120              : 
    6121            0 :         case US_MULT:
    6122            0 :           result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
    6123            0 :           goto clamp_unsigned_saturation;
    6124              : 
    6125            8 :         case SMUL_HIGHPART:
    6126            8 :           result = wi::mul_high (pop0, pop1, SIGNED);
    6127            8 :           break;
    6128              : 
    6129            0 :         case UMUL_HIGHPART:
    6130            0 :           result = wi::mul_high (pop0, pop1, UNSIGNED);
    6131            0 :           break;
    6132              : 
    6133              :         default:
    6134              :           return NULL_RTX;
    6135              :         }
    6136     32945234 :       return immed_wide_int_const (result, int_mode);
    6137     32947663 :     }
    6138              : 
    6139              :   /* Handle polynomial integers.  */
    6140              :   if (NUM_POLY_INT_COEFFS > 1
    6141              :       && is_a <scalar_int_mode> (mode, &int_mode)
    6142              :       && poly_int_rtx_p (op0)
    6143              :       && poly_int_rtx_p (op1))
    6144              :     {
    6145              :       poly_wide_int result;
    6146              :       switch (code)
    6147              :         {
    6148              :         case PLUS:
    6149              :           result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
    6150              :           break;
    6151              : 
    6152              :         case MINUS:
    6153              :           result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
    6154              :           break;
    6155              : 
    6156              :         case MULT:
    6157              :           if (CONST_SCALAR_INT_P (op1))
    6158              :             result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
    6159              :           else
    6160              :             return NULL_RTX;
    6161              :           break;
    6162              : 
    6163              :         case ASHIFT:
    6164              :           if (CONST_SCALAR_INT_P (op1))
    6165              :             {
    6166              :               wide_int shift
    6167              :                 = rtx_mode_t (op1,
    6168              :                               GET_MODE (op1) == VOIDmode
    6169              :                               && (GET_MODE_PRECISION (int_mode)
    6170              :                                   < HOST_BITS_PER_WIDE_INT)
    6171              :                               ? DImode : mode);
    6172              :               if (SHIFT_COUNT_TRUNCATED)
    6173              :                 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
    6174              :               else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
    6175              :                 return NULL_RTX;
    6176              :               result = wi::to_poly_wide (op0, mode) << shift;
    6177              :             }
    6178              :           else
    6179              :             return NULL_RTX;
    6180              :           break;
    6181              : 
    6182              :         case IOR:
    6183              :           if (!CONST_SCALAR_INT_P (op1)
    6184              :               || !can_ior_p (wi::to_poly_wide (op0, mode),
    6185              :                              rtx_mode_t (op1, mode), &result))
    6186              :             return NULL_RTX;
    6187              :           break;
    6188              : 
    6189              :         default:
    6190              :           return NULL_RTX;
    6191              :         }
    6192              :       return immed_wide_int_const (result, int_mode);
    6193              :     }
    6194              : 
    6195              :   return NULL_RTX;
    6196              : }
    6197              : 
    6198              : 
    6199              : 
    6200              : /* Return a positive integer if X should sort after Y.  The value
    6201              :    returned is 1 if and only if X and Y are both regs.  */
    6202              : 
    6203              : static int
    6204    115192931 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
    6205              : {
    6206    115192931 :   int result;
    6207              : 
    6208    115192931 :   result = (commutative_operand_precedence (y)
    6209    115192931 :             - commutative_operand_precedence (x));
    6210    115192931 :   if (result)
    6211     81051942 :     return result + result;
    6212              : 
    6213              :   /* Group together equal REGs to do more simplification.  */
    6214     34140989 :   if (REG_P (x) && REG_P (y))
    6215      8638652 :     return REGNO (x) > REGNO (y);
    6216              : 
    6217              :   return 0;
    6218              : }
    6219              : 
    6220              : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
    6221              :    operands may be another PLUS or MINUS.
    6222              : 
    6223              :    Rather than test for specific case, we do this by a brute-force method
    6224              :    and do all possible simplifications until no more changes occur.  Then
    6225              :    we rebuild the operation.
    6226              : 
    6227              :    May return NULL_RTX when no changes were made.  */
    6228              : 
    6229              : rtx
    6230     38739427 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
    6231              :                                        rtx op0, rtx op1)
    6232              : {
    6233     38739427 :   struct simplify_plus_minus_op_data
    6234              :   {
    6235              :     rtx op;
    6236              :     short neg;
    6237              :   } ops[16];
    6238     38739427 :   rtx result, tem;
    6239     38739427 :   int n_ops = 2;
    6240     38739427 :   int changed, n_constants, canonicalized = 0;
    6241     38739427 :   int i, j;
    6242              : 
    6243     38739427 :   memset (ops, 0, sizeof ops);
    6244              : 
    6245              :   /* Set up the two operands and then expand them until nothing has been
    6246              :      changed.  If we run out of room in our array, give up; this should
    6247              :      almost never happen.  */
    6248              : 
    6249     38739427 :   ops[0].op = op0;
    6250     38739427 :   ops[0].neg = 0;
    6251     38739427 :   ops[1].op = op1;
    6252     38739427 :   ops[1].neg = (code == MINUS);
    6253              : 
    6254     78846195 :   do
    6255              :     {
    6256     78846195 :       changed = 0;
    6257     78846195 :       n_constants = 0;
    6258              : 
    6259    319303023 :       for (i = 0; i < n_ops; i++)
    6260              :         {
    6261    240456843 :           rtx this_op = ops[i].op;
    6262    240456843 :           int this_neg = ops[i].neg;
    6263    240456843 :           enum rtx_code this_code = GET_CODE (this_op);
    6264              : 
    6265    240456843 :           switch (this_code)
    6266              :             {
    6267     39132815 :             case PLUS:
    6268     39132815 :             case MINUS:
    6269     39132815 :               if (n_ops == ARRAY_SIZE (ops))
    6270              :                 return NULL_RTX;
    6271              : 
    6272     39132800 :               ops[n_ops].op = XEXP (this_op, 1);
    6273     39132800 :               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
    6274     39132800 :               n_ops++;
    6275              : 
    6276     39132800 :               ops[i].op = XEXP (this_op, 0);
    6277     39132800 :               changed = 1;
    6278              :               /* If this operand was negated then we will potentially
    6279              :                  canonicalize the expression.  Similarly if we don't
    6280              :                  place the operands adjacent we're re-ordering the
    6281              :                  expression and thus might be performing a
    6282              :                  canonicalization.  Ignore register re-ordering.
    6283              :                  ??? It might be better to shuffle the ops array here,
    6284              :                  but then (plus (plus (A, B), plus (C, D))) wouldn't
    6285              :                  be seen as non-canonical.  */
    6286     39132800 :               if (this_neg
    6287     38437848 :                   || (i != n_ops - 2
    6288     37755638 :                       && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
    6289    240456828 :                 canonicalized = 1;
    6290              :               break;
    6291              : 
    6292         1713 :             case NEG:
    6293         1713 :               ops[i].op = XEXP (this_op, 0);
    6294         1713 :               ops[i].neg = ! this_neg;
    6295         1713 :               changed = 1;
    6296         1713 :               canonicalized = 1;
    6297         1713 :               break;
    6298              : 
    6299      1609758 :             case CONST:
    6300      1609758 :               if (n_ops != ARRAY_SIZE (ops)
    6301      1609758 :                   && GET_CODE (XEXP (this_op, 0)) == PLUS
    6302      1475555 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
    6303      1454761 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
    6304              :                 {
    6305      1454761 :                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
    6306      1454761 :                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
    6307      1454761 :                   ops[n_ops].neg = this_neg;
    6308      1454761 :                   n_ops++;
    6309      1454761 :                   changed = 1;
    6310      1454761 :                   canonicalized = 1;
    6311              :                 }
    6312              :               break;
    6313              : 
    6314        57871 :             case NOT:
    6315              :               /* ~a -> (-a - 1) */
    6316        57871 :               if (n_ops != ARRAY_SIZE (ops))
    6317              :                 {
    6318        57871 :                   ops[n_ops].op = CONSTM1_RTX (mode);
    6319        57871 :                   ops[n_ops++].neg = this_neg;
    6320        57871 :                   ops[i].op = XEXP (this_op, 0);
    6321        57871 :                   ops[i].neg = !this_neg;
    6322        57871 :                   changed = 1;
    6323        57871 :                   canonicalized = 1;
    6324              :                 }
    6325              :               break;
    6326              : 
    6327    119046590 :             CASE_CONST_SCALAR_INT:
    6328    119046590 :             case CONST_POLY_INT:
    6329    119046590 :               n_constants++;
    6330    119046590 :               if (this_neg)
    6331              :                 {
    6332      1174968 :                   ops[i].op = neg_poly_int_rtx (mode, this_op);
    6333      1174968 :                   ops[i].neg = 0;
    6334      1174968 :                   changed = 1;
    6335      1174968 :                   canonicalized = 1;
    6336              :                 }
    6337              :               break;
    6338              : 
    6339              :             default:
    6340              :               break;
    6341              :             }
    6342              :         }
    6343              :     }
    6344     78846180 :   while (changed);
    6345              : 
    6346     38739412 :   if (n_constants > 1)
    6347     23298596 :     canonicalized = 1;
    6348              : 
    6349     38739412 :   gcc_assert (n_ops >= 2);
    6350              : 
    6351              :   /* If we only have two operands, we can avoid the loops.  */
    6352     38739412 :   if (n_ops == 2)
    6353              :     {
    6354            0 :       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
    6355            0 :       rtx lhs, rhs;
    6356              : 
    6357              :       /* Get the two operands.  Be careful with the order, especially for
    6358              :          the cases where code == MINUS.  */
    6359            0 :       if (ops[0].neg && ops[1].neg)
    6360              :         {
    6361            0 :           lhs = gen_rtx_NEG (mode, ops[0].op);
    6362            0 :           rhs = ops[1].op;
    6363              :         }
    6364            0 :       else if (ops[0].neg)
    6365              :         {
    6366            0 :           lhs = ops[1].op;
    6367            0 :           rhs = ops[0].op;
    6368              :         }
    6369              :       else
    6370              :         {
    6371            0 :           lhs = ops[0].op;
    6372            0 :           rhs = ops[1].op;
    6373              :         }
    6374              : 
    6375            0 :       return simplify_const_binary_operation (code, mode, lhs, rhs);
    6376              :     }
    6377              : 
    6378              :   /* Now simplify each pair of operands until nothing changes.  */
    6379     62985579 :   while (1)
    6380              :     {
    6381              :       /* Insertion sort is good enough for a small array.  */
    6382    167140270 :       for (i = 1; i < n_ops; i++)
    6383              :         {
    6384    104154691 :           struct simplify_plus_minus_op_data save;
    6385    104154691 :           int cmp;
    6386              : 
    6387    104154691 :           j = i - 1;
    6388    104154691 :           cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
    6389    104154691 :           if (cmp <= 0)
    6390     91168399 :             continue;
    6391              :           /* Just swapping registers doesn't count as canonicalization.  */
    6392     12986292 :           if (cmp != 1)
    6393      9993320 :             canonicalized = 1;
    6394              : 
    6395     12986292 :           save = ops[i];
    6396     15399636 :           do
    6397     15399636 :             ops[j + 1] = ops[j];
    6398     15399636 :           while (j--
    6399     28385928 :                  && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
    6400     12986292 :           ops[j + 1] = save;
    6401              :         }
    6402              : 
    6403     62985579 :       changed = 0;
    6404    167140270 :       for (i = n_ops - 1; i > 0; i--)
    6405    250147795 :         for (j = i - 1; j >= 0; j--)
    6406              :           {
    6407    146920398 :             rtx lhs = ops[j].op, rhs = ops[i].op;
    6408    146920398 :             int lneg = ops[j].neg, rneg = ops[i].neg;
    6409              : 
    6410    146920398 :             if (lhs != 0 && rhs != 0)
    6411              :               {
    6412    121821590 :                 enum rtx_code ncode = PLUS;
    6413              : 
    6414    121821590 :                 if (lneg != rneg)
    6415              :                   {
    6416     11059594 :                     ncode = MINUS;
    6417     11059594 :                     if (lneg)
    6418      7002344 :                       std::swap (lhs, rhs);
    6419              :                   }
    6420    110761996 :                 else if (swap_commutative_operands_p (lhs, rhs))
    6421       363172 :                   std::swap (lhs, rhs);
    6422              : 
    6423    121821590 :                 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
    6424     27968529 :                     && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
    6425              :                   {
    6426     23449016 :                     rtx tem_lhs, tem_rhs;
    6427              : 
    6428     23449016 :                     tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
    6429     23449016 :                     tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
    6430     23449016 :                     tem = simplify_binary_operation (ncode, mode, tem_lhs,
    6431              :                                                      tem_rhs);
    6432              : 
    6433     23449016 :                     if (tem && !CONSTANT_P (tem))
    6434         1758 :                       tem = gen_rtx_CONST (GET_MODE (tem), tem);
    6435              :                   }
    6436              :                 else
    6437     98372574 :                   tem = simplify_binary_operation (ncode, mode, lhs, rhs);
    6438              : 
    6439     98374332 :                 if (tem)
    6440              :                   {
    6441              :                     /* Reject "simplifications" that just wrap the two
    6442              :                        arguments in a CONST.  Failure to do so can result
    6443              :                        in infinite recursion with simplify_binary_operation
    6444              :                        when it calls us to simplify CONST operations.
    6445              :                        Also, if we find such a simplification, don't try
    6446              :                        any more combinations with this rhs:  We must have
    6447              :                        something like symbol+offset, ie. one of the
    6448              :                        trivial CONST expressions we handle later.  */
    6449     25629448 :                     if (GET_CODE (tem) == CONST
    6450       929052 :                         && GET_CODE (XEXP (tem, 0)) == ncode
    6451       928500 :                         && XEXP (XEXP (tem, 0), 0) == lhs
    6452       927294 :                         && XEXP (XEXP (tem, 0), 1) == rhs)
    6453              :                       break;
    6454     24702154 :                     lneg &= rneg;
    6455     24702154 :                     if (GET_CODE (tem) == NEG)
    6456        45412 :                       tem = XEXP (tem, 0), lneg = !lneg;
    6457     24702154 :                     if (poly_int_rtx_p (tem) && lneg)
    6458            0 :                       tem = neg_poly_int_rtx (mode, tem), lneg = 0;
    6459              : 
    6460     24702154 :                     ops[i].op = tem;
    6461     24702154 :                     ops[i].neg = lneg;
    6462     24702154 :                     ops[j].op = NULL_RTX;
    6463     24702154 :                     changed = 1;
    6464     24702154 :                     canonicalized = 1;
    6465              :                   }
    6466              :               }
    6467              :           }
    6468              : 
    6469     62985579 :       if (!changed)
    6470              :         break;
    6471              : 
    6472              :       /* Pack all the operands to the lower-numbered entries.  */
    6473     97964545 :       for (i = 0, j = 0; j < n_ops; j++)
    6474     73718378 :         if (ops[j].op)
    6475              :           {
    6476     49016224 :             ops[i] = ops[j];
    6477     49016224 :             i++;
    6478              :           }
    6479              :       n_ops = i;
    6480              :     }
    6481              : 
    6482              :   /* If nothing changed, check that rematerialization of rtl instructions
    6483              :      is still required.  */
    6484     38739412 :   if (!canonicalized)
    6485              :     {
    6486              :       /* Perform rematerialization if only all operands are registers and
    6487              :          all operations are PLUS.  */
    6488              :       /* ??? Also disallow (non-global, non-frame) fixed registers to work
    6489              :          around rs6000 and how it uses the CA register.  See PR67145.  */
    6490      5133408 :       for (i = 0; i < n_ops; i++)
    6491      4142371 :         if (ops[i].neg
    6492      3858398 :             || !REG_P (ops[i].op)
    6493      7425358 :             || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
    6494       324239 :                 && fixed_regs[REGNO (ops[i].op)]
    6495          251 :                 && !global_regs[REGNO (ops[i].op)]
    6496          251 :                 && ops[i].op != frame_pointer_rtx
    6497          165 :                 && ops[i].op != arg_pointer_rtx
    6498          149 :                 && ops[i].op != stack_pointer_rtx))
    6499              :           return NULL_RTX;
    6500       991037 :       goto gen_result;
    6501              :     }
    6502              : 
    6503              :   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
    6504     36888991 :   if (n_ops == 2
    6505     22553212 :       && CONST_INT_P (ops[1].op)
    6506     21937493 :       && CONSTANT_P (ops[0].op)
    6507          160 :       && ops[0].neg)
    6508           54 :     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
    6509              : 
    6510              :   /* We suppressed creation of trivial CONST expressions in the
    6511              :      combination loop to avoid recursion.  Create one manually now.
    6512              :      The combination loop should have ensured that there is exactly
    6513              :      one CONST_INT, and the sort will have ensured that it is last
    6514              :      in the array and that any other constant will be next-to-last.  */
    6515              : 
    6516     36888937 :   if (n_ops > 1
    6517     36373397 :       && poly_int_rtx_p (ops[n_ops - 1].op)
    6518     70681844 :       && CONSTANT_P (ops[n_ops - 2].op))
    6519              :     {
    6520      1522748 :       rtx value = ops[n_ops - 1].op;
    6521      1522748 :       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
    6522       681428 :         value = neg_poly_int_rtx (mode, value);
    6523      1522748 :       if (CONST_INT_P (value))
    6524              :         {
    6525      3045496 :           ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
    6526      1522748 :                                              INTVAL (value));
    6527      1522748 :           n_ops--;
    6528              :         }
    6529              :     }
    6530              : 
    6531              :   /* Put a non-negated operand first, if possible.  */
    6532              : 
    6533     38573259 :   for (i = 0; i < n_ops && ops[i].neg; i++)
    6534      1684322 :     continue;
    6535     36888937 :   if (i == n_ops)
    6536         8996 :     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
    6537     36879941 :   else if (i != 0)
    6538              :     {
    6539      1581964 :       tem = ops[0].op;
    6540      1581964 :       ops[0] = ops[i];
    6541      1581964 :       ops[i].op = tem;
    6542      1581964 :       ops[i].neg = 1;
    6543              :     }
    6544              : 
    6545              :   /* Now make the result by performing the requested operations.  */
    6546     35297977 :  gen_result:
    6547     37879974 :   result = ops[0].op;
    6548     89318879 :   for (i = 1; i < n_ops; i++)
    6549    102877810 :     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
    6550              :                              mode, result, ops[i].op);
    6551              : 
    6552              :   return result;
    6553      1684322 : }
    6554              : 
    6555              : /* Check whether an operand is suitable for calling simplify_plus_minus.  */
    6556              : static bool
    6557    524278745 : plus_minus_operand_p (const_rtx x)
    6558              : {
    6559    524278745 :   return GET_CODE (x) == PLUS
    6560    524278745 :          || GET_CODE (x) == MINUS
    6561    524278745 :          || (GET_CODE (x) == CONST
    6562      1966580 :              && GET_CODE (XEXP (x, 0)) == PLUS
    6563      1343535 :              && CONSTANT_P (XEXP (XEXP (x, 0), 0))
    6564      1269590 :              && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
    6565              : }
    6566              : 
    6567              : /* Like simplify_binary_operation except used for relational operators.
    6568              :    MODE is the mode of the result. If MODE is VOIDmode, both operands must
    6569              :    not also be VOIDmode.
    6570              : 
    6571              :    CMP_MODE specifies in which mode the comparison is done in, so it is
    6572              :    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
    6573              :    the operands or, if both are VOIDmode, the operands are compared in
    6574              :    "infinite precision".  */
    6575              : rtx
    6576    127336321 : simplify_context::simplify_relational_operation (rtx_code code,
    6577              :                                                  machine_mode mode,
    6578              :                                                  machine_mode cmp_mode,
    6579              :                                                  rtx op0, rtx op1)
    6580              : {
    6581    127336321 :   rtx tem, trueop0, trueop1;
    6582              : 
    6583    127336321 :   if (cmp_mode == VOIDmode)
    6584     28083317 :     cmp_mode = GET_MODE (op0);
    6585     28083317 :   if (cmp_mode == VOIDmode)
    6586       264566 :     cmp_mode = GET_MODE (op1);
    6587              : 
    6588    127336321 :   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
    6589    127336321 :   if (tem)
    6590       778747 :     return relational_result (mode, cmp_mode, tem);
    6591              : 
    6592              :   /* For the following tests, ensure const0_rtx is op1.  */
    6593    126557574 :   if (swap_commutative_operands_p (op0, op1)
    6594    126557574 :       || (op0 == const0_rtx && op1 != const0_rtx))
    6595      2607365 :     std::swap (op0, op1), code = swap_condition (code);
    6596              : 
    6597              :   /* If op0 is a compare, extract the comparison arguments from it.  */
    6598    126557574 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    6599     13791132 :     return simplify_gen_relational (code, mode, VOIDmode,
    6600     13791132 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6601              : 
    6602    112766442 :   if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    6603              :     return NULL_RTX;
    6604              : 
    6605     82961673 :   trueop0 = avoid_constant_pool_reference (op0);
    6606     82961673 :   trueop1 = avoid_constant_pool_reference (op1);
    6607     82961673 :   return simplify_relational_operation_1 (code, mode, cmp_mode,
    6608     82961673 :                                           trueop0, trueop1);
    6609              : }
    6610              : 
    6611              : /* This part of simplify_relational_operation is only used when CMP_MODE
    6612              :    is not in class MODE_CC (i.e. it is a real comparison).
    6613              : 
    6614              :    MODE is the mode of the result, while CMP_MODE specifies in which
    6615              :    mode the comparison is done in, so it is the mode of the operands.  */
    6616              : 
    6617              : rtx
    6618     82961673 : simplify_context::simplify_relational_operation_1 (rtx_code code,
    6619              :                                                    machine_mode mode,
    6620              :                                                    machine_mode cmp_mode,
    6621              :                                                    rtx op0, rtx op1)
    6622              : {
    6623     82961673 :   enum rtx_code op0code = GET_CODE (op0);
    6624              : 
    6625     82961673 :   if (op1 == const0_rtx && COMPARISON_P (op0))
    6626              :     {
    6627              :       /* If op0 is a comparison, extract the comparison arguments
    6628              :          from it.  */
    6629       267380 :       if (code == NE)
    6630              :         {
    6631       118924 :           if (GET_MODE (op0) == mode)
    6632          187 :             return simplify_rtx (op0);
    6633              :           else
    6634       118737 :             return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
    6635       118737 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6636              :         }
    6637       148456 :       else if (code == EQ)
    6638              :         {
    6639       116944 :           enum rtx_code new_code = reversed_comparison_code (op0, NULL);
    6640       116944 :           if (new_code != UNKNOWN)
    6641       116627 :             return simplify_gen_relational (new_code, mode, VOIDmode,
    6642       116627 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6643              :         }
    6644              :     }
    6645              : 
    6646              :   /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
    6647              :      (GEU/LTU a -C).  Likewise for (LTU/GEU (PLUS a C) a).  */
    6648     82726122 :   if ((code == LTU || code == GEU)
    6649      5155639 :       && GET_CODE (op0) == PLUS
    6650       694915 :       && CONST_INT_P (XEXP (op0, 1))
    6651       472647 :       && (rtx_equal_p (op1, XEXP (op0, 0))
    6652       335157 :           || rtx_equal_p (op1, XEXP (op0, 1)))
    6653              :       /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
    6654     82929366 :       && XEXP (op0, 1) != const0_rtx)
    6655              :     {
    6656       203244 :       rtx new_cmp
    6657       203244 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6658       204775 :       return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
    6659       203244 :                                       cmp_mode, XEXP (op0, 0), new_cmp);
    6660              :     }
    6661              : 
    6662              :   /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
    6663              :      transformed into (LTU a -C).  */
    6664     82522878 :   if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
    6665       330545 :       && CONST_INT_P (XEXP (op0, 1))
    6666       260544 :       && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
    6667        26643 :       && XEXP (op0, 1) != const0_rtx)
    6668              :     {
    6669        26643 :       rtx new_cmp
    6670        26643 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6671        26643 :       return simplify_gen_relational (LTU, mode, cmp_mode,
    6672        26643 :                                        XEXP (op0, 0), new_cmp);
    6673              :     }
    6674              : 
    6675              :   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
    6676     82496235 :   if ((code == LTU || code == GEU)
    6677      4952395 :       && GET_CODE (op0) == PLUS
    6678       491671 :       && rtx_equal_p (op1, XEXP (op0, 1))
    6679              :       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
    6680     82501652 :       && !rtx_equal_p (op1, XEXP (op0, 0)))
    6681         5417 :     return simplify_gen_relational (code, mode, cmp_mode, op0,
    6682         5417 :                                     copy_rtx (XEXP (op0, 0)));
    6683              : 
    6684     82490818 :   if (op1 == const0_rtx)
    6685              :     {
    6686              :       /* Canonicalize (GTU x 0) as (NE x 0).  */
    6687     36744392 :       if (code == GTU)
    6688        75465 :         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
    6689              :       /* Canonicalize (LEU x 0) as (EQ x 0).  */
    6690     36668927 :       if (code == LEU)
    6691        32890 :         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
    6692              : 
    6693     36636037 :       if ((code == NE || code == EQ)
    6694              :           /* Verify op0 is IOR */
    6695     32936540 :           && GET_CODE (op0) == IOR
    6696              :           /* only enters if op1 is 0 */
    6697              :           /* Verify IOR operand is NE */
    6698       544937 :           && GET_CODE (XEXP (op0, 0)) == NE
    6699        16473 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
    6700              :           /* Verify second NE operand is 0 */
    6701          105 :           && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
    6702              :         {
    6703           31 :           rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
    6704           31 :           t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
    6705           31 :           return t;
    6706              :         }
    6707              : 
    6708              :     }
    6709     45746426 :   else if (op1 == const1_rtx)
    6710              :     {
    6711      3031078 :       switch (code)
    6712              :         {
    6713         8594 :         case GE:
    6714              :           /* Canonicalize (GE x 1) as (GT x 0).  */
    6715         8594 :           return simplify_gen_relational (GT, mode, cmp_mode,
    6716         8594 :                                           op0, const0_rtx);
    6717       195840 :         case GEU:
    6718              :           /* Canonicalize (GEU x 1) as (NE x 0).  */
    6719       195840 :           return simplify_gen_relational (NE, mode, cmp_mode,
    6720       195840 :                                           op0, const0_rtx);
    6721        10388 :         case LT:
    6722              :           /* Canonicalize (LT x 1) as (LE x 0).  */
    6723        10388 :           return simplify_gen_relational (LE, mode, cmp_mode,
    6724        10388 :                                           op0, const0_rtx);
    6725        51218 :         case LTU:
    6726              :           /* Canonicalize (LTU x 1) as (EQ x 0).  */
    6727        51218 :           return simplify_gen_relational (EQ, mode, cmp_mode,
    6728        51218 :                                           op0, const0_rtx);
    6729              :         default:
    6730              :           break;
    6731              :         }
    6732              :     }
    6733     42715348 :   else if (op1 == constm1_rtx)
    6734              :     {
    6735              :       /* Canonicalize (LE x -1) as (LT x 0).  */
    6736       991730 :       if (code == LE)
    6737         1568 :         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
    6738              :       /* Canonicalize (GT x -1) as (GE x 0).  */
    6739       990162 :       if (code == GT)
    6740         5186 :         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
    6741              :     }
    6742              : 
    6743              :   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
    6744     78410141 :   if ((code == EQ || code == NE)
    6745     61177412 :       && (op0code == PLUS || op0code == MINUS)
    6746      2407042 :       && CONSTANT_P (op1)
    6747       884437 :       && CONSTANT_P (XEXP (op0, 1))
    6748       497736 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6749              :     {
    6750       497703 :       rtx x = XEXP (op0, 0);
    6751       497703 :       rtx c = XEXP (op0, 1);
    6752       497703 :       enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
    6753       497703 :       rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
    6754              : 
    6755              :       /* Detect an infinite recursive condition, where we oscillate at this
    6756              :          simplification case between:
    6757              :             A + B == C  <--->  C - B == A,
    6758              :          where A, B, and C are all constants with non-simplifiable expressions,
    6759              :          usually SYMBOL_REFs.  */
    6760       497703 :       if (GET_CODE (tem) == invcode
    6761           57 :           && CONSTANT_P (x)
    6762       497721 :           && rtx_equal_p (c, XEXP (tem, 1)))
    6763              :         return NULL_RTX;
    6764              : 
    6765       497685 :       return simplify_gen_relational (code, mode, cmp_mode, x, tem);
    6766              :     }
    6767              : 
    6768              :   /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0).  */
    6769     60679709 :   if ((code == EQ || code == NE)
    6770     60679709 :       && op0code == PLUS
    6771      1585240 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6772         3578 :       && !side_effects_p (op1)
    6773         3578 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6774         3566 :     return simplify_gen_relational (code, mode, cmp_mode,
    6775         3566 :                                     XEXP (op0, 0), CONST0_RTX (cmp_mode));
    6776              : 
    6777              :   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
    6778              :      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
    6779     81608369 :   scalar_int_mode int_mode, int_cmp_mode;
    6780     81608369 :   if (code == NE
    6781     32254111 :       && op1 == const0_rtx
    6782      2195220 :       && is_int_mode (mode, &int_mode)
    6783     83729823 :       && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
    6784              :       /* ??? Work-around BImode bugs in the ia64 backend.  */
    6785      2195220 :       && int_mode != BImode
    6786      2195196 :       && int_cmp_mode != BImode
    6787      2195196 :       && nonzero_bits (op0, int_cmp_mode) == 1
    6788     81608369 :       && STORE_FLAG_VALUE == 1)
    6789       147532 :     return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
    6790        73766 :            ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
    6791        18153 :            : lowpart_subreg (int_mode, op0, int_cmp_mode);
    6792              : 
    6793              :   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
    6794     81534603 :   if ((code == EQ || code == NE)
    6795     60602377 :       && op1 == const0_rtx
    6796     32791066 :       && op0code == XOR)
    6797        13028 :     return simplify_gen_relational (code, mode, cmp_mode,
    6798        13028 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6799              : 
    6800              :   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
    6801     60589349 :   if ((code == EQ || code == NE)
    6802     60589349 :       && op0code == XOR
    6803         4735 :       && rtx_equal_p (XEXP (op0, 0), op1)
    6804            6 :       && !side_effects_p (XEXP (op0, 0)))
    6805            0 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
    6806            0 :                                     CONST0_RTX (mode));
    6807              : 
    6808              :   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
    6809     81521575 :   if ((code == EQ || code == NE)
    6810     60589349 :       && op0code == XOR
    6811         4735 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6812     81521729 :       && !side_effects_p (XEXP (op0, 1)))
    6813          154 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6814          154 :                                     CONST0_RTX (mode));
    6815              : 
    6816              :   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
    6817     81521421 :   if ((code == EQ || code == NE)
    6818     60589195 :       && op0code == XOR
    6819         4581 :       && CONST_SCALAR_INT_P (op1)
    6820          970 :       && CONST_SCALAR_INT_P (XEXP (op0, 1)))
    6821          437 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6822              :                                     simplify_gen_binary (XOR, cmp_mode,
    6823          437 :                                                          XEXP (op0, 1), op1));
    6824              : 
    6825              :   /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
    6826              :      constant folding if x/y is a constant.  */
    6827     60588758 :   if ((code == EQ || code == NE)
    6828     60588758 :       && (op0code == AND || op0code == IOR)
    6829      3684449 :       && !side_effects_p (op1)
    6830      3684343 :       && op1 != CONST0_RTX (cmp_mode))
    6831              :     {
    6832              :       /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
    6833              :          (eq/ne (and (not y) x) 0).  */
    6834       403569 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
    6835       808833 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
    6836              :         {
    6837        24916 :           rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
    6838              :                                           cmp_mode);
    6839        24916 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
    6840              : 
    6841        24916 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6842        24916 :                                           CONST0_RTX (cmp_mode));
    6843              :         }
    6844              : 
    6845              :       /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
    6846              :          (eq/ne (and (not x) y) 0).  */
    6847       378728 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
    6848       741343 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
    6849              :         {
    6850        42596 :           rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
    6851              :                                           cmp_mode);
    6852        42596 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
    6853              : 
    6854        42596 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6855        42596 :                                           CONST0_RTX (cmp_mode));
    6856              :         }
    6857              :     }
    6858              : 
    6859              :   /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
    6860              :      relationship.  */
    6861     81453472 :   if ((op0code == AND || op0code == IOR)
    6862      3797305 :       && CONST_INT_P (op1)
    6863      3621844 :       && CONST_INT_P (XEXP (op0, 1)))
    6864              :     {
    6865      2434644 :       unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
    6866      2434644 :       unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
    6867              : 
    6868              :       /* For AND operations:
    6869              :            - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
    6870              :            - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
    6871              :            - (x & c1) >= c2 when c1 is less than c2 -> false
    6872              :            - (x & c1) < c2 when c1 is less than c2 -> true
    6873              :            - (x & c1) > c2 when c1 is less than or equal to c2 -> false
    6874              :            - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
    6875              : 
    6876              :          For IOR operations:
    6877              :            - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
    6878              :            - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
    6879              :            - (x | c1) <= c2 when c1 is greater than c2 -> false
    6880              :            - (x | c1) > c2 when c1 is greater than c2 -> true
    6881              :            - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
    6882              :            - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
    6883      2434644 :       if ((op0code == AND
    6884      2430402 :            && ((code == EQ && (c1 & c2) != c2)
    6885      2430389 :                || (code == GEU && c1 < c2)
    6886      2430389 :                || (code == GTU && c1 <= c2)))
    6887      2434631 :           || ((op0code == IOR
    6888         4242 :               && ((code == EQ && (c1 & c2) != c1)
    6889         4238 :                   || (code == LEU && c1 > c2)
    6890         4238 :                   || (code == LTU && c1 >= c2)))))
    6891           17 :         return const0_rtx;
    6892              : 
    6893      2434627 :       if ((op0code == AND
    6894      2430389 :            && ((code == NE && (c1 & c2) != c2)
    6895      2430314 :                || (code == LTU && c1 < c2)
    6896      2430314 :                || (code == LEU && c1 <= c2)))
    6897      2434552 :           || ((op0code == IOR
    6898         4238 :               && ((code == NE && (c1 & c2) != c1)
    6899         4178 :                   || (code == GTU && c1 > c2)
    6900         4178 :                   || (code == GEU && c1 >= c2)))))
    6901          135 :         return const_true_rtx;
    6902              :     }
    6903              : 
    6904              :   /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped.  */
    6905     81453320 :   if ((code == EQ || code == NE)
    6906     60521094 :       && GET_CODE (op0) == BSWAP
    6907          324 :       && CONST_SCALAR_INT_P (op1))
    6908           93 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6909              :                                     simplify_gen_unary (BSWAP, cmp_mode,
    6910           93 :                                                         op1, cmp_mode));
    6911              : 
    6912              :   /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y).  */
    6913     60521001 :   if ((code == EQ || code == NE)
    6914     60521001 :       && GET_CODE (op0) == BSWAP
    6915          231 :       && GET_CODE (op1) == BSWAP)
    6916           18 :     return simplify_gen_relational (code, mode, cmp_mode,
    6917           18 :                                     XEXP (op0, 0), XEXP (op1, 0));
    6918              : 
    6919     81453209 :   if (op0code == POPCOUNT && op1 == const0_rtx)
    6920            0 :     switch (code)
    6921              :       {
    6922            0 :       case EQ:
    6923            0 :       case LE:
    6924            0 :       case LEU:
    6925              :         /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
    6926            0 :         return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
    6927              :                                         XEXP (op0, 0),
    6928            0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    6929              : 
    6930            0 :       case NE:
    6931            0 :       case GT:
    6932            0 :       case GTU:
    6933              :         /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
    6934            0 :         return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
    6935              :                                         XEXP (op0, 0),
    6936            0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    6937              : 
    6938              :       default:
    6939              :         break;
    6940              :       }
    6941              : 
    6942              :   /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1).  */
    6943     81453209 :   if (code == NE
    6944     32139366 :       && op1 == const0_rtx
    6945     16528376 :       && (op0code == TRUNCATE
    6946       149842 :           || (partial_subreg_p (op0)
    6947       149098 :               && subreg_lowpart_p (op0)))
    6948       125843 :       && SCALAR_INT_MODE_P (mode)
    6949     81453209 :       && STORE_FLAG_VALUE == 1)
    6950              :     {
    6951        30841 :       rtx tmp = XEXP (op0, 0);
    6952        30841 :       if (GET_CODE (tmp) == ASHIFT
    6953         2440 :           && GET_MODE (tmp) == mode
    6954          229 :           && CONST_INT_P (XEXP (tmp, 1))
    6955          229 :           && is_int_mode (GET_MODE (op0), &int_mode)
    6956        31070 :           && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    6957          229 :         return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
    6958              :     }
    6959              : 
    6960              :   /* For two unsigned booleans A and B:
    6961              : 
    6962              :      A >  B == ~B & A
    6963              :      A >= B == ~B | A
    6964              :      A <  B == ~A & B
    6965              :      A <= B == ~A | B
    6966              :      A == B == ~A ^ B (== ~B ^ A)
    6967              :      A != B ==  A ^ B
    6968              : 
    6969              :      For signed comparisons, we have to take STORE_FLAG_VALUE into account,
    6970              :      with the rules above applying for positive STORE_FLAG_VALUE and with
    6971              :      the relations reversed for negative STORE_FLAG_VALUE.  */
    6972     81452980 :   if (is_a<scalar_int_mode> (cmp_mode)
    6973     78806349 :       && COMPARISON_P (op0)
    6974     81565691 :       && COMPARISON_P (op1))
    6975              :     {
    6976        10039 :       rtx t = NULL_RTX;
    6977        10039 :       if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
    6978          755 :         t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
    6979              :       else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
    6980          720 :         t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
    6981              :       else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
    6982          720 :         t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
    6983              :       else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
    6984          720 :         t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
    6985              :       else if (code == EQ)
    6986         3252 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
    6987              :       else if (code == NE)
    6988         3872 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1);
    6989        10039 :       if (t)
    6990              :         return t;
    6991              :     }
    6992              : 
    6993              :   return NULL_RTX;
    6994              : }
    6995              : 
    6996              : enum
    6997              : {
    6998              :   CMP_EQ = 1,
    6999              :   CMP_LT = 2,
    7000              :   CMP_GT = 4,
    7001              :   CMP_LTU = 8,
    7002              :   CMP_GTU = 16
    7003              : };
    7004              : 
    7005              : 
    7006              : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
    7007              :    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
    7008              :    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
    7009              :    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
    7010              :    For floating-point comparisons, assume that the operands were ordered.  */
    7011              : 
    7012              : static rtx
    7013       711165 : comparison_result (enum rtx_code code, int known_results)
    7014              : {
    7015       711165 :   switch (code)
    7016              :     {
    7017       130806 :     case EQ:
    7018       130806 :     case UNEQ:
    7019       130806 :       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
    7020       443717 :     case NE:
    7021       443717 :     case LTGT:
    7022       443717 :       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
    7023              : 
    7024         9480 :     case LT:
    7025         9480 :     case UNLT:
    7026         9480 :       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
    7027         8616 :     case GE:
    7028         8616 :     case UNGE:
    7029         8616 :       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
    7030              : 
    7031        12724 :     case GT:
    7032        12724 :     case UNGT:
    7033        12724 :       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
    7034        14713 :     case LE:
    7035        14713 :     case UNLE:
    7036        14713 :       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
    7037              : 
    7038        23956 :     case LTU:
    7039        23956 :       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
    7040         8832 :     case GEU:
    7041         8832 :       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
    7042              : 
    7043        47806 :     case GTU:
    7044        47806 :       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
    7045        10507 :     case LEU:
    7046        10507 :       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
    7047              : 
    7048            0 :     case ORDERED:
    7049            0 :       return const_true_rtx;
    7050            8 :     case UNORDERED:
    7051            8 :       return const0_rtx;
    7052            0 :     default:
    7053            0 :       gcc_unreachable ();
    7054              :     }
    7055              : }
    7056              : 
    7057              : /* Check if the given comparison (done in the given MODE) is actually
    7058              :    a tautology or a contradiction.  If the mode is VOIDmode, the
    7059              :    comparison is done in "infinite precision".  If no simplification
    7060              :    is possible, this function returns zero.  Otherwise, it returns
    7061              :    either const_true_rtx or const0_rtx.  */
    7062              : 
    7063              : rtx
    7064    127426465 : simplify_const_relational_operation (enum rtx_code code,
    7065              :                                      machine_mode mode,
    7066              :                                      rtx op0, rtx op1)
    7067              : {
    7068    134126556 :   rtx tem;
    7069    134126556 :   rtx trueop0;
    7070    134126556 :   rtx trueop1;
    7071              : 
    7072    134126556 :   gcc_assert (mode != VOIDmode
    7073              :               || (GET_MODE (op0) == VOIDmode
    7074              :                   && GET_MODE (op1) == VOIDmode));
    7075              : 
    7076              :   /* We only handle MODE_CC comparisons that are COMPARE against zero.  */
    7077    134126556 :   if (GET_MODE_CLASS (mode) == MODE_CC
    7078     43601665 :       && (op1 != const0_rtx
    7079     43601665 :           || GET_CODE (op0) != COMPARE))
    7080              :     return NULL_RTX;
    7081              : 
    7082              :   /* If op0 is a compare, extract the comparison arguments from it.  */
    7083    104321787 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    7084              :     {
    7085     13796896 :       op1 = XEXP (op0, 1);
    7086     13796896 :       op0 = XEXP (op0, 0);
    7087              : 
    7088     13796896 :       if (GET_MODE (op0) != VOIDmode)
    7089     13653580 :         mode = GET_MODE (op0);
    7090       143316 :       else if (GET_MODE (op1) != VOIDmode)
    7091       111229 :         mode = GET_MODE (op1);
    7092              :       else
    7093              :         return 0;
    7094              :     }
    7095              : 
    7096              :   /* We can't simplify MODE_CC values since we don't know what the
    7097              :      actual comparison is.  */
    7098    104289700 :   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
    7099              :     return 0;
    7100              : 
    7101              :   /* Make sure the constant is second.  */
    7102    104289700 :   if (swap_commutative_operands_p (op0, op1))
    7103              :     {
    7104      2995986 :       std::swap (op0, op1);
    7105      2995986 :       code = swap_condition (code);
    7106              :     }
    7107              : 
    7108    104289700 :   trueop0 = avoid_constant_pool_reference (op0);
    7109    104289700 :   trueop1 = avoid_constant_pool_reference (op1);
    7110              : 
    7111              :   /* For integer comparisons of A and B maybe we can simplify A - B and can
    7112              :      then simplify a comparison of that with zero.  If A and B are both either
    7113              :      a register or a CONST_INT, this can't help; testing for these cases will
    7114              :      prevent infinite recursion here and speed things up.
    7115              : 
    7116              :      We can only do this for EQ and NE comparisons as otherwise we may
    7117              :      lose or introduce overflow which we cannot disregard as undefined as
    7118              :      we do not know the signedness of the operation on either the left or
    7119              :      the right hand side of the comparison.  */
    7120              : 
    7121    104289700 :   if (INTEGRAL_MODE_P (mode)
    7122    101659522 :       && trueop1 != CONST0_RTX (mode)
    7123     51729464 :       && (code == EQ || code == NE)
    7124     32682814 :       && ! ((REG_P (op0)
    7125      9570983 :              || CONST_SCALAR_INT_P (trueop0)
    7126      9542931 :              || CONST_VECTOR_P (trueop0))
    7127     23139903 :             && (REG_P (op1)
    7128     13832725 :                 || CONST_SCALAR_INT_P (trueop1)
    7129      3308239 :                 || CONST_VECTOR_P (trueop1)))
    7130     12848970 :       && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
    7131              :       /* We cannot do this if tem is a nonzero address.  */
    7132      6700093 :       && ! nonzero_address_p (tem))
    7133      6700091 :     return simplify_const_relational_operation (signed_condition (code),
    7134      6700091 :                                                 mode, tem, CONST0_RTX (mode));
    7135              : 
    7136     97589609 :   if (! HONOR_NANS (mode) && code == ORDERED)
    7137            0 :     return const_true_rtx;
    7138              : 
    7139     97589609 :   if (! HONOR_NANS (mode) && code == UNORDERED)
    7140            8 :     return const0_rtx;
    7141              : 
    7142              :   /* For modes without NaNs, if the two operands are equal, we know the
    7143              :      result except if they have side-effects.  Even with NaNs we know
    7144              :      the result of unordered comparisons and, if signaling NaNs are
    7145              :      irrelevant, also the result of LT/GT/LTGT.  */
    7146     97589601 :   if ((! HONOR_NANS (trueop0)
    7147      2140407 :        || code == UNEQ || code == UNLE || code == UNGE
    7148              :        || ((code == LT || code == GT || code == LTGT)
    7149       885434 :            && ! HONOR_SNANS (trueop0)))
    7150     96439605 :       && rtx_equal_p (trueop0, trueop1)
    7151     98097238 :       && ! side_effects_p (trueop0))
    7152       507548 :     return comparison_result (code, CMP_EQ);
    7153              : 
    7154              :   /* If the operands are floating-point constants, see if we can fold
    7155              :      the result.  */
    7156     97082053 :   if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
    7157         1293 :       && CONST_DOUBLE_AS_FLOAT_P (trueop1)
    7158         1293 :       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
    7159              :     {
    7160         1293 :       const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
    7161         1293 :       const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    7162              : 
    7163              :       /* Comparisons are unordered iff at least one of the values is NaN.  */
    7164         1293 :       if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
    7165          174 :         switch (code)
    7166              :           {
    7167            0 :           case UNEQ:
    7168            0 :           case UNLT:
    7169            0 :           case UNGT:
    7170            0 :           case UNLE:
    7171            0 :           case UNGE:
    7172            0 :           case NE:
    7173            0 :           case UNORDERED:
    7174            0 :             return const_true_rtx;
    7175          174 :           case EQ:
    7176          174 :           case LT:
    7177          174 :           case GT:
    7178          174 :           case LE:
    7179          174 :           case GE:
    7180          174 :           case LTGT:
    7181          174 :           case ORDERED:
    7182          174 :             return const0_rtx;
    7183              :           default:
    7184              :             return 0;
    7185              :           }
    7186              : 
    7187         1204 :       return comparison_result (code,
    7188         1204 :                                 (real_equal (d0, d1) ? CMP_EQ :
    7189         1204 :                                  real_less (d0, d1) ? CMP_LT : CMP_GT));
    7190              :     }
    7191              : 
    7192              :   /* Otherwise, see if the operands are both integers.  */
    7193     97080760 :   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
    7194     94032938 :       && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
    7195              :     {
    7196              :       /* It would be nice if we really had a mode here.  However, the
    7197              :          largest int representable on the target is as good as
    7198              :          infinite.  */
    7199       202498 :       machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
    7200       202498 :       rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
    7201       202498 :       rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
    7202              : 
    7203       202498 :       if (wi::eq_p (ptrueop0, ptrueop1))
    7204            0 :         return comparison_result (code, CMP_EQ);
    7205              :       else
    7206              :         {
    7207       202498 :           int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
    7208       202498 :           cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
    7209       202498 :           return comparison_result (code, cr);
    7210              :         }
    7211              :     }
    7212              : 
    7213              :   /* Optimize comparisons with upper and lower bounds.  */
    7214     96878262 :   scalar_int_mode int_mode;
    7215     96878262 :   if (CONST_INT_P (trueop1)
    7216     67603699 :       && is_a <scalar_int_mode> (mode, &int_mode)
    7217     67603699 :       && HWI_COMPUTABLE_MODE_P (int_mode)
    7218    164038006 :       && !side_effects_p (trueop0))
    7219              :     {
    7220     67009440 :       int sign;
    7221     67009440 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
    7222     67009440 :       HOST_WIDE_INT val = INTVAL (trueop1);
    7223     67009440 :       HOST_WIDE_INT mmin, mmax;
    7224              : 
    7225     67009440 :       if (code == GEU
    7226     67009440 :           || code == LEU
    7227     63840006 :           || code == GTU
    7228     63840006 :           || code == LTU)
    7229              :         sign = 0;
    7230              :       else
    7231     67009440 :         sign = 1;
    7232              : 
    7233              :       /* Get a reduced range if the sign bit is zero.  */
    7234     67009440 :       if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
    7235              :         {
    7236      6280569 :           mmin = 0;
    7237      6280569 :           mmax = nonzero;
    7238              :         }
    7239              :       else
    7240              :         {
    7241     60728871 :           rtx mmin_rtx, mmax_rtx;
    7242     60728871 :           get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
    7243              : 
    7244     60728871 :           mmin = INTVAL (mmin_rtx);
    7245     60728871 :           mmax = INTVAL (mmax_rtx);
    7246     60728871 :           if (sign)
    7247              :             {
    7248     55008147 :               unsigned int sign_copies
    7249     55008147 :                 = num_sign_bit_copies (trueop0, int_mode);
    7250              : 
    7251     55008147 :               mmin >>= (sign_copies - 1);
    7252     55008147 :               mmax >>= (sign_copies - 1);
    7253              :             }
    7254              :         }
    7255              : 
    7256     67009440 :       switch (code)
    7257              :         {
    7258              :         /* x >= y is always true for y <= mmin, always false for y > mmax.  */
    7259       549677 :         case GEU:
    7260       549677 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    7261        11262 :             return const_true_rtx;
    7262       538415 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    7263           50 :             return const0_rtx;
    7264              :           break;
    7265       944527 :         case GE:
    7266       944527 :           if (val <= mmin)
    7267         2062 :             return const_true_rtx;
    7268       942465 :           if (val > mmax)
    7269            0 :             return const0_rtx;
    7270              :           break;
    7271              : 
    7272              :         /* x <= y is always true for y >= mmax, always false for y < mmin.  */
    7273      2619757 :         case LEU:
    7274      2619757 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    7275        14576 :             return const_true_rtx;
    7276      2605181 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    7277            0 :             return const0_rtx;
    7278              :           break;
    7279      2344054 :         case LE:
    7280      2344054 :           if (val >= mmax)
    7281          460 :             return const_true_rtx;
    7282      2343594 :           if (val < mmin)
    7283            0 :             return const0_rtx;
    7284              :           break;
    7285              : 
    7286     24961991 :         case EQ:
    7287              :           /* x == y is always false for y out of range.  */
    7288     24961991 :           if (val < mmin || val > mmax)
    7289          441 :             return const0_rtx;
    7290              :           break;
    7291              : 
    7292              :         /* x > y is always false for y >= mmax, always true for y < mmin.  */
    7293      2155846 :         case GTU:
    7294      2155846 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    7295        39150 :             return const0_rtx;
    7296      2116696 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    7297            0 :             return const_true_rtx;
    7298              :           break;
    7299      1803118 :         case GT:
    7300      1803118 :           if (val >= mmax)
    7301          332 :             return const0_rtx;
    7302      1802786 :           if (val < mmin)
    7303            5 :             return const_true_rtx;
    7304              :           break;
    7305              : 
    7306              :         /* x < y is always false for y <= mmin, always true for y > mmax.  */
    7307       782824 :         case LTU:
    7308       782824 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    7309         2997 :             return const0_rtx;
    7310       779827 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    7311        79942 :             return const_true_rtx;
    7312              :           break;
    7313      1116854 :         case LT:
    7314      1116854 :           if (val <= mmin)
    7315         2304 :             return const0_rtx;
    7316      1114550 :           if (val > mmax)
    7317         3099 :             return const_true_rtx;
    7318              :           break;
    7319              : 
    7320     29730792 :         case NE:
    7321              :           /* x != y is always true for y out of range.  */
    7322     29730792 :           if (val < mmin || val > mmax)
    7323          120 :             return const_true_rtx;
    7324              :           break;
    7325              : 
    7326              :         default:
    7327              :           break;
    7328              :         }
    7329              :     }
    7330              : 
    7331              :   /* Optimize integer comparisons with zero.  */
    7332     96721462 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    7333     93716721 :       && trueop1 == const0_rtx
    7334     49202072 :       && !side_effects_p (trueop0))
    7335              :     {
    7336              :       /* Some addresses are known to be nonzero.  We don't know
    7337              :          their sign, but equality comparisons are known.  */
    7338     49049613 :       if (nonzero_address_p (trueop0))
    7339              :         {
    7340          540 :           if (code == EQ || code == LEU)
    7341          278 :             return const0_rtx;
    7342          262 :           if (code == NE || code == GTU)
    7343          262 :             return const_true_rtx;
    7344              :         }
    7345              : 
    7346              :       /* See if the first operand is an IOR with a constant.  If so, we
    7347              :          may be able to determine the result of this comparison.  */
    7348     49049073 :       if (GET_CODE (op0) == IOR)
    7349              :         {
    7350       627419 :           rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
    7351       627419 :           if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
    7352              :             {
    7353          288 :               int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
    7354          576 :               int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
    7355          288 :                               && (UINTVAL (inner_const)
    7356          288 :                                   & (HOST_WIDE_INT_1U
    7357              :                                      << sign_bitnum)));
    7358              : 
    7359          288 :               switch (code)
    7360              :                 {
    7361              :                 case EQ:
    7362              :                 case LEU:
    7363              :                   return const0_rtx;
    7364            4 :                 case NE:
    7365            4 :                 case GTU:
    7366            4 :                   return const_true_rtx;
    7367           70 :                 case LT:
    7368           70 :                 case LE:
    7369           70 :                   if (has_sign)
    7370            2 :                     return const_true_rtx;
    7371              :                   break;
    7372          208 :                 case GT:
    7373          208 :                 case GE:
    7374          208 :                   if (has_sign)
    7375              :                     return const0_rtx;
    7376              :                   break;
    7377              :                 default:
    7378              :                   break;
    7379              :                 }
    7380              :             }
    7381              :         }
    7382              :     }
    7383              : 
    7384              :   /* Optimize comparison of ABS with zero.  */
    7385     49535859 :   if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
    7386    146103805 :       && (GET_CODE (trueop0) == ABS
    7387     49382504 :           || (GET_CODE (trueop0) == FLOAT_EXTEND
    7388           38 :               && GET_CODE (XEXP (trueop0, 0)) == ABS)))
    7389              :     {
    7390          583 :       switch (code)
    7391              :         {
    7392           60 :         case LT:
    7393              :           /* Optimize abs(x) < 0.0.  */
    7394           60 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
    7395            0 :             return const0_rtx;
    7396              :           break;
    7397              : 
    7398           42 :         case GE:
    7399              :           /* Optimize abs(x) >= 0.0.  */
    7400           42 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
    7401            0 :             return const_true_rtx;
    7402              :           break;
    7403              : 
    7404            0 :         case UNGE:
    7405              :           /* Optimize ! (abs(x) < 0.0).  */
    7406            0 :           return const_true_rtx;
    7407              : 
    7408              :         default:
    7409              :           break;
    7410              :         }
    7411              :     }
    7412              : 
    7413              :   return 0;
    7414              : }
    7415              : 
    7416              : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
    7417              :    where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
    7418              :    or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
    7419              :    can be simplified to that or NULL_RTX if not.
    7420              :    Assume X is compared against zero with CMP_CODE and the true
    7421              :    arm is TRUE_VAL and the false arm is FALSE_VAL.  */
    7422              : 
    7423              : rtx
    7424     30390013 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
    7425              :                                          rtx true_val, rtx false_val)
    7426              : {
    7427     30390013 :   if (cmp_code != EQ && cmp_code != NE)
    7428              :     return NULL_RTX;
    7429              : 
    7430              :   /* Result on X == 0 and X !=0 respectively.  */
    7431     21943142 :   rtx on_zero, on_nonzero;
    7432     21943142 :   if (cmp_code == EQ)
    7433              :     {
    7434              :       on_zero = true_val;
    7435              :       on_nonzero = false_val;
    7436              :     }
    7437              :   else
    7438              :     {
    7439     11791208 :       on_zero = false_val;
    7440     11791208 :       on_nonzero = true_val;
    7441              :     }
    7442              : 
    7443     21943142 :   rtx_code op_code = GET_CODE (on_nonzero);
    7444     21943142 :   if ((op_code != CLZ && op_code != CTZ)
    7445         1972 :       || !rtx_equal_p (XEXP (on_nonzero, 0), x)
    7446     21944173 :       || !CONST_INT_P (on_zero))
    7447     21942838 :     return NULL_RTX;
    7448              : 
    7449          304 :   HOST_WIDE_INT op_val;
    7450          304 :   scalar_int_mode mode ATTRIBUTE_UNUSED
    7451          304 :     = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
    7452            0 :   if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
    7453          608 :        || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
    7454          328 :       && op_val == INTVAL (on_zero))
    7455              :     return on_nonzero;
    7456              : 
    7457              :   return NULL_RTX;
    7458              : }
    7459              : 
    7460              : /* Try to simplify X given that it appears within operand OP of a
    7461              :    VEC_MERGE operation whose mask is MASK.  X need not use the same
    7462              :    vector mode as the VEC_MERGE, but it must have the same number of
    7463              :    elements.
    7464              : 
    7465              :    Return the simplified X on success, otherwise return NULL_RTX.  */
    7466              : 
    7467              : rtx
    7468      1647504 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
    7469              : {
    7470      1647504 :   gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
    7471      3295008 :   poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
    7472      1647504 :   if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
    7473              :     {
    7474         5491 :       if (side_effects_p (XEXP (x, 1 - op)))
    7475              :         return NULL_RTX;
    7476              : 
    7477         5267 :       return XEXP (x, op);
    7478              :     }
    7479      1642013 :   if (UNARY_P (x)
    7480       194093 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7481      1699721 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
    7482              :     {
    7483        24247 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7484        24247 :       if (top0)
    7485          448 :         return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
    7486          448 :                                    GET_MODE (XEXP (x, 0)));
    7487              :     }
    7488      1641565 :   if (BINARY_P (x)
    7489       207136 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7490       413742 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7491       181291 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7492      1929739 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
    7493              :     {
    7494       144087 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7495       144087 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7496       144087 :       if (top0 || top1)
    7497              :         {
    7498          952 :           if (COMPARISON_P (x))
    7499            0 :             return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
    7500            0 :                                             GET_MODE (XEXP (x, 0)) != VOIDmode
    7501              :                                             ? GET_MODE (XEXP (x, 0))
    7502            0 :                                             : GET_MODE (XEXP (x, 1)),
    7503              :                                             top0 ? top0 : XEXP (x, 0),
    7504            0 :                                             top1 ? top1 : XEXP (x, 1));
    7505              :           else
    7506          952 :             return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
    7507              :                                         top0 ? top0 : XEXP (x, 0),
    7508          952 :                                         top1 ? top1 : XEXP (x, 1));
    7509              :         }
    7510              :     }
    7511      1640613 :   if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
    7512        34869 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7513        69738 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7514        34869 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7515        69738 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
    7516        34869 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
    7517      1657097 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
    7518              :     {
    7519         8242 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7520         8242 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7521         8242 :       rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
    7522         8242 :       if (top0 || top1 || top2)
    7523          448 :         return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
    7524          448 :                                      GET_MODE (XEXP (x, 0)),
    7525              :                                      top0 ? top0 : XEXP (x, 0),
    7526              :                                      top1 ? top1 : XEXP (x, 1),
    7527          448 :                                      top2 ? top2 : XEXP (x, 2));
    7528              :     }
    7529              :   return NULL_RTX;
    7530              : }
    7531              : 
    7532              : 
    7533              : /* Simplify CODE, an operation with result mode MODE and three operands,
    7534              :    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
    7535              :    a constant.  Return 0 if no simplifications is possible.  */
    7536              : 
    7537              : rtx
    7538     41968082 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
    7539              :                                               machine_mode op0_mode,
    7540              :                                               rtx op0, rtx op1, rtx op2)
    7541              : {
    7542     41968082 :   bool any_change = false;
    7543     41968082 :   rtx tem, trueop2;
    7544     41968082 :   scalar_int_mode int_mode, int_op0_mode;
    7545     41968082 :   unsigned int n_elts;
    7546              : 
    7547     41968082 :   switch (code)
    7548              :     {
    7549       338663 :     case FMA:
    7550              :       /* Simplify negations around the multiplication.  */
    7551              :       /* -a * -b + c  =>  a * b + c.  */
    7552       338663 :       if (GET_CODE (op0) == NEG)
    7553              :         {
    7554        82421 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    7555        82421 :           if (tem)
    7556          271 :             op1 = tem, op0 = XEXP (op0, 0), any_change = true;
    7557              :         }
    7558       256242 :       else if (GET_CODE (op1) == NEG)
    7559              :         {
    7560         1060 :           tem = simplify_unary_operation (NEG, mode, op0, mode);
    7561         1060 :           if (tem)
    7562            0 :             op0 = tem, op1 = XEXP (op1, 0), any_change = true;
    7563              :         }
    7564              : 
    7565              :       /* Canonicalize the two multiplication operands.  */
    7566              :       /* a * -b + c  =>  -b * a + c.  */
    7567       338663 :       if (swap_commutative_operands_p (op0, op1))
    7568              :         std::swap (op0, op1), any_change = true;
    7569              : 
    7570       309879 :       if (any_change)
    7571        29046 :         return gen_rtx_FMA (mode, op0, op1, op2);
    7572              :       return NULL_RTX;
    7573              : 
    7574       651224 :     case SIGN_EXTRACT:
    7575       651224 :     case ZERO_EXTRACT:
    7576       651224 :       if (CONST_INT_P (op0)
    7577        17469 :           && CONST_INT_P (op1)
    7578        17469 :           && CONST_INT_P (op2)
    7579     41968114 :           && is_a <scalar_int_mode> (mode, &int_mode)
    7580           32 :           && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
    7581       651256 :           && HWI_COMPUTABLE_MODE_P (int_mode))
    7582              :         {
    7583              :           /* Extracting a bit-field from a constant */
    7584           32 :           unsigned HOST_WIDE_INT val = UINTVAL (op0);
    7585           32 :           HOST_WIDE_INT op1val = INTVAL (op1);
    7586           32 :           HOST_WIDE_INT op2val = INTVAL (op2);
    7587           32 :           if (!BITS_BIG_ENDIAN)
    7588           32 :             val >>= op2val;
    7589              :           else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
    7590              :             val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
    7591              :           else
    7592              :             /* Not enough information to calculate the bit position.  */
    7593              :             break;
    7594              : 
    7595           32 :           if (HOST_BITS_PER_WIDE_INT != op1val)
    7596              :             {
    7597              :               /* First zero-extend.  */
    7598           29 :               val &= (HOST_WIDE_INT_1U << op1val) - 1;
    7599              :               /* If desired, propagate sign bit.  */
    7600           29 :               if (code == SIGN_EXTRACT
    7601            5 :                   && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
    7602            5 :                      != 0)
    7603            2 :                 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
    7604              :             }
    7605              : 
    7606           32 :           return gen_int_mode (val, int_mode);
    7607              :         }
    7608              :       break;
    7609              : 
    7610     40183440 :     case IF_THEN_ELSE:
    7611     40183440 :       if (CONST_INT_P (op0))
    7612       289996 :         return op0 != const0_rtx ? op1 : op2;
    7613              : 
    7614              :       /* Convert c ? a : a into "a".  */
    7615     39986504 :       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
    7616              :         return op1;
    7617              : 
    7618              :       /* Convert a != b ? a : b into "a".  */
    7619     39983364 :       if (GET_CODE (op0) == NE
    7620     15492194 :           && ! side_effects_p (op0)
    7621     15450377 :           && ! HONOR_NANS (mode)
    7622     15444402 :           && ! HONOR_SIGNED_ZEROS (mode)
    7623     55427766 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7624       117227 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7625     15444078 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7626         4433 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7627          533 :         return op1;
    7628              : 
    7629              :       /* Convert a == b ? a : b into "b".  */
    7630     39982831 :       if (GET_CODE (op0) == EQ
    7631     12588268 :           && ! side_effects_p (op0)
    7632     12562549 :           && ! HONOR_NANS (mode)
    7633     12425216 :           && ! HONOR_SIGNED_ZEROS (mode)
    7634     52408047 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7635        14920 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7636     12425205 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7637         7450 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7638           27 :         return op2;
    7639              : 
    7640              :       /* Convert a != 0 ? -a : 0 into "-a".  */
    7641     39982804 :       if (GET_CODE (op0) == NE
    7642     15491661 :           && ! side_effects_p (op0)
    7643     15449844 :           && ! HONOR_NANS (mode)
    7644     15443869 :           && ! HONOR_SIGNED_ZEROS (mode)
    7645     15443869 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7646     11785101 :           && op2 == CONST0_RTX (mode)
    7647       174100 :           && GET_CODE (op1) == NEG
    7648     39982862 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
    7649              :         return op1;
    7650              : 
    7651              :       /* Convert a == 0 ? 0 : -a into "-a".  */
    7652     39982795 :       if (GET_CODE (op0) == EQ
    7653     12588241 :           && ! side_effects_p (op0)
    7654     12562522 :           && ! HONOR_NANS (mode)
    7655     12425189 :           && ! HONOR_SIGNED_ZEROS (mode)
    7656     12425189 :           && op1 == CONST0_RTX (mode)
    7657        30927 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7658        13550 :           && GET_CODE (op2) == NEG
    7659     39982801 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
    7660              :         return op2;
    7661              : 
    7662              :       /* Convert (!c) != {0,...,0} ? a : b into
    7663              :          c != {0,...,0} ? b : a for vector modes.  */
    7664     39982789 :       if (VECTOR_MODE_P (GET_MODE (op1))
    7665        14811 :           && GET_CODE (op0) == NE
    7666          468 :           && GET_CODE (XEXP (op0, 0)) == NOT
    7667            0 :           && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
    7668              :         {
    7669            0 :           rtx cv = XEXP (op0, 1);
    7670            0 :           int nunits;
    7671            0 :           bool ok = true;
    7672            0 :           if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
    7673              :             ok = false;
    7674              :           else
    7675            0 :             for (int i = 0; i < nunits; ++i)
    7676            0 :               if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
    7677              :                 {
    7678              :                   ok = false;
    7679              :                   break;
    7680              :                 }
    7681            0 :           if (ok)
    7682              :             {
    7683            0 :               rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
    7684              :                                         XEXP (XEXP (op0, 0), 0),
    7685              :                                         XEXP (op0, 1));
    7686            0 :               rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
    7687            0 :               return retval;
    7688              :             }
    7689              :         }
    7690              : 
    7691              :       /* Convert x == 0 ? N : clz (x) into clz (x) when
    7692              :          CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
    7693              :          Similarly for ctz (x).  */
    7694     39981791 :       if (COMPARISON_P (op0) && !side_effects_p (op0)
    7695     79864140 :           && XEXP (op0, 1) == const0_rtx)
    7696              :         {
    7697     30390013 :           rtx simplified
    7698     30390013 :             = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
    7699              :                                      op1, op2);
    7700     30390013 :           if (simplified)
    7701              :             return simplified;
    7702              :         }
    7703              : 
    7704     39982789 :       if (COMPARISON_P (op0) && ! side_effects_p (op0))
    7705              :         {
    7706     79853400 :           machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
    7707     39881351 :                                         ? GET_MODE (XEXP (op0, 1))
    7708              :                                         : GET_MODE (XEXP (op0, 0)));
    7709     39881351 :           rtx temp;
    7710              : 
    7711              :           /* Look for happy constants in op1 and op2.  */
    7712     39881351 :           if (CONST_INT_P (op1) && CONST_INT_P (op2))
    7713              :             {
    7714       211401 :               HOST_WIDE_INT t = INTVAL (op1);
    7715       211401 :               HOST_WIDE_INT f = INTVAL (op2);
    7716              : 
    7717       211401 :               if (t == STORE_FLAG_VALUE && f == 0)
    7718        52630 :                 code = GET_CODE (op0);
    7719       158771 :               else if (t == 0 && f == STORE_FLAG_VALUE)
    7720              :                 {
    7721        31398 :                   enum rtx_code tmp;
    7722        31398 :                   tmp = reversed_comparison_code (op0, NULL);
    7723        31398 :                   if (tmp == UNKNOWN)
    7724              :                     break;
    7725              :                   code = tmp;
    7726              :                 }
    7727              :               else
    7728              :                 break;
    7729              : 
    7730        78639 :               return simplify_gen_relational (code, mode, cmp_mode,
    7731        78639 :                                               XEXP (op0, 0), XEXP (op0, 1));
    7732              :             }
    7733              : 
    7734     39669950 :           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
    7735              :                                                 cmp_mode, XEXP (op0, 0),
    7736              :                                                 XEXP (op0, 1));
    7737              : 
    7738              :           /* See if any simplifications were possible.  */
    7739     39669950 :           if (temp)
    7740              :             {
    7741         6975 :               if (CONST_INT_P (temp))
    7742          872 :                 return temp == const0_rtx ? op2 : op1;
    7743         6148 :               else if (temp)
    7744         6148 :                 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
    7745              :             }
    7746              :         }
    7747              :       break;
    7748              : 
    7749       794755 :     case VEC_MERGE:
    7750       794755 :       gcc_assert (GET_MODE (op0) == mode);
    7751       794755 :       gcc_assert (GET_MODE (op1) == mode);
    7752       794755 :       gcc_assert (VECTOR_MODE_P (mode));
    7753       794755 :       trueop2 = avoid_constant_pool_reference (op2);
    7754       794755 :       if (CONST_INT_P (trueop2)
    7755      1268587 :           && GET_MODE_NUNITS (mode).is_constant (&n_elts))
    7756              :         {
    7757       473832 :           unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
    7758       473832 :           unsigned HOST_WIDE_INT mask;
    7759       473832 :           if (n_elts == HOST_BITS_PER_WIDE_INT)
    7760              :             mask = -1;
    7761              :           else
    7762       471375 :             mask = (HOST_WIDE_INT_1U << n_elts) - 1;
    7763              : 
    7764       473832 :           if (!(sel & mask) && !side_effects_p (op0))
    7765              :             return op1;
    7766       473395 :           if ((sel & mask) == mask && !side_effects_p (op1))
    7767              :             return op0;
    7768              : 
    7769       462644 :           rtx trueop0 = avoid_constant_pool_reference (op0);
    7770       462644 :           rtx trueop1 = avoid_constant_pool_reference (op1);
    7771       462644 :           if (GET_CODE (trueop0) == CONST_VECTOR
    7772        10028 :               && GET_CODE (trueop1) == CONST_VECTOR)
    7773              :             {
    7774         5572 :               rtvec v = rtvec_alloc (n_elts);
    7775         5572 :               unsigned int i;
    7776              : 
    7777        58894 :               for (i = 0; i < n_elts; i++)
    7778        47750 :                 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
    7779        47750 :                                     ? CONST_VECTOR_ELT (trueop0, i)
    7780        27384 :                                     : CONST_VECTOR_ELT (trueop1, i));
    7781         5572 :               return gen_rtx_CONST_VECTOR (mode, v);
    7782              :             }
    7783              : 
    7784       457072 :           if (swap_commutative_operands_p (op0, op1)
    7785              :               /* Two operands have same precedence, then first bit of mask
    7786              :                  select first operand.  */
    7787       457072 :               || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
    7788        31384 :             return simplify_gen_ternary (code, mode, mode, op1, op0,
    7789        62768 :                                          GEN_INT (~sel & mask));
    7790              : 
    7791              :           /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
    7792              :              if no element from a appears in the result.  */
    7793       425688 :           if (GET_CODE (op0) == VEC_MERGE)
    7794              :             {
    7795        17218 :               tem = avoid_constant_pool_reference (XEXP (op0, 2));
    7796        17218 :               if (CONST_INT_P (tem))
    7797              :                 {
    7798         1475 :                   unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
    7799         1475 :                   if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
    7800          104 :                     return simplify_gen_ternary (code, mode, mode,
    7801          104 :                                                  XEXP (op0, 1), op1, op2);
    7802         1371 :                   if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
    7803          834 :                     return simplify_gen_ternary (code, mode, mode,
    7804          834 :                                                  XEXP (op0, 0), op1, op2);
    7805              :                 }
    7806              :             }
    7807       424750 :           if (GET_CODE (op1) == VEC_MERGE)
    7808              :             {
    7809          588 :               tem = avoid_constant_pool_reference (XEXP (op1, 2));
    7810          588 :               if (CONST_INT_P (tem))
    7811              :                 {
    7812          557 :                   unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
    7813          557 :                   if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
    7814          526 :                     return simplify_gen_ternary (code, mode, mode,
    7815          526 :                                                  op0, XEXP (op1, 1), op2);
    7816           31 :                   if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
    7817            4 :                     return simplify_gen_ternary (code, mode, mode,
    7818            4 :                                                  op0, XEXP (op1, 0), op2);
    7819              :                 }
    7820              :             }
    7821              : 
    7822              :           /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
    7823              :              with a.  */
    7824       424220 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7825       142927 :               && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
    7826          640 :               && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
    7827       425500 :               && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
    7828              :             {
    7829          572 :               tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
    7830          572 :               if (CONST_INT_P (tem) && CONST_INT_P (op2))
    7831              :                 {
    7832          572 :                   if (XEXP (XEXP (op0, 0), 0) == op1
    7833            2 :                       && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
    7834              :                     return op1;
    7835              :                 }
    7836              :             }
    7837              :           /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
    7838              :              (const_int N))
    7839              :              with (vec_concat (X) (B)) if N == 1 or
    7840              :              (vec_concat (A) (X)) if N == 2.  */
    7841       424218 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7842       142925 :               && GET_CODE (op1) == CONST_VECTOR
    7843       151500 :               && known_eq (CONST_VECTOR_NUNITS (op1), 2)
    7844         2366 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7845       425401 :               && IN_RANGE (sel, 1, 2))
    7846              :             {
    7847         1181 :               rtx newop0 = XEXP (op0, 0);
    7848         1181 :               rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
    7849         1181 :               if (sel == 2)
    7850          123 :                 std::swap (newop0, newop1);
    7851         1181 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7852              :             }
    7853              :           /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
    7854              :              with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
    7855              :              Only applies for vectors of two elements.  */
    7856       423037 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7857       141744 :               && GET_CODE (op1) == VEC_CONCAT
    7858            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7859            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7860       423037 :               && IN_RANGE (sel, 1, 2))
    7861              :             {
    7862            0 :               rtx newop0 = XEXP (op0, 0);
    7863            0 :               rtx newop1 = XEXP (op1, 2 - sel);
    7864            0 :               rtx otherop = XEXP (op1, sel - 1);
    7865            0 :               if (sel == 2)
    7866            0 :                 std::swap (newop0, newop1);
    7867              :               /* Don't want to throw away the other part of the vec_concat if
    7868              :                  it has side-effects.  */
    7869            0 :               if (!side_effects_p (otherop))
    7870            0 :                 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7871              :             }
    7872              : 
    7873              :           /* Replace:
    7874              : 
    7875              :               (vec_merge:outer (vec_duplicate:outer x:inner)
    7876              :                                (subreg:outer y:inner 0)
    7877              :                                (const_int N))
    7878              : 
    7879              :              with (vec_concat:outer x:inner y:inner) if N == 1,
    7880              :              or (vec_concat:outer y:inner x:inner) if N == 2.
    7881              : 
    7882              :              Implicitly, this means we have a paradoxical subreg, but such
    7883              :              a check is cheap, so make it anyway.
    7884              : 
    7885              :              Only applies for vectors of two elements.  */
    7886       423037 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7887       141744 :               && GET_CODE (op1) == SUBREG
    7888        44336 :               && GET_MODE (op1) == GET_MODE (op0)
    7889        44336 :               && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
    7890            0 :               && paradoxical_subreg_p (op1)
    7891            0 :               && subreg_lowpart_p (op1)
    7892            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7893            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7894       423037 :               && IN_RANGE (sel, 1, 2))
    7895              :             {
    7896            0 :               rtx newop0 = XEXP (op0, 0);
    7897            0 :               rtx newop1 = SUBREG_REG (op1);
    7898            0 :               if (sel == 2)
    7899            0 :                 std::swap (newop0, newop1);
    7900            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7901              :             }
    7902              : 
    7903              :           /* Same as above but with switched operands:
    7904              :                 Replace (vec_merge:outer (subreg:outer x:inner 0)
    7905              :                                          (vec_duplicate:outer y:inner)
    7906              :                                (const_int N))
    7907              : 
    7908              :              with (vec_concat:outer x:inner y:inner) if N == 1,
    7909              :              or (vec_concat:outer y:inner x:inner) if N == 2.  */
    7910       423037 :           if (GET_CODE (op1) == VEC_DUPLICATE
    7911        29716 :               && GET_CODE (op0) == SUBREG
    7912        26567 :               && GET_MODE (op0) == GET_MODE (op1)
    7913        26567 :               && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
    7914            0 :               && paradoxical_subreg_p (op0)
    7915            0 :               && subreg_lowpart_p (op0)
    7916            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7917            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7918       423037 :               && IN_RANGE (sel, 1, 2))
    7919              :             {
    7920            0 :               rtx newop0 = SUBREG_REG (op0);
    7921            0 :               rtx newop1 = XEXP (op1, 0);
    7922            0 :               if (sel == 2)
    7923            0 :                 std::swap (newop0, newop1);
    7924            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7925              :             }
    7926              : 
    7927              :           /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
    7928              :                                  (const_int n))
    7929              :              with (vec_concat x y) or (vec_concat y x) depending on value
    7930              :              of N.  */
    7931       423037 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7932       141744 :               && GET_CODE (op1) == VEC_DUPLICATE
    7933          198 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7934            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7935       423037 :               && IN_RANGE (sel, 1, 2))
    7936              :             {
    7937            0 :               rtx newop0 = XEXP (op0, 0);
    7938            0 :               rtx newop1 = XEXP (op1, 0);
    7939            0 :               if (sel == 2)
    7940            0 :                 std::swap (newop0, newop1);
    7941              : 
    7942            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7943              :             }
    7944              :         }
    7945              : 
    7946       743960 :       if (rtx_equal_p (op0, op1)
    7947       743960 :           && !side_effects_p (op2) && !side_effects_p (op1))
    7948              :         return op0;
    7949              : 
    7950       743667 :       if (!side_effects_p (op2))
    7951              :         {
    7952       739989 :           rtx top0
    7953       739989 :             = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
    7954       739989 :           rtx top1
    7955       739989 :             = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
    7956       739989 :           if (top0 || top1)
    7957          998 :             return simplify_gen_ternary (code, mode, mode,
    7958              :                                          top0 ? top0 : op0,
    7959          819 :                                          top1 ? top1 : op1, op2);
    7960              :         }
    7961              : 
    7962              :       break;
    7963              : 
    7964            0 :     default:
    7965            0 :       gcc_unreachable ();
    7966              :     }
    7967              : 
    7968              :   return 0;
    7969              : }
    7970              : 
    7971              : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
    7972              :    starting at byte FIRST_BYTE.  Return true on success and add the
    7973              :    bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
    7974              :    that the bytes follow target memory order.  Leave BYTES unmodified
    7975              :    on failure.
    7976              : 
    7977              :    MODE is the mode of X.  The caller must reserve NUM_BYTES bytes in
    7978              :    BYTES before calling this function.  */
    7979              : 
    7980              : bool
    7981     13511635 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
    7982              :                    unsigned int first_byte, unsigned int num_bytes)
    7983              : {
    7984              :   /* Check the mode is sensible.  */
    7985     13511635 :   gcc_assert (GET_MODE (x) == VOIDmode
    7986              :               ? is_a <scalar_int_mode> (mode)
    7987              :               : mode == GET_MODE (x));
    7988              : 
    7989     13511635 :   if (GET_CODE (x) == CONST_VECTOR)
    7990              :     {
    7991              :       /* CONST_VECTOR_ELT follows target memory order, so no shuffling
    7992              :          is necessary.  The only complication is that MODE_VECTOR_BOOL
    7993              :          vectors can have several elements per byte.  */
    7994      1051852 :       unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    7995              :                                                    GET_MODE_NUNITS (mode));
    7996       525926 :       unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
    7997       525926 :       if (elt_bits < BITS_PER_UNIT)
    7998              :         {
    7999              :           /* This is the only case in which elements can be smaller than
    8000              :              a byte.  */
    8001            0 :           gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    8002            0 :           auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
    8003            0 :           for (unsigned int i = 0; i < num_bytes; ++i)
    8004              :             {
    8005            0 :               target_unit value = 0;
    8006            0 :               for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
    8007              :                 {
    8008            0 :                   if (INTVAL (CONST_VECTOR_ELT (x, elt)))
    8009            0 :                     value |= mask << j;
    8010            0 :                   elt += 1;
    8011              :                 }
    8012            0 :               bytes.quick_push (value);
    8013              :             }
    8014              :           return true;
    8015              :         }
    8016              : 
    8017       525926 :       unsigned int start = bytes.length ();
    8018       525926 :       unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
    8019              :       /* Make FIRST_BYTE relative to ELT.  */
    8020       525926 :       first_byte %= elt_bytes;
    8021      2681423 :       while (num_bytes > 0)
    8022              :         {
    8023              :           /* Work out how many bytes we want from element ELT.  */
    8024      2155497 :           unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
    8025      4310994 :           if (!native_encode_rtx (GET_MODE_INNER (mode),
    8026              :                                   CONST_VECTOR_ELT (x, elt), bytes,
    8027              :                                   first_byte, chunk_bytes))
    8028              :             {
    8029            0 :               bytes.truncate (start);
    8030            0 :               return false;
    8031              :             }
    8032      2155497 :           elt += 1;
    8033      2155497 :           first_byte = 0;
    8034      2155497 :           num_bytes -= chunk_bytes;
    8035              :         }
    8036              :       return true;
    8037              :     }
    8038              : 
    8039              :   /* All subsequent cases are limited to scalars.  */
    8040     12985709 :   scalar_mode smode;
    8041     13016627 :   if (!is_a <scalar_mode> (mode, &smode))
    8042              :     return false;
    8043              : 
    8044              :   /* Make sure that the region is in range.  */
    8045     12985709 :   unsigned int end_byte = first_byte + num_bytes;
    8046     12985709 :   unsigned int mode_bytes = GET_MODE_SIZE (smode);
    8047     12985709 :   gcc_assert (end_byte <= mode_bytes);
    8048              : 
    8049     12985709 :   if (CONST_SCALAR_INT_P (x))
    8050              :     {
    8051              :       /* The target memory layout is affected by both BYTES_BIG_ENDIAN
    8052              :          and WORDS_BIG_ENDIAN.  Use the subreg machinery to get the lsb
    8053              :          position of each byte.  */
    8054     12310015 :       rtx_mode_t value (x, smode);
    8055     12310015 :       wide_int_ref value_wi (value);
    8056     52728259 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8057              :         {
    8058              :           /* Always constant because the inputs are.  */
    8059     40418244 :           unsigned int lsb
    8060     40418244 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8061              :           /* Operate directly on the encoding rather than using
    8062              :              wi::extract_uhwi, so that we preserve the sign or zero
    8063              :              extension for modes that are not a whole number of bits in
    8064              :              size.  (Zero extension is only used for the combination of
    8065              :              innermode == BImode && STORE_FLAG_VALUE == 1).  */
    8066     40418244 :           unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
    8067     40418244 :           unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
    8068     40418244 :           unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
    8069     40418244 :           bytes.quick_push (uhwi >> shift);
    8070              :         }
    8071     12310015 :       return true;
    8072              :     }
    8073              : 
    8074       675694 :   if (CONST_DOUBLE_P (x))
    8075              :     {
    8076              :       /* real_to_target produces an array of integers in target memory order.
    8077              :          All integers before the last one have 32 bits; the last one may
    8078              :          have 32 bits or fewer, depending on whether the mode bitsize
    8079              :          is divisible by 32.  Each of these integers is then laid out
    8080              :          in target memory as any other integer would be.  */
    8081       644776 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    8082       644776 :       real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
    8083              : 
    8084              :       /* The (maximum) number of target bytes per element of el32.  */
    8085       644776 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    8086       644776 :       gcc_assert (bytes_per_el32 != 0);
    8087              : 
    8088              :       /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
    8089              :          handling above.  */
    8090      4406058 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8091              :         {
    8092      3761282 :           unsigned int index = byte / bytes_per_el32;
    8093      3761282 :           unsigned int subbyte = byte % bytes_per_el32;
    8094      3761282 :           unsigned int int_bytes = MIN (bytes_per_el32,
    8095              :                                         mode_bytes - index * bytes_per_el32);
    8096              :           /* Always constant because the inputs are.  */
    8097      3761282 :           unsigned int lsb
    8098      3761282 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    8099      3761282 :           bytes.quick_push ((unsigned long) el32[index] >> lsb);
    8100              :         }
    8101       644776 :       return true;
    8102              :     }
    8103              : 
    8104        30918 :   if (GET_CODE (x) == CONST_FIXED)
    8105              :     {
    8106            0 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8107              :         {
    8108              :           /* Always constant because the inputs are.  */
    8109            0 :           unsigned int lsb
    8110            0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8111            0 :           unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
    8112            0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    8113              :             {
    8114            0 :               lsb -= HOST_BITS_PER_WIDE_INT;
    8115            0 :               piece = CONST_FIXED_VALUE_HIGH (x);
    8116              :             }
    8117            0 :           bytes.quick_push (piece >> lsb);
    8118              :         }
    8119              :       return true;
    8120              :     }
    8121              : 
    8122              :   return false;
    8123              : }
    8124              : 
    8125              : /* Read a vector of mode MODE from the target memory image given by BYTES,
    8126              :    starting at byte FIRST_BYTE.  The vector is known to be encodable using
    8127              :    NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
    8128              :    and BYTES is known to have enough bytes to supply NPATTERNS *
    8129              :    NELTS_PER_PATTERN vector elements.  Each element of BYTES contains
    8130              :    BITS_PER_UNIT bits and the bytes are in target memory order.
    8131              : 
    8132              :    Return the vector on success, otherwise return NULL_RTX.  */
    8133              : 
    8134              : rtx
    8135       265625 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
    8136              :                           unsigned int first_byte, unsigned int npatterns,
    8137              :                           unsigned int nelts_per_pattern)
    8138              : {
    8139       265625 :   rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
    8140              : 
    8141       531250 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8142              :                                                GET_MODE_NUNITS (mode));
    8143       265625 :   if (elt_bits < BITS_PER_UNIT)
    8144              :     {
    8145              :       /* This is the only case in which elements can be smaller than a byte.
    8146              :          Element 0 is always in the lsb of the containing byte.  */
    8147            0 :       gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    8148            0 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    8149              :         {
    8150            0 :           unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
    8151            0 :           unsigned int byte_index = bit_index / BITS_PER_UNIT;
    8152            0 :           unsigned int lsb = bit_index % BITS_PER_UNIT;
    8153            0 :           unsigned int value = bytes[byte_index] >> lsb;
    8154            0 :           builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
    8155              :         }
    8156              :     }
    8157              :   else
    8158              :     {
    8159      1053458 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    8160              :         {
    8161      1575666 :           rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
    8162       787833 :           if (!x)
    8163            0 :             return NULL_RTX;
    8164       787833 :           builder.quick_push (x);
    8165       787833 :           first_byte += elt_bits / BITS_PER_UNIT;
    8166              :         }
    8167              :     }
    8168       265625 :   return builder.build ();
    8169       265625 : }
    8170              : 
    8171              : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
    8172              :    of target memory image BYTES.  */
    8173              : 
    8174              : wide_int
    8175     11381619 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
    8176              :                    unsigned int size, unsigned int precision)
    8177              : {
    8178              :   /* Pull the bytes msb first, so that we can use simple
    8179              :      shift-and-insert wide_int operations.  */
    8180     11381619 :   wide_int result (wi::zero (precision));
    8181     52803392 :   for (unsigned int i = 0; i < size; ++i)
    8182              :     {
    8183     41421773 :       unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
    8184              :       /* Always constant because the inputs are.  */
    8185     41421773 :       unsigned int subbyte
    8186     41421773 :         = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
    8187     41421773 :       result <<= BITS_PER_UNIT;
    8188     41421773 :       result |= bytes[first_byte + subbyte];
    8189              :     }
    8190     11381619 :   return result;
    8191              : }
    8192              : 
    8193              : /* Read an rtx of mode MODE from the target memory image given by BYTES,
    8194              :    starting at byte FIRST_BYTE.  Each element of BYTES contains BITS_PER_UNIT
    8195              :    bits and the bytes are in target memory order.  The image has enough
    8196              :    values to specify all bytes of MODE.
    8197              : 
    8198              :    Return the rtx on success, otherwise return NULL_RTX.  */
    8199              : 
    8200              : rtx
    8201     11714490 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
    8202              :                    unsigned int first_byte)
    8203              : {
    8204     11714490 :   if (VECTOR_MODE_P (mode))
    8205              :     {
    8206              :       /* If we know at compile time how many elements there are,
    8207              :          pull each element directly from BYTES.  */
    8208        90061 :       unsigned int nelts;
    8209       180122 :       if (GET_MODE_NUNITS (mode).is_constant (&nelts))
    8210        90061 :         return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
    8211              :       return NULL_RTX;
    8212              :     }
    8213              : 
    8214     11624429 :   scalar_int_mode imode;
    8215     11624429 :   if (is_a <scalar_int_mode> (mode, &imode)
    8216     11381619 :       && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
    8217              :     {
    8218     11381619 :       auto result = native_decode_int (bytes, first_byte,
    8219     11381619 :                                        GET_MODE_SIZE (imode),
    8220     22763238 :                                        GET_MODE_PRECISION (imode));
    8221     11381619 :       return immed_wide_int_const (result, imode);
    8222     11381619 :     }
    8223              : 
    8224       242810 :   scalar_float_mode fmode;
    8225       242810 :   if (is_a <scalar_float_mode> (mode, &fmode))
    8226              :     {
    8227              :       /* We need to build an array of integers in target memory order.
    8228              :          All integers before the last one have 32 bits; the last one may
    8229              :          have 32 bits or fewer, depending on whether the mode bitsize
    8230              :          is divisible by 32.  */
    8231       242780 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    8232       242780 :       unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
    8233       242780 :       memset (el32, 0, num_el32 * sizeof (long));
    8234              : 
    8235              :       /* The (maximum) number of target bytes per element of el32.  */
    8236       242780 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    8237       242780 :       gcc_assert (bytes_per_el32 != 0);
    8238              : 
    8239       242780 :       unsigned int mode_bytes = GET_MODE_SIZE (fmode);
    8240      1683588 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    8241              :         {
    8242      1440808 :           unsigned int index = byte / bytes_per_el32;
    8243      1440808 :           unsigned int subbyte = byte % bytes_per_el32;
    8244      1440808 :           unsigned int int_bytes = MIN (bytes_per_el32,
    8245              :                                         mode_bytes - index * bytes_per_el32);
    8246              :           /* Always constant because the inputs are.  */
    8247      1440808 :           unsigned int lsb
    8248      1440808 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    8249      1440808 :           el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
    8250              :         }
    8251       242780 :       REAL_VALUE_TYPE r;
    8252       242780 :       real_from_target (&r, el32, fmode);
    8253       242780 :       return const_double_from_real_value (r, fmode);
    8254              :     }
    8255              : 
    8256           30 :   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
    8257              :     {
    8258            0 :       scalar_mode smode = as_a <scalar_mode> (mode);
    8259            0 :       FIXED_VALUE_TYPE f;
    8260            0 :       f.data.low = 0;
    8261            0 :       f.data.high = 0;
    8262            0 :       f.mode = smode;
    8263              : 
    8264            0 :       unsigned int mode_bytes = GET_MODE_SIZE (smode);
    8265            0 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    8266              :         {
    8267              :           /* Always constant because the inputs are.  */
    8268            0 :           unsigned int lsb
    8269            0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8270            0 :           unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
    8271            0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    8272            0 :             f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
    8273              :           else
    8274            0 :             f.data.low |= unit << lsb;
    8275              :         }
    8276            0 :       return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
    8277              :     }
    8278              : 
    8279              :   return NULL_RTX;
    8280              : }
    8281              : 
    8282              : /* Simplify a byte offset BYTE into CONST_VECTOR X.  The main purpose
    8283              :    is to convert a runtime BYTE value into a constant one.  */
    8284              : 
    8285              : static poly_uint64
    8286       318506 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
    8287              : {
    8288              :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    8289       318506 :   machine_mode mode = GET_MODE (x);
    8290       637012 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8291              :                                                GET_MODE_NUNITS (mode));
    8292              :   /* The number of bits needed to encode one element from each pattern.  */
    8293       318506 :   unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
    8294              : 
    8295              :   /* Identify the start point in terms of a sequence number and a byte offset
    8296              :      within that sequence.  */
    8297       318506 :   poly_uint64 first_sequence;
    8298       318506 :   unsigned HOST_WIDE_INT subbit;
    8299       318506 :   if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
    8300              :                        &first_sequence, &subbit))
    8301              :     {
    8302       318506 :       unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    8303       318506 :       if (nelts_per_pattern == 1)
    8304              :         /* This is a duplicated vector, so the value of FIRST_SEQUENCE
    8305              :            doesn't matter.  */
    8306       239786 :         byte = subbit / BITS_PER_UNIT;
    8307        78720 :       else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
    8308              :         {
    8309              :           /* The subreg drops the first element from each pattern and
    8310              :              only uses the second element.  Find the first sequence
    8311              :              that starts on a byte boundary.  */
    8312         5568 :           subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
    8313         5568 :           byte = subbit / BITS_PER_UNIT;
    8314              :         }
    8315              :     }
    8316       318506 :   return byte;
    8317              : }
    8318              : 
    8319              : /* Subroutine of simplify_subreg in which:
    8320              : 
    8321              :    - X is known to be a CONST_VECTOR
    8322              :    - OUTERMODE is known to be a vector mode
    8323              : 
    8324              :    Try to handle the subreg by operating on the CONST_VECTOR encoding
    8325              :    rather than on each individual element of the CONST_VECTOR.
    8326              : 
    8327              :    Return the simplified subreg on success, otherwise return NULL_RTX.  */
    8328              : 
    8329              : static rtx
    8330       183491 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
    8331              :                               machine_mode innermode, unsigned int first_byte)
    8332              : {
    8333              :   /* Paradoxical subregs of vectors have dubious semantics.  */
    8334       183491 :   if (paradoxical_subreg_p (outermode, innermode))
    8335              :     return NULL_RTX;
    8336              : 
    8337              :   /* We can only preserve the semantics of a stepped pattern if the new
    8338              :      vector element is the same as the original one.  */
    8339       183345 :   if (CONST_VECTOR_STEPPED_P (x)
    8340       204131 :       && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
    8341              :     return NULL_RTX;
    8342              : 
    8343              :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    8344       175564 :   unsigned int x_elt_bits
    8345       175564 :     = vector_element_size (GET_MODE_PRECISION (innermode),
    8346              :                            GET_MODE_NUNITS (innermode));
    8347       175564 :   unsigned int out_elt_bits
    8348       175564 :     = vector_element_size (GET_MODE_PRECISION (outermode),
    8349              :                            GET_MODE_NUNITS (outermode));
    8350              : 
    8351              :   /* The number of bits needed to encode one element from every pattern
    8352              :      of the original vector.  */
    8353       175564 :   unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
    8354              : 
    8355              :   /* The number of bits needed to encode one element from every pattern
    8356              :      of the result.  */
    8357       175564 :   unsigned int out_sequence_bits
    8358       175564 :     = least_common_multiple (x_sequence_bits, out_elt_bits);
    8359              : 
    8360              :   /* Work out the number of interleaved patterns in the output vector
    8361              :      and the number of encoded elements per pattern.  */
    8362       175564 :   unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
    8363       175564 :   unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    8364              : 
    8365              :   /* The encoding scheme requires the number of elements to be a multiple
    8366              :      of the number of patterns, so that each pattern appears at least once
    8367              :      and so that the same number of elements appear from each pattern.  */
    8368       351128 :   bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
    8369       175564 :   unsigned int const_nunits;
    8370       351128 :   if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
    8371       175564 :       && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
    8372              :     {
    8373              :       /* Either the encoding is invalid, or applying it would give us
    8374              :          more elements than we need.  Just encode each element directly.  */
    8375              :       out_npatterns = const_nunits;
    8376              :       nelts_per_pattern = 1;
    8377              :     }
    8378              :   else if (!ok_p)
    8379              :     return NULL_RTX;
    8380              : 
    8381              :   /* Get enough bytes of X to form the new encoding.  */
    8382       175564 :   unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
    8383       175564 :   unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
    8384       175564 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8385       175564 :   if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
    8386              :     return NULL_RTX;
    8387              : 
    8388              :   /* Re-encode the bytes as OUTERMODE.  */
    8389       175564 :   return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
    8390       175564 :                                    nelts_per_pattern);
    8391       175564 : }
    8392              : 
    8393              : /* Try to simplify a subreg of a constant by encoding the subreg region
    8394              :    as a sequence of target bytes and reading them back in the new mode.
    8395              :    Return the new value on success, otherwise return null.
    8396              : 
    8397              :    The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
    8398              :    and byte offset FIRST_BYTE.  */
    8399              : 
    8400              : static rtx
    8401     10654656 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
    8402              :                        machine_mode innermode, unsigned int first_byte)
    8403              : {
    8404     10654656 :   unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
    8405     10654656 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8406              : 
    8407              :   /* Some ports misuse CCmode.  */
    8408     10654656 :   if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
    8409              :     return x;
    8410              : 
    8411              :   /* Paradoxical subregs read undefined values for bytes outside of the
    8412              :      inner value.  However, we have traditionally always sign-extended
    8413              :      integer constants and zero-extended others.  */
    8414     10652640 :   unsigned int inner_bytes = buffer_bytes;
    8415     10652640 :   if (paradoxical_subreg_p (outermode, innermode))
    8416              :     {
    8417       962740 :       if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
    8418            0 :         return NULL_RTX;
    8419              : 
    8420       481370 :       target_unit filler = 0;
    8421       481370 :       if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
    8422        43813 :         filler = -1;
    8423              : 
    8424              :       /* Add any leading bytes due to big-endian layout.  The number of
    8425              :          bytes must be constant because both modes have constant size.  */
    8426       481370 :       unsigned int leading_bytes
    8427       481370 :         = -byte_lowpart_offset (outermode, innermode).to_constant ();
    8428       481370 :       for (unsigned int i = 0; i < leading_bytes; ++i)
    8429            0 :         buffer.quick_push (filler);
    8430              : 
    8431       481370 :       if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8432            0 :         return NULL_RTX;
    8433              : 
    8434              :       /* Add any trailing bytes due to little-endian layout.  */
    8435      6306272 :       while (buffer.length () < buffer_bytes)
    8436      2671766 :         buffer.quick_push (filler);
    8437              :     }
    8438     10171270 :   else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8439              :     return NULL_RTX;
    8440     10652640 :   rtx ret = native_decode_rtx (outermode, buffer, 0);
    8441     10652640 :   if (ret && FLOAT_MODE_P (outermode))
    8442              :     {
    8443       127478 :       auto_vec<target_unit, 128> buffer2 (buffer_bytes);
    8444       127478 :       if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
    8445              :         return NULL_RTX;
    8446      1406797 :       for (unsigned int i = 0; i < buffer_bytes; ++i)
    8447      1279354 :         if (buffer[i] != buffer2[i])
    8448              :           return NULL_RTX;
    8449       127478 :     }
    8450              :   return ret;
    8451     10654656 : }
    8452              : 
    8453              : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
    8454              :    Return 0 if no simplifications are possible.  */
    8455              : rtx
    8456     70189178 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
    8457              :                                    machine_mode innermode, poly_uint64 byte)
    8458              : {
    8459              :   /* Little bit of sanity checking.  */
    8460     70189178 :   gcc_assert (innermode != VOIDmode);
    8461     70189178 :   gcc_assert (outermode != VOIDmode);
    8462     70189178 :   gcc_assert (innermode != BLKmode);
    8463     70189178 :   gcc_assert (outermode != BLKmode);
    8464              : 
    8465     70189178 :   gcc_assert (GET_MODE (op) == innermode
    8466              :               || GET_MODE (op) == VOIDmode);
    8467              : 
    8468    140378356 :   poly_uint64 outersize = GET_MODE_SIZE (outermode);
    8469     70189178 :   if (!multiple_p (byte, outersize))
    8470              :     return NULL_RTX;
    8471              : 
    8472    140378316 :   poly_uint64 innersize = GET_MODE_SIZE (innermode);
    8473     70189158 :   if (maybe_ge (byte, innersize))
    8474              :     return NULL_RTX;
    8475              : 
    8476     70189158 :   if (outermode == innermode && known_eq (byte, 0U))
    8477      4543222 :     return op;
    8478              : 
    8479     65645936 :   if (GET_CODE (op) == CONST_VECTOR)
    8480       318506 :     byte = simplify_const_vector_byte_offset (op, byte);
    8481              : 
    8482    131291872 :   if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
    8483              :     {
    8484     59899734 :       rtx elt;
    8485              : 
    8486     51216684 :       if (VECTOR_MODE_P (outermode)
    8487     26049150 :           && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
    8488     61618400 :           && vec_duplicate_p (op, &elt))
    8489        12118 :         return gen_vec_duplicate (outermode, elt);
    8490              : 
    8491     59895979 :       if (outermode == GET_MODE_INNER (innermode)
    8492     59895979 :           && vec_duplicate_p (op, &elt))
    8493         8363 :         return elt;
    8494              :     }
    8495              : 
    8496     65633818 :   if (CONST_SCALAR_INT_P (op)
    8497     55172376 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    8498     55115276 :       || CONST_FIXED_P (op)
    8499     55115276 :       || GET_CODE (op) == CONST_VECTOR)
    8500              :     {
    8501     10830220 :       unsigned HOST_WIDE_INT cbyte;
    8502     10830220 :       if (byte.is_constant (&cbyte))
    8503              :         {
    8504     10830220 :           if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
    8505              :             {
    8506       183491 :               rtx tmp = simplify_const_vector_subreg (outermode, op,
    8507              :                                                       innermode, cbyte);
    8508       183491 :               if (tmp)
    8509     10830220 :                 return tmp;
    8510              :             }
    8511              : 
    8512     10654656 :           fixed_size_mode fs_outermode;
    8513     10654656 :           if (is_a <fixed_size_mode> (outermode, &fs_outermode))
    8514     10654656 :             return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
    8515              :         }
    8516              :     }
    8517              : 
    8518              :   /* Changing mode twice with SUBREG => just change it once,
    8519              :      or not at all if changing back op starting mode.  */
    8520     54803598 :   if (GET_CODE (op) == SUBREG)
    8521              :     {
    8522      1319109 :       machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
    8523      2638218 :       poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
    8524      1319109 :       rtx newx;
    8525              : 
    8526              :       /* Make sure that the relationship between the two subregs is
    8527              :          known at compile time.  */
    8528      1319109 :       if (!ordered_p (outersize, innermostsize))
    8529              :         return NULL_RTX;
    8530              : 
    8531      1319109 :       if (outermode == innermostmode
    8532       753612 :           && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
    8533      2072714 :           && known_eq (SUBREG_BYTE (op),
    8534              :                        subreg_lowpart_offset (innermode, innermostmode)))
    8535       753605 :         return SUBREG_REG (op);
    8536              : 
    8537              :       /* Work out the memory offset of the final OUTERMODE value relative
    8538              :          to the inner value of OP.  */
    8539       565504 :       poly_int64 mem_offset = subreg_memory_offset (outermode,
    8540              :                                                     innermode, byte);
    8541       565504 :       poly_int64 op_mem_offset = subreg_memory_offset (op);
    8542       565504 :       poly_int64 final_offset = mem_offset + op_mem_offset;
    8543              : 
    8544              :       /* See whether resulting subreg will be paradoxical.  */
    8545       565504 :       if (!paradoxical_subreg_p (outermode, innermostmode))
    8546              :         {
    8547              :           /* Bail out in case resulting subreg would be incorrect.  */
    8548       921154 :           if (maybe_lt (final_offset, 0)
    8549       921139 :               || maybe_ge (poly_uint64 (final_offset), innermostsize)
    8550       921147 :               || !multiple_p (final_offset, outersize))
    8551           15 :             return NULL_RTX;
    8552              :         }
    8553              :       else
    8554              :         {
    8555       104927 :           poly_int64 required_offset = subreg_memory_offset (outermode,
    8556              :                                                              innermostmode, 0);
    8557       104927 :           if (maybe_ne (final_offset, required_offset))
    8558            0 :             return NULL_RTX;
    8559              :           /* Paradoxical subregs always have byte offset 0.  */
    8560       104927 :           final_offset = 0;
    8561              :         }
    8562              : 
    8563              :       /* Recurse for further possible simplifications.  */
    8564       565489 :       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
    8565       565489 :                               final_offset);
    8566       565489 :       if (newx)
    8567              :         return newx;
    8568       565111 :       if (validate_subreg (outermode, innermostmode,
    8569       565111 :                            SUBREG_REG (op), final_offset))
    8570              :         {
    8571       506212 :           newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
    8572       506212 :           if (SUBREG_PROMOTED_VAR_P (op)
    8573          610 :               && SUBREG_PROMOTED_SIGN (op) >= 0
    8574          610 :               && GET_MODE_CLASS (outermode) == MODE_INT
    8575          606 :               && known_ge (outersize, innersize)
    8576          392 :               && known_le (outersize, innermostsize)
    8577       506222 :               && subreg_lowpart_p (newx))
    8578              :             {
    8579           10 :               SUBREG_PROMOTED_VAR_P (newx) = 1;
    8580           10 :               SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
    8581              :             }
    8582       506212 :           return newx;
    8583              :         }
    8584              :       return NULL_RTX;
    8585              :     }
    8586              : 
    8587              :   /* SUBREG of a hard register => just change the register number
    8588              :      and/or mode.  If the hard register is not valid in that mode,
    8589              :      suppress this simplification.  If the hard register is the stack,
    8590              :      frame, or argument pointer, leave this as a SUBREG.  */
    8591              : 
    8592     53484489 :   if (REG_P (op) && HARD_REGISTER_P (op))
    8593              :     {
    8594     10639637 :       unsigned int regno, final_regno;
    8595              : 
    8596     10639637 :       regno = REGNO (op);
    8597     10639637 :       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
    8598     10639637 :       if (HARD_REGISTER_NUM_P (final_regno))
    8599              :         {
    8600     10614498 :           rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
    8601              :                                       subreg_memory_offset (outermode,
    8602              :                                                             innermode, byte));
    8603              : 
    8604              :           /* Propagate original regno.  We don't have any way to specify
    8605              :              the offset inside original regno, so do so only for lowpart.
    8606              :              The information is used only by alias analysis that cannot
    8607              :              grog partial register anyway.  */
    8608              : 
    8609     10614498 :           if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
    8610      7946358 :             ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
    8611     10614498 :           return x;
    8612              :         }
    8613              :     }
    8614              : 
    8615              :   /* If we have a SUBREG of a register that we are replacing and we are
    8616              :      replacing it with a MEM, make a new MEM and try replacing the
    8617              :      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
    8618              :      or if we would be widening it.  */
    8619              : 
    8620     42869991 :   if (MEM_P (op)
    8621      1695774 :       && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
    8622              :       /* Allow splitting of volatile memory references in case we don't
    8623              :          have instruction to move the whole thing.  */
    8624      1695771 :       && (! MEM_VOLATILE_P (op)
    8625        44331 :           || ! have_insn_for (SET, innermode))
    8626              :       && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
    8627     44521431 :       && known_le (outersize, innersize))
    8628       808568 :     return adjust_address_nv (op, outermode, byte);
    8629              : 
    8630              :   /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
    8631              :      of two parts.  */
    8632     42061423 :   if (GET_CODE (op) == CONCAT
    8633     42061423 :       || GET_CODE (op) == VEC_CONCAT)
    8634              :     {
    8635       203591 :       poly_uint64 final_offset;
    8636       203591 :       rtx part, res;
    8637              : 
    8638       203591 :       machine_mode part_mode = GET_MODE (XEXP (op, 0));
    8639       203591 :       if (part_mode == VOIDmode)
    8640           11 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8641       407182 :       poly_uint64 part_size = GET_MODE_SIZE (part_mode);
    8642       203591 :       if (known_lt (byte, part_size))
    8643              :         {
    8644       202047 :           part = XEXP (op, 0);
    8645       202047 :           final_offset = byte;
    8646              :         }
    8647         1544 :       else if (known_ge (byte, part_size))
    8648              :         {
    8649         1544 :           part = XEXP (op, 1);
    8650         1544 :           final_offset = byte - part_size;
    8651              :         }
    8652              :       else
    8653              :         return NULL_RTX;
    8654              : 
    8655       203591 :       if (maybe_gt (final_offset + outersize, part_size))
    8656              :         return NULL_RTX;
    8657              : 
    8658       128689 :       part_mode = GET_MODE (part);
    8659       128689 :       if (part_mode == VOIDmode)
    8660            0 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8661       128689 :       res = simplify_subreg (outermode, part, part_mode, final_offset);
    8662       128689 :       if (res)
    8663              :         return res;
    8664          295 :       if (GET_MODE (part) != VOIDmode
    8665          295 :           && validate_subreg (outermode, part_mode, part, final_offset))
    8666          295 :         return gen_rtx_SUBREG (outermode, part, final_offset);
    8667            0 :       return NULL_RTX;
    8668              :     }
    8669              : 
    8670              :   /* Simplify
    8671              :         (subreg (vec_merge (X)
    8672              :                            (vector)
    8673              :                            (const_int ((1 << N) | M)))
    8674              :                 (N * sizeof (outermode)))
    8675              :      to
    8676              :         (subreg (X) (N * sizeof (outermode)))
    8677              :    */
    8678     41857832 :   unsigned int idx;
    8679     83715664 :   if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
    8680     41857832 :       && idx < HOST_BITS_PER_WIDE_INT
    8681     41857832 :       && GET_CODE (op) == VEC_MERGE
    8682       633146 :       && GET_MODE_INNER (innermode) == outermode
    8683         4873 :       && CONST_INT_P (XEXP (op, 2))
    8684     41862123 :       && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
    8685         4282 :     return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
    8686              : 
    8687              :   /* A SUBREG resulting from a zero extension may fold to zero if
    8688              :      it extracts higher bits that the ZERO_EXTEND's source bits.  */
    8689     41853550 :   if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
    8690              :     {
    8691       221138 :       poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
    8692       221138 :       if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
    8693        55095 :         return CONST0_RTX (outermode);
    8694              :     }
    8695              : 
    8696              :   /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant.  */
    8697     41798455 :   if (GET_CODE (op) == ASHIFT
    8698       900718 :       && SCALAR_INT_MODE_P (innermode)
    8699       873246 :       && CONST_INT_P (XEXP (op, 1))
    8700       794021 :       && INTVAL (XEXP (op, 1)) > 0
    8701     43493144 :       && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
    8702              :     {
    8703       793971 :       HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
    8704              :       /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero.  */
    8705       793971 :       if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
    8706      1551322 :           && known_le (GET_MODE_BITSIZE (outermode), val))
    8707       191224 :         return CONST0_RTX (outermode);
    8708              :       /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND).  */
    8709       636822 :       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
    8710        34842 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
    8711        69370 :           && known_eq (GET_MODE_BITSIZE (outermode), val)
    8712        68150 :           && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
    8713       671664 :           && known_eq (subreg_highpart_offset (outermode, innermode), byte))
    8714        34075 :         return XEXP (XEXP (op, 0), 0);
    8715              :     }
    8716              : 
    8717     43139158 :   auto distribute_subreg = [&](rtx op)
    8718              :     {
    8719      1531927 :       return simplify_subreg (outermode, op, innermode, byte);
    8720     41607231 :     };
    8721              : 
    8722              :   /* Try distributing the subreg through logic operations, if that
    8723              :      leads to all subexpressions being simplified.  For example,
    8724              :      distributing the outer subreg in:
    8725              : 
    8726              :        (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
    8727              : 
    8728              :      gives:
    8729              : 
    8730              :        (not:SI (reg:SI X))
    8731              : 
    8732              :      This should be a win if the outermode is word_mode, since logical
    8733              :      operations on word_mode should (a) be no more expensive than logical
    8734              :      operations on subword modes and (b) are likely to be cheaper than
    8735              :      logical operations on multiword modes.
    8736              : 
    8737              :      Otherwise, handle the case where the subreg is non-narrowing and does
    8738              :      not change the number of words.  The non-narrowing condition ensures
    8739              :      that we don't convert word_mode operations to subword operations.  */
    8740     41607231 :   scalar_int_mode int_outermode, int_innermode;
    8741     41607231 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8742     34728505 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8743     75116883 :       && (outermode == word_mode
    8744     19789603 :           || ((GET_MODE_PRECISION (int_outermode)
    8745     19789603 :                >= GET_MODE_PRECISION (int_innermode))
    8746      4261425 :               && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
    8747      4174388 :                   <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
    8748     17835076 :     switch (GET_CODE (op))
    8749              :       {
    8750        31723 :       case NOT:
    8751        31723 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8752         1925 :           return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
    8753              :         break;
    8754              : 
    8755       461386 :       case AND:
    8756       461386 :       case IOR:
    8757       461386 :       case XOR:
    8758       461386 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8759       202966 :           if (rtx op1 = distribute_subreg (XEXP (op, 1)))
    8760       198178 :             return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
    8761              :         break;
    8762              : 
    8763              :       default:
    8764              :         break;
    8765              :       }
    8766              : 
    8767     41407128 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8768     34528402 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8769     75935530 :       && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
    8770              :     {
    8771              :       /* Handle polynomial integers.  The upper bits of a paradoxical
    8772              :          subreg are undefined, so this is safe regardless of whether
    8773              :          we're truncating or extending.  */
    8774     31197847 :       if (CONST_POLY_INT_P (op))
    8775              :         {
    8776              :           poly_wide_int val
    8777              :             = poly_wide_int::from (const_poly_int_value (op),
    8778              :                                    GET_MODE_PRECISION (int_outermode),
    8779              :                                    SIGNED);
    8780              :           return immed_wide_int_const (val, int_outermode);
    8781              :         }
    8782              : 
    8783     31197847 :       if (GET_MODE_PRECISION (int_outermode)
    8784     31197847 :           < GET_MODE_PRECISION (int_innermode))
    8785              :         {
    8786     18766316 :           rtx tem = simplify_truncation (int_outermode, op, int_innermode);
    8787     18766316 :           if (tem)
    8788              :             return tem;
    8789              :         }
    8790              :     }
    8791              : 
    8792              :   /* If the outer mode is not integral, try taking a subreg with the equivalent
    8793              :      integer outer mode and then bitcasting the result.
    8794              :      Other simplifications rely on integer to integer subregs and we'd
    8795              :      potentially miss out on optimizations otherwise.  */
    8796     80093134 :   if (known_gt (GET_MODE_SIZE (innermode),
    8797              :                 GET_MODE_SIZE (outermode))
    8798     20772175 :       && SCALAR_INT_MODE_P (innermode)
    8799     19605571 :       && !SCALAR_INT_MODE_P (outermode)
    8800     60994970 :       && int_mode_for_size (GET_MODE_BITSIZE (outermode),
    8801        88114 :                             0).exists (&int_outermode))
    8802              :     {
    8803        88114 :       rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
    8804        88114 :       if (tem)
    8805         1993 :         return lowpart_subreg (outermode, tem, int_outermode);
    8806              :     }
    8807              : 
    8808              :   /* If OP is a vector comparison and the subreg is not changing the
    8809              :      number of elements or the size of the elements, change the result
    8810              :      of the comparison to the new mode.  */
    8811     40044574 :   if (COMPARISON_P (op)
    8812       286375 :       && VECTOR_MODE_P (outermode)
    8813       198658 :       && VECTOR_MODE_P (innermode)
    8814       595950 :       && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
    8815     40416505 :       && known_eq (GET_MODE_UNIT_SIZE (outermode),
    8816              :                    GET_MODE_UNIT_SIZE (innermode)))
    8817       123633 :     return simplify_gen_relational (GET_CODE (op), outermode, innermode,
    8818       123633 :                                     XEXP (op, 0), XEXP (op, 1));
    8819              : 
    8820              :   /* Distribute non-paradoxical subregs through logic ops in cases where
    8821              :      one term disappears.
    8822              : 
    8823              :      (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
    8824              :      (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
    8825              :      (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
    8826              : 
    8827              :      if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
    8828              : 
    8829              :      (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
    8830              :      (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
    8831              : 
    8832              :      if M2 is no smaller than M1 and (subreg:M1 C2) is zero.  */
    8833     39920941 :   if (known_ge (innersize, outersize)
    8834     27000963 :       && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
    8835     24911754 :       && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
    8836     41548783 :       && CONSTANT_P (XEXP (op, 1)))
    8837              :     {
    8838       828652 :       rtx op1_subreg = distribute_subreg (XEXP (op, 1));
    8839       828652 :       if (op1_subreg == CONSTM1_RTX (outermode))
    8840              :         {
    8841       117368 :           if (GET_CODE (op) == IOR)
    8842              :             return op1_subreg;
    8843       117134 :           rtx op0 = XEXP (op, 0);
    8844       117134 :           if (GET_CODE (op) == XOR)
    8845          901 :             op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
    8846       117134 :           return simplify_gen_subreg (outermode, op0, innermode, byte);
    8847              :         }
    8848              : 
    8849       711284 :       if (op1_subreg == CONST0_RTX (outermode))
    8850        12162 :         return (GET_CODE (op) == AND
    8851        12162 :                 ? op1_subreg
    8852         7200 :                 : distribute_subreg (XEXP (op, 0)));
    8853              :     }
    8854              : 
    8855              :   return NULL_RTX;
    8856              : }
    8857              : 
    8858              : /* Make a SUBREG operation or equivalent if it folds.  */
    8859              : 
    8860              : rtx
    8861     43701731 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
    8862              :                                        machine_mode innermode,
    8863              :                                        poly_uint64 byte)
    8864              : {
    8865     43701731 :   rtx newx;
    8866              : 
    8867     43701731 :   newx = simplify_subreg (outermode, op, innermode, byte);
    8868     43701731 :   if (newx)
    8869              :     return newx;
    8870              : 
    8871     20580921 :   if (GET_CODE (op) == SUBREG
    8872     20580921 :       || GET_CODE (op) == CONCAT
    8873     20546243 :       || CONST_SCALAR_INT_P (op)
    8874     20546217 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    8875     20546217 :       || CONST_FIXED_P (op)
    8876     20546217 :       || GET_CODE (op) == CONST_VECTOR)
    8877              :     return NULL_RTX;
    8878              : 
    8879     20546207 :   if (validate_subreg (outermode, innermode, op, byte))
    8880     20514915 :     return gen_rtx_SUBREG (outermode, op, byte);
    8881              : 
    8882              :   return NULL_RTX;
    8883              : }
    8884              : 
    8885              : /* Generates a subreg to get the least significant part of EXPR (in mode
    8886              :    INNER_MODE) to OUTER_MODE.  */
    8887              : 
    8888              : rtx
    8889     32425695 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
    8890              :                                   machine_mode inner_mode)
    8891              : {
    8892     32425695 :   return simplify_gen_subreg (outer_mode, expr, inner_mode,
    8893     32425695 :                               subreg_lowpart_offset (outer_mode, inner_mode));
    8894              : }
    8895              : 
    8896              : /* Generate RTX to select element at INDEX out of vector OP.  */
    8897              : 
    8898              : rtx
    8899       643961 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
    8900              : {
    8901       643961 :   gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
    8902              : 
    8903       643961 :   scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
    8904              : 
    8905      1287922 :   if (known_eq (index * GET_MODE_SIZE (imode),
    8906              :                 subreg_lowpart_offset (imode, GET_MODE (op))))
    8907              :     {
    8908       643811 :       rtx res = lowpart_subreg (imode, op, GET_MODE (op));
    8909       643811 :       if (res)
    8910              :         return res;
    8911              :     }
    8912              : 
    8913          472 :   rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
    8914          472 :   return gen_rtx_VEC_SELECT (imode, op, tmp);
    8915              : }
    8916              : 
    8917              : 
    8918              : /* Simplify X, an rtx expression.
    8919              : 
    8920              :    Return the simplified expression or NULL if no simplifications
    8921              :    were possible.
    8922              : 
    8923              :    This is the preferred entry point into the simplification routines;
    8924              :    however, we still allow passes to call the more specific routines.
    8925              : 
    8926              :    Right now GCC has three (yes, three) major bodies of RTL simplification
    8927              :    code that need to be unified.
    8928              : 
    8929              :         1. fold_rtx in cse.cc.  This code uses various CSE specific
    8930              :            information to aid in RTL simplification.
    8931              : 
    8932              :         2. simplify_rtx in combine.cc.  Similar to fold_rtx, except that
    8933              :            it uses combine specific information to aid in RTL
    8934              :            simplification.
    8935              : 
    8936              :         3. The routines in this file.
    8937              : 
    8938              : 
    8939              :    Long term we want to only have one body of simplification code; to
    8940              :    get to that state I recommend the following steps:
    8941              : 
    8942              :         1. Pour over fold_rtx & simplify_rtx and move any simplifications
    8943              :            which are not pass dependent state into these routines.
    8944              : 
    8945              :         2. As code is moved by #1, change fold_rtx & simplify_rtx to
    8946              :            use this routine whenever possible.
    8947              : 
    8948              :         3. Allow for pass dependent state to be provided to these
    8949              :            routines and add simplifications based on the pass dependent
    8950              :            state.  Remove code from cse.cc & combine.cc that becomes
    8951              :            redundant/dead.
    8952              : 
    8953              :     It will take time, but ultimately the compiler will be easier to
    8954              :     maintain and improve.  It's totally silly that when we add a
    8955              :     simplification that it needs to be added to 4 places (3 for RTL
    8956              :     simplification and 1 for tree simplification.  */
    8957              : 
    8958              : rtx
    8959     45960778 : simplify_rtx (const_rtx x)
    8960              : {
    8961     45960778 :   const enum rtx_code code = GET_CODE (x);
    8962     45960778 :   const machine_mode mode = GET_MODE (x);
    8963              : 
    8964     45960778 :   switch (GET_RTX_CLASS (code))
    8965              :     {
    8966       848111 :     case RTX_UNARY:
    8967      1696222 :       return simplify_unary_operation (code, mode,
    8968       848111 :                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
    8969     26510468 :     case RTX_COMM_ARITH:
    8970     26510468 :       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    8971       530844 :         return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    8972              : 
    8973              :       /* Fall through.  */
    8974              : 
    8975     31982801 :     case RTX_BIN_ARITH:
    8976     31982801 :       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
    8977              : 
    8978        95817 :     case RTX_TERNARY:
    8979        95817 :     case RTX_BITFIELD_OPS:
    8980        95817 :       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
    8981        95817 :                                          XEXP (x, 0), XEXP (x, 1),
    8982        95817 :                                          XEXP (x, 2));
    8983              : 
    8984       202931 :     case RTX_COMPARE:
    8985       202931 :     case RTX_COMM_COMPARE:
    8986       202931 :       return simplify_relational_operation (code, mode,
    8987       202931 :                                             ((GET_MODE (XEXP (x, 0))
    8988              :                                              != VOIDmode)
    8989              :                                             ? GET_MODE (XEXP (x, 0))
    8990          284 :                                             : GET_MODE (XEXP (x, 1))),
    8991       202931 :                                             XEXP (x, 0),
    8992       405862 :                                             XEXP (x, 1));
    8993              : 
    8994       230439 :     case RTX_EXTRA:
    8995       230439 :       if (code == SUBREG)
    8996         2446 :         return simplify_subreg (mode, SUBREG_REG (x),
    8997         2446 :                                 GET_MODE (SUBREG_REG (x)),
    8998         2446 :                                 SUBREG_BYTE (x));
    8999              :       break;
    9000              : 
    9001      6369671 :     case RTX_OBJ:
    9002      6369671 :       if (code == LO_SUM)
    9003              :         {
    9004              :           /* Convert (lo_sum (high FOO) FOO) to FOO.  */
    9005            0 :           if (GET_CODE (XEXP (x, 0)) == HIGH
    9006            0 :               && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
    9007            0 :           return XEXP (x, 1);
    9008              :         }
    9009              :       break;
    9010              : 
    9011              :     default:
    9012              :       break;
    9013              :     }
    9014              :   return NULL;
    9015              : }
    9016              : 
    9017              : #if CHECKING_P
    9018              : 
    9019              : namespace selftest {
    9020              : 
    9021              : /* Make a unique pseudo REG of mode MODE for use by selftests.  */
    9022              : 
    9023              : static rtx
    9024         2672 : make_test_reg (machine_mode mode)
    9025              : {
    9026         2672 :   static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
    9027              : 
    9028         2672 :   return gen_rtx_REG (mode, test_reg_num++);
    9029              : }
    9030              : 
    9031              : static void
    9032           40 : test_scalar_int_ops (machine_mode mode)
    9033              : {
    9034           40 :   rtx op0 = make_test_reg (mode);
    9035           40 :   rtx op1 = make_test_reg (mode);
    9036           40 :   rtx six = GEN_INT (6);
    9037              : 
    9038           40 :   rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
    9039           40 :   rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
    9040           40 :   rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
    9041              : 
    9042           40 :   rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
    9043           40 :   rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
    9044           40 :   rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
    9045              : 
    9046           40 :   rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
    9047           40 :   rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
    9048              : 
    9049              :   /* Test some binary identities.  */
    9050           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
    9051           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
    9052           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
    9053           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
    9054           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
    9055           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
    9056           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
    9057           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
    9058           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
    9059           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
    9060           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
    9061           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
    9062           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
    9063           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
    9064           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
    9065           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
    9066           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
    9067              : 
    9068              :   /* Test some self-inverse operations.  */
    9069           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
    9070           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
    9071           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
    9072              : 
    9073              :   /* Test some reflexive operations.  */
    9074           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
    9075           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
    9076           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
    9077           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
    9078           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
    9079           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
    9080              : 
    9081           40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
    9082           40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
    9083              : 
    9084              :   /* Test simplify_distributive_operation.  */
    9085           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
    9086              :                  simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
    9087           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
    9088              :                  simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
    9089           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
    9090              :                  simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
    9091              : 
    9092              :   /* Test useless extensions are eliminated.  */
    9093           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
    9094           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
    9095           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
    9096           40 :   ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
    9097           40 : }
    9098              : 
    9099              : /* Verify some simplifications of integer extension/truncation.
    9100              :    Machine mode BMODE is the guaranteed wider than SMODE.  */
    9101              : 
    9102              : static void
    9103           24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
    9104              : {
    9105           24 :   rtx sreg = make_test_reg (smode);
    9106              : 
    9107              :   /* Check truncation of extension.  */
    9108           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9109              :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    9110              :                                                          sreg, smode),
    9111              :                                      bmode),
    9112              :                  sreg);
    9113           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9114              :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    9115              :                                                          sreg, smode),
    9116              :                                      bmode),
    9117              :                  sreg);
    9118           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9119              :                                      lowpart_subreg (bmode, sreg, smode),
    9120              :                                      bmode),
    9121              :                  sreg);
    9122              : 
    9123              :   /* Test extensions, followed by logic ops, followed by truncations.  */
    9124           24 :   rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
    9125           24 :   rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
    9126           24 :   rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
    9127           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9128              :                                  simplify_gen_binary (AND, bmode,
    9129              :                                                       bsubreg, smask),
    9130              :                                  bmode),
    9131              :                  sreg);
    9132           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9133              :                                  simplify_gen_binary (AND, bmode,
    9134              :                                                       bsubreg, inv_smask),
    9135              :                                  bmode),
    9136              :                  const0_rtx);
    9137           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9138              :                                  simplify_gen_binary (IOR, bmode,
    9139              :                                                       bsubreg, smask),
    9140              :                                  bmode),
    9141              :                  constm1_rtx);
    9142           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9143              :                                  simplify_gen_binary (IOR, bmode,
    9144              :                                                       bsubreg, inv_smask),
    9145              :                                  bmode),
    9146              :                  sreg);
    9147           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9148              :                                  simplify_gen_binary (XOR, bmode,
    9149              :                                                       bsubreg, smask),
    9150              :                                  bmode),
    9151              :                  lowpart_subreg (smode,
    9152              :                                  gen_rtx_NOT (bmode, bsubreg),
    9153              :                                  bmode));
    9154           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9155              :                                  simplify_gen_binary (XOR, bmode,
    9156              :                                                       bsubreg, inv_smask),
    9157              :                                  bmode),
    9158              :                  sreg);
    9159              : 
    9160           24 :   if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
    9161              :     {
    9162           24 :       rtx breg1 = make_test_reg (bmode);
    9163           24 :       rtx breg2 = make_test_reg (bmode);
    9164           24 :       rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
    9165           24 :       rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
    9166           24 :       rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
    9167           24 :       rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
    9168           24 :       rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
    9169           24 :       rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
    9170           24 :       rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
    9171           24 :       rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
    9172           24 :       rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
    9173           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
    9174              :                      gen_rtx_NOT (bmode, breg1));
    9175           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
    9176              :                      gen_rtx_AND (bmode, breg1, breg2));
    9177           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
    9178              :                      gen_rtx_IOR (bmode, breg1, breg2));
    9179           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
    9180              :                      gen_rtx_XOR (bmode, breg1, breg2));
    9181           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
    9182              :                      gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    9183           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
    9184              :                      gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    9185           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
    9186              :                      gen_rtx_XOR (bmode,
    9187              :                                   gen_rtx_XOR (bmode, breg1, breg2),
    9188              :                                   const1_rtx));
    9189              :     }
    9190           24 : }
    9191              : 
    9192              : /* Verify more simplifications of integer extension/truncation.
    9193              :    BMODE is wider than MMODE which is wider than SMODE.  */
    9194              : 
    9195              : static void
    9196           16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
    9197              :                           machine_mode smode)
    9198              : {
    9199           16 :   rtx breg = make_test_reg (bmode);
    9200           16 :   rtx mreg = make_test_reg (mmode);
    9201           16 :   rtx sreg = make_test_reg (smode);
    9202              : 
    9203              :   /* Check truncate of truncate.  */
    9204           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9205              :                                      simplify_gen_unary (TRUNCATE, mmode,
    9206              :                                                          breg, bmode),
    9207              :                                      mmode),
    9208              :                  simplify_gen_unary (TRUNCATE, smode, breg, bmode));
    9209              : 
    9210              :   /* Check extension of extension.  */
    9211           16 :   ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
    9212              :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    9213              :                                                          sreg, smode),
    9214              :                                      mmode),
    9215              :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    9216           16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    9217              :                                      simplify_gen_unary (SIGN_EXTEND, mmode,
    9218              :                                                          sreg, smode),
    9219              :                                      mmode),
    9220              :                  simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
    9221           16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    9222              :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    9223              :                                                          sreg, smode),
    9224              :                                      mmode),
    9225              :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    9226              : 
    9227              :   /* Check truncation of extension.  */
    9228           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9229              :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    9230              :                                                          mreg, mmode),
    9231              :                                      bmode),
    9232              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9233           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9234              :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    9235              :                                                          mreg, mmode),
    9236              :                                      bmode),
    9237              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9238           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9239              :                                      lowpart_subreg (bmode, mreg, mmode),
    9240              :                                      bmode),
    9241              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9242           16 : }
    9243              : 
    9244              : /* Test comparisons of comparisons, with the inner comparisons being
    9245              :    between values of mode MODE2 and producing results of mode MODE1,
    9246              :    and with the outer comparisons producing results of mode MODE0.  */
    9247              : 
    9248              : static void
    9249            4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
    9250              : {
    9251            4 :   rtx reg0 = make_test_reg (mode2);
    9252            4 :   rtx reg1 = make_test_reg (mode2);
    9253              : 
    9254            4 :   static const rtx_code codes[] = {
    9255              :     EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
    9256              :   };
    9257            4 :   constexpr auto num_codes = ARRAY_SIZE (codes);
    9258            4 :   rtx cmps[num_codes];
    9259            4 :   rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
    9260              : 
    9261           44 :   for (unsigned int i = 0; i < num_codes; ++i)
    9262           40 :     cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
    9263              : 
    9264           44 :   for (auto code : codes)
    9265          440 :     for (unsigned int i0 = 0; i0 < num_codes; ++i0)
    9266         4400 :       for (unsigned int i1 = 0; i1 < num_codes; ++i1)
    9267              :         {
    9268         4000 :           rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
    9269              :                                                        cmps[i0], cmps[i1]);
    9270         4000 :           if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
    9271         1280 :             ASSERT_TRUE (cmp_res == NULL_RTX);
    9272              :           else
    9273              :             {
    9274         2720 :               ASSERT_TRUE (cmp_res != NULL_RTX
    9275              :                            && (CONSTANT_P (cmp_res)
    9276              :                                || (COMPARISON_P (cmp_res)
    9277              :                                    && GET_MODE (cmp_res) == mode0
    9278              :                                    && REG_P (XEXP (cmp_res, 0))
    9279              :                                    && REG_P (XEXP (cmp_res, 1)))));
    9280        10880 :               for (rtx reg0_val : vals)
    9281        32640 :                 for (rtx reg1_val : vals)
    9282              :                   {
    9283        24480 :                     rtx val0 = simplify_const_relational_operation
    9284        24480 :                       (codes[i0], mode1, reg0_val, reg1_val);
    9285        24480 :                     rtx val1 = simplify_const_relational_operation
    9286        24480 :                       (codes[i1], mode1, reg0_val, reg1_val);
    9287        24480 :                     rtx val = simplify_const_relational_operation
    9288        24480 :                       (code, mode0, val0, val1);
    9289        24480 :                     rtx folded = cmp_res;
    9290        24480 :                     if (COMPARISON_P (cmp_res))
    9291        16704 :                       folded = simplify_const_relational_operation
    9292        16704 :                         (GET_CODE (cmp_res), mode0,
    9293        16704 :                          XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
    9294        16704 :                          XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
    9295        24480 :                     ASSERT_RTX_EQ (val, folded);
    9296              :                   }
    9297              :             }
    9298              :         }
    9299            4 : }
    9300              : 
    9301              : 
    9302              : /* Verify some simplifications involving scalar expressions.  */
    9303              : 
    9304              : static void
    9305            4 : test_scalar_ops ()
    9306              : {
    9307          500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    9308              :     {
    9309          496 :       machine_mode mode = (machine_mode) i;
    9310          496 :       if (SCALAR_INT_MODE_P (mode) && mode != BImode)
    9311           40 :         test_scalar_int_ops (mode);
    9312              :     }
    9313              : 
    9314            4 :   test_scalar_int_ext_ops (HImode, QImode);
    9315            4 :   test_scalar_int_ext_ops (SImode, QImode);
    9316            4 :   test_scalar_int_ext_ops (SImode, HImode);
    9317            4 :   test_scalar_int_ext_ops (DImode, QImode);
    9318            4 :   test_scalar_int_ext_ops (DImode, HImode);
    9319            4 :   test_scalar_int_ext_ops (DImode, SImode);
    9320              : 
    9321            4 :   test_scalar_int_ext_ops2 (SImode, HImode, QImode);
    9322            4 :   test_scalar_int_ext_ops2 (DImode, HImode, QImode);
    9323            4 :   test_scalar_int_ext_ops2 (DImode, SImode, QImode);
    9324            4 :   test_scalar_int_ext_ops2 (DImode, SImode, HImode);
    9325              : 
    9326            4 :   test_comparisons (QImode, HImode, SImode);
    9327            4 : }
    9328              : 
    9329              : /* Test vector simplifications involving VEC_DUPLICATE in which the
    9330              :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9331              :    register that holds one element of MODE.  */
    9332              : 
    9333              : static void
    9334          224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
    9335              : {
    9336          224 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9337          224 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9338          448 :   poly_uint64 nunits = GET_MODE_NUNITS (mode);
    9339          224 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    9340              :     {
    9341              :       /* Test some simple unary cases with VEC_DUPLICATE arguments.  */
    9342          124 :       rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
    9343          124 :       rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
    9344          124 :       ASSERT_RTX_EQ (duplicate,
    9345              :                      simplify_unary_operation (NOT, mode,
    9346              :                                                duplicate_not, mode));
    9347              : 
    9348          124 :       rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9349          124 :       rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
    9350          124 :       ASSERT_RTX_EQ (duplicate,
    9351              :                      simplify_unary_operation (NEG, mode,
    9352              :                                                duplicate_neg, mode));
    9353              : 
    9354              :       /* Test some simple binary cases with VEC_DUPLICATE arguments.  */
    9355          124 :       ASSERT_RTX_EQ (duplicate,
    9356              :                      simplify_binary_operation (PLUS, mode, duplicate,
    9357              :                                                 CONST0_RTX (mode)));
    9358              : 
    9359          124 :       ASSERT_RTX_EQ (duplicate,
    9360              :                      simplify_binary_operation (MINUS, mode, duplicate,
    9361              :                                                 CONST0_RTX (mode)));
    9362              : 
    9363          124 :       ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
    9364              :                          simplify_binary_operation (MINUS, mode, duplicate,
    9365              :                                                     duplicate));
    9366              :     }
    9367              : 
    9368              :   /* Test a scalar VEC_SELECT of a VEC_DUPLICATE.  */
    9369          224 :   rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
    9370          224 :   ASSERT_RTX_PTR_EQ (scalar_reg,
    9371              :                      simplify_binary_operation (VEC_SELECT, inner_mode,
    9372              :                                                 duplicate, zero_par));
    9373              : 
    9374          224 :   unsigned HOST_WIDE_INT const_nunits;
    9375          224 :   if (nunits.is_constant (&const_nunits))
    9376              :     {
    9377              :       /* And again with the final element.  */
    9378          224 :       rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
    9379          224 :       rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
    9380          224 :       ASSERT_RTX_PTR_EQ (scalar_reg,
    9381              :                          simplify_binary_operation (VEC_SELECT, inner_mode,
    9382              :                                                     duplicate, last_par));
    9383              : 
    9384              :       /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE.  */
    9385              :       /* Skip this test for vectors of booleans, because offset is in bytes,
    9386              :          while vec_merge indices are in elements (usually bits).  */
    9387          224 :       if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
    9388              :         {
    9389          224 :           rtx vector_reg = make_test_reg (mode);
    9390         3508 :           for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
    9391              :             {
    9392         3288 :               if (i >= HOST_BITS_PER_WIDE_INT)
    9393              :                 break;
    9394         3284 :               rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
    9395         3284 :               rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
    9396         6568 :               poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
    9397              : 
    9398         3284 :               ASSERT_RTX_EQ (scalar_reg,
    9399              :                              simplify_gen_subreg (inner_mode, vm,
    9400              :                                                   mode, offset));
    9401              :             }
    9402              :         }
    9403              :     }
    9404              : 
    9405              :   /* Test a scalar subreg of a VEC_DUPLICATE.  */
    9406          224 :   poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
    9407          224 :   ASSERT_RTX_EQ (scalar_reg,
    9408              :                  simplify_gen_subreg (inner_mode, duplicate,
    9409              :                                       mode, offset));
    9410              : 
    9411          224 :   machine_mode narrower_mode;
    9412          224 :   if (maybe_ne (nunits, 2U)
    9413          184 :       && multiple_p (nunits, 2)
    9414          396 :       && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
    9415          396 :       && VECTOR_MODE_P (narrower_mode))
    9416              :     {
    9417              :       /* Test VEC_DUPLICATE of a vector.  */
    9418          172 :       rtx_vector_builder nbuilder (narrower_mode, 2, 1);
    9419          172 :       nbuilder.quick_push (const0_rtx);
    9420          172 :       nbuilder.quick_push (const1_rtx);
    9421          172 :       rtx_vector_builder builder (mode, 2, 1);
    9422          172 :       builder.quick_push (const0_rtx);
    9423          172 :       builder.quick_push (const1_rtx);
    9424          172 :       ASSERT_RTX_EQ (builder.build (),
    9425              :                      simplify_unary_operation (VEC_DUPLICATE, mode,
    9426              :                                                nbuilder.build (),
    9427              :                                                narrower_mode));
    9428              : 
    9429              :       /* Test VEC_SELECT of a vector.  */
    9430          172 :       rtx vec_par
    9431          172 :         = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
    9432          172 :       rtx narrower_duplicate
    9433          172 :         = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
    9434          172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9435              :                      simplify_binary_operation (VEC_SELECT, narrower_mode,
    9436              :                                                 duplicate, vec_par));
    9437              : 
    9438              :       /* Test a vector subreg of a VEC_DUPLICATE.  */
    9439          172 :       poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
    9440          172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9441              :                      simplify_gen_subreg (narrower_mode, duplicate,
    9442              :                                           mode, offset));
    9443          172 :     }
    9444          224 : }
    9445              : 
    9446              : /* Test vector simplifications involving VEC_SERIES in which the
    9447              :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9448              :    register that holds one element of MODE.  */
    9449              : 
    9450              : static void
    9451           92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
    9452              : {
    9453              :   /* Test unary cases with VEC_SERIES arguments.  */
    9454           92 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9455           92 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9456           92 :   rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9457           92 :   rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
    9458           92 :   rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
    9459           92 :   rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
    9460           92 :   rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
    9461           92 :   rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
    9462           92 :   rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
    9463              :                                          neg_scalar_reg);
    9464           92 :   ASSERT_RTX_EQ (series_0_r,
    9465              :                  simplify_unary_operation (NEG, mode, series_0_nr, mode));
    9466           92 :   ASSERT_RTX_EQ (series_r_m1,
    9467              :                  simplify_unary_operation (NEG, mode, series_nr_1, mode));
    9468           92 :   ASSERT_RTX_EQ (series_r_r,
    9469              :                  simplify_unary_operation (NEG, mode, series_nr_nr, mode));
    9470              : 
    9471              :   /* Test that a VEC_SERIES with a zero step is simplified away.  */
    9472           92 :   ASSERT_RTX_EQ (duplicate,
    9473              :                  simplify_binary_operation (VEC_SERIES, mode,
    9474              :                                             scalar_reg, const0_rtx));
    9475              : 
    9476              :   /* Test PLUS and MINUS with VEC_SERIES.  */
    9477           92 :   rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
    9478           92 :   rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
    9479           92 :   rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
    9480           92 :   ASSERT_RTX_EQ (series_r_r,
    9481              :                  simplify_binary_operation (PLUS, mode, series_0_r,
    9482              :                                             duplicate));
    9483           92 :   ASSERT_RTX_EQ (series_r_1,
    9484              :                  simplify_binary_operation (PLUS, mode, duplicate,
    9485              :                                             series_0_1));
    9486           92 :   ASSERT_RTX_EQ (series_r_m1,
    9487              :                  simplify_binary_operation (PLUS, mode, duplicate,
    9488              :                                             series_0_m1));
    9489           92 :   ASSERT_RTX_EQ (series_0_r,
    9490              :                  simplify_binary_operation (MINUS, mode, series_r_r,
    9491              :                                             duplicate));
    9492           92 :   ASSERT_RTX_EQ (series_r_m1,
    9493              :                  simplify_binary_operation (MINUS, mode, duplicate,
    9494              :                                             series_0_1));
    9495           92 :   ASSERT_RTX_EQ (series_r_1,
    9496              :                  simplify_binary_operation (MINUS, mode, duplicate,
    9497              :                                             series_0_m1));
    9498           92 :   ASSERT_RTX_EQ (series_0_m1,
    9499              :                  simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
    9500              :                                             constm1_rtx));
    9501              : 
    9502              :   /* Test NEG on constant vector series.  */
    9503           92 :   ASSERT_RTX_EQ (series_0_m1,
    9504              :                  simplify_unary_operation (NEG, mode, series_0_1, mode));
    9505           92 :   ASSERT_RTX_EQ (series_0_1,
    9506              :                  simplify_unary_operation (NEG, mode, series_0_m1, mode));
    9507              : 
    9508              :   /* Test PLUS and MINUS on constant vector series.  */
    9509           92 :   rtx scalar2 = gen_int_mode (2, inner_mode);
    9510           92 :   rtx scalar3 = gen_int_mode (3, inner_mode);
    9511           92 :   rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
    9512           92 :   rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
    9513           92 :   rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
    9514           92 :   ASSERT_RTX_EQ (series_1_1,
    9515              :                  simplify_binary_operation (PLUS, mode, series_0_1,
    9516              :                                             CONST1_RTX (mode)));
    9517           92 :   ASSERT_RTX_EQ (series_0_m1,
    9518              :                  simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
    9519              :                                             series_0_m1));
    9520           92 :   ASSERT_RTX_EQ (series_1_3,
    9521              :                  simplify_binary_operation (PLUS, mode, series_1_1,
    9522              :                                             series_0_2));
    9523           92 :   ASSERT_RTX_EQ (series_0_1,
    9524              :                  simplify_binary_operation (MINUS, mode, series_1_1,
    9525              :                                             CONST1_RTX (mode)));
    9526           92 :   ASSERT_RTX_EQ (series_1_1,
    9527              :                  simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
    9528              :                                             series_0_m1));
    9529           92 :   ASSERT_RTX_EQ (series_1_1,
    9530              :                  simplify_binary_operation (MINUS, mode, series_1_3,
    9531              :                                             series_0_2));
    9532              : 
    9533              :   /* Test MULT between constant vectors.  */
    9534           92 :   rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
    9535           92 :   rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
    9536           92 :   rtx scalar9 = gen_int_mode (9, inner_mode);
    9537           92 :   rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
    9538           92 :   ASSERT_RTX_EQ (series_0_2,
    9539              :                  simplify_binary_operation (MULT, mode, series_0_1, vec2));
    9540           92 :   ASSERT_RTX_EQ (series_3_9,
    9541              :                  simplify_binary_operation (MULT, mode, vec3, series_1_3));
    9542           92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9543              :     ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
    9544              :                                              series_0_1));
    9545              : 
    9546              :   /* Test ASHIFT between constant vectors.  */
    9547           92 :   ASSERT_RTX_EQ (series_0_2,
    9548              :                  simplify_binary_operation (ASHIFT, mode, series_0_1,
    9549              :                                             CONST1_RTX (mode)));
    9550           92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9551              :     ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
    9552              :                                              series_0_1));
    9553           92 : }
    9554              : 
    9555              : static rtx
    9556         3136 : simplify_merge_mask (rtx x, rtx mask, int op)
    9557              : {
    9558            0 :   return simplify_context ().simplify_merge_mask (x, mask, op);
    9559              : }
    9560              : 
    9561              : /* Verify simplify_merge_mask works correctly.  */
    9562              : 
    9563              : static void
    9564          224 : test_vec_merge (machine_mode mode)
    9565              : {
    9566          224 :   rtx op0 = make_test_reg (mode);
    9567          224 :   rtx op1 = make_test_reg (mode);
    9568          224 :   rtx op2 = make_test_reg (mode);
    9569          224 :   rtx op3 = make_test_reg (mode);
    9570          224 :   rtx op4 = make_test_reg (mode);
    9571          224 :   rtx op5 = make_test_reg (mode);
    9572          224 :   rtx mask1 = make_test_reg (SImode);
    9573          224 :   rtx mask2 = make_test_reg (SImode);
    9574          224 :   rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
    9575          224 :   rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
    9576          224 :   rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
    9577              : 
    9578              :   /* Simple vec_merge.  */
    9579          224 :   ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
    9580          224 :   ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
    9581          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
    9582          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
    9583              : 
    9584              :   /* Nested vec_merge.
    9585              :      It's tempting to make this simplify right down to opN, but we don't
    9586              :      because all the simplify_* functions assume that the operands have
    9587              :      already been simplified.  */
    9588          224 :   rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
    9589          224 :   ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
    9590          224 :   ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
    9591              : 
    9592              :   /* Intermediate unary op. */
    9593          224 :   rtx unop = gen_rtx_NOT (mode, vm1);
    9594          224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
    9595              :                  simplify_merge_mask (unop, mask1, 0));
    9596          224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
    9597              :                  simplify_merge_mask (unop, mask1, 1));
    9598              : 
    9599              :   /* Intermediate binary op. */
    9600          224 :   rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
    9601          224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
    9602              :                  simplify_merge_mask (binop, mask1, 0));
    9603          224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
    9604              :                  simplify_merge_mask (binop, mask1, 1));
    9605              : 
    9606              :   /* Intermediate ternary op. */
    9607          224 :   rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
    9608          224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
    9609              :                  simplify_merge_mask (tenop, mask1, 0));
    9610          224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
    9611              :                  simplify_merge_mask (tenop, mask1, 1));
    9612              : 
    9613              :   /* Side effects.  */
    9614          224 :   rtx badop0 = gen_rtx_PRE_INC (mode, op0);
    9615          224 :   rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
    9616          224 :   ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
    9617          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
    9618              : 
    9619              :   /* Called indirectly.  */
    9620          224 :   ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
    9621              :                  simplify_rtx (nvm));
    9622          224 : }
    9623              : 
    9624              : /* Test that vector rotate formation works at RTL level.  Try various
    9625              :    combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)).  */
    9626              : 
    9627              : static void
    9628           92 : test_vector_rotate (rtx reg)
    9629              : {
    9630           92 :   machine_mode mode = GET_MODE (reg);
    9631           92 :   unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
    9632           92 :   rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
    9633           92 :   rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
    9634           92 :   lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
    9635           92 :   rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9636           92 :   rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
    9637              :   /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x).  */
    9638           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9639              :              simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
    9640           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9641              :              simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
    9642           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9643              :              simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
    9644              : 
    9645              :   /* Don't go through every possible rotate amount to save execution time.
    9646              :      Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
    9647              :      other bswap operations sometimes. Go through just the odd amounts.  */
    9648         1380 :   for (unsigned i = 3; i < bitwidth - 2; i += 2)
    9649              :     {
    9650         1288 :       rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
    9651         1288 :       rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
    9652         1288 :       lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
    9653         1288 :       lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9654         1288 :       rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
    9655         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9656              :                  simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
    9657         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9658              :                  simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
    9659         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9660              :                  simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
    9661              :     }
    9662           92 : }
    9663              : 
    9664              : /* Test subregs of integer vector constant X, trying elements in
    9665              :    the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
    9666              :    where NELTS is the number of elements in X.  Subregs involving
    9667              :    elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail.  */
    9668              : 
    9669              : static void
    9670          276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
    9671              :                            unsigned int first_valid = 0)
    9672              : {
    9673          276 :   machine_mode inner_mode = GET_MODE (x);
    9674          276 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9675              : 
    9676        34500 :   for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
    9677              :     {
    9678        34224 :       machine_mode outer_mode = (machine_mode) modei;
    9679        34224 :       if (!VECTOR_MODE_P (outer_mode))
    9680        18768 :         continue;
    9681              : 
    9682        15456 :       unsigned int outer_nunits;
    9683        15456 :       if (GET_MODE_INNER (outer_mode) == int_mode
    9684         1932 :           && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
    9685        20412 :           && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
    9686              :         {
    9687              :           /* Test subregs in which the outer mode is a smaller,
    9688              :              constant-sized vector of the same element type.  */
    9689         1092 :           unsigned int limit
    9690         1092 :             = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
    9691         8028 :           for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
    9692              :             {
    9693         6936 :               rtx expected = NULL_RTX;
    9694         6936 :               if (elt >= first_valid)
    9695              :                 {
    9696         6936 :                   rtx_vector_builder builder (outer_mode, outer_nunits, 1);
    9697        39768 :                   for (unsigned int i = 0; i < outer_nunits; ++i)
    9698        32832 :                     builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
    9699         6936 :                   expected = builder.build ();
    9700         6936 :                 }
    9701        13872 :               poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
    9702         6936 :               ASSERT_RTX_EQ (expected,
    9703              :                              simplify_subreg (outer_mode, x,
    9704              :                                               inner_mode, byte));
    9705              :             }
    9706              :         }
    9707        28728 :       else if (known_eq (GET_MODE_SIZE (outer_mode),
    9708              :                          GET_MODE_SIZE (inner_mode))
    9709         2040 :                && known_eq (elt_bias, 0U)
    9710         2040 :                && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
    9711            0 :                    || known_eq (GET_MODE_BITSIZE (outer_mode),
    9712              :                                 GET_MODE_NUNITS (outer_mode)))
    9713         2040 :                && (!FLOAT_MODE_P (outer_mode)
    9714        15876 :                    || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
    9715         1104 :                        == GET_MODE_UNIT_PRECISION (outer_mode)))
    9716        14364 :                && (GET_MODE_SIZE (inner_mode).is_constant ()
    9717              :                    || !CONST_VECTOR_STEPPED_P (x)))
    9718              :         {
    9719              :           /* Try converting to OUTER_MODE and back.  */
    9720         1800 :           rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
    9721         1800 :           ASSERT_TRUE (outer_x != NULL_RTX);
    9722         1800 :           ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
    9723              :                                              outer_mode, 0));
    9724              :         }
    9725              :     }
    9726              : 
    9727          276 :   if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
    9728              :     {
    9729              :       /* Test each byte in the element range.  */
    9730          276 :       unsigned int limit
    9731          276 :         = constant_lower_bound (GET_MODE_SIZE (inner_mode));
    9732        14604 :       for (unsigned int i = 0; i < limit; ++i)
    9733              :         {
    9734        14328 :           unsigned int elt = i / GET_MODE_SIZE (int_mode);
    9735        14328 :           rtx expected = NULL_RTX;
    9736        14328 :           if (elt >= first_valid)
    9737              :             {
    9738        14328 :               unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
    9739        14328 :               if (BYTES_BIG_ENDIAN)
    9740              :                 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
    9741        14328 :               rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
    9742        14328 :               wide_int shifted_elt
    9743        14328 :                 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
    9744        14328 :               expected = immed_wide_int_const (shifted_elt, QImode);
    9745        14328 :             }
    9746        28656 :           poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
    9747        14328 :           ASSERT_RTX_EQ (expected,
    9748              :                          simplify_subreg (QImode, x, inner_mode, byte));
    9749              :         }
    9750              :     }
    9751          276 : }
    9752              : 
    9753              : /* Test constant subregs of integer vector mode INNER_MODE, using 1
    9754              :    element per pattern.  */
    9755              : 
    9756              : static void
    9757           92 : test_vector_subregs_repeating (machine_mode inner_mode)
    9758              : {
    9759          184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
    9760           92 :   unsigned int min_nunits = constant_lower_bound (nunits);
    9761           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9762           92 :   unsigned int count = gcd (min_nunits, 8);
    9763              : 
    9764           92 :   rtx_vector_builder builder (inner_mode, count, 1);
    9765          684 :   for (unsigned int i = 0; i < count; ++i)
    9766          592 :     builder.quick_push (gen_int_mode (8 - i, int_mode));
    9767           92 :   rtx x = builder.build ();
    9768              : 
    9769           92 :   test_vector_subregs_modes (x);
    9770           92 :   if (!nunits.is_constant ())
    9771              :     test_vector_subregs_modes (x, nunits - min_nunits);
    9772           92 : }
    9773              : 
    9774              : /* Test constant subregs of integer vector mode INNER_MODE, using 2
    9775              :    elements per pattern.  */
    9776              : 
    9777              : static void
    9778           92 : test_vector_subregs_fore_back (machine_mode inner_mode)
    9779              : {
    9780          184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
    9781           92 :   unsigned int min_nunits = constant_lower_bound (nunits);
    9782           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9783           92 :   unsigned int count = gcd (min_nunits, 4);
    9784              : 
    9785           92 :   rtx_vector_builder builder (inner_mode, count, 2);
    9786          444 :   for (unsigned int i = 0; i < count; ++i)
    9787          352 :     builder.quick_push (gen_int_mode (i, int_mode));
    9788          444 :   for (unsigned int i = 0; i < count; ++i)
    9789          352 :     builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
    9790           92 :   rtx x = builder.build ();
    9791              : 
    9792           92 :   test_vector_subregs_modes (x);
    9793           92 :   if (!nunits.is_constant ())
    9794              :     test_vector_subregs_modes (x, nunits - min_nunits, count);
    9795           92 : }
    9796              : 
    9797              : /* Test constant subregs of integer vector mode INNER_MODE, using 3
    9798              :    elements per pattern.  */
    9799              : 
    9800              : static void
    9801           92 : test_vector_subregs_stepped (machine_mode inner_mode)
    9802              : {
    9803              :   /* Build { 0, 1, 2, 3, ... }.  */
    9804           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9805           92 :   rtx_vector_builder builder (inner_mode, 1, 3);
    9806          368 :   for (unsigned int i = 0; i < 3; ++i)
    9807          276 :     builder.quick_push (gen_int_mode (i, int_mode));
    9808           92 :   rtx x = builder.build ();
    9809              : 
    9810           92 :   test_vector_subregs_modes (x);
    9811           92 : }
    9812              : 
    9813              : /* Test constant subregs of integer vector mode INNER_MODE.  */
    9814              : 
    9815              : static void
    9816           92 : test_vector_subregs (machine_mode inner_mode)
    9817              : {
    9818           92 :   test_vector_subregs_repeating (inner_mode);
    9819           92 :   test_vector_subregs_fore_back (inner_mode);
    9820           92 :   test_vector_subregs_stepped (inner_mode);
    9821           92 : }
    9822              : 
    9823              : /* Verify some simplifications involving vectors.  */
    9824              : 
    9825              : static void
    9826            4 : test_vector_ops ()
    9827              : {
    9828          500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    9829              :     {
    9830          496 :       machine_mode mode = (machine_mode) i;
    9831          496 :       if (VECTOR_MODE_P (mode))
    9832              :         {
    9833          448 :           rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
    9834          224 :           test_vector_ops_duplicate (mode, scalar_reg);
    9835          224 :           rtx vector_reg = make_test_reg (mode);
    9836          224 :           if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
    9837          348 :               && maybe_gt (GET_MODE_NUNITS (mode), 2))
    9838              :             {
    9839           92 :               test_vector_ops_series (mode, scalar_reg);
    9840           92 :               test_vector_subregs (mode);
    9841           92 :               test_vector_rotate (vector_reg);
    9842              :             }
    9843          224 :           test_vec_merge (mode);
    9844              :         }
    9845              :     }
    9846            4 : }
    9847              : 
    9848              : template<unsigned int N>
    9849              : struct simplify_const_poly_int_tests
    9850              : {
    9851              :   static void run ();
    9852              : };
    9853              : 
    9854              : template<>
    9855              : struct simplify_const_poly_int_tests<1>
    9856              : {
    9857              :   static void run () {}
    9858              : };
    9859              : 
    9860              : /* Test various CONST_POLY_INT properties.  */
    9861              : 
    9862              : template<unsigned int N>
    9863              : void
    9864              : simplify_const_poly_int_tests<N>::run ()
    9865              : {
    9866              :   using poly_int64 = poly_int<N, HOST_WIDE_INT>;
    9867              :   rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
    9868              :   rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
    9869              :   rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
    9870              :   rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
    9871              :   rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
    9872              :   rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
    9873              :   rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
    9874              :   rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
    9875              :   rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
    9876              :   rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
    9877              :   rtx two = GEN_INT (2);
    9878              :   rtx six = GEN_INT (6);
    9879              :   poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
    9880              : 
    9881              :   /* These tests only try limited operation combinations.  Fuller arithmetic
    9882              :      testing is done directly on poly_ints.  */
    9883              :   ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
    9884              :   ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
    9885              :   ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
    9886              :   ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
    9887              :   ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
    9888              :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
    9889              :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
    9890              :   ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
    9891              :   ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
    9892              :   ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
    9893              :   ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
    9894              : }
    9895              : 
    9896              : /* Run all of the selftests within this file.  */
    9897              : 
    9898              : void
    9899            4 : simplify_rtx_cc_tests ()
    9900              : {
    9901            4 :   test_scalar_ops ();
    9902            4 :   test_vector_ops ();
    9903            4 :   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
    9904            4 : }
    9905              : 
    9906              : } // namespace selftest
    9907              : 
    9908              : #endif /* CHECKING_P */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.