LCOV - code coverage report
Current view: top level - gcc - simplify-rtx.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.9 % 4928 4382
Test Date: 2026-08-22 16:33:35 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      9123258 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
      56              : {
      57      9123258 :   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      6230625 : mode_signbit_p (machine_mode mode, const_rtx x)
      65              : {
      66      6230625 :   unsigned HOST_WIDE_INT val;
      67      6230625 :   unsigned int width;
      68      6230625 :   scalar_int_mode int_mode;
      69              : 
      70      6230625 :   if (!is_int_mode (mode, &int_mode))
      71              :     return false;
      72              : 
      73      6230617 :   width = GET_MODE_PRECISION (int_mode);
      74      6230617 :   if (width == 0)
      75              :     return false;
      76              : 
      77      6230617 :   if (width <= HOST_BITS_PER_WIDE_INT
      78      6229082 :       && CONST_INT_P (x))
      79      6078410 :     val = INTVAL (x);
      80              : #if TARGET_SUPPORTS_WIDE_INT
      81       152207 :   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      6078410 :   if (width < HOST_BITS_PER_WIDE_INT)
     109      5527197 :     val &= (HOST_WIDE_INT_1U << width) - 1;
     110      6078833 :   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      3797934 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     119              : {
     120      3797934 :   unsigned int width;
     121      3797934 :   scalar_int_mode int_mode;
     122              : 
     123      3797934 :   if (!is_int_mode (mode, &int_mode))
     124              :     return false;
     125              : 
     126      3797898 :   width = GET_MODE_PRECISION (int_mode);
     127      3797898 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     128              :     return false;
     129              : 
     130      3792912 :   val &= GET_MODE_MASK (int_mode);
     131      3792912 :   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      2628813 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     138              : {
     139      2628813 :   unsigned int width;
     140              : 
     141      2628813 :   scalar_int_mode int_mode;
     142      2628813 :   if (!is_int_mode (mode, &int_mode))
     143              :     return false;
     144              : 
     145      2582625 :   width = GET_MODE_PRECISION (int_mode);
     146      2582625 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     147              :     return false;
     148              : 
     149      2582625 :   val &= HOST_WIDE_INT_1U << (width - 1);
     150      2582625 :   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      7824665 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     157              : {
     158      7824665 :   unsigned int width;
     159              : 
     160      7824665 :   scalar_int_mode int_mode;
     161      7824665 :   if (!is_int_mode (mode, &int_mode))
     162              :     return false;
     163              : 
     164      7467352 :   width = GET_MODE_PRECISION (int_mode);
     165      7467352 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     166              :     return false;
     167              : 
     168      7356697 :   val &= HOST_WIDE_INT_1U << (width - 1);
     169      7356697 :   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    121734712 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
     177              :                                        rtx op0, rtx op1)
     178              : {
     179    121734712 :   rtx tem;
     180              : 
     181              :   /* If this simplifies, do it.  */
     182    121734712 :   tem = simplify_binary_operation (code, mode, op0, op1);
     183    121734712 :   if (tem)
     184              :     return tem;
     185              : 
     186              :   /* Put complex operands first and constants second if commutative.  */
     187     77307523 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
     188     77307523 :       && swap_commutative_operands_p (op0, op1))
     189              :     std::swap (op0, op1);
     190              : 
     191     77307523 :   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   2786504311 : avoid_constant_pool_reference (rtx x)
     198              : {
     199   2786504311 :   rtx c, tmp, addr;
     200   2786504311 :   machine_mode cmode;
     201   2786504311 :   poly_int64 offset = 0;
     202              : 
     203   2786504311 :   switch (GET_CODE (x))
     204              :     {
     205    266861124 :     case MEM:
     206    266861124 :       break;
     207              : 
     208       916183 :     case FLOAT_EXTEND:
     209              :       /* Handle float extensions of constant pool references.  */
     210       916183 :       tmp = XEXP (x, 0);
     211       916183 :       c = avoid_constant_pool_reference (tmp);
     212       916183 :       if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
     213       124932 :         return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
     214       124932 :                                              GET_MODE (x));
     215              :       return x;
     216              : 
     217              :     default:
     218              :       return x;
     219              :     }
     220              : 
     221    266861124 :   if (GET_MODE (x) == BLKmode)
     222              :     return x;
     223              : 
     224    262772168 :   addr = XEXP (x, 0);
     225              : 
     226              :   /* Call target hook to avoid the effects of -fpic etc....  */
     227    262772168 :   addr = targetm.delegitimize_address (addr);
     228              : 
     229              :   /* Split the address into a base and integer offset.  */
     230    262772168 :   addr = strip_offset (addr, &offset);
     231              : 
     232    262772168 :   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    262772168 :   if (GET_CODE (addr) == SYMBOL_REF
     238    262772168 :       && CONSTANT_POOL_ADDRESS_P (addr))
     239              :     {
     240      5387842 :       c = get_pool_constant (addr);
     241      5387842 :       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      5387842 :       if (known_eq (offset, 0) && cmode == GET_MODE (x))
     247              :         return c;
     248        44856 :       else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
     249              :         {
     250        14952 :           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
     251        14952 :           if (tem && CONSTANT_P (tem))
     252        14835 :             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   3564842858 : 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   3564842858 :   if (MEM_P (x)
     269     63227483 :       && MEM_EXPR (x)
     270   3604138686 :       && MEM_OFFSET_KNOWN_P (x))
     271              :     {
     272     36296774 :       tree decl = MEM_EXPR (x);
     273     36296774 :       machine_mode mode = GET_MODE (x);
     274     36296774 :       poly_int64 offset = 0;
     275              : 
     276     36296774 :       switch (TREE_CODE (decl))
     277              :         {
     278              :         default:
     279              :           decl = NULL;
     280              :           break;
     281              : 
     282              :         case VAR_DECL:
     283              :           break;
     284              : 
     285     10218974 :         case ARRAY_REF:
     286     10218974 :         case ARRAY_RANGE_REF:
     287     10218974 :         case COMPONENT_REF:
     288     10218974 :         case BIT_FIELD_REF:
     289     10218974 :         case REALPART_EXPR:
     290     10218974 :         case IMAGPART_EXPR:
     291     10218974 :         case VIEW_CONVERT_EXPR:
     292     10218974 :           {
     293     10218974 :             poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
     294     10218974 :             tree toffset;
     295     10218974 :             int unsignedp, reversep, volatilep = 0;
     296              : 
     297     10218974 :             decl
     298     10218974 :               = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
     299              :                                      &unsignedp, &reversep, &volatilep);
     300     20437948 :             if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
     301     10515296 :                 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
     302     19997593 :                 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
     303              :               decl = NULL;
     304              :             else
     305      9482297 :               offset += bytepos + toffset_val;
     306     10218974 :             break;
     307              :           }
     308              :         }
     309              : 
     310       736677 :       if (decl
     311     21328520 :           && mode == GET_MODE (x)
     312     21057694 :           && VAR_P (decl)
     313     13761545 :           && (TREE_STATIC (decl)
     314     12530142 :               || DECL_THREAD_LOCAL_P (decl))
     315      1268369 :           && DECL_RTL_SET_P (decl)
     316     10750196 :           && MEM_P (DECL_RTL (decl)))
     317              :         {
     318      1267899 :           rtx newx;
     319              : 
     320      1267899 :           offset += MEM_OFFSET (x);
     321              : 
     322      1267899 :           newx = DECL_RTL (decl);
     323              : 
     324      1267899 :           if (MEM_P (newx))
     325              :             {
     326      1267899 :               rtx n = XEXP (newx, 0), o = XEXP (x, 0);
     327      1267899 :               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      1267899 :               n = strip_offset (n, &n_offset);
     336      1267899 :               o = strip_offset (o, &o_offset);
     337      2507962 :               if (!(known_eq (o_offset, n_offset + offset)
     338      1240063 :                     && rtx_equal_p (o, n)))
     339       212538 :                 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   3564842858 :   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      7134498 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
     355              :                                       machine_mode op_mode)
     356              : {
     357      7134498 :   rtx tem;
     358              : 
     359              :   /* If this simplifies, use it.  */
     360      7134498 :   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
     361              :     return tem;
     362              : 
     363      2440005 :   return gen_rtx_fmt_e (code, mode, op);
     364              : }
     365              : 
     366              : /* Likewise for ternary operations.  */
     367              : 
     368              : rtx
     369      2430018 : 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      2430018 :   rtx tem;
     374              : 
     375              :   /* If this simplifies, use it.  */
     376      2430018 :   if ((tem = simplify_ternary_operation (code, mode, op0_mode,
     377              :                                          op0, op1, op2)) != 0)
     378              :     return tem;
     379              : 
     380      2178870 :   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     21808476 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
     388              :                                            machine_mode cmp_mode,
     389              :                                            rtx op0, rtx op1)
     390              : {
     391     21808476 :   rtx tem;
     392              : 
     393     21808476 :   if ((tem = simplify_relational_operation (code, mode, cmp_mode,
     394              :                                             op0, op1)) != 0)
     395              :     return tem;
     396              : 
     397     19630035 :   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    504157799 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
     407              :                          rtx (*fn) (rtx, const_rtx, void *), void *data)
     408              : {
     409    504157799 :   enum rtx_code code = GET_CODE (x);
     410    504157799 :   machine_mode mode = GET_MODE (x);
     411    504157799 :   machine_mode op_mode;
     412    504157799 :   const char *fmt;
     413    504157799 :   rtx op0, op1, op2, newx, op;
     414    504157799 :   rtvec vec, newvec;
     415    504157799 :   int i, j;
     416              : 
     417    504157799 :   if (UNLIKELY (fn != NULL))
     418              :     {
     419    441838527 :       newx = fn (x, old_rtx, data);
     420    441838527 :       if (newx)
     421              :         return newx;
     422              :     }
     423     62319272 :   else if (rtx_equal_p (x, old_rtx))
     424      5199091 :     return copy_rtx ((rtx) data);
     425              : 
     426    397504366 :   switch (GET_RTX_CLASS (code))
     427              :     {
     428      2062448 :     case RTX_UNARY:
     429      2062448 :       op0 = XEXP (x, 0);
     430      2062448 :       op_mode = GET_MODE (op0);
     431      2062448 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     432      2062448 :       if (op0 == XEXP (x, 0))
     433              :         return x;
     434       650596 :       return simplify_gen_unary (code, mode, op0, op_mode);
     435              : 
     436     76442747 :     case RTX_BIN_ARITH:
     437     76442747 :     case RTX_COMM_ARITH:
     438     76442747 :       op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     439     76442747 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     440     76442747 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     441              :         return x;
     442     23653460 :       return simplify_gen_binary (code, mode, op0, op1);
     443              : 
     444      9765795 :     case RTX_COMPARE:
     445      9765795 :     case RTX_COMM_COMPARE:
     446      9765795 :       op0 = XEXP (x, 0);
     447      9765795 :       op1 = XEXP (x, 1);
     448      9765795 :       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
     449      9765795 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     450      9765795 :       op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
     451      9765795 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     452              :         return x;
     453      2339180 :       return simplify_gen_relational (code, mode, op_mode, op0, op1);
     454              : 
     455      5875596 :     case RTX_TERNARY:
     456      5875596 :     case RTX_BITFIELD_OPS:
     457      5875596 :       op0 = XEXP (x, 0);
     458      5875596 :       op_mode = GET_MODE (op0);
     459      5875596 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     460      5875596 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     461      5875596 :       op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
     462      5875596 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
     463              :         return x;
     464      1686004 :       if (op_mode == VOIDmode)
     465      1662360 :         op_mode = GET_MODE (op0);
     466      1686004 :       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
     467              : 
     468     90584053 :     case RTX_EXTRA:
     469     90584053 :       if (code == SUBREG)
     470              :         {
     471       619288 :           op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
     472       619288 :           if (op0 == SUBREG_REG (x))
     473              :             return x;
     474       133684 :           op0 = simplify_gen_subreg (GET_MODE (x), op0,
     475        66842 :                                      GET_MODE (SUBREG_REG (x)),
     476        66842 :                                      SUBREG_BYTE (x));
     477        66842 :           return op0 ? op0 : x;
     478              :         }
     479              :       break;
     480              : 
     481     63317177 :     case RTX_OBJ:
     482     63317177 :       if (code == MEM)
     483              :         {
     484     10869518 :           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     485     10869518 :           if (op0 == XEXP (x, 0))
     486              :             return x;
     487       162563 :           return replace_equiv_address_nv (x, op0);
     488              :         }
     489     52447659 :       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    291868974 :   newx = x;
     515    291868974 :   fmt = GET_RTX_FORMAT (code);
     516    631210098 :   for (i = 0; fmt[i]; i++)
     517    339341124 :     switch (fmt[i])
     518              :       {
     519      3251835 :       case 'E':
     520      3251835 :         vec = XVEC (x, i);
     521      3251835 :         newvec = XVEC (newx, i);
     522     13572421 :         for (j = 0; j < GET_NUM_ELEM (vec); j++)
     523              :           {
     524     10320586 :             op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
     525              :                                           old_rtx, fn, data);
     526     10320586 :             if (op != RTVEC_ELT (vec, j))
     527              :               {
     528       356706 :                 if (newvec == vec)
     529              :                   {
     530       342146 :                     newvec = shallow_copy_rtvec (vec);
     531       342146 :                     if (x == newx)
     532       342146 :                       newx = shallow_copy_rtx (x);
     533       342146 :                     XVEC (newx, i) = newvec;
     534              :                   }
     535       356706 :                 RTVEC_ELT (newvec, j) = op;
     536              :               }
     537              :           }
     538              :         break;
     539              : 
     540     81938459 :       case 'e':
     541     81938459 :         if (XEXP (x, i))
     542              :           {
     543     81938408 :             op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
     544     81938408 :             if (op != XEXP (x, i))
     545              :               {
     546      4652217 :                 if (x == newx)
     547      4649034 :                   newx = shallow_copy_rtx (x);
     548      4652217 :                 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     12796126 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
     561              : {
     562     12796126 :   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     23474838 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
     614              :                                        machine_mode op_mode)
     615              : {
     616     23474838 :   unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
     617     23474838 :   unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
     618     23474838 :   scalar_int_mode int_mode, int_op_mode, subreg_mode;
     619              : 
     620     23474838 :   gcc_assert (precision <= op_precision);
     621              : 
     622              :   /* Optimize truncations of zero and sign extended values.  */
     623     23474838 :   if (GET_CODE (op) == ZERO_EXTEND
     624     23474838 :       || 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       374602 :       machine_mode origmode = GET_MODE (XEXP (op, 0));
     633       374602 :       if (mode == origmode)
     634              :         return XEXP (op, 0);
     635        26756 :       else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
     636        10528 :         return simplify_gen_unary (TRUNCATE, mode,
     637        10528 :                                    XEXP (op, 0), origmode);
     638              :       else
     639         2850 :         return simplify_gen_unary (GET_CODE (op), mode,
     640         2850 :                                    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     23100236 :   if (1
     647              :       && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
     648              :       && (GET_CODE (op) == PLUS
     649              :           || GET_CODE (op) == MINUS
     650     23100236 :           || GET_CODE (op) == MULT))
     651              :     {
     652      1408536 :       rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
     653      1408536 :       if (op0)
     654              :         {
     655      1408536 :           rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
     656      1408536 :           if (op1)
     657      1408536 :             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     21691700 :   if ((GET_CODE (op) == LSHIFTRT
     665     21691700 :        || 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      1914296 :       && 2 * precision <= op_precision
     671      1914296 :       && CONST_INT_P (XEXP (op, 1))
     672      1812997 :       && 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     21691676 :   if ((GET_CODE (op) == LSHIFTRT
     682              :        || GET_CODE (op) == ASHIFTRT)
     683      1914272 :       && CONST_INT_P (XEXP (op, 1))
     684      1812973 :       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     685          805 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     686          805 :       && UINTVAL (XEXP (op, 1)) < precision)
     687          788 :     return simplify_gen_binary (LSHIFTRT, mode,
     688          788 :                                 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     21690888 :   if (GET_CODE (op) == ASHIFT
     694       837727 :       && CONST_INT_P (XEXP (op, 1))
     695       778143 :       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     696       778143 :           || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
     697          674 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     698          666 :       && UINTVAL (XEXP (op, 1)) < precision)
     699          621 :     return simplify_gen_binary (ASHIFT, mode,
     700          621 :                                 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     21690267 :   if (GET_CODE (op) == AND
     706       790920 :       && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
     707       790920 :           || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
     708        45802 :       && CONST_INT_P (XEXP (XEXP (op, 0), 1))
     709        45700 :       && CONST_INT_P (XEXP (op, 1)))
     710              :     {
     711        45667 :       rtx op0 = (XEXP (XEXP (op, 0), 0));
     712        45667 :       rtx shift_op = XEXP (XEXP (op, 0), 1);
     713        45667 :       rtx mask_op = XEXP (op, 1);
     714        45667 :       unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
     715        45667 :       unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
     716              : 
     717        45667 :       if (shift < precision
     718              :           /* If doing this transform works for an X with all bits set,
     719              :              it works for any X.  */
     720        29817 :           && ((GET_MODE_MASK (mode) >> shift) & mask)
     721        29817 :              == ((GET_MODE_MASK (op_mode) >> shift) & mask)
     722         6697 :           && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
     723        52364 :           && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
     724              :         {
     725         6697 :           mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
     726         6697 :           return simplify_gen_binary (AND, mode, op0, mask_op);
     727              :         }
     728              :     }
     729              : 
     730              :   /* Turn (truncate:M1 (*_extract:M2 (reg:M3) (len) (pos))) into
     731              :      (*_extract:M1 (truncate:M1 (reg:M3)) (len) (pos')) if possible.  */
     732     21683570 :   if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
     733      1120100 :       && precision <= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (op, 0)))
     734       558437 :       && CONST_INT_P (XEXP (op, 1))
     735     22242007 :       && CONST_INT_P (XEXP (op, 2)))
     736              :     {
     737       523511 :       rtx op0 = XEXP (op, 0);
     738       523511 :       unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
     739       523511 :       unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
     740       523511 :       if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
     741              :         {
     742              :           if (GET_MODE (op0) != mode)
     743              :             op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     744              :           if (op0)
     745              :             {
     746              :               pos -= op_precision - precision;
     747              :               return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     748              :                                            XEXP (op, 1), GEN_INT (pos));
     749              :             }
     750              :         }
     751       523511 :       else if (!BITS_BIG_ENDIAN && precision >= len + pos)
     752              :         {
     753       174238 :           if (GET_MODE (op0) != mode)
     754       133214 :             op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     755       133214 :           if (op0)
     756       174238 :             return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     757       174238 :                                          XEXP (op, 1), XEXP (op, 2));
     758              :         }
     759              :     }
     760              : 
     761              :   /* Recognize a word extraction from a multi-word subreg.  */
     762     21509332 :   if ((GET_CODE (op) == LSHIFTRT
     763     21509332 :        || GET_CODE (op) == ASHIFTRT)
     764      1913484 :       && SCALAR_INT_MODE_P (mode)
     765      1910394 :       && SCALAR_INT_MODE_P (op_mode)
     766      2048327 :       && precision >= BITS_PER_WORD
     767        61844 :       && 2 * precision <= op_precision
     768        61844 :       && CONST_INT_P (XEXP (op, 1))
     769        52267 :       && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
     770         2113 :       && UINTVAL (XEXP (op, 1)) < op_precision)
     771              :     {
     772         2113 :       poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
     773         2113 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     774         2113 :       return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
     775              :                                   (WORDS_BIG_ENDIAN
     776         2113 :                                    ? byte - shifted_bytes
     777         2113 :                                    : 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     21507219 :   if ((GET_CODE (op) == LSHIFTRT
     784              :        || GET_CODE (op) == ASHIFTRT)
     785      1908281 :       && is_a <scalar_int_mode> (mode, &int_mode)
     786     21506531 :       && is_a <scalar_int_mode> (op_mode, &int_op_mode)
     787      1908281 :       && MEM_P (XEXP (op, 0))
     788        11280 :       && CONST_INT_P (XEXP (op, 1))
     789        20660 :       && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
     790          731 :       && INTVAL (XEXP (op, 1)) > 0
     791         1462 :       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
     792          731 :       && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
     793          731 :                                      MEM_ADDR_SPACE (XEXP (op, 0)))
     794          731 :       && ! MEM_VOLATILE_P (XEXP (op, 0))
     795     21507219 :       && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
     796              :           || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
     797              :     {
     798          688 :       poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
     799          688 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     800          688 :       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     21506531 :   if ((GET_CODE (op) == ABS
     809     21506531 :        || GET_CODE (op) == NEG)
     810        21121 :       && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
     811        21121 :           || 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     21506530 :   if (GET_CODE (op) == SUBREG
     818     21507079 :       && is_a <scalar_int_mode> (mode, &int_mode)
     819       116424 :       && SCALAR_INT_MODE_P (op_mode)
     820       116424 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
     821     21622459 :       && subreg_lowpart_p (op))
     822              :     {
     823              :       /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X).  */
     824       115909 :       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       115909 :       if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
     841              :         {
     842       115909 :           unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
     843       115909 :           unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
     844       115909 :           if (int_op_prec > subreg_prec)
     845              :             {
     846        85788 :               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        30121 :           else if (int_op_prec < subreg_prec
     855        30121 :                    && GET_MODE_PRECISION (int_mode) < int_op_prec)
     856        30121 :             return simplify_gen_unary (TRUNCATE, int_mode,
     857        30121 :                                        SUBREG_REG (op), subreg_mode);
     858              :         }
     859              :     }
     860              : 
     861              :   /* (truncate:A (truncate:B X)) is (truncate:A X).  */
     862     21390655 :   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     21390655 :   if (GET_CODE (op) == IOR
     869        38352 :       && SCALAR_INT_MODE_P (mode)
     870        38352 :       && SCALAR_INT_MODE_P (op_mode)
     871        38352 :       && CONST_INT_P (XEXP (op, 1))
     872     21399722 :       && 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     29747262 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
     883              :                                             rtx op, machine_mode op_mode)
     884              : {
     885     29747262 :   rtx trueop, tem;
     886              : 
     887     29747262 :   trueop = avoid_constant_pool_reference (op);
     888              : 
     889     29747262 :   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
     890     29747262 :   if (tem)
     891              :     return tem;
     892              : 
     893     24328368 :   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         2833 : exact_int_to_float_conversion_p (const_rtx op)
     901              : {
     902         2833 :   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         2833 :   if (op0_mode == VOIDmode)
     906              :     return false;
     907         5664 :   int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
     908         2832 :   int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
     909         2832 :   int in_bits = in_prec;
     910         2832 :   if (HWI_COMPUTABLE_MODE_P (op0_mode))
     911              :     {
     912         2742 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
     913         2742 :       if (GET_CODE (op) == FLOAT)
     914         2621 :         in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
     915          121 :       else if (GET_CODE (op) == UNSIGNED_FLOAT)
     916          121 :         in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
     917              :       else
     918            0 :         gcc_unreachable ();
     919         2742 :       in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
     920              :     }
     921         2832 :   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     24328368 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
     928              :                                               rtx op)
     929              : {
     930     24328368 :   enum rtx_code reversed;
     931     24328368 :   rtx temp, elt, base, step;
     932     24328368 :   scalar_int_mode inner, int_mode, op_mode, op0_mode;
     933              : 
     934     24328368 :   switch (code)
     935              :     {
     936      2330368 :     case NOT:
     937              :       /* (not (not X)) == X.  */
     938      2330368 :       if (GET_CODE (op) == NOT)
     939         3141 :         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      2327227 :       if (COMPARISON_P (op)
     944        17101 :           && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == -1)
     945              : #ifdef VECTOR_STORE_FLAG_VALUE
     946        17101 :               || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
     947              :                   && VECTOR_STORE_FLAG_VALUE (mode) == constm1_rtx)
     948              : #endif
     949        11831 :               || mode == BImode)
     950      2332497 :           && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
     951         5101 :         return simplify_gen_relational (reversed, mode, VOIDmode,
     952         5101 :                                         XEXP (op, 0), XEXP (op, 1));
     953              : 
     954              :       /* (not (neg (eq X Y))) is (neg (ne X Y)), etc. if the result of
     955              :          the comparison is one.  */
     956      2322126 :       if (GET_CODE (op) == NEG
     957        71207 :           && COMPARISON_P (XEXP (op, 0))
     958            6 :           && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == 1)
     959              : #ifdef VECTOR_STORE_FLAG_VALUE
     960            0 :               || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
     961            0 :                   && VECTOR_STORE_FLAG_VALUE (mode) == const1_rtx)
     962              : #endif
     963              :              )
     964      2322132 :           && ((reversed = reversed_comparison_code (XEXP (op, 0), NULL))
     965              :               != UNKNOWN))
     966              :         {
     967           12 :           temp = simplify_gen_relational (reversed, mode, VOIDmode,
     968              :                                           XEXP (XEXP (op, 0), 0),
     969            6 :                                           XEXP (XEXP (op, 0), 1));
     970            6 :           return simplify_gen_unary (NEG, mode, temp, mode);
     971              :         }
     972              : 
     973              :       /* (not (plus X -1)) can become (neg X).  */
     974      2322120 :       if (GET_CODE (op) == PLUS
     975       249074 :           && XEXP (op, 1) == constm1_rtx)
     976         4623 :         return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
     977              : 
     978              :       /* Similarly, (not (neg X)) is (plus X -1).  Only do this for
     979              :          modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
     980              :          and MODE_VECTOR_INT.  */
     981      2317497 :       if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
     982        71198 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
     983        71198 :                                     CONSTM1_RTX (mode));
     984              : 
     985              :       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
     986      2246299 :       if (GET_CODE (op) == XOR
     987        19320 :           && CONST_INT_P (XEXP (op, 1))
     988      2250870 :           && (temp = simplify_unary_operation (NOT, mode,
     989              :                                                XEXP (op, 1), mode)) != 0)
     990         4571 :         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
     991              : 
     992              :       /* (not (plus X C)) for signbit C is (xor X D) with D = ~C.  */
     993      2241728 :       if (GET_CODE (op) == PLUS
     994       244451 :           && CONST_INT_P (XEXP (op, 1))
     995       137307 :           && mode_signbit_p (mode, XEXP (op, 1))
     996      2245548 :           && (temp = simplify_unary_operation (NOT, mode,
     997              :                                                XEXP (op, 1), mode)) != 0)
     998         3820 :         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
     999              : 
    1000              : 
    1001              :       /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for
    1002              :          operands other than 1, but that is not valid.  We could do a
    1003              :          similar simplification for (not (lshiftrt C X)) where C is
    1004              :          just the sign bit, but this doesn't seem common enough to
    1005              :          bother with.  */
    1006      2237908 :       if (GET_CODE (op) == ASHIFT
    1007        31395 :           && XEXP (op, 0) == const1_rtx)
    1008              :         {
    1009         1139 :           temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
    1010         1139 :           return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
    1011              :         }
    1012              : 
    1013              :       /* (not (ashiftrt foo C)) where C is the number of bits in FOO
    1014              :          minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
    1015              :          so we can perform the above simplification.  */
    1016      2236769 :       if (STORE_FLAG_VALUE == -1
    1017              :           && is_a <scalar_int_mode> (mode, &int_mode)
    1018              :           && GET_CODE (op) == ASHIFTRT
    1019              :           && CONST_INT_P (XEXP (op, 1))
    1020              :           && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    1021              :         return simplify_gen_relational (GE, int_mode, VOIDmode,
    1022              :                                         XEXP (op, 0), const0_rtx);
    1023              : 
    1024              : 
    1025      2236769 :       if (partial_subreg_p (op)
    1026       603865 :           && subreg_lowpart_p (op)
    1027       603553 :           && GET_CODE (SUBREG_REG (op)) == ASHIFT
    1028       621547 :           && XEXP (SUBREG_REG (op), 0) == const1_rtx)
    1029              :         {
    1030          163 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
    1031          163 :           rtx x;
    1032              : 
    1033          163 :           x = gen_rtx_ROTATE (inner_mode,
    1034              :                               simplify_gen_unary (NOT, inner_mode, const1_rtx,
    1035              :                                                   inner_mode),
    1036              :                               XEXP (SUBREG_REG (op), 1));
    1037          163 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
    1038          163 :           if (temp)
    1039              :             return temp;
    1040              :         }
    1041              : 
    1042              :       /* Apply De Morgan's laws to reduce number of patterns for machines
    1043              :          with negating logical insns (and-not, nand, etc.).  If result has
    1044              :          only one NOT, put it first, since that is how the patterns are
    1045              :          coded.  */
    1046      2236606 :       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
    1047              :         {
    1048        14084 :           rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
    1049        14084 :           machine_mode op_mode;
    1050              : 
    1051        14084 :           op_mode = GET_MODE (in1);
    1052        14084 :           in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
    1053              : 
    1054        14084 :           op_mode = GET_MODE (in2);
    1055        14084 :           if (op_mode == VOIDmode)
    1056         5426 :             op_mode = mode;
    1057        14084 :           in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
    1058              : 
    1059        14084 :           if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
    1060              :             std::swap (in1, in2);
    1061              : 
    1062        28168 :           return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
    1063              :                                  mode, in1, in2);
    1064              :         }
    1065              : 
    1066              :       /* (not (bswap x)) -> (bswap (not x)).  */
    1067      2222522 :       if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
    1068              :         {
    1069            0 :           rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1070            0 :           return simplify_gen_unary (GET_CODE (op), mode, x, mode);
    1071              :         }
    1072              :       break;
    1073              : 
    1074      1814223 :     case NEG:
    1075              :       /* (neg (neg X)) == X.  */
    1076      1814223 :       if (GET_CODE (op) == NEG)
    1077         6687 :         return XEXP (op, 0);
    1078              : 
    1079              :       /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
    1080              :          If comparison is not reversible use
    1081              :          x ? y : (neg y).  */
    1082      1807536 :       if (GET_CODE (op) == IF_THEN_ELSE)
    1083              :         {
    1084         3332 :           rtx cond = XEXP (op, 0);
    1085         3332 :           rtx true_rtx = XEXP (op, 1);
    1086         3332 :           rtx false_rtx = XEXP (op, 2);
    1087              : 
    1088         3332 :           if ((GET_CODE (true_rtx) == NEG
    1089            0 :                && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
    1090         3332 :                || (GET_CODE (false_rtx) == NEG
    1091            0 :                    && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
    1092              :             {
    1093            0 :               if (reversed_comparison_code (cond, NULL) != UNKNOWN)
    1094            0 :                 temp = reversed_comparison (cond, mode);
    1095              :               else
    1096              :                 {
    1097              :                   temp = cond;
    1098              :                   std::swap (true_rtx, false_rtx);
    1099              :                 }
    1100            0 :               return simplify_gen_ternary (IF_THEN_ELSE, mode,
    1101            0 :                                             mode, temp, true_rtx, false_rtx);
    1102              :             }
    1103              :         }
    1104              : 
    1105              :       /* (neg (plus X 1)) can become (not X).  */
    1106      1807536 :       if (GET_CODE (op) == PLUS
    1107       139913 :           && XEXP (op, 1) == const1_rtx)
    1108        54443 :         return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1109              : 
    1110              :       /* Similarly, (neg (not X)) is (plus X 1).  */
    1111      1753093 :       if (GET_CODE (op) == NOT)
    1112          341 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
    1113          341 :                                     CONST1_RTX (mode));
    1114              : 
    1115              :       /* (neg (minus X Y)) can become (minus Y X).  This transformation
    1116              :          isn't safe for modes with signed zeros, since if X and Y are
    1117              :          both +0, (minus Y X) is the same as (minus X Y).  If the
    1118              :          rounding mode is towards +infinity (or -infinity) then the two
    1119              :          expressions will be rounded differently.  */
    1120      1752752 :       if (GET_CODE (op) == MINUS
    1121        24972 :           && !HONOR_SIGNED_ZEROS (mode)
    1122      1776312 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1123        23560 :         return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
    1124              : 
    1125      1729192 :       if (GET_CODE (op) == PLUS
    1126        85470 :           && !HONOR_SIGNED_ZEROS (mode)
    1127      1814237 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1128              :         {
    1129              :           /* (neg (plus A C)) is simplified to (minus -C A).  */
    1130        85045 :           if (CONST_SCALAR_INT_P (XEXP (op, 1))
    1131         5570 :               || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
    1132              :             {
    1133        79475 :               temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
    1134        79475 :               if (temp)
    1135        79475 :                 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
    1136              :             }
    1137              : 
    1138              :           /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
    1139         5570 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
    1140         5570 :           return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
    1141              :         }
    1142              : 
    1143              :       /* (neg (mult A B)) becomes (mult A (neg B)).
    1144              :          This works even for floating-point values.  */
    1145      1644147 :       if (GET_CODE (op) == MULT
    1146      1644147 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1147              :         {
    1148        27585 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
    1149        27585 :           return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
    1150              :         }
    1151              : 
    1152              :       /* NEG commutes with ASHIFT since it is multiplication.  Only do
    1153              :          this if we can then eliminate the NEG (e.g., if the operand
    1154              :          is a constant).  */
    1155      1616562 :       if (GET_CODE (op) == ASHIFT)
    1156              :         {
    1157        53599 :           temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
    1158        53599 :           if (temp)
    1159        12348 :             return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
    1160              :         }
    1161              : 
    1162              :       /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
    1163              :          C is equal to the width of MODE minus 1.  */
    1164      1604214 :       if (GET_CODE (op) == ASHIFTRT
    1165        29414 :           && CONST_INT_P (XEXP (op, 1))
    1166      1662934 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1167          776 :         return simplify_gen_binary (LSHIFTRT, mode,
    1168          776 :                                     XEXP (op, 0), XEXP (op, 1));
    1169              : 
    1170              :       /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
    1171              :          C is equal to the width of MODE minus 1.  */
    1172      1603438 :       if (GET_CODE (op) == LSHIFTRT
    1173         9155 :           && CONST_INT_P (XEXP (op, 1))
    1174      1621616 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1175         3645 :         return simplify_gen_binary (ASHIFTRT, mode,
    1176         3645 :                                     XEXP (op, 0), XEXP (op, 1));
    1177              : 
    1178              :       /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
    1179      1599793 :       if (GET_CODE (op) == XOR
    1180        10771 :           && XEXP (op, 1) == const1_rtx
    1181      1599868 :           && nonzero_bits (XEXP (op, 0), mode) == 1)
    1182           32 :         return plus_constant (mode, XEXP (op, 0), -1);
    1183              : 
    1184              :       /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1.  */
    1185              :       /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1.  */
    1186      1599761 :       if (GET_CODE (op) == LT
    1187         3135 :           && XEXP (op, 1) == const0_rtx
    1188      1602068 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
    1189              :         {
    1190          489 :           int_mode = as_a <scalar_int_mode> (mode);
    1191          489 :           int isize = GET_MODE_PRECISION (inner);
    1192          489 :           if (STORE_FLAG_VALUE == 1)
    1193              :             {
    1194          489 :               temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
    1195              :                                           gen_int_shift_amount (inner,
    1196          489 :                                                                 isize - 1));
    1197          489 :               if (int_mode == inner)
    1198              :                 return temp;
    1199          260 :               if (GET_MODE_PRECISION (int_mode) > isize)
    1200          187 :                 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
    1201           73 :               return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
    1202              :             }
    1203              :           else if (STORE_FLAG_VALUE == -1)
    1204              :             {
    1205              :               temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
    1206              :                                           gen_int_shift_amount (inner,
    1207              :                                                                 isize - 1));
    1208              :               if (int_mode == inner)
    1209              :                 return temp;
    1210              :               if (GET_MODE_PRECISION (int_mode) > isize)
    1211              :                 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
    1212              :               return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
    1213              :             }
    1214              :         }
    1215              : 
    1216      1599272 :       if (vec_series_p (op, &base, &step))
    1217              :         {
    1218              :           /* Only create a new series if we can simplify both parts.  In other
    1219              :              cases this isn't really a simplification, and it's not necessarily
    1220              :              a win to replace a vector operation with a scalar operation.  */
    1221          276 :           scalar_mode inner_mode = GET_MODE_INNER (mode);
    1222          276 :           base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
    1223          276 :           if (base)
    1224              :             {
    1225          276 :               step = simplify_unary_operation (NEG, inner_mode,
    1226              :                                                step, inner_mode);
    1227          276 :               if (step)
    1228          276 :                 return gen_vec_series (mode, base, step);
    1229              :             }
    1230              :         }
    1231              :       break;
    1232              : 
    1233      2246768 :     case TRUNCATE:
    1234              :       /* Don't optimize (lshiftrt (mult ...)) as it would interfere
    1235              :          with the umulXi3_highpart patterns.  */
    1236      2246768 :       if (GET_CODE (op) == LSHIFTRT
    1237        20190 :           && GET_CODE (XEXP (op, 0)) == MULT)
    1238              :         break;
    1239              : 
    1240      2239617 :       if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
    1241              :         {
    1242           12 :           if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
    1243              :             {
    1244           12 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1245           12 :               if (temp)
    1246              :                 return temp;
    1247              :             }
    1248              :           /* We can't handle truncation to a partial integer mode here
    1249              :              because we don't know the real bitsize of the partial
    1250              :              integer mode.  */
    1251              :           break;
    1252              :         }
    1253              : 
    1254      2239605 :       if (GET_MODE (op) != VOIDmode)
    1255              :         {
    1256      2239605 :           temp = simplify_truncation (mode, op, GET_MODE (op));
    1257      2239605 :           if (temp)
    1258              :             return temp;
    1259              :         }
    1260              : 
    1261              :       /* If we know that the value is already truncated, we can
    1262              :          replace the TRUNCATE with a SUBREG.  */
    1263      1940759 :       if (known_eq (GET_MODE_NUNITS (mode), 1)
    1264      1940759 :           && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
    1265            0 :               || truncated_to_mode (mode, op)))
    1266              :         {
    1267      1928350 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1268      1928350 :           if (temp)
    1269              :             return temp;
    1270              :         }
    1271              : 
    1272              :       /* A truncate of a comparison can be replaced with a subreg if
    1273              :          STORE_FLAG_VALUE permits.  This is like the previous test,
    1274              :          but it works even if the comparison is done in a mode larger
    1275              :          than HOST_BITS_PER_WIDE_INT.  */
    1276        12570 :       if (HWI_COMPUTABLE_MODE_P (mode)
    1277          161 :           && COMPARISON_P (op)
    1278            0 :           && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
    1279        12570 :           && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
    1280              :         {
    1281            0 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1282            0 :           if (temp)
    1283              :             return temp;
    1284              :         }
    1285              : 
    1286              :       /* A truncate of a memory is just loading the low part of the memory
    1287              :          if we are not changing the meaning of the address. */
    1288        12570 :       if (GET_CODE (op) == MEM
    1289          278 :           && !VECTOR_MODE_P (mode)
    1290          159 :           && !MEM_VOLATILE_P (op)
    1291        12723 :           && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
    1292              :         {
    1293          153 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1294          153 :           if (temp)
    1295              :             return temp;
    1296              :         }
    1297              : 
    1298              :       /* Check for useless truncation.  */
    1299        12570 :       if (GET_MODE (op) == mode)
    1300              :         return op;
    1301              :       break;
    1302              : 
    1303       174717 :     case FLOAT_TRUNCATE:
    1304              :       /* Check for useless truncation.  */
    1305       174717 :       if (GET_MODE (op) == mode)
    1306              :         return op;
    1307              : 
    1308       174717 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1309              :         break;
    1310              : 
    1311              :       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
    1312       174563 :       if (GET_CODE (op) == FLOAT_EXTEND
    1313            5 :           && GET_MODE (XEXP (op, 0)) == mode)
    1314              :         return XEXP (op, 0);
    1315              : 
    1316              :       /* (float_truncate:SF (float_truncate:DF foo:XF))
    1317              :          = (float_truncate:SF foo:XF).
    1318              :          This may eliminate double rounding, so it is unsafe.
    1319              : 
    1320              :          (float_truncate:SF (float_extend:XF foo:DF))
    1321              :          = (float_truncate:SF foo:DF).
    1322              : 
    1323              :          (float_truncate:DF (float_extend:XF foo:SF))
    1324              :          = (float_extend:DF foo:SF).  */
    1325       174561 :       if ((GET_CODE (op) == FLOAT_TRUNCATE
    1326          145 :            && flag_unsafe_math_optimizations)
    1327       174557 :           || GET_CODE (op) == FLOAT_EXTEND)
    1328           14 :         return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
    1329            7 :                                    > GET_MODE_UNIT_SIZE (mode)
    1330              :                                    ? FLOAT_TRUNCATE : FLOAT_EXTEND,
    1331              :                                    mode,
    1332           14 :                                    XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1333              : 
    1334              :       /*  (float_truncate (float x)) is (float x)  */
    1335       174554 :       if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1336       174554 :           && (flag_unsafe_math_optimizations
    1337         1410 :               || exact_int_to_float_conversion_p (op)))
    1338         1409 :         return simplify_gen_unary (GET_CODE (op), mode,
    1339              :                                    XEXP (op, 0),
    1340         1409 :                                    GET_MODE (XEXP (op, 0)));
    1341              : 
    1342              :       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
    1343              :          (OP:SF foo:SF) if OP is NEG or ABS.  */
    1344       173145 :       if ((GET_CODE (op) == ABS
    1345       173145 :            || GET_CODE (op) == NEG)
    1346          210 :           && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
    1347           28 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
    1348           28 :         return simplify_gen_unary (GET_CODE (op), mode,
    1349           28 :                                    XEXP (XEXP (op, 0), 0), mode);
    1350              : 
    1351              :       /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
    1352              :          is (float_truncate:SF x).  */
    1353       173117 :       if (GET_CODE (op) == SUBREG
    1354          307 :           && subreg_lowpart_p (op)
    1355       173421 :           && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
    1356              :         return SUBREG_REG (op);
    1357              :       break;
    1358              : 
    1359       602081 :     case FLOAT_EXTEND:
    1360              :       /* Check for useless extension.  */
    1361       602081 :       if (GET_MODE (op) == mode)
    1362              :         return op;
    1363              : 
    1364       602081 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1365              :         break;
    1366              : 
    1367              :       /*  (float_extend (float_extend x)) is (float_extend x)
    1368              : 
    1369              :           (float_extend (float x)) is (float x) assuming that double
    1370              :           rounding can't happen.
    1371              :           */
    1372       601978 :       if (GET_CODE (op) == FLOAT_EXTEND
    1373       601978 :           || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1374         1423 :               && exact_int_to_float_conversion_p (op)))
    1375          557 :         return simplify_gen_unary (GET_CODE (op), mode,
    1376              :                                    XEXP (op, 0),
    1377          557 :                                    GET_MODE (XEXP (op, 0)));
    1378              : 
    1379              :       break;
    1380              : 
    1381       330046 :     case ABS:
    1382              :       /* (abs (neg <foo>)) -> (abs <foo>) */
    1383       330046 :       if (GET_CODE (op) == NEG)
    1384           18 :         return simplify_gen_unary (ABS, mode, XEXP (op, 0),
    1385           18 :                                    GET_MODE (XEXP (op, 0)));
    1386              : 
    1387              :       /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
    1388              :          do nothing.  */
    1389       330028 :       if (GET_MODE (op) == VOIDmode)
    1390              :         break;
    1391              : 
    1392              :       /* If operand is something known to be positive, ignore the ABS.  */
    1393       330028 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1394              :                                      nonzero_bits (op, GET_MODE (op))))
    1395              :         return op;
    1396              : 
    1397              :       /* Using nonzero_bits doesn't (currently) work for modes wider than
    1398              :          HOST_WIDE_INT, so the following transformations help simplify
    1399              :          ABS for TImode and wider.  */
    1400       329822 :       switch (GET_CODE (op))
    1401              :         {
    1402              :         case ABS:
    1403              :         case CLRSB:
    1404              :         case FFS:
    1405              :         case PARITY:
    1406              :         case POPCOUNT:
    1407              :         case SS_ABS:
    1408              :           return op;
    1409              : 
    1410            0 :         case LSHIFTRT:
    1411            0 :           if (CONST_INT_P (XEXP (op, 1))
    1412            0 :               && INTVAL (XEXP (op, 1)) > 0
    1413       329822 :               && is_a <scalar_int_mode> (mode, &int_mode)
    1414            0 :               && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
    1415              :             return op;
    1416              :           break;
    1417              : 
    1418              :         default:
    1419              :           break;
    1420              :         }
    1421              : 
    1422              :       /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
    1423       329822 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    1424        57443 :           && (num_sign_bit_copies (op, int_mode)
    1425        57443 :               == GET_MODE_PRECISION (int_mode)))
    1426           74 :         return gen_rtx_NEG (int_mode, op);
    1427              : 
    1428              :       break;
    1429              : 
    1430            0 :     case FFS:
    1431              :       /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)).  */
    1432            0 :       if (GET_CODE (op) == SIGN_EXTEND
    1433            0 :           || GET_CODE (op) == ZERO_EXTEND)
    1434              :         {
    1435            0 :           temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
    1436            0 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1437            0 :           return simplify_gen_unary (GET_CODE (op), mode, temp,
    1438            0 :                                      GET_MODE (temp));
    1439              :         }
    1440              :       break;
    1441              : 
    1442         3441 :     case POPCOUNT:
    1443         3441 :       switch (GET_CODE (op))
    1444              :         {
    1445            0 :         case BSWAP:
    1446            0 :         case BITREVERSE:
    1447              :           /* (popcount (bswap <X>)) = (popcount <X>).  */
    1448            0 :           return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
    1449            0 :                                      GET_MODE (XEXP (op, 0)));
    1450              : 
    1451           44 :         case ZERO_EXTEND:
    1452              :           /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)).  */
    1453           88 :           temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
    1454           44 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1455           44 :           return simplify_gen_unary (ZERO_EXTEND, mode, temp,
    1456           44 :                                      GET_MODE (temp));
    1457              : 
    1458            0 :         case ROTATE:
    1459            0 :         case ROTATERT:
    1460              :           /* Rotations don't affect popcount.  */
    1461            0 :           if (!side_effects_p (XEXP (op, 1)))
    1462            0 :             return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
    1463            0 :                                        GET_MODE (XEXP (op, 0)));
    1464              :           break;
    1465              : 
    1466              :         default:
    1467              :           break;
    1468              :         }
    1469              :       break;
    1470              : 
    1471            0 :     case PARITY:
    1472            0 :       switch (GET_CODE (op))
    1473              :         {
    1474            0 :         case NOT:
    1475            0 :         case BSWAP:
    1476            0 :         case BITREVERSE:
    1477            0 :           return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
    1478            0 :                                      GET_MODE (XEXP (op, 0)));
    1479              : 
    1480            0 :         case ZERO_EXTEND:
    1481            0 :         case SIGN_EXTEND:
    1482            0 :           temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
    1483            0 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1484            0 :           return simplify_gen_unary (GET_CODE (op), mode, temp,
    1485            0 :                                      GET_MODE (temp));
    1486              : 
    1487            0 :         case ROTATE:
    1488            0 :         case ROTATERT:
    1489              :           /* Rotations don't affect parity.  */
    1490            0 :           if (!side_effects_p (XEXP (op, 1)))
    1491            0 :             return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
    1492            0 :                                        GET_MODE (XEXP (op, 0)));
    1493              :           break;
    1494              : 
    1495              :         case PARITY:
    1496              :           /* (parity (parity x)) -> parity (x).  */
    1497              :           return op;
    1498              : 
    1499              :         default:
    1500              :           break;
    1501              :         }
    1502              :       break;
    1503              : 
    1504        31065 :     case BSWAP:
    1505              :       /* (bswap (bswap x)) -> x.  */
    1506        31065 :       if (GET_CODE (op) == BSWAP)
    1507          184 :         return XEXP (op, 0);
    1508              :       break;
    1509              : 
    1510            0 :     case BITREVERSE:
    1511              :       /* (bitreverse (bitreverse x)) -> x.  */
    1512            0 :       if (GET_CODE (op) == BITREVERSE)
    1513            0 :         return XEXP (op, 0);
    1514              :       break;
    1515              : 
    1516       903794 :     case FLOAT:
    1517              :       /* (float (sign_extend <X>)) = (float <X>).  */
    1518       903794 :       if (GET_CODE (op) == SIGN_EXTEND)
    1519         9658 :         return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
    1520         9658 :                                    GET_MODE (XEXP (op, 0)));
    1521              :       break;
    1522              : 
    1523      3107610 :     case SIGN_EXTEND:
    1524              :       /* Check for useless extension.  */
    1525      3107610 :       if (GET_MODE (op) == mode)
    1526              :         return op;
    1527              : 
    1528              :       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
    1529              :          becomes just the MINUS if its mode is MODE.  This allows
    1530              :          folding switch statements on machines using casesi (such as
    1531              :          the VAX).  */
    1532      3107570 :       if (GET_CODE (op) == TRUNCATE
    1533           62 :           && GET_MODE (XEXP (op, 0)) == mode
    1534           62 :           && GET_CODE (XEXP (op, 0)) == MINUS
    1535            0 :           && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
    1536            0 :           && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
    1537              :         return XEXP (op, 0);
    1538              : 
    1539              :       /* Extending a widening multiplication should be canonicalized to
    1540              :          a wider widening multiplication.  */
    1541      3107570 :       if (GET_CODE (op) == MULT)
    1542              :         {
    1543        67503 :           rtx lhs = XEXP (op, 0);
    1544        67503 :           rtx rhs = XEXP (op, 1);
    1545        67503 :           enum rtx_code lcode = GET_CODE (lhs);
    1546        67503 :           enum rtx_code rcode = GET_CODE (rhs);
    1547              : 
    1548              :           /* Widening multiplies usually extend both operands, but sometimes
    1549              :              they use a shift to extract a portion of a register.  */
    1550        67503 :           if ((lcode == SIGN_EXTEND
    1551        67374 :                || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1552          888 :               && (rcode == SIGN_EXTEND
    1553          868 :                   || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1554              :             {
    1555          105 :               machine_mode lmode = GET_MODE (lhs);
    1556          105 :               machine_mode rmode = GET_MODE (rhs);
    1557          105 :               int bits;
    1558              : 
    1559          105 :               if (lcode == ASHIFTRT)
    1560              :                 /* Number of bits not shifted off the end.  */
    1561           89 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1562           89 :                         - INTVAL (XEXP (lhs, 1)));
    1563              :               else /* lcode == SIGN_EXTEND */
    1564              :                 /* Size of inner mode.  */
    1565           32 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1566              : 
    1567          105 :               if (rcode == ASHIFTRT)
    1568           85 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1569           85 :                          - INTVAL (XEXP (rhs, 1)));
    1570              :               else /* rcode == SIGN_EXTEND */
    1571           40 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1572              : 
    1573              :               /* We can only widen multiplies if the result is mathematiclly
    1574              :                  equivalent.  I.e. if overflow was impossible.  */
    1575          210 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1576           48 :                 return simplify_gen_binary
    1577           48 :                          (MULT, mode,
    1578              :                           simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
    1579           48 :                           simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
    1580              :             }
    1581              :         }
    1582              : 
    1583              :       /* Check for a sign extension of a subreg of a promoted
    1584              :          variable, where the promotion is sign-extended, and the
    1585              :          target mode is the same as the variable's promotion.  */
    1586      3107522 :       if (GET_CODE (op) == SUBREG
    1587       215754 :           && SUBREG_PROMOTED_VAR_P (op)
    1588      3113670 :           && SUBREG_PROMOTED_SIGNED_P (op))
    1589              :         {
    1590            0 :           rtx subreg = SUBREG_REG (op);
    1591            0 :           machine_mode subreg_mode = GET_MODE (subreg);
    1592            0 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1593              :             {
    1594            0 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1595            0 :               if (temp)
    1596              :                 {
    1597              :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1598            0 :                   if (partial_subreg_p (temp))
    1599              :                     {
    1600            0 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1601            0 :                       SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
    1602              :                     }
    1603              :                   return temp;
    1604              :                 }
    1605              :             }
    1606              :           else
    1607              :             /* Sign-extending a sign-extended subreg.  */
    1608            0 :             return simplify_gen_unary (SIGN_EXTEND, mode,
    1609            0 :                                        subreg, subreg_mode);
    1610              :         }
    1611              : 
    1612              :       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
    1613              :          (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1614      3107522 :       if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
    1615              :         {
    1616        20025 :           gcc_assert (GET_MODE_UNIT_PRECISION (mode)
    1617              :                       > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
    1618         6675 :           return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
    1619         6675 :                                      GET_MODE (XEXP (op, 0)));
    1620              :         }
    1621              : 
    1622              :       /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1623              :          is (sign_extend:M (subreg:O <X>)) if there is mode with
    1624              :          GET_MODE_BITSIZE (N) - I bits.
    1625              :          (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1626              :          is similarly (zero_extend:M (subreg:O <X>)).  */
    1627      3100847 :       if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
    1628        89739 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1629      3103464 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1630         5221 :           && CONST_INT_P (XEXP (op, 1))
    1631         5221 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1632      3105939 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1633         5092 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1634              :         {
    1635         5092 :           scalar_int_mode tmode;
    1636         5092 :           gcc_assert (GET_MODE_PRECISION (int_mode)
    1637              :                       > GET_MODE_PRECISION (op_mode));
    1638         5092 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1639         7580 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1640              :             {
    1641         2604 :               rtx inner =
    1642         2604 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1643         2604 :               if (inner)
    1644         2604 :                 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
    1645              :                                            ? SIGN_EXTEND : ZERO_EXTEND,
    1646         2604 :                                            int_mode, inner, tmode);
    1647              :             }
    1648              :         }
    1649              : 
    1650              :       /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
    1651              :          (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0.  */
    1652      3098243 :       if (GET_CODE (op) == LSHIFTRT
    1653          181 :           && CONST_INT_P (XEXP (op, 1))
    1654          181 :           && XEXP (op, 1) != const0_rtx)
    1655          181 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1656              : 
    1657              :       /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
    1658              :          I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
    1659              :          (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
    1660              :          (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
    1661              :          O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
    1662              :          wider than O.  */
    1663      3098062 :       if (GET_CODE (op) == TRUNCATE
    1664           62 :           && GET_CODE (XEXP (op, 0)) == LSHIFTRT
    1665            0 :           && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
    1666              :         {
    1667            0 :           scalar_int_mode m_mode, n_mode, o_mode;
    1668            0 :           rtx old_shift = XEXP (op, 0);
    1669            0 :           if (is_a <scalar_int_mode> (mode, &m_mode)
    1670            0 :               && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
    1671            0 :               && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
    1672            0 :               && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
    1673            0 :                  == INTVAL (XEXP (old_shift, 1)))
    1674              :             {
    1675            0 :               rtx new_shift = simplify_gen_binary (ASHIFTRT,
    1676              :                                                    GET_MODE (old_shift),
    1677              :                                                    XEXP (old_shift, 0),
    1678              :                                                    XEXP (old_shift, 1));
    1679            0 :               if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
    1680            0 :                 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
    1681            0 :                                            GET_MODE (new_shift));
    1682            0 :               if (mode != GET_MODE (new_shift))
    1683            0 :                 return simplify_gen_unary (TRUNCATE, mode, new_shift,
    1684            0 :                                            GET_MODE (new_shift));
    1685              :               return new_shift;
    1686              :             }
    1687              :         }
    1688              : 
    1689              :       /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
    1690              :          we know the sign bit of OP must be clear.  */
    1691      3098062 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1692      3098062 :                                      nonzero_bits (op, GET_MODE (op))))
    1693        39736 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1694              : 
    1695              :       /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1696      3058326 :       if (GET_CODE (op) == SUBREG
    1697       215469 :           && subreg_lowpart_p (op)
    1698       215357 :           && GET_MODE (SUBREG_REG (op)) == mode
    1699      3242504 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1700       190956 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1701       190956 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1702       189149 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1703      3247475 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1704       189149 :               & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
    1705         6778 :         return SUBREG_REG (op);
    1706              : 
    1707              : #if defined(POINTERS_EXTEND_UNSIGNED)
    1708              :       /* As we do not know which address space the pointer is referring to,
    1709              :          we can do this only if the target does not support different pointer
    1710              :          or address modes depending on the address space.  */
    1711      3051548 :       if (target_default_pointer_address_modes_p ()
    1712              :           && ! POINTERS_EXTEND_UNSIGNED
    1713              :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1714              :           && (CONSTANT_P (op)
    1715              :               || (GET_CODE (op) == SUBREG
    1716              :                   && REG_P (SUBREG_REG (op))
    1717              :                   && REG_POINTER (SUBREG_REG (op))
    1718              :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1719              :           && !targetm.have_ptr_extend ())
    1720              :         {
    1721              :           temp
    1722              :             = convert_memory_address_addr_space_1 (Pmode, op,
    1723              :                                                    ADDR_SPACE_GENERIC, false,
    1724              :                                                    true);
    1725              :           if (temp)
    1726              :             return temp;
    1727              :         }
    1728              : #endif
    1729              :       break;
    1730              : 
    1731     11601053 :     case ZERO_EXTEND:
    1732              :       /* Check for useless extension.  */
    1733     11601053 :       if (GET_MODE (op) == mode)
    1734              :         return op;
    1735              : 
    1736              :       /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
    1737              :          where const does not sign bit set. */
    1738     11601011 :       if (GET_CODE (op) == AND
    1739       118322 :           && CONST_INT_P (XEXP (op, 1))
    1740        91796 :           && INTVAL (XEXP (op, 1)) > 0)
    1741              :         {
    1742        84487 :           rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
    1743        84487 :           if (tem)
    1744        68264 :             return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
    1745              :         }
    1746              : 
    1747              :       /* Check for a zero extension of a subreg of a promoted
    1748              :          variable, where the promotion is zero-extended, and the
    1749              :          target mode is the same as the variable's promotion.  */
    1750     11532747 :       if (GET_CODE (op) == SUBREG
    1751      1674996 :           && SUBREG_PROMOTED_VAR_P (op)
    1752     11533253 :           && SUBREG_PROMOTED_UNSIGNED_P (op))
    1753              :         {
    1754          506 :           rtx subreg = SUBREG_REG (op);
    1755          506 :           machine_mode subreg_mode = GET_MODE (subreg);
    1756          506 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1757              :             {
    1758          320 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1759          320 :               if (temp)
    1760              :                 {
    1761              :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1762          320 :                   if (partial_subreg_p (temp))
    1763              :                     {
    1764          129 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1765          129 :                       SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
    1766              :                     }
    1767              :                   return temp;
    1768              :                 }
    1769              :             }
    1770              :           else
    1771              :             /* Zero-extending a zero-extended subreg.  */
    1772          186 :             return simplify_gen_unary (ZERO_EXTEND, mode,
    1773          186 :                                        subreg, subreg_mode);
    1774              :         }
    1775              : 
    1776              :       /* Extending a widening multiplication should be canonicalized to
    1777              :          a wider widening multiplication.  */
    1778     11532241 :       if (GET_CODE (op) == MULT)
    1779              :         {
    1780       183940 :           rtx lhs = XEXP (op, 0);
    1781       183940 :           rtx rhs = XEXP (op, 1);
    1782       183940 :           enum rtx_code lcode = GET_CODE (lhs);
    1783       183940 :           enum rtx_code rcode = GET_CODE (rhs);
    1784              : 
    1785              :           /* Widening multiplies usually extend both operands, but sometimes
    1786              :              they use a shift to extract a portion of a register.  */
    1787       183940 :           if ((lcode == ZERO_EXTEND
    1788       183316 :                || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1789          822 :               && (rcode == ZERO_EXTEND
    1790          772 :                   || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1791              :             {
    1792           62 :               machine_mode lmode = GET_MODE (lhs);
    1793           62 :               machine_mode rmode = GET_MODE (rhs);
    1794           62 :               int bits;
    1795              : 
    1796           62 :               if (lcode == LSHIFTRT)
    1797              :                 /* Number of bits not shifted off the end.  */
    1798           12 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1799           12 :                         - INTVAL (XEXP (lhs, 1)));
    1800              :               else /* lcode == ZERO_EXTEND */
    1801              :                 /* Size of inner mode.  */
    1802          100 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1803              : 
    1804           62 :               if (rcode == LSHIFTRT)
    1805           12 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1806           12 :                          - INTVAL (XEXP (rhs, 1)));
    1807              :               else /* rcode == ZERO_EXTEND */
    1808          100 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1809              : 
    1810              :               /* We can only widen multiplies if the result is mathematiclly
    1811              :                  equivalent.  I.e. if overflow was impossible.  */
    1812          124 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1813           50 :                 return simplify_gen_binary
    1814           50 :                          (MULT, mode,
    1815              :                           simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
    1816           50 :                           simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
    1817              :             }
    1818              :         }
    1819              : 
    1820              :       /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1821     11532191 :       if (GET_CODE (op) == ZERO_EXTEND)
    1822        21664 :         return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
    1823        21664 :                                    GET_MODE (XEXP (op, 0)));
    1824              : 
    1825              :       /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1826              :          is (zero_extend:M (subreg:O <X>)) if there is mode with
    1827              :          GET_MODE_PRECISION (N) - I bits.  */
    1828     11510527 :       if (GET_CODE (op) == LSHIFTRT
    1829        71796 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1830     11510550 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1831           23 :           && CONST_INT_P (XEXP (op, 1))
    1832           18 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1833     11510527 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1834            0 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1835              :         {
    1836            0 :           scalar_int_mode tmode;
    1837            0 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1838            0 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1839              :             {
    1840            0 :               rtx inner =
    1841            0 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1842            0 :               if (inner)
    1843            0 :                 return simplify_gen_unary (ZERO_EXTEND, int_mode,
    1844            0 :                                            inner, tmode);
    1845              :             }
    1846              :         }
    1847              : 
    1848              :       /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
    1849              :          (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
    1850              :          of mode N.  E.g.
    1851              :          (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
    1852              :          (and:SI (reg:SI) (const_int 63)).  */
    1853     11510527 :       if (partial_subreg_p (op)
    1854     13109750 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1855      1621583 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
    1856      1621177 :           && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
    1857      1296776 :           && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
    1858      1274926 :           && subreg_lowpart_p (op)
    1859      2502471 :           && (nonzero_bits (SUBREG_REG (op), op0_mode)
    1860       827981 :               & ~GET_MODE_MASK (GET_MODE (op))) == 0)
    1861              :         {
    1862        22360 :           if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
    1863        14863 :             return SUBREG_REG (op);
    1864         7497 :           return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
    1865         7497 :                                      op0_mode);
    1866              :         }
    1867              : 
    1868              :       /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1869     11488167 :       if (GET_CODE (op) == SUBREG
    1870      1652130 :           && subreg_lowpart_p (op)
    1871       945309 :           && GET_MODE (SUBREG_REG (op)) == mode
    1872     12293136 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1873       804969 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1874       804969 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1875       741493 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1876     12229660 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1877       741493 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1878            0 :         return SUBREG_REG (op);
    1879              : 
    1880              :       /* Trying to optimize:
    1881              :          (zero_extend:M (subreg:N (not:M (X:M)))) ->
    1882              :          (xor:M (zero_extend:M (subreg:N (X:M)), mask))
    1883              :          where the mask is GET_MODE_MASK (N).
    1884              :          For the cases when X:M doesn't have any non-zero bits
    1885              :          outside of mode N, (zero_extend:M (subreg:N (X:M))
    1886              :          will be simplified to just (X:M)
    1887              :          and whole optimization will be -> (xor:M (X:M, mask)).  */
    1888     11488167 :       if (partial_subreg_p (op)
    1889      1599223 :           && GET_CODE (XEXP (op, 0)) == NOT
    1890         1436 :           && GET_MODE (XEXP (op, 0)) == mode
    1891         1418 :           && subreg_lowpart_p (op)
    1892     11488533 :           && HWI_COMPUTABLE_MODE_P (mode)
    1893          370 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1894      1652500 :           && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
    1895          370 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1896              :       {
    1897            4 :         unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
    1898            8 :         return simplify_gen_binary (XOR, mode,
    1899            4 :                                     XEXP (XEXP (op, 0), 0),
    1900            4 :                                     gen_int_mode (mask, mode));
    1901              :       }
    1902              : 
    1903              : #if defined(POINTERS_EXTEND_UNSIGNED)
    1904              :       /* As we do not know which address space the pointer is referring to,
    1905              :          we can do this only if the target does not support different pointer
    1906              :          or address modes depending on the address space.  */
    1907     11488163 :       if (target_default_pointer_address_modes_p ()
    1908              :           && POINTERS_EXTEND_UNSIGNED > 0
    1909     13104458 :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1910          673 :           && (CONSTANT_P (op)
    1911          652 :               || (GET_CODE (op) == SUBREG
    1912            0 :                   && REG_P (SUBREG_REG (op))
    1913            0 :                   && REG_POINTER (SUBREG_REG (op))
    1914            0 :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1915     11488184 :           && !targetm.have_ptr_extend ())
    1916              :         {
    1917           21 :           temp
    1918           21 :             = convert_memory_address_addr_space_1 (Pmode, op,
    1919              :                                                    ADDR_SPACE_GENERIC, false,
    1920              :                                                    true);
    1921           21 :           if (temp)
    1922              :             return temp;
    1923              :         }
    1924              : #endif
    1925              :       break;
    1926              : 
    1927       806352 :     case VEC_DUPLICATE:
    1928       806352 :       if (GET_CODE (op) == VEC_DUPLICATE)
    1929            2 :         return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
    1930            2 :                                    GET_MODE (XEXP (op, 0)));
    1931              :       break;
    1932              : 
    1933              :     default:
    1934              :       break;
    1935              :     }
    1936              : 
    1937     19740523 :   if (VECTOR_MODE_P (mode)
    1938      1856563 :       && vec_duplicate_p (op, &elt)
    1939     21603038 :       && code != VEC_DUPLICATE)
    1940              :     {
    1941         5952 :       if (code == SIGN_EXTEND || code == ZERO_EXTEND)
    1942              :         /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
    1943              :            operations by promoting VEC_DUPLICATE to the root of the expression
    1944              :            (as far as possible).  */
    1945         4896 :         temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
    1946         9792 :                                    elt, GET_MODE_INNER (GET_MODE (op)));
    1947              :       else
    1948              :         /* Try applying the operator to ELT and see if that simplifies.
    1949              :            We can duplicate the result if so.
    1950              : 
    1951              :            The reason we traditionally haven't used simplify_gen_unary
    1952              :            for these codes is that it didn't necessarily seem to be a
    1953              :            win to convert things like:
    1954              : 
    1955              :              (neg:V (vec_duplicate:V (reg:S R)))
    1956              : 
    1957              :            to:
    1958              : 
    1959              :              (vec_duplicate:V (neg:S (reg:S R)))
    1960              : 
    1961              :            The first might be done entirely in vector registers while the
    1962              :            second might need a move between register files.
    1963              : 
    1964              :            However, there also cases where promoting the vec_duplicate is
    1965              :            more efficient, and there is definite value in having a canonical
    1966              :            form when matching instruction patterns.  We should consider
    1967              :            extending the simplify_gen_unary code above to more cases.  */
    1968         1056 :         temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
    1969         2112 :                                          elt, GET_MODE_INNER (GET_MODE (op)));
    1970         5952 :       if (temp)
    1971         5476 :         return gen_vec_duplicate (mode, temp);
    1972              :     }
    1973              : 
    1974              :   return 0;
    1975              : }
    1976              : 
    1977              : /* Try to compute the value of a unary operation CODE whose output mode is to
    1978              :    be MODE with input operand OP whose mode was originally OP_MODE.
    1979              :    Return zero if the value cannot be computed.  */
    1980              : rtx
    1981     29748248 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
    1982              :                                 rtx op, machine_mode op_mode)
    1983              : {
    1984     29748248 :   scalar_int_mode result_mode;
    1985              : 
    1986     29748248 :   if (code == VEC_DUPLICATE)
    1987              :     {
    1988      1951803 :       gcc_assert (VECTOR_MODE_P (mode));
    1989      1951803 :       if (GET_MODE (op) != VOIDmode)
    1990              :       {
    1991       847011 :         if (!VECTOR_MODE_P (GET_MODE (op)))
    1992      1680642 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
    1993              :         else
    1994        20070 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
    1995              :                                                 (GET_MODE (op)));
    1996              :       }
    1997      1951803 :       if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
    1998      1144695 :         return gen_const_vec_duplicate (mode, op);
    1999       807108 :       if (GET_CODE (op) == CONST_VECTOR
    2000       807108 :           && (CONST_VECTOR_DUPLICATE_P (op)
    2001          756 :               || CONST_VECTOR_NUNITS (op).is_constant ()))
    2002              :         {
    2003          756 :           unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
    2004          756 :                                     ? CONST_VECTOR_NPATTERNS (op)
    2005         1510 :                                     : CONST_VECTOR_NUNITS (op).to_constant ());
    2006         2268 :           gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
    2007          756 :           rtx_vector_builder builder (mode, npatterns, 1);
    2008         3888 :           for (unsigned i = 0; i < npatterns; i++)
    2009         2376 :             builder.quick_push (CONST_VECTOR_ELT (op, i));
    2010          756 :           return builder.build ();
    2011          756 :         }
    2012              :     }
    2013              : 
    2014     27095864 :   if (VECTOR_MODE_P (mode)
    2015      1904949 :       && GET_CODE (op) == CONST_VECTOR
    2016     28706570 :       && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
    2017              :     {
    2018        34591 :       gcc_assert (GET_MODE (op) == op_mode);
    2019              : 
    2020        34591 :       rtx_vector_builder builder;
    2021        34591 :       if (!builder.new_unary_operation (mode, op, false))
    2022              :         return 0;
    2023              : 
    2024        34591 :       unsigned int count = builder.encoded_nelts ();
    2025       153777 :       for (unsigned int i = 0; i < count; i++)
    2026              :         {
    2027       239410 :           rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
    2028              :                                             CONST_VECTOR_ELT (op, i),
    2029       239410 :                                             GET_MODE_INNER (op_mode));
    2030       119705 :           if (!x || !valid_for_const_vector_p (mode, x))
    2031          519 :             return 0;
    2032       119186 :           builder.quick_push (x);
    2033              :         }
    2034        34072 :       return builder.build ();
    2035        34591 :     }
    2036              : 
    2037              :   /* The order of these tests is critical so that, for example, we don't
    2038              :      check the wrong mode (input vs. output) for a conversion operation,
    2039              :      such as FIX.  At some point, this should be simplified.  */
    2040              : 
    2041     28568206 :   if (code == FLOAT && CONST_SCALAR_INT_P (op))
    2042              :     {
    2043         7872 :       REAL_VALUE_TYPE d;
    2044              : 
    2045         7872 :       if (op_mode == VOIDmode)
    2046              :         {
    2047              :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2048              :              the bits of the constant are significant, though, this is
    2049              :              a dangerous assumption as many times CONST_INTs are
    2050              :              created and used with garbage in the bits outside of the
    2051              :              precision of the implied mode of the const_int.  */
    2052           64 :           op_mode = MAX_MODE_INT;
    2053              :         }
    2054              : 
    2055         7872 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
    2056              : 
    2057              :       /* Avoid the folding if flag_signaling_nans is on and
    2058              :          operand is a signaling NaN.  */
    2059         7872 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2060              :         return 0;
    2061              : 
    2062         7872 :       d = real_value_truncate (mode, d);
    2063              : 
    2064              :       /* Avoid the folding if flag_rounding_math is on and the
    2065              :          conversion is not exact.  */
    2066         7872 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2067              :         {
    2068         1011 :           bool fail = false;
    2069         1011 :           wide_int w = real_to_integer (&d, &fail,
    2070              :                                         GET_MODE_PRECISION
    2071         1011 :                                           (as_a <scalar_int_mode> (op_mode)));
    2072         2022 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2073          905 :             return 0;
    2074         1011 :         }
    2075              : 
    2076         6967 :       return const_double_from_real_value (d, mode);
    2077              :     }
    2078     28560334 :   else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
    2079              :     {
    2080         2134 :       REAL_VALUE_TYPE d;
    2081              : 
    2082         2134 :       if (op_mode == VOIDmode)
    2083              :         {
    2084              :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2085              :              the bits of the constant are significant, though, this is
    2086              :              a dangerous assumption as many times CONST_INTs are
    2087              :              created and used with garbage in the bits outside of the
    2088              :              precision of the implied mode of the const_int.  */
    2089            8 :           op_mode = MAX_MODE_INT;
    2090              :         }
    2091              : 
    2092         2134 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
    2093              : 
    2094              :       /* Avoid the folding if flag_signaling_nans is on and
    2095              :          operand is a signaling NaN.  */
    2096         2134 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2097              :         return 0;
    2098              : 
    2099         2134 :       d = real_value_truncate (mode, d);
    2100              : 
    2101              :       /* Avoid the folding if flag_rounding_math is on and the
    2102              :          conversion is not exact.  */
    2103         2134 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2104              :         {
    2105           16 :           bool fail = false;
    2106           16 :           wide_int w = real_to_integer (&d, &fail,
    2107              :                                         GET_MODE_PRECISION
    2108           16 :                                           (as_a <scalar_int_mode> (op_mode)));
    2109           28 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2110           16 :             return 0;
    2111           16 :         }
    2112              : 
    2113         2118 :       return const_double_from_real_value (d, mode);
    2114              :     }
    2115              : 
    2116     28558200 :   if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
    2117              :     {
    2118      3819198 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2119      3819198 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2120              :         return 0;
    2121              : 
    2122      3819198 :       wide_int result;
    2123      3819198 :       scalar_int_mode imode = (op_mode == VOIDmode
    2124      3819198 :                                ? result_mode
    2125      3818982 :                                : as_a <scalar_int_mode> (op_mode));
    2126      3819198 :       rtx_mode_t op0 = rtx_mode_t (op, imode);
    2127      3819198 :       int int_value;
    2128              : 
    2129              : #if TARGET_SUPPORTS_WIDE_INT == 0
    2130              :       /* This assert keeps the simplification from producing a result
    2131              :          that cannot be represented in a CONST_DOUBLE but a lot of
    2132              :          upstream callers expect that this function never fails to
    2133              :          simplify something and so you if you added this to the test
    2134              :          above the code would die later anyway.  If this assert
    2135              :          happens, you just need to make the port support wide int.  */
    2136              :       gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
    2137              : #endif
    2138              : 
    2139      3819198 :       switch (code)
    2140              :         {
    2141       176554 :         case NOT:
    2142       176554 :           result = wi::bit_not (op0);
    2143       176554 :           break;
    2144              : 
    2145      1865337 :         case NEG:
    2146      1865337 :           result = wi::neg (op0);
    2147      1865337 :           break;
    2148              : 
    2149         7087 :         case ABS:
    2150         7087 :           result = wi::abs (op0);
    2151         7087 :           break;
    2152              : 
    2153            0 :         case FFS:
    2154            0 :           result = wi::shwi (wi::ffs (op0), result_mode);
    2155            0 :           break;
    2156              : 
    2157          168 :         case CLZ:
    2158          168 :           if (wi::ne_p (op0, 0))
    2159           38 :             int_value = wi::clz (op0);
    2160          260 :           else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2161              :             return NULL_RTX;
    2162           38 :           result = wi::shwi (int_value, result_mode);
    2163           38 :           break;
    2164              : 
    2165            0 :         case CLRSB:
    2166            0 :           result = wi::shwi (wi::clrsb (op0), result_mode);
    2167            0 :           break;
    2168              : 
    2169            0 :         case CTZ:
    2170            0 :           if (wi::ne_p (op0, 0))
    2171            0 :             int_value = wi::ctz (op0);
    2172            0 :           else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2173              :             return NULL_RTX;
    2174            0 :           result = wi::shwi (int_value, result_mode);
    2175            0 :           break;
    2176              : 
    2177          160 :         case POPCOUNT:
    2178          160 :           result = wi::shwi (wi::popcount (op0), result_mode);
    2179          160 :           break;
    2180              : 
    2181            0 :         case PARITY:
    2182            0 :           result = wi::shwi (wi::parity (op0), result_mode);
    2183            0 :           break;
    2184              : 
    2185         1761 :         case BSWAP:
    2186         1761 :           result = wi::bswap (op0);
    2187         1761 :           break;
    2188              : 
    2189            0 :         case BITREVERSE:
    2190            0 :           result = wi::bitreverse (op0);
    2191            0 :           break;
    2192              : 
    2193      1588879 :         case TRUNCATE:
    2194      1588879 :         case ZERO_EXTEND:
    2195      1588879 :           result = wide_int::from (op0, width, UNSIGNED);
    2196      1588879 :           break;
    2197              : 
    2198        14478 :         case US_TRUNCATE:
    2199        14478 :         case SS_TRUNCATE:
    2200        14478 :           {
    2201        14478 :             signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
    2202        14478 :             wide_int nmax
    2203        14478 :               = wide_int::from (wi::max_value (width, sgn),
    2204        28956 :                                 GET_MODE_PRECISION (imode), sgn);
    2205        14478 :             wide_int nmin
    2206        14478 :               = wide_int::from (wi::min_value (width, sgn),
    2207        28956 :                                 GET_MODE_PRECISION (imode), sgn);
    2208        14478 :             result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
    2209        14478 :             result = wide_int::from (result, width, sgn);
    2210        14478 :             break;
    2211        14478 :           }
    2212       164774 :         case SIGN_EXTEND:
    2213       164774 :           result = wide_int::from (op0, width, SIGNED);
    2214       164774 :           break;
    2215              : 
    2216            0 :         case SS_NEG:
    2217            0 :           if (wi::only_sign_bit_p (op0))
    2218            0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2219              :           else
    2220            0 :             result = wi::neg (op0);
    2221              :           break;
    2222              : 
    2223            0 :         case SS_ABS:
    2224            0 :           if (wi::only_sign_bit_p (op0))
    2225            0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2226              :           else
    2227            0 :             result = wi::abs (op0);
    2228              :           break;
    2229              : 
    2230              :         case SQRT:
    2231              :         default:
    2232              :           return 0;
    2233              :         }
    2234              : 
    2235      3819068 :       return immed_wide_int_const (result, result_mode);
    2236      3819198 :     }
    2237              : 
    2238     24739002 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2239       414971 :            && SCALAR_FLOAT_MODE_P (mode)
    2240       412923 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
    2241              :     {
    2242       412923 :       REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
    2243       412923 :       switch (code)
    2244              :         {
    2245              :         case SQRT:
    2246              :           return 0;
    2247          544 :         case ABS:
    2248          544 :           d = real_value_abs (&d);
    2249          544 :           break;
    2250        15749 :         case NEG:
    2251        15749 :           d = real_value_negate (&d);
    2252        15749 :           break;
    2253         2284 :         case FLOAT_TRUNCATE:
    2254              :           /* Don't perform the operation if flag_signaling_nans is on
    2255              :              and the operand is a signaling NaN.  */
    2256         2284 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2257              :             return NULL_RTX;
    2258              :           /* Or if flag_rounding_math is on and the truncation is not
    2259              :              exact.  */
    2260         2284 :           if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    2261         2284 :               && !exact_real_truncate (mode, &d))
    2262          231 :             return NULL_RTX;
    2263         2053 :           d = real_value_truncate (mode, d);
    2264         2053 :           break;
    2265       387806 :         case FLOAT_EXTEND:
    2266              :           /* Don't perform the operation if flag_signaling_nans is on
    2267              :              and the operand is a signaling NaN.  */
    2268       387806 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2269              :             return NULL_RTX;
    2270              :           /* All this does is change the mode, unless changing
    2271              :              mode class.  */
    2272       387804 :           if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
    2273            0 :             real_convert (&d, mode, &d);
    2274              :           break;
    2275            0 :         case FIX:
    2276              :           /* Don't perform the operation if flag_signaling_nans is on
    2277              :              and the operand is a signaling NaN.  */
    2278            0 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2279              :             return NULL_RTX;
    2280            0 :           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
    2281            0 :           break;
    2282         5931 :         case NOT:
    2283         5931 :           {
    2284         5931 :             long tmp[4];
    2285         5931 :             int i;
    2286              : 
    2287         5931 :             real_to_target (tmp, &d, GET_MODE (op));
    2288        29655 :             for (i = 0; i < 4; i++)
    2289        23724 :               tmp[i] = ~tmp[i];
    2290         5931 :             real_from_target (&d, tmp, mode);
    2291         5931 :             break;
    2292              :           }
    2293            0 :         default:
    2294            0 :           gcc_unreachable ();
    2295              :         }
    2296       412081 :       return const_double_from_real_value (d, mode);
    2297              :     }
    2298         2048 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2299         2048 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op))
    2300     24328127 :            && is_int_mode (mode, &result_mode))
    2301              :     {
    2302         2048 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2303         2048 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2304              :         return 0;
    2305              : 
    2306              :       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
    2307              :          operators are intentionally left unspecified (to ease implementation
    2308              :          by target backends), for consistency, this routine implements the
    2309              :          same semantics for constant folding as used by the middle-end.  */
    2310              : 
    2311              :       /* This was formerly used only for non-IEEE float.
    2312              :          eggert@twinsun.com says it is safe for IEEE also.  */
    2313         2048 :       REAL_VALUE_TYPE t;
    2314         2048 :       const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
    2315         2048 :       wide_int wmax, wmin;
    2316              :       /* This is part of the abi to real_to_integer, but we check
    2317              :          things before making this call.  */
    2318         2048 :       bool fail;
    2319              : 
    2320         2048 :       switch (code)
    2321              :         {
    2322         2040 :         case FIX:
    2323              :           /* According to IEEE standard, for conversions from floating point to
    2324              :              integer. When a NaN or infinite operand cannot be represented in
    2325              :              the destination format and this cannot otherwise be indicated, the
    2326              :              invalid operation exception shall be signaled. When a numeric
    2327              :              operand would convert to an integer outside the range of the
    2328              :              destination format, the invalid operation exception shall be
    2329              :              signaled if this situation cannot otherwise be indicated.  */
    2330         2040 :           if (REAL_VALUE_ISNAN (*x))
    2331          955 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2332              : 
    2333         1085 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2334              :             return NULL_RTX;
    2335              : 
    2336              :           /* Test against the signed upper bound.  */
    2337          125 :           wmax = wi::max_value (width, SIGNED);
    2338          125 :           real_from_integer (&t, VOIDmode, wmax, SIGNED);
    2339          125 :           if (real_less (&t, x))
    2340            3 :             return (flag_trapping_math
    2341            3 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2342              : 
    2343              :           /* Test against the signed lower bound.  */
    2344          122 :           wmin = wi::min_value (width, SIGNED);
    2345          122 :           real_from_integer (&t, VOIDmode, wmin, SIGNED);
    2346          122 :           if (real_less (x, &t))
    2347            8 :             return immed_wide_int_const (wmin, mode);
    2348              : 
    2349          114 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2350              :                                        mode);
    2351              : 
    2352            8 :         case UNSIGNED_FIX:
    2353            8 :           if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
    2354            6 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2355              : 
    2356            2 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2357              :             return NULL_RTX;
    2358              : 
    2359              :           /* Test against the unsigned upper bound.  */
    2360            0 :           wmax = wi::max_value (width, UNSIGNED);
    2361            0 :           real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
    2362            0 :           if (real_less (&t, x))
    2363            0 :             return (flag_trapping_math
    2364            0 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2365              : 
    2366            0 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2367              :                                        mode);
    2368              : 
    2369            0 :         default:
    2370            0 :           gcc_unreachable ();
    2371              :         }
    2372         2048 :     }
    2373              : 
    2374              :   /* Handle polynomial integers.  */
    2375              :   else if (CONST_POLY_INT_P (op))
    2376              :     {
    2377              :       poly_wide_int result;
    2378              :       switch (code)
    2379              :         {
    2380              :         case NEG:
    2381              :           result = -const_poly_int_value (op);
    2382              :           break;
    2383              : 
    2384              :         case NOT:
    2385              :           result = ~const_poly_int_value (op);
    2386              :           break;
    2387              : 
    2388              :         default:
    2389              :           return NULL_RTX;
    2390              :         }
    2391              :       return immed_wide_int_const (result, mode);
    2392              :     }
    2393              : 
    2394              :   return NULL_RTX;
    2395              : }
    2396              : 
    2397              : /* Subroutine of simplify_binary_operation to simplify a binary operation
    2398              :    CODE that can commute with byte swapping, with result mode MODE and
    2399              :    operating on OP0 and OP1.  CODE is currently one of AND, IOR or XOR.
    2400              :    Return zero if no simplification or canonicalization is possible.  */
    2401              : 
    2402              : rtx
    2403     37536743 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
    2404              :                                                     machine_mode mode,
    2405              :                                                     rtx op0, rtx op1)
    2406              : {
    2407     37536743 :   rtx tem;
    2408              : 
    2409              :   /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped.  */
    2410     37536743 :   if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
    2411              :     {
    2412          254 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
    2413              :                                  simplify_gen_unary (BSWAP, mode, op1, mode));
    2414          254 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2415              :     }
    2416              : 
    2417              :   /* (op (bswap x) (bswap y)) -> (bswap (op x y)).  */
    2418     37536489 :   if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
    2419              :     {
    2420            0 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
    2421            0 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2422              :     }
    2423              : 
    2424              :   return NULL_RTX;
    2425              : }
    2426              : 
    2427              : /* Subroutine of simplify_binary_operation to simplify a commutative,
    2428              :    associative binary operation CODE with result mode MODE, operating
    2429              :    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
    2430              :    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
    2431              :    canonicalization is possible.  */
    2432              : 
    2433              : rtx
    2434     48305053 : simplify_context::simplify_associative_operation (rtx_code code,
    2435              :                                                   machine_mode mode,
    2436              :                                                   rtx op0, rtx op1)
    2437              : {
    2438     48305053 :   rtx tem;
    2439              : 
    2440              :   /* Normally expressions simplified by simplify-rtx.cc are combined
    2441              :      at most from a few machine instructions and therefore the
    2442              :      expressions should be fairly small.  During var-tracking
    2443              :      we can see arbitrarily large expressions though and reassociating
    2444              :      those can be quadratic, so punt after encountering max_assoc_count
    2445              :      simplify_associative_operation calls during outermost simplify_*
    2446              :      call.  */
    2447     48305053 :   if (++assoc_count >= max_assoc_count)
    2448              :     return NULL_RTX;
    2449              : 
    2450              :   /* Linearize the operator to the left.  */
    2451     48300653 :   if (GET_CODE (op1) == code)
    2452              :     {
    2453              :       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
    2454        19137 :       if (GET_CODE (op0) == code)
    2455              :         {
    2456         4993 :           tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
    2457         4993 :           return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
    2458              :         }
    2459              : 
    2460              :       /* "a op (b op c)" becomes "(b op c) op a".  */
    2461        14144 :       if (! swap_commutative_operands_p (op1, op0))
    2462        14144 :         return simplify_gen_binary (code, mode, op1, op0);
    2463              : 
    2464              :       std::swap (op0, op1);
    2465              :     }
    2466              : 
    2467     48281516 :   if (GET_CODE (op0) == code)
    2468              :     {
    2469              :       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
    2470      1336881 :       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
    2471              :         {
    2472       269166 :           tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
    2473       269166 :           return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2474              :         }
    2475              : 
    2476              :       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
    2477      1067715 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
    2478      1067715 :       if (tem != 0)
    2479        80656 :         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
    2480              : 
    2481              :       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
    2482       987059 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
    2483       987059 :       if (tem != 0)
    2484        32241 :         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2485              :     }
    2486              : 
    2487              :   return 0;
    2488              : }
    2489              : 
    2490              : /* If COMPARISON can be treated as an unsigned comparison, return a mask
    2491              :    that represents it (8 if it includes <, 4 if it includes > and 2
    2492              :    if it includes ==).  Return 0 otherwise.  */
    2493              : static int
    2494        18890 : unsigned_comparison_to_mask (rtx_code comparison)
    2495              : {
    2496            0 :   switch (comparison)
    2497              :     {
    2498              :     case LTU:
    2499              :       return 8;
    2500              :     case GTU:
    2501              :       return 4;
    2502              :     case EQ:
    2503              :       return 2;
    2504              : 
    2505              :     case LEU:
    2506              :       return 10;
    2507              :     case GEU:
    2508              :       return 6;
    2509              : 
    2510              :     case NE:
    2511              :       return 12;
    2512              : 
    2513              :     default:
    2514              :       return 0;
    2515              :     }
    2516              : }
    2517              : 
    2518              : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
    2519              :    to comparisons.  */
    2520              : static rtx_code
    2521         6608 : mask_to_unsigned_comparison (int mask)
    2522              : {
    2523         6608 :   switch (mask)
    2524              :     {
    2525              :     case 8:
    2526              :       return LTU;
    2527          160 :     case 4:
    2528          160 :       return GTU;
    2529         2514 :     case 2:
    2530         2514 :       return EQ;
    2531              : 
    2532          160 :     case 10:
    2533          160 :       return LEU;
    2534          160 :     case 6:
    2535          160 :       return GEU;
    2536              : 
    2537         3454 :     case 12:
    2538         3454 :       return NE;
    2539              : 
    2540            0 :     default:
    2541            0 :       gcc_unreachable ();
    2542              :     }
    2543              : }
    2544              : 
    2545              : /* Return a mask describing the COMPARISON.  */
    2546              : static int
    2547         2666 : comparison_to_mask (enum rtx_code comparison)
    2548              : {
    2549         2666 :   switch (comparison)
    2550              :     {
    2551              :     case LT:
    2552              :       return 8;
    2553          472 :     case GT:
    2554          472 :       return 4;
    2555          419 :     case EQ:
    2556          419 :       return 2;
    2557           19 :     case UNORDERED:
    2558           19 :       return 1;
    2559              : 
    2560            0 :     case LTGT:
    2561            0 :       return 12;
    2562          441 :     case LE:
    2563          441 :       return 10;
    2564          441 :     case GE:
    2565          441 :       return 6;
    2566            0 :     case UNLT:
    2567            0 :       return 9;
    2568            0 :     case UNGT:
    2569            0 :       return 5;
    2570            0 :     case UNEQ:
    2571            0 :       return 3;
    2572              : 
    2573            0 :     case ORDERED:
    2574            0 :       return 14;
    2575          400 :     case NE:
    2576          400 :       return 13;
    2577            0 :     case UNLE:
    2578            0 :       return 11;
    2579            0 :     case UNGE:
    2580            0 :       return 7;
    2581              : 
    2582            0 :     default:
    2583            0 :       gcc_unreachable ();
    2584              :     }
    2585              : }
    2586              : 
    2587              : /* Return a comparison corresponding to the MASK.  */
    2588              : static enum rtx_code
    2589         1014 : mask_to_comparison (int mask)
    2590              : {
    2591         1014 :   switch (mask)
    2592              :     {
    2593              :     case 8:
    2594              :       return LT;
    2595              :     case 4:
    2596              :       return GT;
    2597              :     case 2:
    2598              :       return EQ;
    2599              :     case 1:
    2600              :       return UNORDERED;
    2601              : 
    2602              :     case 12:
    2603              :       return LTGT;
    2604              :     case 10:
    2605              :       return LE;
    2606              :     case 6:
    2607              :       return GE;
    2608              :     case 9:
    2609              :       return UNLT;
    2610              :     case 5:
    2611              :       return UNGT;
    2612              :     case 3:
    2613              :       return UNEQ;
    2614              : 
    2615              :     case 14:
    2616              :       return ORDERED;
    2617              :     case 13:
    2618              :       return NE;
    2619              :     case 11:
    2620              :       return UNLE;
    2621              :     case 7:
    2622              :       return UNGE;
    2623              : 
    2624            0 :     default:
    2625            0 :       gcc_unreachable ();
    2626              :     }
    2627              : }
    2628              : 
    2629              : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
    2630              :    false/true value of comparison with MODE where comparison operands
    2631              :    have CMP_MODE.  */
    2632              : 
    2633              : static rtx
    2634       785949 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
    2635              : {
    2636       785949 :   if (SCALAR_FLOAT_MODE_P (mode))
    2637              :     {
    2638          197 :       if (res == const0_rtx)
    2639          193 :         return CONST0_RTX (mode);
    2640              : #ifdef FLOAT_STORE_FLAG_VALUE
    2641              :       REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
    2642              :       return const_double_from_real_value (val, mode);
    2643              : #else
    2644              :       return NULL_RTX;
    2645              : #endif
    2646              :     }
    2647       785752 :   if (VECTOR_MODE_P (mode))
    2648              :     {
    2649          406 :       if (res == const0_rtx)
    2650           79 :         return CONST0_RTX (mode);
    2651              : #ifdef VECTOR_STORE_FLAG_VALUE
    2652          327 :       rtx val = VECTOR_STORE_FLAG_VALUE (mode);
    2653          317 :       if (val == NULL_RTX)
    2654              :         return NULL_RTX;
    2655          317 :       if (val == const1_rtx)
    2656            0 :         return CONST1_RTX (mode);
    2657              : 
    2658          317 :       return gen_const_vec_duplicate (mode, val);
    2659              : #else
    2660              :       return NULL_RTX;
    2661              : #endif
    2662              :     }
    2663              :   /* For vector comparison with scalar int result, it is unknown
    2664              :      if the target means here a comparison into an integral bitmask,
    2665              :      or comparison where all comparisons true mean const_true_rtx
    2666              :      whole result, or where any comparisons true mean const_true_rtx
    2667              :      whole result.  For const0_rtx all the cases are the same.  */
    2668       785346 :   if (VECTOR_MODE_P (cmp_mode)
    2669            0 :       && SCALAR_INT_MODE_P (mode)
    2670            0 :       && res == const_true_rtx)
    2671            0 :     return NULL_RTX;
    2672              : 
    2673              :   return res;
    2674              : }
    2675              : 
    2676              : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
    2677              :    and OP1, in the case where both are relational operations.  Assume that
    2678              :    OP0 is inverted if INVERT0_P is true.
    2679              : 
    2680              :    Return 0 if no such simplification is possible.  */
    2681              : rtx
    2682     13584876 : simplify_context::simplify_logical_relational_operation (rtx_code code,
    2683              :                                                          machine_mode mode,
    2684              :                                                          rtx op0, rtx op1,
    2685              :                                                          bool invert0_p)
    2686              : {
    2687     13584876 :   if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
    2688              :     return 0;
    2689              : 
    2690        21685 :   if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2691         9873 :         && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
    2692              :     return 0;
    2693              : 
    2694         9445 :   if (side_effects_p (op0))
    2695              :     return 0;
    2696              : 
    2697         9445 :   enum rtx_code code0 = GET_CODE (op0);
    2698         9445 :   enum rtx_code code1 = GET_CODE (op1);
    2699         9445 :   machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
    2700         9445 :   if (cmp_mode == VOIDmode)
    2701            0 :     cmp_mode = GET_MODE (XEXP (op0, 1));
    2702              : 
    2703              :   /* Assume at first that the comparisons are on integers, and that the
    2704              :      operands are therefore ordered.  */
    2705         9445 :   int all = 14;
    2706         9445 :   int mask0 = unsigned_comparison_to_mask (code0);
    2707         9445 :   int mask1 = unsigned_comparison_to_mask (code1);
    2708        18890 :   bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
    2709         9445 :                      || IN_RANGE (mask1 & 12, 4, 8));
    2710         1333 :   if (unsigned_p)
    2711              :     {
    2712              :       /* We only reach here when comparing integers.  Reject mixtures of signed
    2713              :          and unsigned comparisons.  */
    2714         8112 :       if (mask0 == 0 || mask1 == 0)
    2715              :         return 0;
    2716              :     }
    2717              :   else
    2718              :     {
    2719              :       /* See whether the operands might be unordered.  Assume that all
    2720              :          results are possible for CC modes, and punt later if we don't get an
    2721              :          always-true or always-false answer.  */
    2722         1333 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
    2723              :         all = 15;
    2724         1333 :       mask0 = comparison_to_mask (code0) & all;
    2725         1333 :       mask1 = comparison_to_mask (code1) & all;
    2726              :     }
    2727              : 
    2728         8165 :   if (invert0_p)
    2729         4582 :     mask0 = mask0 ^ all;
    2730              : 
    2731         8165 :   int mask;
    2732         8165 :   if (code == AND)
    2733          960 :     mask = mask0 & mask1;
    2734         7205 :   else if (code == IOR)
    2735          948 :     mask = mask0 | mask1;
    2736         6257 :   else if (code == XOR)
    2737         6257 :     mask = mask0 ^ mask1;
    2738              :   else
    2739              :     return 0;
    2740              : 
    2741         8165 :   if (mask == all)
    2742          232 :     return relational_result (mode, GET_MODE (op0), const_true_rtx);
    2743              : 
    2744         7933 :   if (mask == 0)
    2745          232 :     return relational_result (mode, GET_MODE (op0), const0_rtx);
    2746              : 
    2747         7701 :   if (unsigned_p)
    2748         6608 :     code = mask_to_unsigned_comparison (mask);
    2749              :   else
    2750              :     {
    2751         1093 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    2752              :         return 0;
    2753              : 
    2754         1014 :       code = mask_to_comparison (mask);
    2755              :       /* LTGT and NE are arithmetically equivalent for ordered operands,
    2756              :          with NE being the canonical choice.  */
    2757         1014 :       if (code == LTGT && all == 14)
    2758          184 :         code = NE;
    2759              :     }
    2760              : 
    2761         7622 :   op0 = XEXP (op1, 0);
    2762         7622 :   op1 = XEXP (op1, 1);
    2763              : 
    2764         7622 :   return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
    2765              : }
    2766              : 
    2767              : /* We are going to IOR together OP0/OP1.  If there is a common term in OP0/OP1
    2768              :    then we may be able to simplify the expression.  We're primarily trying to
    2769              :    simplify down to IOR/XOR expression right now, but there may be other
    2770              :    simplifications we can do in the future.
    2771              : 
    2772              :    Return the simplified expression or NULL_RTX if no simplification was
    2773              :    possible.  */
    2774              : rtx
    2775     27705991 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
    2776              : {
    2777              :   /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
    2778              :      X and C have no bits in common.  */
    2779     27705991 :   if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
    2780       227131 :       && rtx_equal_p (op0, XEXP (op1, 0))
    2781         8333 :       && ((nonzero_bits (op0, GET_MODE (op0))
    2782         8333 :           & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
    2783     27705991 :       && !side_effects_p (op1))
    2784            0 :     return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
    2785              : 
    2786              :   /* (ior (and A C1) (and (not A) C2)) can be converted
    2787              :      into (and (xor A C2) (C1 + C2)) when there are no bits
    2788              :      in common between C1 and C2.  */
    2789     27705991 :   if (GET_CODE (op0) == AND
    2790      4008151 :       && GET_CODE (op1) == AND
    2791       392449 :       && GET_CODE (XEXP (op1, 0)) == NOT
    2792        19085 :       && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
    2793         3515 :       && CONST_INT_P (XEXP (op0, 1))
    2794           91 :       && CONST_INT_P (XEXP (op1, 1))
    2795     27706082 :       && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
    2796              :     {
    2797           91 :       rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
    2798              : 
    2799           91 :       rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
    2800           91 :       if (tem)
    2801              :         {
    2802           91 :           tem = simplify_gen_binary (AND, mode, tem, c);
    2803              : 
    2804           91 :           if (tem)
    2805              :             return tem;
    2806              :         }
    2807              :     }
    2808              : 
    2809              :   /* Another variant seen on some target particularly those with
    2810              :      sub-word operations.
    2811              : 
    2812              :      (ior (and A C1) (plus (and A C2) C2)) can be simplified into
    2813              :      (and (xor (A C2) (C1 + C2).
    2814              : 
    2815              :      Where C2 is the sign bit for A's mode.  So 0x80 for QI,
    2816              :      0x8000 for HI, etc.  In this case we know there is no carry
    2817              :      from the PLUS into relevant bits of the output.  */
    2818     27705900 :   if (GET_CODE (op0) == AND
    2819      4008060 :       && GET_CODE (op1) == PLUS
    2820         5819 :       && GET_CODE (XEXP (op1, 0)) == AND
    2821          300 :       && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
    2822          276 :       && CONST_INT_P (XEXP (op0, 1))
    2823          276 :       && CONST_INT_P (XEXP (op1, 1))
    2824          276 :       && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
    2825          276 :       && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
    2826           72 :       && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
    2827          144 :       && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
    2828          144 :           == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
    2829     27705900 :       && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
    2830              :     {
    2831            0 :       rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
    2832              : 
    2833            0 :       rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
    2834            0 :       if (tem)
    2835              :         {
    2836            0 :           tem = simplify_gen_binary (AND, mode, tem, c);
    2837            0 :           if (tem)
    2838              :             return tem;
    2839              :         }
    2840              :     }
    2841              :   return NULL_RTX;
    2842              : }
    2843              : 
    2844              : 
    2845              : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
    2846              :    and OP1.  Return 0 if no simplification is possible.
    2847              : 
    2848              :    Don't use this for relational operations such as EQ or LT.
    2849              :    Use simplify_relational_operation instead.  */
    2850              : rtx
    2851    490317097 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
    2852              :                                              rtx op0, rtx op1)
    2853              : {
    2854    490317097 :   rtx trueop0, trueop1;
    2855    490317097 :   rtx tem;
    2856              : 
    2857              :   /* Relational operations don't work here.  We must know the mode
    2858              :      of the operands in order to do the comparison correctly.
    2859              :      Assuming a full word can give incorrect results.
    2860              :      Consider comparing 128 with -128 in QImode.  */
    2861    490317097 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
    2862    490317097 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
    2863              : 
    2864              :   /* Make sure the constant is second.  */
    2865    490317097 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    2866    490317097 :       && swap_commutative_operands_p (op0, op1))
    2867              :     std::swap (op0, op1);
    2868              : 
    2869    490317097 :   trueop0 = avoid_constant_pool_reference (op0);
    2870    490317097 :   trueop1 = avoid_constant_pool_reference (op1);
    2871              : 
    2872    490317097 :   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
    2873    490317097 :   if (tem)
    2874              :     return tem;
    2875    459915835 :   tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
    2876              : 
    2877    459915835 :   if (tem)
    2878              :     return tem;
    2879              : 
    2880              :   /* If the above steps did not result in a simplification and op0 or op1
    2881              :      were constant pool references, use the referenced constants directly.  */
    2882    395439596 :   if (trueop0 != op0 || trueop1 != op1)
    2883       577382 :     return simplify_gen_binary (code, mode, trueop0, trueop1);
    2884              : 
    2885              :   return NULL_RTX;
    2886              : }
    2887              : 
    2888              : /* Subroutine of simplify_binary_operation_1 that looks for cases in
    2889              :    which OP0 and OP1 are both vector series or vector duplicates
    2890              :    (which are really just series with a step of 0).  If so, try to
    2891              :    form a new series by applying CODE to the bases and to the steps.
    2892              :    Return null if no simplification is possible.
    2893              : 
    2894              :    MODE is the mode of the operation and is known to be a vector
    2895              :    integer mode.  */
    2896              : 
    2897              : rtx
    2898      2523218 : simplify_context::simplify_binary_operation_series (rtx_code code,
    2899              :                                                     machine_mode mode,
    2900              :                                                     rtx op0, rtx op1)
    2901              : {
    2902      2523218 :   rtx base0, step0;
    2903      2523218 :   if (vec_duplicate_p (op0, &base0))
    2904        73119 :     step0 = const0_rtx;
    2905      2450099 :   else if (!vec_series_p (op0, &base0, &step0))
    2906              :     return NULL_RTX;
    2907              : 
    2908        73839 :   rtx base1, step1;
    2909        73839 :   if (vec_duplicate_p (op1, &base1))
    2910          422 :     step1 = const0_rtx;
    2911        73417 :   else if (!vec_series_p (op1, &base1, &step1))
    2912              :     return NULL_RTX;
    2913              : 
    2914              :   /* Only create a new series if we can simplify both parts.  In other
    2915              :      cases this isn't really a simplification, and it's not necessarily
    2916              :      a win to replace a vector operation with a scalar operation.  */
    2917         5646 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    2918         5646 :   rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
    2919         5646 :   if (!new_base)
    2920              :     return NULL_RTX;
    2921              : 
    2922         4704 :   rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
    2923         4704 :   if (!new_step)
    2924              :     return NULL_RTX;
    2925              : 
    2926         4704 :   return gen_vec_series (mode, new_base, new_step);
    2927              : }
    2928              : 
    2929              : /* Subroutine of simplify_binary_operation_1.  Un-distribute a binary
    2930              :    operation CODE with result mode MODE, operating on OP0 and OP1.
    2931              :    e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
    2932              :    Returns NULL_RTX if no simplification is possible.  */
    2933              : 
    2934              : rtx
    2935      1329519 : simplify_context::simplify_distributive_operation (rtx_code code,
    2936              :                                                    machine_mode mode,
    2937              :                                                    rtx op0, rtx op1)
    2938              : {
    2939      1329519 :   enum rtx_code op = GET_CODE (op0);
    2940      1329519 :   gcc_assert (GET_CODE (op1) == op);
    2941              : 
    2942      1329519 :   if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
    2943      1329519 :       && ! side_effects_p (XEXP (op0, 1)))
    2944       328918 :     return simplify_gen_binary (op, mode,
    2945              :                                 simplify_gen_binary (code, mode,
    2946              :                                                      XEXP (op0, 0),
    2947              :                                                      XEXP (op1, 0)),
    2948       328918 :                                 XEXP (op0, 1));
    2949              : 
    2950      1000601 :   if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
    2951              :     {
    2952       982806 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2953       982806 :           && ! side_effects_p (XEXP (op0, 0)))
    2954       484276 :         return simplify_gen_binary (op, mode,
    2955              :                                     simplify_gen_binary (code, mode,
    2956              :                                                          XEXP (op0, 1),
    2957              :                                                          XEXP (op1, 1)),
    2958       484276 :                                     XEXP (op0, 0));
    2959       498530 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
    2960       498530 :           && ! side_effects_p (XEXP (op0, 0)))
    2961           54 :         return simplify_gen_binary (op, mode,
    2962              :                                     simplify_gen_binary (code, mode,
    2963              :                                                          XEXP (op0, 1),
    2964              :                                                          XEXP (op1, 0)),
    2965           54 :                                     XEXP (op0, 0));
    2966       498476 :       if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
    2967       498476 :           && ! side_effects_p (XEXP (op0, 1)))
    2968       254194 :         return simplify_gen_binary (op, mode,
    2969              :                                     simplify_gen_binary (code, mode,
    2970              :                                                          XEXP (op0, 0),
    2971              :                                                          XEXP (op1, 1)),
    2972       254194 :                                     XEXP (op0, 1));
    2973              :     }
    2974              : 
    2975              :   return NULL_RTX;
    2976              : }
    2977              : 
    2978              : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
    2979              :    should be reversed.
    2980              : 
    2981              :    If the rotate should not be reversed, return FALSE.
    2982              : 
    2983              :    LEFT indicates if this is a rotate left or a rotate right.  */
    2984              : 
    2985              : bool
    2986       149611 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
    2987              : {
    2988       149611 :   if (!CONST_INT_P (op1))
    2989              :     return false;
    2990              : 
    2991              :   /* Some targets may only be able to rotate by a constant
    2992              :      in one direction.  So we need to query the optab interface
    2993              :      to see what is possible.  */
    2994       112851 :   optab binoptab = left ? rotl_optab : rotr_optab;
    2995        48613 :   optab re_binoptab = left ? rotr_optab : rotl_optab;
    2996       112851 :   enum insn_code icode = optab_handler (binoptab, mode);
    2997       112851 :   enum insn_code re_icode = optab_handler (re_binoptab, mode);
    2998              : 
    2999              :   /* If the target can not support the reversed optab, then there
    3000              :      is nothing to do.  */
    3001       112851 :   if (re_icode == CODE_FOR_nothing)
    3002              :     return false;
    3003              : 
    3004              :   /* If the target does not support the requested rotate-by-immediate,
    3005              :      then we want to try reversing the rotate.  We also want to try
    3006              :      reversing to minimize the count.  */
    3007       110369 :   if ((icode == CODE_FOR_nothing)
    3008       110369 :       || (!insn_operand_matches (icode, 2, op1))
    3009       551845 :       || (IN_RANGE (INTVAL (op1),
    3010              :                     GET_MODE_UNIT_PRECISION (mode) / 2 + left,
    3011              :                     GET_MODE_UNIT_PRECISION (mode) - 1)))
    3012        15518 :     return (insn_operand_matches (re_icode, 2, op1));
    3013              :   return false;
    3014              : }
    3015              : 
    3016              : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
    3017              :    and return the expression to be shifted in SHIFT_OPND and the shift amount
    3018              :    in SHIFT_AMNT.  This is primarily used to group handling of ASHIFT (X, CST)
    3019              :    and (PLUS (X, X)) in one place.  If the expression is not equivalent to an
    3020              :    ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL.  */
    3021              : 
    3022              : static bool
    3023    539978297 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
    3024              : {
    3025    539978297 :   if (GET_CODE (x) == ASHIFT)
    3026              :     {
    3027     13831737 :       *shift_opnd = XEXP (x, 0);
    3028     13831737 :       *shift_amnt = XEXP (x, 1);
    3029     13831737 :       return true;
    3030              :     }
    3031    526146560 :   if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
    3032              :     {
    3033        11884 :       *shift_opnd = XEXP (x, 0);
    3034        11884 :       *shift_amnt = CONST1_RTX (GET_MODE (x));
    3035        11884 :       return true;
    3036              :     }
    3037    526134676 :   *shift_opnd = NULL_RTX;
    3038    526134676 :   *shift_amnt = NULL_RTX;
    3039    526134676 :   return false;
    3040              : }
    3041              : 
    3042              : /* OP0 and OP1 are combined under an operation of mode MODE that can
    3043              :    potentially result in a ROTATE expression.  Analyze the OP0 and OP1
    3044              :    and return the resulting ROTATE expression if so.  Return NULL otherwise.
    3045              :    This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
    3046              :    C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
    3047              :    (X << C1) and (C >> C2) would be OP0 and OP1.  */
    3048              : 
    3049              : static rtx
    3050    272821377 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
    3051              : {
    3052              :   /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3053              :      mode size to (rotate A CX).  */
    3054              : 
    3055    272821377 :   rtx opleft = op0;
    3056    272821377 :   rtx opright = op1;
    3057    272821377 :   rtx ashift_opnd, ashift_amnt;
    3058              :   /* In some cases the ASHIFT is not a direct ASHIFT.  Look deeper and extract
    3059              :      the relevant operands here.  */
    3060    272821377 :   bool ashift_op_p
    3061    272821377 :     = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
    3062              : 
    3063    272821377 :   if (ashift_op_p
    3064    271125819 :      || GET_CODE (op1) == SUBREG)
    3065              :     {
    3066              :       opleft = op1;
    3067              :       opright = op0;
    3068              :     }
    3069              :   else
    3070              :     {
    3071    267156920 :       opright = op1;
    3072    267156920 :       opleft = op0;
    3073    267156920 :       ashift_op_p
    3074    267156920 :         = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
    3075              :     }
    3076              : 
    3077     13843621 :   if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
    3078    271178840 :       && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
    3079              :     {
    3080         9403 :       rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
    3081         9403 :       rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
    3082              : 
    3083         5590 :       if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
    3084        14993 :           && (INTVAL (leftcst) + INTVAL (rightcst)
    3085         5590 :               == GET_MODE_UNIT_PRECISION (mode)))
    3086         5089 :         return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
    3087              :     }
    3088              : 
    3089              :   /* Same, but for ashift that has been "simplified" to a wider mode
    3090              :      by simplify_shift_const.  */
    3091    272816288 :   scalar_int_mode int_mode, inner_mode;
    3092              : 
    3093    272816288 :   if (GET_CODE (opleft) == SUBREG
    3094    278417751 :       && is_a <scalar_int_mode> (mode, &int_mode)
    3095      5596374 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
    3096              :                                  &inner_mode)
    3097      5559446 :       && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
    3098       189247 :       && GET_CODE (opright) == LSHIFTRT
    3099          888 :       && GET_CODE (XEXP (opright, 0)) == SUBREG
    3100          230 :       && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
    3101          456 :       && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
    3102          221 :       && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
    3103          221 :                       SUBREG_REG (XEXP (opright, 0)))
    3104            5 :       && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
    3105            5 :       && CONST_INT_P (XEXP (opright, 1))
    3106    272816288 :       && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
    3107            5 :             + INTVAL (XEXP (opright, 1))
    3108            5 :          == GET_MODE_PRECISION (int_mode)))
    3109            1 :         return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
    3110              :                                XEXP (SUBREG_REG (opleft), 1));
    3111              :   return NULL_RTX;
    3112              : }
    3113              : 
    3114              : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
    3115              :    and the pattern can be simplified (there are no side effects).  */
    3116              : 
    3117              : static bool
    3118     39614791 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
    3119              : {
    3120              :   /* Remove SUBREG from OP0 and OP1, if needed.  */
    3121     39614791 :   if (GET_CODE (op0) == SUBREG
    3122      7194931 :       && GET_CODE (op1) == SUBREG
    3123       297762 :       && subreg_lowpart_p (op0)
    3124     39911892 :       && subreg_lowpart_p (op1))
    3125              :     {
    3126       297092 :       op0 = XEXP (op0, 0);
    3127       297092 :       op1 = XEXP (op1, 0);
    3128              :     }
    3129              : 
    3130              :   /* Check for the pattern (OP (plus (A - 1)) (neg A)).  */
    3131     39614791 :   if (((GET_CODE (op1) == NEG
    3132         4004 :         && GET_CODE (op0) == PLUS
    3133         2133 :         && XEXP (op0, 1) == CONSTM1_RTX (mode))
    3134     39614101 :        || (GET_CODE (op0) == NEG
    3135        82652 :            && GET_CODE (op1) == PLUS
    3136            0 :            && XEXP (op1, 1) == CONSTM1_RTX (mode)))
    3137          690 :       && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3138     39614793 :       && !side_effects_p (XEXP (op0, 0)))
    3139            2 :     return true;
    3140              :   return false;
    3141              : }
    3142              : 
    3143              : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
    3144              :    non-paradoxical.  */
    3145              : 
    3146              : static bool
    3147     75075958 : non_paradoxical_subreg_not_p (rtx op)
    3148              : {
    3149     75075958 :   return GET_CODE (op) == SUBREG
    3150      8744747 :          && !paradoxical_subreg_p (op)
    3151     77890359 :          && GET_CODE (SUBREG_REG (op)) == NOT;
    3152              : }
    3153              : 
    3154              : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
    3155              :    (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
    3156              :    opportunities to combine another binary logical operation with NOT.  */
    3157              : 
    3158              : static rtx
    3159     37539244 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
    3160              : {
    3161     37539244 :   rtx opn = NULL_RTX;
    3162     37539244 :   if (non_paradoxical_subreg_not_p (op0))
    3163              :     opn = op0;
    3164     37536714 :   else if (non_paradoxical_subreg_not_p (op1))
    3165              :     opn = op1;
    3166              : 
    3167         2553 :   if (opn == NULL_RTX)
    3168              :     return NULL_RTX;
    3169              : 
    3170         5106 :   rtx new_subreg = simplify_gen_subreg (mode,
    3171              :                                         XEXP (SUBREG_REG (opn), 0),
    3172         2553 :                                         GET_MODE (SUBREG_REG (opn)),
    3173         2553 :                                         SUBREG_BYTE (opn));
    3174              : 
    3175         2553 :   if (!new_subreg)
    3176              :     return NULL_RTX;
    3177              : 
    3178         2501 :   rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
    3179         2501 :   if (opn == op0)
    3180         2478 :     return simplify_gen_binary (binop, mode, new_not, op1);
    3181              :   else
    3182           23 :     return simplify_gen_binary (binop, mode, op0, new_not);
    3183              : }
    3184              : 
    3185              : /* Return TRUE iff NOP is a negated form of OP, or vice-versa.  */
    3186              : static bool
    3187      6706277 : negated_ops_p (rtx nop, rtx op)
    3188              : {
    3189              :   /* Explicit negation.  */
    3190      6706277 :   if (GET_CODE (nop) == NOT
    3191      6706277 :       && rtx_equal_p (XEXP (nop, 0), op))
    3192              :     return true;
    3193      6702956 :   if (GET_CODE (op) == NOT
    3194      6702956 :       && rtx_equal_p (XEXP (op, 0), nop))
    3195              :     return true;
    3196              : 
    3197              :   /* (~C <r A) is a negated form of (C << A) if C == 1.  */
    3198      6699880 :   if (GET_CODE (op) == ASHIFT
    3199      1436306 :       && GET_CODE (nop) == ROTATE
    3200            0 :       && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
    3201            0 :       && CONST_INT_P (XEXP (nop, 0))
    3202            0 :       && INTVAL (XEXP (nop, 0)) == -2
    3203      6699880 :       && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
    3204              :     return true;
    3205      6699880 :   if (GET_CODE (nop) == ASHIFT
    3206       152535 :       && GET_CODE (op) == ROTATE
    3207            0 :       && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
    3208            0 :       && CONST_INT_P (XEXP (nop, 0))
    3209            0 :       && INTVAL (XEXP (nop, 0)) == -2
    3210      6699880 :       && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
    3211              :     return true;
    3212              : 
    3213              :   /* ??? Should we consider rotations of C and ~C by the same amount?  */
    3214              : 
    3215              :   return false;
    3216              : }
    3217              : 
    3218              : /* Subroutine of simplify_binary_operation.  Simplify a binary operation
    3219              :    CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
    3220              :    OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
    3221              :    actual constants.  */
    3222              : 
    3223              : rtx
    3224    459915835 : simplify_context::simplify_binary_operation_1 (rtx_code code,
    3225              :                                                machine_mode mode,
    3226              :                                                rtx op0, rtx op1,
    3227              :                                                rtx trueop0, rtx trueop1)
    3228              : {
    3229    459915835 :   rtx tem, reversed, elt0, elt1;
    3230    459915835 :   HOST_WIDE_INT val;
    3231    459915835 :   scalar_int_mode int_mode, inner_mode;
    3232    459915835 :   poly_int64 offset;
    3233              : 
    3234              :   /* Even if we can't compute a constant result,
    3235              :      there are some cases worth simplifying.  */
    3236              : 
    3237    459915835 :   switch (code)
    3238              :     {
    3239    262425734 :     case PLUS:
    3240              :       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
    3241              :          when x is NaN, infinite, or finite and nonzero.  They aren't
    3242              :          when x is -0 and the rounding mode is not towards -infinity,
    3243              :          since (-0) + 0 is then 0.  */
    3244    520962852 :       if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
    3245    520962840 :           && trueop1 == CONST0_RTX (mode))
    3246              :         return op0;
    3247              : 
    3248              :       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
    3249              :          transformations are safe even for IEEE.  */
    3250    260893056 :       if (GET_CODE (op0) == NEG)
    3251        65270 :         return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
    3252    260827786 :       else if (GET_CODE (op1) == NEG)
    3253         8614 :         return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
    3254              : 
    3255              :       /* (~a) + 1 -> -a */
    3256    260819172 :       if (INTEGRAL_MODE_P (mode)
    3257    256020748 :           && GET_CODE (op0) == NOT
    3258      1382472 :           && trueop1 == const1_rtx)
    3259         3830 :         return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
    3260              : 
    3261              :       /* Handle both-operands-constant cases.  We can only add
    3262              :          CONST_INTs to constants since the sum of relocatable symbols
    3263              :          can't be handled by most assemblers.  Don't add CONST_INT
    3264              :          to CONST_INT since overflow won't be computed properly if wider
    3265              :          than HOST_BITS_PER_WIDE_INT.  */
    3266              : 
    3267    260815342 :       if ((GET_CODE (op0) == CONST
    3268    260815342 :            || GET_CODE (op0) == SYMBOL_REF
    3269    258206773 :            || GET_CODE (op0) == LABEL_REF)
    3270    260815342 :           && poly_int_rtx_p (op1, &offset))
    3271      2607601 :         return plus_constant (mode, op0, offset);
    3272    258207741 :       else if ((GET_CODE (op1) == CONST
    3273    258207741 :                 || GET_CODE (op1) == SYMBOL_REF
    3274    254008705 :                 || GET_CODE (op1) == LABEL_REF)
    3275    258207741 :                && poly_int_rtx_p (op0, &offset))
    3276            0 :         return plus_constant (mode, op1, offset);
    3277              : 
    3278              :       /* See if this is something like X * C - X or vice versa or
    3279              :          if the multiplication is written as a shift.  If so, we can
    3280              :          distribute and make a new multiply, shift, or maybe just
    3281              :          have X (if C is 2 in the example above).  But don't make
    3282              :          something more expensive than we had before.  */
    3283              : 
    3284    258207741 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3285              :         {
    3286    251228269 :           rtx lhs = op0, rhs = op1;
    3287              : 
    3288    251228269 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3289    251228269 :           wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3290              : 
    3291    251228269 :           if (GET_CODE (lhs) == NEG)
    3292              :             {
    3293            0 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3294            0 :               lhs = XEXP (lhs, 0);
    3295              :             }
    3296    251228269 :           else if (GET_CODE (lhs) == MULT
    3297      9868676 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3298              :             {
    3299      8562306 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3300      8562306 :               lhs = XEXP (lhs, 0);
    3301              :             }
    3302    242665963 :           else if (GET_CODE (lhs) == ASHIFT
    3303     11047445 :                    && CONST_INT_P (XEXP (lhs, 1))
    3304     10974843 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3305    253640794 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3306              :             {
    3307     10974831 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3308     21949662 :                                             GET_MODE_PRECISION (int_mode));
    3309     10974831 :               lhs = XEXP (lhs, 0);
    3310              :             }
    3311              : 
    3312    251228269 :           if (GET_CODE (rhs) == NEG)
    3313              :             {
    3314            0 :               coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3315            0 :               rhs = XEXP (rhs, 0);
    3316              :             }
    3317    251228269 :           else if (GET_CODE (rhs) == MULT
    3318       353785 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3319              :             {
    3320       197313 :               coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
    3321       197313 :               rhs = XEXP (rhs, 0);
    3322              :             }
    3323    251030956 :           else if (GET_CODE (rhs) == ASHIFT
    3324       575781 :                    && CONST_INT_P (XEXP (rhs, 1))
    3325       566010 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3326    251596966 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3327              :             {
    3328       566010 :               coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3329      1132020 :                                             GET_MODE_PRECISION (int_mode));
    3330       566010 :               rhs = XEXP (rhs, 0);
    3331              :             }
    3332              : 
    3333              :           /* Keep PLUS of 2 volatile memory references.  */
    3334    251228269 :           if (rtx_equal_p (lhs, rhs)
    3335    251228269 :               && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
    3336              :             {
    3337       827647 :               rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
    3338       827647 :               rtx coeff;
    3339       827647 :               bool speed = optimize_function_for_speed_p (cfun);
    3340              : 
    3341       827647 :               coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
    3342              : 
    3343       827647 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3344       827647 :               return (set_src_cost (tem, int_mode, speed)
    3345       827647 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3346              :             }
    3347              : 
    3348              :           /* Optimize (X - 1) * Y + Y to X * Y.  */
    3349    250400622 :           lhs = op0;
    3350    250400622 :           rhs = op1;
    3351    250400622 :           if (GET_CODE (op0) == MULT)
    3352              :             {
    3353      9816510 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3354       635355 :                     && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
    3355      9767576 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3356        51973 :                        && XEXP (XEXP (op0, 0), 1) == const1_rtx))
    3357      9865444 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3358           88 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3359      9816422 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3360         1769 :                          && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
    3361      9816364 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3362          368 :                             && XEXP (XEXP (op0, 1), 1) == const1_rtx))
    3363      9816480 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3364            0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3365              :             }
    3366    240584112 :           else if (GET_CODE (op1) == MULT)
    3367              :             {
    3368       128171 :               if (((GET_CODE (XEXP (op1, 0)) == PLUS
    3369           93 :                     && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
    3370       128165 :                    || (GET_CODE (XEXP (op1, 0)) == MINUS
    3371           23 :                        && XEXP (XEXP (op1, 0), 1) == const1_rtx))
    3372       128177 :                   && rtx_equal_p (XEXP (op1, 1), op0))
    3373            0 :                 rhs = XEXP (XEXP (op1, 0), 0);
    3374       128171 :               else if (((GET_CODE (XEXP (op1, 1)) == PLUS
    3375           45 :                          && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
    3376       128171 :                         || (GET_CODE (XEXP (op1, 1)) == MINUS
    3377            0 :                             && XEXP (XEXP (op1, 1), 1) == const1_rtx))
    3378       128171 :                        && rtx_equal_p (XEXP (op1, 0), op0))
    3379            0 :                 rhs = XEXP (XEXP (op1, 1), 0);
    3380              :             }
    3381    250400622 :           if (lhs != op0 || rhs != op1)
    3382           88 :             return simplify_gen_binary (MULT, int_mode, lhs, rhs);
    3383    251228269 :         }
    3384              : 
    3385              :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
    3386    257380006 :       if (CONST_SCALAR_INT_P (op1)
    3387    196563910 :           && GET_CODE (op0) == XOR
    3388        18419 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3389    257389669 :           && mode_signbit_p (mode, op1))
    3390          121 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3391              :                                     simplify_gen_binary (XOR, mode, op1,
    3392          121 :                                                          XEXP (op0, 1)));
    3393              : 
    3394              :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
    3395              :          2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
    3396    257379885 :       if (CONST_SCALAR_INT_P (op1)
    3397    196563789 :           && GET_CODE (op0) == XOR
    3398        18298 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3399         9542 :           && nonzero_bits (XEXP (op0, 0), mode) == 1
    3400          349 :           && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
    3401    257379885 :           && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
    3402            0 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3403              :                                     simplify_gen_binary (XOR, mode, op1,
    3404            0 :                                                          XEXP (op0, 1)));
    3405              : 
    3406              :       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
    3407    257379885 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3408    257377357 :           && GET_CODE (op0) == MULT
    3409    267565271 :           && GET_CODE (XEXP (op0, 0)) == NEG)
    3410              :         {
    3411         5130 :           rtx in1, in2;
    3412              : 
    3413         5130 :           in1 = XEXP (XEXP (op0, 0), 0);
    3414         5130 :           in2 = XEXP (op0, 1);
    3415         5130 :           return simplify_gen_binary (MINUS, mode, op1,
    3416              :                                       simplify_gen_binary (MULT, mode,
    3417         5130 :                                                            in1, in2));
    3418              :         }
    3419              : 
    3420              :       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
    3421              :          C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
    3422              :          is 1.  */
    3423    257374755 :       if (COMPARISON_P (op0)
    3424      1279700 :           && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
    3425      1279700 :               || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
    3426    257432258 :           && (reversed = reversed_comparison (op0, mode)))
    3427        57146 :         return
    3428        57146 :           simplify_gen_unary (NEG, mode, reversed, mode);
    3429              : 
    3430              :       /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3431              :          mode size to (rotate A CX).  */
    3432    257317609 :       if ((tem = simplify_rotate_op (op0, op1, mode)))
    3433              :         return tem;
    3434              : 
    3435              :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3436              :          simplify this by the associative law.
    3437              :          Don't use the associative law for floating point.
    3438              :          The inaccuracy makes it nonassociative,
    3439              :          and subtle programs can break if operations are associated.  */
    3440              : 
    3441    257316145 :       if (INTEGRAL_MODE_P (mode)
    3442    252517770 :           && (plus_minus_operand_p (op0)
    3443    218181030 :               || plus_minus_operand_p (op1))
    3444     35402567 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3445              :         return tem;
    3446              : 
    3447              :       /* Reassociate floating point addition only when the user
    3448              :          specifies associative math operations.  */
    3449    222611515 :       if (FLOAT_MODE_P (mode)
    3450      4798375 :           && flag_associative_math)
    3451              :         {
    3452       909676 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3453       909676 :           if (tem)
    3454              :             return tem;
    3455              :         }
    3456              : 
    3457              :       /* Handle vector series.  */
    3458    222597772 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3459              :         {
    3460      2015022 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3461      2015022 :           if (tem)
    3462              :             return tem;
    3463              :         }
    3464              :       break;
    3465              : 
    3466              :     case COMPARE:
    3467              :       break;
    3468              : 
    3469     45469057 :     case MINUS:
    3470              :       /* We can't assume x-x is 0 even with non-IEEE floating point,
    3471              :          but since it is zero except in very strange circumstances, we
    3472              :          will treat it as zero with -ffinite-math-only.  */
    3473     45469057 :       if (rtx_equal_p (trueop0, trueop1)
    3474       209134 :           && ! side_effects_p (op0)
    3475     45677778 :           && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
    3476       206008 :         return CONST0_RTX (mode);
    3477              : 
    3478              :       /* Change subtraction from zero into negation.  (0 - x) is the
    3479              :          same as -x when x is NaN, infinite, or finite and nonzero.
    3480              :          But if the mode has signed zeros, and does not round towards
    3481              :          -infinity, then 0 - 0 is 0, not -0.  */
    3482     45263049 :       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
    3483       354262 :         return simplify_gen_unary (NEG, mode, op1, mode);
    3484              : 
    3485              :       /* (-1 - a) is ~a, unless the expression contains symbolic
    3486              :          constants, in which case not retaining additions and
    3487              :          subtractions could cause invalid assembly to be produced.  */
    3488     44908787 :       if (trueop0 == CONSTM1_RTX (mode)
    3489     44908787 :           && !contains_symbolic_reference_p (op1))
    3490       616488 :         return simplify_gen_unary (NOT, mode, op1, mode);
    3491              : 
    3492              :       /* Subtracting 0 has no effect unless the mode has signalling NaNs,
    3493              :          or has signed zeros and supports rounding towards -infinity.
    3494              :          In such a case, 0 - 0 is -0.  */
    3495     45026065 :       if (!(HONOR_SIGNED_ZEROS (mode)
    3496       733766 :             && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    3497     44291149 :           && !HONOR_SNANS (mode)
    3498     88583412 :           && trueop1 == CONST0_RTX (mode))
    3499              :         return op0;
    3500              : 
    3501              :       /* See if this is something like X * C - X or vice versa or
    3502              :          if the multiplication is written as a shift.  If so, we can
    3503              :          distribute and make a new multiply, shift, or maybe just
    3504              :          have X (if C is 2 in the example above).  But don't make
    3505              :          something more expensive than we had before.  */
    3506              : 
    3507     43356785 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3508              :         {
    3509     41969702 :           rtx lhs = op0, rhs = op1;
    3510              : 
    3511     41969702 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3512     41969702 :           wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3513              : 
    3514     41969702 :           if (GET_CODE (lhs) == NEG)
    3515              :             {
    3516        72990 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3517        72990 :               lhs = XEXP (lhs, 0);
    3518              :             }
    3519     41896712 :           else if (GET_CODE (lhs) == MULT
    3520       195022 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3521              :             {
    3522        70121 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3523        70121 :               lhs = XEXP (lhs, 0);
    3524              :             }
    3525     41826591 :           else if (GET_CODE (lhs) == ASHIFT
    3526       315005 :                    && CONST_INT_P (XEXP (lhs, 1))
    3527       311684 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3528     42138254 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3529              :             {
    3530       311663 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3531       623326 :                                             GET_MODE_PRECISION (int_mode));
    3532       311663 :               lhs = XEXP (lhs, 0);
    3533              :             }
    3534              : 
    3535     41969702 :           if (GET_CODE (rhs) == NEG)
    3536              :             {
    3537        13037 :               negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3538        13037 :               rhs = XEXP (rhs, 0);
    3539              :             }
    3540     41956665 :           else if (GET_CODE (rhs) == MULT
    3541       155755 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3542              :             {
    3543       101468 :               negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
    3544       101468 :               rhs = XEXP (rhs, 0);
    3545              :             }
    3546     41855197 :           else if (GET_CODE (rhs) == ASHIFT
    3547       413899 :                    && CONST_INT_P (XEXP (rhs, 1))
    3548       413367 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3549     42268564 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3550              :             {
    3551       413367 :               negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3552       826734 :                                                GET_MODE_PRECISION (int_mode));
    3553       413367 :               negcoeff1 = -negcoeff1;
    3554       413367 :               rhs = XEXP (rhs, 0);
    3555              :             }
    3556              : 
    3557     41969702 :           if (rtx_equal_p (lhs, rhs))
    3558              :             {
    3559        92639 :               rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
    3560        92639 :               rtx coeff;
    3561        92639 :               bool speed = optimize_function_for_speed_p (cfun);
    3562              : 
    3563        92639 :               coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
    3564              : 
    3565        92639 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3566        92639 :               return (set_src_cost (tem, int_mode, speed)
    3567        92639 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3568              :             }
    3569              : 
    3570              :           /* Optimize (X + 1) * Y - Y to X * Y.  */
    3571     41877063 :           lhs = op0;
    3572     41877063 :           if (GET_CODE (op0) == MULT)
    3573              :             {
    3574       194543 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3575         4960 :                     && XEXP (XEXP (op0, 0), 1) == const1_rtx)
    3576       192865 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3577         1643 :                        && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
    3578       196221 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3579            2 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3580       194541 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3581           30 :                          && XEXP (XEXP (op0, 1), 1) == const1_rtx)
    3582       194529 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3583           84 :                             && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
    3584       194553 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3585            0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3586              :             }
    3587     41877063 :           if (lhs != op0)
    3588            2 :             return simplify_gen_binary (MULT, int_mode, lhs, op1);
    3589     41969702 :         }
    3590              : 
    3591              :       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
    3592     43264144 :       if (GET_CODE (op1) == NEG)
    3593        12959 :         return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
    3594              : 
    3595              :       /* (-x - c) may be simplified as (-c - x).  */
    3596     43251185 :       if (GET_CODE (op0) == NEG
    3597        77132 :           && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
    3598              :         {
    3599          725 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    3600          725 :           if (tem)
    3601          725 :             return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
    3602              :         }
    3603              : 
    3604     43250460 :       if ((GET_CODE (op0) == CONST
    3605     43250460 :            || GET_CODE (op0) == SYMBOL_REF
    3606     37728812 :            || GET_CODE (op0) == LABEL_REF)
    3607     43250460 :           && poly_int_rtx_p (op1, &offset))
    3608        54145 :         return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
    3609              : 
    3610              :       /* Don't let a relocatable value get a negative coeff.  */
    3611     43196315 :       if (is_a <scalar_int_mode> (mode)
    3612     41809263 :           && poly_int_rtx_p (op1)
    3613     50396655 :           && GET_MODE (op0) != VOIDmode)
    3614      7200340 :         return simplify_gen_binary (PLUS, mode,
    3615              :                                     op0,
    3616      7200340 :                                     neg_poly_int_rtx (mode, op1));
    3617              : 
    3618              :       /* (x - (x & y)) -> (x & ~y) */
    3619     35995975 :       if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
    3620              :         {
    3621       248467 :           if (rtx_equal_p (op0, XEXP (op1, 0)))
    3622              :             {
    3623          480 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
    3624          240 :                                         GET_MODE (XEXP (op1, 1)));
    3625          240 :               return simplify_gen_binary (AND, mode, op0, tem);
    3626              :             }
    3627       248227 :           if (rtx_equal_p (op0, XEXP (op1, 1)))
    3628              :             {
    3629         2364 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
    3630         1182 :                                         GET_MODE (XEXP (op1, 0)));
    3631         1182 :               return simplify_gen_binary (AND, mode, op0, tem);
    3632              :             }
    3633              :         }
    3634              : 
    3635              :       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
    3636              :          by reversing the comparison code if valid.  */
    3637     35994553 :       if (STORE_FLAG_VALUE == 1
    3638     35994553 :           && trueop0 == const1_rtx
    3639      1183506 :           && COMPARISON_P (op1)
    3640     36098558 :           && (reversed = reversed_comparison (op1, mode)))
    3641              :         return reversed;
    3642              : 
    3643              :       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
    3644     35890553 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3645     35889202 :           && GET_CODE (op1) == MULT
    3646     36146753 :           && GET_CODE (XEXP (op1, 0)) == NEG)
    3647              :         {
    3648          173 :           rtx in1, in2;
    3649              : 
    3650          173 :           in1 = XEXP (XEXP (op1, 0), 0);
    3651          173 :           in2 = XEXP (op1, 1);
    3652          173 :           return simplify_gen_binary (PLUS, mode,
    3653              :                                       simplify_gen_binary (MULT, mode,
    3654              :                                                            in1, in2),
    3655          173 :                                       op0);
    3656              :         }
    3657              : 
    3658              :       /* Canonicalize (minus (neg A) (mult B C)) to
    3659              :          (minus (mult (neg B) C) A).  */
    3660     35890380 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3661     35889029 :           && GET_CODE (op1) == MULT
    3662     36146407 :           && GET_CODE (op0) == NEG)
    3663              :         {
    3664          675 :           rtx in1, in2;
    3665              : 
    3666          675 :           in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
    3667          675 :           in2 = XEXP (op1, 1);
    3668          675 :           return simplify_gen_binary (MINUS, mode,
    3669              :                                       simplify_gen_binary (MULT, mode,
    3670              :                                                            in1, in2),
    3671          675 :                                       XEXP (op0, 0));
    3672              :         }
    3673              : 
    3674              :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3675              :          simplify this by the associative law.  This will, for example,
    3676              :          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
    3677              :          Don't use the associative law for floating point.
    3678              :          The inaccuracy makes it nonassociative,
    3679              :          and subtle programs can break if operations are associated.  */
    3680              : 
    3681     35889705 :       if (INTEGRAL_MODE_P (mode)
    3682     35034686 :           && (plus_minus_operand_p (op0)
    3683     32125746 :               || plus_minus_operand_p (op1))
    3684      4150082 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3685              :         return tem;
    3686              : 
    3687              :       /* Handle vector series.  */
    3688     31889269 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3689              :         {
    3690       508196 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3691       508196 :           if (tem)
    3692              :             return tem;
    3693              :         }
    3694              :       break;
    3695              : 
    3696     12795396 :     case MULT:
    3697     12795396 :       if (trueop1 == constm1_rtx)
    3698        34968 :         return simplify_gen_unary (NEG, mode, op0, mode);
    3699              : 
    3700     12760428 :       if (GET_CODE (op0) == NEG)
    3701              :         {
    3702        40694 :           rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
    3703              :           /* If op1 is a MULT as well and simplify_unary_operation
    3704              :              just moved the NEG to the second operand, simplify_gen_binary
    3705              :              below could through simplify_associative_operation move
    3706              :              the NEG around again and recurse endlessly.  */
    3707        40694 :           if (temp
    3708         1977 :               && GET_CODE (op1) == MULT
    3709            0 :               && GET_CODE (temp) == MULT
    3710            0 :               && XEXP (op1, 0) == XEXP (temp, 0)
    3711            0 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3712            0 :               && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
    3713              :             temp = NULL_RTX;
    3714              :           if (temp)
    3715         1977 :             return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
    3716              :         }
    3717     12758451 :       if (GET_CODE (op1) == NEG)
    3718              :         {
    3719          906 :           rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
    3720              :           /* If op0 is a MULT as well and simplify_unary_operation
    3721              :              just moved the NEG to the second operand, simplify_gen_binary
    3722              :              below could through simplify_associative_operation move
    3723              :              the NEG around again and recurse endlessly.  */
    3724          906 :           if (temp
    3725          413 :               && GET_CODE (op0) == MULT
    3726          302 :               && GET_CODE (temp) == MULT
    3727          302 :               && XEXP (op0, 0) == XEXP (temp, 0)
    3728            6 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3729            5 :               && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
    3730              :             temp = NULL_RTX;
    3731              :           if (temp)
    3732          408 :             return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
    3733              :         }
    3734              : 
    3735              :       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
    3736              :          x is NaN, since x * 0 is then also NaN.  Nor is it valid
    3737              :          when the mode has signed zeros, since multiplying a negative
    3738              :          number by 0 will give -0, not 0.  */
    3739     12758043 :       if (!HONOR_NANS (mode)
    3740     11775390 :           && !HONOR_SIGNED_ZEROS (mode)
    3741     11774974 :           && trueop1 == CONST0_RTX (mode)
    3742     12802194 :           && ! side_effects_p (op0))
    3743              :         return op1;
    3744              : 
    3745              :       /* In IEEE floating point, x*1 is not equivalent to x for
    3746              :          signalling NaNs.  */
    3747     12714307 :       if (!HONOR_SNANS (mode)
    3748     12714307 :           && trueop1 == CONST1_RTX (mode))
    3749              :         return op0;
    3750              : 
    3751              :       /* Convert multiply by constant power of two into shift.  */
    3752     12186455 :       if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
    3753              :         {
    3754      6233236 :           val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
    3755      6233236 :           if (val >= 0)
    3756      2938998 :             return simplify_gen_binary (ASHIFT, mode, op0,
    3757      2938998 :                                         gen_int_shift_amount (mode, val));
    3758              :         }
    3759              : 
    3760              :       /* x*2 is x+x and x*(-1) is -x */
    3761      9247457 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    3762       171735 :           && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
    3763       171735 :           && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
    3764       171451 :           && GET_MODE (op0) == mode)
    3765              :         {
    3766       171451 :           const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    3767              : 
    3768       171451 :           if (real_equal (d1, &dconst2))
    3769          682 :             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
    3770              : 
    3771       170769 :           if (!HONOR_SNANS (mode)
    3772       170769 :               && real_equal (d1, &dconstm1))
    3773           25 :             return simplify_gen_unary (NEG, mode, op0, mode);
    3774              :         }
    3775              : 
    3776              :       /* Optimize -x * -x as x * x.  */
    3777      9246750 :       if (FLOAT_MODE_P (mode)
    3778      1407474 :           && GET_CODE (op0) == NEG
    3779         8307 :           && GET_CODE (op1) == NEG
    3780            0 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3781            0 :           && !side_effects_p (XEXP (op0, 0)))
    3782            0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3783              : 
    3784              :       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
    3785      9246750 :       if (SCALAR_FLOAT_MODE_P (mode)
    3786      1101618 :           && GET_CODE (op0) == ABS
    3787         1468 :           && GET_CODE (op1) == ABS
    3788            1 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3789      9246750 :           && !side_effects_p (XEXP (op0, 0)))
    3790            0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3791              : 
    3792              :       /* Reassociate multiplication, but for floating point MULTs
    3793              :          only when the user specifies unsafe math optimizations.  */
    3794      9246750 :       if (! FLOAT_MODE_P (mode)
    3795      1407474 :           || flag_unsafe_math_optimizations)
    3796              :         {
    3797      8265210 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3798      8265210 :           if (tem)
    3799              :             return tem;
    3800              :         }
    3801              :       break;
    3802              : 
    3803     15349891 :     case IOR:
    3804     15349891 :       if (trueop1 == CONST0_RTX (mode))
    3805              :         return op0;
    3806     14518178 :       if (INTEGRAL_MODE_P (mode)
    3807     14242636 :           && trueop1 == CONSTM1_RTX (mode)
    3808        10156 :           && !side_effects_p (op0))
    3809              :         return op1;
    3810     14508022 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    3811              :         return op0;
    3812              :       /* A | (~A) -> -1 */
    3813        71131 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    3814     14487955 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    3815            2 :           && ! side_effects_p (op0)
    3816     14487959 :           && GET_MODE_CLASS (mode) != MODE_CC)
    3817            2 :         return CONSTM1_RTX (mode);
    3818              : 
    3819              :       /* IOR of two single bit bitfields extracted from the same object.
    3820              :          Bitfields are represented as an AND based extraction */
    3821     14487955 :       if (GET_CODE (op0) == AND
    3822      4034293 :           && GET_CODE (op1) == AND
    3823              :           /* Verify both AND operands are logical right shifts. */
    3824       279036 :           && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    3825         1737 :           && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
    3826              :           /* Verify both bitfields are extracted from the same object. */
    3827           90 :           && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
    3828              :           /* Verify both fields are a single bit (could be generalized). */
    3829           86 :           && XEXP (op0, 1) == CONST1_RTX (mode)
    3830            0 :           && XEXP (op1, 1) == CONST1_RTX (mode)
    3831              :           /* Verify bit positions (for cases with variable bit position). */
    3832            0 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3833            0 :           && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
    3834              :         {
    3835            0 :           unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
    3836            0 :           unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
    3837            0 :           unsigned HOST_WIDE_INT mask
    3838            0 :             = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
    3839              : 
    3840            0 :           rtx m = GEN_INT (mask);
    3841            0 :           rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
    3842            0 :           t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
    3843            0 :           return t;
    3844              :         }
    3845              : 
    3846              :       /* IOR of multiple single bit bitfields extracted from the same object
    3847              :          (building on previous case).
    3848              :          First bitfield is represented as an AND based extraction, as done
    3849              :                 above. Second represented as NE based extraction, from
    3850              :                 output above. */
    3851     14487955 :       if (GET_CODE (op0) == AND
    3852      4034293 :           && GET_CODE (op1) == NE
    3853              :           /* Verify AND operand is logical right shift. */
    3854         3321 :           && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    3855              :           /* Verify NE operand is an AND (based on output above). */
    3856           86 :           && GET_CODE (XEXP (op1, 0)) == AND
    3857              :           /* Verify both bitfields are extracted from the same object. */
    3858            0 :           && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
    3859              :           /* Verify masking is with a single bit and that we have a NE 0
    3860              :              comparison for the other operand.  */
    3861            0 :           && XEXP (op0, 1) == CONST1_RTX (mode)
    3862            0 :           && XEXP (op1, 1) == CONST0_RTX (mode)
    3863              :           /* Verify bit position. */
    3864            0 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    3865              :         {
    3866            0 :           unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
    3867            0 :           unsigned HOST_WIDE_INT mask
    3868            0 :             = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
    3869              : 
    3870            0 :           rtx m = GEN_INT (mask);
    3871            0 :           rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
    3872            0 :           t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
    3873            0 :           return t;
    3874              :         }
    3875              : 
    3876              :       /* Convert (ior (plus (A - 1)) (neg A)) to -1.  */
    3877     14487955 :       if (match_plus_neg_pattern (op0, op1, mode))
    3878            0 :         return CONSTM1_RTX (mode);
    3879              : 
    3880              :       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
    3881     14487955 :       if (CONST_INT_P (op1)
    3882      3613361 :           && HWI_COMPUTABLE_MODE_P (mode)
    3883      3558267 :           && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
    3884     14895705 :           && !side_effects_p (op0))
    3885              :         return op1;
    3886              : 
    3887              :       /* Canonicalize (X & C1) | C2.  */
    3888     14080205 :       if (GET_CODE (op0) == AND
    3889      4025324 :           && CONST_INT_P (trueop1)
    3890       653999 :           && CONST_INT_P (XEXP (op0, 1)))
    3891              :         {
    3892       486825 :           HOST_WIDE_INT mask = GET_MODE_MASK (mode);
    3893       486825 :           HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
    3894       486825 :           HOST_WIDE_INT c2 = INTVAL (trueop1);
    3895              : 
    3896              :           /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2.  */
    3897       486825 :           if ((c1 & c2) == c1
    3898       486825 :               && !side_effects_p (XEXP (op0, 0)))
    3899              :             return trueop1;
    3900              : 
    3901              :           /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
    3902       486805 :           if (((c1|c2) & mask) == mask)
    3903        70852 :             return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
    3904              : 
    3905              :           /* If (C1|C2) has a single bit clear, then adjust C1 so that
    3906              :              when split it'll match a single bit clear style insn.
    3907              : 
    3908              :              This could have been done with a target dependent splitter, but
    3909              :              then every target with single bit manipulation insns would need
    3910              :              to implement such splitters.  */
    3911       415953 :           if (exact_log2 (~(c1 | c2)) >= 0)
    3912              :             {
    3913        61161 :               rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
    3914        61161 :               temp = gen_rtx_IOR (mode, temp, trueop1);
    3915        61161 :               return temp;
    3916              :             }
    3917              :         }
    3918              : 
    3919              :       /* Convert (A & B) | A to A.  */
    3920     13948172 :       if (GET_CODE (op0) == AND
    3921      3893291 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    3922      3892804 :               || rtx_equal_p (XEXP (op0, 1), op1))
    3923         3690 :           && ! side_effects_p (XEXP (op0, 0))
    3924     13951862 :           && ! side_effects_p (XEXP (op0, 1)))
    3925              :         return op1;
    3926              : 
    3927              :       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3928              :          mode size to (rotate A CX).  */
    3929     13944482 :       tem = simplify_rotate_op (op0, op1, mode);
    3930     13944482 :       if (tem)
    3931              :         return tem;
    3932              : 
    3933              :       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
    3934              :          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
    3935              :          the PLUS does not affect any of the bits in OP1: then we can do
    3936              :          the IOR as a PLUS and we can associate.  This is valid if OP1
    3937              :          can be safely shifted left C bits.  */
    3938     13942236 :       if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
    3939         6616 :           && GET_CODE (XEXP (op0, 0)) == PLUS
    3940          141 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3941           87 :           && CONST_INT_P (XEXP (op0, 1))
    3942           87 :           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
    3943              :         {
    3944           87 :           int count = INTVAL (XEXP (op0, 1));
    3945           87 :           HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
    3946              : 
    3947           87 :           if (mask >> count == INTVAL (trueop1)
    3948           80 :               && trunc_int_for_mode (mask, mode) == mask
    3949          154 :               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
    3950            0 :             return simplify_gen_binary (ASHIFTRT, mode,
    3951              :                                         plus_constant (mode, XEXP (op0, 0),
    3952            0 :                                                        mask),
    3953              :                                         XEXP (op0, 1));
    3954              :         }
    3955              : 
    3956              :       /* The following happens with bitfield merging.
    3957              :          (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
    3958     13942236 :       if (GET_CODE (op0) == AND
    3959      3889601 :           && GET_CODE (op1) == AND
    3960       279036 :           && CONST_INT_P (XEXP (op0, 1))
    3961       121570 :           && CONST_INT_P (XEXP (op1, 1))
    3962       117150 :           && (INTVAL (XEXP (op0, 1))
    3963       117150 :               == ~INTVAL (XEXP (op1, 1))))
    3964              :         {
    3965              :           /* The IOR/XOR may be on both sides.  */
    3966        33479 :           rtx top0 = NULL_RTX, top1 = NULL_RTX;
    3967        33479 :           if (GET_CODE (XEXP (op1, 0)) == IOR
    3968        33479 :               || GET_CODE (XEXP (op1, 0)) == XOR)
    3969              :             top0 = op0, top1 = op1;
    3970        33360 :           else if (GET_CODE (XEXP (op0, 0)) == IOR
    3971        33360 :                    || GET_CODE (XEXP (op0, 0)) == XOR)
    3972            3 :             top0 = op1, top1 = op0;
    3973        33479 :           if (top0 && top1)
    3974              :             {
    3975              :               /* X may be on either side of the inner IOR/XOR.  */
    3976          122 :               rtx tem = NULL_RTX;
    3977          122 :               if (rtx_equal_p (XEXP (top0, 0),
    3978          122 :                                XEXP (XEXP (top1, 0), 0)))
    3979           76 :                 tem = XEXP (XEXP (top1, 0), 1);
    3980           46 :               else if (rtx_equal_p (XEXP (top0, 0),
    3981           46 :                                     XEXP (XEXP (top1, 0), 1)))
    3982           13 :                 tem = XEXP (XEXP (top1, 0), 0);
    3983           89 :               if (tem)
    3984           89 :                 return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
    3985              :                                             mode, XEXP (top0, 0),
    3986              :                                             simplify_gen_binary
    3987           89 :                                               (AND, mode, tem, XEXP (top1, 1)));
    3988              :             }
    3989              :         }
    3990              : 
    3991              :       /* Convert (ior (and A C) (and B C)) into (and (ior A B) C).  */
    3992     13942147 :       if (GET_CODE (op0) == GET_CODE (op1)
    3993      3442863 :           && (GET_CODE (op0) == AND
    3994              :               || GET_CODE (op0) == IOR
    3995      3442863 :               || GET_CODE (op0) == LSHIFTRT
    3996      3162962 :               || GET_CODE (op0) == ASHIFTRT
    3997      3162827 :               || GET_CODE (op0) == ASHIFT
    3998      3146749 :               || GET_CODE (op0) == ROTATE
    3999      3146749 :               || GET_CODE (op0) == ROTATERT))
    4000              :         {
    4001       296114 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4002       296114 :           if (tem)
    4003              :             return tem;
    4004              :         }
    4005              : 
    4006              :       /* Convert (ior (and (not A) B) A) into A | B.  */
    4007     13859335 :       if (GET_CODE (op0) == AND
    4008     13859335 :           && negated_ops_p (XEXP (op0, 0), op1))
    4009         6294 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4010              : 
    4011              :       /* op0/op1 may have a common term which in turn may allow simplification
    4012              :          of the the outer IOR.  There are likely other cases we should
    4013              :          handle for the outer code as well as the form of the operands.  */
    4014     13853041 :       tem = simplify_ior_with_common_term (mode, op0, op1);
    4015     13853041 :       if (tem)
    4016              :         return tem;
    4017              : 
    4018              :       /* IOR is commutative and we can't rely on canonicalization at this point,
    4019              :          so try again to simplify with the operands reversed.  */
    4020     13852950 :       tem = simplify_ior_with_common_term (mode, op1, op0);
    4021     13852950 :       if (tem)
    4022              :         return tem;
    4023              : 
    4024     13852950 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4025     13852950 :       if (tem)
    4026              :         return tem;
    4027              : 
    4028     13852945 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4029     13852945 :       if (tem)
    4030              :         return tem;
    4031              : 
    4032     13852912 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4033     13852912 :       if (tem)
    4034              :         return tem;
    4035              : 
    4036     13574845 :       tem = simplify_logical_relational_operation (code, mode, op0, op1);
    4037     13574845 :       if (tem)
    4038              :         return tem;
    4039              :       break;
    4040              : 
    4041      1845959 :     case XOR:
    4042      1845959 :       if (trueop1 == CONST0_RTX (mode))
    4043              :         return op0;
    4044      1787066 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4045        30956 :         return simplify_gen_unary (NOT, mode, op0, mode);
    4046      1756110 :       if (rtx_equal_p (trueop0, trueop1)
    4047         2641 :           && ! side_effects_p (op0)
    4048      1758747 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4049         2637 :          return CONST0_RTX (mode);
    4050              : 
    4051              :       /* Canonicalize XOR of the most significant bit to PLUS.  */
    4052      1753473 :       if (CONST_SCALAR_INT_P (op1)
    4053      1753473 :           && mode_signbit_p (mode, op1))
    4054        40293 :         return simplify_gen_binary (PLUS, mode, op0, op1);
    4055              :       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
    4056      1713180 :       if (CONST_SCALAR_INT_P (op1)
    4057       492833 :           && GET_CODE (op0) == PLUS
    4058         2583 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    4059      1714700 :           && mode_signbit_p (mode, XEXP (op0, 1)))
    4060          189 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    4061              :                                     simplify_gen_binary (XOR, mode, op1,
    4062          189 :                                                          XEXP (op0, 1)));
    4063              : 
    4064              :       /* If we are XORing two things that have no bits in common,
    4065              :          convert them into an IOR.  This helps to detect rotation encoded
    4066              :          using those methods and possibly other simplifications.  */
    4067              : 
    4068      1712991 :       if (HWI_COMPUTABLE_MODE_P (mode)
    4069      1388905 :           && (nonzero_bits (op0, mode)
    4070      1388905 :               & nonzero_bits (op1, mode)) == 0)
    4071        11888 :         return (simplify_gen_binary (IOR, mode, op0, op1));
    4072              : 
    4073              :       /* Convert (xor (plus (A - 1)) (neg A)) to -1.  */
    4074      1701103 :       if (match_plus_neg_pattern (op0, op1, mode))
    4075            0 :         return CONSTM1_RTX (mode);
    4076              : 
    4077              :       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
    4078              :          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
    4079              :          (NOT y).  */
    4080      1701103 :       {
    4081      1701103 :         int num_negated = 0;
    4082              : 
    4083      1701103 :         if (GET_CODE (op0) == NOT)
    4084          720 :           num_negated++, op0 = XEXP (op0, 0);
    4085      1701103 :         if (GET_CODE (op1) == NOT)
    4086           65 :           num_negated++, op1 = XEXP (op1, 0);
    4087              : 
    4088           65 :         if (num_negated == 2)
    4089            0 :           return simplify_gen_binary (XOR, mode, op0, op1);
    4090      1701103 :         else if (num_negated == 1)
    4091          785 :           return simplify_gen_unary (NOT, mode,
    4092              :                                      simplify_gen_binary (XOR, mode, op0, op1),
    4093          785 :                                      mode);
    4094              :       }
    4095              : 
    4096              :       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
    4097              :          correspond to a machine insn or result in further simplifications
    4098              :          if B is a constant.  */
    4099              : 
    4100      1700318 :       if (GET_CODE (op0) == AND
    4101       192368 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4102      1723150 :           && ! side_effects_p (op1))
    4103        22832 :         return simplify_gen_binary (AND, mode,
    4104              :                                     simplify_gen_unary (NOT, mode,
    4105              :                                                         XEXP (op0, 0), mode),
    4106        22832 :                                     op1);
    4107              : 
    4108      1677486 :       else if (GET_CODE (op0) == AND
    4109       169536 :                && rtx_equal_p (XEXP (op0, 0), op1)
    4110      1679577 :                && ! side_effects_p (op1))
    4111         2091 :         return simplify_gen_binary (AND, mode,
    4112              :                                     simplify_gen_unary (NOT, mode,
    4113              :                                                         XEXP (op0, 1), mode),
    4114         2091 :                                     op1);
    4115              : 
    4116              :       /* Given (xor (ior (xor A B) C) D), where B, C and D are
    4117              :          constants, simplify to (xor (ior A C) (B&~C)^D), canceling
    4118              :          out bits inverted twice and not set by C.  Similarly, given
    4119              :          (xor (and (xor A B) C) D), simplify without inverting C in
    4120              :          the xor operand: (xor (and A C) (B&C)^D).
    4121              :       */
    4122      1675395 :       else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
    4123       191401 :                && GET_CODE (XEXP (op0, 0)) == XOR
    4124         7607 :                && CONST_INT_P (op1)
    4125          210 :                && CONST_INT_P (XEXP (op0, 1))
    4126          179 :                && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    4127              :         {
    4128           38 :           enum rtx_code op = GET_CODE (op0);
    4129           38 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4130           38 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4131           38 :           rtx c = XEXP (op0, 1);
    4132           38 :           rtx d = op1;
    4133           38 :           HOST_WIDE_INT bval = INTVAL (b);
    4134           38 :           HOST_WIDE_INT cval = INTVAL (c);
    4135           38 :           HOST_WIDE_INT dval = INTVAL (d);
    4136           38 :           HOST_WIDE_INT xcval;
    4137              : 
    4138           38 :           if (op == IOR)
    4139            8 :             xcval = ~cval;
    4140              :           else
    4141              :             xcval = cval;
    4142              : 
    4143           38 :           return simplify_gen_binary (XOR, mode,
    4144              :                                       simplify_gen_binary (op, mode, a, c),
    4145           38 :                                       gen_int_mode ((bval & xcval) ^ dval,
    4146              :                                                     mode));
    4147              :         }
    4148              : 
    4149              :       /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
    4150              :          we can transform like this:
    4151              :             (A&B)^C == ~(A&B)&C | ~C&(A&B)
    4152              :                     == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
    4153              :                     == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
    4154              :          Attempt a few simplifications when B and C are both constants.  */
    4155      1675357 :       if (GET_CODE (op0) == AND
    4156       167415 :           && CONST_INT_P (op1)
    4157        13988 :           && CONST_INT_P (XEXP (op0, 1)))
    4158              :         {
    4159        11474 :           rtx a = XEXP (op0, 0);
    4160        11474 :           rtx b = XEXP (op0, 1);
    4161        11474 :           rtx c = op1;
    4162        11474 :           HOST_WIDE_INT bval = INTVAL (b);
    4163        11474 :           HOST_WIDE_INT cval = INTVAL (c);
    4164              : 
    4165              :           /* Instead of computing ~A&C, we compute its negated value,
    4166              :              ~(A|~C).  If it yields -1, ~A&C is zero, so we can
    4167              :              optimize for sure.  If it does not simplify, we still try
    4168              :              to compute ~A&C below, but since that always allocates
    4169              :              RTL, we don't try that before committing to returning a
    4170              :              simplified expression.  */
    4171        11474 :           rtx n_na_c = simplify_binary_operation (IOR, mode, a,
    4172              :                                                   GEN_INT (~cval));
    4173              : 
    4174        11474 :           if ((~cval & bval) == 0)
    4175              :             {
    4176          828 :               rtx na_c = NULL_RTX;
    4177          828 :               if (n_na_c)
    4178            0 :                 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
    4179              :               else
    4180              :                 {
    4181              :                   /* If ~A does not simplify, don't bother: we don't
    4182              :                      want to simplify 2 operations into 3, and if na_c
    4183              :                      were to simplify with na, n_na_c would have
    4184              :                      simplified as well.  */
    4185          828 :                   rtx na = simplify_unary_operation (NOT, mode, a, mode);
    4186          828 :                   if (na)
    4187            0 :                     na_c = simplify_gen_binary (AND, mode, na, c);
    4188              :                 }
    4189              : 
    4190              :               /* Try to simplify ~A&C | ~B&C.  */
    4191            0 :               if (na_c != NULL_RTX)
    4192            0 :                 return simplify_gen_binary (IOR, mode, na_c,
    4193            0 :                                             gen_int_mode (~bval & cval, mode));
    4194              :             }
    4195              :           else
    4196              :             {
    4197              :               /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
    4198        10646 :               if (n_na_c == CONSTM1_RTX (mode))
    4199              :                 {
    4200            0 :                   rtx a_nc_b = simplify_gen_binary (AND, mode, a,
    4201            0 :                                                     gen_int_mode (~cval & bval,
    4202              :                                                                   mode));
    4203            0 :                   return simplify_gen_binary (IOR, mode, a_nc_b,
    4204            0 :                                               gen_int_mode (~bval & cval,
    4205              :                                                             mode));
    4206              :                 }
    4207              :             }
    4208              :         }
    4209              : 
    4210              :       /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
    4211              :          do (ior (and A ~C) (and B C)) which is a machine instruction on some
    4212              :          machines, and also has shorter instruction path length.  */
    4213      1675357 :       if (GET_CODE (op0) == AND
    4214       167415 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4215         7119 :           && CONST_INT_P (XEXP (op0, 1))
    4216      1679191 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
    4217              :         {
    4218            7 :           rtx a = trueop1;
    4219            7 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4220            7 :           rtx c = XEXP (op0, 1);
    4221            7 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4222            7 :           rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
    4223            7 :           rtx bc = simplify_gen_binary (AND, mode, b, c);
    4224            7 :           return simplify_gen_binary (IOR, mode, a_nc, bc);
    4225              :         }
    4226              :       /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C))  */
    4227      1675350 :       else if (GET_CODE (op0) == AND
    4228       167408 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4229         7112 :           && CONST_INT_P (XEXP (op0, 1))
    4230      1679177 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
    4231              :         {
    4232            8 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4233            8 :           rtx b = trueop1;
    4234            8 :           rtx c = XEXP (op0, 1);
    4235            8 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4236            8 :           rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
    4237            8 :           rtx ac = simplify_gen_binary (AND, mode, a, c);
    4238            8 :           return simplify_gen_binary (IOR, mode, ac, b_nc);
    4239              :         }
    4240              : 
    4241              :       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
    4242              :          comparison if STORE_FLAG_VALUE is 1.  */
    4243      1675342 :       if (STORE_FLAG_VALUE == 1
    4244      1675342 :           && trueop1 == const1_rtx
    4245       208392 :           && COMPARISON_P (op0)
    4246      1681959 :           && (reversed = reversed_comparison (op0, mode)))
    4247              :         return reversed;
    4248              : 
    4249              :       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
    4250              :          is (lt foo (const_int 0)), so we can perform the above
    4251              :          simplification if STORE_FLAG_VALUE is 1.  */
    4252              : 
    4253      1668733 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4254              :           && STORE_FLAG_VALUE == 1
    4255      1349216 :           && trueop1 == const1_rtx
    4256       201783 :           && GET_CODE (op0) == LSHIFTRT
    4257        36074 :           && CONST_INT_P (XEXP (op0, 1))
    4258        36074 :           && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    4259        34949 :         return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
    4260              : 
    4261              :       /* (xor (comparison foo bar) (const_int sign-bit))
    4262              :          when STORE_FLAG_VALUE is the sign bit.  */
    4263      1633784 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4264      1314267 :           && val_signbit_p (int_mode, STORE_FLAG_VALUE)
    4265            0 :           && trueop1 == const_true_rtx
    4266            0 :           && COMPARISON_P (op0)
    4267            0 :           && (reversed = reversed_comparison (op0, int_mode)))
    4268              :         return reversed;
    4269              : 
    4270              :       /* Convert (xor (and A C) (and B C)) into (and (xor A B) C).  */
    4271      1633784 :       if (GET_CODE (op0) == GET_CODE (op1)
    4272       568920 :           && (GET_CODE (op0) == AND
    4273       568920 :               || GET_CODE (op0) == LSHIFTRT
    4274       491573 :               || GET_CODE (op0) == ASHIFTRT
    4275       491473 :               || GET_CODE (op0) == ASHIFT
    4276       491345 :               || GET_CODE (op0) == ROTATE
    4277       491203 :               || GET_CODE (op0) == ROTATERT))
    4278              :         {
    4279        78251 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4280        78251 :           if (tem)
    4281              :             return tem;
    4282              :         }
    4283              : 
    4284              :       /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    4285              :          mode size to (rotate A CX).  */
    4286      1559286 :       tem = simplify_rotate_op (op0, op1, mode);
    4287      1559286 :       if (tem)
    4288              :         return tem;
    4289              : 
    4290              :       /* Convert (xor (and (not A) B) A) into A | B.  */
    4291      1557906 :       if (GET_CODE (op0) == AND
    4292      1557906 :           && negated_ops_p (XEXP (op0, 0), op1))
    4293            0 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4294              : 
    4295              :       /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
    4296              :          into B | (1 << A).  */
    4297      1557906 :       if (SHIFT_COUNT_TRUNCATED
    4298              :           && GET_CODE (op0) == AND
    4299              :           && GET_CODE (XEXP (op0, 0)) == ROTATE
    4300              :           && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4301              :           && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
    4302              :           && GET_CODE (op1) == ASHIFT
    4303              :           && CONST_INT_P (XEXP (op1, 0))
    4304              :           && INTVAL (XEXP (op1, 0)) == 1
    4305              :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
    4306              :           && !side_effects_p (XEXP (op1, 1)))
    4307              :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4308              : 
    4309      1557906 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4310      1557906 :       if (tem)
    4311              :         return tem;
    4312              : 
    4313      1557905 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4314      1557905 :       if (tem)
    4315              :         return tem;
    4316              : 
    4317      1557905 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4318      1557905 :       if (tem)
    4319              :         return tem;
    4320              :       break;
    4321              : 
    4322     24535039 :     case AND:
    4323     24535039 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    4324              :         return trueop1;
    4325     24252750 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4326              :         return op0;
    4327     23865795 :       if (HWI_COMPUTABLE_MODE_P (mode))
    4328              :         {
    4329              :           /* When WORD_REGISTER_OPERATIONS is true, we need to know the
    4330              :              nonzero bits in WORD_MODE rather than MODE.  */
    4331     20908385 :           scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
    4332     20908385 :           if (WORD_REGISTER_OPERATIONS
    4333              :               && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    4334              :             tmode = word_mode;
    4335     20908385 :           HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
    4336     20908385 :           HOST_WIDE_INT nzop1;
    4337     20908385 :           if (CONST_INT_P (trueop1))
    4338              :             {
    4339     17847448 :               HOST_WIDE_INT val1 = INTVAL (trueop1);
    4340              :               /* If we are turning off bits already known off in OP0, we need
    4341              :                  not do an AND.  */
    4342     17847448 :               if ((nzop0 & ~val1) == 0)
    4343       432424 :                 return op0;
    4344              : 
    4345              :               /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
    4346              :                  (and (lshiftrt (subreg X) shift) mask).
    4347              : 
    4348              :                  Keeps shift and AND in the same mode, improving recognition.
    4349              :                  Only applied when subreg is a lowpart, shift is valid,
    4350              :                  and no precision is lost.  */
    4351     17502000 :               if (SUBREG_P (op0)
    4352      6231713 :                   && subreg_lowpart_p (op0)
    4353      6214743 :                   && !paradoxical_subreg_p (op0)
    4354       790293 :                   && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    4355              :                   /* simplify_subreg asserts the object being accessed is not
    4356              :                      VOIDmode or BLKmode.  We may have a REG_EQUAL note which
    4357              :                      is not simplified and the source operand is a constant,
    4358              :                      and thus VOIDmode.  Guard against that.  */
    4359       117236 :                   && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
    4360       117186 :                   && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
    4361       117186 :                   && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4362       117186 :                   && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    4363        96107 :                   && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
    4364        96107 :                   && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
    4365     17598106 :                   && ((INTVAL (XEXP (XEXP (op0, 0), 1))
    4366        96106 :                       + floor_log2 (val1))
    4367     17502000 :                       < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
    4368              :                 {
    4369        13372 :                   tem = XEXP (XEXP (op0, 0), 0);
    4370        13372 :                   if (SUBREG_P (tem))
    4371              :                     {
    4372          288 :                       if (subreg_lowpart_p (tem))
    4373          288 :                         tem = SUBREG_REG (tem);
    4374              :                       else
    4375              :                         tem = NULL_RTX;
    4376              :                     }
    4377          288 :                   if (tem != NULL_RTX)
    4378              :                     {
    4379        13372 :                       offset = subreg_lowpart_offset (mode, GET_MODE (tem));
    4380        13372 :                       tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
    4381        13372 :                                                  offset);
    4382        13372 :                       if (tem)
    4383              :                         {
    4384        13372 :                           unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
    4385        13372 :                           rtx shiftamtrtx = gen_int_shift_amount (mode,
    4386        13372 :                                                                   shiftamt);
    4387        13372 :                           op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
    4388              :                                                      shiftamtrtx);
    4389        13372 :                           return simplify_gen_binary (AND, mode, op0, op1);
    4390              :                         }
    4391              :                     }
    4392              :                 }
    4393              :             }
    4394     20549565 :           nzop1 = nonzero_bits (trueop1, mode);
    4395              :           /* If we are clearing all the nonzero bits, the result is zero.  */
    4396     20549565 :           if ((nzop1 & nzop0) == 0
    4397     20549565 :               && !side_effects_p (op0) && !side_effects_p (op1))
    4398        73604 :             return CONST0_RTX (mode);
    4399              :         }
    4400     23437859 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
    4401     23437855 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4402              :         return op0;
    4403              :       /* A & (~A) -> 0 */
    4404       591010 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    4405     23425778 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    4406         3155 :           && ! side_effects_p (op0)
    4407     23432041 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4408         3154 :         return CONST0_RTX (mode);
    4409              : 
    4410              :       /* Convert (and (plus (A - 1)) (neg A)) to 0.  */
    4411     23425733 :       if (match_plus_neg_pattern (op0, op1, mode))
    4412            2 :         return CONST0_RTX (mode);
    4413              : 
    4414              :       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
    4415              :          there are no nonzero bits of C outside of X's mode.  */
    4416     46851462 :       if ((GET_CODE (op0) == SIGN_EXTEND
    4417     23425731 :            || GET_CODE (op0) == ZERO_EXTEND)
    4418        94404 :           && CONST_SCALAR_INT_P (trueop1)
    4419        81202 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4420        81202 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4421     23506933 :           && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
    4422        81202 :                         GET_MODE_PRECISION (int_mode))
    4423     23506933 :               & rtx_mode_t (trueop1, mode)) == 0)
    4424              :         {
    4425        79229 :           machine_mode imode = GET_MODE (XEXP (op0, 0));
    4426        79229 :           tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
    4427        79229 :           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
    4428        79229 :           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
    4429              :         }
    4430              : 
    4431              :       /* Transform (and (truncate X) C) into (truncate (and X C)).  This way
    4432              :          we might be able to further simplify the AND with X and potentially
    4433              :          remove the truncation altogether.  */
    4434     23346502 :       if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
    4435              :         {
    4436            6 :           rtx x = XEXP (op0, 0);
    4437            6 :           machine_mode xmode = GET_MODE (x);
    4438            6 :           tem = simplify_gen_binary (AND, xmode, x,
    4439            6 :                                      gen_int_mode (INTVAL (trueop1), xmode));
    4440            6 :           return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
    4441              :         }
    4442              : 
    4443              :       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
    4444     23346496 :       if (GET_CODE (op0) == IOR
    4445      1390932 :           && CONST_INT_P (trueop1)
    4446       216235 :           && CONST_INT_P (XEXP (op0, 1)))
    4447              :         {
    4448       132409 :           HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
    4449       132409 :           return simplify_gen_binary (IOR, mode,
    4450              :                                       simplify_gen_binary (AND, mode,
    4451              :                                                            XEXP (op0, 0), op1),
    4452       132409 :                                       gen_int_mode (tmp, mode));
    4453              :         }
    4454              : 
    4455              :       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
    4456              :          insn (and may simplify more).  */
    4457     23214087 :       if (GET_CODE (op0) == XOR
    4458       151693 :           && rtx_equal_p (XEXP (op0, 0), op1)
    4459     23215528 :           && ! side_effects_p (op1))
    4460         1441 :         return simplify_gen_binary (AND, mode,
    4461              :                                     simplify_gen_unary (NOT, mode,
    4462              :                                                         XEXP (op0, 1), mode),
    4463         1441 :                                     op1);
    4464              : 
    4465     23212646 :       if (GET_CODE (op0) == XOR
    4466       150252 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4467     23217424 :           && ! side_effects_p (op1))
    4468         4778 :         return simplify_gen_binary (AND, mode,
    4469              :                                     simplify_gen_unary (NOT, mode,
    4470              :                                                         XEXP (op0, 0), mode),
    4471         4778 :                                     op1);
    4472              : 
    4473              :       /* Similarly for (~(A ^ B)) & A.  */
    4474     23207868 :       if (GET_CODE (op0) == NOT
    4475       587902 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4476         3893 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
    4477     23207922 :           && ! side_effects_p (op1))
    4478           54 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
    4479              : 
    4480     23207814 :       if (GET_CODE (op0) == NOT
    4481       587848 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4482         3839 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
    4483     23207851 :           && ! side_effects_p (op1))
    4484           37 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
    4485              : 
    4486              :       /* Convert (A | B) & A to A.  */
    4487     23207777 :       if (GET_CODE (op0) == IOR
    4488      1258523 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    4489      1257996 :               || rtx_equal_p (XEXP (op0, 1), op1))
    4490          764 :           && ! side_effects_p (XEXP (op0, 0))
    4491     23208541 :           && ! side_effects_p (XEXP (op0, 1)))
    4492              :         return op1;
    4493              : 
    4494              :       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
    4495              :          ((A & N) + B) & M -> (A + B) & M
    4496              :          Similarly if (N & M) == 0,
    4497              :          ((A | N) + B) & M -> (A + B) & M
    4498              :          and for - instead of + and/or ^ instead of |.
    4499              :          Also, if (N & M) == 0, then
    4500              :          (A +- N) & M -> A & M.  */
    4501     23207013 :       if (CONST_INT_P (trueop1)
    4502     17297260 :           && HWI_COMPUTABLE_MODE_P (mode)
    4503     17275614 :           && ~UINTVAL (trueop1)
    4504     17275614 :           && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
    4505     34570505 :           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
    4506              :         {
    4507       971138 :           rtx pmop[2];
    4508       971138 :           int which;
    4509              : 
    4510       971138 :           pmop[0] = XEXP (op0, 0);
    4511       971138 :           pmop[1] = XEXP (op0, 1);
    4512              : 
    4513       971138 :           if (CONST_INT_P (pmop[1])
    4514       486280 :               && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
    4515       168264 :             return simplify_gen_binary (AND, mode, pmop[0], op1);
    4516              : 
    4517      2431596 :           for (which = 0; which < 2; which++)
    4518              :             {
    4519      1621064 :               tem = pmop[which];
    4520      1621064 :               switch (GET_CODE (tem))
    4521              :                 {
    4522        12117 :                 case AND:
    4523        12117 :                   if (CONST_INT_P (XEXP (tem, 1))
    4524        10631 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
    4525              :                       == UINTVAL (trueop1))
    4526         7651 :                     pmop[which] = XEXP (tem, 0);
    4527              :                   break;
    4528         1194 :                 case IOR:
    4529         1194 :                 case XOR:
    4530         1194 :                   if (CONST_INT_P (XEXP (tem, 1))
    4531          168 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
    4532            7 :                     pmop[which] = XEXP (tem, 0);
    4533              :                   break;
    4534              :                 default:
    4535              :                   break;
    4536              :                 }
    4537              :             }
    4538              : 
    4539       810532 :           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
    4540              :             {
    4541         7658 :               tem = simplify_gen_binary (GET_CODE (op0), mode,
    4542              :                                          pmop[0], pmop[1]);
    4543         7658 :               return simplify_gen_binary (code, mode, tem, op1);
    4544              :             }
    4545              :         }
    4546              : 
    4547              :       /* (and X (ior (not X) Y) -> (and X Y) */
    4548     23038749 :       if (GET_CODE (op1) == IOR
    4549       955340 :           && GET_CODE (XEXP (op1, 0)) == NOT
    4550     23043717 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
    4551            0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
    4552              : 
    4553              :       /* (and (ior (not X) Y) X) -> (and X Y) */
    4554     23038749 :       if (GET_CODE (op0) == IOR
    4555      1257759 :           && GET_CODE (XEXP (op0, 0)) == NOT
    4556     23085972 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
    4557            6 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
    4558              : 
    4559              :       /* (and X (ior Y (not X)) -> (and X Y) */
    4560     23038743 :       if (GET_CODE (op1) == IOR
    4561       955340 :           && GET_CODE (XEXP (op1, 1)) == NOT
    4562     23039325 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
    4563            0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
    4564              : 
    4565              :       /* (and (ior Y (not X)) X) -> (and X Y) */
    4566     23038743 :       if (GET_CODE (op0) == IOR
    4567      1257753 :           && GET_CODE (XEXP (op0, 1)) == NOT
    4568     23045573 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
    4569           78 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
    4570              : 
    4571              :       /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
    4572     23038665 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4573     23038665 :           && negated_ops_p (op1, XEXP (op0, 1)))
    4574          101 :         return simplify_gen_binary (AND, mode, XEXP (op0, 0),
    4575              :                                     simplify_gen_unary (NOT, mode,
    4576              :                                                         XEXP (op0, 1),
    4577          101 :                                                         mode));
    4578              :       /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
    4579     23038564 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4580     23038564 :           && negated_ops_p (op1, XEXP (op0, 0)))
    4581            2 :         return simplify_gen_binary (AND, mode, XEXP (op0, 1),
    4582              :                                     simplify_gen_unary (NOT, mode,
    4583              :                                                         XEXP (op0, 0),
    4584            2 :                                                         mode));
    4585              : 
    4586              :       /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C).  */
    4587     23038562 :       if (GET_CODE (op0) == GET_CODE (op1)
    4588      2215890 :           && (GET_CODE (op0) == AND
    4589              :               || GET_CODE (op0) == IOR
    4590      2215890 :               || GET_CODE (op0) == LSHIFTRT
    4591      1261057 :               || GET_CODE (op0) == ASHIFTRT
    4592      1260905 :               || GET_CODE (op0) == ASHIFT
    4593      1260736 :               || GET_CODE (op0) == ROTATE
    4594      1260736 :               || GET_CODE (op0) == ROTATERT))
    4595              :         {
    4596       955154 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4597       955154 :           if (tem)
    4598              :             return tem;
    4599              :         }
    4600              : 
    4601              :       /* (and:v4si
    4602              :            (ashiftrt:v4si A 16)
    4603              :            (const_vector: 0xffff x4))
    4604              :          is just (lshiftrt:v4si A 16).  */
    4605     22128430 :       if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
    4606         4860 :           && (CONST_INT_P (XEXP (op0, 1))
    4607         2035 :               || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
    4608           94 :                   && const_vec_duplicate_p (XEXP (op0, 1))
    4609            0 :                   && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
    4610         2825 :           && GET_CODE (op1) == CONST_VECTOR
    4611     22128464 :           && const_vec_duplicate_p (op1)
    4612     22128506 :           && CONST_INT_P (XVECEXP (op1, 0, 0)))
    4613              :         {
    4614          148 :           unsigned HOST_WIDE_INT shift_count
    4615              :             = (CONST_INT_P (XEXP (op0, 1))
    4616           74 :                ? UINTVAL (XEXP (op0, 1))
    4617            0 :                : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
    4618           74 :           unsigned HOST_WIDE_INT inner_prec
    4619          148 :             = GET_MODE_PRECISION (GET_MODE_INNER (mode));
    4620              : 
    4621              :           /* Avoid UD shift count.  */
    4622           74 :           if (shift_count < inner_prec
    4623           62 :               && (UINTVAL (XVECEXP (op1, 0, 0))
    4624           62 :                   == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
    4625           42 :             return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
    4626              :         }
    4627              : 
    4628     22128388 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4629     22128388 :       if (tem)
    4630              :         return tem;
    4631              : 
    4632     22125893 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4633     22125893 :       if (tem)
    4634              :         return tem;
    4635              : 
    4636     22125672 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4637     22125672 :       if (tem)
    4638              :         return tem;
    4639              :       break;
    4640              : 
    4641       898722 :     case UDIV:
    4642              :       /* 0/x is 0 (or x&0 if x has side-effects).  */
    4643       898722 :       if (trueop0 == CONST0_RTX (mode)
    4644          377 :           && !cfun->can_throw_non_call_exceptions)
    4645              :         {
    4646          377 :           if (side_effects_p (op1))
    4647            0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4648              :           return trueop0;
    4649              :         }
    4650              :       /* x/1 is x.  */
    4651       898345 :       if (trueop1 == CONST1_RTX (mode))
    4652              :         {
    4653       242062 :           tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4654       242062 :           if (tem)
    4655              :             return tem;
    4656              :         }
    4657              :       /* Convert divide by power of two into shift.  */
    4658       656283 :       if (CONST_INT_P (trueop1)
    4659       979027 :           && (val = exact_log2 (UINTVAL (trueop1))) > 0)
    4660       322744 :         return simplify_gen_binary (LSHIFTRT, mode, op0,
    4661       322744 :                                     gen_int_shift_amount (mode, val));
    4662              :       break;
    4663              : 
    4664      1424562 :     case DIV:
    4665              :       /* Handle floating point and integers separately.  */
    4666      1424562 :       if (SCALAR_FLOAT_MODE_P (mode))
    4667              :         {
    4668              :           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
    4669              :              safe for modes with NaNs, since 0.0 / 0.0 will then be
    4670              :              NaN rather than 0.0.  Nor is it safe for modes with signed
    4671              :              zeros, since dividing 0 by a negative number gives -0.0  */
    4672       327568 :           if (trueop0 == CONST0_RTX (mode)
    4673         2818 :               && !HONOR_NANS (mode)
    4674           14 :               && !HONOR_SIGNED_ZEROS (mode)
    4675       327582 :               && ! side_effects_p (op1))
    4676              :             return op0;
    4677              :           /* x/1.0 is x.  */
    4678       327554 :           if (trueop1 == CONST1_RTX (mode)
    4679       327554 :               && !HONOR_SNANS (mode))
    4680              :             return op0;
    4681              : 
    4682       327550 :           if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    4683        28230 :               && trueop1 != CONST0_RTX (mode))
    4684              :             {
    4685        22114 :               const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    4686              : 
    4687              :               /* x/-1.0 is -x.  */
    4688        22114 :               if (real_equal (d1, &dconstm1)
    4689        22114 :                   && !HONOR_SNANS (mode))
    4690            0 :                 return simplify_gen_unary (NEG, mode, op0, mode);
    4691              : 
    4692              :               /* Change FP division by a constant into multiplication.
    4693              :                  Only do this with -freciprocal-math.  */
    4694        22114 :               if (flag_reciprocal_math
    4695        22114 :                   && !real_equal (d1, &dconst0))
    4696              :                 {
    4697            7 :                   REAL_VALUE_TYPE d;
    4698            7 :                   real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
    4699            7 :                   tem = const_double_from_real_value (d, mode);
    4700            7 :                   return simplify_gen_binary (MULT, mode, op0, tem);
    4701              :                 }
    4702              :             }
    4703              :         }
    4704      1096994 :       else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    4705              :         {
    4706              :           /* 0/x is 0 (or x&0 if x has side-effects).  */
    4707      1065489 :           if (trueop0 == CONST0_RTX (mode)
    4708          985 :               && !cfun->can_throw_non_call_exceptions)
    4709              :             {
    4710          931 :               if (side_effects_p (op1))
    4711            8 :                 return simplify_gen_binary (AND, mode, op1, trueop0);
    4712              :               return trueop0;
    4713              :             }
    4714              :           /* x/1 is x.  */
    4715      1064558 :           if (trueop1 == CONST1_RTX (mode))
    4716              :             {
    4717           85 :               tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4718           85 :               if (tem)
    4719              :                 return tem;
    4720              :             }
    4721              :           /* x/-1 is -x.  */
    4722      1064473 :           if (trueop1 == CONSTM1_RTX (mode))
    4723              :             {
    4724          554 :               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4725          554 :               if (x)
    4726          554 :                 return simplify_gen_unary (NEG, mode, x, mode);
    4727              :             }
    4728              :         }
    4729              :       break;
    4730              : 
    4731       918415 :     case UMOD:
    4732              :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4733       918415 :       if (trueop0 == CONST0_RTX (mode))
    4734              :         {
    4735          933 :           if (side_effects_p (op1))
    4736            0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4737              :           return trueop0;
    4738              :         }
    4739              :       /* x%1 is 0 (of x&0 if x has side-effects).  */
    4740       917482 :       if (trueop1 == CONST1_RTX (mode))
    4741              :         {
    4742       274669 :           if (side_effects_p (op0))
    4743            0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4744       274669 :           return CONST0_RTX (mode);
    4745              :         }
    4746              :       /* Implement modulus by power of two as AND.  */
    4747       642813 :       if (CONST_INT_P (trueop1)
    4748       938993 :           && exact_log2 (UINTVAL (trueop1)) > 0)
    4749       296180 :         return simplify_gen_binary (AND, mode, op0,
    4750       296180 :                                     gen_int_mode (UINTVAL (trueop1) - 1,
    4751              :                                                   mode));
    4752              :       break;
    4753              : 
    4754       576763 :     case MOD:
    4755              :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4756       576763 :       if (trueop0 == CONST0_RTX (mode))
    4757              :         {
    4758         1219 :           if (side_effects_p (op1))
    4759            8 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4760              :           return trueop0;
    4761              :         }
    4762              :       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
    4763       575544 :       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
    4764              :         {
    4765          557 :           if (side_effects_p (op0))
    4766            0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4767          557 :           return CONST0_RTX (mode);
    4768              :         }
    4769              :       break;
    4770              : 
    4771       141141 :     case ROTATERT:
    4772       141141 :     case ROTATE:
    4773       141141 :       if (trueop1 == CONST0_RTX (mode))
    4774              :         return op0;
    4775              :       /* Canonicalize rotates by constant amount.  If the condition of
    4776              :          reversing direction is met, then reverse the direction. */
    4777              : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
    4778       141051 :       if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
    4779              :         {
    4780        12256 :           int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
    4781        12256 :           rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
    4782        12990 :           return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
    4783              :                                       mode, op0, new_amount_rtx);
    4784              :         }
    4785              : #endif
    4786              :       /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X).  Other combinations
    4787              :          such as SImode with a count of 16 do not correspond to RTL BSWAP
    4788              :          semantics.  */
    4789       128795 :       tem = unwrap_const_vec_duplicate (trueop1);
    4790       128795 :       if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
    4791       128795 :           && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
    4792          674 :         return simplify_gen_unary (BSWAP, mode, op0, mode);
    4793              : 
    4794              :       /* FALLTHRU */
    4795      5457117 :     case ASHIFTRT:
    4796      5457117 :       if (trueop1 == CONST0_RTX (mode))
    4797              :         return op0;
    4798      5454852 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4799              :         return op0;
    4800              :       /* Rotating ~0 always results in ~0.  */
    4801      5454679 :       if (CONST_INT_P (trueop0)
    4802        15469 :           && HWI_COMPUTABLE_MODE_P (mode)
    4803        15441 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4804      5454679 :           && ! side_effects_p (op1))
    4805              :         return op0;
    4806              : 
    4807     32036817 :     canonicalize_shift:
    4808              :       /* Given:
    4809              :          scalar modes M1, M2
    4810              :          scalar constants c1, c2
    4811              :          size (M2) > size (M1)
    4812              :          c1 == size (M2) - size (M1)
    4813              :          optimize:
    4814              :          ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
    4815              :                                  <low_part>)
    4816              :                       (const_int <c2>))
    4817              :          to:
    4818              :          (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
    4819              :                     <low_part>).  */
    4820     32036817 :       if ((code == ASHIFTRT || code == LSHIFTRT)
    4821     12213126 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4822     11407472 :           && SUBREG_P (op0)
    4823      1240296 :           && CONST_INT_P (op1)
    4824      1236898 :           && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
    4825        18937 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
    4826              :                                      &inner_mode)
    4827        18937 :           && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
    4828        37488 :           && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
    4829        18744 :           && (INTVAL (XEXP (SUBREG_REG (op0), 1))
    4830        37488 :               == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
    4831     32055331 :           && subreg_lowpart_p (op0))
    4832              :         {
    4833        18514 :           rtx tmp = gen_int_shift_amount
    4834        18514 :             (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
    4835              : 
    4836              :          /* Combine would usually zero out the value when combining two
    4837              :             local shifts and the range becomes larger or equal to the mode.
    4838              :             However since we fold away one of the shifts here combine won't
    4839              :             see it so we should immediately zero the result if it's out of
    4840              :             range.  */
    4841        18514 :          if (code == LSHIFTRT
    4842        33510 :              && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
    4843            0 :           tmp = const0_rtx;
    4844              :          else
    4845        18514 :            tmp = simplify_gen_binary (code,
    4846              :                                       inner_mode,
    4847        18514 :                                       XEXP (SUBREG_REG (op0), 0),
    4848              :                                       tmp);
    4849              : 
    4850        18514 :           return lowpart_subreg (int_mode, tmp, inner_mode);
    4851              :         }
    4852              : 
    4853     32018303 :       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
    4854              :         {
    4855              :           val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
    4856              :           if (val != INTVAL (op1))
    4857              :             return simplify_gen_binary (code, mode, op0,
    4858              :                                         gen_int_shift_amount (mode, val));
    4859              :         }
    4860              : 
    4861              :       /* Simplify:
    4862              : 
    4863              :            (code:M1
    4864              :              (subreg:M1
    4865              :                ([al]shiftrt:M2
    4866              :                  (subreg:M2
    4867              :                    (ashift:M1 X C1))
    4868              :                  C2))
    4869              :              C3)
    4870              : 
    4871              :          to:
    4872              : 
    4873              :            (code:M1
    4874              :              ([al]shiftrt:M1
    4875              :                (ashift:M1 X C1+N)
    4876              :                C2+N)
    4877              :              C3)
    4878              : 
    4879              :          where M1 is N bits wider than M2.  Optimizing the (subreg:M1 ...)
    4880              :          directly would be arithmetically correct, but restricting the
    4881              :          simplification to shifts by constants is more conservative,
    4882              :          since it is more likely to lead to further simplifications.  */
    4883     32018303 :       if (is_a<scalar_int_mode> (mode, &int_mode)
    4884      5735421 :           && paradoxical_subreg_p (op0)
    4885      5215506 :           && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
    4886      5191462 :           && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
    4887      5191462 :               || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
    4888       157708 :           && CONST_INT_P (op1))
    4889              :         {
    4890       157708 :           auto xcode = GET_CODE (SUBREG_REG (op0));
    4891       157708 :           rtx xop0 = XEXP (SUBREG_REG (op0), 0);
    4892       157708 :           rtx xop1 = XEXP (SUBREG_REG (op0), 1);
    4893       157708 :           if (SUBREG_P (xop0)
    4894        11369 :               && GET_MODE (SUBREG_REG (xop0)) == mode
    4895        11224 :               && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
    4896          596 :               && CONST_INT_P (xop1)
    4897       158304 :               && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
    4898              :             {
    4899          596 :               rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
    4900          596 :               rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
    4901          596 :               if (CONST_INT_P (yop1)
    4902          596 :                   && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
    4903              :                 {
    4904         1192 :                   auto bias = (GET_MODE_BITSIZE (int_mode)
    4905          596 :                                - GET_MODE_BITSIZE (inner_mode));
    4906          596 :                   tem = simplify_gen_binary (ASHIFT, mode, yop0,
    4907          596 :                                              GEN_INT (INTVAL (yop1) + bias));
    4908          596 :                   tem = simplify_gen_binary (xcode, mode, tem,
    4909          596 :                                              GEN_INT (INTVAL (xop1) + bias));
    4910          596 :                   return simplify_gen_binary (code, mode, tem, op1);
    4911              :                 }
    4912              :             }
    4913              :         }
    4914              :       break;
    4915              : 
    4916            0 :     case SS_ASHIFT:
    4917            0 :       if (CONST_INT_P (trueop0)
    4918            0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4919            0 :           && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
    4920            0 :               || mode_signbit_p (mode, trueop0))
    4921            0 :           && ! side_effects_p (op1))
    4922              :         return op0;
    4923            0 :       goto simplify_ashift;
    4924              : 
    4925            0 :     case US_ASHIFT:
    4926            0 :       if (CONST_INT_P (trueop0)
    4927            0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4928            0 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4929            0 :           && ! side_effects_p (op1))
    4930              :         return op0;
    4931              :       /* FALLTHRU */
    4932              : 
    4933     20132448 :     case ASHIFT:
    4934     20132448 : simplify_ashift:
    4935     20132448 :       if (trueop1 == CONST0_RTX (mode))
    4936              :         return op0;
    4937     19962886 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4938              :         return op0;
    4939     19933147 :       if (mem_depth
    4940       237546 :           && code == ASHIFT
    4941       237546 :           && CONST_INT_P (trueop1)
    4942       237538 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4943     20170673 :           && IN_RANGE (UINTVAL (trueop1),
    4944              :                        1, GET_MODE_PRECISION (int_mode) - 1))
    4945              :         {
    4946       237526 :           auto c = (wi::one (GET_MODE_PRECISION (int_mode))
    4947       237526 :                     << UINTVAL (trueop1));
    4948       237526 :           rtx new_op1 = immed_wide_int_const (c, int_mode);
    4949       237526 :           return simplify_gen_binary (MULT, int_mode, op0, new_op1);
    4950       237526 :         }
    4951              : 
    4952              :       /* If we're shifting left a signed bitfield extraction and the
    4953              :          shift count + bitfield size is a natural integral mode and
    4954              :          the field starts at offset 0 (counting from the LSB), then
    4955              :          this can be simplified to a sign extension of a left shift.
    4956              : 
    4957              :          Some ISAs (RISC-V 64-bit) have inherent support for such
    4958              :          instructions and it's better for various optimizations to
    4959              :          express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT.  */
    4960     19695621 :       if (GET_CODE (op0) == SIGN_EXTRACT
    4961           28 :           && REG_P (XEXP (op0, 0))
    4962              :           /* The size of the bitfield, the location of the bitfield and
    4963              :              shift count must be CONST_INTs.  */
    4964           22 :           && CONST_INT_P (op1)
    4965           22 :           && CONST_INT_P (XEXP (op0, 1))
    4966           22 :           && CONST_INT_P (XEXP (op0, 2)))
    4967              :         {
    4968           22 :           int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
    4969           22 :           machine_mode smaller_mode;
    4970              :           /* Now we need to verify the size of the bitfield plus the shift
    4971              :              count is an integral mode and smaller than MODE.  This is
    4972              :              requirement for using SIGN_EXTEND.  We also need to verify the
    4973              :              field starts at bit location 0 and that the subreg lowpart also
    4974              :              starts at zero.  */
    4975           22 :           if (int_mode_for_size (size, size).exists (&smaller_mode)
    4976            3 :               && mode > smaller_mode
    4977           22 :               && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
    4978            3 :                   == UINTVAL (XEXP (op0, 2)))
    4979            1 :               && XEXP (op0, 2) == CONST0_RTX (mode))
    4980              :             {
    4981              :               /* Everything passed.  So we just need to get the subreg of the
    4982              :                  original input, shift it and sign extend the result.  */
    4983            1 :               rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
    4984            1 :               rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
    4985            1 :               return gen_rtx_SIGN_EXTEND (mode, x);
    4986              :             }
    4987              :         }
    4988     19695620 :       goto canonicalize_shift;
    4989              : 
    4990      8731557 :     case LSHIFTRT:
    4991      8731557 :       if (trueop1 == CONST0_RTX (mode))
    4992              :         return op0;
    4993      6888113 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4994              :         return op0;
    4995              :       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
    4996      6886518 :       if (GET_CODE (op0) == CLZ
    4997            0 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4998            0 :           && CONST_INT_P (trueop1)
    4999              :           && STORE_FLAG_VALUE == 1
    5000      6886518 :           && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
    5001              :         {
    5002            0 :           unsigned HOST_WIDE_INT zero_val = 0;
    5003              : 
    5004            0 :           if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
    5005            0 :               && zero_val == GET_MODE_PRECISION (inner_mode)
    5006            0 :               && INTVAL (trueop1) == exact_log2 (zero_val))
    5007            0 :             return simplify_gen_relational (EQ, mode, inner_mode,
    5008            0 :                                             XEXP (op0, 0), const0_rtx);
    5009              :         }
    5010      6886518 :       goto canonicalize_shift;
    5011              : 
    5012       240502 :     case SMIN:
    5013       240502 :       if (HWI_COMPUTABLE_MODE_P (mode)
    5014       219609 :           && mode_signbit_p (mode, trueop1)
    5015            0 :           && ! side_effects_p (op0))
    5016              :         return op1;
    5017       240502 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5018              :         return op0;
    5019       240324 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5020       240324 :       if (tem)
    5021              :         return tem;
    5022              :       break;
    5023              : 
    5024       709279 :     case SMAX:
    5025       709279 :       if (HWI_COMPUTABLE_MODE_P (mode)
    5026       681600 :           && CONST_INT_P (trueop1)
    5027       649382 :           && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
    5028            0 :           && ! side_effects_p (op0))
    5029              :         return op1;
    5030       709279 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5031              :         return op0;
    5032       709172 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5033       709172 :       if (tem)
    5034              :         return tem;
    5035              :       break;
    5036              : 
    5037       352404 :     case UMIN:
    5038       352404 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    5039              :         return op1;
    5040       352392 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5041              :         return op0;
    5042       352274 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5043       352274 :       if (tem)
    5044              :         return tem;
    5045              :       break;
    5046              : 
    5047       291998 :     case UMAX:
    5048       291998 :       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
    5049              :         return op1;
    5050       291998 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5051              :         return op0;
    5052       291908 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5053       291908 :       if (tem)
    5054              :         return tem;
    5055              :       break;
    5056              : 
    5057        12109 :     case SS_PLUS:
    5058        12109 :     case US_PLUS:
    5059        12109 :     case SS_MINUS:
    5060        12109 :     case US_MINUS:
    5061              :       /* Simplify x +/- 0 to x, if possible.  */
    5062        12109 :       if (trueop1 == CONST0_RTX (mode))
    5063            0 :         return op0;
    5064              :       return 0;
    5065              : 
    5066            0 :     case SS_MULT:
    5067            0 :     case US_MULT:
    5068              :       /* Simplify x * 0 to 0, if possible.  */
    5069            0 :       if (trueop1 == CONST0_RTX (mode)
    5070            0 :           && !side_effects_p (op0))
    5071              :         return op1;
    5072              : 
    5073              :       /* Simplify x * 1 to x, if possible.  */
    5074            0 :       if (trueop1 == CONST1_RTX (mode))
    5075            0 :         return op0;
    5076              :       return 0;
    5077              : 
    5078       518436 :     case SMUL_HIGHPART:
    5079       518436 :     case UMUL_HIGHPART:
    5080              :       /* Simplify x * 0 to 0, if possible.  */
    5081       518436 :       if (trueop1 == CONST0_RTX (mode)
    5082       518436 :           && !side_effects_p (op0))
    5083           78 :         return op1;
    5084              :       return 0;
    5085              : 
    5086            0 :     case SS_DIV:
    5087            0 :     case US_DIV:
    5088              :       /* Simplify x / 1 to x, if possible.  */
    5089            0 :       if (trueop1 == CONST1_RTX (mode))
    5090            0 :         return op0;
    5091              :       return 0;
    5092              : 
    5093            0 :     case COPYSIGN:
    5094            0 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5095              :         return op0;
    5096            0 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5097              :         {
    5098            0 :           REAL_VALUE_TYPE f1;
    5099            0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
    5100            0 :           rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
    5101            0 :           if (REAL_VALUE_NEGATIVE (f1))
    5102            0 :             tmp = simplify_unary_operation (NEG, mode, tmp, mode);
    5103            0 :           return tmp;
    5104              :         }
    5105            0 :       if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
    5106            0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    5107            0 :       if (GET_CODE (op1) == ABS
    5108            0 :           && ! side_effects_p (op1))
    5109            0 :         return simplify_gen_unary (ABS, mode, op0, mode);
    5110            0 :       if (GET_CODE (op0) == COPYSIGN
    5111            0 :           && ! side_effects_p (XEXP (op0, 1)))
    5112            0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    5113            0 :       if (GET_CODE (op1) == COPYSIGN
    5114            0 :           && ! side_effects_p (XEXP (op1, 0)))
    5115            0 :         return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
    5116              :       return 0;
    5117              : 
    5118         1112 :     case VEC_SERIES:
    5119         2224 :       if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
    5120           92 :         return gen_vec_duplicate (mode, op0);
    5121         1020 :       if (valid_for_const_vector_p (mode, op0)
    5122         1020 :           && valid_for_const_vector_p (mode, op1))
    5123           93 :         return gen_const_vec_series (mode, op0, op1);
    5124              :       return 0;
    5125              : 
    5126      3974018 :     case VEC_SELECT:
    5127      3974018 :       if (!VECTOR_MODE_P (mode))
    5128              :         {
    5129      1051497 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    5130      2102994 :           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
    5131      1051497 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    5132      1051497 :           gcc_assert (XVECLEN (trueop1, 0) == 1);
    5133              : 
    5134              :           /* We can't reason about selections made at runtime.  */
    5135      1051497 :           if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5136    459915835 :             return 0;
    5137              : 
    5138      1051497 :           if (vec_duplicate_p (trueop0, &elt0))
    5139         2132 :             return elt0;
    5140              : 
    5141      1049365 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    5142         7255 :             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
    5143              :                                                       (trueop1, 0, 0)));
    5144              : 
    5145              :           /* Extract a scalar element from a nested VEC_SELECT expression
    5146              :              (with optional nested VEC_CONCAT expression).  Some targets
    5147              :              (i386) extract scalar element from a vector using chain of
    5148              :              nested VEC_SELECT expressions.  When input operand is a memory
    5149              :              operand, this operation can be simplified to a simple scalar
    5150              :              load from an offsetted memory address.  */
    5151      1042110 :           int n_elts;
    5152      1042110 :           if (GET_CODE (trueop0) == VEC_SELECT
    5153      1117079 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5154        74969 :                   .is_constant (&n_elts)))
    5155              :             {
    5156        74969 :               rtx op0 = XEXP (trueop0, 0);
    5157        74969 :               rtx op1 = XEXP (trueop0, 1);
    5158              : 
    5159        74969 :               int i = INTVAL (XVECEXP (trueop1, 0, 0));
    5160        74969 :               int elem;
    5161              : 
    5162        74969 :               rtvec vec;
    5163        74969 :               rtx tmp_op, tmp;
    5164              : 
    5165        74969 :               gcc_assert (GET_CODE (op1) == PARALLEL);
    5166        74969 :               gcc_assert (i < XVECLEN (op1, 0));
    5167              : 
    5168              :               /* Select element, pointed by nested selector.  */
    5169        74969 :               elem = INTVAL (XVECEXP (op1, 0, i));
    5170              : 
    5171        74969 :               gcc_assert (elem < n_elts);
    5172              : 
    5173              :               /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
    5174        74969 :               if (GET_CODE (op0) == VEC_CONCAT)
    5175              :                 {
    5176        30972 :                   rtx op00 = XEXP (op0, 0);
    5177        30972 :                   rtx op01 = XEXP (op0, 1);
    5178              : 
    5179        30972 :                   machine_mode mode00, mode01;
    5180        30972 :                   int n_elts00, n_elts01;
    5181              : 
    5182        30972 :                   mode00 = GET_MODE (op00);
    5183        30972 :                   mode01 = GET_MODE (op01);
    5184              : 
    5185              :                   /* Find out the number of elements of each operand.
    5186              :                      Since the concatenated result has a constant number
    5187              :                      of elements, the operands must too.  */
    5188        30972 :                   n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
    5189        30972 :                   n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
    5190              : 
    5191        30972 :                   gcc_assert (n_elts == n_elts00 + n_elts01);
    5192              : 
    5193              :                   /* Select correct operand of VEC_CONCAT
    5194              :                      and adjust selector. */
    5195        30972 :                   if (elem < n_elts01)
    5196              :                     tmp_op = op00;
    5197              :                   else
    5198              :                     {
    5199           53 :                       tmp_op = op01;
    5200           53 :                       elem -= n_elts00;
    5201              :                     }
    5202              :                 }
    5203              :               else
    5204              :                 tmp_op = op0;
    5205              : 
    5206        74969 :               vec = rtvec_alloc (1);
    5207        74969 :               RTVEC_ELT (vec, 0) = GEN_INT (elem);
    5208              : 
    5209        74969 :               tmp = gen_rtx_fmt_ee (code, mode,
    5210              :                                     tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
    5211        74969 :               return tmp;
    5212              :             }
    5213              :           /* If we select one half of a vec_concat, return that.  */
    5214       967141 :           else if (GET_CODE (trueop0) == VEC_CONCAT)
    5215              :             {
    5216         1542 :               rtx subop0 = XEXP (trueop0, 0);
    5217         1542 :               rtx subop1 = XEXP (trueop0, 1);
    5218         1542 :               machine_mode mode0 = GET_MODE (subop0);
    5219         1542 :               machine_mode mode1 = GET_MODE (subop1);
    5220         1542 :               int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5221         1542 :               if (i0 == 0 && mode == mode0 && !side_effects_p (subop1))
    5222    459915835 :                 return subop0;
    5223         1132 :               if (known_eq (i0, GET_MODE_NUNITS (mode0))
    5224          566 :                   && mode == mode1 && !side_effects_p (subop0))
    5225              :                 return subop1;
    5226              :             }
    5227              :         }
    5228              :       else
    5229              :         {
    5230      2922521 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    5231      8767563 :           gcc_assert (GET_MODE_INNER (mode)
    5232              :                       == GET_MODE_INNER (GET_MODE (trueop0)));
    5233      2922521 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    5234              : 
    5235      2922521 :           if (vec_duplicate_p (trueop0, &elt0))
    5236              :             /* It doesn't matter which elements are selected by trueop1,
    5237              :                because they are all the same.  */
    5238        17594 :             return gen_vec_duplicate (mode, elt0);
    5239              : 
    5240      2904927 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    5241              :             {
    5242        18045 :               unsigned n_elts = XVECLEN (trueop1, 0);
    5243        18045 :               rtvec v = rtvec_alloc (n_elts);
    5244        18045 :               unsigned int i;
    5245              : 
    5246        36090 :               gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
    5247        83493 :               for (i = 0; i < n_elts; i++)
    5248              :                 {
    5249        65448 :                   rtx x = XVECEXP (trueop1, 0, i);
    5250              : 
    5251        65448 :                   if (!CONST_INT_P (x))
    5252              :                     return 0;
    5253              : 
    5254        65448 :                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
    5255              :                                                        INTVAL (x));
    5256              :                 }
    5257              : 
    5258        18045 :               return gen_rtx_CONST_VECTOR (mode, v);
    5259              :             }
    5260              : 
    5261              :           /* Recognize the identity.  */
    5262      2886882 :           if (GET_MODE (trueop0) == mode)
    5263              :             {
    5264       617758 :               bool maybe_ident = true;
    5265       617758 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5266              :                 {
    5267       617381 :                   rtx j = XVECEXP (trueop1, 0, i);
    5268       617381 :                   if (!CONST_INT_P (j) || INTVAL (j) != i)
    5269              :                     {
    5270              :                       maybe_ident = false;
    5271              :                       break;
    5272              :                     }
    5273              :                 }
    5274       381776 :               if (maybe_ident)
    5275              :                 return trueop0;
    5276              :             }
    5277              : 
    5278              :           /* If we select a low-part subreg, return that.  */
    5279      2886505 :           if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
    5280              :             {
    5281            0 :               rtx new_rtx = lowpart_subreg (mode, trueop0,
    5282            0 :                                             GET_MODE (trueop0));
    5283            0 :               if (new_rtx != NULL_RTX)
    5284              :                 return new_rtx;
    5285              :             }
    5286              : 
    5287              :           /* If we build {a,b} then permute it, build the result directly.  */
    5288      2886505 :           if (XVECLEN (trueop1, 0) == 2
    5289       598183 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5290       598183 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    5291       598183 :               && GET_CODE (trueop0) == VEC_CONCAT
    5292       177092 :               && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
    5293           75 :               && GET_MODE (XEXP (trueop0, 0)) == mode
    5294           75 :               && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
    5295           64 :               && GET_MODE (XEXP (trueop0, 1)) == mode)
    5296              :             {
    5297           64 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5298           64 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5299           64 :               rtx subop0, subop1;
    5300              : 
    5301           64 :               gcc_assert (i0 < 4 && i1 < 4);
    5302           64 :               subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
    5303           64 :               subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
    5304              : 
    5305           64 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5306              :             }
    5307              : 
    5308      2886441 :           if (XVECLEN (trueop1, 0) == 2
    5309       598119 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5310       598119 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    5311       598119 :               && GET_CODE (trueop0) == VEC_CONCAT
    5312       177028 :               && GET_MODE (trueop0) == mode)
    5313              :             {
    5314            2 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5315            2 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5316            2 :               rtx subop0, subop1;
    5317              : 
    5318            2 :               gcc_assert (i0 < 2 && i1 < 2);
    5319            2 :               subop0 = XEXP (trueop0, i0);
    5320            2 :               subop1 = XEXP (trueop0, i1);
    5321              : 
    5322            2 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5323              :             }
    5324              : 
    5325              :           /* If we select one half of a vec_concat, return that.  */
    5326      2886439 :           int l0, l1;
    5327      2886439 :           if (GET_CODE (trueop0) == VEC_CONCAT
    5328      3854506 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5329      1927253 :                   .is_constant (&l0))
    5330      3854506 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
    5331      1927253 :                   .is_constant (&l1))
    5332      4813692 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5333              :             {
    5334      1927253 :               rtx subop0 = XEXP (trueop0, 0);
    5335      1927253 :               rtx subop1 = XEXP (trueop0, 1);
    5336      1927253 :               machine_mode mode0 = GET_MODE (subop0);
    5337      1927253 :               machine_mode mode1 = GET_MODE (subop1);
    5338      1927253 :               int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5339      1927253 :               if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
    5340              :                 {
    5341      1494580 :                   bool success = true;
    5342      1494580 :                   for (int i = 1; i < l0; ++i)
    5343              :                     {
    5344      1494262 :                       rtx j = XVECEXP (trueop1, 0, i);
    5345      1494262 :                       if (!CONST_INT_P (j) || INTVAL (j) != i)
    5346              :                         {
    5347              :                           success = false;
    5348              :                           break;
    5349              :                         }
    5350              :                     }
    5351      1262455 :                   if (success)
    5352              :                     return subop0;
    5353              :                 }
    5354      1926935 :               if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
    5355              :                 {
    5356          590 :                   bool success = true;
    5357          590 :                   for (int i = 1; i < l1; ++i)
    5358              :                     {
    5359          543 :                       rtx j = XVECEXP (trueop1, 0, i);
    5360          543 :                       if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
    5361              :                         {
    5362              :                           success = false;
    5363              :                           break;
    5364              :                         }
    5365              :                     }
    5366           76 :                   if (success)
    5367              :                     return subop1;
    5368              :                 }
    5369              :             }
    5370              : 
    5371              :           /* Simplify vec_select of a subreg of X to just a vec_select of X
    5372              :              when X has same component mode as vec_select.  */
    5373      2886074 :           unsigned HOST_WIDE_INT subreg_offset = 0;
    5374      2886074 :           if (GET_CODE (trueop0) == SUBREG
    5375       370894 :               && GET_MODE_INNER (mode)
    5376       741788 :                  == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
    5377        29990 :               && GET_MODE_NUNITS (mode).is_constant (&l1)
    5378      3256968 :               && constant_multiple_p (subreg_memory_offset (trueop0),
    5379        29990 :                                       GET_MODE_UNIT_BITSIZE (mode),
    5380              :                                       &subreg_offset))
    5381              :             {
    5382        14995 :               poly_uint64 nunits
    5383        29990 :                 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
    5384        14995 :               bool success = true;
    5385        92021 :               for (int i = 0; i != l1; i++)
    5386              :                 {
    5387        87375 :                   rtx idx = XVECEXP (trueop1, 0, i);
    5388        87375 :                   if (!CONST_INT_P (idx)
    5389        87375 :                       || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
    5390              :                     {
    5391              :                       success = false;
    5392              :                       break;
    5393              :                     }
    5394              :                 }
    5395              : 
    5396        14995 :               if (success)
    5397              :                 {
    5398         4646 :                   rtx par = trueop1;
    5399         4646 :                   if (subreg_offset)
    5400              :                     {
    5401            0 :                       rtvec vec = rtvec_alloc (l1);
    5402            0 :                       for (int i = 0; i < l1; i++)
    5403            0 :                         RTVEC_ELT (vec, i)
    5404            0 :                           = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
    5405              :                                      + subreg_offset);
    5406            0 :                       par = gen_rtx_PARALLEL (VOIDmode, vec);
    5407              :                     }
    5408         4646 :                   return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
    5409              :                 }
    5410              :             }
    5411              :         }
    5412              : 
    5413      3847212 :       if (XVECLEN (trueop1, 0) == 1
    5414       965868 :           && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5415       965868 :           && GET_CODE (trueop0) == VEC_CONCAT)
    5416              :         {
    5417          185 :           rtx vec = trueop0;
    5418          370 :           offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
    5419              : 
    5420              :           /* Try to find the element in the VEC_CONCAT.  */
    5421          185 :           while (GET_MODE (vec) != mode
    5422          370 :                  && GET_CODE (vec) == VEC_CONCAT)
    5423              :             {
    5424          185 :               poly_int64 vec_size;
    5425              : 
    5426          185 :               if (CONST_INT_P (XEXP (vec, 0)))
    5427              :                 {
    5428              :                   /* vec_concat of two const_ints doesn't make sense with
    5429              :                      respect to modes.  */
    5430            0 :                   if (CONST_INT_P (XEXP (vec, 1)))
    5431    459915835 :                     return 0;
    5432              : 
    5433            0 :                   vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
    5434            0 :                              - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
    5435              :                 }
    5436              :               else
    5437          370 :                 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
    5438              : 
    5439          185 :               if (known_lt (offset, vec_size))
    5440              :                 vec = XEXP (vec, 0);
    5441           15 :               else if (known_ge (offset, vec_size))
    5442              :                 {
    5443           15 :                   offset -= vec_size;
    5444           15 :                   vec = XEXP (vec, 1);
    5445              :                 }
    5446              :               else
    5447              :                 break;
    5448          185 :               vec = avoid_constant_pool_reference (vec);
    5449              :             }
    5450              : 
    5451          185 :           if (GET_MODE (vec) == mode)
    5452              :             return vec;
    5453              :         }
    5454              : 
    5455              :       /* If we select elements in a vec_merge that all come from the same
    5456              :          operand, select from that operand directly.  */
    5457      3847212 :       if (GET_CODE (op0) == VEC_MERGE)
    5458              :         {
    5459         9370 :           rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
    5460         9370 :           if (CONST_INT_P (trueop02))
    5461              :             {
    5462         2959 :               unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
    5463         2959 :               bool all_operand0 = true;
    5464         2959 :               bool all_operand1 = true;
    5465        10781 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5466              :                 {
    5467         7822 :                   rtx j = XVECEXP (trueop1, 0, i);
    5468         7822 :                   if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
    5469              :                     all_operand1 = false;
    5470              :                   else
    5471         3420 :                     all_operand0 = false;
    5472              :                 }
    5473         2959 :               if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
    5474         1440 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
    5475         1519 :               if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
    5476           55 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
    5477              :             }
    5478              :         }
    5479              : 
    5480              :       /* If we have two nested selects that are inverses of each
    5481              :          other, replace them with the source operand.  */
    5482      3845717 :       if (GET_CODE (trueop0) == VEC_SELECT
    5483        74083 :           && GET_MODE (XEXP (trueop0, 0)) == mode)
    5484              :         {
    5485         1042 :           rtx op0_subop1 = XEXP (trueop0, 1);
    5486         1042 :           gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
    5487         2084 :           gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
    5488              :           bool identical_p = true;
    5489              : 
    5490              :           /* Apply the outer ordering vector to the inner one.  (The inner
    5491              :              ordering vector is expressly permitted to be of a different
    5492              :              length than the outer one.)  If the result is { 0, 1, ..., n-1 }
    5493              :              then the two VEC_SELECTs cancel.  */
    5494         9014 :           for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
    5495              :             {
    5496         7972 :               rtx x = XVECEXP (trueop1, 0, i);
    5497         7972 :               if (!CONST_INT_P (x))
    5498              :                 return 0;
    5499         7972 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5500         7972 :               if (!CONST_INT_P (y))
    5501              :                 return 0;
    5502         7972 :               if (i != INTVAL (y))
    5503         5898 :                 identical_p = false;
    5504              :             }
    5505         1042 :           if (identical_p)
    5506              :             return XEXP (trueop0, 0);
    5507              : 
    5508              :           /* Otherwise a permutation of a permutation is a permutation.  */
    5509         1042 :           int len = XVECLEN (trueop1, 0);
    5510         1042 :           rtvec vec = rtvec_alloc (len);
    5511        10056 :           for (int i = 0; i < len; ++i)
    5512              :             {
    5513         7972 :               rtx x = XVECEXP (trueop1, 0, i);
    5514         7972 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5515         7972 :               RTVEC_ELT (vec, i) = y;
    5516              :             }
    5517         1042 :           return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
    5518              :                                  gen_rtx_PARALLEL (VOIDmode, vec));
    5519              :         }
    5520              : 
    5521              :       return 0;
    5522      4117504 :     case VEC_CONCAT:
    5523      4117504 :       {
    5524      4117504 :         machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
    5525      4117504 :                                       ? GET_MODE (trueop0)
    5526      4117504 :                                       : GET_MODE_INNER (mode));
    5527      4117504 :         machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
    5528      4117504 :                                       ? GET_MODE (trueop1)
    5529      4117504 :                                       : GET_MODE_INNER (mode));
    5530              : 
    5531      4117504 :         gcc_assert (VECTOR_MODE_P (mode));
    5532     16470016 :         gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
    5533              :                               + GET_MODE_SIZE (op1_mode),
    5534              :                               GET_MODE_SIZE (mode)));
    5535              : 
    5536      4117504 :         if (VECTOR_MODE_P (op0_mode))
    5537      6492294 :           gcc_assert (GET_MODE_INNER (mode)
    5538              :                       == GET_MODE_INNER (op0_mode));
    5539              :         else
    5540      3906812 :           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
    5541              : 
    5542      4117504 :         if (VECTOR_MODE_P (op1_mode))
    5543      6492294 :           gcc_assert (GET_MODE_INNER (mode)
    5544              :                       == GET_MODE_INNER (op1_mode));
    5545              :         else
    5546      3906812 :           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
    5547              : 
    5548      4117504 :         unsigned int n_elts, in_n_elts;
    5549      4117504 :         if ((GET_CODE (trueop0) == CONST_VECTOR
    5550      4117504 :              || CONST_SCALAR_INT_P (trueop0)
    5551      4087474 :              || CONST_DOUBLE_AS_FLOAT_P (trueop0))
    5552        31329 :             && (GET_CODE (trueop1) == CONST_VECTOR
    5553        31329 :                 || CONST_SCALAR_INT_P (trueop1)
    5554        31329 :                 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5555            0 :             && GET_MODE_NUNITS (mode).is_constant (&n_elts)
    5556      4117504 :             && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
    5557              :           {
    5558            0 :             rtvec v = rtvec_alloc (n_elts);
    5559            0 :             unsigned int i;
    5560            0 :             for (i = 0; i < n_elts; i++)
    5561              :               {
    5562            0 :                 if (i < in_n_elts)
    5563              :                   {
    5564            0 :                     if (!VECTOR_MODE_P (op0_mode))
    5565            0 :                       RTVEC_ELT (v, i) = trueop0;
    5566              :                     else
    5567            0 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
    5568              :                   }
    5569              :                 else
    5570              :                   {
    5571            0 :                     if (!VECTOR_MODE_P (op1_mode))
    5572            0 :                       RTVEC_ELT (v, i) = trueop1;
    5573              :                     else
    5574            0 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
    5575              :                                                            i - in_n_elts);
    5576              :                   }
    5577              :               }
    5578              : 
    5579            0 :             return gen_rtx_CONST_VECTOR (mode, v);
    5580              :           }
    5581              : 
    5582              :         /* Try to merge two VEC_SELECTs from the same vector into a single one.
    5583              :            Restrict the transformation to avoid generating a VEC_SELECT with a
    5584              :            mode unrelated to its operand.  */
    5585      4117504 :         if (GET_CODE (trueop0) == VEC_SELECT
    5586       187100 :             && GET_CODE (trueop1) == VEC_SELECT
    5587        38072 :             && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
    5588      4137409 :             && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
    5589        39810 :                == GET_MODE_INNER(mode))
    5590              :           {
    5591        19905 :             rtx par0 = XEXP (trueop0, 1);
    5592        19905 :             rtx par1 = XEXP (trueop1, 1);
    5593        19905 :             int len0 = XVECLEN (par0, 0);
    5594        19905 :             int len1 = XVECLEN (par1, 0);
    5595        19905 :             rtvec vec = rtvec_alloc (len0 + len1);
    5596       138808 :             for (int i = 0; i < len0; i++)
    5597        98998 :               RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
    5598       118903 :             for (int i = 0; i < len1; i++)
    5599        98998 :               RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
    5600        19905 :             return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
    5601        19905 :                                         gen_rtx_PARALLEL (VOIDmode, vec));
    5602              :           }
    5603              :         /* (vec_concat:
    5604              :              (subreg_lowpart:N OP)
    5605              :              (vec_select:N OP P))  -->  OP when P selects the high half
    5606              :             of the OP.  */
    5607      4097599 :         if (GET_CODE (trueop0) == SUBREG
    5608       482826 :             && subreg_lowpart_p (trueop0)
    5609       482581 :             && GET_CODE (trueop1) == VEC_SELECT
    5610            3 :             && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
    5611            0 :             && !side_effects_p (XEXP (trueop1, 0))
    5612      4097599 :             && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
    5613            0 :           return XEXP (trueop1, 0);
    5614              :       }
    5615              :       return 0;
    5616              : 
    5617            0 :     default:
    5618            0 :       gcc_unreachable ();
    5619              :     }
    5620              : 
    5621    386292403 :   if (mode == GET_MODE (op0)
    5622    331361042 :       && mode == GET_MODE (op1)
    5623    105169821 :       && vec_duplicate_p (op0, &elt0)
    5624    386417906 :       && vec_duplicate_p (op1, &elt1))
    5625              :     {
    5626              :       /* Try applying the operator to ELT and see if that simplifies.
    5627              :          We can duplicate the result if so.
    5628              : 
    5629              :          The reason we don't use simplify_gen_binary is that it isn't
    5630              :          necessarily a win to convert things like:
    5631              : 
    5632              :            (plus:V (vec_duplicate:V (reg:S R1))
    5633              :                    (vec_duplicate:V (reg:S R2)))
    5634              : 
    5635              :          to:
    5636              : 
    5637              :            (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
    5638              : 
    5639              :          The first might be done entirely in vector registers while the
    5640              :          second might need a move between register files.  */
    5641          158 :       tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5642              :                                        elt0, elt1);
    5643           79 :       if (tem)
    5644            2 :         return gen_vec_duplicate (mode, tem);
    5645              :     }
    5646              : 
    5647              :   return 0;
    5648              : }
    5649              : 
    5650              : /* Return true if binary operation OP distributes over addition in operand
    5651              :    OPNO, with the other operand being held constant.  OPNO counts from 1.  */
    5652              : 
    5653              : static bool
    5654         8223 : distributes_over_addition_p (rtx_code op, int opno)
    5655              : {
    5656            0 :   switch (op)
    5657              :     {
    5658              :     case PLUS:
    5659              :     case MINUS:
    5660              :     case MULT:
    5661              :       return true;
    5662              : 
    5663            0 :     case ASHIFT:
    5664            0 :       return opno == 1;
    5665              : 
    5666            0 :     default:
    5667            0 :       return false;
    5668              :     }
    5669              : }
    5670              : 
    5671              : rtx
    5672    494113088 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
    5673              :                                  rtx op0, rtx op1)
    5674              : {
    5675    494113088 :   if (VECTOR_MODE_P (mode)
    5676     15679999 :       && code != VEC_CONCAT
    5677     11547956 :       && GET_CODE (op0) == CONST_VECTOR
    5678       183483 :       && GET_CODE (op1) == CONST_VECTOR)
    5679              :     {
    5680         8932 :       bool step_ok_p;
    5681         8932 :       if (CONST_VECTOR_STEPPED_P (op0)
    5682         8932 :           && CONST_VECTOR_STEPPED_P (op1))
    5683              :         /* We can operate directly on the encoding if:
    5684              : 
    5685              :               a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
    5686              :             implies
    5687              :               (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
    5688              : 
    5689              :            Addition and subtraction are the supported operators
    5690              :            for which this is true.  */
    5691          709 :         step_ok_p = (code == PLUS || code == MINUS);
    5692         8223 :       else if (CONST_VECTOR_STEPPED_P (op0))
    5693              :         /* We can operate directly on stepped encodings if:
    5694              : 
    5695              :              a3 - a2 == a2 - a1
    5696              :            implies:
    5697              :              (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
    5698              : 
    5699              :            which is true if (x -> x op c) distributes over addition.  */
    5700         1300 :         step_ok_p = distributes_over_addition_p (code, 1);
    5701              :       else
    5702              :         /* Similarly in reverse.  */
    5703         6923 :         step_ok_p = distributes_over_addition_p (code, 2);
    5704         8932 :       rtx_vector_builder builder;
    5705         8932 :       if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
    5706              :         return 0;
    5707              : 
    5708         8932 :       unsigned int count = builder.encoded_nelts ();
    5709        54484 :       for (unsigned int i = 0; i < count; i++)
    5710              :         {
    5711        91204 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5712              :                                              CONST_VECTOR_ELT (op0, i),
    5713        45602 :                                              CONST_VECTOR_ELT (op1, i));
    5714        45602 :           if (!x || !valid_for_const_vector_p (mode, x))
    5715           50 :             return 0;
    5716        45552 :           builder.quick_push (x);
    5717              :         }
    5718         8882 :       return builder.build ();
    5719         8932 :     }
    5720              : 
    5721    494104156 :   if (VECTOR_MODE_P (mode)
    5722     15671067 :       && code == VEC_CONCAT
    5723      4132043 :       && (CONST_SCALAR_INT_P (op0)
    5724      4108436 :           || CONST_FIXED_P (op0)
    5725      4108436 :           || CONST_DOUBLE_AS_FLOAT_P (op0)
    5726      4104820 :           || CONST_VECTOR_P (op0))
    5727        45868 :       && (CONST_SCALAR_INT_P (op1)
    5728        42427 :           || CONST_DOUBLE_AS_FLOAT_P (op1)
    5729        40110 :           || CONST_FIXED_P (op1)
    5730        40110 :           || CONST_VECTOR_P (op1)))
    5731              :     {
    5732              :       /* Both inputs have a constant number of elements, so the result
    5733              :          must too.  */
    5734        14539 :       unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
    5735        14539 :       rtvec v = rtvec_alloc (n_elts);
    5736              : 
    5737        14539 :       gcc_assert (n_elts >= 2);
    5738        14539 :       if (n_elts == 2)
    5739              :         {
    5740         5758 :           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
    5741         5758 :           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
    5742              : 
    5743         5758 :           RTVEC_ELT (v, 0) = op0;
    5744         5758 :           RTVEC_ELT (v, 1) = op1;
    5745              :         }
    5746              :       else
    5747              :         {
    5748         8781 :           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
    5749         8781 :           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
    5750         8781 :           unsigned i;
    5751              : 
    5752         8781 :           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
    5753         8781 :           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
    5754         8781 :           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
    5755              : 
    5756        53523 :           for (i = 0; i < op0_n_elts; ++i)
    5757        44742 :             RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
    5758        53715 :           for (i = 0; i < op1_n_elts; ++i)
    5759        44934 :             RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
    5760              :         }
    5761              : 
    5762        14539 :       return gen_rtx_CONST_VECTOR (mode, v);
    5763              :     }
    5764              : 
    5765    481887269 :   if (VECTOR_MODE_P (mode)
    5766     15656528 :       && GET_CODE (op0) == CONST_VECTOR
    5767       184415 :       && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
    5768    494089617 :       && (CONST_VECTOR_DUPLICATE_P (op0)
    5769       120919 :           || CONST_VECTOR_NUNITS (op0).is_constant ()))
    5770              :     {
    5771       120919 :       switch (code)
    5772              :         {
    5773       120919 :         case PLUS:
    5774       120919 :         case MINUS:
    5775       120919 :         case MULT:
    5776       120919 :         case DIV:
    5777       120919 :         case MOD:
    5778       120919 :         case UDIV:
    5779       120919 :         case UMOD:
    5780       120919 :         case AND:
    5781       120919 :         case IOR:
    5782       120919 :         case XOR:
    5783       120919 :         case SMIN:
    5784       120919 :         case SMAX:
    5785       120919 :         case UMIN:
    5786       120919 :         case UMAX:
    5787       120919 :         case LSHIFTRT:
    5788       120919 :         case ASHIFTRT:
    5789       120919 :         case ASHIFT:
    5790       120919 :         case ROTATE:
    5791       120919 :         case ROTATERT:
    5792       120919 :         case SS_PLUS:
    5793       120919 :         case US_PLUS:
    5794       120919 :         case SS_MINUS:
    5795       120919 :         case US_MINUS:
    5796       120919 :         case SS_ASHIFT:
    5797       120919 :         case US_ASHIFT:
    5798       120919 :         case COPYSIGN:
    5799       120919 :           break;
    5800              :         default:
    5801              :           return NULL_RTX;
    5802              :         }
    5803              : 
    5804       120919 :       unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
    5805       120919 :                                 ? CONST_VECTOR_NPATTERNS (op0)
    5806       128900 :                                 : CONST_VECTOR_NUNITS (op0).to_constant ());
    5807       120919 :       rtx_vector_builder builder (mode, npatterns, 1);
    5808       375910 :       for (unsigned i = 0; i < npatterns; i++)
    5809              :         {
    5810       268144 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5811       134072 :                                              CONST_VECTOR_ELT (op0, i), op1);
    5812       134072 :           if (!x || !valid_for_const_vector_p (mode, x))
    5813            0 :             return 0;
    5814       134072 :           builder.quick_push (x);
    5815              :         }
    5816       120919 :       return builder.build ();
    5817              :     }
    5818              : 
    5819    493968698 :   if (SCALAR_FLOAT_MODE_P (mode)
    5820      6440513 :       && CONST_DOUBLE_AS_FLOAT_P (op0)
    5821        76369 :       && CONST_DOUBLE_AS_FLOAT_P (op1)
    5822        11609 :       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
    5823              :     {
    5824        11609 :       if (code == AND
    5825              :           || code == IOR
    5826        11609 :           || code == XOR)
    5827              :         {
    5828         2537 :           long tmp0[4];
    5829         2537 :           long tmp1[4];
    5830         2537 :           REAL_VALUE_TYPE r;
    5831         2537 :           int i;
    5832              : 
    5833         2537 :           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
    5834         2537 :                           GET_MODE (op0));
    5835         2537 :           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
    5836         2537 :                           GET_MODE (op1));
    5837        12685 :           for (i = 0; i < 4; i++)
    5838              :             {
    5839        10148 :               switch (code)
    5840              :               {
    5841         5268 :               case AND:
    5842         5268 :                 tmp0[i] &= tmp1[i];
    5843         5268 :                 break;
    5844         2512 :               case IOR:
    5845         2512 :                 tmp0[i] |= tmp1[i];
    5846         2512 :                 break;
    5847         2368 :               case XOR:
    5848         2368 :                 tmp0[i] ^= tmp1[i];
    5849         2368 :                 break;
    5850              :               default:
    5851              :                 gcc_unreachable ();
    5852              :               }
    5853              :             }
    5854         2537 :            real_from_target (&r, tmp0, mode);
    5855         2537 :            return const_double_from_real_value (r, mode);
    5856              :         }
    5857         9072 :       else if (code == COPYSIGN)
    5858              :         {
    5859            0 :           REAL_VALUE_TYPE f0, f1;
    5860            0 :           real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
    5861            0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
    5862            0 :           real_copysign (&f0, &f1);
    5863            0 :           return const_double_from_real_value (f0, mode);
    5864              :         }
    5865              :       else
    5866              :         {
    5867         9072 :           REAL_VALUE_TYPE f0, f1, value, result;
    5868         9072 :           const REAL_VALUE_TYPE *opr0, *opr1;
    5869         9072 :           bool inexact;
    5870              : 
    5871         9072 :           opr0 = CONST_DOUBLE_REAL_VALUE (op0);
    5872         9072 :           opr1 = CONST_DOUBLE_REAL_VALUE (op1);
    5873              : 
    5874         9072 :           if (HONOR_SNANS (mode)
    5875         9072 :               && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
    5876          803 :                   || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
    5877              :             return 0;
    5878              : 
    5879         9062 :           real_convert (&f0, mode, opr0);
    5880         9062 :           real_convert (&f1, mode, opr1);
    5881              : 
    5882         9062 :           if (code == DIV
    5883         4160 :               && real_equal (&f1, &dconst0)
    5884        12704 :               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
    5885              :             return 0;
    5886              : 
    5887        27021 :           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5888         5334 :               && flag_trapping_math
    5889         5256 :               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
    5890              :             {
    5891            9 :               int s0 = REAL_VALUE_NEGATIVE (f0);
    5892            9 :               int s1 = REAL_VALUE_NEGATIVE (f1);
    5893              : 
    5894            9 :               switch (code)
    5895              :                 {
    5896            0 :                 case PLUS:
    5897              :                   /* Inf + -Inf = NaN plus exception.  */
    5898            0 :                   if (s0 != s1)
    5899              :                     return 0;
    5900              :                   break;
    5901            0 :                 case MINUS:
    5902              :                   /* Inf - Inf = NaN plus exception.  */
    5903            0 :                   if (s0 == s1)
    5904              :                     return 0;
    5905              :                   break;
    5906              :                 case DIV:
    5907              :                   /* Inf / Inf = NaN plus exception.  */
    5908              :                   return 0;
    5909              :                 default:
    5910              :                   break;
    5911              :                 }
    5912              :             }
    5913              : 
    5914         7922 :           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5915         1945 :               && flag_trapping_math
    5916         7312 :               && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
    5917         1889 :                   || (REAL_VALUE_ISINF (f1)
    5918           10 :                       && real_equal (&f0, &dconst0))))
    5919              :             /* Inf * 0 = NaN plus exception.  */
    5920              :             return 0;
    5921              : 
    5922         5397 :           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
    5923              :                                      &f0, &f1);
    5924         5397 :           real_convert (&result, mode, &value);
    5925              : 
    5926              :           /* Don't constant fold this floating point operation if
    5927              :              the result has overflowed and flag_trapping_math.  */
    5928              : 
    5929         5397 :           if (flag_trapping_math
    5930        20916 :               && MODE_HAS_INFINITIES (mode)
    5931         5229 :               && REAL_VALUE_ISINF (result)
    5932         1141 :               && !REAL_VALUE_ISINF (f0)
    5933         6524 :               && !REAL_VALUE_ISINF (f1))
    5934              :             /* Overflow plus exception.  */
    5935         1127 :             return 0;
    5936              : 
    5937              :           /* Don't constant fold this floating point operation if the
    5938              :              result may dependent upon the run-time rounding mode and
    5939              :              flag_rounding_math is set, or if GCC's software emulation
    5940              :              is unable to accurately represent the result.  */
    5941              : 
    5942         4270 :           if ((flag_rounding_math
    5943        27587 :                || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
    5944         4270 :               && (inexact || !real_identical (&result, &value)))
    5945              :             return NULL_RTX;
    5946              : 
    5947         3892 :           return const_double_from_real_value (result, mode);
    5948              :         }
    5949              :     }
    5950              : 
    5951              :   /* We can fold some multi-word operations.  */
    5952    493957089 :   scalar_int_mode int_mode;
    5953    493957089 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    5954    422867769 :       && CONST_SCALAR_INT_P (op0)
    5955     41177849 :       && CONST_SCALAR_INT_P (op1)
    5956     34048800 :       && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
    5957              :     {
    5958     34048800 :       wide_int result;
    5959     34048800 :       wi::overflow_type overflow;
    5960     34048800 :       rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
    5961     34048800 :       rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
    5962              : 
    5963              : #if TARGET_SUPPORTS_WIDE_INT == 0
    5964              :       /* This assert keeps the simplification from producing a result
    5965              :          that cannot be represented in a CONST_DOUBLE but a lot of
    5966              :          upstream callers expect that this function never fails to
    5967              :          simplify something and so you if you added this to the test
    5968              :          above the code would die later anyway.  If this assert
    5969              :          happens, you just need to make the port support wide int.  */
    5970              :       gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
    5971              : #endif
    5972     34048800 :       switch (code)
    5973              :         {
    5974      1092954 :         case MINUS:
    5975      1092954 :           result = wi::sub (pop0, pop1);
    5976      1092954 :           break;
    5977              : 
    5978     26603637 :         case PLUS:
    5979     26603637 :           result = wi::add (pop0, pop1);
    5980     26603637 :           break;
    5981              : 
    5982       308294 :         case MULT:
    5983       308294 :           result = wi::mul (pop0, pop1);
    5984       308294 :           break;
    5985              : 
    5986         9138 :         case DIV:
    5987         9138 :           result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
    5988         9138 :           if (overflow)
    5989              :             return NULL_RTX;
    5990              :           break;
    5991              : 
    5992         1201 :         case MOD:
    5993         1201 :           result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
    5994         1201 :           if (overflow)
    5995              :             return NULL_RTX;
    5996              :           break;
    5997              : 
    5998         6266 :         case UDIV:
    5999         6266 :           result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
    6000         6266 :           if (overflow)
    6001              :             return NULL_RTX;
    6002              :           break;
    6003              : 
    6004        16317 :         case UMOD:
    6005        16317 :           result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
    6006        16317 :           if (overflow)
    6007              :             return NULL_RTX;
    6008              :           break;
    6009              : 
    6010       728634 :         case AND:
    6011       728634 :           result = wi::bit_and (pop0, pop1);
    6012       728634 :           break;
    6013              : 
    6014       284120 :         case IOR:
    6015       284120 :           result = wi::bit_or (pop0, pop1);
    6016       284120 :           break;
    6017              : 
    6018        44055 :         case XOR:
    6019        44055 :           result = wi::bit_xor (pop0, pop1);
    6020        44055 :           break;
    6021              : 
    6022         1763 :         case SMIN:
    6023         1763 :           result = wi::smin (pop0, pop1);
    6024         1763 :           break;
    6025              : 
    6026         1994 :         case SMAX:
    6027         1994 :           result = wi::smax (pop0, pop1);
    6028         1994 :           break;
    6029              : 
    6030         3205 :         case UMIN:
    6031         3205 :           result = wi::umin (pop0, pop1);
    6032         3205 :           break;
    6033              : 
    6034         2858 :         case UMAX:
    6035         2858 :           result = wi::umax (pop0, pop1);
    6036         2858 :           break;
    6037              : 
    6038      4904234 :         case LSHIFTRT:
    6039      4904234 :         case ASHIFTRT:
    6040      4904234 :         case ASHIFT:
    6041      4904234 :         case SS_ASHIFT:
    6042      4904234 :         case US_ASHIFT:
    6043      4904234 :           {
    6044              :             /* The shift count might be in SImode while int_mode might
    6045              :                be narrower.  On IA-64 it is even DImode.  If the shift
    6046              :                count is too large and doesn't fit into int_mode, we'd
    6047              :                ICE.  So, if int_mode is narrower than
    6048              :                HOST_BITS_PER_WIDE_INT, use DImode for the shift count.  */
    6049      4904234 :             if (GET_MODE (op1) == VOIDmode
    6050      4904234 :                 && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
    6051      1858522 :               pop1 = rtx_mode_t (op1, DImode);
    6052              : 
    6053      4904234 :             wide_int wop1 = pop1;
    6054      4904234 :             if (SHIFT_COUNT_TRUNCATED)
    6055              :               wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
    6056      4904234 :             else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
    6057           64 :               return NULL_RTX;
    6058              : 
    6059      4904170 :             switch (code)
    6060              :               {
    6061      2797287 :               case LSHIFTRT:
    6062      2797287 :                 result = wi::lrshift (pop0, wop1);
    6063      2797287 :                 break;
    6064              : 
    6065        82024 :               case ASHIFTRT:
    6066        82024 :                 result = wi::arshift (pop0, wop1);
    6067        82024 :                 break;
    6068              : 
    6069      2024859 :               case ASHIFT:
    6070      2024859 :                 result = wi::lshift (pop0, wop1);
    6071      2024859 :                 break;
    6072              : 
    6073            0 :               case SS_ASHIFT:
    6074            0 :                 if (wi::leu_p (wop1, wi::clrsb (pop0)))
    6075            0 :                   result = wi::lshift (pop0, wop1);
    6076            0 :                 else if (wi::neg_p (pop0))
    6077            0 :                   result = wi::min_value (int_mode, SIGNED);
    6078              :                 else
    6079            0 :                   result = wi::max_value (int_mode, SIGNED);
    6080              :                 break;
    6081              : 
    6082            0 :               case US_ASHIFT:
    6083            0 :                 if (wi::eq_p (pop0, 0))
    6084            0 :                   result = pop0;
    6085            0 :                 else if (wi::leu_p (wop1, wi::clz (pop0)))
    6086            0 :                   result = wi::lshift (pop0, wop1);
    6087              :                 else
    6088            0 :                   result = wi::max_value (int_mode, UNSIGNED);
    6089              :                 break;
    6090              : 
    6091              :               default:
    6092              :                 gcc_unreachable ();
    6093              :               }
    6094      4904170 :             break;
    6095      4904234 :           }
    6096        31568 :         case ROTATE:
    6097        31568 :         case ROTATERT:
    6098        31568 :           {
    6099              :             /* The rotate count might be in SImode while int_mode might
    6100              :                be narrower.  On IA-64 it is even DImode.  If the shift
    6101              :                count is too large and doesn't fit into int_mode, we'd
    6102              :                ICE.  So, if int_mode is narrower than
    6103              :                HOST_BITS_PER_WIDE_INT, use DImode for the shift count.  */
    6104        31568 :             if (GET_MODE (op1) == VOIDmode
    6105        31568 :                 && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
    6106        23782 :               pop1 = rtx_mode_t (op1, DImode);
    6107              : 
    6108        31568 :             if (wi::neg_p (pop1))
    6109              :               return NULL_RTX;
    6110              : 
    6111        31468 :             switch (code)
    6112              :               {
    6113        10480 :               case ROTATE:
    6114        10480 :                 result = wi::lrotate (pop0, pop1);
    6115        10480 :                 break;
    6116              : 
    6117        20988 :               case ROTATERT:
    6118        20988 :                 result = wi::rrotate (pop0, pop1);
    6119        20988 :                 break;
    6120              : 
    6121              :               default:
    6122              :                 gcc_unreachable ();
    6123              :               }
    6124              :             break;
    6125              :           }
    6126              : 
    6127         2270 :         case SS_PLUS:
    6128         2270 :           result = wi::add (pop0, pop1, SIGNED, &overflow);
    6129         4484 :  clamp_signed_saturation:
    6130         4484 :           if (overflow == wi::OVF_OVERFLOW)
    6131          314 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
    6132         4170 :           else if (overflow == wi::OVF_UNDERFLOW)
    6133          278 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
    6134         3892 :           else if (overflow != wi::OVF_NONE)
    6135              :             return NULL_RTX;
    6136              :           break;
    6137              : 
    6138         2220 :         case US_PLUS:
    6139         2220 :           result = wi::add (pop0, pop1, UNSIGNED, &overflow);
    6140         2220 :  clamp_unsigned_saturation:
    6141         2220 :           if (overflow != wi::OVF_NONE)
    6142          461 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    6143              :           break;
    6144              : 
    6145         2214 :         case SS_MINUS:
    6146         2214 :           result = wi::sub (pop0, pop1, SIGNED, &overflow);
    6147         2214 :           goto clamp_signed_saturation;
    6148              : 
    6149         1852 :         case US_MINUS:
    6150         1852 :           result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
    6151         1852 :           if (overflow != wi::OVF_NONE)
    6152         1203 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    6153              :           break;
    6154              : 
    6155            0 :         case SS_MULT:
    6156            0 :           result = wi::mul (pop0, pop1, SIGNED, &overflow);
    6157            0 :           goto clamp_signed_saturation;
    6158              : 
    6159            0 :         case US_MULT:
    6160            0 :           result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
    6161            0 :           goto clamp_unsigned_saturation;
    6162              : 
    6163            6 :         case SMUL_HIGHPART:
    6164            6 :           result = wi::mul_high (pop0, pop1, SIGNED);
    6165            6 :           break;
    6166              : 
    6167            0 :         case UMUL_HIGHPART:
    6168            0 :           result = wi::mul_high (pop0, pop1, UNSIGNED);
    6169            0 :           break;
    6170              : 
    6171              :         default:
    6172              :           return NULL_RTX;
    6173              :         }
    6174     34046484 :       return immed_wide_int_const (result, int_mode);
    6175     34048800 :     }
    6176              : 
    6177              :   /* Handle polynomial integers.  */
    6178              :   if (NUM_POLY_INT_COEFFS > 1
    6179              :       && is_a <scalar_int_mode> (mode, &int_mode)
    6180              :       && poly_int_rtx_p (op0)
    6181              :       && poly_int_rtx_p (op1))
    6182              :     {
    6183              :       poly_wide_int result;
    6184              :       switch (code)
    6185              :         {
    6186              :         case PLUS:
    6187              :           result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
    6188              :           break;
    6189              : 
    6190              :         case MINUS:
    6191              :           result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
    6192              :           break;
    6193              : 
    6194              :         case MULT:
    6195              :           if (CONST_SCALAR_INT_P (op1))
    6196              :             result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
    6197              :           else
    6198              :             return NULL_RTX;
    6199              :           break;
    6200              : 
    6201              :         case ASHIFT:
    6202              :           if (CONST_SCALAR_INT_P (op1))
    6203              :             {
    6204              :               wide_int shift
    6205              :                 = rtx_mode_t (op1,
    6206              :                               GET_MODE (op1) == VOIDmode
    6207              :                               && (GET_MODE_PRECISION (int_mode)
    6208              :                                   < HOST_BITS_PER_WIDE_INT)
    6209              :                               ? DImode : mode);
    6210              :               if (SHIFT_COUNT_TRUNCATED)
    6211              :                 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
    6212              :               else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
    6213              :                 return NULL_RTX;
    6214              :               result = wi::to_poly_wide (op0, mode) << shift;
    6215              :             }
    6216              :           else
    6217              :             return NULL_RTX;
    6218              :           break;
    6219              : 
    6220              :         case IOR:
    6221              :           if (!CONST_SCALAR_INT_P (op1)
    6222              :               || !can_ior_p (wi::to_poly_wide (op0, mode),
    6223              :                              rtx_mode_t (op1, mode), &result))
    6224              :             return NULL_RTX;
    6225              :           break;
    6226              : 
    6227              :         default:
    6228              :           return NULL_RTX;
    6229              :         }
    6230              :       return immed_wide_int_const (result, int_mode);
    6231              :     }
    6232              : 
    6233              :   return NULL_RTX;
    6234              : }
    6235              : 
    6236              : 
    6237              : 
    6238              : /* Return a positive integer if X should sort after Y.  The value
    6239              :    returned is 1 if and only if X and Y are both regs.  */
    6240              : 
    6241              : static int
    6242    117320595 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
    6243              : {
    6244    117320595 :   int result;
    6245              : 
    6246    117320595 :   result = (commutative_operand_precedence (y)
    6247    117320595 :             - commutative_operand_precedence (x));
    6248    117320595 :   if (result)
    6249     81936993 :     return result + result;
    6250              : 
    6251              :   /* Group together equal REGs to do more simplification.  */
    6252     35383602 :   if (REG_P (x) && REG_P (y))
    6253      8699824 :     return REGNO (x) > REGNO (y);
    6254              : 
    6255              :   return 0;
    6256              : }
    6257              : 
    6258              : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
    6259              :    operands may be another PLUS or MINUS.
    6260              : 
    6261              :    Rather than test for specific case, we do this by a brute-force method
    6262              :    and do all possible simplifications until no more changes occur.  Then
    6263              :    we rebuild the operation.
    6264              : 
    6265              :    May return NULL_RTX when no changes were made.  */
    6266              : 
    6267              : rtx
    6268     39552649 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
    6269              :                                        rtx op0, rtx op1)
    6270              : {
    6271     39552649 :   struct simplify_plus_minus_op_data
    6272              :   {
    6273              :     rtx op;
    6274              :     short neg;
    6275              :   } ops[16];
    6276     39552649 :   rtx result, tem;
    6277     39552649 :   int n_ops = 2;
    6278     39552649 :   int changed, n_constants, canonicalized = 0;
    6279     39552649 :   int i, j;
    6280              : 
    6281     39552649 :   memset (ops, 0, sizeof ops);
    6282              : 
    6283              :   /* Set up the two operands and then expand them until nothing has been
    6284              :      changed.  If we run out of room in our array, give up; this should
    6285              :      almost never happen.  */
    6286              : 
    6287     39552649 :   ops[0].op = op0;
    6288     39552649 :   ops[0].neg = 0;
    6289     39552649 :   ops[1].op = op1;
    6290     39552649 :   ops[1].neg = (code == MINUS);
    6291              : 
    6292     80419473 :   do
    6293              :     {
    6294     80419473 :       changed = 0;
    6295     80419473 :       n_constants = 0;
    6296              : 
    6297    325512627 :       for (i = 0; i < n_ops; i++)
    6298              :         {
    6299    245093174 :           rtx this_op = ops[i].op;
    6300    245093174 :           int this_neg = ops[i].neg;
    6301    245093174 :           enum rtx_code this_code = GET_CODE (this_op);
    6302              : 
    6303    245093174 :           switch (this_code)
    6304              :             {
    6305     39879524 :             case PLUS:
    6306     39879524 :             case MINUS:
    6307     39879524 :               if (n_ops == ARRAY_SIZE (ops))
    6308              :                 return NULL_RTX;
    6309              : 
    6310     39879504 :               ops[n_ops].op = XEXP (this_op, 1);
    6311     39879504 :               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
    6312     39879504 :               n_ops++;
    6313              : 
    6314     39879504 :               ops[i].op = XEXP (this_op, 0);
    6315     39879504 :               changed = 1;
    6316              :               /* If this operand was negated then we will potentially
    6317              :                  canonicalize the expression.  Similarly if we don't
    6318              :                  place the operands adjacent we're re-ordering the
    6319              :                  expression and thus might be performing a
    6320              :                  canonicalization.  Ignore register re-ordering.
    6321              :                  ??? It might be better to shuffle the ops array here,
    6322              :                  but then (plus (plus (A, B), plus (C, D))) wouldn't
    6323              :                  be seen as non-canonical.  */
    6324     39879504 :               if (this_neg
    6325     39171627 :                   || (i != n_ops - 2
    6326     38497549 :                       && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
    6327    245093154 :                 canonicalized = 1;
    6328              :               break;
    6329              : 
    6330         2061 :             case NEG:
    6331         2061 :               ops[i].op = XEXP (this_op, 0);
    6332         2061 :               ops[i].neg = ! this_neg;
    6333         2061 :               changed = 1;
    6334         2061 :               canonicalized = 1;
    6335         2061 :               break;
    6336              : 
    6337      1610321 :             case CONST:
    6338      1610321 :               if (n_ops != ARRAY_SIZE (ops)
    6339      1610321 :                   && GET_CODE (XEXP (this_op, 0)) == PLUS
    6340      1476807 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
    6341      1455983 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
    6342              :                 {
    6343      1455983 :                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
    6344      1455983 :                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
    6345      1455983 :                   ops[n_ops].neg = this_neg;
    6346      1455983 :                   n_ops++;
    6347      1455983 :                   changed = 1;
    6348      1455983 :                   canonicalized = 1;
    6349              :                 }
    6350              :               break;
    6351              : 
    6352        66225 :             case NOT:
    6353              :               /* ~a -> (-a - 1) */
    6354        66225 :               if (n_ops != ARRAY_SIZE (ops))
    6355              :                 {
    6356        66225 :                   ops[n_ops].op = CONSTM1_RTX (mode);
    6357        66225 :                   ops[n_ops++].neg = this_neg;
    6358        66225 :                   ops[i].op = XEXP (this_op, 0);
    6359        66225 :                   ops[i].neg = !this_neg;
    6360        66225 :                   changed = 1;
    6361        66225 :                   canonicalized = 1;
    6362              :                 }
    6363              :               break;
    6364              : 
    6365    122165456 :             CASE_CONST_SCALAR_INT:
    6366    122165456 :             case CONST_POLY_INT:
    6367    122165456 :               n_constants++;
    6368    122165456 :               if (this_neg)
    6369              :                 {
    6370      1212606 :                   ops[i].op = neg_poly_int_rtx (mode, this_op);
    6371      1212606 :                   ops[i].neg = 0;
    6372      1212606 :                   changed = 1;
    6373      1212606 :                   canonicalized = 1;
    6374              :                 }
    6375              :               break;
    6376              : 
    6377              :             default:
    6378              :               break;
    6379              :             }
    6380              :         }
    6381              :     }
    6382     80419453 :   while (changed);
    6383              : 
    6384     39552629 :   if (n_constants > 1)
    6385     24193677 :     canonicalized = 1;
    6386              : 
    6387     39552629 :   gcc_assert (n_ops >= 2);
    6388              : 
    6389              :   /* If we only have two operands, we can avoid the loops.  */
    6390     39552629 :   if (n_ops == 2)
    6391              :     {
    6392            0 :       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
    6393            0 :       rtx lhs, rhs;
    6394              : 
    6395              :       /* Get the two operands.  Be careful with the order, especially for
    6396              :          the cases where code == MINUS.  */
    6397            0 :       if (ops[0].neg && ops[1].neg)
    6398              :         {
    6399            0 :           lhs = gen_rtx_NEG (mode, ops[0].op);
    6400            0 :           rhs = ops[1].op;
    6401              :         }
    6402            0 :       else if (ops[0].neg)
    6403              :         {
    6404            0 :           lhs = ops[1].op;
    6405            0 :           rhs = ops[0].op;
    6406              :         }
    6407              :       else
    6408              :         {
    6409            0 :           lhs = ops[0].op;
    6410            0 :           rhs = ops[1].op;
    6411              :         }
    6412              : 
    6413            0 :       return simplify_const_binary_operation (code, mode, lhs, rhs);
    6414              :     }
    6415              : 
    6416              :   /* Now simplify each pair of operands until nothing changes.  */
    6417     64747218 :   while (1)
    6418              :     {
    6419              :       /* Insertion sort is good enough for a small array.  */
    6420    171345413 :       for (i = 1; i < n_ops; i++)
    6421              :         {
    6422    106598195 :           struct simplify_plus_minus_op_data save;
    6423    106598195 :           int cmp;
    6424              : 
    6425    106598195 :           j = i - 1;
    6426    106598195 :           cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
    6427    106598195 :           if (cmp <= 0)
    6428     93758756 :             continue;
    6429              :           /* Just swapping registers doesn't count as canonicalization.  */
    6430     12839439 :           if (cmp != 1)
    6431      9860560 :             canonicalized = 1;
    6432              : 
    6433     12839439 :           save = ops[i];
    6434     15220640 :           do
    6435     15220640 :             ops[j + 1] = ops[j];
    6436     15220640 :           while (j--
    6437     28060079 :                  && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
    6438     12839439 :           ops[j + 1] = save;
    6439              :         }
    6440              : 
    6441     64747218 :       changed = 0;
    6442    171345413 :       for (i = n_ops - 1; i > 0; i--)
    6443    255751625 :         for (j = i - 1; j >= 0; j--)
    6444              :           {
    6445    150053969 :             rtx lhs = ops[j].op, rhs = ops[i].op;
    6446    150053969 :             int lneg = ops[j].neg, rneg = ops[i].neg;
    6447              : 
    6448    150053969 :             if (lhs != 0 && rhs != 0)
    6449              :               {
    6450    124106437 :                 enum rtx_code ncode = PLUS;
    6451              : 
    6452    124106437 :                 if (lneg != rneg)
    6453              :                   {
    6454     11710906 :                     ncode = MINUS;
    6455     11710906 :                     if (lneg)
    6456      7380812 :                       std::swap (lhs, rhs);
    6457              :                   }
    6458    112395531 :                 else if (swap_commutative_operands_p (lhs, rhs))
    6459       423365 :                   std::swap (lhs, rhs);
    6460              : 
    6461    124106437 :                 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
    6462     29157629 :                     && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
    6463              :                   {
    6464     24347259 :                     rtx tem_lhs, tem_rhs;
    6465              : 
    6466     24347259 :                     tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
    6467     24347259 :                     tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
    6468     24347259 :                     tem = simplify_binary_operation (ncode, mode, tem_lhs,
    6469              :                                                      tem_rhs);
    6470              : 
    6471     24347259 :                     if (tem && !CONSTANT_P (tem))
    6472         1757 :                       tem = gen_rtx_CONST (GET_MODE (tem), tem);
    6473              :                   }
    6474              :                 else
    6475     99759178 :                   tem = simplify_binary_operation (ncode, mode, lhs, rhs);
    6476              : 
    6477     99760935 :                 if (tem)
    6478              :                   {
    6479              :                     /* Reject "simplifications" that just wrap the two
    6480              :                        arguments in a CONST.  Failure to do so can result
    6481              :                        in infinite recursion with simplify_binary_operation
    6482              :                        when it calls us to simplify CONST operations.
    6483              :                        Also, if we find such a simplification, don't try
    6484              :                        any more combinations with this rhs:  We must have
    6485              :                        something like symbol+offset, ie. one of the
    6486              :                        trivial CONST expressions we handle later.  */
    6487     26532345 :                     if (GET_CODE (tem) == CONST
    6488       902296 :                         && GET_CODE (XEXP (tem, 0)) == ncode
    6489       901744 :                         && XEXP (XEXP (tem, 0), 0) == lhs
    6490       900539 :                         && XEXP (XEXP (tem, 0), 1) == rhs)
    6491              :                       break;
    6492     25631806 :                     lneg &= rneg;
    6493     25631806 :                     if (GET_CODE (tem) == NEG)
    6494        45208 :                       tem = XEXP (tem, 0), lneg = !lneg;
    6495     25631806 :                     if (poly_int_rtx_p (tem) && lneg)
    6496            0 :                       tem = neg_poly_int_rtx (mode, tem), lneg = 0;
    6497              : 
    6498     25631806 :                     ops[i].op = tem;
    6499     25631806 :                     ops[i].neg = lneg;
    6500     25631806 :                     ops[j].op = NULL_RTX;
    6501     25631806 :                     changed = 1;
    6502     25631806 :                     canonicalized = 1;
    6503              :                   }
    6504              :               }
    6505              :           }
    6506              : 
    6507     64747218 :       if (!changed)
    6508              :         break;
    6509              : 
    6510              :       /* Pack all the operands to the lower-numbered entries.  */
    6511    101665118 :       for (i = 0, j = 0; j < n_ops; j++)
    6512     76470529 :         if (ops[j].op)
    6513              :           {
    6514     50838723 :             ops[i] = ops[j];
    6515     50838723 :             i++;
    6516              :           }
    6517              :       n_ops = i;
    6518              :     }
    6519              : 
    6520              :   /* If nothing changed, check that rematerialization of rtl instructions
    6521              :      is still required.  */
    6522     39552629 :   if (!canonicalized)
    6523              :     {
    6524              :       /* Perform rematerialization if only all operands are registers and
    6525              :          all operations are PLUS.  */
    6526              :       /* ??? Also disallow (non-global, non-frame) fixed registers to work
    6527              :          around rs6000 and how it uses the CA register.  See PR67145.  */
    6528      5073028 :       for (i = 0; i < n_ops; i++)
    6529      4095460 :         if (ops[i].neg
    6530      3810166 :             || !REG_P (ops[i].op)
    6531      7343357 :             || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
    6532       317736 :                 && fixed_regs[REGNO (ops[i].op)]
    6533          238 :                 && !global_regs[REGNO (ops[i].op)]
    6534          238 :                 && ops[i].op != frame_pointer_rtx
    6535          118 :                 && ops[i].op != arg_pointer_rtx
    6536          105 :                 && ops[i].op != stack_pointer_rtx))
    6537              :           return NULL_RTX;
    6538       977568 :       goto gen_result;
    6539              :     }
    6540              : 
    6541              :   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
    6542     37727498 :   if (n_ops == 2
    6543     23609874 :       && CONST_INT_P (ops[1].op)
    6544     22943435 :       && CONSTANT_P (ops[0].op)
    6545          162 :       && ops[0].neg)
    6546           56 :     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
    6547              : 
    6548              :   /* We suppressed creation of trivial CONST expressions in the
    6549              :      combination loop to avoid recursion.  Create one manually now.
    6550              :      The combination loop should have ensured that there is exactly
    6551              :      one CONST_INT, and the sort will have ensured that it is last
    6552              :      in the array and that any other constant will be next-to-last.  */
    6553              : 
    6554     37727442 :   if (n_ops > 1
    6555     37224250 :       && poly_int_rtx_p (ops[n_ops - 1].op)
    6556     72227339 :       && CONSTANT_P (ops[n_ops - 2].op))
    6557              :     {
    6558      1532466 :       rtx value = ops[n_ops - 1].op;
    6559      1532466 :       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
    6560       710312 :         value = neg_poly_int_rtx (mode, value);
    6561      1532466 :       if (CONST_INT_P (value))
    6562              :         {
    6563      3064932 :           ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
    6564      1532466 :                                              INTVAL (value));
    6565      1532466 :           n_ops--;
    6566              :         }
    6567              :     }
    6568              : 
    6569              :   /* Put a non-negated operand first, if possible.  */
    6570              : 
    6571     39472628 :   for (i = 0; i < n_ops && ops[i].neg; i++)
    6572      1745186 :     continue;
    6573     37727442 :   if (i == n_ops)
    6574         9099 :     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
    6575     37718343 :   else if (i != 0)
    6576              :     {
    6577      1639178 :       tem = ops[0].op;
    6578      1639178 :       ops[0] = ops[i];
    6579      1639178 :       ops[i].op = tem;
    6580      1639178 :       ops[i].neg = 1;
    6581              :     }
    6582              : 
    6583              :   /* Now make the result by performing the requested operations.  */
    6584     36079165 :  gen_result:
    6585     38705010 :   result = ops[0].op;
    6586     90790955 :   for (i = 1; i < n_ops; i++)
    6587    104171890 :     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
    6588              :                              mode, result, ops[i].op);
    6589              : 
    6590              :   return result;
    6591      1745186 : }
    6592              : 
    6593              : /* Check whether an operand is suitable for calling simplify_plus_minus.  */
    6594              : static bool
    6595    537859232 : plus_minus_operand_p (const_rtx x)
    6596              : {
    6597    537859232 :   return GET_CODE (x) == PLUS
    6598    537859232 :          || GET_CODE (x) == MINUS
    6599    537859232 :          || (GET_CODE (x) == CONST
    6600      1971333 :              && GET_CODE (XEXP (x, 0)) == PLUS
    6601      1348312 :              && CONSTANT_P (XEXP (XEXP (x, 0), 0))
    6602      1274387 :              && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
    6603              : }
    6604              : 
    6605              : /* Like simplify_binary_operation except used for relational operators.
    6606              :    MODE is the mode of the result. If MODE is VOIDmode, both operands must
    6607              :    not also be VOIDmode.
    6608              : 
    6609              :    CMP_MODE specifies in which mode the comparison is done in, so it is
    6610              :    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
    6611              :    the operands or, if both are VOIDmode, the operands are compared in
    6612              :    "infinite precision".  */
    6613              : rtx
    6614    132131639 : simplify_context::simplify_relational_operation (rtx_code code,
    6615              :                                                  machine_mode mode,
    6616              :                                                  machine_mode cmp_mode,
    6617              :                                                  rtx op0, rtx op1)
    6618              : {
    6619    132131639 :   rtx tem, trueop0, trueop1;
    6620              : 
    6621    132131639 :   if (cmp_mode == VOIDmode)
    6622     29190095 :     cmp_mode = GET_MODE (op0);
    6623     29190095 :   if (cmp_mode == VOIDmode)
    6624       272817 :     cmp_mode = GET_MODE (op1);
    6625              : 
    6626    132131639 :   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
    6627    132131639 :   if (tem)
    6628       785485 :     return relational_result (mode, cmp_mode, tem);
    6629              : 
    6630              :   /* For the following tests, ensure const0_rtx is op1.  */
    6631    131346154 :   if (swap_commutative_operands_p (op0, op1)
    6632    131346154 :       || (op0 == const0_rtx && op1 != const0_rtx))
    6633      2751804 :     std::swap (op0, op1), code = swap_condition (code);
    6634              : 
    6635              :   /* If op0 is a compare, extract the comparison arguments from it.  */
    6636    131346154 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    6637     14356617 :     return simplify_gen_relational (code, mode, VOIDmode,
    6638     14356617 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6639              : 
    6640    116989537 :   if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    6641              :     return NULL_RTX;
    6642              : 
    6643     85978329 :   trueop0 = avoid_constant_pool_reference (op0);
    6644     85978329 :   trueop1 = avoid_constant_pool_reference (op1);
    6645     85978329 :   return simplify_relational_operation_1 (code, mode, cmp_mode,
    6646     85978329 :                                           trueop0, trueop1);
    6647              : }
    6648              : 
    6649              : /* This part of simplify_relational_operation is only used when CMP_MODE
    6650              :    is not in class MODE_CC (i.e. it is a real comparison).
    6651              : 
    6652              :    MODE is the mode of the result, while CMP_MODE specifies in which
    6653              :    mode the comparison is done in, so it is the mode of the operands.  */
    6654              : 
    6655              : rtx
    6656     85978329 : simplify_context::simplify_relational_operation_1 (rtx_code code,
    6657              :                                                    machine_mode mode,
    6658              :                                                    machine_mode cmp_mode,
    6659              :                                                    rtx op0, rtx op1)
    6660              : {
    6661     85978329 :   enum rtx_code op0code = GET_CODE (op0);
    6662              : 
    6663     85978329 :   if (op1 == const0_rtx && COMPARISON_P (op0))
    6664              :     {
    6665              :       /* If op0 is a comparison, extract the comparison arguments
    6666              :          from it.  */
    6667       300638 :       if (code == NE)
    6668              :         {
    6669       133359 :           if (GET_MODE (op0) == mode)
    6670          187 :             return simplify_rtx (op0);
    6671              :           else
    6672       133172 :             return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
    6673       133172 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6674              :         }
    6675       167279 :       else if (code == EQ)
    6676              :         {
    6677       134836 :           enum rtx_code new_code = reversed_comparison_code (op0, NULL);
    6678       134836 :           if (new_code != UNKNOWN)
    6679       134519 :             return simplify_gen_relational (new_code, mode, VOIDmode,
    6680       134519 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6681              :         }
    6682              :     }
    6683              : 
    6684              :   /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
    6685              :      (GEU/LTU a -C).  Likewise for (LTU/GEU (PLUS a C) a).  */
    6686     85710451 :   if ((code == LTU || code == GEU)
    6687      5188680 :       && GET_CODE (op0) == PLUS
    6688       633784 :       && CONST_INT_P (XEXP (op0, 1))
    6689       421039 :       && (rtx_equal_p (op1, XEXP (op0, 0))
    6690       282076 :           || rtx_equal_p (op1, XEXP (op0, 1)))
    6691              :       /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
    6692     85913065 :       && XEXP (op0, 1) != const0_rtx)
    6693              :     {
    6694       202614 :       rtx new_cmp
    6695       202614 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6696       204175 :       return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
    6697       202614 :                                       cmp_mode, XEXP (op0, 0), new_cmp);
    6698              :     }
    6699              : 
    6700              :   /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
    6701              :      transformed into (LTU a -C).  */
    6702     85507837 :   if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
    6703       325308 :       && CONST_INT_P (XEXP (op0, 1))
    6704       244594 :       && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
    6705        20045 :       && XEXP (op0, 1) != const0_rtx)
    6706              :     {
    6707        20045 :       rtx new_cmp
    6708        20045 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6709        20045 :       return simplify_gen_relational (LTU, mode, cmp_mode,
    6710        20045 :                                        XEXP (op0, 0), new_cmp);
    6711              :     }
    6712              : 
    6713              :   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
    6714     85487792 :   if ((code == LTU || code == GEU)
    6715      4986066 :       && GET_CODE (op0) == PLUS
    6716       431170 :       && rtx_equal_p (op1, XEXP (op0, 1))
    6717              :       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
    6718     85494440 :       && !rtx_equal_p (op1, XEXP (op0, 0)))
    6719         6648 :     return simplify_gen_relational (code, mode, cmp_mode, op0,
    6720         6648 :                                     copy_rtx (XEXP (op0, 0)));
    6721              : 
    6722     85481144 :   if (op1 == const0_rtx)
    6723              :     {
    6724              :       /* Canonicalize (GTU x 0) as (NE x 0).  */
    6725     37382681 :       if (code == GTU)
    6726        76812 :         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
    6727              :       /* Canonicalize (LEU x 0) as (EQ x 0).  */
    6728     37305869 :       if (code == LEU)
    6729        33039 :         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
    6730              : 
    6731     37272830 :       if ((code == NE || code == EQ)
    6732              :           /* Verify op0 is IOR */
    6733     33493939 :           && GET_CODE (op0) == IOR
    6734              :           /* only enters if op1 is 0 */
    6735              :           /* Verify IOR operand is NE */
    6736       601417 :           && GET_CODE (XEXP (op0, 0)) == NE
    6737        21018 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
    6738              :           /* Verify second NE operand is 0 */
    6739          348 :           && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
    6740              :         {
    6741           31 :           rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
    6742           31 :           t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
    6743           31 :           return t;
    6744              :         }
    6745              : 
    6746              :     }
    6747     48098463 :   else if (op1 == const1_rtx)
    6748              :     {
    6749      3276877 :       switch (code)
    6750              :         {
    6751        10139 :         case GE:
    6752              :           /* Canonicalize (GE x 1) as (GT x 0).  */
    6753        10139 :           return simplify_gen_relational (GT, mode, cmp_mode,
    6754        10139 :                                           op0, const0_rtx);
    6755       195146 :         case GEU:
    6756              :           /* Canonicalize (GEU x 1) as (NE x 0).  */
    6757       195146 :           return simplify_gen_relational (NE, mode, cmp_mode,
    6758       195146 :                                           op0, const0_rtx);
    6759        10582 :         case LT:
    6760              :           /* Canonicalize (LT x 1) as (LE x 0).  */
    6761        10582 :           return simplify_gen_relational (LE, mode, cmp_mode,
    6762        10582 :                                           op0, const0_rtx);
    6763        53067 :         case LTU:
    6764              :           /* Canonicalize (LTU x 1) as (EQ x 0).  */
    6765        53067 :           return simplify_gen_relational (EQ, mode, cmp_mode,
    6766        53067 :                                           op0, const0_rtx);
    6767              :         default:
    6768              :           break;
    6769              :         }
    6770              :     }
    6771     44821586 :   else if (op1 == constm1_rtx)
    6772              :     {
    6773              :       /* Canonicalize (LE x -1) as (LT x 0).  */
    6774      1160783 :       if (code == LE)
    6775         1566 :         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
    6776              :       /* Canonicalize (GT x -1) as (GE x 0).  */
    6777      1159217 :       if (code == GT)
    6778         5166 :         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
    6779              :     }
    6780              : 
    6781              :   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
    6782     81316705 :   if ((code == EQ || code == NE)
    6783     63275944 :       && (op0code == PLUS || op0code == MINUS)
    6784      2514712 :       && CONSTANT_P (op1)
    6785       913577 :       && CONSTANT_P (XEXP (op0, 1))
    6786       511955 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6787              :     {
    6788       511921 :       rtx x = XEXP (op0, 0);
    6789       511921 :       rtx c = XEXP (op0, 1);
    6790       511921 :       enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
    6791       511921 :       rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
    6792              : 
    6793              :       /* Detect an infinite recursive condition, where we oscillate at this
    6794              :          simplification case between:
    6795              :             A + B == C  <--->  C - B == A,
    6796              :          where A, B, and C are all constants with non-simplifiable expressions,
    6797              :          usually SYMBOL_REFs.  */
    6798       511921 :       if (GET_CODE (tem) == invcode
    6799           57 :           && CONSTANT_P (x)
    6800       511939 :           && rtx_equal_p (c, XEXP (tem, 1)))
    6801              :         return NULL_RTX;
    6802              : 
    6803       511903 :       return simplify_gen_relational (code, mode, cmp_mode, x, tem);
    6804              :     }
    6805              : 
    6806              :   /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0).  */
    6807     62764023 :   if ((code == EQ || code == NE)
    6808     62764023 :       && op0code == PLUS
    6809      1662366 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6810          248 :       && !side_effects_p (op1)
    6811          248 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6812          224 :     return simplify_gen_relational (code, mode, cmp_mode,
    6813          224 :                                     XEXP (op0, 0), CONST0_RTX (cmp_mode));
    6814              : 
    6815              :   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
    6816              :      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
    6817     84583451 :   scalar_int_mode int_mode, int_cmp_mode;
    6818     84583451 :   if (code == NE
    6819     33791964 :       && op1 == const0_rtx
    6820      2281567 :       && is_int_mode (mode, &int_mode)
    6821     86790097 :       && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
    6822              :       /* ??? Work-around BImode bugs in the ia64 backend.  */
    6823      2281567 :       && int_mode != BImode
    6824      2281547 :       && int_cmp_mode != BImode
    6825      2281547 :       && nonzero_bits (op0, int_cmp_mode) == 1
    6826     84583451 :       && STORE_FLAG_VALUE == 1)
    6827       149842 :     return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
    6828        74921 :            ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
    6829        18933 :            : lowpart_subreg (int_mode, op0, int_cmp_mode);
    6830              : 
    6831              :   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
    6832     84508530 :   if ((code == EQ || code == NE)
    6833     62688878 :       && op1 == const0_rtx
    6834     33343905 :       && op0code == XOR)
    6835        14010 :     return simplify_gen_relational (code, mode, cmp_mode,
    6836        14010 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6837              : 
    6838              :   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
    6839     62674868 :   if ((code == EQ || code == NE)
    6840     62674868 :       && op0code == XOR
    6841         5341 :       && rtx_equal_p (XEXP (op0, 0), op1)
    6842            6 :       && !side_effects_p (XEXP (op0, 0)))
    6843            0 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
    6844            0 :                                     CONST0_RTX (mode));
    6845              : 
    6846              :   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
    6847     84494520 :   if ((code == EQ || code == NE)
    6848     62674868 :       && op0code == XOR
    6849         5341 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6850     84494688 :       && !side_effects_p (XEXP (op0, 1)))
    6851          168 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6852          168 :                                     CONST0_RTX (mode));
    6853              : 
    6854              :   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
    6855     84494352 :   if ((code == EQ || code == NE)
    6856     62674700 :       && op0code == XOR
    6857         5173 :       && CONST_SCALAR_INT_P (op1)
    6858         1409 :       && CONST_SCALAR_INT_P (XEXP (op0, 1)))
    6859          874 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6860              :                                     simplify_gen_binary (XOR, cmp_mode,
    6861          874 :                                                          XEXP (op0, 1), op1));
    6862              : 
    6863              :   /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
    6864              :      constant folding if x/y is a constant.  */
    6865     62673826 :   if ((code == EQ || code == NE)
    6866     62673826 :       && (op0code == AND || op0code == IOR)
    6867      3623886 :       && !side_effects_p (op1)
    6868      3623780 :       && op1 != CONST0_RTX (cmp_mode))
    6869              :     {
    6870              :       /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
    6871              :          (eq/ne (and (not y) x) 0).  */
    6872       465468 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
    6873       933644 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
    6874              :         {
    6875        24711 :           rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
    6876              :                                           cmp_mode);
    6877        24711 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
    6878              : 
    6879        24711 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6880        24711 :                                           CONST0_RTX (cmp_mode));
    6881              :         }
    6882              : 
    6883              :       /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
    6884              :          (eq/ne (and (not x) y) 0).  */
    6885       440840 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
    6886       863716 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
    6887              :         {
    6888        45231 :           rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
    6889              :                                           cmp_mode);
    6890        45231 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
    6891              : 
    6892        45231 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6893        45231 :                                           CONST0_RTX (cmp_mode));
    6894              :         }
    6895              :     }
    6896              : 
    6897              :   /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
    6898              :      relationship.  */
    6899     84423536 :   if ((op0code == AND || op0code == IOR)
    6900      3803133 :       && CONST_INT_P (op1)
    6901      3623405 :       && CONST_INT_P (XEXP (op0, 1)))
    6902              :     {
    6903      2341168 :       unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
    6904      2341168 :       unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
    6905              : 
    6906              :       /* For AND operations:
    6907              :            - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
    6908              :            - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
    6909              :            - (x & c1) >= c2 when c1 is less than c2 -> false
    6910              :            - (x & c1) < c2 when c1 is less than c2 -> true
    6911              :            - (x & c1) > c2 when c1 is less than or equal to c2 -> false
    6912              :            - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
    6913              : 
    6914              :          For IOR operations:
    6915              :            - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
    6916              :            - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
    6917              :            - (x | c1) <= c2 when c1 is greater than c2 -> false
    6918              :            - (x | c1) > c2 when c1 is greater than c2 -> true
    6919              :            - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
    6920              :            - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
    6921      2341168 :       if ((op0code == AND
    6922      2336929 :            && ((code == EQ && (c1 & c2) != c2)
    6923      2336916 :                || (code == GEU && c1 < c2)
    6924      2336916 :                || (code == GTU && c1 <= c2)))
    6925      2341155 :           || ((op0code == IOR
    6926         4239 :               && ((code == EQ && (c1 & c2) != c1)
    6927         4235 :                   || (code == LEU && c1 > c2)
    6928         4235 :                   || (code == LTU && c1 >= c2)))))
    6929           17 :         return const0_rtx;
    6930              : 
    6931      2341151 :       if ((op0code == AND
    6932      2336916 :            && ((code == NE && (c1 & c2) != c2)
    6933      2336836 :                || (code == LTU && c1 < c2)
    6934      2336836 :                || (code == LEU && c1 <= c2)))
    6935      2341071 :           || ((op0code == IOR
    6936         4235 :               && ((code == NE && (c1 & c2) != c1)
    6937         4175 :                   || (code == GTU && c1 > c2)
    6938         4175 :                   || (code == GEU && c1 >= c2)))))
    6939          140 :         return const_true_rtx;
    6940              :     }
    6941              : 
    6942              :   /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped.  */
    6943     84423379 :   if ((code == EQ || code == NE)
    6944     62603727 :       && GET_CODE (op0) == BSWAP
    6945          316 :       && CONST_SCALAR_INT_P (op1))
    6946           85 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6947              :                                     simplify_gen_unary (BSWAP, cmp_mode,
    6948           85 :                                                         op1, cmp_mode));
    6949              : 
    6950              :   /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y).  */
    6951     62603642 :   if ((code == EQ || code == NE)
    6952     62603642 :       && GET_CODE (op0) == BSWAP
    6953          231 :       && GET_CODE (op1) == BSWAP)
    6954           18 :     return simplify_gen_relational (code, mode, cmp_mode,
    6955           18 :                                     XEXP (op0, 0), XEXP (op1, 0));
    6956              : 
    6957     84423276 :   if (op0code == POPCOUNT && op1 == const0_rtx)
    6958            0 :     switch (code)
    6959              :       {
    6960            0 :       case EQ:
    6961            0 :       case LE:
    6962            0 :       case LEU:
    6963              :         /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
    6964            0 :         return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
    6965              :                                         XEXP (op0, 0),
    6966            0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    6967              : 
    6968            0 :       case NE:
    6969            0 :       case GT:
    6970            0 :       case GTU:
    6971              :         /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
    6972            0 :         return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
    6973              :                                         XEXP (op0, 0),
    6974            0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    6975              : 
    6976              :       default:
    6977              :         break;
    6978              :       }
    6979              : 
    6980              :   /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1).  */
    6981     84423276 :   if (code == NE
    6982     33673863 :       && op1 == const0_rtx
    6983     17450375 :       && (op0code == TRUNCATE
    6984       155036 :           || (partial_subreg_p (op0)
    6985       154309 :               && subreg_lowpart_p (op0)))
    6986       131186 :       && SCALAR_INT_MODE_P (mode)
    6987     84423276 :       && STORE_FLAG_VALUE == 1)
    6988              :     {
    6989        34379 :       rtx tmp = XEXP (op0, 0);
    6990        34379 :       if (GET_CODE (tmp) == ASHIFT
    6991         2736 :           && GET_MODE (tmp) == mode
    6992          241 :           && CONST_INT_P (XEXP (tmp, 1))
    6993          241 :           && is_int_mode (GET_MODE (op0), &int_mode)
    6994        34620 :           && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    6995          241 :         return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
    6996              :     }
    6997              : 
    6998              :   /* For two unsigned booleans A and B:
    6999              : 
    7000              :      A >  B == ~B & A
    7001              :      A >= B == ~B | A
    7002              :      A <  B == ~A & B
    7003              :      A <= B == ~A | B
    7004              :      A == B == ~A ^ B (== ~B ^ A)
    7005              :      A != B ==  A ^ B
    7006              : 
    7007              :      For signed comparisons, we have to take STORE_FLAG_VALUE into account,
    7008              :      with the rules above applying for positive STORE_FLAG_VALUE and with
    7009              :      the relations reversed for negative STORE_FLAG_VALUE.  */
    7010     84423035 :   if (is_a<scalar_int_mode> (cmp_mode)
    7011     81684395 :       && COMPARISON_P (op0)
    7012     84538148 :       && COMPARISON_P (op1))
    7013              :     {
    7014        10031 :       rtx t = NULL_RTX;
    7015        10031 :       if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
    7016          755 :         t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
    7017              :       else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
    7018          720 :         t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
    7019              :       else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
    7020          720 :         t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
    7021              :       else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
    7022          720 :         t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
    7023              :       else if (code == EQ)
    7024         3173 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
    7025              :       else if (code == NE)
    7026         3943 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1);
    7027              :       if (t)
    7028              :         return t;
    7029              :     }
    7030              : 
    7031              :   return NULL_RTX;
    7032              : }
    7033              : 
    7034              : enum
    7035              : {
    7036              :   CMP_EQ = 1,
    7037              :   CMP_LT = 2,
    7038              :   CMP_GT = 4,
    7039              :   CMP_LTU = 8,
    7040              :   CMP_GTU = 16
    7041              : };
    7042              : 
    7043              : 
    7044              : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
    7045              :    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
    7046              :    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
    7047              :    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
    7048              :    For floating-point comparisons, assume that the operands were ordered.  */
    7049              : 
    7050              : static rtx
    7051       723305 : comparison_result (enum rtx_code code, int known_results)
    7052              : {
    7053       723305 :   switch (code)
    7054              :     {
    7055       132267 :     case EQ:
    7056       132267 :     case UNEQ:
    7057       132267 :       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
    7058       451084 :     case NE:
    7059       451084 :     case LTGT:
    7060       451084 :       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
    7061              : 
    7062         9424 :     case LT:
    7063         9424 :     case UNLT:
    7064         9424 :       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
    7065         8682 :     case GE:
    7066         8682 :     case UNGE:
    7067         8682 :       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
    7068              : 
    7069        12904 :     case GT:
    7070        12904 :     case UNGT:
    7071        12904 :       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
    7072        15119 :     case LE:
    7073        15119 :     case UNLE:
    7074        15119 :       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
    7075              : 
    7076        25047 :     case LTU:
    7077        25047 :       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
    7078         8851 :     case GEU:
    7079         8851 :       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
    7080              : 
    7081        49472 :     case GTU:
    7082        49472 :       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
    7083        10389 :     case LEU:
    7084        10389 :       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
    7085              : 
    7086            0 :     case ORDERED:
    7087            0 :       return const_true_rtx;
    7088           66 :     case UNORDERED:
    7089           66 :       return const0_rtx;
    7090            0 :     default:
    7091            0 :       gcc_unreachable ();
    7092              :     }
    7093              : }
    7094              : 
    7095              : /* Check if the given comparison (done in the given MODE) is actually
    7096              :    a tautology or a contradiction.  If the mode is VOIDmode, the
    7097              :    comparison is done in "infinite precision".  If no simplification
    7098              :    is possible, this function returns zero.  Otherwise, it returns
    7099              :    either const_true_rtx or const0_rtx.  */
    7100              : 
    7101              : rtx
    7102    132221783 : simplify_const_relational_operation (enum rtx_code code,
    7103              :                                      machine_mode mode,
    7104              :                                      rtx op0, rtx op1)
    7105              : {
    7106    139266134 :   rtx tem;
    7107    139266134 :   rtx trueop0;
    7108    139266134 :   rtx trueop1;
    7109              : 
    7110    139266134 :   gcc_assert (mode != VOIDmode
    7111              :               || (GET_MODE (op0) == VOIDmode
    7112              :                   && GET_MODE (op1) == VOIDmode));
    7113              : 
    7114              :   /* We only handle MODE_CC comparisons that are COMPARE against zero.  */
    7115    139266134 :   if (GET_MODE_CLASS (mode) == MODE_CC
    7116     45374944 :       && (op1 != const0_rtx
    7117     45374944 :           || GET_CODE (op0) != COMPARE))
    7118              :     return NULL_RTX;
    7119              : 
    7120              :   /* If op0 is a compare, extract the comparison arguments from it.  */
    7121    108254926 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    7122              :     {
    7123     14363736 :       op1 = XEXP (op0, 1);
    7124     14363736 :       op0 = XEXP (op0, 0);
    7125              : 
    7126     14363736 :       if (GET_MODE (op0) != VOIDmode)
    7127     14214310 :         mode = GET_MODE (op0);
    7128       149426 :       else if (GET_MODE (op1) != VOIDmode)
    7129       116976 :         mode = GET_MODE (op1);
    7130              :       else
    7131              :         return 0;
    7132              :     }
    7133              : 
    7134              :   /* We can't simplify MODE_CC values since we don't know what the
    7135              :      actual comparison is.  */
    7136    108222476 :   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
    7137              :     return 0;
    7138              : 
    7139              :   /* Make sure the constant is second.  */
    7140    108222476 :   if (swap_commutative_operands_p (op0, op1))
    7141              :     {
    7142      3167032 :       std::swap (op0, op1);
    7143      3167032 :       code = swap_condition (code);
    7144              :     }
    7145              : 
    7146    108222476 :   trueop0 = avoid_constant_pool_reference (op0);
    7147    108222476 :   trueop1 = avoid_constant_pool_reference (op1);
    7148              : 
    7149              :   /* For integer comparisons of A and B maybe we can simplify A - B and can
    7150              :      then simplify a comparison of that with zero.  If A and B are both either
    7151              :      a register or a CONST_INT, this can't help; testing for these cases will
    7152              :      prevent infinite recursion here and speed things up.
    7153              : 
    7154              :      We can only do this for EQ and NE comparisons as otherwise we may
    7155              :      lose or introduce overflow which we cannot disregard as undefined as
    7156              :      we do not know the signedness of the operation on either the left or
    7157              :      the right hand side of the comparison.  */
    7158              : 
    7159    108222476 :   if (INTEGRAL_MODE_P (mode)
    7160    105542251 :       && trueop1 != CONST0_RTX (mode)
    7161     54460134 :       && (code == EQ || code == NE)
    7162     34484122 :       && ! ((REG_P (op0)
    7163     10065880 :              || CONST_SCALAR_INT_P (trueop0)
    7164     10037579 :              || CONST_VECTOR_P (trueop0))
    7165     24446563 :             && (REG_P (op1)
    7166     14671526 :                 || CONST_SCALAR_INT_P (trueop1)
    7167      3457178 :                 || CONST_VECTOR_P (trueop1)))
    7168     13491770 :       && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
    7169              :       /* We cannot do this if tem is a nonzero address.  */
    7170      7044353 :       && ! nonzero_address_p (tem))
    7171      7044351 :     return simplify_const_relational_operation (signed_condition (code),
    7172      7044351 :                                                 mode, tem, CONST0_RTX (mode));
    7173              : 
    7174    101178125 :   if (! HONOR_NANS (mode) && code == ORDERED)
    7175            0 :     return const_true_rtx;
    7176              : 
    7177    101178125 :   if (! HONOR_NANS (mode) && code == UNORDERED)
    7178            8 :     return const0_rtx;
    7179              : 
    7180              :   /* For modes without NaNs, if the two operands are equal, we know the
    7181              :      result except if they have side-effects.  Even with NaNs we know
    7182              :      the result of unordered comparisons and, if signaling NaNs are
    7183              :      irrelevant, also the result of LT/GT/LTGT.  */
    7184    101178117 :   if ((! HONOR_NANS (trueop0)
    7185      2189053 :        || code == UNEQ || code == UNLE || code == UNGE
    7186              :        || ((code == LT || code == GT || code == LTGT)
    7187       894493 :            && ! HONOR_SNANS (trueop0)))
    7188     99991062 :       && rtx_equal_p (trueop0, trueop1)
    7189    101693693 :       && ! side_effects_p (trueop0))
    7190       515495 :     return comparison_result (code, CMP_EQ);
    7191              : 
    7192              :   /* If the operands are floating-point constants, see if we can fold
    7193              :      the result.  */
    7194    100662622 :   if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
    7195         1497 :       && CONST_DOUBLE_AS_FLOAT_P (trueop1)
    7196         1497 :       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
    7197              :     {
    7198         1497 :       const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
    7199         1497 :       const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    7200              : 
    7201              :       /* Comparisons are unordered iff at least one of the values is NaN.  */
    7202         1497 :       if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
    7203          173 :         switch (code)
    7204              :           {
    7205            0 :           case UNEQ:
    7206            0 :           case UNLT:
    7207            0 :           case UNGT:
    7208            0 :           case UNLE:
    7209            0 :           case UNGE:
    7210            0 :           case NE:
    7211            0 :           case UNORDERED:
    7212            0 :             return const_true_rtx;
    7213          173 :           case EQ:
    7214          173 :           case LT:
    7215          173 :           case GT:
    7216          173 :           case LE:
    7217          173 :           case GE:
    7218          173 :           case LTGT:
    7219          173 :           case ORDERED:
    7220          173 :             return const0_rtx;
    7221              :           default:
    7222              :             return 0;
    7223              :           }
    7224              : 
    7225         1484 :       return comparison_result (code,
    7226         1484 :                                 (real_equal (d0, d1) ? CMP_EQ :
    7227         1484 :                                  real_less (d0, d1) ? CMP_LT : CMP_GT));
    7228              :     }
    7229              : 
    7230              :   /* Otherwise, see if the operands are both integers.  */
    7231    100661125 :   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
    7232     97519439 :       && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
    7233              :     {
    7234              :       /* It would be nice if we really had a mode here.  However, the
    7235              :          largest int representable on the target is as good as
    7236              :          infinite.  */
    7237       206486 :       machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
    7238       206486 :       rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
    7239       206486 :       rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
    7240              : 
    7241       206486 :       if (wi::eq_p (ptrueop0, ptrueop1))
    7242            0 :         return comparison_result (code, CMP_EQ);
    7243              :       else
    7244              :         {
    7245       206486 :           int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
    7246       206486 :           cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
    7247       206486 :           return comparison_result (code, cr);
    7248              :         }
    7249              :     }
    7250              : 
    7251              :   /* Optimize comparisons with upper and lower bounds.  */
    7252    100454639 :   scalar_int_mode int_mode;
    7253    100454639 :   if (CONST_INT_P (trueop1)
    7254     70111623 :       && is_a <scalar_int_mode> (mode, &int_mode)
    7255     70111623 :       && HWI_COMPUTABLE_MODE_P (int_mode)
    7256    170110475 :       && !side_effects_p (trueop0))
    7257              :     {
    7258     69504584 :       int sign;
    7259     69504584 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
    7260     69504584 :       HOST_WIDE_INT val = INTVAL (trueop1);
    7261     69504584 :       HOST_WIDE_INT mmin, mmax;
    7262              : 
    7263     69504584 :       if (code == GEU
    7264     69504584 :           || code == LEU
    7265     66191269 :           || code == GTU
    7266     66191269 :           || code == LTU)
    7267              :         sign = 0;
    7268              :       else
    7269     69504584 :         sign = 1;
    7270              : 
    7271              :       /* Get a reduced range if the sign bit is zero.  */
    7272     69504584 :       if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
    7273              :         {
    7274      6264595 :           mmin = 0;
    7275      6264595 :           mmax = nonzero;
    7276              :         }
    7277              :       else
    7278              :         {
    7279     63239989 :           rtx mmin_rtx, mmax_rtx;
    7280     63239989 :           get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
    7281              : 
    7282     63239989 :           mmin = INTVAL (mmin_rtx);
    7283     63239989 :           mmax = INTVAL (mmax_rtx);
    7284     63239989 :           if (sign)
    7285              :             {
    7286     57059419 :               unsigned int sign_copies
    7287     57059419 :                 = num_sign_bit_copies (trueop0, int_mode);
    7288              : 
    7289     57059419 :               mmin >>= (sign_copies - 1);
    7290     57059419 :               mmax >>= (sign_copies - 1);
    7291              :             }
    7292              :         }
    7293              : 
    7294     69504584 :       switch (code)
    7295              :         {
    7296              :         /* x >= y is always true for y <= mmin, always false for y > mmax.  */
    7297       538669 :         case GEU:
    7298       538669 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    7299         6042 :             return const_true_rtx;
    7300       532627 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    7301           48 :             return const0_rtx;
    7302              :           break;
    7303       963304 :         case GE:
    7304       963304 :           if (val <= mmin)
    7305         2098 :             return const_true_rtx;
    7306       961206 :           if (val > mmax)
    7307            0 :             return const0_rtx;
    7308              :           break;
    7309              : 
    7310              :         /* x <= y is always true for y >= mmax, always false for y < mmin.  */
    7311      2774646 :         case LEU:
    7312      2774646 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    7313        15293 :             return const_true_rtx;
    7314      2759353 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    7315            0 :             return const0_rtx;
    7316              :           break;
    7317      2567838 :         case LE:
    7318      2567838 :           if (val >= mmax)
    7319          459 :             return const_true_rtx;
    7320      2567379 :           if (val < mmin)
    7321            0 :             return const0_rtx;
    7322              :           break;
    7323              : 
    7324     25177065 :         case EQ:
    7325              :           /* x == y is always false for y out of range.  */
    7326     25177065 :           if (val < mmin || val > mmax)
    7327          486 :             return const0_rtx;
    7328              :           break;
    7329              : 
    7330              :         /* x > y is always false for y >= mmax, always true for y < mmin.  */
    7331      2489903 :         case GTU:
    7332      2489903 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    7333        40274 :             return const0_rtx;
    7334      2449629 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    7335            0 :             return const_true_rtx;
    7336              :           break;
    7337      1831582 :         case GT:
    7338      1831582 :           if (val >= mmax)
    7339          325 :             return const0_rtx;
    7340      1831257 :           if (val < mmin)
    7341            2 :             return const_true_rtx;
    7342              :           break;
    7343              : 
    7344              :         /* x < y is always false for y <= mmin, always true for y > mmax.  */
    7345       842034 :         case LTU:
    7346       842034 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    7347         3897 :             return const0_rtx;
    7348       838137 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    7349        76653 :             return const_true_rtx;
    7350              :           break;
    7351      1083784 :         case LT:
    7352      1083784 :           if (val <= mmin)
    7353         2344 :             return const0_rtx;
    7354      1081440 :           if (val > mmax)
    7355         3364 :             return const_true_rtx;
    7356              :           break;
    7357              : 
    7358     31235759 :         case NE:
    7359              :           /* x != y is always true for y out of range.  */
    7360     31235759 :           if (val < mmin || val > mmax)
    7361          121 :             return const_true_rtx;
    7362              :           break;
    7363              : 
    7364              :         default:
    7365              :           break;
    7366              :         }
    7367              :     }
    7368              : 
    7369              :   /* Optimize integer comparisons with zero.  */
    7370    100303233 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    7371     97204628 :       && trueop1 == const0_rtx
    7372     50341564 :       && !side_effects_p (trueop0))
    7373              :     {
    7374              :       /* Some addresses are known to be nonzero.  We don't know
    7375              :          their sign, but equality comparisons are known.  */
    7376     50188248 :       if (nonzero_address_p (trueop0))
    7377              :         {
    7378          533 :           if (code == EQ || code == LEU)
    7379          274 :             return const0_rtx;
    7380          259 :           if (code == NE || code == GTU)
    7381          259 :             return const_true_rtx;
    7382              :         }
    7383              : 
    7384              :       /* See if the first operand is an IOR with a constant.  If so, we
    7385              :          may be able to determine the result of this comparison.  */
    7386     50187715 :       if (GET_CODE (op0) == IOR)
    7387              :         {
    7388       691895 :           rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
    7389       691895 :           if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
    7390              :             {
    7391          229 :               int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
    7392          458 :               int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
    7393          229 :                               && (UINTVAL (inner_const)
    7394          229 :                                   & (HOST_WIDE_INT_1U
    7395              :                                      << sign_bitnum)));
    7396              : 
    7397          229 :               switch (code)
    7398              :                 {
    7399              :                 case EQ:
    7400              :                 case LEU:
    7401              :                   return const0_rtx;
    7402            4 :                 case NE:
    7403            4 :                 case GTU:
    7404            4 :                   return const_true_rtx;
    7405           17 :                 case LT:
    7406           17 :                 case LE:
    7407           17 :                   if (has_sign)
    7408            2 :                     return const_true_rtx;
    7409              :                   break;
    7410          202 :                 case GT:
    7411          202 :                 case GE:
    7412          202 :                   if (has_sign)
    7413              :                     return const0_rtx;
    7414              :                   break;
    7415              :                 default:
    7416              :                   break;
    7417              :                 }
    7418              :             }
    7419              :         }
    7420              :     }
    7421              : 
    7422              :   /* Optimize comparison of ABS with zero.  */
    7423     50693091 :   if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
    7424    150841958 :       && (GET_CODE (trueop0) == ABS
    7425     50538881 :           || (GET_CODE (trueop0) == FLOAT_EXTEND
    7426          100 :               && GET_CODE (XEXP (trueop0, 0)) == ABS)))
    7427              :     {
    7428          581 :       switch (code)
    7429              :         {
    7430           60 :         case LT:
    7431              :           /* Optimize abs(x) < 0.0.  */
    7432           60 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
    7433            0 :             return const0_rtx;
    7434              :           break;
    7435              : 
    7436           42 :         case GE:
    7437              :           /* Optimize abs(x) >= 0.0.  */
    7438           42 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
    7439            0 :             return const_true_rtx;
    7440              :           break;
    7441              : 
    7442            0 :         case UNGE:
    7443              :           /* Optimize ! (abs(x) < 0.0).  */
    7444            0 :           return const_true_rtx;
    7445              : 
    7446              :         default:
    7447              :           break;
    7448              :         }
    7449              :     }
    7450              : 
    7451              :   return 0;
    7452              : }
    7453              : 
    7454              : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
    7455              :    where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
    7456              :    or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
    7457              :    can be simplified to that or NULL_RTX if not.
    7458              :    Assume X is compared against zero with CMP_CODE and the true
    7459              :    arm is TRUE_VAL and the false arm is FALSE_VAL.  */
    7460              : 
    7461              : rtx
    7462     31472459 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
    7463              :                                          rtx true_val, rtx false_val)
    7464              : {
    7465     31472459 :   if (cmp_code != EQ && cmp_code != NE)
    7466              :     return NULL_RTX;
    7467              : 
    7468              :   /* Result on X == 0 and X !=0 respectively.  */
    7469     22603142 :   rtx on_zero, on_nonzero;
    7470     22603142 :   if (cmp_code == EQ)
    7471              :     {
    7472              :       on_zero = true_val;
    7473              :       on_nonzero = false_val;
    7474              :     }
    7475              :   else
    7476              :     {
    7477     12353474 :       on_zero = false_val;
    7478     12353474 :       on_nonzero = true_val;
    7479              :     }
    7480              : 
    7481     22603142 :   rtx_code op_code = GET_CODE (on_nonzero);
    7482     22603142 :   if ((op_code != CLZ && op_code != CTZ)
    7483         2024 :       || !rtx_equal_p (XEXP (on_nonzero, 0), x)
    7484     22604198 :       || !CONST_INT_P (on_zero))
    7485              :     return NULL_RTX;
    7486              : 
    7487          301 :   HOST_WIDE_INT op_val;
    7488          301 :   scalar_int_mode mode ATTRIBUTE_UNUSED
    7489          301 :     = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
    7490            0 :   if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
    7491          602 :        || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
    7492          325 :       && op_val == INTVAL (on_zero))
    7493            0 :     return on_nonzero;
    7494              : 
    7495              :   return NULL_RTX;
    7496              : }
    7497              : 
    7498              : /* Try to simplify X given that it appears within operand OP of a
    7499              :    VEC_MERGE operation whose mask is MASK.  X need not use the same
    7500              :    vector mode as the VEC_MERGE, but it must have the same number of
    7501              :    elements.
    7502              : 
    7503              :    Return the simplified X on success, otherwise return NULL_RTX.  */
    7504              : 
    7505              : rtx
    7506      2123784 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
    7507              : {
    7508      2123784 :   gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
    7509      4247568 :   poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
    7510      2123784 :   if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
    7511              :     {
    7512         5491 :       if (side_effects_p (XEXP (x, 1 - op)))
    7513              :         return NULL_RTX;
    7514              : 
    7515         5267 :       return XEXP (x, op);
    7516              :     }
    7517      2118293 :   if (UNARY_P (x)
    7518       383029 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7519      2176095 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
    7520              :     {
    7521        24255 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7522        24255 :       if (top0)
    7523          448 :         return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
    7524          448 :                                    GET_MODE (XEXP (x, 0)));
    7525              :     }
    7526      2117845 :   if (BINARY_P (x)
    7527       208785 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7528       416942 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7529       181373 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7530      2406065 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
    7531              :     {
    7532       144110 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7533       144110 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7534       144110 :       if (top0 || top1)
    7535              :         {
    7536          952 :           if (COMPARISON_P (x))
    7537            0 :             return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
    7538            0 :                                             GET_MODE (XEXP (x, 0)) != VOIDmode
    7539              :                                             ? GET_MODE (XEXP (x, 0))
    7540            0 :                                             : GET_MODE (XEXP (x, 1)),
    7541              :                                             top0 ? top0 : XEXP (x, 0),
    7542            0 :                                             top1 ? top1 : XEXP (x, 1));
    7543              :           else
    7544          952 :             return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
    7545              :                                         top0 ? top0 : XEXP (x, 0),
    7546          952 :                                         top1 ? top1 : XEXP (x, 1));
    7547              :         }
    7548              :     }
    7549      2116893 :   if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
    7550        59830 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7551       119660 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7552        59830 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7553       119660 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
    7554        59830 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
    7555      2133617 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
    7556              :     {
    7557         8362 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7558         8362 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7559         8362 :       rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
    7560         8362 :       if (top0 || top1 || top2)
    7561          448 :         return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
    7562          448 :                                      GET_MODE (XEXP (x, 0)),
    7563              :                                      top0 ? top0 : XEXP (x, 0),
    7564              :                                      top1 ? top1 : XEXP (x, 1),
    7565          448 :                                      top2 ? top2 : XEXP (x, 2));
    7566              :     }
    7567              :   return NULL_RTX;
    7568              : }
    7569              : 
    7570              : 
    7571              : /* Simplify CODE, an operation with result mode MODE and three operands,
    7572              :    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
    7573              :    a constant.  Return 0 if no simplifications is possible.  */
    7574              : 
    7575              : rtx
    7576     43839980 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
    7577              :                                               machine_mode op0_mode,
    7578              :                                               rtx op0, rtx op1, rtx op2)
    7579              : {
    7580     43839980 :   bool any_change = false;
    7581     43839980 :   rtx tem, trueop2;
    7582     43839980 :   scalar_int_mode int_mode, int_op0_mode;
    7583     43839980 :   unsigned int n_elts;
    7584              : 
    7585     43839980 :   switch (code)
    7586              :     {
    7587       336323 :     case FMA:
    7588              :       /* Simplify negations around the multiplication.  */
    7589              :       /* -a * -b + c  =>  a * b + c.  */
    7590       336323 :       if (GET_CODE (op0) == NEG)
    7591              :         {
    7592        83004 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    7593        83004 :           if (tem)
    7594          271 :             op1 = tem, op0 = XEXP (op0, 0), any_change = true;
    7595              :         }
    7596       253319 :       else if (GET_CODE (op1) == NEG)
    7597              :         {
    7598         1068 :           tem = simplify_unary_operation (NEG, mode, op0, mode);
    7599         1068 :           if (tem)
    7600            0 :             op0 = tem, op1 = XEXP (op1, 0), any_change = true;
    7601              :         }
    7602              : 
    7603              :       /* Canonicalize the two multiplication operands.  */
    7604              :       /* a * -b + c  =>  -b * a + c.  */
    7605       336323 :       if (swap_commutative_operands_p (op0, op1))
    7606              :         std::swap (op0, op1), any_change = true;
    7607              : 
    7608       306536 :       if (any_change)
    7609        30049 :         return gen_rtx_FMA (mode, op0, op1, op2);
    7610              :       return NULL_RTX;
    7611              : 
    7612       760034 :     case SIGN_EXTRACT:
    7613       760034 :     case ZERO_EXTRACT:
    7614       760034 :       if (CONST_INT_P (op0)
    7615        17318 :           && CONST_INT_P (op1)
    7616        17318 :           && CONST_INT_P (op2)
    7617     43840012 :           && is_a <scalar_int_mode> (mode, &int_mode)
    7618           32 :           && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
    7619       760066 :           && HWI_COMPUTABLE_MODE_P (int_mode))
    7620              :         {
    7621              :           /* Extracting a bit-field from a constant */
    7622           32 :           unsigned HOST_WIDE_INT val = UINTVAL (op0);
    7623           32 :           HOST_WIDE_INT op1val = INTVAL (op1);
    7624           32 :           HOST_WIDE_INT op2val = INTVAL (op2);
    7625           32 :           if (!BITS_BIG_ENDIAN)
    7626           32 :             val >>= op2val;
    7627              :           else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
    7628              :             val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
    7629              :           else
    7630              :             /* Not enough information to calculate the bit position.  */
    7631              :             break;
    7632              : 
    7633           32 :           if (HOST_BITS_PER_WIDE_INT != op1val)
    7634              :             {
    7635              :               /* First zero-extend.  */
    7636           29 :               val &= (HOST_WIDE_INT_1U << op1val) - 1;
    7637              :               /* If desired, propagate sign bit.  */
    7638           29 :               if (code == SIGN_EXTRACT
    7639            5 :                   && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
    7640            5 :                      != 0)
    7641            2 :                 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
    7642              :             }
    7643              : 
    7644           32 :           return gen_int_mode (val, int_mode);
    7645              :         }
    7646              :       break;
    7647              : 
    7648     41658516 :     case IF_THEN_ELSE:
    7649     41658516 :       if (CONST_INT_P (op0))
    7650       200390 :         return op0 != const0_rtx ? op1 : op2;
    7651              : 
    7652              :       /* Convert c ? a : a into "a".  Beware that two rtx_equal_p MEMs can
    7653              :          still carry different memory attributes, in particular incompatible
    7654              :          alias sets; returning one of them would narrow the aliasing of the
    7655              :          result to that operand's, which is unsound (PR125683).  When the
    7656              :          attributes differ, fold to a copy that keeps only what both operands
    7657              :          guarantee, like merge_memattrs does when cross-jumping commons two
    7658              :          memory references.  */
    7659     41458126 :       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
    7660              :         {
    7661         3364 :           if (op1 == op2
    7662         2912 :               || !MEM_P (op1)
    7663         3386 :               || (mem_attrs_eq_p (get_mem_attrs (op1), get_mem_attrs (op2))
    7664            8 :                   && MEM_READONLY_P (op1) == MEM_READONLY_P (op2)
    7665            8 :                   && MEM_NOTRAP_P (op1) == MEM_NOTRAP_P (op2)
    7666            8 :                   && MEM_POINTER (op1) == MEM_POINTER (op2)))
    7667              :             return op1;
    7668              : 
    7669              :           /* For BLKmode the size in MEM_ATTRS describes the access itself,
    7670              :              so it cannot be dropped.  Volatility is not merged either: it
    7671              :              constrains when the access happens rather than describing the
    7672              :              memory, so unlike the flags below it cannot be weakened to what
    7673              :              both operands allow.  Dropping it would lose a required access;
    7674              :              merge_memattrs and noce_try_cmove_arith instead set it, which is
    7675              :              sound but claims more than either operand did.  Those two have to
    7676              :              put something on a reference they are already committed to, while
    7677              :              this fold is free to do nothing, and if-conversion never reaches
    7678              :              it with a volatile operand in any case: side_effects_p is true
    7679              :              for one, so noce_operand_ok rejects it.  Decline the fold.  */
    7680           14 :           if (GET_MODE (op1) != BLKmode
    7681           14 :               && MEM_VOLATILE_P (op1) == MEM_VOLATILE_P (op2))
    7682              :             {
    7683           14 :               rtx mem = shallow_copy_rtx (op1);
    7684              : 
    7685           14 :               if (MEM_ALIAS_SET (op1) != MEM_ALIAS_SET (op2))
    7686            1 :                 set_mem_alias_set (mem, 0);
    7687              : 
    7688           14 :               if (!mem_expr_equal_p (MEM_EXPR (op1), MEM_EXPR (op2)))
    7689              :                 {
    7690           14 :                   set_mem_expr (mem, NULL_TREE);
    7691           14 :                   clear_mem_offset (mem);
    7692              :                 }
    7693            0 :               else if (MEM_OFFSET_KNOWN_P (op1) != MEM_OFFSET_KNOWN_P (op2)
    7694            0 :                        || (MEM_OFFSET_KNOWN_P (op1)
    7695            0 :                            && maybe_ne (MEM_OFFSET (op1), MEM_OFFSET (op2))))
    7696            0 :                 clear_mem_offset (mem);
    7697              : 
    7698              :               /* Unlike merge_memattrs, which fixes up two references that
    7699              :                  both stay in the stream, this returns a single reference
    7700              :                  that stands in for either arm, so keep the size only when
    7701              :                  both agree rather than taking the larger one.  */
    7702           28 :               if (!MEM_SIZE_KNOWN_P (op1) || !MEM_SIZE_KNOWN_P (op2)
    7703           28 :                   || maybe_ne (MEM_SIZE (op1), MEM_SIZE (op2)))
    7704            0 :                 clear_mem_size (mem);
    7705              : 
    7706           14 :               set_mem_align (mem, MIN (MEM_ALIGN (op1), MEM_ALIGN (op2)));
    7707              : 
    7708              :               /* MEM_READONLY_P, MEM_NOTRAP_P and MEM_POINTER are rtx flag
    7709              :                  bits rather than MEM_ATTRS fields, so shallow_copy_rtx has
    7710              :                  already taken them from OP1 and they need clearing by hand.
    7711              :                  Each asserts something about the reference, so the copy may
    7712              :                  only keep it when both operands do, as merge_memattrs does
    7713              :                  for the first two.  */
    7714           14 :               if (MEM_READONLY_P (op1) != MEM_READONLY_P (op2))
    7715            0 :                 MEM_READONLY_P (mem) = 0;
    7716           14 :               if (MEM_NOTRAP_P (op1) != MEM_NOTRAP_P (op2))
    7717            0 :                 MEM_NOTRAP_P (mem) = 0;
    7718           14 :               if (MEM_POINTER (op1) != MEM_POINTER (op2))
    7719            0 :                 MEM_POINTER (mem) = 0;
    7720              : 
    7721              :               return mem;
    7722              :             }
    7723              :         }
    7724              : 
    7725              :       /* Convert a != b ? a : b into "a".  */
    7726     41454762 :       if (GET_CODE (op0) == NE
    7727     16166294 :           && ! side_effects_p (op0)
    7728     16117675 :           && ! HONOR_NANS (mode)
    7729     15927248 :           && ! HONOR_SIGNED_ZEROS (mode)
    7730     57382010 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7731       127875 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7732     15926921 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7733         3610 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7734              :         return op1;
    7735              : 
    7736              :       /* Convert a == b ? a : b into "b".  */
    7737     41454196 :       if (GET_CODE (op0) == EQ
    7738     12838747 :           && ! side_effects_p (op0)
    7739     12819702 :           && ! HONOR_NANS (mode)
    7740     12794446 :           && ! HONOR_SIGNED_ZEROS (mode)
    7741     54248642 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7742        15024 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7743     12794442 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7744         7634 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7745              :         return op2;
    7746              : 
    7747              :       /* Convert a != 0 ? -a : 0 into "-a".  */
    7748     41454174 :       if (GET_CODE (op0) == NE
    7749     16165728 :           && ! side_effects_p (op0)
    7750     16117109 :           && ! HONOR_NANS (mode)
    7751     15926682 :           && ! HONOR_SIGNED_ZEROS (mode)
    7752     15926682 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7753     12162870 :           && op2 == CONST0_RTX (mode)
    7754       179843 :           && GET_CODE (op1) == NEG
    7755     41454214 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
    7756              :         return op1;
    7757              : 
    7758              :       /* Convert a == 0 ? 0 : -a into "-a".  */
    7759     41454165 :       if (GET_CODE (op0) == EQ
    7760     12838725 :           && ! side_effects_p (op0)
    7761     12819680 :           && ! HONOR_NANS (mode)
    7762     12794424 :           && ! HONOR_SIGNED_ZEROS (mode)
    7763     12794424 :           && op1 == CONST0_RTX (mode)
    7764        41907 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7765        21523 :           && GET_CODE (op2) == NEG
    7766     41454171 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
    7767              :         return op2;
    7768              : 
    7769              :       /* Convert (!c) != {0,...,0} ? a : b into
    7770              :          c != {0,...,0} ? b : a for vector modes.  */
    7771     41454159 :       if (VECTOR_MODE_P (GET_MODE (op1))
    7772        14815 :           && GET_CODE (op0) == NE
    7773          477 :           && GET_CODE (XEXP (op0, 0)) == NOT
    7774            0 :           && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
    7775              :         {
    7776            0 :           rtx cv = XEXP (op0, 1);
    7777            0 :           int nunits;
    7778            0 :           bool ok = true;
    7779            0 :           if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
    7780              :             ok = false;
    7781              :           else
    7782            0 :             for (int i = 0; i < nunits; ++i)
    7783            0 :               if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
    7784              :                 {
    7785              :                   ok = false;
    7786              :                   break;
    7787              :                 }
    7788            0 :           if (ok)
    7789              :             {
    7790            0 :               rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
    7791              :                                         XEXP (XEXP (op0, 0), 0),
    7792              :                                         XEXP (op0, 1));
    7793            0 :               rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
    7794            0 :               return retval;
    7795              :             }
    7796              :         }
    7797              : 
    7798              :       /* Convert x == 0 ? N : clz (x) into clz (x) when
    7799              :          CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
    7800              :          Similarly for ctz (x).  */
    7801     41453166 :       if (COMPARISON_P (op0) && !side_effects_p (op0)
    7802     82806944 :           && XEXP (op0, 1) == const0_rtx)
    7803              :         {
    7804     31472459 :           rtx simplified
    7805     31472459 :             = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
    7806              :                                      op1, op2);
    7807     31472459 :           if (simplified)
    7808              :             return simplified;
    7809              :         }
    7810              : 
    7811     41454159 :       if (COMPARISON_P (op0) && ! side_effects_p (op0))
    7812              :         {
    7813     82802054 :           machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
    7814     41352785 :                                         ? GET_MODE (XEXP (op0, 1))
    7815              :                                         : GET_MODE (XEXP (op0, 0)));
    7816     41352785 :           rtx temp;
    7817              : 
    7818              :           /* Look for happy constants in op1 and op2.  */
    7819     41352785 :           if (CONST_INT_P (op1) && CONST_INT_P (op2))
    7820              :             {
    7821       231253 :               HOST_WIDE_INT t = INTVAL (op1);
    7822       231253 :               HOST_WIDE_INT f = INTVAL (op2);
    7823              : 
    7824       231253 :               if (t == STORE_FLAG_VALUE && f == 0)
    7825        55290 :                 code = GET_CODE (op0);
    7826       175963 :               else if (t == 0 && f == STORE_FLAG_VALUE)
    7827              :                 {
    7828        31258 :                   enum rtx_code tmp;
    7829        31258 :                   tmp = reversed_comparison_code (op0, NULL);
    7830        31258 :                   if (tmp == UNKNOWN)
    7831              :                     break;
    7832              :                   code = tmp;
    7833              :                 }
    7834              :               else
    7835              :                 break;
    7836              : 
    7837        81383 :               return simplify_gen_relational (code, mode, cmp_mode,
    7838        81383 :                                               XEXP (op0, 0), XEXP (op0, 1));
    7839              :             }
    7840              : 
    7841     41121532 :           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
    7842              :                                                 cmp_mode, XEXP (op0, 0),
    7843              :                                                 XEXP (op0, 1));
    7844              : 
    7845              :           /* See if any simplifications were possible.  */
    7846     41121532 :           if (temp)
    7847              :             {
    7848         7009 :               if (CONST_INT_P (temp))
    7849          827 :                 return temp == const0_rtx ? op2 : op1;
    7850         6182 :               else if (temp)
    7851         6182 :                 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
    7852              :             }
    7853              :         }
    7854              :       break;
    7855              : 
    7856      1085107 :     case VEC_MERGE:
    7857      1085107 :       gcc_assert (GET_MODE (op0) == mode);
    7858      1085107 :       gcc_assert (GET_MODE (op1) == mode);
    7859      1085107 :       gcc_assert (VECTOR_MODE_P (mode));
    7860      1085107 :       trueop2 = avoid_constant_pool_reference (op2);
    7861      1085107 :       if (CONST_INT_P (trueop2)
    7862      1843657 :           && GET_MODE_NUNITS (mode).is_constant (&n_elts))
    7863              :         {
    7864       758550 :           unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
    7865       758550 :           unsigned HOST_WIDE_INT mask;
    7866       758550 :           if (n_elts == HOST_BITS_PER_WIDE_INT)
    7867              :             mask = -1;
    7868              :           else
    7869       756073 :             mask = (HOST_WIDE_INT_1U << n_elts) - 1;
    7870              : 
    7871       758550 :           if (!(sel & mask) && !side_effects_p (op0))
    7872              :             return op1;
    7873       758125 :           if ((sel & mask) == mask && !side_effects_p (op1))
    7874              :             return op0;
    7875              : 
    7876       747024 :           rtx trueop0 = avoid_constant_pool_reference (op0);
    7877       747024 :           rtx trueop1 = avoid_constant_pool_reference (op1);
    7878       747024 :           if (GET_CODE (trueop0) == CONST_VECTOR
    7879        11357 :               && GET_CODE (trueop1) == CONST_VECTOR)
    7880              :             {
    7881         6968 :               rtvec v = rtvec_alloc (n_elts);
    7882         6968 :               unsigned int i;
    7883              : 
    7884        67198 :               for (i = 0; i < n_elts; i++)
    7885        53262 :                 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
    7886        53262 :                                     ? CONST_VECTOR_ELT (trueop0, i)
    7887        31413 :                                     : CONST_VECTOR_ELT (trueop1, i));
    7888         6968 :               return gen_rtx_CONST_VECTOR (mode, v);
    7889              :             }
    7890              : 
    7891       740056 :           if (swap_commutative_operands_p (op0, op1)
    7892              :               /* Two operands have same precedence, then first bit of mask
    7893              :                  select first operand.  */
    7894       740056 :               || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
    7895        33844 :             return simplify_gen_ternary (code, mode, mode, op1, op0,
    7896        67688 :                                          GEN_INT (~sel & mask));
    7897              : 
    7898              :           /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
    7899              :              if no element from a appears in the result.  */
    7900       706212 :           if (GET_CODE (op0) == VEC_MERGE)
    7901              :             {
    7902        47331 :               tem = avoid_constant_pool_reference (XEXP (op0, 2));
    7903        47331 :               if (CONST_INT_P (tem))
    7904              :                 {
    7905        31608 :                   unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
    7906        31608 :                   if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
    7907           99 :                     return simplify_gen_ternary (code, mode, mode,
    7908           99 :                                                  XEXP (op0, 1), op1, op2);
    7909        31509 :                   if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
    7910          815 :                     return simplify_gen_ternary (code, mode, mode,
    7911          815 :                                                  XEXP (op0, 0), op1, op2);
    7912              : 
    7913              :                   /* Replace (vec_merge (vec_merge a b m) a n) with
    7914              :                      (vec_merge a b (m|~n)).  */
    7915        30694 :                   if (rtx_equal_p (XEXP (op0, 0), op1)
    7916        30694 :                       && ! side_effects_p (op1))
    7917          143 :                     return simplify_gen_ternary (code, mode, mode,
    7918              :                                                  op1, XEXP (op0, 1),
    7919          286 :                                                  GEN_INT ((sel0 | ~sel) & mask));
    7920              :                   /* Replace (vec_merge (vec_merge b a m) a n) with
    7921              :                      (vec_merge b a (m&n)).  */
    7922        30551 :                   if (rtx_equal_p (XEXP (op0, 1), op1)
    7923        30551 :                       && ! side_effects_p (op1))
    7924           48 :                     return simplify_gen_ternary (code, mode, mode,
    7925              :                                                  XEXP (op0, 0), op1,
    7926           48 :                                                  GEN_INT (sel & sel0 & mask));
    7927              :                 }
    7928              :             }
    7929       705107 :           if (GET_CODE (op1) == VEC_MERGE)
    7930              :             {
    7931          585 :               tem = avoid_constant_pool_reference (XEXP (op1, 2));
    7932          585 :               if (CONST_INT_P (tem))
    7933              :                 {
    7934          554 :                   unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
    7935          554 :                   if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
    7936          523 :                     return simplify_gen_ternary (code, mode, mode,
    7937          523 :                                                  op0, XEXP (op1, 1), op2);
    7938           31 :                   if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
    7939            4 :                     return simplify_gen_ternary (code, mode, mode,
    7940            4 :                                                  op0, XEXP (op1, 0), op2);
    7941              : 
    7942              :                   /* Replace (vec_merge a (vec_merge a b m) n) with
    7943              :                      (vec_merge a b (m|n)).  */
    7944           27 :                   if (rtx_equal_p (XEXP (op1, 0), op0)
    7945           27 :                       && ! side_effects_p (op0))
    7946            1 :                     return simplify_gen_ternary (code, mode, mode,
    7947              :                                                  op0, XEXP (op1, 1),
    7948            1 :                                                  GEN_INT ((sel | sel1) & mask));
    7949              : 
    7950              :                   /* Replace (vec_merge a (vec_merge b a m) n) with
    7951              :                      (vec_merge a b (~m|n)).  */
    7952           26 :                   if (rtx_equal_p (XEXP (op1, 1), op0)
    7953           26 :                       && ! side_effects_p (op0))
    7954            0 :                     return simplify_gen_ternary (code, mode, mode,
    7955              :                                                  op0, XEXP (op1, 0),
    7956            0 :                                                  GEN_INT ((sel | ~sel1) & mask));
    7957              :                 }
    7958              :             }
    7959              : 
    7960              :           /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
    7961              :              with a.  */
    7962       704579 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7963       398779 :               && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
    7964         5369 :               && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
    7965       715317 :               && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
    7966              :             {
    7967         5301 :               tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
    7968         5301 :               if (CONST_INT_P (tem) && CONST_INT_P (op2))
    7969              :                 {
    7970         5301 :                   if (XEXP (XEXP (op0, 0), 0) == op1
    7971            2 :                       && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
    7972              :                     return op1;
    7973              :                 }
    7974              :             }
    7975              :           /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
    7976              :              (const_int N))
    7977              :              with (vec_concat (X) (B)) if N == 1 or
    7978              :              (vec_concat (A) (X)) if N == 2.  */
    7979       704577 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7980       398777 :               && GET_CODE (op1) == CONST_VECTOR
    7981       596982 :               && known_eq (CONST_VECTOR_NUNITS (op1), 2)
    7982         1804 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7983       705479 :               && IN_RANGE (sel, 1, 2))
    7984              :             {
    7985          900 :               rtx newop0 = XEXP (op0, 0);
    7986          900 :               rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
    7987          900 :               if (sel == 2)
    7988          111 :                 std::swap (newop0, newop1);
    7989          900 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7990              :             }
    7991              :           /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
    7992              :              with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
    7993              :              Only applies for vectors of two elements.  */
    7994       703677 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7995       397877 :               && GET_CODE (op1) == VEC_CONCAT
    7996            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7997            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7998       703677 :               && IN_RANGE (sel, 1, 2))
    7999              :             {
    8000            0 :               rtx newop0 = XEXP (op0, 0);
    8001            0 :               rtx newop1 = XEXP (op1, 2 - sel);
    8002            0 :               rtx otherop = XEXP (op1, sel - 1);
    8003            0 :               if (sel == 2)
    8004            0 :                 std::swap (newop0, newop1);
    8005              :               /* Don't want to throw away the other part of the vec_concat if
    8006              :                  it has side-effects.  */
    8007            0 :               if (!side_effects_p (otherop))
    8008            0 :                 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8009              :             }
    8010              : 
    8011              :           /* Replace:
    8012              : 
    8013              :               (vec_merge:outer (vec_duplicate:outer x:inner)
    8014              :                                (subreg:outer y:inner 0)
    8015              :                                (const_int N))
    8016              : 
    8017              :              with (vec_concat:outer x:inner y:inner) if N == 1,
    8018              :              or (vec_concat:outer y:inner x:inner) if N == 2.
    8019              : 
    8020              :              Implicitly, this means we have a paradoxical subreg, but such
    8021              :              a check is cheap, so make it anyway.
    8022              : 
    8023              :              Only applies for vectors of two elements.  */
    8024       703677 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8025       397877 :               && GET_CODE (op1) == SUBREG
    8026        35075 :               && GET_MODE (op1) == GET_MODE (op0)
    8027        35075 :               && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
    8028            0 :               && paradoxical_subreg_p (op1)
    8029            0 :               && subreg_lowpart_p (op1)
    8030            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8031            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8032       703677 :               && IN_RANGE (sel, 1, 2))
    8033              :             {
    8034            0 :               rtx newop0 = XEXP (op0, 0);
    8035            0 :               rtx newop1 = SUBREG_REG (op1);
    8036            0 :               if (sel == 2)
    8037            0 :                 std::swap (newop0, newop1);
    8038            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8039              :             }
    8040              : 
    8041              :           /* Same as above but with switched operands:
    8042              :                 Replace (vec_merge:outer (subreg:outer x:inner 0)
    8043              :                                          (vec_duplicate:outer y:inner)
    8044              :                                (const_int N))
    8045              : 
    8046              :              with (vec_concat:outer x:inner y:inner) if N == 1,
    8047              :              or (vec_concat:outer y:inner x:inner) if N == 2.  */
    8048       703677 :           if (GET_CODE (op1) == VEC_DUPLICATE
    8049        53857 :               && GET_CODE (op0) == SUBREG
    8050        20654 :               && GET_MODE (op0) == GET_MODE (op1)
    8051        20654 :               && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
    8052            0 :               && paradoxical_subreg_p (op0)
    8053            0 :               && subreg_lowpart_p (op0)
    8054            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8055            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8056       703677 :               && IN_RANGE (sel, 1, 2))
    8057              :             {
    8058            0 :               rtx newop0 = SUBREG_REG (op0);
    8059            0 :               rtx newop1 = XEXP (op1, 0);
    8060            0 :               if (sel == 2)
    8061            0 :                 std::swap (newop0, newop1);
    8062            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8063              :             }
    8064              : 
    8065              :           /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
    8066              :                                  (const_int n))
    8067              :              with (vec_concat x y) or (vec_concat y x) depending on value
    8068              :              of N.  */
    8069       703677 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8070       397877 :               && GET_CODE (op1) == VEC_DUPLICATE
    8071          208 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8072            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8073       703677 :               && IN_RANGE (sel, 1, 2))
    8074              :             {
    8075            0 :               rtx newop0 = XEXP (op0, 0);
    8076            0 :               rtx newop1 = XEXP (op1, 0);
    8077            0 :               if (sel == 2)
    8078            0 :                 std::swap (newop0, newop1);
    8079              : 
    8080            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8081              :             }
    8082              :         }
    8083              : 
    8084      1030234 :       if (rtx_equal_p (op0, op1)
    8085      1030234 :           && !side_effects_p (op2) && !side_effects_p (op1))
    8086              :         return op0;
    8087              : 
    8088      1029938 :       if (!side_effects_p (op2))
    8089              :         {
    8090      1026150 :           rtx top0
    8091      1026150 :             = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
    8092      1026150 :           rtx top1
    8093      1026150 :             = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
    8094      1026150 :           if (top0 || top1)
    8095          998 :             return simplify_gen_ternary (code, mode, mode,
    8096              :                                          top0 ? top0 : op0,
    8097          819 :                                          top1 ? top1 : op1, op2);
    8098              :         }
    8099              : 
    8100              :       break;
    8101              : 
    8102            0 :     default:
    8103            0 :       gcc_unreachable ();
    8104              :     }
    8105              : 
    8106              :   return 0;
    8107              : }
    8108              : 
    8109              : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
    8110              :    starting at byte FIRST_BYTE.  Return true on success and add the
    8111              :    bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
    8112              :    that the bytes follow target memory order.  Leave BYTES unmodified
    8113              :    on failure.
    8114              : 
    8115              :    MODE is the mode of X.  The caller must reserve NUM_BYTES bytes in
    8116              :    BYTES before calling this function.  */
    8117              : 
    8118              : bool
    8119     13939368 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
    8120              :                    unsigned int first_byte, unsigned int num_bytes)
    8121              : {
    8122              :   /* Check the mode is sensible.  */
    8123     13939368 :   gcc_assert (GET_MODE (x) == VOIDmode
    8124              :               ? is_a <scalar_int_mode> (mode)
    8125              :               : mode == GET_MODE (x));
    8126              : 
    8127     13939368 :   if (GET_CODE (x) == CONST_VECTOR)
    8128              :     {
    8129              :       /* CONST_VECTOR_ELT follows target memory order, so no shuffling
    8130              :          is necessary.  The only complication is that MODE_VECTOR_BOOL
    8131              :          vectors can have several elements per byte.  */
    8132      1123924 :       unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8133              :                                                    GET_MODE_NUNITS (mode));
    8134       561962 :       unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
    8135       561962 :       if (elt_bits < BITS_PER_UNIT)
    8136              :         {
    8137              :           /* This is the only case in which elements can be smaller than
    8138              :              a byte.  */
    8139            0 :           gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    8140            0 :           auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
    8141            0 :           for (unsigned int i = 0; i < num_bytes; ++i)
    8142              :             {
    8143            0 :               target_unit value = 0;
    8144            0 :               for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
    8145              :                 {
    8146            0 :                   if (INTVAL (CONST_VECTOR_ELT (x, elt)))
    8147            0 :                     value |= mask << j;
    8148            0 :                   elt += 1;
    8149              :                 }
    8150            0 :               bytes.quick_push (value);
    8151              :             }
    8152              :           return true;
    8153              :         }
    8154              : 
    8155       561962 :       unsigned int start = bytes.length ();
    8156       561962 :       unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
    8157              :       /* Make FIRST_BYTE relative to ELT.  */
    8158       561962 :       first_byte %= elt_bytes;
    8159      2813890 :       while (num_bytes > 0)
    8160              :         {
    8161              :           /* Work out how many bytes we want from element ELT.  */
    8162      2251928 :           unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
    8163      4503856 :           if (!native_encode_rtx (GET_MODE_INNER (mode),
    8164              :                                   CONST_VECTOR_ELT (x, elt), bytes,
    8165              :                                   first_byte, chunk_bytes))
    8166              :             {
    8167            0 :               bytes.truncate (start);
    8168            0 :               return false;
    8169              :             }
    8170      2251928 :           elt += 1;
    8171      2251928 :           first_byte = 0;
    8172      2251928 :           num_bytes -= chunk_bytes;
    8173              :         }
    8174              :       return true;
    8175              :     }
    8176              : 
    8177              :   /* All subsequent cases are limited to scalars.  */
    8178     13377406 :   scalar_mode smode;
    8179     13377406 :   if (!is_a <scalar_mode> (mode, &smode))
    8180              :     return false;
    8181              : 
    8182              :   /* Make sure that the region is in range.  */
    8183     13377406 :   unsigned int end_byte = first_byte + num_bytes;
    8184     13377406 :   unsigned int mode_bytes = GET_MODE_SIZE (smode);
    8185     13377406 :   gcc_assert (end_byte <= mode_bytes);
    8186              : 
    8187     13377406 :   if (CONST_SCALAR_INT_P (x))
    8188              :     {
    8189              :       /* The target memory layout is affected by both BYTES_BIG_ENDIAN
    8190              :          and WORDS_BIG_ENDIAN.  Use the subreg machinery to get the lsb
    8191              :          position of each byte.  */
    8192     12697459 :       rtx_mode_t value (x, smode);
    8193     12697459 :       wide_int_ref value_wi (value);
    8194     66781865 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8195              :         {
    8196              :           /* Always constant because the inputs are.  */
    8197     41386947 :           unsigned int lsb
    8198     41386947 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8199              :           /* Operate directly on the encoding rather than using
    8200              :              wi::extract_uhwi, so that we preserve the sign or zero
    8201              :              extension for modes that are not a whole number of bits in
    8202              :              size.  (Zero extension is only used for the combination of
    8203              :              innermode == BImode && STORE_FLAG_VALUE == 1).  */
    8204     41386947 :           unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
    8205     41386947 :           unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
    8206     41386947 :           unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
    8207     41386947 :           bytes.quick_push (uhwi >> shift);
    8208              :         }
    8209     12697459 :       return true;
    8210              :     }
    8211              : 
    8212       679947 :   if (CONST_DOUBLE_P (x))
    8213              :     {
    8214              :       /* real_to_target produces an array of integers in target memory order.
    8215              :          All integers before the last one have 32 bits; the last one may
    8216              :          have 32 bits or fewer, depending on whether the mode bitsize
    8217              :          is divisible by 32.  Each of these integers is then laid out
    8218              :          in target memory as any other integer would be.  */
    8219       651765 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    8220       651765 :       real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
    8221              : 
    8222              :       /* The (maximum) number of target bytes per element of el32.  */
    8223       651765 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    8224       651765 :       gcc_assert (bytes_per_el32 != 0);
    8225              : 
    8226              :       /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
    8227              :          handling above.  */
    8228      4460672 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8229              :         {
    8230      3808907 :           unsigned int index = byte / bytes_per_el32;
    8231      3808907 :           unsigned int subbyte = byte % bytes_per_el32;
    8232      3808907 :           unsigned int int_bytes = MIN (bytes_per_el32,
    8233              :                                         mode_bytes - index * bytes_per_el32);
    8234              :           /* Always constant because the inputs are.  */
    8235      3808907 :           unsigned int lsb
    8236      3808907 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    8237      3808907 :           bytes.quick_push ((unsigned long) el32[index] >> lsb);
    8238              :         }
    8239       651765 :       return true;
    8240              :     }
    8241              : 
    8242        28182 :   if (GET_CODE (x) == CONST_FIXED)
    8243              :     {
    8244            0 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8245              :         {
    8246              :           /* Always constant because the inputs are.  */
    8247            0 :           unsigned int lsb
    8248            0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8249            0 :           unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
    8250            0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    8251              :             {
    8252            0 :               lsb -= HOST_BITS_PER_WIDE_INT;
    8253            0 :               piece = CONST_FIXED_VALUE_HIGH (x);
    8254              :             }
    8255            0 :           bytes.quick_push (piece >> lsb);
    8256              :         }
    8257              :       return true;
    8258              :     }
    8259              : 
    8260              :   return false;
    8261              : }
    8262              : 
    8263              : /* Read a vector of mode MODE from the target memory image given by BYTES,
    8264              :    starting at byte FIRST_BYTE.  The vector is known to be encodable using
    8265              :    NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
    8266              :    and BYTES is known to have enough bytes to supply NPATTERNS *
    8267              :    NELTS_PER_PATTERN vector elements.  Each element of BYTES contains
    8268              :    BITS_PER_UNIT bits and the bytes are in target memory order.
    8269              : 
    8270              :    Return the vector on success, otherwise return NULL_RTX.  */
    8271              : 
    8272              : rtx
    8273       293720 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
    8274              :                           unsigned int first_byte, unsigned int npatterns,
    8275              :                           unsigned int nelts_per_pattern)
    8276              : {
    8277       293720 :   rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
    8278              : 
    8279       587440 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8280              :                                                GET_MODE_NUNITS (mode));
    8281       293720 :   if (elt_bits < BITS_PER_UNIT)
    8282              :     {
    8283              :       /* This is the only case in which elements can be smaller than a byte.
    8284              :          Element 0 is always in the lsb of the containing byte.  */
    8285            0 :       gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    8286            0 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    8287              :         {
    8288            0 :           unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
    8289            0 :           unsigned int byte_index = bit_index / BITS_PER_UNIT;
    8290            0 :           unsigned int lsb = bit_index % BITS_PER_UNIT;
    8291            0 :           unsigned int value = bytes[byte_index] >> lsb;
    8292            0 :           builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
    8293              :         }
    8294              :     }
    8295              :   else
    8296              :     {
    8297      1189353 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    8298              :         {
    8299      1791266 :           rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
    8300       895633 :           if (!x)
    8301            0 :             return NULL_RTX;
    8302       895633 :           builder.quick_push (x);
    8303       895633 :           first_byte += elt_bits / BITS_PER_UNIT;
    8304              :         }
    8305              :     }
    8306       293720 :   return builder.build ();
    8307       293720 : }
    8308              : 
    8309              : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
    8310              :    of target memory image BYTES.  */
    8311              : 
    8312              : wide_int
    8313     11802621 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
    8314              :                    unsigned int size, unsigned int precision)
    8315              : {
    8316              :   /* Pull the bytes msb first, so that we can use simple
    8317              :      shift-and-insert wide_int operations.  */
    8318     11802621 :   wide_int result (wi::zero (precision));
    8319     54384064 :   for (unsigned int i = 0; i < size; ++i)
    8320              :     {
    8321     42581443 :       unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
    8322              :       /* Always constant because the inputs are.  */
    8323     42581443 :       unsigned int subbyte
    8324     42581443 :         = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
    8325     42581443 :       result <<= BITS_PER_UNIT;
    8326     42581443 :       result |= bytes[first_byte + subbyte];
    8327              :     }
    8328     11802621 :   return result;
    8329              : }
    8330              : 
    8331              : /* Read an rtx of mode MODE from the target memory image given by BYTES,
    8332              :    starting at byte FIRST_BYTE.  Each element of BYTES contains BITS_PER_UNIT
    8333              :    bits and the bytes are in target memory order.  The image has enough
    8334              :    values to specify all bytes of MODE.
    8335              : 
    8336              :    Return the rtx on success, otherwise return NULL_RTX.  */
    8337              : 
    8338              : rtx
    8339     12139060 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
    8340              :                    unsigned int first_byte)
    8341              : {
    8342     12139060 :   if (VECTOR_MODE_P (mode))
    8343              :     {
    8344              :       /* If we know at compile time how many elements there are,
    8345              :          pull each element directly from BYTES.  */
    8346        91390 :       unsigned int nelts;
    8347       182780 :       if (GET_MODE_NUNITS (mode).is_constant (&nelts))
    8348        91390 :         return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
    8349              :       return NULL_RTX;
    8350              :     }
    8351              : 
    8352     12047670 :   scalar_int_mode imode;
    8353     12047670 :   if (is_a <scalar_int_mode> (mode, &imode)
    8354     11802621 :       && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
    8355              :     {
    8356     11802621 :       auto result = native_decode_int (bytes, first_byte,
    8357     11802621 :                                        GET_MODE_SIZE (imode),
    8358     23605242 :                                        GET_MODE_PRECISION (imode));
    8359     11802621 :       return immed_wide_int_const (result, imode);
    8360     11802621 :     }
    8361              : 
    8362       245049 :   scalar_float_mode fmode;
    8363       245049 :   if (is_a <scalar_float_mode> (mode, &fmode))
    8364              :     {
    8365              :       /* We need to build an array of integers in target memory order.
    8366              :          All integers before the last one have 32 bits; the last one may
    8367              :          have 32 bits or fewer, depending on whether the mode bitsize
    8368              :          is divisible by 32.  */
    8369       245019 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    8370       245019 :       unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
    8371       245019 :       memset (el32, 0, num_el32 * sizeof (long));
    8372              : 
    8373              :       /* The (maximum) number of target bytes per element of el32.  */
    8374       245019 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    8375       245019 :       gcc_assert (bytes_per_el32 != 0);
    8376              : 
    8377       245019 :       unsigned int mode_bytes = GET_MODE_SIZE (fmode);
    8378      1702889 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    8379              :         {
    8380      1457870 :           unsigned int index = byte / bytes_per_el32;
    8381      1457870 :           unsigned int subbyte = byte % bytes_per_el32;
    8382      1457870 :           unsigned int int_bytes = MIN (bytes_per_el32,
    8383              :                                         mode_bytes - index * bytes_per_el32);
    8384              :           /* Always constant because the inputs are.  */
    8385      1457870 :           unsigned int lsb
    8386      1457870 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    8387      1457870 :           el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
    8388              :         }
    8389       245019 :       REAL_VALUE_TYPE r;
    8390       245019 :       real_from_target (&r, el32, fmode);
    8391       245019 :       return const_double_from_real_value (r, fmode);
    8392              :     }
    8393              : 
    8394           30 :   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
    8395              :     {
    8396            0 :       scalar_mode smode = as_a <scalar_mode> (mode);
    8397            0 :       FIXED_VALUE_TYPE f;
    8398            0 :       f.data.low = 0;
    8399            0 :       f.data.high = 0;
    8400            0 :       f.mode = smode;
    8401              : 
    8402            0 :       unsigned int mode_bytes = GET_MODE_SIZE (smode);
    8403            0 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    8404              :         {
    8405              :           /* Always constant because the inputs are.  */
    8406            0 :           unsigned int lsb
    8407            0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8408            0 :           unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
    8409            0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    8410            0 :             f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
    8411              :           else
    8412            0 :             f.data.low |= unit << lsb;
    8413              :         }
    8414            0 :       return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
    8415              :     }
    8416              : 
    8417              :   return NULL_RTX;
    8418              : }
    8419              : 
    8420              : /* Simplify a byte offset BYTE into CONST_VECTOR X.  The main purpose
    8421              :    is to convert a runtime BYTE value into a constant one.  */
    8422              : 
    8423              : static poly_uint64
    8424       352052 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
    8425              : {
    8426              :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    8427       352052 :   machine_mode mode = GET_MODE (x);
    8428       704104 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8429              :                                                GET_MODE_NUNITS (mode));
    8430              :   /* The number of bits needed to encode one element from each pattern.  */
    8431       352052 :   unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
    8432              : 
    8433              :   /* Identify the start point in terms of a sequence number and a byte offset
    8434              :      within that sequence.  */
    8435       352052 :   poly_uint64 first_sequence;
    8436       352052 :   unsigned HOST_WIDE_INT subbit;
    8437       352052 :   if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
    8438              :                        &first_sequence, &subbit))
    8439              :     {
    8440       352052 :       unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    8441       352052 :       if (nelts_per_pattern == 1)
    8442              :         /* This is a duplicated vector, so the value of FIRST_SEQUENCE
    8443              :            doesn't matter.  */
    8444       268983 :         byte = subbit / BITS_PER_UNIT;
    8445        83069 :       else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
    8446              :         {
    8447              :           /* The subreg drops the first element from each pattern and
    8448              :              only uses the second element.  Find the first sequence
    8449              :              that starts on a byte boundary.  */
    8450         5568 :           subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
    8451         5568 :           byte = subbit / BITS_PER_UNIT;
    8452              :         }
    8453              :     }
    8454       352052 :   return byte;
    8455              : }
    8456              : 
    8457              : /* Subroutine of simplify_subreg in which:
    8458              : 
    8459              :    - X is known to be a CONST_VECTOR
    8460              :    - OUTERMODE is known to be a vector mode
    8461              : 
    8462              :    Try to handle the subreg by operating on the CONST_VECTOR encoding
    8463              :    rather than on each individual element of the CONST_VECTOR.
    8464              : 
    8465              :    Return the simplified subreg on success, otherwise return NULL_RTX.  */
    8466              : 
    8467              : static rtx
    8468       210319 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
    8469              :                               machine_mode innermode, unsigned int first_byte)
    8470              : {
    8471              :   /* Paradoxical subregs of vectors have dubious semantics.  */
    8472       210319 :   if (paradoxical_subreg_p (outermode, innermode))
    8473              :     return NULL_RTX;
    8474              : 
    8475              :   /* We can only preserve the semantics of a stepped pattern if the new
    8476              :      vector element is the same as the original one.  */
    8477       210171 :   if (CONST_VECTOR_STEPPED_P (x)
    8478       231077 :       && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
    8479              :     return NULL_RTX;
    8480              : 
    8481              :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    8482       202330 :   unsigned int x_elt_bits
    8483       202330 :     = vector_element_size (GET_MODE_PRECISION (innermode),
    8484              :                            GET_MODE_NUNITS (innermode));
    8485       202330 :   unsigned int out_elt_bits
    8486       202330 :     = vector_element_size (GET_MODE_PRECISION (outermode),
    8487              :                            GET_MODE_NUNITS (outermode));
    8488              : 
    8489              :   /* The number of bits needed to encode one element from every pattern
    8490              :      of the original vector.  */
    8491       202330 :   unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
    8492              : 
    8493              :   /* The number of bits needed to encode one element from every pattern
    8494              :      of the result.  */
    8495       202330 :   unsigned int out_sequence_bits
    8496       202330 :     = least_common_multiple (x_sequence_bits, out_elt_bits);
    8497              : 
    8498              :   /* Work out the number of interleaved patterns in the output vector
    8499              :      and the number of encoded elements per pattern.  */
    8500       202330 :   unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
    8501       202330 :   unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    8502              : 
    8503              :   /* The encoding scheme requires the number of elements to be a multiple
    8504              :      of the number of patterns, so that each pattern appears at least once
    8505              :      and so that the same number of elements appear from each pattern.  */
    8506       404660 :   bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
    8507       202330 :   unsigned int const_nunits;
    8508       404660 :   if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
    8509       202330 :       && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
    8510              :     {
    8511              :       /* Either the encoding is invalid, or applying it would give us
    8512              :          more elements than we need.  Just encode each element directly.  */
    8513              :       out_npatterns = const_nunits;
    8514              :       nelts_per_pattern = 1;
    8515              :     }
    8516              :   else if (!ok_p)
    8517              :     return NULL_RTX;
    8518              : 
    8519              :   /* Get enough bytes of X to form the new encoding.  */
    8520       202330 :   unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
    8521       202330 :   unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
    8522       202330 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8523       202330 :   if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
    8524              :     return NULL_RTX;
    8525              : 
    8526              :   /* Re-encode the bytes as OUTERMODE.  */
    8527       202330 :   return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
    8528       202330 :                                    nelts_per_pattern);
    8529       202330 : }
    8530              : 
    8531              : /* Try to simplify a subreg of a constant by encoding the subreg region
    8532              :    as a sequence of target bytes and reading them back in the new mode.
    8533              :    Return the new value on success, otherwise return null.
    8534              : 
    8535              :    The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
    8536              :    and byte offset FIRST_BYTE.  */
    8537              : 
    8538              : static rtx
    8539     10953790 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
    8540              :                        machine_mode innermode, unsigned int first_byte)
    8541              : {
    8542     10953790 :   unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
    8543     10953790 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8544              : 
    8545              :   /* Some ports misuse CCmode.  */
    8546     10953790 :   if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
    8547              :     return x;
    8548              : 
    8549              :   /* Paradoxical subregs read undefined values for bytes outside of the
    8550              :      inner value.  However, we have traditionally always sign-extended
    8551              :      integer constants and zero-extended others.  */
    8552     10951784 :   unsigned int inner_bytes = buffer_bytes;
    8553     10951784 :   if (paradoxical_subreg_p (outermode, innermode))
    8554              :     {
    8555      1019830 :       if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
    8556            0 :         return NULL_RTX;
    8557              : 
    8558       509915 :       target_unit filler = 0;
    8559       509915 :       if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
    8560        51717 :         filler = -1;
    8561              : 
    8562              :       /* Add any leading bytes due to big-endian layout.  The number of
    8563              :          bytes must be constant because both modes have constant size.  */
    8564       509915 :       unsigned int leading_bytes
    8565       509915 :         = -byte_lowpart_offset (outermode, innermode).to_constant ();
    8566       509915 :       for (unsigned int i = 0; i < leading_bytes; ++i)
    8567            0 :         buffer.quick_push (filler);
    8568              : 
    8569       509915 :       if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8570            0 :         return NULL_RTX;
    8571              : 
    8572              :       /* Add any trailing bytes due to little-endian layout.  */
    8573      6638654 :       while (buffer.length () < buffer_bytes)
    8574      2809412 :         buffer.quick_push (filler);
    8575              :     }
    8576     10441869 :   else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8577              :     return NULL_RTX;
    8578     10951784 :   rtx ret = native_decode_rtx (outermode, buffer, 0);
    8579     10951784 :   if (ret && FLOAT_MODE_P (outermode))
    8580              :     {
    8581       129422 :       auto_vec<target_unit, 128> buffer2 (buffer_bytes);
    8582       129422 :       if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
    8583              :         return NULL_RTX;
    8584      1424573 :       for (unsigned int i = 0; i < buffer_bytes; ++i)
    8585      1295186 :         if (buffer[i] != buffer2[i])
    8586              :           return NULL_RTX;
    8587       129422 :     }
    8588              :   return ret;
    8589     10953790 : }
    8590              : 
    8591              : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
    8592              :    Return 0 if no simplifications are possible.  */
    8593              : rtx
    8594     74435167 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
    8595              :                                    machine_mode innermode, poly_uint64 byte)
    8596              : {
    8597              :   /* Little bit of sanity checking.  */
    8598     74435167 :   gcc_assert (innermode != VOIDmode);
    8599     74435167 :   gcc_assert (outermode != VOIDmode);
    8600     74435167 :   gcc_assert (innermode != BLKmode);
    8601     74435167 :   gcc_assert (outermode != BLKmode);
    8602              : 
    8603     74435167 :   gcc_assert (GET_MODE (op) == innermode
    8604              :               || GET_MODE (op) == VOIDmode);
    8605              : 
    8606    148870334 :   poly_uint64 outersize = GET_MODE_SIZE (outermode);
    8607     74435167 :   if (!multiple_p (byte, outersize))
    8608              :     return NULL_RTX;
    8609              : 
    8610    148870294 :   poly_uint64 innersize = GET_MODE_SIZE (innermode);
    8611     74435147 :   if (maybe_ge (byte, innersize))
    8612              :     return NULL_RTX;
    8613              : 
    8614     74435147 :   if (outermode == innermode && known_eq (byte, 0U))
    8615      4599700 :     return op;
    8616              : 
    8617     69835447 :   if (GET_CODE (op) == CONST_VECTOR)
    8618       352052 :     byte = simplify_const_vector_byte_offset (op, byte);
    8619              : 
    8620    139670894 :   if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
    8621              :     {
    8622     63816859 :       rtx elt;
    8623              : 
    8624     54821508 :       if (VECTOR_MODE_P (outermode)
    8625     26986053 :           && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
    8626     65574802 :           && vec_duplicate_p (op, &elt))
    8627        14307 :         return gen_vec_duplicate (outermode, elt);
    8628              : 
    8629     63810815 :       if (outermode == GET_MODE_INNER (innermode)
    8630     63810815 :           && vec_duplicate_p (op, &elt))
    8631         8263 :         return elt;
    8632              :     }
    8633              : 
    8634     69821140 :   if (CONST_SCALAR_INT_P (op)
    8635     59065892 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    8636     59008539 :       || CONST_FIXED_P (op)
    8637     59008539 :       || GET_CODE (op) == CONST_VECTOR)
    8638              :     {
    8639     11156120 :       unsigned HOST_WIDE_INT cbyte;
    8640     11156120 :       if (byte.is_constant (&cbyte))
    8641              :         {
    8642     11156120 :           if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
    8643              :             {
    8644       210319 :               rtx tmp = simplify_const_vector_subreg (outermode, op,
    8645              :                                                       innermode, cbyte);
    8646       210319 :               if (tmp)
    8647     11156120 :                 return tmp;
    8648              :             }
    8649              : 
    8650     10953790 :           fixed_size_mode fs_outermode;
    8651     10953790 :           if (is_a <fixed_size_mode> (outermode, &fs_outermode))
    8652     10953790 :             return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
    8653              :         }
    8654              :     }
    8655              : 
    8656              :   /* Changing mode twice with SUBREG => just change it once,
    8657              :      or not at all if changing back op starting mode.  */
    8658     58665020 :   if (GET_CODE (op) == SUBREG)
    8659              :     {
    8660      1337287 :       machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
    8661      2674574 :       poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
    8662      1337287 :       rtx newx;
    8663              : 
    8664              :       /* Make sure that the relationship between the two subregs is
    8665              :          known at compile time.  */
    8666      1337287 :       if (!ordered_p (outersize, innermostsize))
    8667              :         return NULL_RTX;
    8668              : 
    8669      1337287 :       if (outermode == innermostmode
    8670       665591 :           && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
    8671      2002871 :           && known_eq (SUBREG_BYTE (op),
    8672              :                        subreg_lowpart_offset (innermode, innermostmode)))
    8673       665584 :         return SUBREG_REG (op);
    8674              : 
    8675              :       /* Work out the memory offset of the final OUTERMODE value relative
    8676              :          to the inner value of OP.  */
    8677       671703 :       poly_int64 mem_offset = subreg_memory_offset (outermode,
    8678              :                                                     innermode, byte);
    8679       671703 :       poly_int64 op_mem_offset = subreg_memory_offset (op);
    8680       671703 :       poly_int64 final_offset = mem_offset + op_mem_offset;
    8681              : 
    8682              :       /* See whether resulting subreg will be paradoxical.  */
    8683       671703 :       if (!paradoxical_subreg_p (outermode, innermostmode))
    8684              :         {
    8685              :           /* Bail out in case resulting subreg would be incorrect.  */
    8686      1065196 :           if (maybe_lt (final_offset, 0)
    8687      1065189 :               || maybe_ge (poly_uint64 (final_offset), innermostsize)
    8688      1065189 :               || !multiple_p (final_offset, outersize))
    8689              :             return NULL_RTX;
    8690              :         }
    8691              :       else
    8692              :         {
    8693       139105 :           poly_int64 required_offset = subreg_memory_offset (outermode,
    8694              :                                                              innermostmode, 0);
    8695       139105 :           if (maybe_ne (final_offset, required_offset))
    8696            0 :             return NULL_RTX;
    8697              :           /* Paradoxical subregs always have byte offset 0.  */
    8698       139105 :           final_offset = 0;
    8699              :         }
    8700              : 
    8701              :       /* Recurse for further possible simplifications.  */
    8702       671688 :       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
    8703       671688 :                               final_offset);
    8704       671688 :       if (newx)
    8705              :         return newx;
    8706       671291 :       if (validate_subreg (outermode, innermostmode,
    8707       671291 :                            SUBREG_REG (op), final_offset))
    8708              :         {
    8709       611583 :           newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
    8710       611583 :           if (SUBREG_PROMOTED_VAR_P (op)
    8711          721 :               && SUBREG_PROMOTED_SIGN (op) >= 0
    8712          721 :               && GET_MODE_CLASS (outermode) == MODE_INT
    8713          717 :               && known_ge (outersize, innersize)
    8714          298 :               && known_le (outersize, innermostsize)
    8715       611593 :               && subreg_lowpart_p (newx))
    8716              :             {
    8717           10 :               SUBREG_PROMOTED_VAR_P (newx) = 1;
    8718           10 :               SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
    8719              :             }
    8720              :           return newx;
    8721              :         }
    8722              :       return NULL_RTX;
    8723              :     }
    8724              : 
    8725              :   /* SUBREG of a hard register => just change the register number
    8726              :      and/or mode.  If the hard register is not valid in that mode,
    8727              :      suppress this simplification.  If the hard register is the stack,
    8728              :      frame, or argument pointer, leave this as a SUBREG.  */
    8729              : 
    8730     57327733 :   if (REG_P (op) && HARD_REGISTER_P (op))
    8731              :     {
    8732     11072868 :       unsigned int regno, final_regno;
    8733              : 
    8734     11072868 :       regno = REGNO (op);
    8735     11072868 :       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
    8736     11072868 :       if (HARD_REGISTER_NUM_P (final_regno))
    8737              :         {
    8738     11047177 :           rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
    8739              :                                       subreg_memory_offset (outermode,
    8740              :                                                             innermode, byte));
    8741              : 
    8742              :           /* Propagate original regno.  We don't have any way to specify
    8743              :              the offset inside original regno, so do so only for lowpart.
    8744              :              The information is used only by alias analysis that cannot
    8745              :              grog partial register anyway.  */
    8746              : 
    8747     11047177 :           if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
    8748      8276473 :             ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
    8749              :           return x;
    8750              :         }
    8751              :     }
    8752              : 
    8753              :   /* If we have a SUBREG of a register that we are replacing and we are
    8754              :      replacing it with a MEM, make a new MEM and try replacing the
    8755              :      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
    8756              :      or if we would be widening it.  */
    8757              : 
    8758     46280556 :   if (MEM_P (op)
    8759      1660725 :       && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
    8760              :       /* Allow splitting of volatile memory references in case we don't
    8761              :          have instruction to move the whole thing.  */
    8762      1660722 :       && (! MEM_VOLATILE_P (op)
    8763        45486 :           || ! have_insn_for (SET, innermode))
    8764              :       && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
    8765     47895792 :       && known_le (outersize, innersize))
    8766       826087 :     return adjust_address_nv (op, outermode, byte);
    8767              : 
    8768              :   /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
    8769              :      of two parts.  */
    8770     45454469 :   if (GET_CODE (op) == CONCAT
    8771     45454469 :       || GET_CODE (op) == VEC_CONCAT)
    8772              :     {
    8773       258078 :       poly_uint64 final_offset;
    8774       258078 :       rtx part, res;
    8775              : 
    8776       258078 :       machine_mode part_mode = GET_MODE (XEXP (op, 0));
    8777       258078 :       if (part_mode == VOIDmode)
    8778           27 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8779       516156 :       poly_uint64 part_size = GET_MODE_SIZE (part_mode);
    8780       258078 :       if (known_lt (byte, part_size))
    8781              :         {
    8782       256567 :           part = XEXP (op, 0);
    8783       256567 :           final_offset = byte;
    8784              :         }
    8785         1511 :       else if (known_ge (byte, part_size))
    8786              :         {
    8787         1511 :           part = XEXP (op, 1);
    8788         1511 :           final_offset = byte - part_size;
    8789              :         }
    8790              :       else
    8791              :         return NULL_RTX;
    8792              : 
    8793       258078 :       if (maybe_gt (final_offset + outersize, part_size))
    8794              :         return NULL_RTX;
    8795              : 
    8796       128936 :       part_mode = GET_MODE (part);
    8797       128936 :       if (part_mode == VOIDmode)
    8798            0 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8799       128936 :       res = simplify_subreg (outermode, part, part_mode, final_offset);
    8800       128936 :       if (res)
    8801              :         return res;
    8802          306 :       if (GET_MODE (part) != VOIDmode
    8803          306 :           && validate_subreg (outermode, part_mode, part, final_offset))
    8804          306 :         return gen_rtx_SUBREG (outermode, part, final_offset);
    8805              :       return NULL_RTX;
    8806              :     }
    8807              : 
    8808              :   /* Simplify
    8809              :         (subreg (vec_merge (X)
    8810              :                            (vector)
    8811              :                            (const_int ((1 << N) | M)))
    8812              :                 (N * sizeof (outermode)))
    8813              :      to
    8814              :         (subreg (X) (N * sizeof (outermode)))
    8815              :    */
    8816     45196391 :   unsigned int idx;
    8817     90392782 :   if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
    8818     45196391 :       && idx < HOST_BITS_PER_WIDE_INT
    8819     45196391 :       && GET_CODE (op) == VEC_MERGE
    8820       537194 :       && GET_MODE_INNER (innermode) == outermode
    8821         4889 :       && CONST_INT_P (XEXP (op, 2))
    8822     45200698 :       && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
    8823         4298 :     return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
    8824              : 
    8825              :   /* A SUBREG resulting from a zero extension may fold to zero if
    8826              :      it extracts higher bits that the ZERO_EXTEND's source bits.  */
    8827     45192093 :   if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
    8828              :     {
    8829       232446 :       poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
    8830       232446 :       if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
    8831        55291 :         return CONST0_RTX (outermode);
    8832              :     }
    8833              : 
    8834              :   /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant.  */
    8835     45136802 :   if (GET_CODE (op) == ASHIFT
    8836      1070053 :       && SCALAR_INT_MODE_P (innermode)
    8837       988432 :       && CONST_INT_P (XEXP (op, 1))
    8838       906233 :       && INTVAL (XEXP (op, 1)) > 0
    8839     47113088 :       && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
    8840              :     {
    8841       906233 :       HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
    8842              :       /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero.  */
    8843       906233 :       if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
    8844      1775008 :           && known_le (GET_MODE_BITSIZE (outermode), val))
    8845       192246 :         return CONST0_RTX (outermode);
    8846              :       /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND).  */
    8847       748208 :       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
    8848        34901 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
    8849        69484 :           && known_eq (GET_MODE_BITSIZE (outermode), val)
    8850        68442 :           && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
    8851       783109 :           && known_eq (subreg_highpart_offset (outermode, innermode), byte))
    8852        34221 :         return XEXP (XEXP (op, 0), 0);
    8853              :     }
    8854              : 
    8855     46547514 :   auto distribute_subreg = [&](rtx op)
    8856              :     {
    8857      1602958 :       return simplify_subreg (outermode, op, innermode, byte);
    8858     44944556 :     };
    8859              : 
    8860              :   /* Try distributing the subreg through logic operations, if that
    8861              :      leads to all subexpressions being simplified.  For example,
    8862              :      distributing the outer subreg in:
    8863              : 
    8864              :        (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
    8865              : 
    8866              :      gives:
    8867              : 
    8868              :        (not:SI (reg:SI X))
    8869              : 
    8870              :      This should be a win if the outermode is word_mode, since logical
    8871              :      operations on word_mode should (a) be no more expensive than logical
    8872              :      operations on subword modes and (b) are likely to be cheaper than
    8873              :      logical operations on multiword modes.
    8874              : 
    8875              :      Otherwise, handle the case where the subreg is non-narrowing and does
    8876              :      not change the number of words.  The non-narrowing condition ensures
    8877              :      that we don't convert word_mode operations to subword operations.  */
    8878     44944556 :   scalar_int_mode int_outermode, int_innermode;
    8879     44944556 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8880     37878120 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8881     81303972 :       && (outermode == word_mode
    8882     22013726 :           || ((GET_MODE_PRECISION (int_outermode)
    8883     22013726 :                >= GET_MODE_PRECISION (int_innermode))
    8884      4321174 :               && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
    8885      4251441 :                   <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
    8886     18536690 :     switch (GET_CODE (op))
    8887              :       {
    8888        34875 :       case NOT:
    8889        34875 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8890         1871 :           return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
    8891              :         break;
    8892              : 
    8893       468197 :       case AND:
    8894       468197 :       case IOR:
    8895       468197 :       case XOR:
    8896       468197 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8897       205232 :           if (rtx op1 = distribute_subreg (XEXP (op, 1)))
    8898       200444 :             return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
    8899              :         break;
    8900              : 
    8901              :       default:
    8902              :         break;
    8903              :       }
    8904              : 
    8905     44742241 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8906     37675805 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8907     82418046 :       && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
    8908              :     {
    8909              :       /* Handle polynomial integers.  The upper bits of a paradoxical
    8910              :          subreg are undefined, so this is safe regardless of whether
    8911              :          we're truncating or extending.  */
    8912     33887047 :       if (CONST_POLY_INT_P (op))
    8913              :         {
    8914              :           poly_wide_int val
    8915              :             = poly_wide_int::from (const_poly_int_value (op),
    8916              :                                    GET_MODE_PRECISION (int_outermode),
    8917              :                                    SIGNED);
    8918              :           return immed_wide_int_const (val, int_outermode);
    8919              :         }
    8920              : 
    8921     33887047 :       if (GET_MODE_PRECISION (int_outermode)
    8922     33887047 :           < GET_MODE_PRECISION (int_innermode))
    8923              :         {
    8924     21235233 :           rtx tem = simplify_truncation (int_outermode, op, int_innermode);
    8925     21235233 :           if (tem)
    8926              :             return tem;
    8927              :         }
    8928              :     }
    8929              : 
    8930              :   /* If the outer mode is not integral, try taking a subreg with the equivalent
    8931              :      integer outer mode and then bitcasting the result.
    8932              :      Other simplifications rely on integer to integer subregs and we'd
    8933              :      potentially miss out on optimizations otherwise.  */
    8934     85913724 :   if (known_gt (GET_MODE_SIZE (innermode),
    8935              :                 GET_MODE_SIZE (outermode))
    8936     23086747 :       && SCALAR_INT_MODE_P (innermode)
    8937     21803785 :       && !SCALAR_INT_MODE_P (outermode)
    8938     66211363 :       && int_mode_for_size (GET_MODE_BITSIZE (outermode),
    8939        83877 :                             0).exists (&int_outermode))
    8940              :     {
    8941        83877 :       rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
    8942        83877 :       if (tem)
    8943         1979 :         return lowpart_subreg (outermode, tem, int_outermode);
    8944              :     }
    8945              : 
    8946              :   /* If OP is a vector comparison and the subreg is not changing the
    8947              :      number of elements or the size of the elements, change the result
    8948              :      of the comparison to the new mode.  */
    8949     42954883 :   if (COMPARISON_P (op)
    8950       302227 :       && VECTOR_MODE_P (outermode)
    8951       214097 :       && VECTOR_MODE_P (innermode)
    8952       642267 :       && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
    8953     43355950 :       && known_eq (GET_MODE_UNIT_SIZE (outermode),
    8954              :                    GET_MODE_UNIT_SIZE (innermode)))
    8955       133345 :     return simplify_gen_relational (GET_CODE (op), outermode, innermode,
    8956       133345 :                                     XEXP (op, 0), XEXP (op, 1));
    8957              : 
    8958              :   /* Distribute non-paradoxical subregs through logic ops in cases where
    8959              :      one term disappears.
    8960              : 
    8961              :      (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
    8962              :      (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
    8963              :      (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
    8964              : 
    8965              :      if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
    8966              : 
    8967              :      (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
    8968              :      (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
    8969              : 
    8970              :      if M2 is no smaller than M1 and (subreg:M1 C2) is zero.  */
    8971     42821538 :   if (known_ge (innersize, outersize)
    8972     29586584 :       && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
    8973     27237460 :       && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
    8974     44528705 :       && CONSTANT_P (XEXP (op, 1)))
    8975              :     {
    8976       887381 :       rtx op1_subreg = distribute_subreg (XEXP (op, 1));
    8977       887381 :       if (op1_subreg == CONSTM1_RTX (outermode))
    8978              :         {
    8979       120764 :           if (GET_CODE (op) == IOR)
    8980              :             return op1_subreg;
    8981       120530 :           rtx op0 = XEXP (op, 0);
    8982       120530 :           if (GET_CODE (op) == XOR)
    8983          909 :             op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
    8984       120530 :           return simplify_gen_subreg (outermode, op0, innermode, byte);
    8985              :         }
    8986              : 
    8987       766617 :       if (op1_subreg == CONST0_RTX (outermode))
    8988        12384 :         return (GET_CODE (op) == AND
    8989        12384 :                 ? op1_subreg
    8990         7273 :                 : distribute_subreg (XEXP (op, 0)));
    8991              :     }
    8992              : 
    8993              :   return NULL_RTX;
    8994              : }
    8995              : 
    8996              : /* Make a SUBREG operation or equivalent if it folds.  */
    8997              : 
    8998              : rtx
    8999     45851139 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
    9000              :                                        machine_mode innermode,
    9001              :                                        poly_uint64 byte)
    9002              : {
    9003     45851139 :   rtx newx;
    9004              : 
    9005     45851139 :   newx = simplify_subreg (outermode, op, innermode, byte);
    9006     45851139 :   if (newx)
    9007              :     return newx;
    9008              : 
    9009     21804744 :   if (GET_CODE (op) == SUBREG
    9010     21804744 :       || GET_CODE (op) == CONCAT
    9011     21768310 :       || CONST_SCALAR_INT_P (op)
    9012     21768284 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    9013     21768284 :       || CONST_FIXED_P (op)
    9014     21768284 :       || GET_CODE (op) == CONST_VECTOR)
    9015              :     return NULL_RTX;
    9016              : 
    9017     21768274 :   if (validate_subreg (outermode, innermode, op, byte))
    9018     21735188 :     return gen_rtx_SUBREG (outermode, op, byte);
    9019              : 
    9020              :   return NULL_RTX;
    9021              : }
    9022              : 
    9023              : /* Generates a subreg to get the least significant part of EXPR (in mode
    9024              :    INNER_MODE) to OUTER_MODE.  */
    9025              : 
    9026              : rtx
    9027     33985532 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
    9028              :                                   machine_mode inner_mode)
    9029              : {
    9030     33985532 :   return simplify_gen_subreg (outer_mode, expr, inner_mode,
    9031     33985532 :                               subreg_lowpart_offset (outer_mode, inner_mode));
    9032              : }
    9033              : 
    9034              : /* Generate RTX to select element at INDEX out of vector OP.  */
    9035              : 
    9036              : rtx
    9037       678673 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
    9038              : {
    9039       678673 :   gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
    9040              : 
    9041       678673 :   scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
    9042              : 
    9043      1357346 :   if (known_eq (index * GET_MODE_SIZE (imode),
    9044              :                 subreg_lowpart_offset (imode, GET_MODE (op))))
    9045              :     {
    9046       678523 :       rtx res = lowpart_subreg (imode, op, GET_MODE (op));
    9047       678523 :       if (res)
    9048              :         return res;
    9049              :     }
    9050              : 
    9051          671 :   rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
    9052          671 :   return gen_rtx_VEC_SELECT (imode, op, tmp);
    9053              : }
    9054              : 
    9055              : 
    9056              : /* Simplify X, an rtx expression.
    9057              : 
    9058              :    Return the simplified expression or NULL if no simplifications
    9059              :    were possible.
    9060              : 
    9061              :    This is the preferred entry point into the simplification routines;
    9062              :    however, we still allow passes to call the more specific routines.
    9063              : 
    9064              :    Right now GCC has three (yes, three) major bodies of RTL simplification
    9065              :    code that need to be unified.
    9066              : 
    9067              :         1. fold_rtx in cse.cc.  This code uses various CSE specific
    9068              :            information to aid in RTL simplification.
    9069              : 
    9070              :         2. simplify_rtx in combine.cc.  Similar to fold_rtx, except that
    9071              :            it uses combine specific information to aid in RTL
    9072              :            simplification.
    9073              : 
    9074              :         3. The routines in this file.
    9075              : 
    9076              : 
    9077              :    Long term we want to only have one body of simplification code; to
    9078              :    get to that state I recommend the following steps:
    9079              : 
    9080              :         1. Pour over fold_rtx & simplify_rtx and move any simplifications
    9081              :            which are not pass dependent state into these routines.
    9082              : 
    9083              :         2. As code is moved by #1, change fold_rtx & simplify_rtx to
    9084              :            use this routine whenever possible.
    9085              : 
    9086              :         3. Allow for pass dependent state to be provided to these
    9087              :            routines and add simplifications based on the pass dependent
    9088              :            state.  Remove code from cse.cc & combine.cc that becomes
    9089              :            redundant/dead.
    9090              : 
    9091              :     It will take time, but ultimately the compiler will be easier to
    9092              :     maintain and improve.  It's totally silly that when we add a
    9093              :     simplification that it needs to be added to 4 places (3 for RTL
    9094              :     simplification and 1 for tree simplification.  */
    9095              : 
    9096              : rtx
    9097     47851852 : simplify_rtx (const_rtx x)
    9098              : {
    9099     47851852 :   const enum rtx_code code = GET_CODE (x);
    9100     47851852 :   const machine_mode mode = GET_MODE (x);
    9101              : 
    9102     47851852 :   switch (GET_RTX_CLASS (code))
    9103              :     {
    9104       783606 :     case RTX_UNARY:
    9105      1567212 :       return simplify_unary_operation (code, mode,
    9106       783606 :                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
    9107     27394058 :     case RTX_COMM_ARITH:
    9108     27394058 :       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    9109       463072 :         return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    9110              : 
    9111              :       /* Fall through.  */
    9112              : 
    9113     33567910 :     case RTX_BIN_ARITH:
    9114     33567910 :       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
    9115              : 
    9116       109289 :     case RTX_TERNARY:
    9117       109289 :     case RTX_BITFIELD_OPS:
    9118       109289 :       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
    9119       109289 :                                          XEXP (x, 0), XEXP (x, 1),
    9120       109289 :                                          XEXP (x, 2));
    9121              : 
    9122       230893 :     case RTX_COMPARE:
    9123       230893 :     case RTX_COMM_COMPARE:
    9124       230893 :       return simplify_relational_operation (code, mode,
    9125       230893 :                                             ((GET_MODE (XEXP (x, 0))
    9126              :                                              != VOIDmode)
    9127              :                                             ? GET_MODE (XEXP (x, 0))
    9128          329 :                                             : GET_MODE (XEXP (x, 1))),
    9129       230893 :                                             XEXP (x, 0),
    9130       461786 :                                             XEXP (x, 1));
    9131              : 
    9132       234360 :     case RTX_EXTRA:
    9133       234360 :       if (code == SUBREG)
    9134         2505 :         return simplify_subreg (mode, SUBREG_REG (x),
    9135         2505 :                                 GET_MODE (SUBREG_REG (x)),
    9136         2505 :                                 SUBREG_BYTE (x));
    9137              :       break;
    9138              : 
    9139      6693324 :     case RTX_OBJ:
    9140      6693324 :       if (code == LO_SUM)
    9141              :         {
    9142              :           /* Convert (lo_sum (high FOO) FOO) to FOO.  */
    9143            0 :           if (GET_CODE (XEXP (x, 0)) == HIGH
    9144            0 :               && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
    9145            0 :           return XEXP (x, 1);
    9146              :         }
    9147              :       break;
    9148              : 
    9149              :     default:
    9150              :       break;
    9151              :     }
    9152              :   return NULL;
    9153              : }
    9154              : 
    9155              : #if CHECKING_P
    9156              : 
    9157              : namespace selftest {
    9158              : 
    9159              : /* Make a unique pseudo REG of mode MODE for use by selftests.  */
    9160              : 
    9161              : static rtx
    9162         2672 : make_test_reg (machine_mode mode)
    9163              : {
    9164         2672 :   static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
    9165              : 
    9166         2672 :   return gen_rtx_REG (mode, test_reg_num++);
    9167              : }
    9168              : 
    9169              : static void
    9170           40 : test_scalar_int_ops (machine_mode mode)
    9171              : {
    9172           40 :   rtx op0 = make_test_reg (mode);
    9173           40 :   rtx op1 = make_test_reg (mode);
    9174           40 :   rtx six = GEN_INT (6);
    9175              : 
    9176           40 :   rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
    9177           40 :   rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
    9178           40 :   rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
    9179              : 
    9180           40 :   rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
    9181           40 :   rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
    9182           40 :   rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
    9183              : 
    9184           40 :   rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
    9185           40 :   rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
    9186              : 
    9187              :   /* Test some binary identities.  */
    9188           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
    9189           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
    9190           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
    9191           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
    9192           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
    9193           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
    9194           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
    9195           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
    9196           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
    9197           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
    9198           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
    9199           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
    9200           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
    9201           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
    9202           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
    9203           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
    9204           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
    9205              : 
    9206              :   /* Test some self-inverse operations.  */
    9207           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
    9208           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
    9209           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
    9210              : 
    9211              :   /* Test some reflexive operations.  */
    9212           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
    9213           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
    9214           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
    9215           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
    9216           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
    9217           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
    9218              : 
    9219           40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
    9220           40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
    9221              : 
    9222              :   /* Test simplify_distributive_operation.  */
    9223           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
    9224              :                  simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
    9225           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
    9226              :                  simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
    9227           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
    9228              :                  simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
    9229              : 
    9230              :   /* Test useless extensions are eliminated.  */
    9231           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
    9232           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
    9233           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
    9234           40 :   ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
    9235           40 : }
    9236              : 
    9237              : /* Verify some simplifications of integer extension/truncation.
    9238              :    Machine mode BMODE is the guaranteed wider than SMODE.  */
    9239              : 
    9240              : static void
    9241           24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
    9242              : {
    9243           24 :   rtx sreg = make_test_reg (smode);
    9244              : 
    9245              :   /* Check truncation of extension.  */
    9246           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9247              :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    9248              :                                                          sreg, smode),
    9249              :                                      bmode),
    9250              :                  sreg);
    9251           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9252              :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    9253              :                                                          sreg, smode),
    9254              :                                      bmode),
    9255              :                  sreg);
    9256           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9257              :                                      lowpart_subreg (bmode, sreg, smode),
    9258              :                                      bmode),
    9259              :                  sreg);
    9260              : 
    9261              :   /* Test extensions, followed by logic ops, followed by truncations.  */
    9262           24 :   rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
    9263           24 :   rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
    9264           24 :   rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
    9265           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9266              :                                  simplify_gen_binary (AND, bmode,
    9267              :                                                       bsubreg, smask),
    9268              :                                  bmode),
    9269              :                  sreg);
    9270           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9271              :                                  simplify_gen_binary (AND, bmode,
    9272              :                                                       bsubreg, inv_smask),
    9273              :                                  bmode),
    9274              :                  const0_rtx);
    9275           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9276              :                                  simplify_gen_binary (IOR, bmode,
    9277              :                                                       bsubreg, smask),
    9278              :                                  bmode),
    9279              :                  constm1_rtx);
    9280           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9281              :                                  simplify_gen_binary (IOR, bmode,
    9282              :                                                       bsubreg, inv_smask),
    9283              :                                  bmode),
    9284              :                  sreg);
    9285           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9286              :                                  simplify_gen_binary (XOR, bmode,
    9287              :                                                       bsubreg, smask),
    9288              :                                  bmode),
    9289              :                  lowpart_subreg (smode,
    9290              :                                  gen_rtx_NOT (bmode, bsubreg),
    9291              :                                  bmode));
    9292           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9293              :                                  simplify_gen_binary (XOR, bmode,
    9294              :                                                       bsubreg, inv_smask),
    9295              :                                  bmode),
    9296              :                  sreg);
    9297              : 
    9298           24 :   if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
    9299              :     {
    9300           24 :       rtx breg1 = make_test_reg (bmode);
    9301           24 :       rtx breg2 = make_test_reg (bmode);
    9302           24 :       rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
    9303           24 :       rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
    9304           24 :       rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
    9305           24 :       rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
    9306           24 :       rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
    9307           24 :       rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
    9308           24 :       rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
    9309           24 :       rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
    9310           24 :       rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
    9311           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
    9312              :                      gen_rtx_NOT (bmode, breg1));
    9313           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
    9314              :                      gen_rtx_AND (bmode, breg1, breg2));
    9315           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
    9316              :                      gen_rtx_IOR (bmode, breg1, breg2));
    9317           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
    9318              :                      gen_rtx_XOR (bmode, breg1, breg2));
    9319           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
    9320              :                      gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    9321           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
    9322              :                      gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    9323           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
    9324              :                      gen_rtx_XOR (bmode,
    9325              :                                   gen_rtx_XOR (bmode, breg1, breg2),
    9326              :                                   const1_rtx));
    9327              :     }
    9328           24 : }
    9329              : 
    9330              : /* Verify more simplifications of integer extension/truncation.
    9331              :    BMODE is wider than MMODE which is wider than SMODE.  */
    9332              : 
    9333              : static void
    9334           16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
    9335              :                           machine_mode smode)
    9336              : {
    9337           16 :   rtx breg = make_test_reg (bmode);
    9338           16 :   rtx mreg = make_test_reg (mmode);
    9339           16 :   rtx sreg = make_test_reg (smode);
    9340              : 
    9341              :   /* Check truncate of truncate.  */
    9342           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9343              :                                      simplify_gen_unary (TRUNCATE, mmode,
    9344              :                                                          breg, bmode),
    9345              :                                      mmode),
    9346              :                  simplify_gen_unary (TRUNCATE, smode, breg, bmode));
    9347              : 
    9348              :   /* Check extension of extension.  */
    9349           16 :   ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
    9350              :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    9351              :                                                          sreg, smode),
    9352              :                                      mmode),
    9353              :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    9354           16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    9355              :                                      simplify_gen_unary (SIGN_EXTEND, mmode,
    9356              :                                                          sreg, smode),
    9357              :                                      mmode),
    9358              :                  simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
    9359           16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    9360              :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    9361              :                                                          sreg, smode),
    9362              :                                      mmode),
    9363              :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    9364              : 
    9365              :   /* Check truncation of extension.  */
    9366           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9367              :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    9368              :                                                          mreg, mmode),
    9369              :                                      bmode),
    9370              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9371           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9372              :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    9373              :                                                          mreg, mmode),
    9374              :                                      bmode),
    9375              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9376           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9377              :                                      lowpart_subreg (bmode, mreg, mmode),
    9378              :                                      bmode),
    9379              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9380           16 : }
    9381              : 
    9382              : /* Test comparisons of comparisons, with the inner comparisons being
    9383              :    between values of mode MODE2 and producing results of mode MODE1,
    9384              :    and with the outer comparisons producing results of mode MODE0.  */
    9385              : 
    9386              : static void
    9387            4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
    9388              : {
    9389            4 :   rtx reg0 = make_test_reg (mode2);
    9390            4 :   rtx reg1 = make_test_reg (mode2);
    9391              : 
    9392            4 :   static const rtx_code codes[] = {
    9393              :     EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
    9394              :   };
    9395            4 :   constexpr auto num_codes = ARRAY_SIZE (codes);
    9396            4 :   rtx cmps[num_codes];
    9397            4 :   rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
    9398              : 
    9399           44 :   for (unsigned int i = 0; i < num_codes; ++i)
    9400           40 :     cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
    9401              : 
    9402           44 :   for (auto code : codes)
    9403          440 :     for (unsigned int i0 = 0; i0 < num_codes; ++i0)
    9404         4400 :       for (unsigned int i1 = 0; i1 < num_codes; ++i1)
    9405              :         {
    9406         4000 :           rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
    9407              :                                                        cmps[i0], cmps[i1]);
    9408         4000 :           if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
    9409         1280 :             ASSERT_TRUE (cmp_res == NULL_RTX);
    9410              :           else
    9411              :             {
    9412         2720 :               ASSERT_TRUE (cmp_res != NULL_RTX
    9413              :                            && (CONSTANT_P (cmp_res)
    9414              :                                || (COMPARISON_P (cmp_res)
    9415              :                                    && GET_MODE (cmp_res) == mode0
    9416              :                                    && REG_P (XEXP (cmp_res, 0))
    9417              :                                    && REG_P (XEXP (cmp_res, 1)))));
    9418        10880 :               for (rtx reg0_val : vals)
    9419        32640 :                 for (rtx reg1_val : vals)
    9420              :                   {
    9421        24480 :                     rtx val0 = simplify_const_relational_operation
    9422        24480 :                       (codes[i0], mode1, reg0_val, reg1_val);
    9423        24480 :                     rtx val1 = simplify_const_relational_operation
    9424        24480 :                       (codes[i1], mode1, reg0_val, reg1_val);
    9425        24480 :                     rtx val = simplify_const_relational_operation
    9426        24480 :                       (code, mode0, val0, val1);
    9427        24480 :                     rtx folded = cmp_res;
    9428        24480 :                     if (COMPARISON_P (cmp_res))
    9429        16704 :                       folded = simplify_const_relational_operation
    9430        16704 :                         (GET_CODE (cmp_res), mode0,
    9431        16704 :                          XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
    9432        16704 :                          XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
    9433        24480 :                     ASSERT_RTX_EQ (val, folded);
    9434              :                   }
    9435              :             }
    9436              :         }
    9437            4 : }
    9438              : 
    9439              : 
    9440              : /* Verify some simplifications involving scalar expressions.  */
    9441              : 
    9442              : static void
    9443            4 : test_scalar_ops ()
    9444              : {
    9445          500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    9446              :     {
    9447          496 :       machine_mode mode = (machine_mode) i;
    9448          496 :       if (SCALAR_INT_MODE_P (mode) && mode != BImode)
    9449           40 :         test_scalar_int_ops (mode);
    9450              :     }
    9451              : 
    9452            4 :   test_scalar_int_ext_ops (HImode, QImode);
    9453            4 :   test_scalar_int_ext_ops (SImode, QImode);
    9454            4 :   test_scalar_int_ext_ops (SImode, HImode);
    9455            4 :   test_scalar_int_ext_ops (DImode, QImode);
    9456            4 :   test_scalar_int_ext_ops (DImode, HImode);
    9457            4 :   test_scalar_int_ext_ops (DImode, SImode);
    9458              : 
    9459            4 :   test_scalar_int_ext_ops2 (SImode, HImode, QImode);
    9460            4 :   test_scalar_int_ext_ops2 (DImode, HImode, QImode);
    9461            4 :   test_scalar_int_ext_ops2 (DImode, SImode, QImode);
    9462            4 :   test_scalar_int_ext_ops2 (DImode, SImode, HImode);
    9463              : 
    9464            4 :   test_comparisons (QImode, HImode, SImode);
    9465            4 : }
    9466              : 
    9467              : /* Test vector simplifications involving VEC_DUPLICATE in which the
    9468              :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9469              :    register that holds one element of MODE.  */
    9470              : 
    9471              : static void
    9472          224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
    9473              : {
    9474          224 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9475          224 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9476          448 :   poly_uint64 nunits = GET_MODE_NUNITS (mode);
    9477          224 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    9478              :     {
    9479              :       /* Test some simple unary cases with VEC_DUPLICATE arguments.  */
    9480          124 :       rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
    9481          124 :       rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
    9482          124 :       ASSERT_RTX_EQ (duplicate,
    9483              :                      simplify_unary_operation (NOT, mode,
    9484              :                                                duplicate_not, mode));
    9485              : 
    9486          124 :       rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9487          124 :       rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
    9488          124 :       ASSERT_RTX_EQ (duplicate,
    9489              :                      simplify_unary_operation (NEG, mode,
    9490              :                                                duplicate_neg, mode));
    9491              : 
    9492              :       /* Test some simple binary cases with VEC_DUPLICATE arguments.  */
    9493          124 :       ASSERT_RTX_EQ (duplicate,
    9494              :                      simplify_binary_operation (PLUS, mode, duplicate,
    9495              :                                                 CONST0_RTX (mode)));
    9496              : 
    9497          124 :       ASSERT_RTX_EQ (duplicate,
    9498              :                      simplify_binary_operation (MINUS, mode, duplicate,
    9499              :                                                 CONST0_RTX (mode)));
    9500              : 
    9501          124 :       ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
    9502              :                          simplify_binary_operation (MINUS, mode, duplicate,
    9503              :                                                     duplicate));
    9504              :     }
    9505              : 
    9506              :   /* Test a scalar VEC_SELECT of a VEC_DUPLICATE.  */
    9507          224 :   rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
    9508          224 :   ASSERT_RTX_PTR_EQ (scalar_reg,
    9509              :                      simplify_binary_operation (VEC_SELECT, inner_mode,
    9510              :                                                 duplicate, zero_par));
    9511              : 
    9512          224 :   unsigned HOST_WIDE_INT const_nunits;
    9513          224 :   if (nunits.is_constant (&const_nunits))
    9514              :     {
    9515              :       /* And again with the final element.  */
    9516          224 :       rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
    9517          224 :       rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
    9518          224 :       ASSERT_RTX_PTR_EQ (scalar_reg,
    9519              :                          simplify_binary_operation (VEC_SELECT, inner_mode,
    9520              :                                                     duplicate, last_par));
    9521              : 
    9522              :       /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE.  */
    9523              :       /* Skip this test for vectors of booleans, because offset is in bytes,
    9524              :          while vec_merge indices are in elements (usually bits).  */
    9525          224 :       if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
    9526              :         {
    9527          224 :           rtx vector_reg = make_test_reg (mode);
    9528         3732 :           for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
    9529              :             {
    9530         3288 :               if (i >= HOST_BITS_PER_WIDE_INT)
    9531              :                 break;
    9532         3284 :               rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
    9533         3284 :               rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
    9534         6568 :               poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
    9535              : 
    9536         3284 :               ASSERT_RTX_EQ (scalar_reg,
    9537              :                              simplify_gen_subreg (inner_mode, vm,
    9538              :                                                   mode, offset));
    9539              :             }
    9540              :         }
    9541              :     }
    9542              : 
    9543              :   /* Test a scalar subreg of a VEC_DUPLICATE.  */
    9544          224 :   poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
    9545          224 :   ASSERT_RTX_EQ (scalar_reg,
    9546              :                  simplify_gen_subreg (inner_mode, duplicate,
    9547              :                                       mode, offset));
    9548              : 
    9549          224 :   machine_mode narrower_mode;
    9550          224 :   if (maybe_ne (nunits, 2U)
    9551          184 :       && multiple_p (nunits, 2)
    9552          396 :       && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
    9553          396 :       && VECTOR_MODE_P (narrower_mode))
    9554              :     {
    9555              :       /* Test VEC_DUPLICATE of a vector.  */
    9556          172 :       rtx_vector_builder nbuilder (narrower_mode, 2, 1);
    9557          172 :       nbuilder.quick_push (const0_rtx);
    9558          172 :       nbuilder.quick_push (const1_rtx);
    9559          172 :       rtx_vector_builder builder (mode, 2, 1);
    9560          172 :       builder.quick_push (const0_rtx);
    9561          172 :       builder.quick_push (const1_rtx);
    9562          172 :       ASSERT_RTX_EQ (builder.build (),
    9563              :                      simplify_unary_operation (VEC_DUPLICATE, mode,
    9564              :                                                nbuilder.build (),
    9565              :                                                narrower_mode));
    9566              : 
    9567              :       /* Test VEC_SELECT of a vector.  */
    9568          172 :       rtx vec_par
    9569          172 :         = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
    9570          172 :       rtx narrower_duplicate
    9571          172 :         = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
    9572          172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9573              :                      simplify_binary_operation (VEC_SELECT, narrower_mode,
    9574              :                                                 duplicate, vec_par));
    9575              : 
    9576              :       /* Test a vector subreg of a VEC_DUPLICATE.  */
    9577          172 :       poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
    9578          172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9579              :                      simplify_gen_subreg (narrower_mode, duplicate,
    9580              :                                           mode, offset));
    9581          172 :     }
    9582          224 : }
    9583              : 
    9584              : /* Test vector simplifications involving VEC_SERIES in which the
    9585              :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9586              :    register that holds one element of MODE.  */
    9587              : 
    9588              : static void
    9589           92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
    9590              : {
    9591              :   /* Test unary cases with VEC_SERIES arguments.  */
    9592           92 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9593           92 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9594           92 :   rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9595           92 :   rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
    9596           92 :   rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
    9597           92 :   rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
    9598           92 :   rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
    9599           92 :   rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
    9600           92 :   rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
    9601              :                                          neg_scalar_reg);
    9602           92 :   ASSERT_RTX_EQ (series_0_r,
    9603              :                  simplify_unary_operation (NEG, mode, series_0_nr, mode));
    9604           92 :   ASSERT_RTX_EQ (series_r_m1,
    9605              :                  simplify_unary_operation (NEG, mode, series_nr_1, mode));
    9606           92 :   ASSERT_RTX_EQ (series_r_r,
    9607              :                  simplify_unary_operation (NEG, mode, series_nr_nr, mode));
    9608              : 
    9609              :   /* Test that a VEC_SERIES with a zero step is simplified away.  */
    9610           92 :   ASSERT_RTX_EQ (duplicate,
    9611              :                  simplify_binary_operation (VEC_SERIES, mode,
    9612              :                                             scalar_reg, const0_rtx));
    9613              : 
    9614              :   /* Test PLUS and MINUS with VEC_SERIES.  */
    9615           92 :   rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
    9616           92 :   rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
    9617           92 :   rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
    9618           92 :   ASSERT_RTX_EQ (series_r_r,
    9619              :                  simplify_binary_operation (PLUS, mode, series_0_r,
    9620              :                                             duplicate));
    9621           92 :   ASSERT_RTX_EQ (series_r_1,
    9622              :                  simplify_binary_operation (PLUS, mode, duplicate,
    9623              :                                             series_0_1));
    9624           92 :   ASSERT_RTX_EQ (series_r_m1,
    9625              :                  simplify_binary_operation (PLUS, mode, duplicate,
    9626              :                                             series_0_m1));
    9627           92 :   ASSERT_RTX_EQ (series_0_r,
    9628              :                  simplify_binary_operation (MINUS, mode, series_r_r,
    9629              :                                             duplicate));
    9630           92 :   ASSERT_RTX_EQ (series_r_m1,
    9631              :                  simplify_binary_operation (MINUS, mode, duplicate,
    9632              :                                             series_0_1));
    9633           92 :   ASSERT_RTX_EQ (series_r_1,
    9634              :                  simplify_binary_operation (MINUS, mode, duplicate,
    9635              :                                             series_0_m1));
    9636           92 :   ASSERT_RTX_EQ (series_0_m1,
    9637              :                  simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
    9638              :                                             constm1_rtx));
    9639              : 
    9640              :   /* Test NEG on constant vector series.  */
    9641           92 :   ASSERT_RTX_EQ (series_0_m1,
    9642              :                  simplify_unary_operation (NEG, mode, series_0_1, mode));
    9643           92 :   ASSERT_RTX_EQ (series_0_1,
    9644              :                  simplify_unary_operation (NEG, mode, series_0_m1, mode));
    9645              : 
    9646              :   /* Test PLUS and MINUS on constant vector series.  */
    9647           92 :   rtx scalar2 = gen_int_mode (2, inner_mode);
    9648           92 :   rtx scalar3 = gen_int_mode (3, inner_mode);
    9649           92 :   rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
    9650           92 :   rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
    9651           92 :   rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
    9652           92 :   ASSERT_RTX_EQ (series_1_1,
    9653              :                  simplify_binary_operation (PLUS, mode, series_0_1,
    9654              :                                             CONST1_RTX (mode)));
    9655           92 :   ASSERT_RTX_EQ (series_0_m1,
    9656              :                  simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
    9657              :                                             series_0_m1));
    9658           92 :   ASSERT_RTX_EQ (series_1_3,
    9659              :                  simplify_binary_operation (PLUS, mode, series_1_1,
    9660              :                                             series_0_2));
    9661           92 :   ASSERT_RTX_EQ (series_0_1,
    9662              :                  simplify_binary_operation (MINUS, mode, series_1_1,
    9663              :                                             CONST1_RTX (mode)));
    9664           92 :   ASSERT_RTX_EQ (series_1_1,
    9665              :                  simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
    9666              :                                             series_0_m1));
    9667           92 :   ASSERT_RTX_EQ (series_1_1,
    9668              :                  simplify_binary_operation (MINUS, mode, series_1_3,
    9669              :                                             series_0_2));
    9670              : 
    9671              :   /* Test MULT between constant vectors.  */
    9672           92 :   rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
    9673           92 :   rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
    9674           92 :   rtx scalar9 = gen_int_mode (9, inner_mode);
    9675           92 :   rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
    9676           92 :   ASSERT_RTX_EQ (series_0_2,
    9677              :                  simplify_binary_operation (MULT, mode, series_0_1, vec2));
    9678           92 :   ASSERT_RTX_EQ (series_3_9,
    9679              :                  simplify_binary_operation (MULT, mode, vec3, series_1_3));
    9680           92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9681              :     ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
    9682              :                                              series_0_1));
    9683              : 
    9684              :   /* Test ASHIFT between constant vectors.  */
    9685           92 :   ASSERT_RTX_EQ (series_0_2,
    9686              :                  simplify_binary_operation (ASHIFT, mode, series_0_1,
    9687              :                                             CONST1_RTX (mode)));
    9688           92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9689              :     ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
    9690              :                                              series_0_1));
    9691           92 : }
    9692              : 
    9693              : static rtx
    9694         3136 : simplify_merge_mask (rtx x, rtx mask, int op)
    9695              : {
    9696            0 :   return simplify_context ().simplify_merge_mask (x, mask, op);
    9697              : }
    9698              : 
    9699              : /* Verify simplify_merge_mask works correctly.  */
    9700              : 
    9701              : static void
    9702          224 : test_vec_merge (machine_mode mode)
    9703              : {
    9704          224 :   rtx op0 = make_test_reg (mode);
    9705          224 :   rtx op1 = make_test_reg (mode);
    9706          224 :   rtx op2 = make_test_reg (mode);
    9707          224 :   rtx op3 = make_test_reg (mode);
    9708          224 :   rtx op4 = make_test_reg (mode);
    9709          224 :   rtx op5 = make_test_reg (mode);
    9710          224 :   rtx mask1 = make_test_reg (SImode);
    9711          224 :   rtx mask2 = make_test_reg (SImode);
    9712          224 :   rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
    9713          224 :   rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
    9714          224 :   rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
    9715              : 
    9716              :   /* Simple vec_merge.  */
    9717          224 :   ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
    9718          224 :   ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
    9719          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
    9720          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
    9721              : 
    9722              :   /* Nested vec_merge.
    9723              :      It's tempting to make this simplify right down to opN, but we don't
    9724              :      because all the simplify_* functions assume that the operands have
    9725              :      already been simplified.  */
    9726          224 :   rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
    9727          224 :   ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
    9728          224 :   ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
    9729              : 
    9730              :   /* Intermediate unary op. */
    9731          224 :   rtx unop = gen_rtx_NOT (mode, vm1);
    9732          224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
    9733              :                  simplify_merge_mask (unop, mask1, 0));
    9734          224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
    9735              :                  simplify_merge_mask (unop, mask1, 1));
    9736              : 
    9737              :   /* Intermediate binary op. */
    9738          224 :   rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
    9739          224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
    9740              :                  simplify_merge_mask (binop, mask1, 0));
    9741          224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
    9742              :                  simplify_merge_mask (binop, mask1, 1));
    9743              : 
    9744              :   /* Intermediate ternary op. */
    9745          224 :   rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
    9746          224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
    9747              :                  simplify_merge_mask (tenop, mask1, 0));
    9748          224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
    9749              :                  simplify_merge_mask (tenop, mask1, 1));
    9750              : 
    9751              :   /* Side effects.  */
    9752          224 :   rtx badop0 = gen_rtx_PRE_INC (mode, op0);
    9753          224 :   rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
    9754          224 :   ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
    9755          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
    9756              : 
    9757              :   /* Called indirectly.  */
    9758          224 :   ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
    9759              :                  simplify_rtx (nvm));
    9760          224 : }
    9761              : 
    9762              : /* Test that vector rotate formation works at RTL level.  Try various
    9763              :    combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)).  */
    9764              : 
    9765              : static void
    9766           92 : test_vector_rotate (rtx reg)
    9767              : {
    9768           92 :   machine_mode mode = GET_MODE (reg);
    9769           92 :   unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
    9770           92 :   rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
    9771           92 :   rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
    9772           92 :   lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
    9773           92 :   rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9774           92 :   rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
    9775              :   /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x).  */
    9776           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9777              :              simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
    9778           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9779              :              simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
    9780           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9781              :              simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
    9782              : 
    9783              :   /* Don't go through every possible rotate amount to save execution time.
    9784              :      Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
    9785              :      other bswap operations sometimes. Go through just the odd amounts.  */
    9786         1380 :   for (unsigned i = 3; i < bitwidth - 2; i += 2)
    9787              :     {
    9788         1288 :       rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
    9789         1288 :       rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
    9790         1288 :       lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
    9791         1288 :       lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9792         1288 :       rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
    9793         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9794              :                  simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
    9795         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9796              :                  simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
    9797         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9798              :                  simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
    9799              :     }
    9800           92 : }
    9801              : 
    9802              : /* Test subregs of integer vector constant X, trying elements in
    9803              :    the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
    9804              :    where NELTS is the number of elements in X.  Subregs involving
    9805              :    elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail.  */
    9806              : 
    9807              : static void
    9808          276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
    9809              :                            unsigned int first_valid = 0)
    9810              : {
    9811          276 :   machine_mode inner_mode = GET_MODE (x);
    9812          276 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9813              : 
    9814        34500 :   for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
    9815              :     {
    9816        34224 :       machine_mode outer_mode = (machine_mode) modei;
    9817        34224 :       if (!VECTOR_MODE_P (outer_mode))
    9818        18768 :         continue;
    9819              : 
    9820        15456 :       unsigned int outer_nunits;
    9821        15456 :       if (GET_MODE_INNER (outer_mode) == int_mode
    9822         1932 :           && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
    9823        20412 :           && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
    9824              :         {
    9825              :           /* Test subregs in which the outer mode is a smaller,
    9826              :              constant-sized vector of the same element type.  */
    9827         1092 :           unsigned int limit
    9828         1092 :             = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
    9829         8028 :           for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
    9830              :             {
    9831         6936 :               rtx expected = NULL_RTX;
    9832         6936 :               if (elt >= first_valid)
    9833              :                 {
    9834         6936 :                   rtx_vector_builder builder (outer_mode, outer_nunits, 1);
    9835        46704 :                   for (unsigned int i = 0; i < outer_nunits; ++i)
    9836        32832 :                     builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
    9837         6936 :                   expected = builder.build ();
    9838         6936 :                 }
    9839        13872 :               poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
    9840         6936 :               ASSERT_RTX_EQ (expected,
    9841              :                              simplify_subreg (outer_mode, x,
    9842              :                                               inner_mode, byte));
    9843              :             }
    9844              :         }
    9845        28728 :       else if (known_eq (GET_MODE_SIZE (outer_mode),
    9846              :                          GET_MODE_SIZE (inner_mode))
    9847         2040 :                && known_eq (elt_bias, 0U)
    9848         2040 :                && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
    9849            0 :                    || known_eq (GET_MODE_BITSIZE (outer_mode),
    9850              :                                 GET_MODE_NUNITS (outer_mode)))
    9851         2040 :                && (!FLOAT_MODE_P (outer_mode)
    9852        15876 :                    || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
    9853         1104 :                        == GET_MODE_UNIT_PRECISION (outer_mode)))
    9854        14364 :                && (GET_MODE_SIZE (inner_mode).is_constant ()
    9855              :                    || !CONST_VECTOR_STEPPED_P (x)))
    9856              :         {
    9857              :           /* Try converting to OUTER_MODE and back.  */
    9858         1800 :           rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
    9859         1800 :           ASSERT_TRUE (outer_x != NULL_RTX);
    9860         1800 :           ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
    9861              :                                              outer_mode, 0));
    9862              :         }
    9863              :     }
    9864              : 
    9865          276 :   if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
    9866              :     {
    9867              :       /* Test each byte in the element range.  */
    9868          276 :       unsigned int limit
    9869          276 :         = constant_lower_bound (GET_MODE_SIZE (inner_mode));
    9870        14604 :       for (unsigned int i = 0; i < limit; ++i)
    9871              :         {
    9872        14328 :           unsigned int elt = i / GET_MODE_SIZE (int_mode);
    9873        14328 :           rtx expected = NULL_RTX;
    9874        14328 :           if (elt >= first_valid)
    9875              :             {
    9876        14328 :               unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
    9877        14328 :               if (BYTES_BIG_ENDIAN)
    9878              :                 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
    9879        14328 :               rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
    9880        14328 :               wide_int shifted_elt
    9881        14328 :                 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
    9882        14328 :               expected = immed_wide_int_const (shifted_elt, QImode);
    9883        14328 :             }
    9884        28656 :           poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
    9885        14328 :           ASSERT_RTX_EQ (expected,
    9886              :                          simplify_subreg (QImode, x, inner_mode, byte));
    9887              :         }
    9888              :     }
    9889          276 : }
    9890              : 
    9891              : /* Test constant subregs of integer vector mode INNER_MODE, using 1
    9892              :    element per pattern.  */
    9893              : 
    9894              : static void
    9895           92 : test_vector_subregs_repeating (machine_mode inner_mode)
    9896              : {
    9897          184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
    9898           92 :   unsigned int min_nunits = constant_lower_bound (nunits);
    9899           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9900           92 :   unsigned int count = gcd (min_nunits, 8);
    9901              : 
    9902           92 :   rtx_vector_builder builder (inner_mode, count, 1);
    9903          776 :   for (unsigned int i = 0; i < count; ++i)
    9904          592 :     builder.quick_push (gen_int_mode (8 - i, int_mode));
    9905           92 :   rtx x = builder.build ();
    9906              : 
    9907           92 :   test_vector_subregs_modes (x);
    9908           92 :   if (!nunits.is_constant ())
    9909              :     test_vector_subregs_modes (x, nunits - min_nunits);
    9910           92 : }
    9911              : 
    9912              : /* Test constant subregs of integer vector mode INNER_MODE, using 2
    9913              :    elements per pattern.  */
    9914              : 
    9915              : static void
    9916           92 : test_vector_subregs_fore_back (machine_mode inner_mode)
    9917              : {
    9918          184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
    9919           92 :   unsigned int min_nunits = constant_lower_bound (nunits);
    9920           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9921           92 :   unsigned int count = gcd (min_nunits, 4);
    9922              : 
    9923           92 :   rtx_vector_builder builder (inner_mode, count, 2);
    9924          536 :   for (unsigned int i = 0; i < count; ++i)
    9925          352 :     builder.quick_push (gen_int_mode (i, int_mode));
    9926          444 :   for (unsigned int i = 0; i < count; ++i)
    9927          352 :     builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
    9928           92 :   rtx x = builder.build ();
    9929              : 
    9930           92 :   test_vector_subregs_modes (x);
    9931           92 :   if (!nunits.is_constant ())
    9932              :     test_vector_subregs_modes (x, nunits - min_nunits, count);
    9933           92 : }
    9934              : 
    9935              : /* Test constant subregs of integer vector mode INNER_MODE, using 3
    9936              :    elements per pattern.  */
    9937              : 
    9938              : static void
    9939           92 : test_vector_subregs_stepped (machine_mode inner_mode)
    9940              : {
    9941              :   /* Build { 0, 1, 2, 3, ... }.  */
    9942           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9943           92 :   rtx_vector_builder builder (inner_mode, 1, 3);
    9944          460 :   for (unsigned int i = 0; i < 3; ++i)
    9945          276 :     builder.quick_push (gen_int_mode (i, int_mode));
    9946           92 :   rtx x = builder.build ();
    9947              : 
    9948           92 :   test_vector_subregs_modes (x);
    9949           92 : }
    9950              : 
    9951              : /* Test constant subregs of integer vector mode INNER_MODE.  */
    9952              : 
    9953              : static void
    9954           92 : test_vector_subregs (machine_mode inner_mode)
    9955              : {
    9956           92 :   test_vector_subregs_repeating (inner_mode);
    9957           92 :   test_vector_subregs_fore_back (inner_mode);
    9958           92 :   test_vector_subregs_stepped (inner_mode);
    9959           92 : }
    9960              : 
    9961              : /* Verify some simplifications involving vectors.  */
    9962              : 
    9963              : static void
    9964            4 : test_vector_ops ()
    9965              : {
    9966          500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    9967              :     {
    9968          496 :       machine_mode mode = (machine_mode) i;
    9969          496 :       if (VECTOR_MODE_P (mode))
    9970              :         {
    9971          448 :           rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
    9972          224 :           test_vector_ops_duplicate (mode, scalar_reg);
    9973          224 :           rtx vector_reg = make_test_reg (mode);
    9974          224 :           if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
    9975          348 :               && maybe_gt (GET_MODE_NUNITS (mode), 2))
    9976              :             {
    9977           92 :               test_vector_ops_series (mode, scalar_reg);
    9978           92 :               test_vector_subregs (mode);
    9979           92 :               test_vector_rotate (vector_reg);
    9980              :             }
    9981          224 :           test_vec_merge (mode);
    9982              :         }
    9983              :     }
    9984            4 : }
    9985              : 
    9986              : template<unsigned int N>
    9987              : struct simplify_const_poly_int_tests
    9988              : {
    9989              :   static void run ();
    9990              : };
    9991              : 
    9992              : template<>
    9993              : struct simplify_const_poly_int_tests<1>
    9994              : {
    9995              :   static void run () {}
    9996              : };
    9997              : 
    9998              : /* Test various CONST_POLY_INT properties.  */
    9999              : 
   10000              : template<unsigned int N>
   10001              : void
   10002              : simplify_const_poly_int_tests<N>::run ()
   10003              : {
   10004              :   using poly_int64 = poly_int<N, HOST_WIDE_INT>;
   10005              :   rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
   10006              :   rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
   10007              :   rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
   10008              :   rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
   10009              :   rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
   10010              :   rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
   10011              :   rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
   10012              :   rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
   10013              :   rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
   10014              :   rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
   10015              :   rtx two = GEN_INT (2);
   10016              :   rtx six = GEN_INT (6);
   10017              :   poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
   10018              : 
   10019              :   /* These tests only try limited operation combinations.  Fuller arithmetic
   10020              :      testing is done directly on poly_ints.  */
   10021              :   ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
   10022              :   ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
   10023              :   ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
   10024              :   ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
   10025              :   ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
   10026              :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
   10027              :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
   10028              :   ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
   10029              :   ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
   10030              :   ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
   10031              :   ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
   10032              : }
   10033              : 
   10034              : /* Run all of the selftests within this file.  */
   10035              : 
   10036              : void
   10037            4 : simplify_rtx_cc_tests ()
   10038              : {
   10039            4 :   test_scalar_ops ();
   10040            4 :   test_vector_ops ();
   10041            4 :   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
   10042            4 : }
   10043              : 
   10044              : } // namespace selftest
   10045              : 
   10046              : #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.