LCOV - code coverage report
Current view: top level - gcc - simplify-rtx.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.7 % 4989 4424
Test Date: 2026-10-17 16:30:31 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      9279549 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
      56              : {
      57      9279549 :   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      6298465 : mode_signbit_p (machine_mode mode, const_rtx x)
      65              : {
      66      6298465 :   unsigned HOST_WIDE_INT val;
      67      6298465 :   unsigned int width;
      68      6298465 :   scalar_int_mode int_mode;
      69              : 
      70      6298465 :   if (!is_int_mode (mode, &int_mode))
      71              :     return false;
      72              : 
      73      6298457 :   width = GET_MODE_PRECISION (int_mode);
      74      6298457 :   if (width == 0)
      75              :     return false;
      76              : 
      77      6298457 :   if (width <= HOST_BITS_PER_WIDE_INT
      78      6296924 :       && CONST_INT_P (x))
      79      6151417 :     val = INTVAL (x);
      80              : #if TARGET_SUPPORTS_WIDE_INT
      81       147040 :   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      6151417 :   if (width < HOST_BITS_PER_WIDE_INT)
     109      5573363 :     val &= (HOST_WIDE_INT_1U << width) - 1;
     110      6151840 :   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      3840615 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     119              : {
     120      3840615 :   unsigned int width;
     121      3840615 :   scalar_int_mode int_mode;
     122              : 
     123      3840615 :   if (!is_int_mode (mode, &int_mode))
     124              :     return false;
     125              : 
     126      3840579 :   width = GET_MODE_PRECISION (int_mode);
     127      3840579 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     128              :     return false;
     129              : 
     130      3835661 :   val &= GET_MODE_MASK (int_mode);
     131      3835661 :   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      2697946 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     138              : {
     139      2697946 :   unsigned int width;
     140              : 
     141      2697946 :   scalar_int_mode int_mode;
     142      2697946 :   if (!is_int_mode (mode, &int_mode))
     143              :     return false;
     144              : 
     145      2635996 :   width = GET_MODE_PRECISION (int_mode);
     146      2635996 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     147              :     return false;
     148              : 
     149      2635996 :   val &= HOST_WIDE_INT_1U << (width - 1);
     150      2635996 :   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      7898286 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     157              : {
     158      7898286 :   unsigned int width;
     159              : 
     160      7898286 :   scalar_int_mode int_mode;
     161      7898286 :   if (!is_int_mode (mode, &int_mode))
     162              :     return false;
     163              : 
     164      7535067 :   width = GET_MODE_PRECISION (int_mode);
     165      7535067 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     166              :     return false;
     167              : 
     168      7424474 :   val &= HOST_WIDE_INT_1U << (width - 1);
     169      7424474 :   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    123490602 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
     177              :                                        rtx op0, rtx op1)
     178              : {
     179    123490602 :   rtx tem;
     180              : 
     181              :   /* If this simplifies, do it.  */
     182    123490602 :   tem = simplify_binary_operation (code, mode, op0, op1);
     183    123490602 :   if (tem)
     184              :     return tem;
     185              : 
     186              :   /* Put complex operands first and constants second if commutative.  */
     187     78641212 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
     188     78641212 :       && swap_commutative_operands_p (op0, op1))
     189              :     std::swap (op0, op1);
     190              : 
     191     78641212 :   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   2826279200 : avoid_constant_pool_reference (rtx x)
     198              : {
     199   2826279200 :   rtx c, tmp, addr;
     200   2826279200 :   machine_mode cmode;
     201   2826279200 :   poly_int64 offset = 0;
     202              : 
     203   2826279200 :   switch (GET_CODE (x))
     204              :     {
     205    271286103 :     case MEM:
     206    271286103 :       break;
     207              : 
     208       915913 :     case FLOAT_EXTEND:
     209              :       /* Handle float extensions of constant pool references.  */
     210       915913 :       tmp = XEXP (x, 0);
     211       915913 :       c = avoid_constant_pool_reference (tmp);
     212       915913 :       if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
     213       125077 :         return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
     214       125077 :                                              GET_MODE (x));
     215              :       return x;
     216              : 
     217              :     default:
     218              :       return x;
     219              :     }
     220              : 
     221    271286103 :   if (GET_MODE (x) == BLKmode)
     222              :     return x;
     223              : 
     224    267186314 :   addr = XEXP (x, 0);
     225              : 
     226              :   /* Call target hook to avoid the effects of -fpic etc....  */
     227    267186314 :   addr = targetm.delegitimize_address (addr);
     228              : 
     229              :   /* Split the address into a base and integer offset.  */
     230    267186314 :   addr = strip_offset (addr, &offset);
     231              : 
     232    267186314 :   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    267186314 :   if (GET_CODE (addr) == SYMBOL_REF
     238    267186314 :       && CONSTANT_POOL_ADDRESS_P (addr))
     239              :     {
     240      5454155 :       c = get_pool_constant (addr);
     241      5454155 :       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      5454155 :       if (known_eq (offset, 0) && cmode == GET_MODE (x))
     247              :         return c;
     248        45870 :       else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
     249              :         {
     250        15290 :           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
     251        15290 :           if (tem && CONSTANT_P (tem))
     252        15173 :             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   3574865152 : 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   3574865152 :   if (MEM_P (x)
     269     63177807 :       && MEM_EXPR (x)
     270   3614132219 :       && MEM_OFFSET_KNOWN_P (x))
     271              :     {
     272     36196256 :       tree decl = MEM_EXPR (x);
     273     36196256 :       machine_mode mode = GET_MODE (x);
     274     36196256 :       poly_int64 offset = 0;
     275              : 
     276     36196256 :       switch (TREE_CODE (decl))
     277              :         {
     278              :         default:
     279              :           decl = NULL;
     280              :           break;
     281              : 
     282              :         case VAR_DECL:
     283              :           break;
     284              : 
     285     10309648 :         case ARRAY_REF:
     286     10309648 :         case ARRAY_RANGE_REF:
     287     10309648 :         case COMPONENT_REF:
     288     10309648 :         case BIT_FIELD_REF:
     289     10309648 :         case REALPART_EXPR:
     290     10309648 :         case IMAGPART_EXPR:
     291     10309648 :         case VIEW_CONVERT_EXPR:
     292     10309648 :           {
     293     10309648 :             poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
     294     10309648 :             tree toffset;
     295     10309648 :             int unsignedp, reversep, volatilep = 0;
     296              : 
     297     10309648 :             decl
     298     10309648 :               = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
     299              :                                      &unsignedp, &reversep, &volatilep);
     300     20619296 :             if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
     301     10602172 :                 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
     302     20178486 :                 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
     303              :               decl = NULL;
     304              :             else
     305      9576314 :               offset += bytepos + toffset_val;
     306     10309648 :             break;
     307              :           }
     308              :         }
     309              : 
     310       733334 :       if (decl
     311     21281339 :           && mode == GET_MODE (x)
     312     21008727 :           && VAR_P (decl)
     313     13637213 :           && (TREE_STATIC (decl)
     314     12403815 :               || DECL_THREAD_LOCAL_P (decl))
     315      1270358 :           && DECL_RTL_SET_P (decl)
     316     10846222 :           && MEM_P (DECL_RTL (decl)))
     317              :         {
     318      1269908 :           rtx newx;
     319              : 
     320      1269908 :           offset += MEM_OFFSET (x);
     321              : 
     322      1269908 :           newx = DECL_RTL (decl);
     323              : 
     324      1269908 :           if (MEM_P (newx))
     325              :             {
     326      1269908 :               rtx n = XEXP (newx, 0), o = XEXP (x, 0);
     327      1269908 :               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      1269908 :               n = strip_offset (n, &n_offset);
     336      1269908 :               o = strip_offset (o, &o_offset);
     337      2511938 :               if (!(known_eq (o_offset, n_offset + offset)
     338      1242030 :                     && rtx_equal_p (o, n)))
     339       212855 :                 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   3574865152 :   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      7245283 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
     355              :                                       machine_mode op_mode)
     356              : {
     357      7245283 :   rtx tem;
     358              : 
     359              :   /* If this simplifies, use it.  */
     360      7245283 :   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
     361              :     return tem;
     362              : 
     363      2502702 :   return gen_rtx_fmt_e (code, mode, op);
     364              : }
     365              : 
     366              : /* Likewise for ternary operations.  */
     367              : 
     368              : rtx
     369      2972109 : 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      2972109 :   rtx tem;
     374              : 
     375              :   /* If this simplifies, use it.  */
     376      2972109 :   if ((tem = simplify_ternary_operation (code, mode, op0_mode,
     377              :                                          op0, op1, op2)) != 0)
     378              :     return tem;
     379              : 
     380      2718149 :   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     22942341 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
     388              :                                            machine_mode cmp_mode,
     389              :                                            rtx op0, rtx op1)
     390              : {
     391     22942341 :   rtx tem;
     392              : 
     393     22942341 :   if ((tem = simplify_relational_operation (code, mode, cmp_mode,
     394              :                                             op0, op1)) != 0)
     395              :     return tem;
     396              : 
     397     20239514 :   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    514079731 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
     407              :                          rtx (*fn) (rtx, const_rtx, void *), void *data)
     408              : {
     409    514079731 :   enum rtx_code code = GET_CODE (x);
     410    514079731 :   machine_mode mode = GET_MODE (x);
     411    514079731 :   machine_mode op_mode;
     412    514079731 :   const char *fmt;
     413    514079731 :   rtx op0, op1, op2, newx, op;
     414    514079731 :   rtvec vec, newvec;
     415    514079731 :   int i, j;
     416              : 
     417    514079731 :   if (UNLIKELY (fn != NULL))
     418              :     {
     419    448720594 :       newx = fn (x, old_rtx, data);
     420    448720594 :       if (newx)
     421              :         return newx;
     422              :     }
     423     65359137 :   else if (rtx_equal_p (x, old_rtx))
     424      5737561 :     return copy_rtx ((rtx) data);
     425              : 
     426    405802591 :   switch (GET_RTX_CLASS (code))
     427              :     {
     428      2083538 :     case RTX_UNARY:
     429      2083538 :       op0 = XEXP (x, 0);
     430      2083538 :       op_mode = GET_MODE (op0);
     431      2083538 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     432      2083538 :       if (op0 == XEXP (x, 0))
     433              :         return x;
     434       663609 :       return simplify_gen_unary (code, mode, op0, op_mode);
     435              : 
     436     77365228 :     case RTX_BIN_ARITH:
     437     77365228 :     case RTX_COMM_ARITH:
     438     77365228 :       op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     439     77365228 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     440     77365228 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     441              :         return x;
     442     23907847 :       return simplify_gen_binary (code, mode, op0, op1);
     443              : 
     444     10190371 :     case RTX_COMPARE:
     445     10190371 :     case RTX_COMM_COMPARE:
     446     10190371 :       op0 = XEXP (x, 0);
     447     10190371 :       op1 = XEXP (x, 1);
     448     10190371 :       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
     449     10190371 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     450     10190371 :       op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
     451     10190371 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     452              :         return x;
     453      2811430 :       return simplify_gen_relational (code, mode, op_mode, op0, op1);
     454              : 
     455      6427762 :     case RTX_TERNARY:
     456      6427762 :     case RTX_BITFIELD_OPS:
     457      6427762 :       op0 = XEXP (x, 0);
     458      6427762 :       op_mode = GET_MODE (op0);
     459      6427762 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     460      6427762 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     461      6427762 :       op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
     462      6427762 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
     463              :         return x;
     464      2203835 :       if (op_mode == VOIDmode)
     465      2180289 :         op_mode = GET_MODE (op0);
     466      2203835 :       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
     467              : 
     468     92621824 :     case RTX_EXTRA:
     469     92621824 :       if (code == SUBREG)
     470              :         {
     471       621401 :           op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
     472       621401 :           if (op0 == SUBREG_REG (x))
     473              :             return x;
     474       135354 :           op0 = simplify_gen_subreg (GET_MODE (x), op0,
     475        67677 :                                      GET_MODE (SUBREG_REG (x)),
     476        67677 :                                      SUBREG_BYTE (x));
     477        67677 :           return op0 ? op0 : x;
     478              :         }
     479              :       break;
     480              : 
     481     64408528 :     case RTX_OBJ:
     482     64408528 :       if (code == MEM)
     483              :         {
     484     10970712 :           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     485     10970712 :           if (op0 == XEXP (x, 0))
     486              :             return x;
     487       162457 :           return replace_equiv_address_nv (x, op0);
     488              :         }
     489     53437816 :       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    298143579 :   newx = x;
     515    298143579 :   fmt = GET_RTX_FORMAT (code);
     516    644123877 :   for (i = 0; fmt[i]; i++)
     517    345980298 :     switch (fmt[i])
     518              :       {
     519      3279932 :       case 'E':
     520      3279932 :         vec = XVEC (x, i);
     521      3279932 :         newvec = XVEC (newx, i);
     522     13656800 :         for (j = 0; j < GET_NUM_ELEM (vec); j++)
     523              :           {
     524     10376868 :             op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
     525              :                                           old_rtx, fn, data);
     526     10376868 :             if (op != RTVEC_ELT (vec, j))
     527              :               {
     528       356974 :                 if (newvec == vec)
     529              :                   {
     530       342340 :                     newvec = shallow_copy_rtvec (vec);
     531       342340 :                     if (x == newx)
     532       342340 :                       newx = shallow_copy_rtx (x);
     533       342340 :                     XVEC (newx, i) = newvec;
     534              :                   }
     535       356974 :                 RTVEC_ELT (newvec, j) = op;
     536              :               }
     537              :           }
     538              :         break;
     539              : 
     540     83790690 :       case 'e':
     541     83790690 :         if (XEXP (x, i))
     542              :           {
     543     83790640 :             op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
     544     83790640 :             if (op != XEXP (x, i))
     545              :               {
     546      4778196 :                 if (x == newx)
     547      4774976 :                   newx = shallow_copy_rtx (x);
     548      4778196 :                 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     13293928 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
     561              : {
     562     13293928 :   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     23648811 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
     614              :                                        machine_mode op_mode)
     615              : {
     616     23648811 :   unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
     617     23648811 :   unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
     618     23648811 :   scalar_int_mode int_mode, int_op_mode, subreg_mode;
     619              : 
     620     23648811 :   gcc_assert (precision <= op_precision);
     621              : 
     622              :   /* Optimize truncations of zero and sign extended values.  */
     623     23648811 :   if (GET_CODE (op) == ZERO_EXTEND
     624     23648811 :       || 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       375556 :       machine_mode origmode = GET_MODE (XEXP (op, 0));
     633       375556 :       if (mode == origmode)
     634              :         return XEXP (op, 0);
     635        27468 :       else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
     636        10827 :         return simplify_gen_unary (TRUNCATE, mode,
     637        10827 :                                    XEXP (op, 0), origmode);
     638              :       else
     639         2907 :         return simplify_gen_unary (GET_CODE (op), mode,
     640         2907 :                                    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     23273255 :   if (1
     647              :       && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
     648              :       && (GET_CODE (op) == PLUS
     649              :           || GET_CODE (op) == MINUS
     650     23273255 :           || GET_CODE (op) == MULT))
     651              :     {
     652      1413740 :       rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
     653      1413740 :       if (op0)
     654              :         {
     655      1413740 :           rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
     656      1413740 :           if (op1)
     657      1413740 :             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     21859515 :   if ((GET_CODE (op) == LSHIFTRT
     665     21859515 :        || 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      1925515 :       && 2 * precision <= op_precision
     671      1925515 :       && CONST_INT_P (XEXP (op, 1))
     672      1824411 :       && 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     21859491 :   if ((GET_CODE (op) == LSHIFTRT
     682              :        || GET_CODE (op) == ASHIFTRT)
     683      1925491 :       && CONST_INT_P (XEXP (op, 1))
     684      1824387 :       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     685          924 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     686          924 :       && UINTVAL (XEXP (op, 1)) < precision)
     687          907 :     return simplify_gen_binary (LSHIFTRT, mode,
     688          907 :                                 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     21858584 :   if (GET_CODE (op) == ASHIFT
     694       841123 :       && CONST_INT_P (XEXP (op, 1))
     695       781330 :       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     696       781330 :           || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
     697          638 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     698          628 :       && UINTVAL (XEXP (op, 1)) < precision)
     699          583 :     return simplify_gen_binary (ASHIFT, mode,
     700          583 :                                 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     21858001 :   if (GET_CODE (op) == AND
     706       799740 :       && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
     707       799740 :           || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
     708        47916 :       && CONST_INT_P (XEXP (XEXP (op, 0), 1))
     709        47811 :       && CONST_INT_P (XEXP (op, 1)))
     710              :     {
     711        47778 :       rtx op0 = (XEXP (XEXP (op, 0), 0));
     712        47778 :       rtx shift_op = XEXP (XEXP (op, 0), 1);
     713        47778 :       rtx mask_op = XEXP (op, 1);
     714        47778 :       unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
     715        47778 :       unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
     716              : 
     717        47778 :       if (shift < precision
     718              :           /* If doing this transform works for an X with all bits set,
     719              :              it works for any X.  */
     720        31636 :           && ((GET_MODE_MASK (mode) >> shift) & mask)
     721        31636 :              == ((GET_MODE_MASK (op_mode) >> shift) & mask)
     722         6839 :           && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
     723        54617 :           && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
     724              :         {
     725         6839 :           mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
     726         6839 :           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     21851162 :   if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
     733      1141892 :       && precision <= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (op, 0)))
     734       569162 :       && CONST_INT_P (XEXP (op, 1))
     735     22420324 :       && CONST_INT_P (XEXP (op, 2)))
     736              :     {
     737       533833 :       rtx op0 = XEXP (op, 0);
     738       533833 :       unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
     739       533833 :       unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
     740       533833 :       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       533833 :       else if (!BITS_BIG_ENDIAN && precision >= len + pos)
     752              :         {
     753       182261 :           if (GET_MODE (op0) != mode)
     754       138281 :             op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     755       138281 :           if (op0)
     756       182261 :             return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     757       182261 :                                          XEXP (op, 1), XEXP (op, 2));
     758              :         }
     759              :     }
     760              : 
     761              :   /* Recognize a word extraction from a multi-word subreg.  */
     762     21668901 :   if ((GET_CODE (op) == LSHIFTRT
     763     21668901 :        || GET_CODE (op) == ASHIFTRT)
     764      1924584 :       && SCALAR_INT_MODE_P (mode)
     765      1921367 :       && SCALAR_INT_MODE_P (op_mode)
     766      2059159 :       && precision >= BITS_PER_WORD
     767        61695 :       && 2 * precision <= op_precision
     768        61695 :       && CONST_INT_P (XEXP (op, 1))
     769        52210 :       && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
     770         1766 :       && UINTVAL (XEXP (op, 1)) < op_precision)
     771              :     {
     772         1766 :       poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
     773         1766 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     774         1766 :       return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
     775              :                                   (WORDS_BIG_ENDIAN
     776         1766 :                                    ? byte - shifted_bytes
     777         1766 :                                    : 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     21667135 :   if ((GET_CODE (op) == LSHIFTRT
     784              :        || GET_CODE (op) == ASHIFTRT)
     785      1919601 :       && is_a <scalar_int_mode> (mode, &int_mode)
     786     21666463 :       && is_a <scalar_int_mode> (op_mode, &int_op_mode)
     787      1919601 :       && MEM_P (XEXP (op, 0))
     788        11321 :       && CONST_INT_P (XEXP (op, 1))
     789        20866 :       && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
     790          715 :       && INTVAL (XEXP (op, 1)) > 0
     791         1430 :       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
     792          715 :       && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
     793          715 :                                      MEM_ADDR_SPACE (XEXP (op, 0)))
     794          715 :       && ! MEM_VOLATILE_P (XEXP (op, 0))
     795     21667135 :       && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
     796              :           || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
     797              :     {
     798          672 :       poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
     799          672 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     800          672 :       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     21666463 :   if ((GET_CODE (op) == ABS
     809     21666463 :        || GET_CODE (op) == NEG)
     810        21304 :       && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
     811        21304 :           || 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     21666462 :   if (GET_CODE (op) == SUBREG
     818     21667012 :       && is_a <scalar_int_mode> (mode, &int_mode)
     819       120600 :       && SCALAR_INT_MODE_P (op_mode)
     820       120600 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
     821     21786568 :       && subreg_lowpart_p (op))
     822              :     {
     823              :       /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X).  */
     824       120086 :       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       120086 :       if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
     841              :         {
     842       120086 :           unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
     843       120086 :           unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
     844       120086 :           if (int_op_prec > subreg_prec)
     845              :             {
     846        89574 :               if (int_mode == subreg_mode)
     847              :                 return SUBREG_REG (op);
     848           63 :               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        30512 :           else if (int_op_prec < subreg_prec
     855        30512 :                    && GET_MODE_PRECISION (int_mode) < int_op_prec)
     856        30512 :             return simplify_gen_unary (TRUNCATE, int_mode,
     857        30512 :                                        SUBREG_REG (op), subreg_mode);
     858              :         }
     859              :     }
     860              : 
     861              :   /* (truncate:A (truncate:B X)) is (truncate:A X).  */
     862     21546412 :   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     21546412 :   if (GET_CODE (op) == IOR
     869        35200 :       && SCALAR_INT_MODE_P (mode)
     870        35200 :       && SCALAR_INT_MODE_P (op_mode)
     871        35200 :       && CONST_INT_P (XEXP (op, 1))
     872     21554889 :       && 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     30124506 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
     883              :                                             rtx op, machine_mode op_mode)
     884              : {
     885     30124506 :   rtx trueop, tem;
     886              : 
     887     30124506 :   trueop = avoid_constant_pool_reference (op);
     888              : 
     889     30124506 :   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
     890     30124506 :   if (tem)
     891              :     return tem;
     892              : 
     893     24649531 :   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         2797 : exact_int_to_float_conversion_p (const_rtx op)
     901              : {
     902         2797 :   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         2797 :   if (op0_mode == VOIDmode)
     906              :     return false;
     907         5592 :   int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
     908         2796 :   int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
     909         2796 :   int in_bits = in_prec;
     910         2796 :   if (HWI_COMPUTABLE_MODE_P (op0_mode))
     911              :     {
     912         2706 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
     913         2706 :       if (GET_CODE (op) == FLOAT)
     914         2585 :         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         2706 :       in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
     920              :     }
     921         2796 :   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     24649531 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
     928              :                                               rtx op)
     929              : {
     930     24649531 :   enum rtx_code reversed;
     931     24649531 :   rtx temp, elt, base, step;
     932     24649531 :   scalar_int_mode inner, int_mode, op_mode, op0_mode;
     933              : 
     934     24649531 :   switch (code)
     935              :     {
     936      2415723 :     case NOT:
     937              :       /* (not (not X)) == X.  */
     938      2415723 :       if (GET_CODE (op) == NOT)
     939         3169 :         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      2412554 :       if (COMPARISON_P (op)
     944        17236 :           && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == -1)
     945              : #ifdef VECTOR_STORE_FLAG_VALUE
     946        17236 :               || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
     947              :                   && VECTOR_STORE_FLAG_VALUE (mode) == constm1_rtx)
     948              : #endif
     949        11932 :               || mode == BImode)
     950      2417858 :           && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
     951         5133 :         return simplify_gen_relational (reversed, mode, VOIDmode,
     952         5133 :                                         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      2407421 :       if (GET_CODE (op) == NEG
     957        76461 :           && 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      2407427 :           && ((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      2407415 :       if (GET_CODE (op) == PLUS
     975       285120 :           && XEXP (op, 1) == constm1_rtx)
     976         4647 :         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      2402768 :       if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
     982        76452 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
     983        76452 :                                     CONSTM1_RTX (mode));
     984              : 
     985              :       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
     986      2326316 :       if (GET_CODE (op) == XOR
     987        18668 :           && CONST_INT_P (XEXP (op, 1))
     988      2330860 :           && (temp = simplify_unary_operation (NOT, mode,
     989              :                                                XEXP (op, 1), mode)) != 0)
     990         4544 :         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      2321772 :       if (GET_CODE (op) == PLUS
     994       280473 :           && CONST_INT_P (XEXP (op, 1))
     995       164949 :           && mode_signbit_p (mode, XEXP (op, 1))
     996      2325658 :           && (temp = simplify_unary_operation (NOT, mode,
     997              :                                                XEXP (op, 1), mode)) != 0)
     998         3886 :         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      2317886 :       if (GET_CODE (op) == ASHIFT
    1007        31832 :           && XEXP (op, 0) == const1_rtx)
    1008              :         {
    1009         1143 :           temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
    1010         1143 :           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      2316743 :       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      2316743 :       if (partial_subreg_p (op)
    1026       605892 :           && subreg_lowpart_p (op)
    1027       605580 :           && GET_CODE (SUBREG_REG (op)) == ASHIFT
    1028       623764 :           && XEXP (SUBREG_REG (op), 0) == const1_rtx)
    1029              :         {
    1030          147 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
    1031          147 :           rtx x;
    1032              : 
    1033          147 :           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          147 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
    1038          147 :           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      2316596 :       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
    1047              :         {
    1048        14293 :           rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
    1049        14293 :           machine_mode op_mode;
    1050              : 
    1051        14293 :           op_mode = GET_MODE (in1);
    1052        14293 :           in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
    1053              : 
    1054        14293 :           op_mode = GET_MODE (in2);
    1055        14293 :           if (op_mode == VOIDmode)
    1056         5686 :             op_mode = mode;
    1057        14293 :           in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
    1058              : 
    1059        14293 :           if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
    1060              :             std::swap (in1, in2);
    1061              : 
    1062        28586 :           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      2302303 :       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      1816595 :     case NEG:
    1075              :       /* (neg (neg X)) == X.  */
    1076      1816595 :       if (GET_CODE (op) == NEG)
    1077         6887 :         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      1809708 :       if (GET_CODE (op) == IF_THEN_ELSE)
    1083              :         {
    1084         3355 :           rtx cond = XEXP (op, 0);
    1085         3355 :           rtx true_rtx = XEXP (op, 1);
    1086         3355 :           rtx false_rtx = XEXP (op, 2);
    1087              : 
    1088         3355 :           if ((GET_CODE (true_rtx) == NEG
    1089            0 :                && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
    1090         3355 :                || (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      1809708 :       if (GET_CODE (op) == PLUS
    1107       143595 :           && XEXP (op, 1) == const1_rtx)
    1108        57266 :         return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1109              : 
    1110              :       /* Similarly, (neg (not X)) is (plus X 1).  */
    1111      1752442 :       if (GET_CODE (op) == NOT)
    1112          264 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
    1113          264 :                                     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      1752178 :       if (GET_CODE (op) == MINUS
    1121        25049 :           && !HONOR_SIGNED_ZEROS (mode)
    1122      1775837 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1123        23659 :         return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
    1124              : 
    1125      1728519 :       if (GET_CODE (op) == PLUS
    1126        86329 :           && !HONOR_SIGNED_ZEROS (mode)
    1127      1814372 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1128              :         {
    1129              :           /* (neg (plus A C)) is simplified to (minus -C A).  */
    1130        85853 :           if (CONST_SCALAR_INT_P (XEXP (op, 1))
    1131         5166 :               || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
    1132              :             {
    1133        80687 :               temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
    1134        80687 :               if (temp)
    1135        80687 :                 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         5166 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
    1140         5166 :           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      1642666 :       if (GET_CODE (op) == MULT
    1146      1642666 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1147              :         {
    1148        24901 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
    1149        24901 :           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      1617765 :       if (GET_CODE (op) == ASHIFT)
    1156              :         {
    1157        50446 :           temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
    1158        50446 :           if (temp)
    1159        10123 :             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      1607642 :       if (GET_CODE (op) == ASHIFTRT
    1165        30304 :           && CONST_INT_P (XEXP (op, 1))
    1166      1668142 :           && 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      1606866 :       if (GET_CODE (op) == LSHIFTRT
    1173         9242 :           && CONST_INT_P (XEXP (op, 1))
    1174      1625206 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1175         3619 :         return simplify_gen_binary (ASHIFTRT, mode,
    1176         3619 :                                     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      1603247 :       if (GET_CODE (op) == XOR
    1180        11009 :           && XEXP (op, 1) == const1_rtx
    1181      1603336 :           && nonzero_bits (XEXP (op, 0), mode) == 1)
    1182           34 :         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      1603213 :       if (GET_CODE (op) == LT
    1187         3187 :           && XEXP (op, 1) == const0_rtx
    1188      1605567 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
    1189              :         {
    1190          544 :           int_mode = as_a <scalar_int_mode> (mode);
    1191          544 :           int isize = GET_MODE_PRECISION (inner);
    1192          544 :           if (STORE_FLAG_VALUE == 1)
    1193              :             {
    1194          544 :               temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
    1195              :                                           gen_int_shift_amount (inner,
    1196          544 :                                                                 isize - 1));
    1197          544 :               if (int_mode == inner)
    1198              :                 return temp;
    1199          315 :               if (GET_MODE_PRECISION (int_mode) > isize)
    1200          187 :                 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
    1201          128 :               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      1602669 :       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      2265282 :     case TRUNCATE:
    1234              :       /* Don't optimize (lshiftrt (mult ...)) as it would interfere
    1235              :          with the umulXi3_highpart patterns.  */
    1236      2265282 :       if (GET_CODE (op) == LSHIFTRT
    1237        20045 :           && GET_CODE (XEXP (op, 0)) == MULT)
    1238              :         break;
    1239              : 
    1240      2258112 :       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      2258100 :       if (GET_MODE (op) != VOIDmode)
    1255              :         {
    1256      2258100 :           temp = simplify_truncation (mode, op, GET_MODE (op));
    1257      2258100 :           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      1955178 :       if (known_eq (GET_MODE_NUNITS (mode), 1)
    1264      1955178 :           && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
    1265            0 :               || truncated_to_mode (mode, op)))
    1266              :         {
    1267      1942609 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1268      1942609 :           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        12743 :       if (HWI_COMPUTABLE_MODE_P (mode)
    1277          174 :           && COMPARISON_P (op)
    1278            0 :           && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
    1279        12743 :           && 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        12743 :       if (GET_CODE (op) == MEM
    1289          286 :           && !VECTOR_MODE_P (mode)
    1290          170 :           && !MEM_VOLATILE_P (op)
    1291        12907 :           && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
    1292              :         {
    1293          164 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1294          164 :           if (temp)
    1295              :             return temp;
    1296              :         }
    1297              : 
    1298              :       /* Check for useless truncation.  */
    1299        12743 :       if (GET_MODE (op) == mode)
    1300              :         return op;
    1301              :       break;
    1302              : 
    1303       174484 :     case FLOAT_TRUNCATE:
    1304              :       /* Check for useless truncation.  */
    1305       174484 :       if (GET_MODE (op) == mode)
    1306              :         return op;
    1307              : 
    1308       174484 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1309              :         break;
    1310              : 
    1311              :       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
    1312       174330 :       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       174328 :       if ((GET_CODE (op) == FLOAT_TRUNCATE
    1326          145 :            && flag_unsafe_math_optimizations)
    1327       174324 :           || 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       174321 :       if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1336       174321 :           && (flag_unsafe_math_optimizations
    1337         1413 :               || exact_int_to_float_conversion_p (op)))
    1338         1412 :         return simplify_gen_unary (GET_CODE (op), mode,
    1339              :                                    XEXP (op, 0),
    1340         1412 :                                    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       172909 :       if ((GET_CODE (op) == ABS
    1345       172909 :            || 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       172881 :       if (GET_CODE (op) == SUBREG
    1354          307 :           && subreg_lowpart_p (op)
    1355       173185 :           && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
    1356              :         return SUBREG_REG (op);
    1357              :       break;
    1358              : 
    1359       600785 :     case FLOAT_EXTEND:
    1360              :       /* Check for useless extension.  */
    1361       600785 :       if (GET_MODE (op) == mode)
    1362              :         return op;
    1363              : 
    1364       600785 :       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       600682 :       if (GET_CODE (op) == FLOAT_EXTEND
    1373       600682 :           || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1374         1384 :               && exact_int_to_float_conversion_p (op)))
    1375          551 :         return simplify_gen_unary (GET_CODE (op), mode,
    1376              :                                    XEXP (op, 0),
    1377          551 :                                    GET_MODE (XEXP (op, 0)));
    1378              : 
    1379              :       break;
    1380              : 
    1381       332497 :     case ABS:
    1382              :       /* (abs (neg <foo>)) -> (abs <foo>) */
    1383       332497 :       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       332479 :       if (GET_MODE (op) == VOIDmode)
    1390              :         break;
    1391              : 
    1392              :       /* If operand is something known to be positive, ignore the ABS.  */
    1393       332479 :       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       332333 :       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       332333 :               && 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       332333 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    1424        55220 :           && (num_sign_bit_copies (op, int_mode)
    1425        55220 :               == GET_MODE_PRECISION (int_mode)))
    1426           14 :         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        31296 :     case BSWAP:
    1505              :       /* (bswap (bswap x)) -> x.  */
    1506        31296 :       if (GET_CODE (op) == BSWAP)
    1507          184 :         return XEXP (op, 0);
    1508              :       /* Canonicalize (bswap (bitreverse x)) as (bitreverse (bswap x)).  */
    1509        31112 :       if (GET_CODE (op) == BITREVERSE)
    1510            0 :         return simplify_gen_unary (BITREVERSE, mode,
    1511              :                                    simplify_gen_unary (BSWAP, mode,
    1512              :                                                        XEXP (op, 0), mode),
    1513            0 :                                    mode);
    1514              :       break;
    1515              : 
    1516            0 :     case BITREVERSE:
    1517              :       /* (bitreverse (bitreverse x)) -> x.  */
    1518            0 :       if (GET_CODE (op) == BITREVERSE)
    1519            0 :         return XEXP (op, 0);
    1520              :       break;
    1521              : 
    1522       957007 :     case FLOAT:
    1523              :       /* (float (sign_extend <X>)) = (float <X>).  */
    1524       957007 :       if (GET_CODE (op) == SIGN_EXTEND)
    1525         9666 :         return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
    1526         9666 :                                    GET_MODE (XEXP (op, 0)));
    1527              :       break;
    1528              : 
    1529      3123829 :     case SIGN_EXTEND:
    1530              :       /* Check for useless extension.  */
    1531      3123829 :       if (GET_MODE (op) == mode)
    1532              :         return op;
    1533              : 
    1534              :       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
    1535              :          becomes just the MINUS if its mode is MODE.  This allows
    1536              :          folding switch statements on machines using casesi (such as
    1537              :          the VAX).  */
    1538      3123789 :       if (GET_CODE (op) == TRUNCATE
    1539           62 :           && GET_MODE (XEXP (op, 0)) == mode
    1540           62 :           && GET_CODE (XEXP (op, 0)) == MINUS
    1541            0 :           && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
    1542            0 :           && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
    1543              :         return XEXP (op, 0);
    1544              : 
    1545              :       /* Extending a widening multiplication should be canonicalized to
    1546              :          a wider widening multiplication.  */
    1547      3123789 :       if (GET_CODE (op) == MULT)
    1548              :         {
    1549        67558 :           rtx lhs = XEXP (op, 0);
    1550        67558 :           rtx rhs = XEXP (op, 1);
    1551        67558 :           enum rtx_code lcode = GET_CODE (lhs);
    1552        67558 :           enum rtx_code rcode = GET_CODE (rhs);
    1553              : 
    1554              :           /* Widening multiplies usually extend both operands, but sometimes
    1555              :              they use a shift to extract a portion of a register.  */
    1556        67558 :           if ((lcode == SIGN_EXTEND
    1557        67429 :                || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1558          888 :               && (rcode == SIGN_EXTEND
    1559          868 :                   || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1560              :             {
    1561          105 :               machine_mode lmode = GET_MODE (lhs);
    1562          105 :               machine_mode rmode = GET_MODE (rhs);
    1563          105 :               int bits;
    1564              : 
    1565          105 :               if (lcode == ASHIFTRT)
    1566              :                 /* Number of bits not shifted off the end.  */
    1567           89 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1568           89 :                         - INTVAL (XEXP (lhs, 1)));
    1569              :               else /* lcode == SIGN_EXTEND */
    1570              :                 /* Size of inner mode.  */
    1571           32 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1572              : 
    1573          105 :               if (rcode == ASHIFTRT)
    1574           85 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1575           85 :                          - INTVAL (XEXP (rhs, 1)));
    1576              :               else /* rcode == SIGN_EXTEND */
    1577           40 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1578              : 
    1579              :               /* We can only widen multiplies if the result is mathematiclly
    1580              :                  equivalent.  I.e. if overflow was impossible.  */
    1581          210 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1582           48 :                 return simplify_gen_binary
    1583           48 :                          (MULT, mode,
    1584              :                           simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
    1585           48 :                           simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
    1586              :             }
    1587              :         }
    1588              : 
    1589              :       /* Check for a sign extension of a subreg of a promoted
    1590              :          variable, where the promotion is sign-extended, and the
    1591              :          target mode is the same as the variable's promotion.  */
    1592      3123741 :       if (GET_CODE (op) == SUBREG
    1593       214195 :           && SUBREG_PROMOTED_VAR_P (op)
    1594      3128882 :           && SUBREG_PROMOTED_SIGNED_P (op))
    1595              :         {
    1596            0 :           rtx subreg = SUBREG_REG (op);
    1597            0 :           machine_mode subreg_mode = GET_MODE (subreg);
    1598            0 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1599              :             {
    1600            0 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1601            0 :               if (temp)
    1602              :                 {
    1603              :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1604            0 :                   if (partial_subreg_p (temp))
    1605              :                     {
    1606            0 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1607            0 :                       SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
    1608              :                     }
    1609              :                   return temp;
    1610              :                 }
    1611              :             }
    1612              :           else
    1613              :             /* Sign-extending a sign-extended subreg.  */
    1614            0 :             return simplify_gen_unary (SIGN_EXTEND, mode,
    1615            0 :                                        subreg, subreg_mode);
    1616              :         }
    1617              : 
    1618              :       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
    1619              :          (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1620      3123741 :       if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
    1621              :         {
    1622        20034 :           gcc_assert (GET_MODE_UNIT_PRECISION (mode)
    1623              :                       > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
    1624         6678 :           return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
    1625         6678 :                                      GET_MODE (XEXP (op, 0)));
    1626              :         }
    1627              : 
    1628              :       /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1629              :          is (sign_extend:M (subreg:O <X>)) if there is mode with
    1630              :          GET_MODE_BITSIZE (N) - I bits.
    1631              :          (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1632              :          is similarly (zero_extend:M (subreg:O <X>)).  */
    1633      3117063 :       if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
    1634        90203 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1635      3119685 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1636         5241 :           && CONST_INT_P (XEXP (op, 1))
    1637         5241 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1638      3122175 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1639         5112 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1640              :         {
    1641         5112 :           scalar_int_mode tmode;
    1642         5112 :           gcc_assert (GET_MODE_PRECISION (int_mode)
    1643              :                       > GET_MODE_PRECISION (op_mode));
    1644         5112 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1645         7605 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1646              :             {
    1647         2619 :               rtx inner =
    1648         2619 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1649         2619 :               if (inner)
    1650         2619 :                 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
    1651              :                                            ? SIGN_EXTEND : ZERO_EXTEND,
    1652         2619 :                                            int_mode, inner, tmode);
    1653              :             }
    1654              :         }
    1655              : 
    1656              :       /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
    1657              :          (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0.  */
    1658      3114444 :       if (GET_CODE (op) == LSHIFTRT
    1659          167 :           && CONST_INT_P (XEXP (op, 1))
    1660          167 :           && XEXP (op, 1) != const0_rtx)
    1661          167 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1662              : 
    1663              :       /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
    1664              :          I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
    1665              :          (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
    1666              :          (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
    1667              :          O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
    1668              :          wider than O.  */
    1669      3114277 :       if (GET_CODE (op) == TRUNCATE
    1670           62 :           && GET_CODE (XEXP (op, 0)) == LSHIFTRT
    1671            0 :           && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
    1672              :         {
    1673            0 :           scalar_int_mode m_mode, n_mode, o_mode;
    1674            0 :           rtx old_shift = XEXP (op, 0);
    1675            0 :           if (is_a <scalar_int_mode> (mode, &m_mode)
    1676            0 :               && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
    1677            0 :               && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
    1678            0 :               && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
    1679            0 :                  == INTVAL (XEXP (old_shift, 1)))
    1680              :             {
    1681            0 :               rtx new_shift = simplify_gen_binary (ASHIFTRT,
    1682              :                                                    GET_MODE (old_shift),
    1683              :                                                    XEXP (old_shift, 0),
    1684              :                                                    XEXP (old_shift, 1));
    1685            0 :               if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
    1686            0 :                 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
    1687            0 :                                            GET_MODE (new_shift));
    1688            0 :               if (mode != GET_MODE (new_shift))
    1689            0 :                 return simplify_gen_unary (TRUNCATE, mode, new_shift,
    1690            0 :                                            GET_MODE (new_shift));
    1691              :               return new_shift;
    1692              :             }
    1693              :         }
    1694              : 
    1695              :       /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
    1696              :          we know the sign bit of OP must be clear.  */
    1697      3114277 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1698      3114277 :                                      nonzero_bits (op, GET_MODE (op))))
    1699        39596 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1700              : 
    1701              :       /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1702      3074681 :       if (GET_CODE (op) == SUBREG
    1703       213911 :           && subreg_lowpart_p (op)
    1704       213799 :           && GET_MODE (SUBREG_REG (op)) == mode
    1705      3257015 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1706       189112 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1707       189112 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1708       187319 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1709      3262000 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1710       187319 :               & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
    1711         6778 :         return SUBREG_REG (op);
    1712              : 
    1713              : #if defined(POINTERS_EXTEND_UNSIGNED)
    1714              :       /* As we do not know which address space the pointer is referring to,
    1715              :          we can do this only if the target does not support different pointer
    1716              :          or address modes depending on the address space.  */
    1717      3067903 :       if (target_default_pointer_address_modes_p ()
    1718              :           && ! POINTERS_EXTEND_UNSIGNED
    1719              :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1720              :           && (CONSTANT_P (op)
    1721              :               || (GET_CODE (op) == SUBREG
    1722              :                   && REG_P (SUBREG_REG (op))
    1723              :                   && REG_POINTER (SUBREG_REG (op))
    1724              :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1725              :           && !targetm.have_ptr_extend ())
    1726              :         {
    1727              :           temp
    1728              :             = convert_memory_address_addr_space_1 (Pmode, op,
    1729              :                                                    ADDR_SPACE_GENERIC, false,
    1730              :                                                    true);
    1731              :           if (temp)
    1732              :             return temp;
    1733              :         }
    1734              : #endif
    1735              :       break;
    1736              : 
    1737     11751895 :     case ZERO_EXTEND:
    1738              :       /* Check for useless extension.  */
    1739     11751895 :       if (GET_MODE (op) == mode)
    1740              :         return op;
    1741              : 
    1742              :       /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
    1743              :          where const does not sign bit set. */
    1744     11751853 :       if (GET_CODE (op) == AND
    1745       122106 :           && CONST_INT_P (XEXP (op, 1))
    1746        93515 :           && INTVAL (XEXP (op, 1)) > 0)
    1747              :         {
    1748        85485 :           rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
    1749        85485 :           if (tem)
    1750        69166 :             return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
    1751              :         }
    1752              : 
    1753              :       /* Check for a zero extension of a subreg of a promoted
    1754              :          variable, where the promotion is zero-extended, and the
    1755              :          target mode is the same as the variable's promotion.  */
    1756     11682687 :       if (GET_CODE (op) == SUBREG
    1757      1696663 :           && SUBREG_PROMOTED_VAR_P (op)
    1758     11683112 :           && SUBREG_PROMOTED_UNSIGNED_P (op))
    1759              :         {
    1760          425 :           rtx subreg = SUBREG_REG (op);
    1761          425 :           machine_mode subreg_mode = GET_MODE (subreg);
    1762          425 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1763              :             {
    1764          271 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1765          271 :               if (temp)
    1766              :                 {
    1767              :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1768          271 :                   if (partial_subreg_p (temp))
    1769              :                     {
    1770          129 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1771          129 :                       SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
    1772              :                     }
    1773              :                   return temp;
    1774              :                 }
    1775              :             }
    1776              :           else
    1777              :             /* Zero-extending a zero-extended subreg.  */
    1778          154 :             return simplify_gen_unary (ZERO_EXTEND, mode,
    1779          154 :                                        subreg, subreg_mode);
    1780              :         }
    1781              : 
    1782              :       /* Extending a widening multiplication should be canonicalized to
    1783              :          a wider widening multiplication.  */
    1784     11682262 :       if (GET_CODE (op) == MULT)
    1785              :         {
    1786       185134 :           rtx lhs = XEXP (op, 0);
    1787       185134 :           rtx rhs = XEXP (op, 1);
    1788       185134 :           enum rtx_code lcode = GET_CODE (lhs);
    1789       185134 :           enum rtx_code rcode = GET_CODE (rhs);
    1790              : 
    1791              :           /* Widening multiplies usually extend both operands, but sometimes
    1792              :              they use a shift to extract a portion of a register.  */
    1793       185134 :           if ((lcode == ZERO_EXTEND
    1794       184499 :                || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1795          833 :               && (rcode == ZERO_EXTEND
    1796          783 :                   || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1797              :             {
    1798           62 :               machine_mode lmode = GET_MODE (lhs);
    1799           62 :               machine_mode rmode = GET_MODE (rhs);
    1800           62 :               int bits;
    1801              : 
    1802           62 :               if (lcode == LSHIFTRT)
    1803              :                 /* Number of bits not shifted off the end.  */
    1804           12 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1805           12 :                         - INTVAL (XEXP (lhs, 1)));
    1806              :               else /* lcode == ZERO_EXTEND */
    1807              :                 /* Size of inner mode.  */
    1808          100 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1809              : 
    1810           62 :               if (rcode == LSHIFTRT)
    1811           12 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1812           12 :                          - INTVAL (XEXP (rhs, 1)));
    1813              :               else /* rcode == ZERO_EXTEND */
    1814          100 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1815              : 
    1816              :               /* We can only widen multiplies if the result is mathematiclly
    1817              :                  equivalent.  I.e. if overflow was impossible.  */
    1818          124 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1819           50 :                 return simplify_gen_binary
    1820           50 :                          (MULT, mode,
    1821              :                           simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
    1822           50 :                           simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
    1823              :             }
    1824              :         }
    1825              : 
    1826              :       /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1827     11682212 :       if (GET_CODE (op) == ZERO_EXTEND)
    1828        22370 :         return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
    1829        22370 :                                    GET_MODE (XEXP (op, 0)));
    1830              : 
    1831              :       /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1832              :          is (zero_extend:M (subreg:O <X>)) if there is mode with
    1833              :          GET_MODE_PRECISION (N) - I bits.  */
    1834     11659842 :       if (GET_CODE (op) == LSHIFTRT
    1835        52124 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1836     11659860 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1837           18 :           && CONST_INT_P (XEXP (op, 1))
    1838           13 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1839     11659842 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1840            0 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1841              :         {
    1842            0 :           scalar_int_mode tmode;
    1843            0 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1844            0 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1845              :             {
    1846            0 :               rtx inner =
    1847            0 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1848            0 :               if (inner)
    1849            0 :                 return simplify_gen_unary (ZERO_EXTEND, int_mode,
    1850            0 :                                            inner, tmode);
    1851              :             }
    1852              :         }
    1853              : 
    1854              :       /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
    1855              :          (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
    1856              :          of mode N.  E.g.
    1857              :          (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
    1858              :          (and:SI (reg:SI) (const_int 63)).  */
    1859     11659842 :       if (partial_subreg_p (op)
    1860     13281137 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1861      1643210 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
    1862      1642499 :           && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
    1863      1314991 :           && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
    1864      1293307 :           && subreg_lowpart_p (op)
    1865      2546697 :           && (nonzero_bits (SUBREG_REG (op), op0_mode)
    1866       850459 :               & ~GET_MODE_MASK (GET_MODE (op))) == 0)
    1867              :         {
    1868        21915 :           if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
    1869        14802 :             return SUBREG_REG (op);
    1870         7113 :           return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
    1871         7113 :                                      op0_mode);
    1872              :         }
    1873              : 
    1874              :       /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1875     11637927 :       if (GET_CODE (op) == SUBREG
    1876      1674323 :           && subreg_lowpart_p (op)
    1877       968606 :           && GET_MODE (SUBREG_REG (op)) == mode
    1878     12459298 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1879       821371 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1880       821371 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1881       757834 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1882     12395761 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1883       757834 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1884            0 :         return SUBREG_REG (op);
    1885              : 
    1886              :       /* Trying to optimize:
    1887              :          (zero_extend:M (subreg:N (not:M (X:M)))) ->
    1888              :          (xor:M (zero_extend:M (subreg:N (X:M)), mask))
    1889              :          where the mask is GET_MODE_MASK (N).
    1890              :          For the cases when X:M doesn't have any non-zero bits
    1891              :          outside of mode N, (zero_extend:M (subreg:N (X:M))
    1892              :          will be simplified to just (X:M)
    1893              :          and whole optimization will be -> (xor:M (X:M, mask)).  */
    1894     11637927 :       if (partial_subreg_p (op)
    1895      1621295 :           && GET_CODE (XEXP (op, 0)) == NOT
    1896         1417 :           && GET_MODE (XEXP (op, 0)) == mode
    1897         1399 :           && subreg_lowpart_p (op)
    1898     11638278 :           && HWI_COMPUTABLE_MODE_P (mode)
    1899          352 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1900      1674675 :           && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
    1901          352 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1902              :       {
    1903            1 :         unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
    1904            2 :         return simplify_gen_binary (XOR, mode,
    1905            1 :                                     XEXP (XEXP (op, 0), 0),
    1906            1 :                                     gen_int_mode (mask, mode));
    1907              :       }
    1908              : 
    1909              : #if defined(POINTERS_EXTEND_UNSIGNED)
    1910              :       /* As we do not know which address space the pointer is referring to,
    1911              :          we can do this only if the target does not support different pointer
    1912              :          or address modes depending on the address space.  */
    1913     11637926 :       if (target_default_pointer_address_modes_p ()
    1914              :           && POINTERS_EXTEND_UNSIGNED > 0
    1915     13267383 :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1916          977 :           && (CONSTANT_P (op)
    1917          956 :               || (GET_CODE (op) == SUBREG
    1918            0 :                   && REG_P (SUBREG_REG (op))
    1919            0 :                   && REG_POINTER (SUBREG_REG (op))
    1920            0 :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1921     11637947 :           && !targetm.have_ptr_extend ())
    1922              :         {
    1923           21 :           temp
    1924           21 :             = convert_memory_address_addr_space_1 (Pmode, op,
    1925              :                                                    ADDR_SPACE_GENERIC, false,
    1926              :                                                    true);
    1927           21 :           if (temp)
    1928              :             return temp;
    1929              :         }
    1930              : #endif
    1931              :       break;
    1932              : 
    1933       791085 :     case VEC_DUPLICATE:
    1934       791085 :       if (GET_CODE (op) == VEC_DUPLICATE)
    1935            2 :         return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
    1936            2 :                                    GET_MODE (XEXP (op, 0)));
    1937              :       break;
    1938              : 
    1939              :     default:
    1940              :       break;
    1941              :     }
    1942              : 
    1943     19980804 :   if (VECTOR_MODE_P (mode)
    1944      1913746 :       && vec_duplicate_p (op, &elt)
    1945     21900560 :       && code != VEC_DUPLICATE)
    1946              :     {
    1947         6010 :       if (code == SIGN_EXTEND || code == ZERO_EXTEND)
    1948              :         /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
    1949              :            operations by promoting VEC_DUPLICATE to the root of the expression
    1950              :            (as far as possible).  */
    1951         4953 :         temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
    1952         9906 :                                    elt, GET_MODE_INNER (GET_MODE (op)));
    1953              :       else
    1954              :         /* Try applying the operator to ELT and see if that simplifies.
    1955              :            We can duplicate the result if so.
    1956              : 
    1957              :            The reason we traditionally haven't used simplify_gen_unary
    1958              :            for these codes is that it didn't necessarily seem to be a
    1959              :            win to convert things like:
    1960              : 
    1961              :              (neg:V (vec_duplicate:V (reg:S R)))
    1962              : 
    1963              :            to:
    1964              : 
    1965              :              (vec_duplicate:V (neg:S (reg:S R)))
    1966              : 
    1967              :            The first might be done entirely in vector registers while the
    1968              :            second might need a move between register files.
    1969              : 
    1970              :            However, there also cases where promoting the vec_duplicate is
    1971              :            more efficient, and there is definite value in having a canonical
    1972              :            form when matching instruction patterns.  We should consider
    1973              :            extending the simplify_gen_unary code above to more cases.  */
    1974         1057 :         temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
    1975         2114 :                                          elt, GET_MODE_INNER (GET_MODE (op)));
    1976         6010 :       if (temp)
    1977         5539 :         return gen_vec_duplicate (mode, temp);
    1978              :     }
    1979              : 
    1980              :   return 0;
    1981              : }
    1982              : 
    1983              : /* Try to compute the value of a unary operation CODE whose output mode is to
    1984              :    be MODE with input operand OP whose mode was originally OP_MODE.
    1985              :    Return zero if the value cannot be computed.  */
    1986              : rtx
    1987     30125492 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
    1988              :                                 rtx op, machine_mode op_mode)
    1989              : {
    1990     30125492 :   scalar_int_mode result_mode;
    1991              : 
    1992     30125492 :   if (code == VEC_DUPLICATE)
    1993              :     {
    1994      1963293 :       gcc_assert (VECTOR_MODE_P (mode));
    1995      1963293 :       if (GET_MODE (op) != VOIDmode)
    1996              :       {
    1997       832422 :         if (!VECTOR_MODE_P (GET_MODE (op)))
    1998      1651466 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
    1999              :         else
    2000        20067 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
    2001              :                                                 (GET_MODE (op)));
    2002              :       }
    2003      1963293 :       if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
    2004      1171452 :         return gen_const_vec_duplicate (mode, op);
    2005       791841 :       if (GET_CODE (op) == CONST_VECTOR
    2006       791841 :           && (CONST_VECTOR_DUPLICATE_P (op)
    2007          756 :               || CONST_VECTOR_NUNITS (op).is_constant ()))
    2008              :         {
    2009          756 :           unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
    2010          756 :                                     ? CONST_VECTOR_NPATTERNS (op)
    2011         1510 :                                     : CONST_VECTOR_NUNITS (op).to_constant ());
    2012         2268 :           gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
    2013          756 :           rtx_vector_builder builder (mode, npatterns, 1);
    2014         3888 :           for (unsigned i = 0; i < npatterns; i++)
    2015         2376 :             builder.quick_push (CONST_VECTOR_ELT (op, i));
    2016          756 :           return builder.build ();
    2017          756 :         }
    2018              :     }
    2019              : 
    2020     27349307 :   if (VECTOR_MODE_P (mode)
    2021      1970277 :       && GET_CODE (op) == CONST_VECTOR
    2022     29081702 :       && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
    2023              :     {
    2024        42806 :       gcc_assert (GET_MODE (op) == op_mode);
    2025              : 
    2026        42806 :       rtx_vector_builder builder;
    2027        42806 :       if (!builder.new_unary_operation (mode, op, false))
    2028              :         return 0;
    2029              : 
    2030        42806 :       unsigned int count = builder.encoded_nelts ();
    2031       170590 :       for (unsigned int i = 0; i < count; i++)
    2032              :         {
    2033       256606 :           rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
    2034              :                                             CONST_VECTOR_ELT (op, i),
    2035       256606 :                                             GET_MODE_INNER (op_mode));
    2036       128303 :           if (!x || !valid_for_const_vector_p (mode, x))
    2037          519 :             return 0;
    2038       127784 :           builder.quick_push (x);
    2039              :         }
    2040        42287 :       return builder.build ();
    2041        42806 :     }
    2042              : 
    2043              :   /* The order of these tests is critical so that, for example, we don't
    2044              :      check the wrong mode (input vs. output) for a conversion operation,
    2045              :      such as FIX.  At some point, this should be simplified.  */
    2046              : 
    2047     28910478 :   if (code == FLOAT && CONST_SCALAR_INT_P (op))
    2048              :     {
    2049         7973 :       REAL_VALUE_TYPE d;
    2050              : 
    2051         7973 :       if (op_mode == VOIDmode)
    2052              :         {
    2053              :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2054              :              the bits of the constant are significant, though, this is
    2055              :              a dangerous assumption as many times CONST_INTs are
    2056              :              created and used with garbage in the bits outside of the
    2057              :              precision of the implied mode of the const_int.  */
    2058           64 :           op_mode = MAX_MODE_INT;
    2059              :         }
    2060              : 
    2061         7973 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
    2062              : 
    2063              :       /* Avoid the folding if flag_signaling_nans is on and
    2064              :          operand is a signaling NaN.  */
    2065         7973 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2066              :         return 0;
    2067              : 
    2068         7973 :       d = real_value_truncate (mode, d);
    2069              : 
    2070              :       /* Avoid the folding if flag_rounding_math is on and the
    2071              :          conversion is not exact.  */
    2072         7973 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2073              :         {
    2074         1011 :           bool fail = false;
    2075         1011 :           wide_int w = real_to_integer (&d, &fail,
    2076              :                                         GET_MODE_PRECISION
    2077         1011 :                                           (as_a <scalar_int_mode> (op_mode)));
    2078         2022 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2079          905 :             return 0;
    2080         1011 :         }
    2081              : 
    2082         7068 :       return const_double_from_real_value (d, mode);
    2083              :     }
    2084     28902505 :   else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
    2085              :     {
    2086         2134 :       REAL_VALUE_TYPE d;
    2087              : 
    2088         2134 :       if (op_mode == VOIDmode)
    2089              :         {
    2090              :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2091              :              the bits of the constant are significant, though, this is
    2092              :              a dangerous assumption as many times CONST_INTs are
    2093              :              created and used with garbage in the bits outside of the
    2094              :              precision of the implied mode of the const_int.  */
    2095            8 :           op_mode = MAX_MODE_INT;
    2096              :         }
    2097              : 
    2098         2134 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
    2099              : 
    2100              :       /* Avoid the folding if flag_signaling_nans is on and
    2101              :          operand is a signaling NaN.  */
    2102         2134 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2103              :         return 0;
    2104              : 
    2105         2134 :       d = real_value_truncate (mode, d);
    2106              : 
    2107              :       /* Avoid the folding if flag_rounding_math is on and the
    2108              :          conversion is not exact.  */
    2109         2134 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2110              :         {
    2111           16 :           bool fail = false;
    2112           16 :           wide_int w = real_to_integer (&d, &fail,
    2113              :                                         GET_MODE_PRECISION
    2114           16 :                                           (as_a <scalar_int_mode> (op_mode)));
    2115           28 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2116           16 :             return 0;
    2117           16 :         }
    2118              : 
    2119         2118 :       return const_double_from_real_value (d, mode);
    2120              :     }
    2121              : 
    2122     28900371 :   if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
    2123              :     {
    2124      3841163 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2125      3841163 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2126              :         return 0;
    2127              : 
    2128      3841163 :       wide_int result;
    2129      3841163 :       scalar_int_mode imode = (op_mode == VOIDmode
    2130      3841163 :                                ? result_mode
    2131      3840882 :                                : as_a <scalar_int_mode> (op_mode));
    2132      3841163 :       rtx_mode_t op0 = rtx_mode_t (op, imode);
    2133      3841163 :       int int_value;
    2134              : 
    2135              : #if TARGET_SUPPORTS_WIDE_INT == 0
    2136              :       /* This assert keeps the simplification from producing a result
    2137              :          that cannot be represented in a CONST_DOUBLE but a lot of
    2138              :          upstream callers expect that this function never fails to
    2139              :          simplify something and so you if you added this to the test
    2140              :          above the code would die later anyway.  If this assert
    2141              :          happens, you just need to make the port support wide int.  */
    2142              :       gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
    2143              : #endif
    2144              : 
    2145      3841163 :       switch (code)
    2146              :         {
    2147       173346 :         case NOT:
    2148       173346 :           result = wi::bit_not (op0);
    2149       173346 :           break;
    2150              : 
    2151      1871821 :         case NEG:
    2152      1871821 :           result = wi::neg (op0);
    2153      1871821 :           break;
    2154              : 
    2155         7111 :         case ABS:
    2156         7111 :           result = wi::abs (op0);
    2157         7111 :           break;
    2158              : 
    2159            0 :         case FFS:
    2160            0 :           result = wi::shwi (wi::ffs (op0), result_mode);
    2161            0 :           break;
    2162              : 
    2163          168 :         case CLZ:
    2164          168 :           if (wi::ne_p (op0, 0))
    2165           38 :             int_value = wi::clz (op0);
    2166          260 :           else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2167              :             return NULL_RTX;
    2168           38 :           result = wi::shwi (int_value, result_mode);
    2169           38 :           break;
    2170              : 
    2171            0 :         case CLRSB:
    2172            0 :           result = wi::shwi (wi::clrsb (op0), result_mode);
    2173            0 :           break;
    2174              : 
    2175            0 :         case CTZ:
    2176            0 :           if (wi::ne_p (op0, 0))
    2177            0 :             int_value = wi::ctz (op0);
    2178            0 :           else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2179              :             return NULL_RTX;
    2180            0 :           result = wi::shwi (int_value, result_mode);
    2181            0 :           break;
    2182              : 
    2183          160 :         case POPCOUNT:
    2184          160 :           result = wi::shwi (wi::popcount (op0), result_mode);
    2185          160 :           break;
    2186              : 
    2187            0 :         case PARITY:
    2188            0 :           result = wi::shwi (wi::parity (op0), result_mode);
    2189            0 :           break;
    2190              : 
    2191         1734 :         case BSWAP:
    2192         1734 :           result = wi::bswap (op0);
    2193         1734 :           break;
    2194              : 
    2195            0 :         case BITREVERSE:
    2196            0 :           result = wi::bitreverse (op0);
    2197            0 :           break;
    2198              : 
    2199      1607155 :         case TRUNCATE:
    2200      1607155 :         case ZERO_EXTEND:
    2201      1607155 :           result = wide_int::from (op0, width, UNSIGNED);
    2202      1607155 :           break;
    2203              : 
    2204        14450 :         case US_TRUNCATE:
    2205        14450 :         case SS_TRUNCATE:
    2206        14450 :           {
    2207        14450 :             signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
    2208        14450 :             wide_int nmax
    2209        14450 :               = wide_int::from (wi::max_value (width, sgn),
    2210        28900 :                                 GET_MODE_PRECISION (imode), sgn);
    2211        14450 :             wide_int nmin
    2212        14450 :               = wide_int::from (wi::min_value (width, sgn),
    2213        28900 :                                 GET_MODE_PRECISION (imode), sgn);
    2214        14450 :             result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
    2215        14450 :             result = wide_int::from (result, width, sgn);
    2216        14450 :             break;
    2217        14450 :           }
    2218       165218 :         case SIGN_EXTEND:
    2219       165218 :           result = wide_int::from (op0, width, SIGNED);
    2220       165218 :           break;
    2221              : 
    2222            0 :         case SS_NEG:
    2223            0 :           if (wi::only_sign_bit_p (op0))
    2224            0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2225              :           else
    2226            0 :             result = wi::neg (op0);
    2227              :           break;
    2228              : 
    2229            0 :         case SS_ABS:
    2230            0 :           if (wi::only_sign_bit_p (op0))
    2231            0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2232              :           else
    2233            0 :             result = wi::abs (op0);
    2234              :           break;
    2235              : 
    2236              :         case SQRT:
    2237              :         default:
    2238              :           return 0;
    2239              :         }
    2240              : 
    2241      3841033 :       return immed_wide_int_const (result, result_mode);
    2242      3841163 :     }
    2243              : 
    2244     25059208 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2245       414014 :            && SCALAR_FLOAT_MODE_P (mode)
    2246       411964 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
    2247              :     {
    2248       411964 :       REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
    2249       411964 :       switch (code)
    2250              :         {
    2251              :         case SQRT:
    2252              :           return 0;
    2253          838 :         case ABS:
    2254          838 :           d = real_value_abs (&d);
    2255          838 :           break;
    2256        15847 :         case NEG:
    2257        15847 :           d = real_value_negate (&d);
    2258        15847 :           break;
    2259         2284 :         case FLOAT_TRUNCATE:
    2260              :           /* Don't perform the operation if flag_signaling_nans is on
    2261              :              and the operand is a signaling NaN.  */
    2262         2284 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2263              :             return NULL_RTX;
    2264              :           /* Or if flag_rounding_math is on and the truncation is not
    2265              :              exact.  */
    2266         2284 :           if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    2267         2284 :               && !exact_real_truncate (mode, &d))
    2268          231 :             return NULL_RTX;
    2269         2053 :           d = real_value_truncate (mode, d);
    2270         2053 :           break;
    2271       386352 :         case FLOAT_EXTEND:
    2272              :           /* Don't perform the operation if flag_signaling_nans is on
    2273              :              and the operand is a signaling NaN.  */
    2274       386352 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2275              :             return NULL_RTX;
    2276              :           /* All this does is change the mode, unless changing
    2277              :              mode class.  */
    2278       386350 :           if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
    2279            0 :             real_convert (&d, mode, &d);
    2280              :           break;
    2281            0 :         case FIX:
    2282              :           /* Don't perform the operation if flag_signaling_nans is on
    2283              :              and the operand is a signaling NaN.  */
    2284            0 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2285              :             return NULL_RTX;
    2286            0 :           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
    2287            0 :           break;
    2288         6034 :         case NOT:
    2289         6034 :           {
    2290         6034 :             long tmp[4];
    2291         6034 :             int i;
    2292              : 
    2293         6034 :             real_to_target (tmp, &d, GET_MODE (op));
    2294        30170 :             for (i = 0; i < 4; i++)
    2295        24136 :               tmp[i] = ~tmp[i];
    2296         6034 :             real_from_target (&d, tmp, mode);
    2297         6034 :             break;
    2298              :           }
    2299            0 :         default:
    2300            0 :           gcc_unreachable ();
    2301              :         }
    2302       411122 :       return const_double_from_real_value (d, mode);
    2303              :     }
    2304         2050 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2305         2050 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op))
    2306     24649294 :            && is_int_mode (mode, &result_mode))
    2307              :     {
    2308         2050 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2309         2050 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2310              :         return 0;
    2311              : 
    2312              :       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
    2313              :          operators are intentionally left unspecified (to ease implementation
    2314              :          by target backends), for consistency, this routine implements the
    2315              :          same semantics for constant folding as used by the middle-end.  */
    2316              : 
    2317              :       /* This was formerly used only for non-IEEE float.
    2318              :          eggert@twinsun.com says it is safe for IEEE also.  */
    2319         2050 :       REAL_VALUE_TYPE t;
    2320         2050 :       const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
    2321         2050 :       wide_int wmax, wmin;
    2322              :       /* This is part of the abi to real_to_integer, but we check
    2323              :          things before making this call.  */
    2324         2050 :       bool fail;
    2325              : 
    2326         2050 :       switch (code)
    2327              :         {
    2328         2042 :         case FIX:
    2329              :           /* According to IEEE standard, for conversions from floating point to
    2330              :              integer. When a NaN or infinite operand cannot be represented in
    2331              :              the destination format and this cannot otherwise be indicated, the
    2332              :              invalid operation exception shall be signaled. When a numeric
    2333              :              operand would convert to an integer outside the range of the
    2334              :              destination format, the invalid operation exception shall be
    2335              :              signaled if this situation cannot otherwise be indicated.  */
    2336         2042 :           if (REAL_VALUE_ISNAN (*x))
    2337          955 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2338              : 
    2339         1087 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2340              :             return NULL_RTX;
    2341              : 
    2342              :           /* Test against the signed upper bound.  */
    2343          127 :           wmax = wi::max_value (width, SIGNED);
    2344          127 :           real_from_integer (&t, VOIDmode, wmax, SIGNED);
    2345          127 :           if (real_less (&t, x))
    2346            3 :             return (flag_trapping_math
    2347            3 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2348              : 
    2349              :           /* Test against the signed lower bound.  */
    2350          124 :           wmin = wi::min_value (width, SIGNED);
    2351          124 :           real_from_integer (&t, VOIDmode, wmin, SIGNED);
    2352          124 :           if (real_less (x, &t))
    2353            8 :             return immed_wide_int_const (wmin, mode);
    2354              : 
    2355          116 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2356              :                                        mode);
    2357              : 
    2358            8 :         case UNSIGNED_FIX:
    2359            8 :           if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
    2360            6 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2361              : 
    2362            2 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2363              :             return NULL_RTX;
    2364              : 
    2365              :           /* Test against the unsigned upper bound.  */
    2366            0 :           wmax = wi::max_value (width, UNSIGNED);
    2367            0 :           real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
    2368            0 :           if (real_less (&t, x))
    2369            0 :             return (flag_trapping_math
    2370            0 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2371              : 
    2372            0 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2373              :                                        mode);
    2374              : 
    2375            0 :         default:
    2376            0 :           gcc_unreachable ();
    2377              :         }
    2378         2050 :     }
    2379              : 
    2380              :   /* Handle polynomial integers.  */
    2381              :   else if (CONST_POLY_INT_P (op))
    2382              :     {
    2383              :       poly_wide_int result;
    2384              :       switch (code)
    2385              :         {
    2386              :         case NEG:
    2387              :           result = -const_poly_int_value (op);
    2388              :           break;
    2389              : 
    2390              :         case NOT:
    2391              :           result = ~const_poly_int_value (op);
    2392              :           break;
    2393              : 
    2394              :         default:
    2395              :           return NULL_RTX;
    2396              :         }
    2397              :       return immed_wide_int_const (result, mode);
    2398              :     }
    2399              : 
    2400              :   return NULL_RTX;
    2401              : }
    2402              : 
    2403              : /* Subroutine of simplify_binary_operation to simplify a binary operation
    2404              :    CODE that can commute with byte swapping, with result mode MODE and
    2405              :    operating on OP0 and OP1.  CODE is currently one of AND, IOR or XOR.
    2406              :    Return zero if no simplification or canonicalization is possible.  */
    2407              : 
    2408              : rtx
    2409     37898169 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
    2410              :                                                     machine_mode mode,
    2411              :                                                     rtx op0, rtx op1)
    2412              : {
    2413     37898169 :   rtx tem;
    2414              : 
    2415              :   /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped.  */
    2416     37898169 :   if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
    2417              :     {
    2418          227 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
    2419              :                                  simplify_gen_unary (BSWAP, mode, op1, mode));
    2420          227 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2421              :     }
    2422              : 
    2423              :   /* (op (bswap x) (bswap y)) -> (bswap (op x y)).  */
    2424     37897942 :   if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
    2425              :     {
    2426            0 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
    2427            0 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2428              :     }
    2429              : 
    2430              :   return NULL_RTX;
    2431              : }
    2432              : 
    2433              : /* Subroutine of simplify_binary_operation to simplify a commutative,
    2434              :    associative binary operation CODE with result mode MODE, operating
    2435              :    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
    2436              :    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
    2437              :    canonicalization is possible.  */
    2438              : 
    2439              : rtx
    2440     48908232 : simplify_context::simplify_associative_operation (rtx_code code,
    2441              :                                                   machine_mode mode,
    2442              :                                                   rtx op0, rtx op1)
    2443              : {
    2444     48908232 :   rtx tem;
    2445              : 
    2446              :   /* Normally expressions simplified by simplify-rtx.cc are combined
    2447              :      at most from a few machine instructions and therefore the
    2448              :      expressions should be fairly small.  During var-tracking
    2449              :      we can see arbitrarily large expressions though and reassociating
    2450              :      those can be quadratic, so punt after encountering max_assoc_count
    2451              :      simplify_associative_operation calls during outermost simplify_*
    2452              :      call.  */
    2453     48908232 :   if (++assoc_count >= max_assoc_count)
    2454              :     return NULL_RTX;
    2455              : 
    2456              :   /* Linearize the operator to the left.  */
    2457     48903161 :   if (GET_CODE (op1) == code)
    2458              :     {
    2459              :       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
    2460        18199 :       if (GET_CODE (op0) == code)
    2461              :         {
    2462         5065 :           tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
    2463         5065 :           return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
    2464              :         }
    2465              : 
    2466              :       /* "a op (b op c)" becomes "(b op c) op a".  */
    2467        13134 :       if (! swap_commutative_operands_p (op1, op0))
    2468        13134 :         return simplify_gen_binary (code, mode, op1, op0);
    2469              : 
    2470              :       std::swap (op0, op1);
    2471              :     }
    2472              : 
    2473     48884962 :   if (GET_CODE (op0) == code)
    2474              :     {
    2475              :       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
    2476      1238181 :       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
    2477              :         {
    2478       266043 :           tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
    2479       266043 :           return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2480              :         }
    2481              : 
    2482              :       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
    2483       972138 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
    2484       972138 :       if (tem != 0)
    2485        69917 :         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
    2486              : 
    2487              :       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
    2488       902221 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
    2489       902221 :       if (tem != 0)
    2490        37431 :         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2491              :     }
    2492              : 
    2493              :   return 0;
    2494              : }
    2495              : 
    2496              : /* If COMPARISON can be treated as an unsigned comparison, return a mask
    2497              :    that represents it (8 if it includes <, 4 if it includes > and 2
    2498              :    if it includes ==).  Return 0 otherwise.  */
    2499              : static int
    2500        18610 : unsigned_comparison_to_mask (rtx_code comparison)
    2501              : {
    2502            0 :   switch (comparison)
    2503              :     {
    2504              :     case LTU:
    2505              :       return 8;
    2506              :     case GTU:
    2507              :       return 4;
    2508              :     case EQ:
    2509              :       return 2;
    2510              : 
    2511              :     case LEU:
    2512              :       return 10;
    2513              :     case GEU:
    2514              :       return 6;
    2515              : 
    2516              :     case NE:
    2517              :       return 12;
    2518              : 
    2519              :     default:
    2520              :       return 0;
    2521              :     }
    2522              : }
    2523              : 
    2524              : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
    2525              :    to comparisons.  */
    2526              : static rtx_code
    2527         6577 : mask_to_unsigned_comparison (int mask)
    2528              : {
    2529         6577 :   switch (mask)
    2530              :     {
    2531              :     case 8:
    2532              :       return LTU;
    2533          160 :     case 4:
    2534          160 :       return GTU;
    2535         2562 :     case 2:
    2536         2562 :       return EQ;
    2537              : 
    2538          160 :     case 10:
    2539          160 :       return LEU;
    2540          160 :     case 6:
    2541          160 :       return GEU;
    2542              : 
    2543         3375 :     case 12:
    2544         3375 :       return NE;
    2545              : 
    2546            0 :     default:
    2547            0 :       gcc_unreachable ();
    2548              :     }
    2549              : }
    2550              : 
    2551              : /* Return a mask describing the COMPARISON.  */
    2552              : static int
    2553         2448 : comparison_to_mask (enum rtx_code comparison)
    2554              : {
    2555         2448 :   switch (comparison)
    2556              :     {
    2557              :     case LT:
    2558              :       return 8;
    2559          400 :     case GT:
    2560          400 :       return 4;
    2561          423 :     case EQ:
    2562          423 :       return 2;
    2563           23 :     case UNORDERED:
    2564           23 :       return 1;
    2565              : 
    2566            0 :     case LTGT:
    2567            0 :       return 12;
    2568          400 :     case LE:
    2569          400 :       return 10;
    2570          401 :     case GE:
    2571          401 :       return 6;
    2572            0 :     case UNLT:
    2573            0 :       return 9;
    2574            0 :     case UNGT:
    2575            0 :       return 5;
    2576            0 :     case UNEQ:
    2577            0 :       return 3;
    2578              : 
    2579            0 :     case ORDERED:
    2580            0 :       return 14;
    2581          400 :     case NE:
    2582          400 :       return 13;
    2583            0 :     case UNLE:
    2584            0 :       return 11;
    2585            0 :     case UNGE:
    2586            0 :       return 7;
    2587              : 
    2588            0 :     default:
    2589            0 :       gcc_unreachable ();
    2590              :     }
    2591              : }
    2592              : 
    2593              : /* Return a comparison corresponding to the MASK.  */
    2594              : static enum rtx_code
    2595          984 : mask_to_comparison (int mask)
    2596              : {
    2597          984 :   switch (mask)
    2598              :     {
    2599              :     case 8:
    2600              :       return LT;
    2601              :     case 4:
    2602              :       return GT;
    2603              :     case 2:
    2604              :       return EQ;
    2605              :     case 1:
    2606              :       return UNORDERED;
    2607              : 
    2608              :     case 12:
    2609              :       return LTGT;
    2610              :     case 10:
    2611              :       return LE;
    2612              :     case 6:
    2613              :       return GE;
    2614              :     case 9:
    2615              :       return UNLT;
    2616              :     case 5:
    2617              :       return UNGT;
    2618              :     case 3:
    2619              :       return UNEQ;
    2620              : 
    2621              :     case 14:
    2622              :       return ORDERED;
    2623              :     case 13:
    2624              :       return NE;
    2625              :     case 11:
    2626              :       return UNLE;
    2627              :     case 7:
    2628              :       return UNGE;
    2629              : 
    2630            0 :     default:
    2631            0 :       gcc_unreachable ();
    2632              :     }
    2633              : }
    2634              : 
    2635              : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
    2636              :    false/true value of comparison with MODE where comparison operands
    2637              :    have CMP_MODE.  */
    2638              : 
    2639              : static rtx
    2640       785509 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
    2641              : {
    2642       785509 :   if (SCALAR_FLOAT_MODE_P (mode))
    2643              :     {
    2644          168 :       if (res == const0_rtx)
    2645          164 :         return CONST0_RTX (mode);
    2646              : #ifdef FLOAT_STORE_FLAG_VALUE
    2647              :       REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
    2648              :       return const_double_from_real_value (val, mode);
    2649              : #else
    2650              :       return NULL_RTX;
    2651              : #endif
    2652              :     }
    2653       785341 :   if (VECTOR_MODE_P (mode))
    2654              :     {
    2655          423 :       if (res == const0_rtx)
    2656           82 :         return CONST0_RTX (mode);
    2657              : #ifdef VECTOR_STORE_FLAG_VALUE
    2658          341 :       rtx val = VECTOR_STORE_FLAG_VALUE (mode);
    2659          331 :       if (val == NULL_RTX)
    2660              :         return NULL_RTX;
    2661          331 :       if (val == const1_rtx)
    2662            0 :         return CONST1_RTX (mode);
    2663              : 
    2664          331 :       return gen_const_vec_duplicate (mode, val);
    2665              : #else
    2666              :       return NULL_RTX;
    2667              : #endif
    2668              :     }
    2669              :   /* For vector comparison with scalar int result, it is unknown
    2670              :      if the target means here a comparison into an integral bitmask,
    2671              :      or comparison where all comparisons true mean const_true_rtx
    2672              :      whole result, or where any comparisons true mean const_true_rtx
    2673              :      whole result.  For const0_rtx all the cases are the same.  */
    2674       784918 :   if (VECTOR_MODE_P (cmp_mode)
    2675            0 :       && SCALAR_INT_MODE_P (mode)
    2676            0 :       && res == const_true_rtx)
    2677            0 :     return NULL_RTX;
    2678              : 
    2679              :   return res;
    2680              : }
    2681              : 
    2682              : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
    2683              :    and OP1, in the case where both are relational operations.  Assume that
    2684              :    OP0 is inverted if INVERT0_P is true.
    2685              : 
    2686              :    Return 0 if no such simplification is possible.  */
    2687              : rtx
    2688     13517655 : simplify_context::simplify_logical_relational_operation (rtx_code code,
    2689              :                                                          machine_mode mode,
    2690              :                                                          rtx op0, rtx op1,
    2691              :                                                          bool invert0_p)
    2692              : {
    2693     13517655 :   if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
    2694              :     return 0;
    2695              : 
    2696        21440 :   if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2697         9749 :         && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
    2698              :     return 0;
    2699              : 
    2700         9305 :   if (side_effects_p (op0))
    2701              :     return 0;
    2702              : 
    2703         9305 :   enum rtx_code code0 = GET_CODE (op0);
    2704         9305 :   enum rtx_code code1 = GET_CODE (op1);
    2705         9305 :   machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
    2706         9305 :   if (cmp_mode == VOIDmode)
    2707            0 :     cmp_mode = GET_MODE (XEXP (op0, 1));
    2708              : 
    2709              :   /* Assume at first that the comparisons are on integers, and that the
    2710              :      operands are therefore ordered.  */
    2711         9305 :   int all = 14;
    2712         9305 :   int mask0 = unsigned_comparison_to_mask (code0);
    2713         9305 :   int mask1 = unsigned_comparison_to_mask (code1);
    2714        18610 :   bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
    2715         9305 :                      || IN_RANGE (mask1 & 12, 4, 8));
    2716         1224 :   if (unsigned_p)
    2717              :     {
    2718              :       /* We only reach here when comparing integers.  Reject mixtures of signed
    2719              :          and unsigned comparisons.  */
    2720         8081 :       if (mask0 == 0 || mask1 == 0)
    2721              :         return 0;
    2722              :     }
    2723              :   else
    2724              :     {
    2725              :       /* See whether the operands might be unordered.  Assume that all
    2726              :          results are possible for CC modes, and punt later if we don't get an
    2727              :          always-true or always-false answer.  */
    2728         1224 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
    2729              :         all = 15;
    2730         1224 :       mask0 = comparison_to_mask (code0) & all;
    2731         1224 :       mask1 = comparison_to_mask (code1) & all;
    2732              :     }
    2733              : 
    2734         8025 :   if (invert0_p)
    2735         4522 :     mask0 = mask0 ^ all;
    2736              : 
    2737         8025 :   int mask;
    2738         8025 :   if (code == AND)
    2739          928 :     mask = mask0 & mask1;
    2740         7097 :   else if (code == IOR)
    2741          952 :     mask = mask0 | mask1;
    2742         6145 :   else if (code == XOR)
    2743         6145 :     mask = mask0 ^ mask1;
    2744              :   else
    2745              :     return 0;
    2746              : 
    2747         8025 :   if (mask == all)
    2748          232 :     return relational_result (mode, GET_MODE (op0), const_true_rtx);
    2749              : 
    2750         7793 :   if (mask == 0)
    2751          232 :     return relational_result (mode, GET_MODE (op0), const0_rtx);
    2752              : 
    2753         7561 :   if (unsigned_p)
    2754         6577 :     code = mask_to_unsigned_comparison (mask);
    2755              :   else
    2756              :     {
    2757          984 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    2758              :         return 0;
    2759              : 
    2760          984 :       code = mask_to_comparison (mask);
    2761              :       /* LTGT and NE are arithmetically equivalent for ordered operands,
    2762              :          with NE being the canonical choice.  */
    2763          984 :       if (code == LTGT && all == 14)
    2764          160 :         code = NE;
    2765              :     }
    2766              : 
    2767         7561 :   op0 = XEXP (op1, 0);
    2768         7561 :   op1 = XEXP (op1, 1);
    2769              : 
    2770         7561 :   return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
    2771              : }
    2772              : 
    2773              : /* We are going to IOR together OP0/OP1.  If there is a common term in OP0/OP1
    2774              :    then we may be able to simplify the expression.  We're primarily trying to
    2775              :    simplify down to IOR/XOR expression right now, but there may be other
    2776              :    simplifications we can do in the future.
    2777              : 
    2778              :    Return the simplified expression or NULL_RTX if no simplification was
    2779              :    possible.  */
    2780              : rtx
    2781     27535972 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
    2782              : {
    2783              :   /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
    2784              :      X and C have no bits in common.  */
    2785     27535972 :   if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
    2786       254466 :       && rtx_equal_p (op0, XEXP (op1, 0))
    2787         8336 :       && ((nonzero_bits (op0, GET_MODE (op0))
    2788         8336 :           & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
    2789     27535972 :       && !side_effects_p (op1))
    2790            0 :     return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
    2791              : 
    2792              :   /* (ior (and A C1) (and (not A) C2)) can be converted
    2793              :      into (and (xor A C2) (C1 + C2)) when there are no bits
    2794              :      in common between C1 and C2.  */
    2795     27535972 :   if (GET_CODE (op0) == AND
    2796      4376002 :       && GET_CODE (op1) == AND
    2797       414936 :       && GET_CODE (XEXP (op1, 0)) == NOT
    2798        20188 :       && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
    2799         3620 :       && CONST_INT_P (XEXP (op0, 1))
    2800           90 :       && CONST_INT_P (XEXP (op1, 1))
    2801     27536062 :       && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
    2802              :     {
    2803           90 :       rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
    2804              : 
    2805           90 :       rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
    2806           90 :       if (tem)
    2807              :         {
    2808           90 :           tem = simplify_gen_binary (AND, mode, tem, c);
    2809              : 
    2810           90 :           if (tem)
    2811              :             return tem;
    2812              :         }
    2813              :     }
    2814              : 
    2815              :   /* Another variant seen on some target particularly those with
    2816              :      sub-word operations.
    2817              : 
    2818              :      (ior (and A C1) (plus (and A C2) C2)) can be simplified into
    2819              :      (and (xor (A C2) (C1 + C2).
    2820              : 
    2821              :      Where C2 is the sign bit for A's mode.  So 0x80 for QI,
    2822              :      0x8000 for HI, etc.  In this case we know there is no carry
    2823              :      from the PLUS into relevant bits of the output.  */
    2824     27535882 :   if (GET_CODE (op0) == AND
    2825      4375912 :       && GET_CODE (op1) == PLUS
    2826         8018 :       && GET_CODE (XEXP (op1, 0)) == AND
    2827          330 :       && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
    2828          144 :       && CONST_INT_P (XEXP (op0, 1))
    2829          144 :       && CONST_INT_P (XEXP (op1, 1))
    2830          144 :       && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
    2831          144 :       && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
    2832           36 :       && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
    2833           72 :       && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
    2834           72 :           == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
    2835     27535882 :       && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
    2836              :     {
    2837            0 :       rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
    2838              : 
    2839            0 :       rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
    2840            0 :       if (tem)
    2841              :         {
    2842            0 :           tem = simplify_gen_binary (AND, mode, tem, c);
    2843            0 :           if (tem)
    2844              :             return tem;
    2845              :         }
    2846              :     }
    2847              :   return NULL_RTX;
    2848              : }
    2849              : 
    2850              : 
    2851              : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
    2852              :    and OP1.  Return 0 if no simplification is possible.
    2853              : 
    2854              :    Don't use this for relational operations such as EQ or LT.
    2855              :    Use simplify_relational_operation instead.  */
    2856              : rtx
    2857    496244047 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
    2858              :                                              rtx op0, rtx op1)
    2859              : {
    2860    496244047 :   rtx trueop0, trueop1;
    2861    496244047 :   rtx tem;
    2862              : 
    2863              :   /* Relational operations don't work here.  We must know the mode
    2864              :      of the operands in order to do the comparison correctly.
    2865              :      Assuming a full word can give incorrect results.
    2866              :      Consider comparing 128 with -128 in QImode.  */
    2867    496244047 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
    2868    496244047 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
    2869              : 
    2870              :   /* Make sure the constant is second.  */
    2871    496244047 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    2872    496244047 :       && swap_commutative_operands_p (op0, op1))
    2873              :     std::swap (op0, op1);
    2874              : 
    2875    496244047 :   trueop0 = avoid_constant_pool_reference (op0);
    2876    496244047 :   trueop1 = avoid_constant_pool_reference (op1);
    2877              : 
    2878    496244047 :   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
    2879    496244047 :   if (tem)
    2880              :     return tem;
    2881    465407793 :   tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
    2882              : 
    2883    465407793 :   if (tem)
    2884              :     return tem;
    2885              : 
    2886              :   /* If the above steps did not result in a simplification and op0 or op1
    2887              :      were constant pool references, use the referenced constants directly.  */
    2888    400360600 :   if (trueop0 != op0 || trueop1 != op1)
    2889       585218 :     return simplify_gen_binary (code, mode, trueop0, trueop1);
    2890              : 
    2891              :   return NULL_RTX;
    2892              : }
    2893              : 
    2894              : /* Subroutine of simplify_binary_operation_1 that looks for cases in
    2895              :    which OP0 and OP1 are both vector series or vector duplicates
    2896              :    (which are really just series with a step of 0).  If so, try to
    2897              :    form a new series by applying CODE to the bases and to the steps.
    2898              :    Return null if no simplification is possible.
    2899              : 
    2900              :    MODE is the mode of the operation and is known to be a vector
    2901              :    integer mode.  */
    2902              : 
    2903              : rtx
    2904      2670455 : simplify_context::simplify_binary_operation_series (rtx_code code,
    2905              :                                                     machine_mode mode,
    2906              :                                                     rtx op0, rtx op1)
    2907              : {
    2908      2670455 :   rtx base0, step0;
    2909      2670455 :   if (vec_duplicate_p (op0, &base0))
    2910        77774 :     step0 = const0_rtx;
    2911      2592681 :   else if (!vec_series_p (op0, &base0, &step0))
    2912              :     return NULL_RTX;
    2913              : 
    2914        78518 :   rtx base1, step1;
    2915        78518 :   if (vec_duplicate_p (op1, &base1))
    2916          435 :     step1 = const0_rtx;
    2917        78083 :   else if (!vec_series_p (op1, &base1, &step1))
    2918              :     return NULL_RTX;
    2919              : 
    2920              :   /* Only create a new series if we can simplify both parts.  In other
    2921              :      cases this isn't really a simplification, and it's not necessarily
    2922              :      a win to replace a vector operation with a scalar operation.  */
    2923         5735 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    2924         5735 :   rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
    2925         5735 :   if (!new_base)
    2926              :     return NULL_RTX;
    2927              : 
    2928         4757 :   rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
    2929         4757 :   if (!new_step)
    2930              :     return NULL_RTX;
    2931              : 
    2932         4757 :   return gen_vec_series (mode, new_base, new_step);
    2933              : }
    2934              : 
    2935              : /* Subroutine of simplify_binary_operation_1.  Un-distribute a binary
    2936              :    operation CODE with result mode MODE, operating on OP0 and OP1.
    2937              :    e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
    2938              :    Returns NULL_RTX if no simplification is possible.  */
    2939              : 
    2940              : rtx
    2941      1407709 : simplify_context::simplify_distributive_operation (rtx_code code,
    2942              :                                                    machine_mode mode,
    2943              :                                                    rtx op0, rtx op1)
    2944              : {
    2945      1407709 :   enum rtx_code op = GET_CODE (op0);
    2946      1407709 :   gcc_assert (GET_CODE (op1) == op);
    2947              : 
    2948      1407709 :   if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
    2949      1407709 :       && ! side_effects_p (XEXP (op0, 1)))
    2950       349393 :     return simplify_gen_binary (op, mode,
    2951              :                                 simplify_gen_binary (code, mode,
    2952              :                                                      XEXP (op0, 0),
    2953              :                                                      XEXP (op1, 0)),
    2954       349393 :                                 XEXP (op0, 1));
    2955              : 
    2956      1058316 :   if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
    2957              :     {
    2958      1039784 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2959      1039784 :           && ! side_effects_p (XEXP (op0, 0)))
    2960       516376 :         return simplify_gen_binary (op, mode,
    2961              :                                     simplify_gen_binary (code, mode,
    2962              :                                                          XEXP (op0, 1),
    2963              :                                                          XEXP (op1, 1)),
    2964       516376 :                                     XEXP (op0, 0));
    2965       523408 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
    2966       523408 :           && ! side_effects_p (XEXP (op0, 0)))
    2967           54 :         return simplify_gen_binary (op, mode,
    2968              :                                     simplify_gen_binary (code, mode,
    2969              :                                                          XEXP (op0, 1),
    2970              :                                                          XEXP (op1, 0)),
    2971           54 :                                     XEXP (op0, 0));
    2972       523354 :       if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
    2973       523354 :           && ! side_effects_p (XEXP (op0, 1)))
    2974       263913 :         return simplify_gen_binary (op, mode,
    2975              :                                     simplify_gen_binary (code, mode,
    2976              :                                                          XEXP (op0, 0),
    2977              :                                                          XEXP (op1, 1)),
    2978       263913 :                                     XEXP (op0, 1));
    2979              :     }
    2980              : 
    2981              :   return NULL_RTX;
    2982              : }
    2983              : 
    2984              : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
    2985              :    should be reversed.
    2986              : 
    2987              :    If the rotate should not be reversed, return FALSE.
    2988              : 
    2989              :    LEFT indicates if this is a rotate left or a rotate right.  */
    2990              : 
    2991              : bool
    2992       149596 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
    2993              : {
    2994       149596 :   if (!CONST_INT_P (op1))
    2995              :     return false;
    2996              : 
    2997              :   /* Some targets may only be able to rotate by a constant
    2998              :      in one direction.  So we need to query the optab interface
    2999              :      to see what is possible.  */
    3000       112354 :   optab binoptab = left ? rotl_optab : rotr_optab;
    3001        48306 :   optab re_binoptab = left ? rotr_optab : rotl_optab;
    3002       112354 :   enum insn_code icode = optab_handler (binoptab, mode);
    3003       112354 :   enum insn_code re_icode = optab_handler (re_binoptab, mode);
    3004              : 
    3005              :   /* If the target can not support the reversed optab, then there
    3006              :      is nothing to do.  */
    3007       112354 :   if (re_icode == CODE_FOR_nothing)
    3008              :     return false;
    3009              : 
    3010              :   /* If the target does not support the requested rotate-by-immediate,
    3011              :      then we want to try reversing the rotate.  We also want to try
    3012              :      reversing to minimize the count.  */
    3013       109872 :   if ((icode == CODE_FOR_nothing)
    3014       109872 :       || (!insn_operand_matches (icode, 2, op1))
    3015       549360 :       || (IN_RANGE (INTVAL (op1),
    3016              :                     GET_MODE_UNIT_PRECISION (mode) / 2 + left,
    3017              :                     GET_MODE_UNIT_PRECISION (mode) - 1)))
    3018        15463 :     return (insn_operand_matches (re_icode, 2, op1));
    3019              :   return false;
    3020              : }
    3021              : 
    3022              : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
    3023              :    and return the expression to be shifted in SHIFT_OPND and the shift amount
    3024              :    in SHIFT_AMNT.  This is primarily used to group handling of ASHIFT (X, CST)
    3025              :    and (PLUS (X, X)) in one place.  If the expression is not equivalent to an
    3026              :    ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL.  */
    3027              : 
    3028              : static bool
    3029    548024490 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
    3030              : {
    3031    548024490 :   if (GET_CODE (x) == ASHIFT)
    3032              :     {
    3033     14026052 :       *shift_opnd = XEXP (x, 0);
    3034     14026052 :       *shift_amnt = XEXP (x, 1);
    3035     14026052 :       return true;
    3036              :     }
    3037    533998438 :   if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
    3038              :     {
    3039        11581 :       *shift_opnd = XEXP (x, 0);
    3040        11581 :       *shift_amnt = CONST1_RTX (GET_MODE (x));
    3041        11581 :       return true;
    3042              :     }
    3043    533986857 :   *shift_opnd = NULL_RTX;
    3044    533986857 :   *shift_amnt = NULL_RTX;
    3045    533986857 :   return false;
    3046              : }
    3047              : 
    3048              : /* OP0 and OP1 are combined under an operation of mode MODE that can
    3049              :    potentially result in a ROTATE expression.  Analyze the OP0 and OP1
    3050              :    and return the resulting ROTATE expression if so.  Return NULL otherwise.
    3051              :    This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
    3052              :    C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
    3053              :    (X << C1) and (C >> C2) would be OP0 and OP1.  */
    3054              : 
    3055              : static rtx
    3056    276896826 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
    3057              : {
    3058              :   /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3059              :      mode size to (rotate A CX).  */
    3060              : 
    3061    276896826 :   rtx opleft = op0;
    3062    276896826 :   rtx opright = op1;
    3063    276896826 :   rtx ashift_opnd, ashift_amnt;
    3064              :   /* In some cases the ASHIFT is not a direct ASHIFT.  Look deeper and extract
    3065              :      the relevant operands here.  */
    3066    276896826 :   bool ashift_op_p
    3067    276896826 :     = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
    3068              : 
    3069    276896826 :   if (ashift_op_p
    3070    275117518 :      || GET_CODE (op1) == SUBREG)
    3071              :     {
    3072              :       opleft = op1;
    3073              :       opright = op0;
    3074              :     }
    3075              :   else
    3076              :     {
    3077    271127664 :       opright = op1;
    3078    271127664 :       opleft = op0;
    3079    271127664 :       ashift_op_p
    3080    271127664 :         = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
    3081              :     }
    3082              : 
    3083     14037633 :   if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
    3084    275189254 :       && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
    3085              :     {
    3086         9586 :       rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
    3087         9586 :       rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
    3088              : 
    3089         5754 :       if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
    3090        15340 :           && (INTVAL (leftcst) + INTVAL (rightcst)
    3091         5754 :               == GET_MODE_UNIT_PRECISION (mode)))
    3092         5095 :         return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
    3093              :     }
    3094              : 
    3095              :   /* Same, but for ashift that has been "simplified" to a wider mode
    3096              :      by simplify_shift_const.  */
    3097    276891731 :   scalar_int_mode int_mode, inner_mode;
    3098              : 
    3099    276891731 :   if (GET_CODE (opleft) == SUBREG
    3100    282562389 :       && is_a <scalar_int_mode> (mode, &int_mode)
    3101      5665563 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
    3102              :                                  &inner_mode)
    3103      5626554 :       && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
    3104       190952 :       && GET_CODE (opright) == LSHIFTRT
    3105          874 :       && GET_CODE (XEXP (opright, 0)) == SUBREG
    3106          238 :       && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
    3107          472 :       && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
    3108          229 :       && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
    3109          229 :                       SUBREG_REG (XEXP (opright, 0)))
    3110           13 :       && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
    3111           13 :       && CONST_INT_P (XEXP (opright, 1))
    3112    276891731 :       && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
    3113           13 :             + INTVAL (XEXP (opright, 1))
    3114           13 :          == GET_MODE_PRECISION (int_mode)))
    3115            1 :         return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
    3116              :                                XEXP (SUBREG_REG (opleft), 1));
    3117              :   return NULL_RTX;
    3118              : }
    3119              : 
    3120              : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
    3121              :    and the pattern can be simplified (there are no side effects).  */
    3122              : 
    3123              : static bool
    3124     39885132 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
    3125              : {
    3126              :   /* Remove SUBREG from OP0 and OP1, if needed.  */
    3127     39885132 :   if (GET_CODE (op0) == SUBREG
    3128      7173060 :       && GET_CODE (op1) == SUBREG
    3129       301531 :       && subreg_lowpart_p (op0)
    3130     40186002 :       && subreg_lowpart_p (op1))
    3131              :     {
    3132       300861 :       op0 = XEXP (op0, 0);
    3133       300861 :       op1 = XEXP (op1, 0);
    3134              :     }
    3135              : 
    3136              :   /* Check for the pattern (OP (plus (A - 1)) (neg A)).  */
    3137     39885132 :   if (((GET_CODE (op1) == NEG
    3138         3888 :         && GET_CODE (op0) == PLUS
    3139         2132 :         && XEXP (op0, 1) == CONSTM1_RTX (mode))
    3140     39884446 :        || (GET_CODE (op0) == NEG
    3141        78040 :            && GET_CODE (op1) == PLUS
    3142            0 :            && XEXP (op1, 1) == CONSTM1_RTX (mode)))
    3143          686 :       && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3144     39885134 :       && !side_effects_p (XEXP (op0, 0)))
    3145            2 :     return true;
    3146              :   return false;
    3147              : }
    3148              : 
    3149              : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
    3150              :    non-paradoxical.  */
    3151              : 
    3152              : static bool
    3153     75798732 : non_paradoxical_subreg_not_p (rtx op)
    3154              : {
    3155     75798732 :   return GET_CODE (op) == SUBREG
    3156      8730961 :          && !paradoxical_subreg_p (op)
    3157     78609679 :          && GET_CODE (SUBREG_REG (op)) == NOT;
    3158              : }
    3159              : 
    3160              : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
    3161              :    (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
    3162              :    opportunities to combine another binary logical operation with NOT.  */
    3163              : 
    3164              : static rtx
    3165     37900592 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
    3166              : {
    3167     37900592 :   rtx opn = NULL_RTX;
    3168     37900592 :   if (non_paradoxical_subreg_not_p (op0))
    3169              :     opn = op0;
    3170     37898140 :   else if (non_paradoxical_subreg_not_p (op1))
    3171              :     opn = op1;
    3172              : 
    3173         2475 :   if (opn == NULL_RTX)
    3174              :     return NULL_RTX;
    3175              : 
    3176         4950 :   rtx new_subreg = simplify_gen_subreg (mode,
    3177              :                                         XEXP (SUBREG_REG (opn), 0),
    3178         2475 :                                         GET_MODE (SUBREG_REG (opn)),
    3179         2475 :                                         SUBREG_BYTE (opn));
    3180              : 
    3181         2475 :   if (!new_subreg)
    3182              :     return NULL_RTX;
    3183              : 
    3184         2423 :   rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
    3185         2423 :   if (opn == op0)
    3186         2400 :     return simplify_gen_binary (binop, mode, new_not, op1);
    3187              :   else
    3188           23 :     return simplify_gen_binary (binop, mode, op0, new_not);
    3189              : }
    3190              : 
    3191              : /* Return TRUE iff NOP is a negated form of OP, or vice-versa.  */
    3192              : static bool
    3193      7196745 : negated_ops_p (rtx nop, rtx op)
    3194              : {
    3195              :   /* Explicit negation.  */
    3196      7196745 :   if (GET_CODE (nop) == NOT
    3197      7196745 :       && rtx_equal_p (XEXP (nop, 0), op))
    3198              :     return true;
    3199      7193385 :   if (GET_CODE (op) == NOT
    3200      7193385 :       && rtx_equal_p (XEXP (op, 0), nop))
    3201              :     return true;
    3202              : 
    3203              :   /* (~C <r A) is a negated form of (C << A) if C == 1.  */
    3204      7190213 :   if (GET_CODE (op) == ASHIFT
    3205      1483770 :       && GET_CODE (nop) == ROTATE
    3206            0 :       && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
    3207            0 :       && CONST_INT_P (XEXP (nop, 0))
    3208            0 :       && INTVAL (XEXP (nop, 0)) == -2
    3209      7190213 :       && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
    3210              :     return true;
    3211      7190213 :   if (GET_CODE (nop) == ASHIFT
    3212       153898 :       && GET_CODE (op) == ROTATE
    3213            0 :       && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
    3214            0 :       && CONST_INT_P (XEXP (nop, 0))
    3215            0 :       && INTVAL (XEXP (nop, 0)) == -2
    3216      7190213 :       && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
    3217              :     return true;
    3218              : 
    3219              :   /* ??? Should we consider rotations of C and ~C by the same amount?  */
    3220              : 
    3221              :   return false;
    3222              : }
    3223              : 
    3224              : /* Subroutine of simplify_binary_operation.  Simplify a binary operation
    3225              :    CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
    3226              :    OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
    3227              :    actual constants.  */
    3228              : 
    3229              : rtx
    3230    465407793 : simplify_context::simplify_binary_operation_1 (rtx_code code,
    3231              :                                                machine_mode mode,
    3232              :                                                rtx op0, rtx op1,
    3233              :                                                rtx trueop0, rtx trueop1)
    3234              : {
    3235    465407793 :   rtx tem, reversed, elt0, elt1;
    3236    465407793 :   HOST_WIDE_INT val;
    3237    465407793 :   scalar_int_mode int_mode, inner_mode;
    3238    465407793 :   poly_int64 offset;
    3239              : 
    3240              :   /* Even if we can't compute a constant result,
    3241              :      there are some cases worth simplifying.  */
    3242              : 
    3243    465407793 :   switch (code)
    3244              :     {
    3245    266656530 :     case PLUS:
    3246              :       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
    3247              :          when x is NaN, infinite, or finite and nonzero.  They aren't
    3248              :          when x is -0 and the rounding mode is not towards -infinity,
    3249              :          since (-0) + 0 is then 0.  */
    3250    529409576 :       if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
    3251    529409564 :           && trueop1 == CONST0_RTX (mode))
    3252              :         return op0;
    3253              : 
    3254              :       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
    3255              :          transformations are safe even for IEEE.  */
    3256    265034864 :       if (GET_CODE (op0) == NEG)
    3257        64401 :         return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
    3258    264970463 :       else if (GET_CODE (op1) == NEG)
    3259         8568 :         return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
    3260              : 
    3261              :       /* (~a) + 1 -> -a */
    3262    264961895 :       if (INTEGRAL_MODE_P (mode)
    3263    260148152 :           && GET_CODE (op0) == NOT
    3264      1385731 :           && trueop1 == const1_rtx)
    3265         3925 :         return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
    3266              : 
    3267              :       /* Handle both-operands-constant cases.  We can only add
    3268              :          CONST_INTs to constants since the sum of relocatable symbols
    3269              :          can't be handled by most assemblers.  Don't add CONST_INT
    3270              :          to CONST_INT since overflow won't be computed properly if wider
    3271              :          than HOST_BITS_PER_WIDE_INT.  */
    3272              : 
    3273    264957970 :       if ((GET_CODE (op0) == CONST
    3274    264957970 :            || GET_CODE (op0) == SYMBOL_REF
    3275    262338294 :            || GET_CODE (op0) == LABEL_REF)
    3276    264957970 :           && poly_int_rtx_p (op1, &offset))
    3277      2618711 :         return plus_constant (mode, op0, offset);
    3278    262339259 :       else if ((GET_CODE (op1) == CONST
    3279    262339259 :                 || GET_CODE (op1) == SYMBOL_REF
    3280    258163342 :                 || GET_CODE (op1) == LABEL_REF)
    3281    262339259 :                && poly_int_rtx_p (op0, &offset))
    3282            0 :         return plus_constant (mode, op1, offset);
    3283              : 
    3284              :       /* See if this is something like X * C - X or vice versa or
    3285              :          if the multiplication is written as a shift.  If so, we can
    3286              :          distribute and make a new multiply, shift, or maybe just
    3287              :          have X (if C is 2 in the example above).  But don't make
    3288              :          something more expensive than we had before.  */
    3289              : 
    3290    262339259 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3291              :         {
    3292    255221835 :           rtx lhs = op0, rhs = op1;
    3293              : 
    3294    255221835 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3295    255221835 :           wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3296              : 
    3297    255221835 :           if (GET_CODE (lhs) == NEG)
    3298              :             {
    3299            0 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3300            0 :               lhs = XEXP (lhs, 0);
    3301              :             }
    3302    255221835 :           else if (GET_CODE (lhs) == MULT
    3303      9581051 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3304              :             {
    3305      8251665 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3306      8251665 :               lhs = XEXP (lhs, 0);
    3307              :             }
    3308    246970170 :           else if (GET_CODE (lhs) == ASHIFT
    3309     11110337 :                    && CONST_INT_P (XEXP (lhs, 1))
    3310     11037812 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3311    258007970 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3312              :             {
    3313     11037800 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3314     22075600 :                                             GET_MODE_PRECISION (int_mode));
    3315     11037800 :               lhs = XEXP (lhs, 0);
    3316              :             }
    3317              : 
    3318    255221835 :           if (GET_CODE (rhs) == NEG)
    3319              :             {
    3320            0 :               coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3321            0 :               rhs = XEXP (rhs, 0);
    3322              :             }
    3323    255221835 :           else if (GET_CODE (rhs) == MULT
    3324       353268 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3325              :             {
    3326       195758 :               coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
    3327       195758 :               rhs = XEXP (rhs, 0);
    3328              :             }
    3329    255026077 :           else if (GET_CODE (rhs) == ASHIFT
    3330       626414 :                    && CONST_INT_P (XEXP (rhs, 1))
    3331       616577 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3332    255642654 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3333              :             {
    3334       616577 :               coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3335      1233154 :                                             GET_MODE_PRECISION (int_mode));
    3336       616577 :               rhs = XEXP (rhs, 0);
    3337              :             }
    3338              : 
    3339              :           /* Don't merge operands that have side effects.  */
    3340    255221835 :           if (rtx_equal_p (lhs, rhs) && !side_effects_p (lhs))
    3341              :             {
    3342       850278 :               rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
    3343       850278 :               rtx coeff;
    3344       850278 :               bool speed = optimize_function_for_speed_p (cfun);
    3345              : 
    3346       850278 :               coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
    3347              : 
    3348       850278 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3349       850278 :               return (set_src_cost (tem, int_mode, speed)
    3350       850278 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3351              :             }
    3352              : 
    3353              :           /* Optimize (X - 1) * Y + Y to X * Y.  */
    3354    254371557 :           lhs = op0;
    3355    254371557 :           rhs = op1;
    3356    254371557 :           if (GET_CODE (op0) == MULT)
    3357              :             {
    3358      9529518 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3359       631316 :                     && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
    3360      9476123 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3361        51304 :                        && XEXP (XEXP (op0, 0), 1) == const1_rtx))
    3362      9582913 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3363           85 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3364      9529433 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3365         1680 :                          && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
    3366      9529357 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3367          502 :                             && XEXP (XEXP (op0, 1), 1) == const1_rtx))
    3368      9529509 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3369            0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3370              :             }
    3371    244842039 :           else if (GET_CODE (op1) == MULT)
    3372              :             {
    3373       128138 :               if (((GET_CODE (XEXP (op1, 0)) == PLUS
    3374           99 :                     && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
    3375       128130 :                    || (GET_CODE (XEXP (op1, 0)) == MINUS
    3376           23 :                        && XEXP (XEXP (op1, 0), 1) == const1_rtx))
    3377       128146 :                   && rtx_equal_p (XEXP (op1, 1), op0))
    3378            0 :                 rhs = XEXP (XEXP (op1, 0), 0);
    3379       128138 :               else if (((GET_CODE (XEXP (op1, 1)) == PLUS
    3380           45 :                          && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
    3381       128138 :                         || (GET_CODE (XEXP (op1, 1)) == MINUS
    3382            4 :                             && XEXP (XEXP (op1, 1), 1) == const1_rtx))
    3383       128138 :                        && rtx_equal_p (XEXP (op1, 0), op0))
    3384            0 :                 rhs = XEXP (XEXP (op1, 1), 0);
    3385              :             }
    3386           85 :           if ((lhs != op0 && !side_effects_p (op1))
    3387    254371558 :               || (rhs != op1 && !side_effects_p (op0)))
    3388           84 :             return simplify_gen_binary (MULT, int_mode, lhs, rhs);
    3389    255221835 :         }
    3390              : 
    3391              :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
    3392    261488897 :       if (CONST_SCALAR_INT_P (op1)
    3393    198956508 :           && GET_CODE (op0) == XOR
    3394        18625 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3395    261498624 :           && mode_signbit_p (mode, op1))
    3396          121 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3397              :                                     simplify_gen_binary (XOR, mode, op1,
    3398          121 :                                                          XEXP (op0, 1)));
    3399              : 
    3400              :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
    3401              :          2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
    3402    261488776 :       if (CONST_SCALAR_INT_P (op1)
    3403    198956387 :           && GET_CODE (op0) == XOR
    3404        18504 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3405         9606 :           && nonzero_bits (XEXP (op0, 0), mode) == 1
    3406          341 :           && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
    3407    261488776 :           && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
    3408            0 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3409              :                                     simplify_gen_binary (XOR, mode, op1,
    3410            0 :                                                          XEXP (op0, 1)));
    3411              : 
    3412              :       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
    3413    261488776 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3414    261486248 :           && GET_CODE (op0) == MULT
    3415    271401455 :           && GET_CODE (XEXP (op0, 0)) == NEG)
    3416              :         {
    3417         4085 :           rtx in1, in2;
    3418              : 
    3419         4085 :           in1 = XEXP (XEXP (op0, 0), 0);
    3420         4085 :           in2 = XEXP (op0, 1);
    3421         4085 :           return simplify_gen_binary (MINUS, mode, op1,
    3422              :                                       simplify_gen_binary (MULT, mode,
    3423         4085 :                                                            in1, in2));
    3424              :         }
    3425              : 
    3426              :       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
    3427              :          C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
    3428              :          is 1.  */
    3429    261484691 :       if (COMPARISON_P (op0)
    3430      1298206 :           && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
    3431      1298206 :               || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
    3432    261542076 :           && (reversed = reversed_comparison (op0, mode)))
    3433        57028 :         return
    3434        57028 :           simplify_gen_unary (NEG, mode, reversed, mode);
    3435              : 
    3436              :       /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3437              :          mode size to (rotate A CX).  */
    3438    261427663 :       if ((tem = simplify_rotate_op (op0, op1, mode)))
    3439              :         return tem;
    3440              : 
    3441              :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3442              :          simplify this by the associative law.
    3443              :          Don't use the associative law for floating point.
    3444              :          The inaccuracy makes it nonassociative,
    3445              :          and subtle programs can break if operations are associated.  */
    3446              : 
    3447    261426173 :       if (INTEGRAL_MODE_P (mode)
    3448    256612479 :           && (plus_minus_operand_p (op0)
    3449    221840672 :               || plus_minus_operand_p (op1))
    3450     35779013 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3451              :         return tem;
    3452              : 
    3453              :       /* Reassociate floating point addition only when the user
    3454              :          specifies associative math operations.  */
    3455    226289300 :       if (FLOAT_MODE_P (mode)
    3456      4813694 :           && flag_associative_math)
    3457              :         {
    3458       910127 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3459       910127 :           if (tem)
    3460              :             return tem;
    3461              :         }
    3462              : 
    3463              :       /* Handle vector series.  */
    3464    226275596 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3465              :         {
    3466      2129390 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3467      2129390 :           if (tem)
    3468              :             return tem;
    3469              :         }
    3470              :       break;
    3471              : 
    3472              :     case COMPARE:
    3473              :       break;
    3474              : 
    3475     45985768 :     case MINUS:
    3476              :       /* We can't assume x-x is 0 even with non-IEEE floating point,
    3477              :          but since it is zero except in very strange circumstances, we
    3478              :          will treat it as zero with -ffinite-math-only.  */
    3479     45985768 :       if (rtx_equal_p (trueop0, trueop1)
    3480       214072 :           && ! side_effects_p (op0)
    3481     46199398 :           && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
    3482       210773 :         return CONST0_RTX (mode);
    3483              : 
    3484              :       /* Change subtraction from zero into negation.  (0 - x) is the
    3485              :          same as -x when x is NaN, infinite, or finite and nonzero.
    3486              :          But if the mode has signed zeros, and does not round towards
    3487              :          -infinity, then 0 - 0 is 0, not -0.  */
    3488     45774995 :       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
    3489       360467 :         return simplify_gen_unary (NEG, mode, op1, mode);
    3490              : 
    3491              :       /* (-1 - a) is ~a, unless the expression contains symbolic
    3492              :          constants, in which case not retaining additions and
    3493              :          subtractions could cause invalid assembly to be produced.  */
    3494     45414528 :       if (trueop0 == CONSTM1_RTX (mode)
    3495     45414528 :           && !contains_symbolic_reference_p (op1))
    3496       616161 :         return simplify_gen_unary (NOT, mode, op1, mode);
    3497              : 
    3498              :       /* Subtracting 0 has no effect unless the mode has signalling NaNs,
    3499              :          or has signed zeros and supports rounding towards -infinity.
    3500              :          In such a case, 0 - 0 is -0.  */
    3501     45542848 :       if (!(HONOR_SIGNED_ZEROS (mode)
    3502       744481 :             && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    3503     44797217 :           && !HONOR_SNANS (mode)
    3504     89595548 :           && trueop1 == CONST0_RTX (mode))
    3505              :         return op0;
    3506              : 
    3507              :       /* See if this is something like X * C - X or vice versa or
    3508              :          if the multiplication is written as a shift.  If so, we can
    3509              :          distribute and make a new multiply, shift, or maybe just
    3510              :          have X (if C is 2 in the example above).  But don't make
    3511              :          something more expensive than we had before.  */
    3512              : 
    3513     43866000 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3514              :         {
    3515     42429338 :           rtx lhs = op0, rhs = op1;
    3516              : 
    3517     42429338 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3518     42429338 :           wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3519              : 
    3520     42429338 :           if (GET_CODE (lhs) == NEG)
    3521              :             {
    3522        73828 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3523        73828 :               lhs = XEXP (lhs, 0);
    3524              :             }
    3525     42355510 :           else if (GET_CODE (lhs) == MULT
    3526       236598 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3527              :             {
    3528        80463 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3529        80463 :               lhs = XEXP (lhs, 0);
    3530              :             }
    3531     42275047 :           else if (GET_CODE (lhs) == ASHIFT
    3532       307624 :                    && CONST_INT_P (XEXP (lhs, 1))
    3533       304366 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3534     42579392 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3535              :             {
    3536       304345 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3537       608690 :                                             GET_MODE_PRECISION (int_mode));
    3538       304345 :               lhs = XEXP (lhs, 0);
    3539              :             }
    3540              : 
    3541     42429338 :           if (GET_CODE (rhs) == NEG)
    3542              :             {
    3543        13479 :               negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3544        13479 :               rhs = XEXP (rhs, 0);
    3545              :             }
    3546     42415859 :           else if (GET_CODE (rhs) == MULT
    3547       131949 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3548              :             {
    3549        93335 :               negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
    3550        93335 :               rhs = XEXP (rhs, 0);
    3551              :             }
    3552     42322524 :           else if (GET_CODE (rhs) == ASHIFT
    3553       404327 :                    && CONST_INT_P (XEXP (rhs, 1))
    3554       403779 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3555     42726303 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3556              :             {
    3557       403779 :               negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3558       807558 :                                                GET_MODE_PRECISION (int_mode));
    3559       403779 :               negcoeff1 = -negcoeff1;
    3560       403779 :               rhs = XEXP (rhs, 0);
    3561              :             }
    3562              : 
    3563     42429338 :           if (rtx_equal_p (lhs, rhs) && !side_effects_p (lhs))
    3564              :             {
    3565        92122 :               rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
    3566        92122 :               rtx coeff;
    3567        92122 :               bool speed = optimize_function_for_speed_p (cfun);
    3568              : 
    3569        92122 :               coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
    3570              : 
    3571        92122 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3572        92122 :               return (set_src_cost (tem, int_mode, speed)
    3573        92122 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3574              :             }
    3575              : 
    3576              :           /* Optimize (X + 1) * Y - Y to X * Y.  */
    3577     42337216 :           lhs = op0;
    3578     42337216 :           if (GET_CODE (op0) == MULT)
    3579              :             {
    3580       236120 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3581         4953 :                     && XEXP (XEXP (op0, 0), 1) == const1_rtx)
    3582       234420 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3583         1665 :                        && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
    3584       237820 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3585            3 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3586       236117 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3587           30 :                          && XEXP (XEXP (op0, 1), 1) == const1_rtx)
    3588       236109 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3589           84 :                             && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
    3590       236125 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3591            0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3592              :             }
    3593     42337216 :           if (lhs != op0 && !side_effects_p (op1))
    3594            2 :             return simplify_gen_binary (MULT, int_mode, lhs, op1);
    3595     42429338 :         }
    3596              : 
    3597              :       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
    3598     43773876 :       if (GET_CODE (op1) == NEG)
    3599        13425 :         return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
    3600              : 
    3601              :       /* (-x - c) may be simplified as (-c - x).  */
    3602     43760451 :       if (GET_CODE (op0) == NEG
    3603        77973 :           && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
    3604              :         {
    3605          724 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    3606          724 :           if (tem)
    3607          724 :             return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
    3608              :         }
    3609              : 
    3610     43759727 :       if ((GET_CODE (op0) == CONST
    3611     43759727 :            || GET_CODE (op0) == SYMBOL_REF
    3612     38076772 :            || GET_CODE (op0) == LABEL_REF)
    3613     43759727 :           && poly_int_rtx_p (op1, &offset))
    3614        54018 :         return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
    3615              : 
    3616              :       /* Don't let a relocatable value get a negative coeff.  */
    3617     43705709 :       if (is_a <scalar_int_mode> (mode)
    3618     42269078 :           && poly_int_rtx_p (op1)
    3619     51062913 :           && GET_MODE (op0) != VOIDmode)
    3620      7357204 :         return simplify_gen_binary (PLUS, mode,
    3621              :                                     op0,
    3622      7357204 :                                     neg_poly_int_rtx (mode, op1));
    3623              : 
    3624              :       /* (x - (x & y)) -> (x & ~y) */
    3625     36348505 :       if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
    3626              :         {
    3627       223770 :           if (rtx_equal_p (op0, XEXP (op1, 0)))
    3628              :             {
    3629          590 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
    3630          295 :                                         GET_MODE (XEXP (op1, 1)));
    3631          295 :               return simplify_gen_binary (AND, mode, op0, tem);
    3632              :             }
    3633       223475 :           if (rtx_equal_p (op0, XEXP (op1, 1)))
    3634              :             {
    3635         2476 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
    3636         1238 :                                         GET_MODE (XEXP (op1, 0)));
    3637         1238 :               return simplify_gen_binary (AND, mode, op0, tem);
    3638              :             }
    3639              :         }
    3640              : 
    3641              :       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
    3642              :          by reversing the comparison code if valid.  */
    3643     36346972 :       if (STORE_FLAG_VALUE == 1
    3644     36346972 :           && trueop0 == const1_rtx
    3645      1211532 :           && COMPARISON_P (op1)
    3646     36451618 :           && (reversed = reversed_comparison (op1, mode)))
    3647              :         return reversed;
    3648              : 
    3649              :       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
    3650     36242331 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3651     36240980 :           && GET_CODE (op1) == MULT
    3652     36474916 :           && GET_CODE (XEXP (op1, 0)) == NEG)
    3653              :         {
    3654          173 :           rtx in1, in2;
    3655              : 
    3656          173 :           in1 = XEXP (XEXP (op1, 0), 0);
    3657          173 :           in2 = XEXP (op1, 1);
    3658          173 :           return simplify_gen_binary (PLUS, mode,
    3659              :                                       simplify_gen_binary (MULT, mode,
    3660              :                                                            in1, in2),
    3661          173 :                                       op0);
    3662              :         }
    3663              : 
    3664              :       /* Canonicalize (minus (neg A) (mult B C)) to
    3665              :          (minus (mult (neg B) C) A).  */
    3666     36242158 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3667     36240807 :           && GET_CODE (op1) == MULT
    3668     36474570 :           && GET_CODE (op0) == NEG)
    3669              :         {
    3670          678 :           rtx in1, in2;
    3671              : 
    3672          678 :           in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
    3673          678 :           in2 = XEXP (op1, 1);
    3674          678 :           return simplify_gen_binary (MINUS, mode,
    3675              :                                       simplify_gen_binary (MULT, mode,
    3676              :                                                            in1, in2),
    3677          678 :                                       XEXP (op0, 0));
    3678              :         }
    3679              : 
    3680              :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3681              :          simplify this by the associative law.  This will, for example,
    3682              :          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
    3683              :          Don't use the associative law for floating point.
    3684              :          The inaccuracy makes it nonassociative,
    3685              :          and subtle programs can break if operations are associated.  */
    3686              : 
    3687     36241480 :       if (INTEGRAL_MODE_P (mode)
    3688     35375544 :           && (plus_minus_operand_p (op0)
    3689     32422212 :               || plus_minus_operand_p (op1))
    3690      4195995 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3691              :         return tem;
    3692              : 
    3693              :       /* Handle vector series.  */
    3694     32197278 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3695              :         {
    3696       541065 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3697       541065 :           if (tem)
    3698              :             return tem;
    3699              :         }
    3700              :       break;
    3701              : 
    3702     12913496 :     case MULT:
    3703     12913496 :       if (trueop1 == constm1_rtx)
    3704        34847 :         return simplify_gen_unary (NEG, mode, op0, mode);
    3705              : 
    3706     12878649 :       if (GET_CODE (op0) == NEG)
    3707              :         {
    3708        38101 :           rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
    3709              :           /* If op1 is a MULT as well and simplify_unary_operation
    3710              :              just moved the NEG to the second operand, simplify_gen_binary
    3711              :              below could through simplify_associative_operation move
    3712              :              the NEG around again and recurse endlessly.  */
    3713        38101 :           if (temp
    3714         1901 :               && GET_CODE (op1) == MULT
    3715            0 :               && GET_CODE (temp) == MULT
    3716            0 :               && XEXP (op1, 0) == XEXP (temp, 0)
    3717            0 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3718            0 :               && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
    3719              :             temp = NULL_RTX;
    3720              :           if (temp)
    3721         1901 :             return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
    3722              :         }
    3723     12876748 :       if (GET_CODE (op1) == NEG)
    3724              :         {
    3725          961 :           rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
    3726              :           /* If op0 is a MULT as well and simplify_unary_operation
    3727              :              just moved the NEG to the second operand, simplify_gen_binary
    3728              :              below could through simplify_associative_operation move
    3729              :              the NEG around again and recurse endlessly.  */
    3730          961 :           if (temp
    3731          399 :               && GET_CODE (op0) == MULT
    3732          296 :               && GET_CODE (temp) == MULT
    3733          296 :               && XEXP (op0, 0) == XEXP (temp, 0)
    3734            6 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3735            5 :               && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
    3736              :             temp = NULL_RTX;
    3737              :           if (temp)
    3738          394 :             return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
    3739              :         }
    3740              : 
    3741              :       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
    3742              :          x is NaN, since x * 0 is then also NaN.  Nor is it valid
    3743              :          when the mode has signed zeros, since multiplying a negative
    3744              :          number by 0 will give -0, not 0.  */
    3745     12876354 :       if (!HONOR_NANS (mode)
    3746     11886564 :           && !HONOR_SIGNED_ZEROS (mode)
    3747     11886148 :           && trueop1 == CONST0_RTX (mode)
    3748     12923091 :           && ! side_effects_p (op0))
    3749              :         return op1;
    3750              : 
    3751              :       /* In IEEE floating point, x*1 is not equivalent to x for
    3752              :          signalling NaNs.  */
    3753     12829617 :       if (!HONOR_SNANS (mode)
    3754     12829617 :           && trueop1 == CONST1_RTX (mode))
    3755              :         return op0;
    3756              : 
    3757              :       /* Convert multiply by constant power of two into shift.  */
    3758     12287413 :       if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
    3759              :         {
    3760      6280237 :           val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
    3761      6280237 :           if (val >= 0)
    3762      2949319 :             return simplify_gen_binary (ASHIFT, mode, op0,
    3763      2949319 :                                         gen_int_shift_amount (mode, val));
    3764              :         }
    3765              : 
    3766              :       /* x*2 is x+x and x*(-1) is -x */
    3767      9338094 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    3768       173284 :           && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
    3769       173284 :           && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
    3770       173000 :           && GET_MODE (op0) == mode)
    3771              :         {
    3772       173000 :           const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    3773              : 
    3774       173000 :           if (real_equal (d1, &dconst2))
    3775          682 :             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
    3776              : 
    3777       172318 :           if (!HONOR_SNANS (mode)
    3778       172318 :               && real_equal (d1, &dconstm1))
    3779           24 :             return simplify_gen_unary (NEG, mode, op0, mode);
    3780              :         }
    3781              : 
    3782              :       /* Optimize -x * -x as x * x.  */
    3783      9337388 :       if (FLOAT_MODE_P (mode)
    3784      1413096 :           && GET_CODE (op0) == NEG
    3785         8342 :           && GET_CODE (op1) == NEG
    3786            0 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3787            0 :           && !side_effects_p (XEXP (op0, 0)))
    3788            0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3789              : 
    3790              :       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
    3791      9337388 :       if (SCALAR_FLOAT_MODE_P (mode)
    3792      1107943 :           && GET_CODE (op0) == ABS
    3793         1488 :           && GET_CODE (op1) == ABS
    3794            1 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3795      9337388 :           && !side_effects_p (XEXP (op0, 0)))
    3796            0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3797              : 
    3798              :       /* Reassociate multiplication, but for floating point MULTs
    3799              :          only when the user specifies unsafe math optimizations.  */
    3800      9337388 :       if (! FLOAT_MODE_P (mode)
    3801      1413096 :           || flag_unsafe_math_optimizations)
    3802              :         {
    3803      8348712 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3804      8348712 :           if (tem)
    3805              :             return tem;
    3806              :         }
    3807              :       break;
    3808              : 
    3809     14977070 :     case IOR:
    3810     14977070 :       if (trueop1 == CONST0_RTX (mode))
    3811              :         return op0;
    3812     14257301 :       if (INTEGRAL_MODE_P (mode)
    3813     13980439 :           && trueop1 == CONSTM1_RTX (mode)
    3814        10033 :           && !side_effects_p (op0))
    3815              :         return op1;
    3816     14247268 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    3817              :         return op0;
    3818              :       /* A | (~A) -> -1 */
    3819        77129 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    3820     14236434 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    3821            0 :           && ! side_effects_p (op0)
    3822     14236434 :           && GET_MODE_CLASS (mode) != MODE_CC)
    3823            0 :         return CONSTM1_RTX (mode);
    3824              : 
    3825              :       /* IOR of two single bit bitfields extracted from the same object.
    3826              :          Bitfields are represented as an AND based extraction */
    3827     14236434 :       if (GET_CODE (op0) == AND
    3828      4408856 :           && GET_CODE (op1) == AND
    3829              :           /* Verify both AND operands are logical right shifts. */
    3830       291695 :           && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    3831         2264 :           && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
    3832              :           /* Verify both bitfields are extracted from the same object. */
    3833          260 :           && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
    3834              :           /* Verify both fields are a single bit (could be generalized). */
    3835          256 :           && XEXP (op0, 1) == CONST1_RTX (mode)
    3836            0 :           && XEXP (op1, 1) == CONST1_RTX (mode)
    3837              :           /* Verify bit positions (for cases with variable bit position). */
    3838            0 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3839            0 :           && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
    3840              :         {
    3841            0 :           unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
    3842            0 :           unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
    3843            0 :           unsigned HOST_WIDE_INT mask
    3844            0 :             = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
    3845              : 
    3846            0 :           rtx m = GEN_INT (mask);
    3847            0 :           rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
    3848            0 :           t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
    3849            0 :           return t;
    3850              :         }
    3851              : 
    3852              :       /* IOR of multiple single bit bitfields extracted from the same object
    3853              :          (building on previous case).
    3854              :          First bitfield is represented as an AND based extraction, as done
    3855              :                 above. Second represented as NE based extraction, from
    3856              :                 output above. */
    3857     14236434 :       if (GET_CODE (op0) == AND
    3858      4408856 :           && GET_CODE (op1) == NE
    3859              :           /* Verify AND operand is logical right shift. */
    3860         3392 :           && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    3861              :           /* Verify NE operand is an AND (based on output above). */
    3862           86 :           && GET_CODE (XEXP (op1, 0)) == AND
    3863              :           /* Verify both bitfields are extracted from the same object. */
    3864            0 :           && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
    3865              :           /* Verify masking is with a single bit and that we have a NE 0
    3866              :              comparison for the other operand.  */
    3867            0 :           && XEXP (op0, 1) == CONST1_RTX (mode)
    3868            0 :           && XEXP (op1, 1) == CONST0_RTX (mode)
    3869              :           /* Verify bit position. */
    3870            0 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    3871              :         {
    3872            0 :           unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
    3873            0 :           unsigned HOST_WIDE_INT mask
    3874            0 :             = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
    3875              : 
    3876            0 :           rtx m = GEN_INT (mask);
    3877            0 :           rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
    3878            0 :           t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
    3879            0 :           return t;
    3880              :         }
    3881              : 
    3882              :       /* Convert (ior (plus (A - 1)) (neg A)) to -1.  */
    3883     14236434 :       if (match_plus_neg_pattern (op0, op1, mode))
    3884            0 :         return CONSTM1_RTX (mode);
    3885              : 
    3886              :       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
    3887     14236434 :       if (CONST_INT_P (op1)
    3888      3742347 :           && HWI_COMPUTABLE_MODE_P (mode)
    3889      3685637 :           && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
    3890     14460498 :           && !side_effects_p (op0))
    3891              :         return op1;
    3892              : 
    3893              :       /* Canonicalize (X & C1) | C2.  */
    3894     14012370 :       if (GET_CODE (op0) == AND
    3895      4399995 :           && CONST_INT_P (trueop1)
    3896       786743 :           && CONST_INT_P (XEXP (op0, 1)))
    3897              :         {
    3898       563310 :           HOST_WIDE_INT mask = GET_MODE_MASK (mode);
    3899       563310 :           HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
    3900       563310 :           HOST_WIDE_INT c2 = INTVAL (trueop1);
    3901              : 
    3902              :           /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2.  */
    3903       563310 :           if ((c1 & c2) == c1
    3904       563310 :               && !side_effects_p (XEXP (op0, 0)))
    3905              :             return trueop1;
    3906              : 
    3907              :           /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
    3908       563302 :           if (((c1|c2) & mask) == mask)
    3909        78054 :             return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
    3910              : 
    3911              :           /* If (C1|C2) has a single bit clear, then adjust C1 so that
    3912              :              when split it'll match a single bit clear style insn.
    3913              : 
    3914              :              This could have been done with a target dependent splitter, but
    3915              :              then every target with single bit manipulation insns would need
    3916              :              to implement such splitters.  */
    3917       485248 :           if (exact_log2 (~(c1 | c2)) >= 0)
    3918              :             {
    3919        69515 :               rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
    3920        69515 :               temp = gen_rtx_IOR (mode, temp, trueop1);
    3921        69515 :               return temp;
    3922              :             }
    3923              :         }
    3924              : 
    3925              :       /* Convert (A & B) | A to A.  */
    3926     13864793 :       if (GET_CODE (op0) == AND
    3927      4252418 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    3928      4251933 :               || rtx_equal_p (XEXP (op0, 1), op1))
    3929         3676 :           && ! side_effects_p (XEXP (op0, 0))
    3930     13868469 :           && ! side_effects_p (XEXP (op0, 1)))
    3931              :         return op1;
    3932              : 
    3933              :       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3934              :          mode size to (rotate A CX).  */
    3935     13861117 :       tem = simplify_rotate_op (op0, op1, mode);
    3936     13861117 :       if (tem)
    3937              :         return tem;
    3938              : 
    3939              :       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
    3940              :          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
    3941              :          the PLUS does not affect any of the bits in OP1: then we can do
    3942              :          the IOR as a PLUS and we can associate.  This is valid if OP1
    3943              :          can be safely shifted left C bits.  */
    3944     13858891 :       if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
    3945         6186 :           && GET_CODE (XEXP (op0, 0)) == PLUS
    3946           74 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3947           50 :           && CONST_INT_P (XEXP (op0, 1))
    3948           50 :           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
    3949              :         {
    3950           50 :           int count = INTVAL (XEXP (op0, 1));
    3951           50 :           HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
    3952              : 
    3953           50 :           if (mask >> count == INTVAL (trueop1)
    3954           43 :               && trunc_int_for_mode (mask, mode) == mask
    3955           80 :               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
    3956            0 :             return simplify_gen_binary (ASHIFTRT, mode,
    3957              :                                         plus_constant (mode, XEXP (op0, 0),
    3958            0 :                                                        mask),
    3959              :                                         XEXP (op0, 1));
    3960              :         }
    3961              : 
    3962              :       /* The following happens with bitfield merging.
    3963              :          (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
    3964     13858891 :       if (GET_CODE (op0) == AND
    3965      4248742 :           && GET_CODE (op1) == AND
    3966       291695 :           && CONST_INT_P (XEXP (op0, 1))
    3967       130500 :           && CONST_INT_P (XEXP (op1, 1))
    3968       126126 :           && (INTVAL (XEXP (op0, 1))
    3969       126126 :               == ~INTVAL (XEXP (op1, 1))))
    3970              :         {
    3971              :           /* The IOR/XOR may be on both sides.  */
    3972        37098 :           rtx top0 = NULL_RTX, top1 = NULL_RTX;
    3973        37098 :           if (GET_CODE (XEXP (op1, 0)) == IOR
    3974        37098 :               || GET_CODE (XEXP (op1, 0)) == XOR)
    3975              :             top0 = op0, top1 = op1;
    3976        36979 :           else if (GET_CODE (XEXP (op0, 0)) == IOR
    3977        36979 :                    || GET_CODE (XEXP (op0, 0)) == XOR)
    3978            3 :             top0 = op1, top1 = op0;
    3979        37098 :           if (top0 && top1)
    3980              :             {
    3981              :               /* X may be on either side of the inner IOR/XOR.  */
    3982          122 :               rtx tem = NULL_RTX;
    3983          122 :               if (rtx_equal_p (XEXP (top0, 0),
    3984          122 :                                XEXP (XEXP (top1, 0), 0)))
    3985           76 :                 tem = XEXP (XEXP (top1, 0), 1);
    3986           46 :               else if (rtx_equal_p (XEXP (top0, 0),
    3987           46 :                                     XEXP (XEXP (top1, 0), 1)))
    3988           13 :                 tem = XEXP (XEXP (top1, 0), 0);
    3989           89 :               if (tem)
    3990           89 :                 return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
    3991              :                                             mode, XEXP (top0, 0),
    3992              :                                             simplify_gen_binary
    3993           89 :                                               (AND, mode, tem, XEXP (top1, 1)));
    3994              :             }
    3995              :         }
    3996              : 
    3997              :       /* Convert (ior (and A C) (and B C)) into (and (ior A B) C).  */
    3998     13858802 :       if (GET_CODE (op0) == GET_CODE (op1)
    3999      3052560 :           && (GET_CODE (op0) == AND
    4000              :               || GET_CODE (op0) == IOR
    4001      3052560 :               || GET_CODE (op0) == LSHIFTRT
    4002      2759983 :               || GET_CODE (op0) == ASHIFTRT
    4003      2759850 :               || GET_CODE (op0) == ASHIFT
    4004      2742991 :               || GET_CODE (op0) == ROTATE
    4005      2742991 :               || GET_CODE (op0) == ROTATERT))
    4006              :         {
    4007       309569 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4008       309569 :           if (tem)
    4009              :             return tem;
    4010              :         }
    4011              : 
    4012              :       /* Convert (ior (and (not A) B) A) into A | B.  */
    4013     13774527 :       if (GET_CODE (op0) == AND
    4014     13774527 :           && negated_ops_p (XEXP (op0, 0), op1))
    4015         6496 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4016              : 
    4017              :       /* op0/op1 may have a common term which in turn may allow simplification
    4018              :          of the the outer IOR.  There are likely other cases we should
    4019              :          handle for the outer code as well as the form of the operands.  */
    4020     13768031 :       tem = simplify_ior_with_common_term (mode, op0, op1);
    4021     13768031 :       if (tem)
    4022              :         return tem;
    4023              : 
    4024              :       /* IOR is commutative and we can't rely on canonicalization at this point,
    4025              :          so try again to simplify with the operands reversed.  */
    4026     13767941 :       tem = simplify_ior_with_common_term (mode, op1, op0);
    4027     13767941 :       if (tem)
    4028              :         return tem;
    4029              : 
    4030     13767941 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4031     13767941 :       if (tem)
    4032              :         return tem;
    4033              : 
    4034     13767936 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4035     13767936 :       if (tem)
    4036              :         return tem;
    4037              : 
    4038     13767930 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4039     13767930 :       if (tem)
    4040              :         return tem;
    4041              : 
    4042     13507768 :       tem = simplify_logical_relational_operation (code, mode, op0, op1);
    4043     13507768 :       if (tem)
    4044              :         return tem;
    4045              :       break;
    4046              : 
    4047      1896415 :     case XOR:
    4048      1896415 :       if (trueop1 == CONST0_RTX (mode))
    4049              :         return op0;
    4050      1836600 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4051        31096 :         return simplify_gen_unary (NOT, mode, op0, mode);
    4052      1805504 :       if (rtx_equal_p (trueop0, trueop1)
    4053         2851 :           && ! side_effects_p (op0)
    4054      1808351 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4055         2847 :          return CONST0_RTX (mode);
    4056              : 
    4057              :       /* Canonicalize XOR of the most significant bit to PLUS.  */
    4058      1802657 :       if (CONST_SCALAR_INT_P (op1)
    4059      1802657 :           && mode_signbit_p (mode, op1))
    4060        41202 :         return simplify_gen_binary (PLUS, mode, op0, op1);
    4061              :       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
    4062      1761455 :       if (CONST_SCALAR_INT_P (op1)
    4063       505600 :           && GET_CODE (op0) == PLUS
    4064         2539 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    4065      1762975 :           && mode_signbit_p (mode, XEXP (op0, 1)))
    4066          189 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    4067              :                                     simplify_gen_binary (XOR, mode, op1,
    4068          189 :                                                          XEXP (op0, 1)));
    4069              : 
    4070              :       /* If we are XORing two things that have no bits in common,
    4071              :          convert them into an IOR.  This helps to detect rotation encoded
    4072              :          using those methods and possibly other simplifications.  */
    4073              : 
    4074      1761266 :       if (HWI_COMPUTABLE_MODE_P (mode)
    4075      1415523 :           && (nonzero_bits (op0, mode)
    4076      1415523 :               & nonzero_bits (op1, mode)) == 0)
    4077        10205 :         return (simplify_gen_binary (IOR, mode, op0, op1));
    4078              : 
    4079              :       /* Convert (xor (plus (A - 1)) (neg A)) to -1.  */
    4080      1751061 :       if (match_plus_neg_pattern (op0, op1, mode))
    4081            0 :         return CONSTM1_RTX (mode);
    4082              : 
    4083              :       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
    4084              :          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
    4085              :          (NOT y).  */
    4086      1751061 :       {
    4087      1751061 :         int num_negated = 0;
    4088              : 
    4089      1751061 :         if (GET_CODE (op0) == NOT)
    4090          723 :           num_negated++, op0 = XEXP (op0, 0);
    4091      1751061 :         if (GET_CODE (op1) == NOT)
    4092           67 :           num_negated++, op1 = XEXP (op1, 0);
    4093              : 
    4094           67 :         if (num_negated == 2)
    4095            0 :           return simplify_gen_binary (XOR, mode, op0, op1);
    4096      1751061 :         else if (num_negated == 1)
    4097          790 :           return simplify_gen_unary (NOT, mode,
    4098              :                                      simplify_gen_binary (XOR, mode, op0, op1),
    4099          790 :                                      mode);
    4100              :       }
    4101              : 
    4102              :       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
    4103              :          correspond to a machine insn or result in further simplifications
    4104              :          if B is a constant.  */
    4105              : 
    4106      1750271 :       if (GET_CODE (op0) == AND
    4107       195245 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4108      1773258 :           && ! side_effects_p (op1))
    4109        22987 :         return simplify_gen_binary (AND, mode,
    4110              :                                     simplify_gen_unary (NOT, mode,
    4111              :                                                         XEXP (op0, 0), mode),
    4112        22987 :                                     op1);
    4113              : 
    4114      1727284 :       else if (GET_CODE (op0) == AND
    4115       172258 :                && rtx_equal_p (XEXP (op0, 0), op1)
    4116      1729386 :                && ! side_effects_p (op1))
    4117         2102 :         return simplify_gen_binary (AND, mode,
    4118              :                                     simplify_gen_unary (NOT, mode,
    4119              :                                                         XEXP (op0, 1), mode),
    4120         2102 :                                     op1);
    4121              : 
    4122              :       /* Similarly, convert (xor (ior A B) B) to (and (not B) A).  */
    4123      1725182 :       else if (GET_CODE (op0) == IOR
    4124        23216 :                && rtx_equal_p (XEXP (op0, 1), op1)
    4125      1725337 :                && ! side_effects_p (op1))
    4126          155 :         return simplify_gen_binary (AND, mode,
    4127              :                                     simplify_gen_unary (NOT, mode,
    4128              :                                                         op1, mode),
    4129          155 :                                     XEXP (op0, 0));
    4130      1725027 :       else if (GET_CODE (op0) == IOR
    4131        23061 :                && rtx_equal_p (XEXP (op0, 0), op1)
    4132      1725035 :                && ! side_effects_p (op1))
    4133            8 :         return simplify_gen_binary (AND, mode,
    4134              :                                     simplify_gen_unary (NOT, mode,
    4135              :                                                         op1, mode),
    4136            8 :                                     XEXP (op0, 1));
    4137              : 
    4138              :       /* Given (xor (ior (xor A B) C) D), where B, C and D are
    4139              :          constants, simplify to (xor (ior A C) (B&~C)^D), canceling
    4140              :          out bits inverted twice and not set by C.  Similarly, given
    4141              :          (xor (and (xor A B) C) D), simplify without inverting C in
    4142              :          the xor operand: (xor (and A C) (B&C)^D).
    4143              :       */
    4144      1725019 :       else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
    4145       193209 :                && GET_CODE (XEXP (op0, 0)) == XOR
    4146         7612 :                && CONST_INT_P (op1)
    4147          222 :                && CONST_INT_P (XEXP (op0, 1))
    4148          179 :                && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    4149              :         {
    4150           38 :           enum rtx_code op = GET_CODE (op0);
    4151           38 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4152           38 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4153           38 :           rtx c = XEXP (op0, 1);
    4154           38 :           rtx d = op1;
    4155           38 :           HOST_WIDE_INT bval = INTVAL (b);
    4156           38 :           HOST_WIDE_INT cval = INTVAL (c);
    4157           38 :           HOST_WIDE_INT dval = INTVAL (d);
    4158           38 :           HOST_WIDE_INT xcval;
    4159              : 
    4160           38 :           if (op == IOR)
    4161            8 :             xcval = ~cval;
    4162              :           else
    4163              :             xcval = cval;
    4164              : 
    4165           38 :           return simplify_gen_binary (XOR, mode,
    4166              :                                       simplify_gen_binary (op, mode, a, c),
    4167           38 :                                       gen_int_mode ((bval & xcval) ^ dval,
    4168              :                                                     mode));
    4169              :         }
    4170              : 
    4171              :       /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
    4172              :          we can transform like this:
    4173              :             (A&B)^C == ~(A&B)&C | ~C&(A&B)
    4174              :                     == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
    4175              :                     == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
    4176              :          Attempt a few simplifications when B and C are both constants.  */
    4177      1724981 :       if (GET_CODE (op0) == AND
    4178       170126 :           && CONST_INT_P (op1)
    4179        14490 :           && CONST_INT_P (XEXP (op0, 1)))
    4180              :         {
    4181        11501 :           rtx a = XEXP (op0, 0);
    4182        11501 :           rtx b = XEXP (op0, 1);
    4183        11501 :           rtx c = op1;
    4184        11501 :           HOST_WIDE_INT bval = INTVAL (b);
    4185        11501 :           HOST_WIDE_INT cval = INTVAL (c);
    4186              : 
    4187              :           /* Instead of computing ~A&C, we compute its negated value,
    4188              :              ~(A|~C).  If it yields -1, ~A&C is zero, so we can
    4189              :              optimize for sure.  If it does not simplify, we still try
    4190              :              to compute ~A&C below, but since that always allocates
    4191              :              RTL, we don't try that before committing to returning a
    4192              :              simplified expression.  */
    4193        11501 :           rtx n_na_c = simplify_binary_operation (IOR, mode, a,
    4194              :                                                   GEN_INT (~cval));
    4195              : 
    4196        11501 :           if ((~cval & bval) == 0)
    4197              :             {
    4198          824 :               rtx na_c = NULL_RTX;
    4199          824 :               if (n_na_c)
    4200            0 :                 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
    4201              :               else
    4202              :                 {
    4203              :                   /* If ~A does not simplify, don't bother: we don't
    4204              :                      want to simplify 2 operations into 3, and if na_c
    4205              :                      were to simplify with na, n_na_c would have
    4206              :                      simplified as well.  */
    4207          824 :                   rtx na = simplify_unary_operation (NOT, mode, a, mode);
    4208          824 :                   if (na)
    4209            0 :                     na_c = simplify_gen_binary (AND, mode, na, c);
    4210              :                 }
    4211              : 
    4212              :               /* Try to simplify ~A&C | ~B&C.  */
    4213            0 :               if (na_c != NULL_RTX)
    4214            0 :                 return simplify_gen_binary (IOR, mode, na_c,
    4215            0 :                                             gen_int_mode (~bval & cval, mode));
    4216              :             }
    4217              :           else
    4218              :             {
    4219              :               /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
    4220        10677 :               if (n_na_c == CONSTM1_RTX (mode))
    4221              :                 {
    4222            0 :                   rtx a_nc_b = simplify_gen_binary (AND, mode, a,
    4223            0 :                                                     gen_int_mode (~cval & bval,
    4224              :                                                                   mode));
    4225            0 :                   return simplify_gen_binary (IOR, mode, a_nc_b,
    4226            0 :                                               gen_int_mode (~bval & cval,
    4227              :                                                             mode));
    4228              :                 }
    4229              :             }
    4230              :         }
    4231              : 
    4232              :       /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
    4233              :          do (ior (and A ~C) (and B C)) which is a machine instruction on some
    4234              :          machines, and also has shorter instruction path length.  */
    4235      1724981 :       if (GET_CODE (op0) == AND
    4236       170126 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4237         7124 :           && CONST_INT_P (XEXP (op0, 1))
    4238      1728809 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
    4239              :         {
    4240            7 :           rtx a = trueop1;
    4241            7 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4242            7 :           rtx c = XEXP (op0, 1);
    4243            7 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4244            7 :           rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
    4245            7 :           rtx bc = simplify_gen_binary (AND, mode, b, c);
    4246            7 :           return simplify_gen_binary (IOR, mode, a_nc, bc);
    4247              :         }
    4248              :       /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C))  */
    4249      1724974 :       else if (GET_CODE (op0) == AND
    4250       170119 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4251         7117 :           && CONST_INT_P (XEXP (op0, 1))
    4252      1728795 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
    4253              :         {
    4254            8 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4255            8 :           rtx b = trueop1;
    4256            8 :           rtx c = XEXP (op0, 1);
    4257            8 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4258            8 :           rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
    4259            8 :           rtx ac = simplify_gen_binary (AND, mode, a, c);
    4260            8 :           return simplify_gen_binary (IOR, mode, ac, b_nc);
    4261              :         }
    4262              : 
    4263              :       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
    4264              :          comparison if STORE_FLAG_VALUE is 1.  */
    4265      1724966 :       if (STORE_FLAG_VALUE == 1
    4266      1724966 :           && trueop1 == const1_rtx
    4267       212555 :           && COMPARISON_P (op0)
    4268      1731765 :           && (reversed = reversed_comparison (op0, mode)))
    4269              :         return reversed;
    4270              : 
    4271              :       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
    4272              :          is (lt foo (const_int 0)), so we can perform the above
    4273              :          simplification if STORE_FLAG_VALUE is 1.  */
    4274              : 
    4275      1718191 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4276              :           && STORE_FLAG_VALUE == 1
    4277      1376987 :           && trueop1 == const1_rtx
    4278       205780 :           && GET_CODE (op0) == LSHIFTRT
    4279        35201 :           && CONST_INT_P (XEXP (op0, 1))
    4280        35201 :           && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    4281        34098 :         return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
    4282              : 
    4283              :       /* (xor (comparison foo bar) (const_int sign-bit))
    4284              :          when STORE_FLAG_VALUE is the sign bit.  */
    4285      1684093 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4286      1342889 :           && val_signbit_p (int_mode, STORE_FLAG_VALUE)
    4287            0 :           && trueop1 == const_true_rtx
    4288            0 :           && COMPARISON_P (op0)
    4289            0 :           && (reversed = reversed_comparison (op0, int_mode)))
    4290              :         return reversed;
    4291              : 
    4292              :       /* Convert (xor (and A C) (and B C)) into (and (xor A B) C).  */
    4293      1684093 :       if (GET_CODE (op0) == GET_CODE (op1)
    4294       586608 :           && (GET_CODE (op0) == AND
    4295       586608 :               || GET_CODE (op0) == LSHIFTRT
    4296       507485 :               || GET_CODE (op0) == ASHIFTRT
    4297       507383 :               || GET_CODE (op0) == ASHIFT
    4298       507255 :               || GET_CODE (op0) == ROTATE
    4299       507113 :               || GET_CODE (op0) == ROTATERT))
    4300              :         {
    4301        80029 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4302        80029 :           if (tem)
    4303              :             return tem;
    4304              :         }
    4305              : 
    4306              :       /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    4307              :          mode size to (rotate A CX).  */
    4308      1608046 :       tem = simplify_rotate_op (op0, op1, mode);
    4309      1608046 :       if (tem)
    4310              :         return tem;
    4311              : 
    4312              :       /* Convert (xor (and (not A) B) A) into A | B.  */
    4313      1606666 :       if (GET_CODE (op0) == AND
    4314      1606666 :           && negated_ops_p (XEXP (op0, 0), op1))
    4315            0 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4316              : 
    4317              :       /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
    4318              :          into B | (1 << A).  */
    4319      1606666 :       if (SHIFT_COUNT_TRUNCATED
    4320              :           && GET_CODE (op0) == AND
    4321              :           && GET_CODE (XEXP (op0, 0)) == ROTATE
    4322              :           && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4323              :           && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
    4324              :           && GET_CODE (op1) == ASHIFT
    4325              :           && CONST_INT_P (XEXP (op1, 0))
    4326              :           && INTVAL (XEXP (op1, 0)) == 1
    4327              :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
    4328              :           && !side_effects_p (XEXP (op1, 1)))
    4329              :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4330              : 
    4331      1606666 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4332      1606666 :       if (tem)
    4333              :         return tem;
    4334              : 
    4335      1606665 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4336      1606665 :       if (tem)
    4337              :         return tem;
    4338              : 
    4339      1606665 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4340      1606665 :       if (tem)
    4341              :         return tem;
    4342              :       break;
    4343              : 
    4344     25094019 :     case AND:
    4345     25094019 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    4346              :         return trueop1;
    4347     24764042 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4348              :         return op0;
    4349     24354651 :       if (HWI_COMPUTABLE_MODE_P (mode))
    4350              :         {
    4351              :           /* When WORD_REGISTER_OPERATIONS is true, we need to know the
    4352              :              nonzero bits in WORD_MODE rather than MODE.  */
    4353     21328522 :           scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
    4354     21328522 :           if (WORD_REGISTER_OPERATIONS
    4355              :               && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    4356              :             tmode = word_mode;
    4357     21328522 :           HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
    4358     21328522 :           HOST_WIDE_INT nzop1;
    4359     21328522 :           if (CONST_INT_P (trueop1))
    4360              :             {
    4361     18012982 :               HOST_WIDE_INT val1 = INTVAL (trueop1);
    4362              :               /* If we are turning off bits already known off in OP0, we need
    4363              :                  not do an AND.  */
    4364     18012982 :               if ((nzop0 & ~val1) == 0)
    4365       448521 :                 return op0;
    4366              : 
    4367              :               /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
    4368              :                  (and (lshiftrt (subreg X) shift) mask).
    4369              : 
    4370              :                  Keeps shift and AND in the same mode, improving recognition.
    4371              :                  Only applied when subreg is a lowpart, shift is valid,
    4372              :                  and no precision is lost.  */
    4373     17651478 :               if (SUBREG_P (op0)
    4374      6208121 :                   && subreg_lowpart_p (op0)
    4375      6191076 :                   && !paradoxical_subreg_p (op0)
    4376       799030 :                   && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
    4377              :                   /* simplify_subreg asserts the object being accessed is not
    4378              :                      VOIDmode or BLKmode.  We may have a REG_EQUAL note which
    4379              :                      is not simplified and the source operand is a constant,
    4380              :                      and thus VOIDmode.  Guard against that.  */
    4381       117448 :                   && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
    4382       117398 :                   && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
    4383       117398 :                   && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4384       117398 :                   && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    4385        96425 :                   && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
    4386        96425 :                   && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
    4387     17747878 :                   && ((INTVAL (XEXP (XEXP (op0, 0), 1))
    4388        96400 :                       + floor_log2 (val1))
    4389     17651478 :                       < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
    4390              :                 {
    4391        13389 :                   tem = XEXP (XEXP (op0, 0), 0);
    4392        13389 :                   if (SUBREG_P (tem))
    4393              :                     {
    4394          296 :                       if (subreg_lowpart_p (tem))
    4395          296 :                         tem = SUBREG_REG (tem);
    4396              :                       else
    4397              :                         tem = NULL_RTX;
    4398              :                     }
    4399          296 :                   if (tem != NULL_RTX)
    4400              :                     {
    4401        13389 :                       offset = subreg_lowpart_offset (mode, GET_MODE (tem));
    4402        13389 :                       tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
    4403        13389 :                                                  offset);
    4404        13389 :                       if (tem)
    4405              :                         {
    4406        13389 :                           unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
    4407        13389 :                           rtx shiftamtrtx = gen_int_shift_amount (mode,
    4408        13389 :                                                                   shiftamt);
    4409        13389 :                           op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
    4410              :                                                      shiftamtrtx);
    4411        13389 :                           return simplify_gen_binary (AND, mode, op0, op1);
    4412              :                         }
    4413              :                     }
    4414              :                 }
    4415              :             }
    4416     20953629 :           nzop1 = nonzero_bits (trueop1, mode);
    4417              :           /* If we are clearing all the nonzero bits, the result is zero.  */
    4418     20953629 :           if ((nzop1 & nzop0) == 0
    4419     20953629 :               && !side_effects_p (op0) && !side_effects_p (op1))
    4420        73628 :             return CONST0_RTX (mode);
    4421              :         }
    4422     23910894 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
    4423     23910890 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4424              :         return op0;
    4425              :       /* A & (~A) -> 0 */
    4426       638361 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    4427     23897684 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    4428         3734 :           && ! side_effects_p (op0)
    4429     23905103 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4430         3733 :         return CONST0_RTX (mode);
    4431              : 
    4432              :       /* Convert (and (plus (A - 1)) (neg A)) to 0.  */
    4433     23897637 :       if (match_plus_neg_pattern (op0, op1, mode))
    4434            2 :         return CONST0_RTX (mode);
    4435              : 
    4436              :       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
    4437              :          there are no nonzero bits of C outside of X's mode.  */
    4438     47795270 :       if ((GET_CODE (op0) == SIGN_EXTEND
    4439     23897635 :            || GET_CODE (op0) == ZERO_EXTEND)
    4440        95478 :           && CONST_SCALAR_INT_P (trueop1)
    4441        82249 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4442        82249 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4443     23979884 :           && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
    4444        82249 :                         GET_MODE_PRECISION (int_mode))
    4445     23979884 :               & rtx_mode_t (trueop1, mode)) == 0)
    4446              :         {
    4447        80187 :           machine_mode imode = GET_MODE (XEXP (op0, 0));
    4448        80187 :           tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
    4449        80187 :           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
    4450        80187 :           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
    4451              :         }
    4452              : 
    4453              :       /* Transform (and (truncate X) C) into (truncate (and X C)).  This way
    4454              :          we might be able to further simplify the AND with X and potentially
    4455              :          remove the truncation altogether.  */
    4456     23817448 :       if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
    4457              :         {
    4458            6 :           rtx x = XEXP (op0, 0);
    4459            6 :           machine_mode xmode = GET_MODE (x);
    4460            6 :           tem = simplify_gen_binary (AND, xmode, x,
    4461            6 :                                      gen_int_mode (INTVAL (trueop1), xmode));
    4462            6 :           return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
    4463              :         }
    4464              : 
    4465              :       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
    4466     23817442 :       if (GET_CODE (op0) == IOR
    4467      1463100 :           && CONST_INT_P (trueop1)
    4468       225032 :           && CONST_INT_P (XEXP (op0, 1)))
    4469              :         {
    4470       142219 :           HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
    4471       142219 :           return simplify_gen_binary (IOR, mode,
    4472              :                                       simplify_gen_binary (AND, mode,
    4473              :                                                            XEXP (op0, 0), op1),
    4474       142219 :                                       gen_int_mode (tmp, mode));
    4475              :         }
    4476              : 
    4477              :       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
    4478              :          insn (and may simplify more).  */
    4479     23675223 :       if (GET_CODE (op0) == XOR
    4480       155366 :           && rtx_equal_p (XEXP (op0, 0), op1)
    4481     23676879 :           && ! side_effects_p (op1))
    4482         1656 :         return simplify_gen_binary (AND, mode,
    4483              :                                     simplify_gen_unary (NOT, mode,
    4484              :                                                         XEXP (op0, 1), mode),
    4485         1656 :                                     op1);
    4486              : 
    4487     23673567 :       if (GET_CODE (op0) == XOR
    4488       153710 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4489     23678437 :           && ! side_effects_p (op1))
    4490         4870 :         return simplify_gen_binary (AND, mode,
    4491              :                                     simplify_gen_unary (NOT, mode,
    4492              :                                                         XEXP (op0, 0), mode),
    4493         4870 :                                     op1);
    4494              : 
    4495              :       /* Similarly for (~(A ^ B)) & A.  */
    4496     23668697 :       if (GET_CODE (op0) == NOT
    4497       634676 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4498         3868 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
    4499     23668751 :           && ! side_effects_p (op1))
    4500           54 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
    4501              : 
    4502     23668643 :       if (GET_CODE (op0) == NOT
    4503       634622 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4504         3814 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
    4505     23668680 :           && ! side_effects_p (op1))
    4506           37 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
    4507              : 
    4508              :       /* Convert (A | B) & A to A.  */
    4509     23668606 :       if (GET_CODE (op0) == IOR
    4510      1320881 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    4511      1320356 :               || rtx_equal_p (XEXP (op0, 1), op1))
    4512          750 :           && ! side_effects_p (XEXP (op0, 0))
    4513     23669356 :           && ! side_effects_p (XEXP (op0, 1)))
    4514              :         return op1;
    4515              : 
    4516              :       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
    4517              :          ((A & N) + B) & M -> (A + B) & M
    4518              :          Similarly if (N & M) == 0,
    4519              :          ((A | N) + B) & M -> (A + B) & M
    4520              :          and for - instead of + and/or ^ instead of |.
    4521              :          Also, if (N & M) == 0, then
    4522              :          (A +- N) & M -> A & M.  */
    4523     23667856 :       if (CONST_INT_P (trueop1)
    4524     17437069 :           && HWI_COMPUTABLE_MODE_P (mode)
    4525     17415145 :           && ~UINTVAL (trueop1)
    4526     17415145 :           && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
    4527     35142440 :           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
    4528              :         {
    4529       991504 :           rtx pmop[2];
    4530       991504 :           int which;
    4531              : 
    4532       991504 :           pmop[0] = XEXP (op0, 0);
    4533       991504 :           pmop[1] = XEXP (op0, 1);
    4534              : 
    4535       991504 :           if (CONST_INT_P (pmop[1])
    4536       489881 :               && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
    4537       172301 :             return simplify_gen_binary (AND, mode, pmop[0], op1);
    4538              : 
    4539      2480526 :           for (which = 0; which < 2; which++)
    4540              :             {
    4541      1653684 :               tem = pmop[which];
    4542      1653684 :               switch (GET_CODE (tem))
    4543              :                 {
    4544        14762 :                 case AND:
    4545        14762 :                   if (CONST_INT_P (XEXP (tem, 1))
    4546        13191 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
    4547              :                       == UINTVAL (trueop1))
    4548         7630 :                     pmop[which] = XEXP (tem, 0);
    4549              :                   break;
    4550         1346 :                 case IOR:
    4551         1346 :                 case XOR:
    4552         1346 :                   if (CONST_INT_P (XEXP (tem, 1))
    4553          176 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
    4554            9 :                     pmop[which] = XEXP (tem, 0);
    4555              :                   break;
    4556              :                 default:
    4557              :                   break;
    4558              :                 }
    4559              :             }
    4560              : 
    4561       826842 :           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
    4562              :             {
    4563         7639 :               tem = simplify_gen_binary (GET_CODE (op0), mode,
    4564              :                                          pmop[0], pmop[1]);
    4565         7639 :               return simplify_gen_binary (code, mode, tem, op1);
    4566              :             }
    4567              :         }
    4568              : 
    4569              :       /* (and X (ior (not X) Y) -> (and X Y) */
    4570     23495555 :       if (GET_CODE (op1) == IOR
    4571      1018327 :           && GET_CODE (XEXP (op1, 0)) == NOT
    4572     23500974 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
    4573            0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
    4574              : 
    4575              :       /* (and (ior (not X) Y) X) -> (and X Y) */
    4576     23495555 :       if (GET_CODE (op0) == IOR
    4577      1320131 :           && GET_CODE (XEXP (op0, 0)) == NOT
    4578     23548122 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
    4579            6 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
    4580              : 
    4581              :       /* (and X (ior Y (not X)) -> (and X Y) */
    4582     23495549 :       if (GET_CODE (op1) == IOR
    4583      1018327 :           && GET_CODE (XEXP (op1, 1)) == NOT
    4584     23496115 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
    4585            0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
    4586              : 
    4587              :       /* (and (ior Y (not X)) X) -> (and X Y) */
    4588     23495549 :       if (GET_CODE (op0) == IOR
    4589      1320125 :           && GET_CODE (XEXP (op0, 1)) == NOT
    4590     23502939 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
    4591           72 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
    4592              : 
    4593              :       /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
    4594     23495477 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4595     23495477 :           && negated_ops_p (op1, XEXP (op0, 1)))
    4596           36 :         return simplify_gen_binary (AND, mode, XEXP (op0, 0),
    4597              :                                     simplify_gen_unary (NOT, mode,
    4598              :                                                         XEXP (op0, 1),
    4599           36 :                                                         mode));
    4600              :       /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
    4601     23495441 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4602     23495441 :           && negated_ops_p (op1, XEXP (op0, 0)))
    4603            0 :         return simplify_gen_binary (AND, mode, XEXP (op0, 1),
    4604              :                                     simplify_gen_unary (NOT, mode,
    4605              :                                                         XEXP (op0, 0),
    4606            0 :                                                         mode));
    4607              : 
    4608              :       /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C).  */
    4609     23495441 :       if (GET_CODE (op0) == GET_CODE (op1)
    4610      2400046 :           && (GET_CODE (op0) == AND
    4611              :               || GET_CODE (op0) == IOR
    4612      2400046 :               || GET_CODE (op0) == LSHIFTRT
    4613      1382235 :               || GET_CODE (op0) == ASHIFTRT
    4614      1382095 :               || GET_CODE (op0) == ASHIFT
    4615      1381935 :               || GET_CODE (op0) == ROTATE
    4616      1381935 :               || GET_CODE (op0) == ROTATERT))
    4617              :         {
    4618      1018111 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4619      1018111 :           if (tem)
    4620              :             return tem;
    4621              :         }
    4622              : 
    4623              :       /* (and:v4si
    4624              :            (ashiftrt:v4si A 16)
    4625              :            (const_vector: 0xffff x4))
    4626              :          is just (lshiftrt:v4si A 16).  */
    4627     22526027 :       if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
    4628         4880 :           && (CONST_INT_P (XEXP (op0, 1))
    4629         2035 :               || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
    4630           94 :                   && const_vec_duplicate_p (XEXP (op0, 1))
    4631            0 :                   && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
    4632         2845 :           && GET_CODE (op1) == CONST_VECTOR
    4633     22526055 :           && const_vec_duplicate_p (op1)
    4634     22526097 :           && CONST_INT_P (XVECEXP (op1, 0, 0)))
    4635              :         {
    4636          136 :           unsigned HOST_WIDE_INT shift_count
    4637              :             = (CONST_INT_P (XEXP (op0, 1))
    4638           68 :                ? UINTVAL (XEXP (op0, 1))
    4639            0 :                : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
    4640           68 :           unsigned HOST_WIDE_INT inner_prec
    4641          136 :             = GET_MODE_PRECISION (GET_MODE_INNER (mode));
    4642              : 
    4643              :           /* Avoid UD shift count.  */
    4644           68 :           if (shift_count < inner_prec
    4645           56 :               && (UINTVAL (XVECEXP (op1, 0, 0))
    4646           56 :                   == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
    4647           42 :             return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
    4648              :         }
    4649              : 
    4650     22525985 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4651     22525985 :       if (tem)
    4652              :         return tem;
    4653              : 
    4654     22523568 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4655     22523568 :       if (tem)
    4656              :         return tem;
    4657              : 
    4658     22523347 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4659     22523347 :       if (tem)
    4660              :         return tem;
    4661              :       break;
    4662              : 
    4663       901351 :     case UDIV:
    4664              :       /* 0/x is 0 (or x&0 if x has side-effects).  */
    4665       901351 :       if (trueop0 == CONST0_RTX (mode)
    4666          392 :           && !cfun->can_throw_non_call_exceptions)
    4667              :         {
    4668          392 :           if (side_effects_p (op1))
    4669            0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4670              :           return trueop0;
    4671              :         }
    4672              :       /* x/1 is x.  */
    4673       900959 :       if (trueop1 == CONST1_RTX (mode))
    4674              :         {
    4675       242049 :           tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4676       242049 :           if (tem)
    4677              :             return tem;
    4678              :         }
    4679              :       /* Convert divide by power of two into shift.  */
    4680       658910 :       if (CONST_INT_P (trueop1)
    4681       984080 :           && (val = exact_log2 (UINTVAL (trueop1))) > 0)
    4682       325170 :         return simplify_gen_binary (LSHIFTRT, mode, op0,
    4683       325170 :                                     gen_int_shift_amount (mode, val));
    4684              :       break;
    4685              : 
    4686      1434182 :     case DIV:
    4687              :       /* Handle floating point and integers separately.  */
    4688      1434182 :       if (SCALAR_FLOAT_MODE_P (mode))
    4689              :         {
    4690              :           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
    4691              :              safe for modes with NaNs, since 0.0 / 0.0 will then be
    4692              :              NaN rather than 0.0.  Nor is it safe for modes with signed
    4693              :              zeros, since dividing 0 by a negative number gives -0.0  */
    4694       339673 :           if (trueop0 == CONST0_RTX (mode)
    4695         2817 :               && !HONOR_NANS (mode)
    4696           14 :               && !HONOR_SIGNED_ZEROS (mode)
    4697       339687 :               && ! side_effects_p (op1))
    4698              :             return op0;
    4699              :           /* x/1.0 is x.  */
    4700       339659 :           if (trueop1 == CONST1_RTX (mode)
    4701       339659 :               && !HONOR_SNANS (mode))
    4702              :             return op0;
    4703              : 
    4704       339655 :           if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    4705        35045 :               && trueop1 != CONST0_RTX (mode))
    4706              :             {
    4707        28975 :               const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    4708              : 
    4709              :               /* x/-1.0 is -x.  */
    4710        28975 :               if (real_equal (d1, &dconstm1)
    4711        28975 :                   && !HONOR_SNANS (mode))
    4712            0 :                 return simplify_gen_unary (NEG, mode, op0, mode);
    4713              : 
    4714              :               /* Change FP division by a constant into multiplication.
    4715              :                  Only do this with -freciprocal-math.  */
    4716        28975 :               if (flag_reciprocal_math
    4717        28975 :                   && !real_equal (d1, &dconst0))
    4718              :                 {
    4719            7 :                   REAL_VALUE_TYPE d;
    4720            7 :                   real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
    4721            7 :                   tem = const_double_from_real_value (d, mode);
    4722            7 :                   return simplify_gen_binary (MULT, mode, op0, tem);
    4723              :                 }
    4724              :             }
    4725              :         }
    4726      1094509 :       else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    4727              :         {
    4728              :           /* 0/x is 0 (or x&0 if x has side-effects).  */
    4729      1062970 :           if (trueop0 == CONST0_RTX (mode)
    4730          984 :               && !cfun->can_throw_non_call_exceptions)
    4731              :             {
    4732          930 :               if (side_effects_p (op1))
    4733            8 :                 return simplify_gen_binary (AND, mode, op1, trueop0);
    4734              :               return trueop0;
    4735              :             }
    4736              :           /* x/1 is x.  */
    4737      1062040 :           if (trueop1 == CONST1_RTX (mode))
    4738              :             {
    4739           92 :               tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4740           92 :               if (tem)
    4741              :                 return tem;
    4742              :             }
    4743              :           /* x/-1 is -x.  */
    4744      1061948 :           if (trueop1 == CONSTM1_RTX (mode))
    4745              :             {
    4746          512 :               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4747          512 :               if (x)
    4748          512 :                 return simplify_gen_unary (NEG, mode, x, mode);
    4749              :             }
    4750              :         }
    4751              :       break;
    4752              : 
    4753       917913 :     case UMOD:
    4754              :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4755       917913 :       if (trueop0 == CONST0_RTX (mode))
    4756              :         {
    4757          951 :           if (side_effects_p (op1))
    4758            0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4759              :           return trueop0;
    4760              :         }
    4761              :       /* x%1 is 0 (of x&0 if x has side-effects).  */
    4762       916962 :       if (trueop1 == CONST1_RTX (mode))
    4763              :         {
    4764       268596 :           if (side_effects_p (op0))
    4765            0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4766       268596 :           return CONST0_RTX (mode);
    4767              :         }
    4768              :       /* Implement modulus by power of two as AND.  */
    4769       648366 :       if (CONST_INT_P (trueop1)
    4770       947327 :           && exact_log2 (UINTVAL (trueop1)) > 0)
    4771       298961 :         return simplify_gen_binary (AND, mode, op0,
    4772       298961 :                                     gen_int_mode (UINTVAL (trueop1) - 1,
    4773              :                                                   mode));
    4774              :       break;
    4775              : 
    4776       580552 :     case MOD:
    4777              :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4778       580552 :       if (trueop0 == CONST0_RTX (mode))
    4779              :         {
    4780         1216 :           if (side_effects_p (op1))
    4781            8 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4782              :           return trueop0;
    4783              :         }
    4784              :       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
    4785       579336 :       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
    4786              :         {
    4787          486 :           if (side_effects_p (op0))
    4788            0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4789          486 :           return CONST0_RTX (mode);
    4790              :         }
    4791              :       break;
    4792              : 
    4793       141031 :     case ROTATERT:
    4794       141031 :     case ROTATE:
    4795       141031 :       if (trueop1 == CONST0_RTX (mode))
    4796              :         return op0;
    4797              :       /* Canonicalize rotates by constant amount.  If the condition of
    4798              :          reversing direction is met, then reverse the direction. */
    4799              : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
    4800       140941 :       if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
    4801              :         {
    4802        12173 :           int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
    4803        12173 :           rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
    4804        12899 :           return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
    4805              :                                       mode, op0, new_amount_rtx);
    4806              :         }
    4807              : #endif
    4808              :       /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X).  Other combinations
    4809              :          such as SImode with a count of 16 do not correspond to RTL BSWAP
    4810              :          semantics.  */
    4811       128768 :       tem = unwrap_const_vec_duplicate (trueop1);
    4812       128768 :       if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
    4813       128768 :           && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
    4814          666 :         return simplify_gen_unary (BSWAP, mode, op0, mode);
    4815              : 
    4816              :       /* FALLTHRU */
    4817      5506132 :     case ASHIFTRT:
    4818      5506132 :       if (trueop1 == CONST0_RTX (mode))
    4819              :         return op0;
    4820      5503850 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4821              :         return op0;
    4822              :       /* Rotating ~0 always results in ~0.  */
    4823      5503669 :       if (CONST_INT_P (trueop0)
    4824        15591 :           && HWI_COMPUTABLE_MODE_P (mode)
    4825        15563 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4826      5503669 :           && ! side_effects_p (op1))
    4827              :         return op0;
    4828              : 
    4829     32258396 :     canonicalize_shift:
    4830              :       /* Given:
    4831              :          scalar modes M1, M2
    4832              :          scalar constants c1, c2
    4833              :          size (M2) > size (M1)
    4834              :          c1 == size (M2) - size (M1)
    4835              :          optimize:
    4836              :          ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
    4837              :                                  <low_part>)
    4838              :                       (const_int <c2>))
    4839              :          to:
    4840              :          (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
    4841              :                     <low_part>).  */
    4842     32258396 :       if ((code == ASHIFTRT || code == LSHIFTRT)
    4843     12347272 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4844     11513871 :           && SUBREG_P (op0)
    4845      1262601 :           && CONST_INT_P (op1)
    4846      1259619 :           && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
    4847        19077 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
    4848              :                                      &inner_mode)
    4849        19077 :           && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
    4850        37768 :           && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
    4851        18884 :           && (INTVAL (XEXP (SUBREG_REG (op0), 1))
    4852        37768 :               == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
    4853     32277031 :           && subreg_lowpart_p (op0))
    4854              :         {
    4855        18635 :           rtx tmp = gen_int_shift_amount
    4856        18635 :             (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
    4857              : 
    4858              :          /* Combine would usually zero out the value when combining two
    4859              :             local shifts and the range becomes larger or equal to the mode.
    4860              :             However since we fold away one of the shifts here combine won't
    4861              :             see it so we should immediately zero the result if it's out of
    4862              :             range.  */
    4863        18635 :          if (code == LSHIFTRT
    4864        33743 :              && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
    4865            0 :           tmp = const0_rtx;
    4866              :          else
    4867        18635 :            tmp = simplify_gen_binary (code,
    4868              :                                       inner_mode,
    4869        18635 :                                       XEXP (SUBREG_REG (op0), 0),
    4870              :                                       tmp);
    4871              : 
    4872        18635 :           return lowpart_subreg (int_mode, tmp, inner_mode);
    4873              :         }
    4874              : 
    4875     32239761 :       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
    4876              :         {
    4877              :           val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
    4878              :           if (val != INTVAL (op1))
    4879              :             return simplify_gen_binary (code, mode, op0,
    4880              :                                         gen_int_shift_amount (mode, val));
    4881              :         }
    4882              : 
    4883              :       /* Simplify:
    4884              : 
    4885              :            (code:M1
    4886              :              (subreg:M1
    4887              :                ([al]shiftrt:M2
    4888              :                  (subreg:M2
    4889              :                    (ashift:M1 X C1))
    4890              :                  C2))
    4891              :              C3)
    4892              : 
    4893              :          to:
    4894              : 
    4895              :            (code:M1
    4896              :              ([al]shiftrt:M1
    4897              :                (ashift:M1 X C1+N)
    4898              :                C2+N)
    4899              :              C3)
    4900              : 
    4901              :          where M1 is N bits wider than M2.  Optimizing the (subreg:M1 ...)
    4902              :          directly would be arithmetically correct, but restricting the
    4903              :          simplification to shifts by constants is more conservative,
    4904              :          since it is more likely to lead to further simplifications.  */
    4905     32239761 :       if (is_a<scalar_int_mode> (mode, &int_mode)
    4906      5688466 :           && paradoxical_subreg_p (op0)
    4907      5170204 :           && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
    4908      5145757 :           && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
    4909      5145757 :               || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
    4910       135467 :           && CONST_INT_P (op1))
    4911              :         {
    4912       135467 :           auto xcode = GET_CODE (SUBREG_REG (op0));
    4913       135467 :           rtx xop0 = XEXP (SUBREG_REG (op0), 0);
    4914       135467 :           rtx xop1 = XEXP (SUBREG_REG (op0), 1);
    4915       135467 :           if (SUBREG_P (xop0)
    4916        10087 :               && GET_MODE (SUBREG_REG (xop0)) == mode
    4917         9964 :               && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
    4918          595 :               && CONST_INT_P (xop1)
    4919       136062 :               && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
    4920              :             {
    4921          595 :               rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
    4922          595 :               rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
    4923          595 :               if (CONST_INT_P (yop1)
    4924          595 :                   && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
    4925              :                 {
    4926         1190 :                   auto bias = (GET_MODE_BITSIZE (int_mode)
    4927          595 :                                - GET_MODE_BITSIZE (inner_mode));
    4928          595 :                   tem = simplify_gen_binary (ASHIFT, mode, yop0,
    4929          595 :                                              GEN_INT (INTVAL (yop1) + bias));
    4930          595 :                   tem = simplify_gen_binary (xcode, mode, tem,
    4931          595 :                                              GEN_INT (INTVAL (xop1) + bias));
    4932          595 :                   return simplify_gen_binary (code, mode, tem, op1);
    4933              :                 }
    4934              :             }
    4935              :         }
    4936              :       break;
    4937              : 
    4938            0 :     case SS_ASHIFT:
    4939            0 :       if (CONST_INT_P (trueop0)
    4940            0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4941            0 :           && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
    4942            0 :               || mode_signbit_p (mode, trueop0))
    4943            0 :           && ! side_effects_p (op1))
    4944              :         return op0;
    4945            0 :       goto simplify_ashift;
    4946              : 
    4947            0 :     case US_ASHIFT:
    4948            0 :       if (CONST_INT_P (trueop0)
    4949            0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4950            0 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4951            0 :           && ! side_effects_p (op1))
    4952              :         return op0;
    4953              :       /* FALLTHRU */
    4954              : 
    4955     20199380 :     case ASHIFT:
    4956     20199380 : simplify_ashift:
    4957     20199380 :       if (trueop1 == CONST0_RTX (mode))
    4958              :         return op0;
    4959     20029101 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4960              :         return op0;
    4961     19999410 :       if (mem_depth
    4962       216357 :           && code == ASHIFT
    4963       216357 :           && CONST_INT_P (trueop1)
    4964       216349 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4965     20215747 :           && IN_RANGE (UINTVAL (trueop1),
    4966              :                        1, GET_MODE_PRECISION (int_mode) - 1))
    4967              :         {
    4968       216337 :           auto c = (wi::one (GET_MODE_PRECISION (int_mode))
    4969       216337 :                     << UINTVAL (trueop1));
    4970       216337 :           rtx new_op1 = immed_wide_int_const (c, int_mode);
    4971       216337 :           return simplify_gen_binary (MULT, int_mode, op0, new_op1);
    4972       216337 :         }
    4973              : 
    4974              :       /* If we're shifting left a signed bitfield extraction and the
    4975              :          shift count + bitfield size is a natural integral mode and
    4976              :          the field starts at offset 0 (counting from the LSB), then
    4977              :          this can be simplified to a sign extension of a left shift.
    4978              : 
    4979              :          Some ISAs (RISC-V 64-bit) have inherent support for such
    4980              :          instructions and it's better for various optimizations to
    4981              :          express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT.  */
    4982     19783073 :       if (GET_CODE (op0) == SIGN_EXTRACT
    4983           26 :           && REG_P (XEXP (op0, 0))
    4984              :           /* The size of the bitfield, the location of the bitfield and
    4985              :              shift count must be CONST_INTs.  */
    4986           20 :           && CONST_INT_P (op1)
    4987           20 :           && CONST_INT_P (XEXP (op0, 1))
    4988           20 :           && CONST_INT_P (XEXP (op0, 2)))
    4989              :         {
    4990           20 :           int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
    4991           20 :           machine_mode smaller_mode;
    4992              :           /* Now we need to verify the size of the bitfield plus the shift
    4993              :              count is an integral mode and smaller than MODE.  This is
    4994              :              requirement for using SIGN_EXTEND.  We also need to verify the
    4995              :              field starts at bit location 0 and that the subreg lowpart also
    4996              :              starts at zero.  */
    4997           20 :           if (int_mode_for_size (size, size).exists (&smaller_mode)
    4998            1 :               && mode > smaller_mode
    4999           20 :               && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
    5000            1 :                   == UINTVAL (XEXP (op0, 2)))
    5001            1 :               && XEXP (op0, 2) == CONST0_RTX (mode))
    5002              :             {
    5003              :               /* Everything passed.  So we just need to get the subreg of the
    5004              :                  original input, shift it and sign extend the result.  */
    5005            1 :               rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
    5006            1 :               rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
    5007            1 :               return gen_rtx_SIGN_EXTEND (mode, x);
    5008              :             }
    5009              :         }
    5010     19783072 :       goto canonicalize_shift;
    5011              : 
    5012      8759306 :     case LSHIFTRT:
    5013      8759306 :       if (trueop1 == CONST0_RTX (mode))
    5014              :         return op0;
    5015      6973235 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    5016              :         return op0;
    5017              :       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
    5018      6971655 :       if (GET_CODE (op0) == CLZ
    5019            0 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    5020            0 :           && CONST_INT_P (trueop1)
    5021              :           && STORE_FLAG_VALUE == 1
    5022      6971655 :           && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
    5023              :         {
    5024            0 :           unsigned HOST_WIDE_INT zero_val = 0;
    5025              : 
    5026            0 :           if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
    5027            0 :               && zero_val == GET_MODE_PRECISION (inner_mode)
    5028            0 :               && INTVAL (trueop1) == exact_log2 (zero_val))
    5029            0 :             return simplify_gen_relational (EQ, mode, inner_mode,
    5030            0 :                                             XEXP (op0, 0), const0_rtx);
    5031              :         }
    5032      6971655 :       goto canonicalize_shift;
    5033              : 
    5034       228636 :     case SMIN:
    5035       228636 :       if (HWI_COMPUTABLE_MODE_P (mode)
    5036       207702 :           && mode_signbit_p (mode, trueop1)
    5037            0 :           && ! side_effects_p (op0))
    5038              :         return op1;
    5039       228636 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5040              :         return op0;
    5041       228458 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5042       228458 :       if (tem)
    5043              :         return tem;
    5044              :       break;
    5045              : 
    5046       716630 :     case SMAX:
    5047       716630 :       if (HWI_COMPUTABLE_MODE_P (mode)
    5048       688557 :           && CONST_INT_P (trueop1)
    5049       655034 :           && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
    5050            0 :           && ! side_effects_p (op0))
    5051              :         return op1;
    5052       716630 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5053              :         return op0;
    5054       716523 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5055       716523 :       if (tem)
    5056              :         return tem;
    5057              :       break;
    5058              : 
    5059       427944 :     case UMIN:
    5060       427944 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    5061              :         return op1;
    5062       427869 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5063              :         return op0;
    5064       427750 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5065       427750 :       if (tem)
    5066              :         return tem;
    5067              :       break;
    5068              : 
    5069       378810 :     case UMAX:
    5070       378810 :       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
    5071              :         return op1;
    5072       378810 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5073              :         return op0;
    5074       378720 :       tem = simplify_associative_operation (code, mode, op0, op1);
    5075       378720 :       if (tem)
    5076              :         return tem;
    5077              :       break;
    5078              : 
    5079        12130 :     case SS_PLUS:
    5080        12130 :     case US_PLUS:
    5081        12130 :     case SS_MINUS:
    5082        12130 :     case US_MINUS:
    5083              :       /* Simplify x +/- 0 to x, if possible.  */
    5084        12130 :       if (trueop1 == CONST0_RTX (mode))
    5085            0 :         return op0;
    5086              :       return 0;
    5087              : 
    5088            0 :     case SS_MULT:
    5089            0 :     case US_MULT:
    5090              :       /* Simplify x * 0 to 0, if possible.  */
    5091            0 :       if (trueop1 == CONST0_RTX (mode)
    5092            0 :           && !side_effects_p (op0))
    5093              :         return op1;
    5094              : 
    5095              :       /* Simplify x * 1 to x, if possible.  */
    5096            0 :       if (trueop1 == CONST1_RTX (mode))
    5097            0 :         return op0;
    5098              :       return 0;
    5099              : 
    5100       201164 :     case SMUL_HIGHPART:
    5101              :       /* Simplify x h* 0 to 0, if possible.  */
    5102       201164 :       if (trueop1 == CONST0_RTX (mode)
    5103       201164 :           && !side_effects_p (op0))
    5104              :         return op1;
    5105              :       /* Simplify x h* 1 to sign(x).  */
    5106       201164 :       if (trueop1 == const1_rtx
    5107       201164 :           && is_a <scalar_int_mode> (mode, &int_mode))
    5108              :         {
    5109            0 :           HOST_WIDE_INT bits = GET_MODE_PRECISION (int_mode) - 1;
    5110            0 :           return simplify_gen_binary (ASHIFTRT, mode, op0,
    5111            0 :                                       gen_int_shift_amount (mode, bits));
    5112              :         }
    5113              :       /* Simplify SMUL_HIGHPART by power of two as ASHIFRT.  */
    5114       201164 :       if (CONST_INT_P (trueop1)
    5115        89990 :           && INTVAL (trueop1) > 1
    5116       277830 :           && is_a <scalar_int_mode> (mode, &int_mode))
    5117              :         {
    5118        76666 :           HOST_WIDE_INT prec = GET_MODE_PRECISION (int_mode);
    5119        76666 :           val = wi::exact_log2 (INTVAL (trueop1));
    5120        76666 :           if (val > 0 && val < prec)
    5121            0 :             return simplify_gen_binary (ASHIFTRT, mode, op0,
    5122              :                                         gen_int_shift_amount (mode,
    5123            0 :                                                               prec - val));
    5124              :         }
    5125              :       return 0;
    5126              : 
    5127       309866 :     case UMUL_HIGHPART:
    5128              :       /* Simplify x h* 0 to 0, if possible.  */
    5129       309866 :       if (trueop1 == CONST0_RTX (mode)
    5130       309866 :           && !side_effects_p (op0))
    5131              :         return op1;
    5132              :       /* Simplify x h* 1 to 0.  */
    5133       309792 :       if (trueop1 == CONST1_RTX (mode)
    5134       309792 :           && !side_effects_p (op1))
    5135            0 :         return CONST0_RTX (mode);
    5136              :       /* Simplify UMUL_HIGHPART by power of two as LSHIFRT.  */
    5137       309792 :       if (CONST_INT_P (trueop1)
    5138       156098 :           && UINTVAL (trueop1) > 1
    5139       465890 :           && is_a <scalar_int_mode> (mode, &int_mode))
    5140              :         {
    5141       156098 :           HOST_WIDE_INT prec = GET_MODE_PRECISION (int_mode);
    5142       156098 :           val = wi::exact_log2 (UINTVAL (trueop1));
    5143       156098 :           if (val > 0 && val < prec)
    5144           58 :             return simplify_gen_binary (LSHIFTRT, mode, op0,
    5145              :                                         gen_int_shift_amount (mode,
    5146           58 :                                                               prec - val));
    5147              :         }
    5148              :       return 0;
    5149              : 
    5150            0 :     case SS_DIV:
    5151            0 :     case US_DIV:
    5152              :       /* Simplify x / 1 to x, if possible.  */
    5153            0 :       if (trueop1 == CONST1_RTX (mode))
    5154            0 :         return op0;
    5155              :       return 0;
    5156              : 
    5157            0 :     case COPYSIGN:
    5158            0 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    5159              :         return op0;
    5160            0 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5161              :         {
    5162            0 :           REAL_VALUE_TYPE f1;
    5163            0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
    5164            0 :           rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
    5165            0 :           if (REAL_VALUE_NEGATIVE (f1))
    5166            0 :             tmp = simplify_unary_operation (NEG, mode, tmp, mode);
    5167            0 :           return tmp;
    5168              :         }
    5169            0 :       if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
    5170            0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    5171            0 :       if (GET_CODE (op1) == ABS
    5172            0 :           && ! side_effects_p (op1))
    5173            0 :         return simplify_gen_unary (ABS, mode, op0, mode);
    5174            0 :       if (GET_CODE (op0) == COPYSIGN
    5175            0 :           && ! side_effects_p (XEXP (op0, 1)))
    5176            0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    5177            0 :       if (GET_CODE (op1) == COPYSIGN
    5178            0 :           && ! side_effects_p (XEXP (op1, 0)))
    5179            0 :         return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
    5180              :       return 0;
    5181              : 
    5182         1115 :     case VEC_SERIES:
    5183         2230 :       if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
    5184           92 :         return gen_vec_duplicate (mode, op0);
    5185         1023 :       if (valid_for_const_vector_p (mode, op0)
    5186         1023 :           && valid_for_const_vector_p (mode, op1))
    5187           93 :         return gen_const_vec_series (mode, op0, op1);
    5188              :       return 0;
    5189              : 
    5190      3748746 :     case VEC_SELECT:
    5191      3748746 :       if (!VECTOR_MODE_P (mode))
    5192              :         {
    5193       826211 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    5194      1652422 :           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
    5195       826211 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    5196       826211 :           gcc_assert (XVECLEN (trueop1, 0) == 1);
    5197              : 
    5198              :           /* We can't reason about selections made at runtime.  */
    5199       826211 :           if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5200    465407793 :             return 0;
    5201              : 
    5202       826211 :           if (vec_duplicate_p (trueop0, &elt0))
    5203         2020 :             return elt0;
    5204              : 
    5205       824191 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    5206         7345 :             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
    5207              :                                                       (trueop1, 0, 0)));
    5208              : 
    5209              :           /* Extract a scalar element from a nested VEC_SELECT expression
    5210              :              (with optional nested VEC_CONCAT expression).  Some targets
    5211              :              (i386) extract scalar element from a vector using chain of
    5212              :              nested VEC_SELECT expressions.  When input operand is a memory
    5213              :              operand, this operation can be simplified to a simple scalar
    5214              :              load from an offsetted memory address.  */
    5215       816846 :           int n_elts;
    5216       816846 :           if (GET_CODE (trueop0) == VEC_SELECT
    5217       889783 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5218        72937 :                   .is_constant (&n_elts)))
    5219              :             {
    5220        72937 :               rtx op0 = XEXP (trueop0, 0);
    5221        72937 :               rtx op1 = XEXP (trueop0, 1);
    5222              : 
    5223        72937 :               int i = INTVAL (XVECEXP (trueop1, 0, 0));
    5224        72937 :               int elem;
    5225              : 
    5226        72937 :               rtvec vec;
    5227        72937 :               rtx tmp_op, tmp;
    5228              : 
    5229        72937 :               gcc_assert (GET_CODE (op1) == PARALLEL);
    5230        72937 :               gcc_assert (i < XVECLEN (op1, 0));
    5231              : 
    5232              :               /* Select element, pointed by nested selector.  */
    5233        72937 :               elem = INTVAL (XVECEXP (op1, 0, i));
    5234              : 
    5235        72937 :               gcc_assert (elem < n_elts);
    5236              : 
    5237              :               /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
    5238        72937 :               if (GET_CODE (op0) == VEC_CONCAT)
    5239              :                 {
    5240        30068 :                   rtx op00 = XEXP (op0, 0);
    5241        30068 :                   rtx op01 = XEXP (op0, 1);
    5242              : 
    5243        30068 :                   machine_mode mode00, mode01;
    5244        30068 :                   int n_elts00, n_elts01;
    5245              : 
    5246        30068 :                   mode00 = GET_MODE (op00);
    5247        30068 :                   mode01 = GET_MODE (op01);
    5248              : 
    5249              :                   /* Find out the number of elements of each operand.
    5250              :                      Since the concatenated result has a constant number
    5251              :                      of elements, the operands must too.  */
    5252        30068 :                   n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
    5253        30068 :                   n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
    5254              : 
    5255        30068 :                   gcc_assert (n_elts == n_elts00 + n_elts01);
    5256              : 
    5257              :                   /* Select correct operand of VEC_CONCAT
    5258              :                      and adjust selector. */
    5259        30068 :                   if (elem < n_elts01)
    5260              :                     tmp_op = op00;
    5261              :                   else
    5262              :                     {
    5263           41 :                       tmp_op = op01;
    5264           41 :                       elem -= n_elts00;
    5265              :                     }
    5266              :                 }
    5267              :               else
    5268              :                 tmp_op = op0;
    5269              : 
    5270        72937 :               vec = rtvec_alloc (1);
    5271        72937 :               RTVEC_ELT (vec, 0) = GEN_INT (elem);
    5272              : 
    5273        72937 :               tmp = gen_rtx_fmt_ee (code, mode,
    5274              :                                     tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
    5275        72937 :               return tmp;
    5276              :             }
    5277              :           /* If we select one half of a vec_concat, return that.  */
    5278       743909 :           else if (GET_CODE (trueop0) == VEC_CONCAT)
    5279              :             {
    5280          725 :               rtx subop0 = XEXP (trueop0, 0);
    5281          725 :               rtx subop1 = XEXP (trueop0, 1);
    5282          725 :               machine_mode mode0 = GET_MODE (subop0);
    5283          725 :               machine_mode mode1 = GET_MODE (subop1);
    5284          725 :               int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5285          725 :               if (i0 == 0 && mode == mode0 && !side_effects_p (subop1))
    5286    465407793 :                 return subop0;
    5287          490 :               if (known_eq (i0, GET_MODE_NUNITS (mode0))
    5288          245 :                   && mode == mode1 && !side_effects_p (subop0))
    5289              :                 return subop1;
    5290              :             }
    5291              :         }
    5292              :       else
    5293              :         {
    5294      2922535 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    5295      8767605 :           gcc_assert (GET_MODE_INNER (mode)
    5296              :                       == GET_MODE_INNER (GET_MODE (trueop0)));
    5297      2922535 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    5298              : 
    5299      2922535 :           if (vec_duplicate_p (trueop0, &elt0))
    5300              :             /* It doesn't matter which elements are selected by trueop1,
    5301              :                because they are all the same.  */
    5302        17682 :             return gen_vec_duplicate (mode, elt0);
    5303              : 
    5304      2904853 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    5305              :             {
    5306        25922 :               unsigned n_elts = XVECLEN (trueop1, 0);
    5307        25922 :               rtvec v = rtvec_alloc (n_elts);
    5308        25922 :               unsigned int i;
    5309              : 
    5310        51844 :               gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
    5311       107420 :               for (i = 0; i < n_elts; i++)
    5312              :                 {
    5313        81498 :                   rtx x = XVECEXP (trueop1, 0, i);
    5314              : 
    5315        81498 :                   if (!CONST_INT_P (x))
    5316              :                     return 0;
    5317              : 
    5318        81498 :                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
    5319              :                                                        INTVAL (x));
    5320              :                 }
    5321              : 
    5322        25922 :               return gen_rtx_CONST_VECTOR (mode, v);
    5323              :             }
    5324              : 
    5325              :           /* Recognize the identity.  */
    5326      2878931 :           if (GET_MODE (trueop0) == mode)
    5327              :             {
    5328       618127 :               bool maybe_ident = true;
    5329       618127 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5330              :                 {
    5331       617730 :                   rtx j = XVECEXP (trueop1, 0, i);
    5332       617730 :                   if (!CONST_INT_P (j) || INTVAL (j) != i)
    5333              :                     {
    5334              :                       maybe_ident = false;
    5335              :                       break;
    5336              :                     }
    5337              :                 }
    5338       381872 :               if (maybe_ident)
    5339              :                 return trueop0;
    5340              :             }
    5341              : 
    5342              :           /* If we select a low-part subreg, return that.  */
    5343      2878534 :           if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
    5344              :             {
    5345            0 :               rtx new_rtx = lowpart_subreg (mode, trueop0,
    5346            0 :                                             GET_MODE (trueop0));
    5347            0 :               if (new_rtx != NULL_RTX)
    5348              :                 return new_rtx;
    5349              :             }
    5350              : 
    5351              :           /* If we build {a,b} then permute it, build the result directly.  */
    5352      2878534 :           if (XVECLEN (trueop1, 0) == 2
    5353       637569 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5354       637569 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    5355       637569 :               && GET_CODE (trueop0) == VEC_CONCAT
    5356       168114 :               && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
    5357           63 :               && GET_MODE (XEXP (trueop0, 0)) == mode
    5358           63 :               && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
    5359           52 :               && GET_MODE (XEXP (trueop0, 1)) == mode)
    5360              :             {
    5361           52 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5362           52 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5363           52 :               rtx subop0, subop1;
    5364              : 
    5365           52 :               gcc_assert (i0 < 4 && i1 < 4);
    5366           52 :               subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
    5367           52 :               subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
    5368              : 
    5369           52 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5370              :             }
    5371              : 
    5372      2878482 :           if (XVECLEN (trueop1, 0) == 2
    5373       637517 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5374       637517 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    5375       637517 :               && GET_CODE (trueop0) == VEC_CONCAT
    5376       168062 :               && GET_MODE (trueop0) == mode)
    5377              :             {
    5378            2 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5379            2 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5380            2 :               rtx subop0, subop1;
    5381              : 
    5382            2 :               gcc_assert (i0 < 2 && i1 < 2);
    5383            2 :               subop0 = XEXP (trueop0, i0);
    5384            2 :               subop1 = XEXP (trueop0, i1);
    5385              : 
    5386            2 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5387              :             }
    5388              : 
    5389              :           /* If we select one half of a vec_concat, return that.  */
    5390      2878480 :           int l0, l1;
    5391      2878480 :           if (GET_CODE (trueop0) == VEC_CONCAT
    5392      3740948 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5393      1870474 :                   .is_constant (&l0))
    5394      3740948 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
    5395      1870474 :                   .is_constant (&l1))
    5396      4748954 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5397              :             {
    5398      1870474 :               rtx subop0 = XEXP (trueop0, 0);
    5399      1870474 :               rtx subop1 = XEXP (trueop0, 1);
    5400      1870474 :               machine_mode mode0 = GET_MODE (subop0);
    5401      1870474 :               machine_mode mode1 = GET_MODE (subop1);
    5402      1870474 :               int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5403      1870474 :               if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
    5404              :                 {
    5405      1425708 :                   bool success = true;
    5406      1425708 :                   for (int i = 1; i < l0; ++i)
    5407              :                     {
    5408      1425382 :                       rtx j = XVECEXP (trueop1, 0, i);
    5409      1425382 :                       if (!CONST_INT_P (j) || INTVAL (j) != i)
    5410              :                         {
    5411              :                           success = false;
    5412              :                           break;
    5413              :                         }
    5414              :                     }
    5415      1211064 :                   if (success)
    5416              :                     return subop0;
    5417              :                 }
    5418      1870148 :               if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
    5419              :                 {
    5420         1234 :                   bool success = true;
    5421         1234 :                   for (int i = 1; i < l1; ++i)
    5422              :                     {
    5423         1187 :                       rtx j = XVECEXP (trueop1, 0, i);
    5424         1187 :                       if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
    5425              :                         {
    5426              :                           success = false;
    5427              :                           break;
    5428              :                         }
    5429              :                     }
    5430          560 :                   if (success)
    5431              :                     return subop1;
    5432              :                 }
    5433              :             }
    5434              : 
    5435              :           /* Simplify vec_select of a subreg of X to just a vec_select of X
    5436              :              when X has same component mode as vec_select.  */
    5437      2878107 :           unsigned HOST_WIDE_INT subreg_offset = 0;
    5438      2878107 :           if (GET_CODE (trueop0) == SUBREG
    5439       416018 :               && GET_MODE_INNER (mode)
    5440       832036 :                  == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
    5441        29894 :               && GET_MODE_NUNITS (mode).is_constant (&l1)
    5442      3294125 :               && constant_multiple_p (subreg_memory_offset (trueop0),
    5443        29894 :                                       GET_MODE_UNIT_BITSIZE (mode),
    5444              :                                       &subreg_offset))
    5445              :             {
    5446        14947 :               poly_uint64 nunits
    5447        29894 :                 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
    5448        14947 :               bool success = true;
    5449        91723 :               for (int i = 0; i != l1; i++)
    5450              :                 {
    5451        87125 :                   rtx idx = XVECEXP (trueop1, 0, i);
    5452        87125 :                   if (!CONST_INT_P (idx)
    5453        87125 :                       || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
    5454              :                     {
    5455              :                       success = false;
    5456              :                       break;
    5457              :                     }
    5458              :                 }
    5459              : 
    5460        14947 :               if (success)
    5461              :                 {
    5462         4598 :                   rtx par = trueop1;
    5463         4598 :                   if (subreg_offset)
    5464              :                     {
    5465            0 :                       rtvec vec = rtvec_alloc (l1);
    5466            0 :                       for (int i = 0; i < l1; i++)
    5467            0 :                         RTVEC_ELT (vec, i)
    5468            0 :                           = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
    5469              :                                      + subreg_offset);
    5470            0 :                       par = gen_rtx_PARALLEL (VOIDmode, vec);
    5471              :                     }
    5472         4598 :                   return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
    5473              :                 }
    5474              :             }
    5475              :         }
    5476              : 
    5477      3616878 :       if (XVECLEN (trueop1, 0) == 1
    5478       743453 :           && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5479       743453 :           && GET_CODE (trueop0) == VEC_CONCAT)
    5480              :         {
    5481          185 :           rtx vec = trueop0;
    5482          370 :           offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
    5483              : 
    5484              :           /* Try to find the element in the VEC_CONCAT.  */
    5485          185 :           while (GET_MODE (vec) != mode
    5486          370 :                  && GET_CODE (vec) == VEC_CONCAT)
    5487              :             {
    5488          185 :               poly_int64 vec_size;
    5489              : 
    5490          185 :               if (CONST_INT_P (XEXP (vec, 0)))
    5491              :                 {
    5492              :                   /* vec_concat of two const_ints doesn't make sense with
    5493              :                      respect to modes.  */
    5494            0 :                   if (CONST_INT_P (XEXP (vec, 1)))
    5495    465407793 :                     return 0;
    5496              : 
    5497            0 :                   vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
    5498            0 :                              - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
    5499              :                 }
    5500              :               else
    5501          370 :                 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
    5502              : 
    5503          185 :               if (known_lt (offset, vec_size))
    5504              :                 vec = XEXP (vec, 0);
    5505           15 :               else if (known_ge (offset, vec_size))
    5506              :                 {
    5507           15 :                   offset -= vec_size;
    5508           15 :                   vec = XEXP (vec, 1);
    5509              :                 }
    5510              :               else
    5511              :                 break;
    5512          185 :               vec = avoid_constant_pool_reference (vec);
    5513              :             }
    5514              : 
    5515          185 :           if (GET_MODE (vec) == mode)
    5516              :             return vec;
    5517              :         }
    5518              : 
    5519              :       /* If we select elements in a vec_merge that all come from the same
    5520              :          operand, select from that operand directly.  */
    5521      3616878 :       if (GET_CODE (op0) == VEC_MERGE)
    5522              :         {
    5523         9282 :           rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
    5524         9282 :           if (CONST_INT_P (trueop02))
    5525              :             {
    5526         2871 :               unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
    5527         2871 :               bool all_operand0 = true;
    5528         2871 :               bool all_operand1 = true;
    5529        10689 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5530              :                 {
    5531         7818 :                   rtx j = XVECEXP (trueop1, 0, i);
    5532         7818 :                   if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
    5533              :                     all_operand1 = false;
    5534              :                   else
    5535         3504 :                     all_operand0 = false;
    5536              :                 }
    5537         2871 :               if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
    5538         1340 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
    5539         1531 :               if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
    5540           55 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
    5541              :             }
    5542              :         }
    5543              : 
    5544              :       /* If we have two nested selects that are inverses of each
    5545              :          other, replace them with the source operand.  */
    5546      3615483 :       if (GET_CODE (trueop0) == VEC_SELECT
    5547        72502 :           && GET_MODE (XEXP (trueop0, 0)) == mode)
    5548              :         {
    5549         1048 :           rtx op0_subop1 = XEXP (trueop0, 1);
    5550         1048 :           gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
    5551         2096 :           gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
    5552              :           bool identical_p = true;
    5553              : 
    5554              :           /* Apply the outer ordering vector to the inner one.  (The inner
    5555              :              ordering vector is expressly permitted to be of a different
    5556              :              length than the outer one.)  If the result is { 0, 1, ..., n-1 }
    5557              :              then the two VEC_SELECTs cancel.  */
    5558         9068 :           for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
    5559              :             {
    5560         8020 :               rtx x = XVECEXP (trueop1, 0, i);
    5561         8020 :               if (!CONST_INT_P (x))
    5562              :                 return 0;
    5563         8020 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5564         8020 :               if (!CONST_INT_P (y))
    5565              :                 return 0;
    5566         8020 :               if (i != INTVAL (y))
    5567         5918 :                 identical_p = false;
    5568              :             }
    5569         1048 :           if (identical_p)
    5570              :             return XEXP (trueop0, 0);
    5571              : 
    5572              :           /* Otherwise a permutation of a permutation is a permutation.  */
    5573         1048 :           int len = XVECLEN (trueop1, 0);
    5574         1048 :           rtvec vec = rtvec_alloc (len);
    5575        10116 :           for (int i = 0; i < len; ++i)
    5576              :             {
    5577         8020 :               rtx x = XVECEXP (trueop1, 0, i);
    5578         8020 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5579         8020 :               RTVEC_ELT (vec, i) = y;
    5580              :             }
    5581         1048 :           return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
    5582              :                                  gen_rtx_PARALLEL (VOIDmode, vec));
    5583              :         }
    5584              : 
    5585              :       return 0;
    5586      4090776 :     case VEC_CONCAT:
    5587      4090776 :       {
    5588      4090776 :         machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
    5589      4090776 :                                       ? GET_MODE (trueop0)
    5590      4090776 :                                       : GET_MODE_INNER (mode));
    5591      4090776 :         machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
    5592      4090776 :                                       ? GET_MODE (trueop1)
    5593      4090776 :                                       : GET_MODE_INNER (mode));
    5594              : 
    5595      4090776 :         gcc_assert (VECTOR_MODE_P (mode));
    5596     16363104 :         gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
    5597              :                               + GET_MODE_SIZE (op1_mode),
    5598              :                               GET_MODE_SIZE (mode)));
    5599              : 
    5600      4090776 :         if (VECTOR_MODE_P (op0_mode))
    5601      6382827 :           gcc_assert (GET_MODE_INNER (mode)
    5602              :                       == GET_MODE_INNER (op0_mode));
    5603              :         else
    5604      3926334 :           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
    5605              : 
    5606      4090776 :         if (VECTOR_MODE_P (op1_mode))
    5607      6382827 :           gcc_assert (GET_MODE_INNER (mode)
    5608              :                       == GET_MODE_INNER (op1_mode));
    5609              :         else
    5610      3926334 :           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
    5611              : 
    5612      4090776 :         unsigned int n_elts, in_n_elts;
    5613      4090776 :         if ((GET_CODE (trueop0) == CONST_VECTOR
    5614      4090776 :              || CONST_SCALAR_INT_P (trueop0)
    5615      4064001 :              || CONST_DOUBLE_AS_FLOAT_P (trueop0))
    5616        28225 :             && (GET_CODE (trueop1) == CONST_VECTOR
    5617        28225 :                 || CONST_SCALAR_INT_P (trueop1)
    5618        28225 :                 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5619            0 :             && GET_MODE_NUNITS (mode).is_constant (&n_elts)
    5620      4090776 :             && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
    5621              :           {
    5622            0 :             rtvec v = rtvec_alloc (n_elts);
    5623            0 :             unsigned int i;
    5624            0 :             for (i = 0; i < n_elts; i++)
    5625              :               {
    5626            0 :                 if (i < in_n_elts)
    5627              :                   {
    5628            0 :                     if (!VECTOR_MODE_P (op0_mode))
    5629            0 :                       RTVEC_ELT (v, i) = trueop0;
    5630              :                     else
    5631            0 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
    5632              :                   }
    5633              :                 else
    5634              :                   {
    5635            0 :                     if (!VECTOR_MODE_P (op1_mode))
    5636            0 :                       RTVEC_ELT (v, i) = trueop1;
    5637              :                     else
    5638            0 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
    5639              :                                                            i - in_n_elts);
    5640              :                   }
    5641              :               }
    5642              : 
    5643            0 :             return gen_rtx_CONST_VECTOR (mode, v);
    5644              :           }
    5645              : 
    5646              :         /* Try to merge two VEC_SELECTs from the same vector into a single one.
    5647              :            Restrict the transformation to avoid generating a VEC_SELECT with a
    5648              :            mode unrelated to its operand.  */
    5649      4090776 :         if (GET_CODE (trueop0) == VEC_SELECT
    5650       180046 :             && GET_CODE (trueop1) == VEC_SELECT
    5651        36098 :             && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
    5652      4109406 :             && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
    5653        37260 :                == GET_MODE_INNER(mode))
    5654              :           {
    5655        18630 :             rtx par0 = XEXP (trueop0, 1);
    5656        18630 :             rtx par1 = XEXP (trueop1, 1);
    5657        18630 :             int len0 = XVECLEN (par0, 0);
    5658        18630 :             int len1 = XVECLEN (par1, 0);
    5659        18630 :             rtvec vec = rtvec_alloc (len0 + len1);
    5660       131358 :             for (int i = 0; i < len0; i++)
    5661        94098 :               RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
    5662       112728 :             for (int i = 0; i < len1; i++)
    5663        94098 :               RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
    5664        18630 :             return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
    5665        18630 :                                         gen_rtx_PARALLEL (VOIDmode, vec));
    5666              :           }
    5667              :         /* (vec_concat:N
    5668              :              (subreg:N/2 OP 0)
    5669              :              (subreg:N/2 OP N/2)) --> OP
    5670              :            i.e. where concatenating the first and second halves of the
    5671              :            same object OP.  */
    5672      4072146 :         {
    5673      4072146 :           poly_uint64 offset = 0u;
    5674      4072146 :           rtx base0 = get_ref_base_and_offset (trueop0, &offset);
    5675      4072146 :           if (known_eq (offset, 0u)
    5676     12214778 :               && known_eq (GET_MODE_SIZE (GET_MODE (base0)),
    5677              :                            GET_MODE_SIZE (mode)))
    5678              :             {
    5679        68034 :               rtx base1 = get_ref_base_and_offset (trueop1, &offset);
    5680        68034 :               if (rtx_equal_p (base0, base1)
    5681         1190 :                   && known_eq (offset, GET_MODE_SIZE (op0_mode))
    5682         1149 :                   && !side_effects_p (trueop0)
    5683        69183 :                   && !side_effects_p (trueop1))
    5684              :                 {
    5685         1149 :                   tem = rtl_hooks.gen_lowpart_no_emit (mode, base0);
    5686         1149 :                   if (tem)
    5687         1149 :                     return tem;
    5688              :                 }
    5689              :             }
    5690              :         }
    5691              :       }
    5692      4070997 :       return 0;
    5693              : 
    5694            0 :     default:
    5695            0 :       gcc_unreachable ();
    5696              :     }
    5697              : 
    5698    391467705 :   if (mode == GET_MODE (op0)
    5699    336248378 :       && mode == GET_MODE (op1)
    5700    106992271 :       && vec_duplicate_p (op0, &elt0)
    5701    391599251 :       && vec_duplicate_p (op1, &elt1))
    5702              :     {
    5703              :       /* Try applying the operator to ELT and see if that simplifies.
    5704              :          We can duplicate the result if so.
    5705              : 
    5706              :          The reason we don't use simplify_gen_binary is that it isn't
    5707              :          necessarily a win to convert things like:
    5708              : 
    5709              :            (plus:V (vec_duplicate:V (reg:S R1))
    5710              :                    (vec_duplicate:V (reg:S R2)))
    5711              : 
    5712              :          to:
    5713              : 
    5714              :            (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
    5715              : 
    5716              :          The first might be done entirely in vector registers while the
    5717              :          second might need a move between register files.  */
    5718          172 :       tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5719              :                                        elt0, elt1);
    5720           86 :       if (tem)
    5721            2 :         return gen_vec_duplicate (mode, tem);
    5722              :     }
    5723              : 
    5724              :   return 0;
    5725              : }
    5726              : 
    5727              : /* Return true if binary operation OP distributes over addition in operand
    5728              :    OPNO, with the other operand being held constant.  OPNO counts from 1.  */
    5729              : 
    5730              : static bool
    5731         8291 : distributes_over_addition_p (rtx_code op, int opno)
    5732              : {
    5733            0 :   switch (op)
    5734              :     {
    5735              :     case PLUS:
    5736              :     case MINUS:
    5737              :     case MULT:
    5738              :       return true;
    5739              : 
    5740            0 :     case ASHIFT:
    5741            0 :       return opno == 1;
    5742              : 
    5743            0 :     default:
    5744            0 :       return false;
    5745              :     }
    5746              : }
    5747              : 
    5748              : rtx
    5749    500019432 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
    5750              :                                  rtx op0, rtx op1)
    5751              : {
    5752    500019432 :   if (VECTOR_MODE_P (mode)
    5753     16009398 :       && code != VEC_CONCAT
    5754     11904102 :       && GET_CODE (op0) == CONST_VECTOR
    5755       196087 :       && GET_CODE (op1) == CONST_VECTOR)
    5756              :     {
    5757         9000 :       bool step_ok_p;
    5758         9000 :       if (CONST_VECTOR_STEPPED_P (op0)
    5759         9000 :           && CONST_VECTOR_STEPPED_P (op1))
    5760              :         /* We can operate directly on the encoding if:
    5761              : 
    5762              :               a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
    5763              :             implies
    5764              :               (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
    5765              : 
    5766              :            Addition and subtraction are the supported operators
    5767              :            for which this is true.  */
    5768          709 :         step_ok_p = (code == PLUS || code == MINUS);
    5769         8291 :       else if (CONST_VECTOR_STEPPED_P (op0))
    5770              :         /* We can operate directly on stepped encodings if:
    5771              : 
    5772              :              a3 - a2 == a2 - a1
    5773              :            implies:
    5774              :              (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
    5775              : 
    5776              :            which is true if (x -> x op c) distributes over addition.  */
    5777         1313 :         step_ok_p = distributes_over_addition_p (code, 1);
    5778              :       else
    5779              :         /* Similarly in reverse.  */
    5780         6978 :         step_ok_p = distributes_over_addition_p (code, 2);
    5781         9000 :       rtx_vector_builder builder;
    5782         9000 :       if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
    5783              :         return 0;
    5784              : 
    5785         9000 :       unsigned int count = builder.encoded_nelts ();
    5786        55219 :       for (unsigned int i = 0; i < count; i++)
    5787              :         {
    5788        92538 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5789              :                                              CONST_VECTOR_ELT (op0, i),
    5790        46269 :                                              CONST_VECTOR_ELT (op1, i));
    5791        46269 :           if (!x || !valid_for_const_vector_p (mode, x))
    5792           50 :             return 0;
    5793        46219 :           builder.quick_push (x);
    5794              :         }
    5795         8950 :       return builder.build ();
    5796         9000 :     }
    5797              : 
    5798    500010432 :   if (VECTOR_MODE_P (mode)
    5799     16000398 :       && code == VEC_CONCAT
    5800      4105296 :       && (CONST_SCALAR_INT_P (op0)
    5801      4084578 :           || CONST_FIXED_P (op0)
    5802      4084578 :           || CONST_DOUBLE_AS_FLOAT_P (op0)
    5803      4080753 :           || CONST_VECTOR_P (op0))
    5804        42745 :       && (CONST_SCALAR_INT_P (op1)
    5805        39442 :           || CONST_DOUBLE_AS_FLOAT_P (op1)
    5806        37067 :           || CONST_FIXED_P (op1)
    5807        37067 :           || CONST_VECTOR_P (op1)))
    5808              :     {
    5809              :       /* Both inputs have a constant number of elements, so the result
    5810              :          must too.  */
    5811        14520 :       unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
    5812        14520 :       rtvec v = rtvec_alloc (n_elts);
    5813              : 
    5814        14520 :       gcc_assert (n_elts >= 2);
    5815        14520 :       if (n_elts == 2)
    5816              :         {
    5817         5678 :           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
    5818         5678 :           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
    5819              : 
    5820         5678 :           RTVEC_ELT (v, 0) = op0;
    5821         5678 :           RTVEC_ELT (v, 1) = op1;
    5822              :         }
    5823              :       else
    5824              :         {
    5825         8842 :           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
    5826         8842 :           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
    5827         8842 :           unsigned i;
    5828              : 
    5829         8842 :           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
    5830         8842 :           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
    5831         8842 :           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
    5832              : 
    5833        53690 :           for (i = 0; i < op0_n_elts; ++i)
    5834        44848 :             RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
    5835        53882 :           for (i = 0; i < op1_n_elts; ++i)
    5836        45040 :             RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
    5837              :         }
    5838              : 
    5839        14520 :       return gen_rtx_CONST_VECTOR (mode, v);
    5840              :     }
    5841              : 
    5842    487379411 :   if (VECTOR_MODE_P (mode)
    5843     15985878 :       && GET_CODE (op0) == CONST_VECTOR
    5844       196447 :       && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
    5845    499995912 :       && (CONST_VECTOR_DUPLICATE_P (op0)
    5846       124714 :           || CONST_VECTOR_NUNITS (op0).is_constant ()))
    5847              :     {
    5848       124714 :       switch (code)
    5849              :         {
    5850       124714 :         case PLUS:
    5851       124714 :         case MINUS:
    5852       124714 :         case MULT:
    5853       124714 :         case DIV:
    5854       124714 :         case MOD:
    5855       124714 :         case UDIV:
    5856       124714 :         case UMOD:
    5857       124714 :         case AND:
    5858       124714 :         case IOR:
    5859       124714 :         case XOR:
    5860       124714 :         case SMIN:
    5861       124714 :         case SMAX:
    5862       124714 :         case UMIN:
    5863       124714 :         case UMAX:
    5864       124714 :         case LSHIFTRT:
    5865       124714 :         case ASHIFTRT:
    5866       124714 :         case ASHIFT:
    5867       124714 :         case ROTATE:
    5868       124714 :         case ROTATERT:
    5869       124714 :         case SS_PLUS:
    5870       124714 :         case US_PLUS:
    5871       124714 :         case SS_MINUS:
    5872       124714 :         case US_MINUS:
    5873       124714 :         case SS_ASHIFT:
    5874       124714 :         case US_ASHIFT:
    5875       124714 :         case COPYSIGN:
    5876       124714 :           break;
    5877              :         default:
    5878              :           return NULL_RTX;
    5879              :         }
    5880              : 
    5881       124714 :       unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
    5882       124714 :                                 ? CONST_VECTOR_NPATTERNS (op0)
    5883       132721 :                                 : CONST_VECTOR_NUNITS (op0).to_constant ());
    5884       124714 :       rtx_vector_builder builder (mode, npatterns, 1);
    5885       387309 :       for (unsigned i = 0; i < npatterns; i++)
    5886              :         {
    5887       275762 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5888       137881 :                                              CONST_VECTOR_ELT (op0, i), op1);
    5889       137881 :           if (!x || !valid_for_const_vector_p (mode, x))
    5890            0 :             return 0;
    5891       137881 :           builder.quick_push (x);
    5892              :         }
    5893       124714 :       return builder.build ();
    5894              :     }
    5895              : 
    5896    499871198 :   if (SCALAR_FLOAT_MODE_P (mode)
    5897      6486076 :       && CONST_DOUBLE_AS_FLOAT_P (op0)
    5898        80992 :       && CONST_DOUBLE_AS_FLOAT_P (op1)
    5899        11617 :       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
    5900              :     {
    5901        11617 :       if (code == AND
    5902              :           || code == IOR
    5903        11617 :           || code == XOR)
    5904              :         {
    5905         2538 :           long tmp0[4];
    5906         2538 :           long tmp1[4];
    5907         2538 :           REAL_VALUE_TYPE r;
    5908         2538 :           int i;
    5909              : 
    5910         2538 :           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
    5911         2538 :                           GET_MODE (op0));
    5912         2538 :           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
    5913         2538 :                           GET_MODE (op1));
    5914        12690 :           for (i = 0; i < 4; i++)
    5915              :             {
    5916        10152 :               switch (code)
    5917              :               {
    5918         5272 :               case AND:
    5919         5272 :                 tmp0[i] &= tmp1[i];
    5920         5272 :                 break;
    5921         2512 :               case IOR:
    5922         2512 :                 tmp0[i] |= tmp1[i];
    5923         2512 :                 break;
    5924         2368 :               case XOR:
    5925         2368 :                 tmp0[i] ^= tmp1[i];
    5926         2368 :                 break;
    5927              :               default:
    5928              :                 gcc_unreachable ();
    5929              :               }
    5930              :             }
    5931         2538 :            real_from_target (&r, tmp0, mode);
    5932         2538 :            return const_double_from_real_value (r, mode);
    5933              :         }
    5934         9079 :       else if (code == COPYSIGN)
    5935              :         {
    5936            0 :           REAL_VALUE_TYPE f0, f1;
    5937            0 :           real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
    5938            0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
    5939            0 :           real_copysign (&f0, &f1);
    5940            0 :           return const_double_from_real_value (f0, mode);
    5941              :         }
    5942              :       else
    5943              :         {
    5944         9079 :           REAL_VALUE_TYPE f0, f1, value, result;
    5945         9079 :           const REAL_VALUE_TYPE *opr0, *opr1;
    5946         9079 :           bool inexact;
    5947              : 
    5948         9079 :           opr0 = CONST_DOUBLE_REAL_VALUE (op0);
    5949         9079 :           opr1 = CONST_DOUBLE_REAL_VALUE (op1);
    5950              : 
    5951         9079 :           if (HONOR_SNANS (mode)
    5952         9079 :               && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
    5953          803 :                   || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
    5954              :             return 0;
    5955              : 
    5956         9069 :           real_convert (&f0, mode, opr0);
    5957         9069 :           real_convert (&f1, mode, opr1);
    5958              : 
    5959         9069 :           if (code == DIV
    5960         4158 :               && real_equal (&f1, &dconst0)
    5961        12709 :               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
    5962              :             return 0;
    5963              : 
    5964        27066 :           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5965         5343 :               && flag_trapping_math
    5966         5265 :               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
    5967              :             {
    5968            9 :               int s0 = REAL_VALUE_NEGATIVE (f0);
    5969            9 :               int s1 = REAL_VALUE_NEGATIVE (f1);
    5970              : 
    5971            9 :               switch (code)
    5972              :                 {
    5973            0 :                 case PLUS:
    5974              :                   /* Inf + -Inf = NaN plus exception.  */
    5975            0 :                   if (s0 != s1)
    5976              :                     return 0;
    5977              :                   break;
    5978            0 :                 case MINUS:
    5979              :                   /* Inf - Inf = NaN plus exception.  */
    5980            0 :                   if (s0 == s1)
    5981              :                     return 0;
    5982              :                   break;
    5983              :                 case DIV:
    5984              :                   /* Inf / Inf = NaN plus exception.  */
    5985              :                   return 0;
    5986              :                 default:
    5987              :                   break;
    5988              :                 }
    5989              :             }
    5990              : 
    5991         7938 :           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5992         1949 :               && flag_trapping_math
    5993         7325 :               && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
    5994         1893 :                   || (REAL_VALUE_ISINF (f1)
    5995           10 :                       && real_equal (&f0, &dconst0))))
    5996              :             /* Inf * 0 = NaN plus exception.  */
    5997              :             return 0;
    5998              : 
    5999         5406 :           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
    6000              :                                      &f0, &f1);
    6001         5406 :           real_convert (&result, mode, &value);
    6002              : 
    6003              :           /* Don't constant fold this floating point operation if
    6004              :              the result has overflowed and flag_trapping_math.  */
    6005              : 
    6006         5406 :           if (flag_trapping_math
    6007        20952 :               && MODE_HAS_INFINITIES (mode)
    6008         5238 :               && REAL_VALUE_ISINF (result)
    6009         1141 :               && !REAL_VALUE_ISINF (f0)
    6010         6533 :               && !REAL_VALUE_ISINF (f1))
    6011              :             /* Overflow plus exception.  */
    6012         1127 :             return 0;
    6013              : 
    6014              :           /* Don't constant fold this floating point operation if the
    6015              :              result may dependent upon the run-time rounding mode and
    6016              :              flag_rounding_math is set, or if GCC's software emulation
    6017              :              is unable to accurately represent the result.  */
    6018              : 
    6019         4279 :           if ((flag_rounding_math
    6020        27650 :                || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
    6021         4279 :               && (inexact || !real_identical (&result, &value)))
    6022              :             return NULL_RTX;
    6023              : 
    6024         3901 :           return const_double_from_real_value (result, mode);
    6025              :         }
    6026              :     }
    6027              : 
    6028              :   /* We can fold some multi-word operations.  */
    6029    499859581 :   scalar_int_mode int_mode;
    6030    499859581 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    6031    428067011 :       && CONST_SCALAR_INT_P (op0)
    6032     41551107 :       && CONST_SCALAR_INT_P (op1)
    6033     34459324 :       && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
    6034              :     {
    6035     34459324 :       wide_int result;
    6036     34459324 :       wi::overflow_type overflow;
    6037     34459324 :       rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
    6038     34459324 :       rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
    6039              : 
    6040              : #if TARGET_SUPPORTS_WIDE_INT == 0
    6041              :       /* This assert keeps the simplification from producing a result
    6042              :          that cannot be represented in a CONST_DOUBLE but a lot of
    6043              :          upstream callers expect that this function never fails to
    6044              :          simplify something and so you if you added this to the test
    6045              :          above the code would die later anyway.  If this assert
    6046              :          happens, you just need to make the port support wide int.  */
    6047              :       gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
    6048              : #endif
    6049     34459324 :       switch (code)
    6050              :         {
    6051      1097075 :         case MINUS:
    6052      1097075 :           result = wi::sub (pop0, pop1);
    6053      1097075 :           break;
    6054              : 
    6055     26953555 :         case PLUS:
    6056     26953555 :           result = wi::add (pop0, pop1);
    6057     26953555 :           break;
    6058              : 
    6059       320564 :         case MULT:
    6060       320564 :           result = wi::mul (pop0, pop1);
    6061       320564 :           break;
    6062              : 
    6063         9023 :         case DIV:
    6064         9023 :           result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
    6065         9023 :           if (overflow)
    6066              :             return NULL_RTX;
    6067              :           break;
    6068              : 
    6069         1195 :         case MOD:
    6070         1195 :           result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
    6071         1195 :           if (overflow)
    6072              :             return NULL_RTX;
    6073              :           break;
    6074              : 
    6075         6122 :         case UDIV:
    6076         6122 :           result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
    6077         6122 :           if (overflow)
    6078              :             return NULL_RTX;
    6079              :           break;
    6080              : 
    6081        16279 :         case UMOD:
    6082        16279 :           result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
    6083        16279 :           if (overflow)
    6084              :             return NULL_RTX;
    6085              :           break;
    6086              : 
    6087       787187 :         case AND:
    6088       787187 :           result = wi::bit_and (pop0, pop1);
    6089       787187 :           break;
    6090              : 
    6091       265381 :         case IOR:
    6092       265381 :           result = wi::bit_or (pop0, pop1);
    6093       265381 :           break;
    6094              : 
    6095        44960 :         case XOR:
    6096        44960 :           result = wi::bit_xor (pop0, pop1);
    6097        44960 :           break;
    6098              : 
    6099         1763 :         case SMIN:
    6100         1763 :           result = wi::smin (pop0, pop1);
    6101         1763 :           break;
    6102              : 
    6103         1988 :         case SMAX:
    6104         1988 :           result = wi::smax (pop0, pop1);
    6105         1988 :           break;
    6106              : 
    6107         3219 :         case UMIN:
    6108         3219 :           result = wi::umin (pop0, pop1);
    6109         3219 :           break;
    6110              : 
    6111         2998 :         case UMAX:
    6112         2998 :           result = wi::umax (pop0, pop1);
    6113         2998 :           break;
    6114              : 
    6115      4907304 :         case LSHIFTRT:
    6116      4907304 :         case ASHIFTRT:
    6117      4907304 :         case ASHIFT:
    6118      4907304 :         case SS_ASHIFT:
    6119      4907304 :         case US_ASHIFT:
    6120      4907304 :           {
    6121              :             /* The shift count might be in SImode while int_mode might
    6122              :                be narrower.  On IA-64 it is even DImode.  If the shift
    6123              :                count is too large and doesn't fit into int_mode, we'd
    6124              :                ICE.  So, if int_mode is narrower than
    6125              :                HOST_BITS_PER_WIDE_INT, use DImode for the shift count.  */
    6126      4907304 :             if (GET_MODE (op1) == VOIDmode
    6127      4907304 :                 && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
    6128      1870276 :               pop1 = rtx_mode_t (op1, DImode);
    6129              : 
    6130      4907304 :             wide_int wop1 = pop1;
    6131      4907304 :             if (SHIFT_COUNT_TRUNCATED)
    6132              :               wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
    6133      4907304 :             else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
    6134           64 :               return NULL_RTX;
    6135              : 
    6136      4907240 :             switch (code)
    6137              :               {
    6138      2767474 :               case LSHIFTRT:
    6139      2767474 :                 result = wi::lrshift (pop0, wop1);
    6140      2767474 :                 break;
    6141              : 
    6142        82614 :               case ASHIFTRT:
    6143        82614 :                 result = wi::arshift (pop0, wop1);
    6144        82614 :                 break;
    6145              : 
    6146      2057152 :               case ASHIFT:
    6147      2057152 :                 result = wi::lshift (pop0, wop1);
    6148      2057152 :                 break;
    6149              : 
    6150            0 :               case SS_ASHIFT:
    6151            0 :                 if (wi::leu_p (wop1, wi::clrsb (pop0)))
    6152            0 :                   result = wi::lshift (pop0, wop1);
    6153            0 :                 else if (wi::neg_p (pop0))
    6154            0 :                   result = wi::min_value (int_mode, SIGNED);
    6155              :                 else
    6156            0 :                   result = wi::max_value (int_mode, SIGNED);
    6157              :                 break;
    6158              : 
    6159            0 :               case US_ASHIFT:
    6160            0 :                 if (wi::eq_p (pop0, 0))
    6161            0 :                   result = pop0;
    6162            0 :                 else if (wi::leu_p (wop1, wi::clz (pop0)))
    6163            0 :                   result = wi::lshift (pop0, wop1);
    6164              :                 else
    6165            0 :                   result = wi::max_value (int_mode, UNSIGNED);
    6166              :                 break;
    6167              : 
    6168              :               default:
    6169              :                 gcc_unreachable ();
    6170              :               }
    6171      4907240 :             break;
    6172      4907304 :           }
    6173        31429 :         case ROTATE:
    6174        31429 :         case ROTATERT:
    6175        31429 :           {
    6176              :             /* The rotate count might be in SImode while int_mode might
    6177              :                be narrower.  On IA-64 it is even DImode.  If the shift
    6178              :                count is too large and doesn't fit into int_mode, we'd
    6179              :                ICE.  So, if int_mode is narrower than
    6180              :                HOST_BITS_PER_WIDE_INT, use DImode for the shift count.  */
    6181        31429 :             if (GET_MODE (op1) == VOIDmode
    6182        31429 :                 && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
    6183        23759 :               pop1 = rtx_mode_t (op1, DImode);
    6184              : 
    6185        31429 :             if (wi::neg_p (pop1))
    6186              :               return NULL_RTX;
    6187              : 
    6188        31329 :             switch (code)
    6189              :               {
    6190        10361 :               case ROTATE:
    6191        10361 :                 result = wi::lrotate (pop0, pop1);
    6192        10361 :                 break;
    6193              : 
    6194        20968 :               case ROTATERT:
    6195        20968 :                 result = wi::rrotate (pop0, pop1);
    6196        20968 :                 break;
    6197              : 
    6198              :               default:
    6199              :                 gcc_unreachable ();
    6200              :               }
    6201              :             break;
    6202              :           }
    6203              : 
    6204         2438 :         case SS_PLUS:
    6205         2438 :           result = wi::add (pop0, pop1, SIGNED, &overflow);
    6206         4820 :  clamp_signed_saturation:
    6207         4820 :           if (overflow == wi::OVF_OVERFLOW)
    6208          314 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
    6209         4506 :           else if (overflow == wi::OVF_UNDERFLOW)
    6210          278 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
    6211         4228 :           else if (overflow != wi::OVF_NONE)
    6212              :             return NULL_RTX;
    6213              :           break;
    6214              : 
    6215         2388 :         case US_PLUS:
    6216         2388 :           result = wi::add (pop0, pop1, UNSIGNED, &overflow);
    6217         2388 :  clamp_unsigned_saturation:
    6218         2388 :           if (overflow != wi::OVF_NONE)
    6219          502 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    6220              :           break;
    6221              : 
    6222         2382 :         case SS_MINUS:
    6223         2382 :           result = wi::sub (pop0, pop1, SIGNED, &overflow);
    6224         2382 :           goto clamp_signed_saturation;
    6225              : 
    6226         2068 :         case US_MINUS:
    6227         2068 :           result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
    6228         2068 :           if (overflow != wi::OVF_NONE)
    6229         1350 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    6230              :           break;
    6231              : 
    6232            0 :         case SS_MULT:
    6233            0 :           result = wi::mul (pop0, pop1, SIGNED, &overflow);
    6234            0 :           goto clamp_signed_saturation;
    6235              : 
    6236            0 :         case US_MULT:
    6237            0 :           result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
    6238            0 :           goto clamp_unsigned_saturation;
    6239              : 
    6240            6 :         case SMUL_HIGHPART:
    6241            6 :           result = wi::mul_high (pop0, pop1, SIGNED);
    6242            6 :           break;
    6243              : 
    6244            0 :         case UMUL_HIGHPART:
    6245            0 :           result = wi::mul_high (pop0, pop1, UNSIGNED);
    6246            0 :           break;
    6247              : 
    6248              :         default:
    6249              :           return NULL_RTX;
    6250              :         }
    6251     34457016 :       return immed_wide_int_const (result, int_mode);
    6252     34459324 :     }
    6253              : 
    6254              :   /* Handle polynomial integers.  */
    6255              :   if (NUM_POLY_INT_COEFFS > 1
    6256              :       && is_a <scalar_int_mode> (mode, &int_mode)
    6257              :       && poly_int_rtx_p (op0)
    6258              :       && poly_int_rtx_p (op1))
    6259              :     {
    6260              :       poly_wide_int result;
    6261              :       switch (code)
    6262              :         {
    6263              :         case PLUS:
    6264              :           result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
    6265              :           break;
    6266              : 
    6267              :         case MINUS:
    6268              :           result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
    6269              :           break;
    6270              : 
    6271              :         case MULT:
    6272              :           if (CONST_SCALAR_INT_P (op1))
    6273              :             result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
    6274              :           else
    6275              :             return NULL_RTX;
    6276              :           break;
    6277              : 
    6278              :         case ASHIFT:
    6279              :           if (CONST_SCALAR_INT_P (op1))
    6280              :             {
    6281              :               wide_int shift
    6282              :                 = rtx_mode_t (op1,
    6283              :                               GET_MODE (op1) == VOIDmode
    6284              :                               && (GET_MODE_PRECISION (int_mode)
    6285              :                                   < HOST_BITS_PER_WIDE_INT)
    6286              :                               ? DImode : mode);
    6287              :               if (SHIFT_COUNT_TRUNCATED)
    6288              :                 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
    6289              :               else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
    6290              :                 return NULL_RTX;
    6291              :               result = wi::to_poly_wide (op0, mode) << shift;
    6292              :             }
    6293              :           else
    6294              :             return NULL_RTX;
    6295              :           break;
    6296              : 
    6297              :         case IOR:
    6298              :           if (!CONST_SCALAR_INT_P (op1)
    6299              :               || !can_ior_p (wi::to_poly_wide (op0, mode),
    6300              :                              rtx_mode_t (op1, mode), &result))
    6301              :             return NULL_RTX;
    6302              :           break;
    6303              : 
    6304              :         default:
    6305              :           return NULL_RTX;
    6306              :         }
    6307              :       return immed_wide_int_const (result, int_mode);
    6308              :     }
    6309              : 
    6310              :   return NULL_RTX;
    6311              : }
    6312              : 
    6313              : 
    6314              : 
    6315              : /* Return a positive integer if X should sort after Y.  The value
    6316              :    returned is 1 if and only if X and Y are both regs.  */
    6317              : 
    6318              : static int
    6319    118636318 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
    6320              : {
    6321    118636318 :   int result;
    6322              : 
    6323    118636318 :   result = (commutative_operand_precedence (y)
    6324    118636318 :             - commutative_operand_precedence (x));
    6325    118636318 :   if (result)
    6326     82390365 :     return result + result;
    6327              : 
    6328              :   /* Group together equal REGs to do more simplification.  */
    6329     36245953 :   if (REG_P (x) && REG_P (y))
    6330      9240836 :     return REGNO (x) > REGNO (y);
    6331              : 
    6332              :   return 0;
    6333              : }
    6334              : 
    6335              : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
    6336              :    operands may be another PLUS or MINUS.
    6337              : 
    6338              :    Rather than test for specific case, we do this by a brute-force method
    6339              :    and do all possible simplifications until no more changes occur.  Then
    6340              :    we rebuild the operation.
    6341              : 
    6342              :    May return NULL_RTX when no changes were made.  */
    6343              : 
    6344              : rtx
    6345     39975008 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
    6346              :                                        rtx op0, rtx op1)
    6347              : {
    6348     39975008 :   struct simplify_plus_minus_op_data
    6349              :   {
    6350              :     rtx op;
    6351              :     short neg;
    6352              :   } ops[16];
    6353     39975008 :   rtx result, tem;
    6354     39975008 :   int n_ops = 2;
    6355     39975008 :   int changed, n_constants, canonicalized = 0;
    6356     39975008 :   int i, j;
    6357              : 
    6358     39975008 :   memset (ops, 0, sizeof ops);
    6359              : 
    6360              :   /* Set up the two operands and then expand them until nothing has been
    6361              :      changed.  If we run out of room in our array, give up; this should
    6362              :      almost never happen.  */
    6363              : 
    6364     39975008 :   ops[0].op = op0;
    6365     39975008 :   ops[0].neg = 0;
    6366     39975008 :   ops[1].op = op1;
    6367     39975008 :   ops[1].neg = (code == MINUS);
    6368              : 
    6369     81280886 :   do
    6370              :     {
    6371     81280886 :       changed = 0;
    6372     81280886 :       n_constants = 0;
    6373              : 
    6374    328982837 :       for (i = 0; i < n_ops; i++)
    6375              :         {
    6376    247701967 :           rtx this_op = ops[i].op;
    6377    247701967 :           int this_neg = ops[i].neg;
    6378    247701967 :           enum rtx_code this_code = GET_CODE (this_op);
    6379              : 
    6380    247701967 :           switch (this_code)
    6381              :             {
    6382     40315282 :             case PLUS:
    6383     40315282 :             case MINUS:
    6384     40315282 :               if (n_ops == ARRAY_SIZE (ops))
    6385              :                 return NULL_RTX;
    6386              : 
    6387     40315266 :               ops[n_ops].op = XEXP (this_op, 1);
    6388     40315266 :               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
    6389     40315266 :               n_ops++;
    6390              : 
    6391     40315266 :               ops[i].op = XEXP (this_op, 0);
    6392     40315266 :               changed = 1;
    6393              :               /* If this operand was negated then we will potentially
    6394              :                  canonicalize the expression.  Similarly if we don't
    6395              :                  place the operands adjacent we're re-ordering the
    6396              :                  expression and thus might be performing a
    6397              :                  canonicalization.  Ignore register re-ordering.
    6398              :                  ??? It might be better to shuffle the ops array here,
    6399              :                  but then (plus (plus (A, B), plus (C, D))) wouldn't
    6400              :                  be seen as non-canonical.  */
    6401     40315266 :               if (this_neg
    6402     39613358 :                   || (i != n_ops - 2
    6403     39001802 :                       && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
    6404    247701951 :                 canonicalized = 1;
    6405              :               break;
    6406              : 
    6407         2062 :             case NEG:
    6408         2062 :               ops[i].op = XEXP (this_op, 0);
    6409         2062 :               ops[i].neg = ! this_neg;
    6410         2062 :               changed = 1;
    6411         2062 :               canonicalized = 1;
    6412         2062 :               break;
    6413              : 
    6414      1608000 :             case CONST:
    6415      1608000 :               if (n_ops != ARRAY_SIZE (ops)
    6416      1608000 :                   && GET_CODE (XEXP (this_op, 0)) == PLUS
    6417      1474394 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
    6418      1453656 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
    6419              :                 {
    6420      1453656 :                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
    6421      1453656 :                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
    6422      1453656 :                   ops[n_ops].neg = this_neg;
    6423      1453656 :                   n_ops++;
    6424      1453656 :                   changed = 1;
    6425      1453656 :                   canonicalized = 1;
    6426              :                 }
    6427              :               break;
    6428              : 
    6429        68873 :             case NOT:
    6430              :               /* ~a -> (-a - 1) */
    6431        68873 :               if (n_ops != ARRAY_SIZE (ops))
    6432              :                 {
    6433        68873 :                   ops[n_ops].op = CONSTM1_RTX (mode);
    6434        68873 :                   ops[n_ops++].neg = this_neg;
    6435        68873 :                   ops[i].op = XEXP (this_op, 0);
    6436        68873 :                   ops[i].neg = !this_neg;
    6437        68873 :                   changed = 1;
    6438        68873 :                   canonicalized = 1;
    6439              :                 }
    6440              :               break;
    6441              : 
    6442    123255868 :             CASE_CONST_SCALAR_INT:
    6443    123255868 :             case CONST_POLY_INT:
    6444    123255868 :               n_constants++;
    6445    123255868 :               if (this_neg)
    6446              :                 {
    6447      1210568 :                   ops[i].op = neg_poly_int_rtx (mode, this_op);
    6448      1210568 :                   ops[i].neg = 0;
    6449      1210568 :                   changed = 1;
    6450      1210568 :                   canonicalized = 1;
    6451              :                 }
    6452              :               break;
    6453              : 
    6454              :             default:
    6455              :               break;
    6456              :             }
    6457              :         }
    6458              :     }
    6459     81280870 :   while (changed);
    6460              : 
    6461     39974992 :   if (n_constants > 1)
    6462     24458550 :     canonicalized = 1;
    6463              : 
    6464     39974992 :   gcc_assert (n_ops >= 2);
    6465              : 
    6466              :   /* If we only have two operands, we can avoid the loops.  */
    6467     39974992 :   if (n_ops == 2)
    6468              :     {
    6469            0 :       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
    6470            0 :       rtx lhs, rhs;
    6471              : 
    6472              :       /* Get the two operands.  Be careful with the order, especially for
    6473              :          the cases where code == MINUS.  */
    6474            0 :       if (ops[0].neg && ops[1].neg)
    6475              :         {
    6476            0 :           lhs = gen_rtx_NEG (mode, ops[0].op);
    6477            0 :           rhs = ops[1].op;
    6478              :         }
    6479            0 :       else if (ops[0].neg)
    6480              :         {
    6481            0 :           lhs = ops[1].op;
    6482            0 :           rhs = ops[0].op;
    6483              :         }
    6484              :       else
    6485              :         {
    6486            0 :           lhs = ops[0].op;
    6487            0 :           rhs = ops[1].op;
    6488              :         }
    6489              : 
    6490            0 :       return simplify_const_binary_operation (code, mode, lhs, rhs);
    6491              :     }
    6492              : 
    6493              :   /* Now simplify each pair of operands until nothing changes.  */
    6494     65441938 :   while (1)
    6495              :     {
    6496              :       /* Insertion sort is good enough for a small array.  */
    6497    173176274 :       for (i = 1; i < n_ops; i++)
    6498              :         {
    6499    107734336 :           struct simplify_plus_minus_op_data save;
    6500    107734336 :           int cmp;
    6501              : 
    6502    107734336 :           j = i - 1;
    6503    107734336 :           cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
    6504    107734336 :           if (cmp <= 0)
    6505     94670332 :             continue;
    6506              :           /* Just swapping registers doesn't count as canonicalization.  */
    6507     13064004 :           if (cmp != 1)
    6508      9870218 :             canonicalized = 1;
    6509              : 
    6510     13064004 :           save = ops[i];
    6511     15529985 :           do
    6512     15529985 :             ops[j + 1] = ops[j];
    6513     15529985 :           while (j--
    6514     28593989 :                  && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
    6515     13064004 :           ops[j + 1] = save;
    6516              :         }
    6517              : 
    6518     65441938 :       changed = 0;
    6519    173176274 :       for (i = n_ops - 1; i > 0; i--)
    6520    258486103 :         for (j = i - 1; j >= 0; j--)
    6521              :           {
    6522    151647734 :             rtx lhs = ops[j].op, rhs = ops[i].op;
    6523    151647734 :             int lneg = ops[j].neg, rneg = ops[i].neg;
    6524              : 
    6525    151647734 :             if (lhs != 0 && rhs != 0)
    6526              :               {
    6527    125436663 :                 enum rtx_code ncode = PLUS;
    6528              : 
    6529    125436663 :                 if (lneg != rneg)
    6530              :                   {
    6531     11792820 :                     ncode = MINUS;
    6532     11792820 :                     if (lneg)
    6533      7429407 :                       std::swap (lhs, rhs);
    6534              :                   }
    6535    113643843 :                 else if (swap_commutative_operands_p (lhs, rhs))
    6536       423249 :                   std::swap (lhs, rhs);
    6537              : 
    6538    125436663 :                 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
    6539     29470933 :                     && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
    6540              :                   {
    6541     24614046 :                     rtx tem_lhs, tem_rhs;
    6542              : 
    6543     24614046 :                     tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
    6544     24614046 :                     tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
    6545     24614046 :                     tem = simplify_binary_operation (ncode, mode, tem_lhs,
    6546              :                                                      tem_rhs);
    6547              : 
    6548     24614046 :                     if (tem && !CONSTANT_P (tem))
    6549         1751 :                       tem = gen_rtx_CONST (GET_MODE (tem), tem);
    6550              :                   }
    6551              :                 else
    6552    100822617 :                   tem = simplify_binary_operation (ncode, mode, lhs, rhs);
    6553              : 
    6554    100824368 :                 if (tem)
    6555              :                   {
    6556              :                     /* Reject "simplifications" that just wrap the two
    6557              :                        arguments in a CONST.  Failure to do so can result
    6558              :                        in infinite recursion with simplify_binary_operation
    6559              :                        when it calls us to simplify CONST operations.
    6560              :                        Also, if we find such a simplification, don't try
    6561              :                        any more combinations with this rhs:  We must have
    6562              :                        something like symbol+offset, ie. one of the
    6563              :                        trivial CONST expressions we handle later.  */
    6564     26794236 :                     if (GET_CODE (tem) == CONST
    6565       897718 :                         && GET_CODE (XEXP (tem, 0)) == ncode
    6566       897167 :                         && XEXP (XEXP (tem, 0), 0) == lhs
    6567       895967 :                         && XEXP (XEXP (tem, 0), 1) == rhs)
    6568              :                       break;
    6569     25898269 :                     lneg &= rneg;
    6570     25898269 :                     if (GET_CODE (tem) == NEG)
    6571        45048 :                       tem = XEXP (tem, 0), lneg = !lneg;
    6572     25898269 :                     if (poly_int_rtx_p (tem) && lneg)
    6573            0 :                       tem = neg_poly_int_rtx (mode, tem), lneg = 0;
    6574              : 
    6575     25898269 :                     ops[i].op = tem;
    6576     25898269 :                     ops[i].neg = lneg;
    6577     25898269 :                     ops[j].op = NULL_RTX;
    6578     25898269 :                     changed = 1;
    6579     25898269 :                     canonicalized = 1;
    6580              :                   }
    6581              :               }
    6582              :           }
    6583              : 
    6584     65441938 :       if (!changed)
    6585              :         break;
    6586              : 
    6587              :       /* Pack all the operands to the lower-numbered entries.  */
    6588    102753934 :       for (i = 0, j = 0; j < n_ops; j++)
    6589     77286988 :         if (ops[j].op)
    6590              :           {
    6591     51388719 :             ops[i] = ops[j];
    6592     51388719 :             i++;
    6593              :           }
    6594              :       n_ops = i;
    6595              :     }
    6596              : 
    6597              :   /* If nothing changed, check that rematerialization of rtl instructions
    6598              :      is still required.  */
    6599     39974992 :   if (!canonicalized)
    6600              :     {
    6601              :       /* Perform rematerialization if only all operands are registers and
    6602              :          all operations are PLUS.  */
    6603              :       /* ??? Also disallow (non-global, non-frame) fixed registers to work
    6604              :          around rs6000 and how it uses the CA register.  See PR67145.  */
    6605      5447919 :       for (i = 0; i < n_ops; i++)
    6606      4364530 :         if (ops[i].neg
    6607      4078429 :             || !REG_P (ops[i].op)
    6608      7935143 :             || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
    6609       339536 :                 && fixed_regs[REGNO (ops[i].op)]
    6610          235 :                 && !global_regs[REGNO (ops[i].op)]
    6611          235 :                 && ops[i].op != frame_pointer_rtx
    6612          109 :                 && ops[i].op != arg_pointer_rtx
    6613          100 :                 && ops[i].op != stack_pointer_rtx))
    6614              :           return NULL_RTX;
    6615      1083389 :       goto gen_result;
    6616              :     }
    6617              : 
    6618              :   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
    6619     38097686 :   if (n_ops == 2
    6620     23879936 :       && CONST_INT_P (ops[1].op)
    6621     23216330 :       && CONSTANT_P (ops[0].op)
    6622          164 :       && ops[0].neg)
    6623           58 :     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
    6624              : 
    6625              :   /* We suppressed creation of trivial CONST expressions in the
    6626              :      combination loop to avoid recursion.  Create one manually now.
    6627              :      The combination loop should have ensured that there is exactly
    6628              :      one CONST_INT, and the sort will have ensured that it is last
    6629              :      in the array and that any other constant will be next-to-last.  */
    6630              : 
    6631     38097628 :   if (n_ops > 1
    6632     37596001 :       && poly_int_rtx_p (ops[n_ops - 1].op)
    6633     72932867 :       && CONSTANT_P (ops[n_ops - 2].op))
    6634              :     {
    6635      1529191 :       rtx value = ops[n_ops - 1].op;
    6636      1529191 :       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
    6637       711777 :         value = neg_poly_int_rtx (mode, value);
    6638      1529191 :       if (CONST_INT_P (value))
    6639              :         {
    6640      3058382 :           ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
    6641      1529191 :                                              INTVAL (value));
    6642      1529191 :           n_ops--;
    6643              :         }
    6644              :     }
    6645              : 
    6646              :   /* Put a non-negated operand first, if possible.  */
    6647              : 
    6648     39845372 :   for (i = 0; i < n_ops && ops[i].neg; i++)
    6649      1747744 :     continue;
    6650     38097628 :   if (i == n_ops)
    6651        10237 :     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
    6652     38087391 :   else if (i != 0)
    6653              :     {
    6654      1640585 :       tem = ops[0].op;
    6655      1640585 :       ops[0] = ops[i];
    6656      1640585 :       ops[i].op = tem;
    6657      1640585 :       ops[i].neg = 1;
    6658              :     }
    6659              : 
    6660              :   /* Now make the result by performing the requested operations.  */
    6661     36446806 :  gen_result:
    6662     39181017 :   result = ops[0].op;
    6663     91969531 :   for (i = 1; i < n_ops; i++)
    6664    105577028 :     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
    6665              :                              mode, result, ops[i].op);
    6666              : 
    6667              :   return result;
    6668      1747744 : }
    6669              : 
    6670              : /* Check whether an operand is suitable for calling simplify_plus_minus.  */
    6671              : static bool
    6672    546250907 : plus_minus_operand_p (const_rtx x)
    6673              : {
    6674    546250907 :   return GET_CODE (x) == PLUS
    6675    546250907 :          || GET_CODE (x) == MINUS
    6676    546250907 :          || (GET_CODE (x) == CONST
    6677      1970997 :              && GET_CODE (XEXP (x, 0)) == PLUS
    6678      1346963 :              && CONSTANT_P (XEXP (XEXP (x, 0), 0))
    6679      1273809 :              && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
    6680              : }
    6681              : 
    6682              : /* Like simplify_binary_operation except used for relational operators.
    6683              :    MODE is the mode of the result. If MODE is VOIDmode, both operands must
    6684              :    not also be VOIDmode.
    6685              : 
    6686              :    CMP_MODE specifies in which mode the comparison is done in, so it is
    6687              :    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
    6688              :    the operands or, if both are VOIDmode, the operands are compared in
    6689              :    "infinite precision".  */
    6690              : rtx
    6691    134523356 : simplify_context::simplify_relational_operation (rtx_code code,
    6692              :                                                  machine_mode mode,
    6693              :                                                  machine_mode cmp_mode,
    6694              :                                                  rtx op0, rtx op1)
    6695              : {
    6696    134523356 :   rtx tem, trueop0, trueop1;
    6697              : 
    6698    134523356 :   if (cmp_mode == VOIDmode)
    6699     29876666 :     cmp_mode = GET_MODE (op0);
    6700     29876666 :   if (cmp_mode == VOIDmode)
    6701       255442 :     cmp_mode = GET_MODE (op1);
    6702              : 
    6703    134523356 :   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
    6704    134523356 :   if (tem)
    6705       785045 :     return relational_result (mode, cmp_mode, tem);
    6706              : 
    6707              :   /* For the following tests, ensure const0_rtx is op1.  */
    6708    133738311 :   if (swap_commutative_operands_p (op0, op1)
    6709    133738311 :       || (op0 == const0_rtx && op1 != const0_rtx))
    6710      2650913 :     std::swap (op0, op1), code = swap_condition (code);
    6711              : 
    6712              :   /* If op0 is a compare, extract the comparison arguments from it.  */
    6713    133738311 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    6714     14900065 :     return simplify_gen_relational (code, mode, VOIDmode,
    6715     14900065 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6716              : 
    6717    118838246 :   if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    6718              :     return NULL_RTX;
    6719              : 
    6720     87584844 :   trueop0 = avoid_constant_pool_reference (op0);
    6721     87584844 :   trueop1 = avoid_constant_pool_reference (op1);
    6722     87584844 :   return simplify_relational_operation_1 (code, mode, cmp_mode,
    6723     87584844 :                                           trueop0, trueop1);
    6724              : }
    6725              : 
    6726              : /* This part of simplify_relational_operation is only used when CMP_MODE
    6727              :    is not in class MODE_CC (i.e. it is a real comparison).
    6728              : 
    6729              :    MODE is the mode of the result, while CMP_MODE specifies in which
    6730              :    mode the comparison is done in, so it is the mode of the operands.  */
    6731              : 
    6732              : rtx
    6733     87584844 : simplify_context::simplify_relational_operation_1 (rtx_code code,
    6734              :                                                    machine_mode mode,
    6735              :                                                    machine_mode cmp_mode,
    6736              :                                                    rtx op0, rtx op1)
    6737              : {
    6738     87584844 :   enum rtx_code op0code = GET_CODE (op0);
    6739              : 
    6740     87584844 :   if (op1 == const0_rtx && COMPARISON_P (op0))
    6741              :     {
    6742              :       /* If op0 is a comparison, extract the comparison arguments
    6743              :          from it.  */
    6744       301620 :       if (code == NE)
    6745              :         {
    6746       133468 :           if (GET_MODE (op0) == mode)
    6747          178 :             return simplify_rtx (op0);
    6748              :           else
    6749       133290 :             return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
    6750       133290 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6751              :         }
    6752       168152 :       else if (code == EQ)
    6753              :         {
    6754       135689 :           enum rtx_code new_code = reversed_comparison_code (op0, NULL);
    6755       135689 :           if (new_code != UNKNOWN)
    6756       135372 :             return simplify_gen_relational (new_code, mode, VOIDmode,
    6757       135372 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6758              :         }
    6759              :     }
    6760              : 
    6761              :   /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
    6762              :      (GEU/LTU a -C).  Likewise for (LTU/GEU (PLUS a C) a).  */
    6763     87316004 :   if ((code == LTU || code == GEU)
    6764      5273683 :       && GET_CODE (op0) == PLUS
    6765       638391 :       && CONST_INT_P (XEXP (op0, 1))
    6766       420536 :       && (rtx_equal_p (op1, XEXP (op0, 0))
    6767       281579 :           || rtx_equal_p (op1, XEXP (op0, 1)))
    6768              :       /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
    6769     87521872 :       && XEXP (op0, 1) != const0_rtx)
    6770              :     {
    6771       205868 :       rtx new_cmp
    6772       205868 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6773       207427 :       return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
    6774       205868 :                                       cmp_mode, XEXP (op0, 0), new_cmp);
    6775              :     }
    6776              : 
    6777              :   /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
    6778              :      transformed into (LTU a -C).  */
    6779     87110136 :   if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
    6780       325640 :       && CONST_INT_P (XEXP (op0, 1))
    6781       243613 :       && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
    6782        19064 :       && XEXP (op0, 1) != const0_rtx)
    6783              :     {
    6784        19064 :       rtx new_cmp
    6785        19064 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6786        19064 :       return simplify_gen_relational (LTU, mode, cmp_mode,
    6787        19064 :                                        XEXP (op0, 0), new_cmp);
    6788              :     }
    6789              : 
    6790              :   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
    6791     87091072 :   if ((code == LTU || code == GEU)
    6792      5067815 :       && GET_CODE (op0) == PLUS
    6793       432523 :       && rtx_equal_p (op1, XEXP (op0, 1))
    6794              :       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
    6795     87097883 :       && !rtx_equal_p (op1, XEXP (op0, 0)))
    6796         6811 :     return simplify_gen_relational (code, mode, cmp_mode, op0,
    6797         6811 :                                     copy_rtx (XEXP (op0, 0)));
    6798              : 
    6799     87084261 :   if (op1 == const0_rtx)
    6800              :     {
    6801              :       /* Canonicalize (GTU x 0) as (NE x 0).  */
    6802     38094493 :       if (code == GTU)
    6803        77079 :         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
    6804              :       /* Canonicalize (LEU x 0) as (EQ x 0).  */
    6805     38017414 :       if (code == LEU)
    6806        33309 :         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
    6807              : 
    6808     37984105 :       if ((code == NE || code == EQ)
    6809              :           /* Verify op0 is IOR */
    6810     34079712 :           && GET_CODE (op0) == IOR
    6811              :           /* only enters if op1 is 0 */
    6812              :           /* Verify IOR operand is NE */
    6813       584880 :           && GET_CODE (XEXP (op0, 0)) == NE
    6814        21441 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
    6815              :           /* Verify second NE operand is 0 */
    6816          374 :           && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
    6817              :         {
    6818           31 :           rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
    6819           31 :           t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
    6820           31 :           return t;
    6821              :         }
    6822              : 
    6823              :     }
    6824     48989768 :   else if (op1 == const1_rtx)
    6825              :     {
    6826      3359593 :       switch (code)
    6827              :         {
    6828         9269 :         case GE:
    6829              :           /* Canonicalize (GE x 1) as (GT x 0).  */
    6830         9269 :           return simplify_gen_relational (GT, mode, cmp_mode,
    6831         9269 :                                           op0, const0_rtx);
    6832       198373 :         case GEU:
    6833              :           /* Canonicalize (GEU x 1) as (NE x 0).  */
    6834       198373 :           return simplify_gen_relational (NE, mode, cmp_mode,
    6835       198373 :                                           op0, const0_rtx);
    6836         6802 :         case LT:
    6837              :           /* Canonicalize (LT x 1) as (LE x 0).  */
    6838         6802 :           return simplify_gen_relational (LE, mode, cmp_mode,
    6839         6802 :                                           op0, const0_rtx);
    6840        54027 :         case LTU:
    6841              :           /* Canonicalize (LTU x 1) as (EQ x 0).  */
    6842        54027 :           return simplify_gen_relational (EQ, mode, cmp_mode,
    6843        54027 :                                           op0, const0_rtx);
    6844              :         default:
    6845              :           break;
    6846              :         }
    6847              :     }
    6848     45630175 :   else if (op1 == constm1_rtx)
    6849              :     {
    6850              :       /* Canonicalize (LE x -1) as (LT x 0).  */
    6851      1192691 :       if (code == LE)
    6852         1575 :         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
    6853              :       /* Canonicalize (GT x -1) as (GE x 0).  */
    6854      1191116 :       if (code == GT)
    6855         5060 :         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
    6856              :     }
    6857              : 
    6858              :   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
    6859     82794343 :   if ((code == EQ || code == NE)
    6860     64691221 :       && (op0code == PLUS || op0code == MINUS)
    6861      2575078 :       && CONSTANT_P (op1)
    6862       929341 :       && CONSTANT_P (XEXP (op0, 1))
    6863       514057 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6864              :     {
    6865       514023 :       rtx x = XEXP (op0, 0);
    6866       514023 :       rtx c = XEXP (op0, 1);
    6867       514023 :       enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
    6868       514023 :       rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
    6869              : 
    6870              :       /* Detect an infinite recursive condition, where we oscillate at this
    6871              :          simplification case between:
    6872              :             A + B == C  <--->  C - B == A,
    6873              :          where A, B, and C are all constants with non-simplifiable expressions,
    6874              :          usually SYMBOL_REFs.  */
    6875       514023 :       if (GET_CODE (tem) == invcode
    6876           57 :           && CONSTANT_P (x)
    6877       514041 :           && rtx_equal_p (c, XEXP (tem, 1)))
    6878              :         return NULL_RTX;
    6879              : 
    6880       514005 :       return simplify_gen_relational (code, mode, cmp_mode, x, tem);
    6881              :     }
    6882              : 
    6883              :   /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0).  */
    6884     64177198 :   if ((code == EQ || code == NE)
    6885     64177198 :       && op0code == PLUS
    6886      1709900 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6887          250 :       && !side_effects_p (op1)
    6888          250 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6889          226 :     return simplify_gen_relational (code, mode, cmp_mode,
    6890          226 :                                     XEXP (op0, 0), CONST0_RTX (cmp_mode));
    6891              : 
    6892              :   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
    6893              :      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
    6894     86184487 :   scalar_int_mode int_mode, int_cmp_mode;
    6895     86184487 :   if (code == NE
    6896     34429979 :       && op1 == const0_rtx
    6897      2298415 :       && is_int_mode (mode, &int_mode)
    6898     88407655 :       && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
    6899              :       /* ??? Work-around BImode bugs in the ia64 backend.  */
    6900      2298415 :       && int_mode != BImode
    6901      2298391 :       && int_cmp_mode != BImode
    6902      2298391 :       && nonzero_bits (op0, int_cmp_mode) == 1
    6903     86184487 :       && STORE_FLAG_VALUE == 1)
    6904       150494 :     return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
    6905        75247 :            ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
    6906        19104 :            : lowpart_subreg (int_mode, op0, int_cmp_mode);
    6907              : 
    6908              :   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
    6909     86109240 :   if ((code == EQ || code == NE)
    6910     64101725 :       && op1 == const0_rtx
    6911     33929208 :       && op0code == XOR)
    6912        14966 :     return simplify_gen_relational (code, mode, cmp_mode,
    6913        14966 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6914              : 
    6915              :   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
    6916     64086759 :   if ((code == EQ || code == NE)
    6917     64086759 :       && op0code == XOR
    6918         5382 :       && rtx_equal_p (XEXP (op0, 0), op1)
    6919            6 :       && !side_effects_p (XEXP (op0, 0)))
    6920            0 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
    6921            0 :                                     CONST0_RTX (mode));
    6922              : 
    6923              :   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
    6924     86094274 :   if ((code == EQ || code == NE)
    6925     64086759 :       && op0code == XOR
    6926         5382 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6927     86094458 :       && !side_effects_p (XEXP (op0, 1)))
    6928          184 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6929          184 :                                     CONST0_RTX (mode));
    6930              : 
    6931              :   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
    6932     86094090 :   if ((code == EQ || code == NE)
    6933     64086575 :       && op0code == XOR
    6934         5198 :       && CONST_SCALAR_INT_P (op1)
    6935         1479 :       && CONST_SCALAR_INT_P (XEXP (op0, 1)))
    6936          876 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6937              :                                     simplify_gen_binary (XOR, cmp_mode,
    6938          876 :                                                          XEXP (op0, 1), op1));
    6939              : 
    6940              :   /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
    6941              :      constant folding if x/y is a constant.  */
    6942     64085699 :   if ((code == EQ || code == NE)
    6943     64085699 :       && (op0code == AND || op0code == IOR)
    6944      3654864 :       && !side_effects_p (op1)
    6945      3654758 :       && op1 != CONST0_RTX (cmp_mode))
    6946              :     {
    6947              :       /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
    6948              :          (eq/ne (and (not y) x) 0).  */
    6949       476541 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
    6950       950189 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
    6951              :         {
    6952        24816 :           rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
    6953              :                                           cmp_mode);
    6954        24816 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
    6955              : 
    6956        24816 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6957        24816 :                                           CONST0_RTX (cmp_mode));
    6958              :         }
    6959              : 
    6960              :       /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
    6961              :          (eq/ne (and (not x) y) 0).  */
    6962       451827 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
    6963       878854 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
    6964              :         {
    6965        46523 :           rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
    6966              :                                           cmp_mode);
    6967        46523 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
    6968              : 
    6969        46523 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6970        46523 :                                           CONST0_RTX (cmp_mode));
    6971              :         }
    6972              :     }
    6973              : 
    6974              :   /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
    6975              :      relationship.  */
    6976     86021875 :   if ((op0code == AND || op0code == IOR)
    6977      3832861 :       && CONST_INT_P (op1)
    6978      3656254 :       && CONST_INT_P (XEXP (op0, 1)))
    6979              :     {
    6980      2382030 :       unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
    6981      2382030 :       unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
    6982              : 
    6983              :       /* For AND operations:
    6984              :            - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
    6985              :            - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
    6986              :            - (x & c1) >= c2 when c1 is less than c2 -> false
    6987              :            - (x & c1) < c2 when c1 is less than c2 -> true
    6988              :            - (x & c1) > c2 when c1 is less than or equal to c2 -> false
    6989              :            - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
    6990              : 
    6991              :          For IOR operations:
    6992              :            - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
    6993              :            - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
    6994              :            - (x | c1) <= c2 when c1 is greater than c2 -> false
    6995              :            - (x | c1) > c2 when c1 is greater than c2 -> true
    6996              :            - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
    6997              :            - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
    6998      2382030 :       if ((op0code == AND
    6999      2378455 :            && ((code == EQ && (c1 & c2) != c2)
    7000      2378437 :                || (code == GEU && c1 < c2)
    7001      2378437 :                || (code == GTU && c1 <= c2)))
    7002      2382012 :           || ((op0code == IOR
    7003         3575 :               && ((code == EQ && (c1 & c2) != c1)
    7004         3575 :                   || (code == LEU && c1 > c2)
    7005         3575 :                   || (code == LTU && c1 >= c2)))))
    7006           18 :         return const0_rtx;
    7007              : 
    7008      2382012 :       if ((op0code == AND
    7009      2378437 :            && ((code == NE && (c1 & c2) != c2)
    7010      2378356 :                || (code == LTU && c1 < c2)
    7011      2378356 :                || (code == LEU && c1 <= c2)))
    7012      2381931 :           || ((op0code == IOR
    7013         3575 :               && ((code == NE && (c1 & c2) != c1)
    7014         3515 :                   || (code == GTU && c1 > c2)
    7015         3515 :                   || (code == GEU && c1 >= c2)))))
    7016          141 :         return const_true_rtx;
    7017              :     }
    7018              : 
    7019              :   /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped.  */
    7020     86021716 :   if ((code == EQ || code == NE)
    7021     64014201 :       && GET_CODE (op0) == BSWAP
    7022          316 :       && CONST_SCALAR_INT_P (op1))
    7023           85 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    7024              :                                     simplify_gen_unary (BSWAP, cmp_mode,
    7025           85 :                                                         op1, cmp_mode));
    7026              : 
    7027              :   /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y).  */
    7028     64014116 :   if ((code == EQ || code == NE)
    7029     64014116 :       && GET_CODE (op0) == BSWAP
    7030          231 :       && GET_CODE (op1) == BSWAP)
    7031           18 :     return simplify_gen_relational (code, mode, cmp_mode,
    7032           18 :                                     XEXP (op0, 0), XEXP (op1, 0));
    7033              : 
    7034     86021613 :   if (op0code == POPCOUNT && op1 == const0_rtx)
    7035            0 :     switch (code)
    7036              :       {
    7037            0 :       case EQ:
    7038            0 :       case LE:
    7039            0 :       case LEU:
    7040              :         /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
    7041            0 :         return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
    7042              :                                         XEXP (op0, 0),
    7043            0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    7044              : 
    7045            0 :       case NE:
    7046            0 :       case GT:
    7047            0 :       case GTU:
    7048              :         /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
    7049            0 :         return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
    7050              :                                         XEXP (op0, 0),
    7051            0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    7052              : 
    7053              :       default:
    7054              :         break;
    7055              :       }
    7056              : 
    7057              :   /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1).  */
    7058     86021613 :   if (code == NE
    7059     34308064 :       && op1 == const0_rtx
    7060     17658691 :       && (op0code == TRUNCATE
    7061       156974 :           || (partial_subreg_p (op0)
    7062       156247 :               && subreg_lowpart_p (op0)))
    7063       132762 :       && SCALAR_INT_MODE_P (mode)
    7064     86021613 :       && STORE_FLAG_VALUE == 1)
    7065              :     {
    7066        34661 :       rtx tmp = XEXP (op0, 0);
    7067        34661 :       if (GET_CODE (tmp) == ASHIFT
    7068         2639 :           && GET_MODE (tmp) == mode
    7069          241 :           && CONST_INT_P (XEXP (tmp, 1))
    7070          241 :           && is_int_mode (GET_MODE (op0), &int_mode)
    7071        34902 :           && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    7072          241 :         return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
    7073              :     }
    7074              : 
    7075              :   /* For two unsigned booleans A and B:
    7076              : 
    7077              :      A >  B == ~B & A
    7078              :      A >= B == ~B | A
    7079              :      A <  B == ~A & B
    7080              :      A <= B == ~A | B
    7081              :      A == B == ~A ^ B (== ~B ^ A)
    7082              :      A != B ==  A ^ B
    7083              : 
    7084              :      For signed comparisons, we have to take STORE_FLAG_VALUE into account,
    7085              :      with the rules above applying for positive STORE_FLAG_VALUE and with
    7086              :      the relations reversed for negative STORE_FLAG_VALUE.  */
    7087     86021372 :   if (is_a<scalar_int_mode> (cmp_mode)
    7088     83238767 :       && COMPARISON_P (op0)
    7089     86137113 :       && COMPARISON_P (op1))
    7090              :     {
    7091         9887 :       rtx t = NULL_RTX;
    7092         9887 :       if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
    7093          723 :         t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
    7094              :       else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
    7095          720 :         t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
    7096              :       else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
    7097          720 :         t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
    7098              :       else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
    7099          720 :         t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
    7100              :       else if (code == EQ)
    7101         3145 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
    7102              :       else if (code == NE)
    7103         3859 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1);
    7104              :       if (t)
    7105              :         return t;
    7106              :     }
    7107              : 
    7108              :   return NULL_RTX;
    7109              : }
    7110              : 
    7111              : enum
    7112              : {
    7113              :   CMP_EQ = 1,
    7114              :   CMP_LT = 2,
    7115              :   CMP_GT = 4,
    7116              :   CMP_LTU = 8,
    7117              :   CMP_GTU = 16
    7118              : };
    7119              : 
    7120              : 
    7121              : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
    7122              :    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
    7123              :    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
    7124              :    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
    7125              :    For floating-point comparisons, assume that the operands were ordered.  */
    7126              : 
    7127              : static rtx
    7128       721571 : comparison_result (enum rtx_code code, int known_results)
    7129              : {
    7130       721571 :   switch (code)
    7131              :     {
    7132       132416 :     case EQ:
    7133       132416 :     case UNEQ:
    7134       132416 :       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
    7135       453275 :     case NE:
    7136       453275 :     case LTGT:
    7137       453275 :       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
    7138              : 
    7139         9297 :     case LT:
    7140         9297 :     case UNLT:
    7141         9297 :       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
    7142         8685 :     case GE:
    7143         8685 :     case UNGE:
    7144         8685 :       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
    7145              : 
    7146        12064 :     case GT:
    7147        12064 :     case UNGT:
    7148        12064 :       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
    7149        13181 :     case LE:
    7150        13181 :     case UNLE:
    7151        13181 :       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
    7152              : 
    7153        24014 :     case LTU:
    7154        24014 :       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
    7155         8858 :     case GEU:
    7156         8858 :       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
    7157              : 
    7158        49365 :     case GTU:
    7159        49365 :       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
    7160        10350 :     case LEU:
    7161        10350 :       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
    7162              : 
    7163            0 :     case ORDERED:
    7164            0 :       return const_true_rtx;
    7165           66 :     case UNORDERED:
    7166           66 :       return const0_rtx;
    7167            0 :     default:
    7168            0 :       gcc_unreachable ();
    7169              :     }
    7170              : }
    7171              : 
    7172              : /* Check if the given comparison (done in the given MODE) is actually
    7173              :    a tautology or a contradiction.  If the mode is VOIDmode, the
    7174              :    comparison is done in "infinite precision".  If no simplification
    7175              :    is possible, this function returns zero.  Otherwise, it returns
    7176              :    either const_true_rtx or const0_rtx.  */
    7177              : 
    7178              : rtx
    7179    134613500 : simplify_const_relational_operation (enum rtx_code code,
    7180              :                                      machine_mode mode,
    7181              :                                      rtx op0, rtx op1)
    7182              : {
    7183    141825390 :   rtx tem;
    7184    141825390 :   rtx trueop0;
    7185    141825390 :   rtx trueop1;
    7186              : 
    7187    141825390 :   gcc_assert (mode != VOIDmode
    7188              :               || (GET_MODE (op0) == VOIDmode
    7189              :                   && GET_MODE (op1) == VOIDmode));
    7190              : 
    7191              :   /* We only handle MODE_CC comparisons that are COMPARE against zero.  */
    7192    141825390 :   if (GET_MODE_CLASS (mode) == MODE_CC
    7193     46160211 :       && (op1 != const0_rtx
    7194     46160211 :           || GET_CODE (op0) != COMPARE))
    7195              :     return NULL_RTX;
    7196              : 
    7197              :   /* If op0 is a compare, extract the comparison arguments from it.  */
    7198    110571988 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    7199              :     {
    7200     14906809 :       op1 = XEXP (op0, 1);
    7201     14906809 :       op0 = XEXP (op0, 0);
    7202              : 
    7203     14906809 :       if (GET_MODE (op0) != VOIDmode)
    7204     14775452 :         mode = GET_MODE (op0);
    7205       131357 :       else if (GET_MODE (op1) != VOIDmode)
    7206        98867 :         mode = GET_MODE (op1);
    7207              :       else
    7208              :         return 0;
    7209              :     }
    7210              : 
    7211              :   /* We can't simplify MODE_CC values since we don't know what the
    7212              :      actual comparison is.  */
    7213    110539498 :   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
    7214              :     return 0;
    7215              : 
    7216              :   /* Make sure the constant is second.  */
    7217    110539498 :   if (swap_commutative_operands_p (op0, op1))
    7218              :     {
    7219      3040483 :       std::swap (op0, op1);
    7220      3040483 :       code = swap_condition (code);
    7221              :     }
    7222              : 
    7223    110539498 :   trueop0 = avoid_constant_pool_reference (op0);
    7224    110539498 :   trueop1 = avoid_constant_pool_reference (op1);
    7225              : 
    7226              :   /* For integer comparisons of A and B maybe we can simplify A - B and can
    7227              :      then simplify a comparison of that with zero.  If A and B are both either
    7228              :      a register or a CONST_INT, this can't help; testing for these cases will
    7229              :      prevent infinite recursion here and speed things up.
    7230              : 
    7231              :      We can only do this for EQ and NE comparisons as otherwise we may
    7232              :      lose or introduce overflow which we cannot disregard as undefined as
    7233              :      we do not know the signedness of the operation on either the left or
    7234              :      the right hand side of the comparison.  */
    7235              : 
    7236    110539498 :   if (INTEGRAL_MODE_P (mode)
    7237    107799322 :       && trueop1 != CONST0_RTX (mode)
    7238     55572825 :       && (code == EQ || code == NE)
    7239     35576308 :       && ! ((REG_P (op0)
    7240     10355862 :              || CONST_SCALAR_INT_P (trueop0)
    7241     10326453 :              || CONST_VECTOR_P (trueop0))
    7242     25249875 :             && (REG_P (op1)
    7243     15044419 :                 || CONST_SCALAR_INT_P (trueop1)
    7244      3507305 :                 || CONST_VECTOR_P (trueop1)))
    7245     13830667 :       && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
    7246              :       /* We cannot do this if tem is a nonzero address.  */
    7247      7211892 :       && ! nonzero_address_p (tem))
    7248      7211890 :     return simplify_const_relational_operation (signed_condition (code),
    7249      7211890 :                                                 mode, tem, CONST0_RTX (mode));
    7250              : 
    7251    103327608 :   if (! HONOR_NANS (mode) && code == ORDERED)
    7252            0 :     return const_true_rtx;
    7253              : 
    7254    103327608 :   if (! HONOR_NANS (mode) && code == UNORDERED)
    7255            8 :     return const0_rtx;
    7256              : 
    7257              :   /* For modes without NaNs, if the two operands are equal, we know the
    7258              :      result except if they have side-effects.  Even with NaNs we know
    7259              :      the result of unordered comparisons and, if signaling NaNs are
    7260              :      irrelevant, also the result of LT/GT/LTGT.  */
    7261    103327600 :   if ((! HONOR_NANS (trueop0)
    7262      2248195 :        || code == UNEQ || code == UNLE || code == UNGE
    7263              :        || ((code == LT || code == GT || code == LTGT)
    7264       946185 :            && ! HONOR_SNANS (trueop0)))
    7265    102132915 :       && rtx_equal_p (trueop0, trueop1)
    7266    103844140 :       && ! side_effects_p (trueop0))
    7267       516447 :     return comparison_result (code, CMP_EQ);
    7268              : 
    7269              :   /* If the operands are floating-point constants, see if we can fold
    7270              :      the result.  */
    7271    102811153 :   if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
    7272         1498 :       && CONST_DOUBLE_AS_FLOAT_P (trueop1)
    7273         1498 :       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
    7274              :     {
    7275         1498 :       const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
    7276         1498 :       const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    7277              : 
    7278              :       /* Comparisons are unordered iff at least one of the values is NaN.  */
    7279         1498 :       if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
    7280          173 :         switch (code)
    7281              :           {
    7282            0 :           case UNEQ:
    7283            0 :           case UNLT:
    7284            0 :           case UNGT:
    7285            0 :           case UNLE:
    7286            0 :           case UNGE:
    7287            0 :           case NE:
    7288            0 :           case UNORDERED:
    7289            0 :             return const_true_rtx;
    7290          173 :           case EQ:
    7291          173 :           case LT:
    7292          173 :           case GT:
    7293          173 :           case LE:
    7294          173 :           case GE:
    7295          173 :           case LTGT:
    7296          173 :           case ORDERED:
    7297          173 :             return const0_rtx;
    7298              :           default:
    7299              :             return 0;
    7300              :           }
    7301              : 
    7302         1486 :       return comparison_result (code,
    7303         1486 :                                 (real_equal (d0, d1) ? CMP_EQ :
    7304         1486 :                                  real_less (d0, d1) ? CMP_LT : CMP_GT));
    7305              :     }
    7306              : 
    7307              :   /* Otherwise, see if the operands are both integers.  */
    7308    102809655 :   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
    7309     99616529 :       && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
    7310              :     {
    7311              :       /* It would be nice if we really had a mode here.  However, the
    7312              :          largest int representable on the target is as good as
    7313              :          infinite.  */
    7314       203799 :       machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
    7315       203799 :       rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
    7316       203799 :       rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
    7317              : 
    7318       203799 :       if (wi::eq_p (ptrueop0, ptrueop1))
    7319            0 :         return comparison_result (code, CMP_EQ);
    7320              :       else
    7321              :         {
    7322       203799 :           int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
    7323       203799 :           cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
    7324       203799 :           return comparison_result (code, cr);
    7325              :         }
    7326              :     }
    7327              : 
    7328              :   /* Optimize comparisons with upper and lower bounds.  */
    7329    102605856 :   scalar_int_mode int_mode;
    7330    102605856 :   if (CONST_INT_P (trueop1)
    7331     71710481 :       && is_a <scalar_int_mode> (mode, &int_mode)
    7332     71710481 :       && HWI_COMPUTABLE_MODE_P (int_mode)
    7333    173855404 :       && !side_effects_p (trueop0))
    7334              :     {
    7335     71098213 :       int sign;
    7336     71098213 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
    7337     71098213 :       HOST_WIDE_INT val = INTVAL (trueop1);
    7338     71098213 :       HOST_WIDE_INT mmin, mmax;
    7339              : 
    7340     71098213 :       if (code == GEU
    7341     71098213 :           || code == LEU
    7342     67738384 :           || code == GTU
    7343     67738384 :           || code == LTU)
    7344              :         sign = 0;
    7345              :       else
    7346     71098213 :         sign = 1;
    7347              : 
    7348              :       /* Get a reduced range if the sign bit is zero.  */
    7349     71098213 :       if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
    7350              :         {
    7351      6298827 :           mmin = 0;
    7352      6298827 :           mmax = nonzero;
    7353              :         }
    7354              :       else
    7355              :         {
    7356     64799386 :           rtx mmin_rtx, mmax_rtx;
    7357     64799386 :           get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
    7358              : 
    7359     64799386 :           mmin = INTVAL (mmin_rtx);
    7360     64799386 :           mmax = INTVAL (mmax_rtx);
    7361     64799386 :           if (sign)
    7362              :             {
    7363     58526166 :               unsigned int sign_copies
    7364     58526166 :                 = num_sign_bit_copies (trueop0, int_mode);
    7365              : 
    7366     58526166 :               mmin >>= (sign_copies - 1);
    7367     58526166 :               mmax >>= (sign_copies - 1);
    7368              :             }
    7369              :         }
    7370              : 
    7371     71098213 :       switch (code)
    7372              :         {
    7373              :         /* x >= y is always true for y <= mmin, always false for y > mmax.  */
    7374       547074 :         case GEU:
    7375       547074 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    7376         5715 :             return const_true_rtx;
    7377       541359 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    7378           48 :             return const0_rtx;
    7379              :           break;
    7380       975620 :         case GE:
    7381       975620 :           if (val <= mmin)
    7382         1966 :             return const_true_rtx;
    7383       973654 :           if (val > mmax)
    7384            0 :             return const0_rtx;
    7385              :           break;
    7386              : 
    7387              :         /* x <= y is always true for y >= mmax, always false for y < mmin.  */
    7388      2812755 :         case LEU:
    7389      2812755 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    7390        15340 :             return const_true_rtx;
    7391      2797415 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    7392            0 :             return const0_rtx;
    7393              :           break;
    7394      2660205 :         case LE:
    7395      2660205 :           if (val >= mmax)
    7396          445 :             return const_true_rtx;
    7397      2659760 :           if (val < mmin)
    7398            0 :             return const0_rtx;
    7399              :           break;
    7400              : 
    7401     25872785 :         case EQ:
    7402              :           /* x == y is always false for y out of range.  */
    7403     25872785 :           if (val < mmin || val > mmax)
    7404          448 :             return const0_rtx;
    7405              :           break;
    7406              : 
    7407              :         /* x > y is always false for y >= mmax, always true for y < mmin.  */
    7408      2520426 :         case GTU:
    7409      2520426 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    7410        40324 :             return const0_rtx;
    7411      2480102 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    7412            0 :             return const_true_rtx;
    7413              :           break;
    7414      1913959 :         case GT:
    7415      1913959 :           if (val >= mmax)
    7416          243 :             return const0_rtx;
    7417      1913716 :           if (val < mmin)
    7418            2 :             return const_true_rtx;
    7419              :           break;
    7420              : 
    7421              :         /* x < y is always false for y <= mmin, always true for y > mmax.  */
    7422       864219 :         case LTU:
    7423       864219 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    7424         3569 :             return const0_rtx;
    7425       860650 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    7426        78993 :             return const_true_rtx;
    7427              :           break;
    7428      1117474 :         case LT:
    7429      1117474 :           if (val <= mmin)
    7430         2307 :             return const0_rtx;
    7431      1115167 :           if (val > mmax)
    7432         3154 :             return const_true_rtx;
    7433              :           break;
    7434              : 
    7435     31813696 :         case NE:
    7436              :           /* x != y is always true for y out of range.  */
    7437     31813696 :           if (val < mmin || val > mmax)
    7438          154 :             return const_true_rtx;
    7439              :           break;
    7440              : 
    7441              :         default:
    7442              :           break;
    7443              :         }
    7444              :     }
    7445              : 
    7446              :   /* Optimize integer comparisons with zero.  */
    7447    102453148 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    7448     99303103 :       && trueop1 == const0_rtx
    7449     51489733 :       && !side_effects_p (trueop0))
    7450              :     {
    7451              :       /* Some addresses are known to be nonzero.  We don't know
    7452              :          their sign, but equality comparisons are known.  */
    7453     51336361 :       if (nonzero_address_p (trueop0))
    7454              :         {
    7455          533 :           if (code == EQ || code == LEU)
    7456          278 :             return const0_rtx;
    7457          255 :           if (code == NE || code == GTU)
    7458          255 :             return const_true_rtx;
    7459              :         }
    7460              : 
    7461              :       /* See if the first operand is an IOR with a constant.  If so, we
    7462              :          may be able to determine the result of this comparison.  */
    7463     51335828 :       if (GET_CODE (op0) == IOR)
    7464              :         {
    7465       674257 :           rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
    7466       674257 :           if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
    7467              :             {
    7468          207 :               int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
    7469          414 :               int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
    7470          207 :                               && (UINTVAL (inner_const)
    7471          207 :                                   & (HOST_WIDE_INT_1U
    7472              :                                      << sign_bitnum)));
    7473              : 
    7474          207 :               switch (code)
    7475              :                 {
    7476              :                 case EQ:
    7477              :                 case LEU:
    7478              :                   return const0_rtx;
    7479            0 :                 case NE:
    7480            0 :                 case GTU:
    7481            0 :                   return const_true_rtx;
    7482           13 :                 case LT:
    7483           13 :                 case LE:
    7484           13 :                   if (has_sign)
    7485            2 :                     return const_true_rtx;
    7486              :                   break;
    7487          192 :                 case GT:
    7488          192 :                 case GE:
    7489          192 :                   if (has_sign)
    7490              :                     return const0_rtx;
    7491              :                   break;
    7492              :                 default:
    7493              :                   break;
    7494              :                 }
    7495              :             }
    7496              :         }
    7497              :     }
    7498              : 
    7499              :   /* Optimize comparison of ABS with zero.  */
    7500     51839549 :   if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
    7501    154138283 :       && (GET_CODE (trueop0) == ABS
    7502     51685301 :           || (GET_CODE (trueop0) == FLOAT_EXTEND
    7503           90 :               && GET_CODE (XEXP (trueop0, 0)) == ABS)))
    7504              :     {
    7505          563 :       switch (code)
    7506              :         {
    7507           60 :         case LT:
    7508              :           /* Optimize abs(x) < 0.0.  */
    7509           60 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
    7510            0 :             return const0_rtx;
    7511              :           break;
    7512              : 
    7513           42 :         case GE:
    7514              :           /* Optimize abs(x) >= 0.0.  */
    7515           42 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
    7516            0 :             return const_true_rtx;
    7517              :           break;
    7518              : 
    7519            0 :         case UNGE:
    7520              :           /* Optimize ! (abs(x) < 0.0).  */
    7521            0 :           return const_true_rtx;
    7522              : 
    7523              :         default:
    7524              :           break;
    7525              :         }
    7526              :     }
    7527              : 
    7528              :   return 0;
    7529              : }
    7530              : 
    7531              : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
    7532              :    where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
    7533              :    or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
    7534              :    can be simplified to that or NULL_RTX if not.
    7535              :    Assume X is compared against zero with CMP_CODE and the true
    7536              :    arm is TRUE_VAL and the false arm is FALSE_VAL.  */
    7537              : 
    7538              : rtx
    7539     31992514 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
    7540              :                                          rtx true_val, rtx false_val)
    7541              : {
    7542     31992514 :   if (cmp_code != EQ && cmp_code != NE)
    7543              :     return NULL_RTX;
    7544              : 
    7545              :   /* Result on X == 0 and X !=0 respectively.  */
    7546     23012211 :   rtx on_zero, on_nonzero;
    7547     23012211 :   if (cmp_code == EQ)
    7548              :     {
    7549              :       on_zero = true_val;
    7550              :       on_nonzero = false_val;
    7551              :     }
    7552              :   else
    7553              :     {
    7554     12517903 :       on_zero = false_val;
    7555     12517903 :       on_nonzero = true_val;
    7556              :     }
    7557              : 
    7558     23012211 :   rtx_code op_code = GET_CODE (on_nonzero);
    7559     23012211 :   if ((op_code != CLZ && op_code != CTZ)
    7560         2175 :       || !rtx_equal_p (XEXP (on_nonzero, 0), x)
    7561     23013310 :       || !CONST_INT_P (on_zero))
    7562              :     return NULL_RTX;
    7563              : 
    7564          294 :   HOST_WIDE_INT op_val;
    7565          294 :   scalar_int_mode mode ATTRIBUTE_UNUSED
    7566          294 :     = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
    7567            8 :   if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
    7568          580 :        || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
    7569          326 :       && op_val == INTVAL (on_zero))
    7570            0 :     return on_nonzero;
    7571              : 
    7572              :   return NULL_RTX;
    7573              : }
    7574              : 
    7575              : /* Try to simplify X given that it appears within operand OP of a
    7576              :    VEC_MERGE operation whose mask is MASK.  X need not use the same
    7577              :    vector mode as the VEC_MERGE, but it must have the same number of
    7578              :    elements.
    7579              : 
    7580              :    Return the simplified X on success, otherwise return NULL_RTX.  */
    7581              : 
    7582              : rtx
    7583      2135780 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
    7584              : {
    7585      2135780 :   gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
    7586      4271560 :   poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
    7587      2135780 :   if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
    7588              :     {
    7589         5491 :       if (side_effects_p (XEXP (x, 1 - op)))
    7590              :         return NULL_RTX;
    7591              : 
    7592         5267 :       return XEXP (x, op);
    7593              :     }
    7594      2130289 :   if (UNARY_P (x)
    7595       372529 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7596      2188037 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
    7597              :     {
    7598        24228 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7599        24228 :       if (top0)
    7600          448 :         return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
    7601          448 :                                    GET_MODE (XEXP (x, 0)));
    7602              :     }
    7603      2129841 :   if (BINARY_P (x)
    7604       208647 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7605       416666 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7606       181020 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7607      2417987 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
    7608              :     {
    7609       144073 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7610       144073 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7611       144073 :       if (top0 || top1)
    7612              :         {
    7613          952 :           if (COMPARISON_P (x))
    7614            0 :             return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
    7615            0 :                                             GET_MODE (XEXP (x, 0)) != VOIDmode
    7616              :                                             ? GET_MODE (XEXP (x, 0))
    7617            0 :                                             : GET_MODE (XEXP (x, 1)),
    7618              :                                             top0 ? top0 : XEXP (x, 0),
    7619            0 :                                             top1 ? top1 : XEXP (x, 1));
    7620              :           else
    7621          952 :             return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
    7622              :                                         top0 ? top0 : XEXP (x, 0),
    7623          952 :                                         top1 ? top1 : XEXP (x, 1));
    7624              :         }
    7625              :     }
    7626      2128889 :   if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
    7627        61973 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7628       123946 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7629        61973 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7630       123946 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
    7631        61973 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
    7632      2145621 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
    7633              :     {
    7634         8366 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7635         8366 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7636         8366 :       rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
    7637         8366 :       if (top0 || top1 || top2)
    7638          448 :         return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
    7639          448 :                                      GET_MODE (XEXP (x, 0)),
    7640              :                                      top0 ? top0 : XEXP (x, 0),
    7641              :                                      top1 ? top1 : XEXP (x, 1),
    7642          448 :                                      top2 ? top2 : XEXP (x, 2));
    7643              :     }
    7644              :   return NULL_RTX;
    7645              : }
    7646              : 
    7647              : 
    7648              : /* Simplify CODE, an operation with result mode MODE and three operands,
    7649              :    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
    7650              :    a constant.  Return 0 if no simplifications is possible.  */
    7651              : 
    7652              : rtx
    7653     44755325 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
    7654              :                                               machine_mode op0_mode,
    7655              :                                               rtx op0, rtx op1, rtx op2)
    7656              : {
    7657     44755325 :   bool any_change = false;
    7658     44755325 :   rtx tem, trueop2;
    7659     44755325 :   scalar_int_mode int_mode, int_op0_mode;
    7660     44755325 :   unsigned int n_elts;
    7661              : 
    7662     44755325 :   switch (code)
    7663              :     {
    7664       334058 :     case FMA:
    7665              :       /* Simplify negations around the multiplication.  */
    7666              :       /* -a * -b + c  =>  a * b + c.  */
    7667       334058 :       if (GET_CODE (op0) == NEG)
    7668              :         {
    7669        82764 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    7670        82764 :           if (tem)
    7671          280 :             op1 = tem, op0 = XEXP (op0, 0), any_change = true;
    7672              :         }
    7673       251294 :       else if (GET_CODE (op1) == NEG)
    7674              :         {
    7675         1072 :           tem = simplify_unary_operation (NEG, mode, op0, mode);
    7676         1072 :           if (tem)
    7677            0 :             op0 = tem, op1 = XEXP (op1, 0), any_change = true;
    7678              :         }
    7679              : 
    7680              :       /* Canonicalize the two multiplication operands.  */
    7681              :       /* a * -b + c  =>  -b * a + c.  */
    7682       334058 :       if (swap_commutative_operands_p (op0, op1))
    7683              :         std::swap (op0, op1), any_change = true;
    7684              : 
    7685       303921 :       if (any_change)
    7686        30408 :         return gen_rtx_FMA (mode, op0, op1, op2);
    7687              :       return NULL_RTX;
    7688              : 
    7689       797094 :     case SIGN_EXTRACT:
    7690       797094 :     case ZERO_EXTRACT:
    7691       797094 :       if (CONST_INT_P (op0)
    7692        17400 :           && CONST_INT_P (op1)
    7693        17400 :           && CONST_INT_P (op2)
    7694     44755357 :           && is_a <scalar_int_mode> (mode, &int_mode)
    7695           32 :           && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
    7696       797126 :           && HWI_COMPUTABLE_MODE_P (int_mode))
    7697              :         {
    7698              :           /* Extracting a bit-field from a constant */
    7699           32 :           unsigned HOST_WIDE_INT val = UINTVAL (op0);
    7700           32 :           HOST_WIDE_INT op1val = INTVAL (op1);
    7701           32 :           HOST_WIDE_INT op2val = INTVAL (op2);
    7702           32 :           if (!BITS_BIG_ENDIAN)
    7703           32 :             val >>= op2val;
    7704              :           else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
    7705              :             val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
    7706              :           else
    7707              :             /* Not enough information to calculate the bit position.  */
    7708              :             break;
    7709              : 
    7710           32 :           if (HOST_BITS_PER_WIDE_INT != op1val)
    7711              :             {
    7712              :               /* First zero-extend.  */
    7713           29 :               val &= (HOST_WIDE_INT_1U << op1val) - 1;
    7714              :               /* If desired, propagate sign bit.  */
    7715           29 :               if (code == SIGN_EXTRACT
    7716            5 :                   && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
    7717            5 :                      != 0)
    7718            2 :                 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
    7719              :             }
    7720              : 
    7721           32 :           return gen_int_mode (val, int_mode);
    7722              :         }
    7723              :       break;
    7724              : 
    7725     42557008 :     case IF_THEN_ELSE:
    7726     42557008 :       if (CONST_INT_P (op0))
    7727       202999 :         return op0 != const0_rtx ? op1 : op2;
    7728              : 
    7729              :       /* Convert c ? a : a into "a".  Beware that two rtx_equal_p MEMs can
    7730              :          still carry different memory attributes, in particular incompatible
    7731              :          alias sets; returning one of them would narrow the aliasing of the
    7732              :          result to that operand's, which is unsound (PR125683).  When the
    7733              :          attributes differ, fold to a copy that keeps only what both operands
    7734              :          guarantee, like merge_memattrs does when cross-jumping commons two
    7735              :          memory references.  */
    7736     42354009 :       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
    7737              :         {
    7738         5404 :           if (op1 == op2
    7739         2967 :               || !MEM_P (op1)
    7740         5426 :               || (mem_attrs_eq_p (get_mem_attrs (op1), get_mem_attrs (op2))
    7741            8 :                   && MEM_READONLY_P (op1) == MEM_READONLY_P (op2)
    7742            8 :                   && MEM_NOTRAP_P (op1) == MEM_NOTRAP_P (op2)
    7743            8 :                   && MEM_POINTER (op1) == MEM_POINTER (op2)))
    7744              :             return op1;
    7745              : 
    7746              :           /* For BLKmode the size in MEM_ATTRS describes the access itself,
    7747              :              so it cannot be dropped.  Volatility is not merged either: it
    7748              :              constrains when the access happens rather than describing the
    7749              :              memory, so unlike the flags below it cannot be weakened to what
    7750              :              both operands allow.  Dropping it would lose a required access;
    7751              :              merge_memattrs and noce_try_cmove_arith instead set it, which is
    7752              :              sound but claims more than either operand did.  Those two have to
    7753              :              put something on a reference they are already committed to, while
    7754              :              this fold is free to do nothing, and if-conversion never reaches
    7755              :              it with a volatile operand in any case: side_effects_p is true
    7756              :              for one, so noce_operand_ok rejects it.  Decline the fold.  */
    7757           14 :           if (GET_MODE (op1) != BLKmode
    7758           14 :               && MEM_VOLATILE_P (op1) == MEM_VOLATILE_P (op2))
    7759              :             {
    7760           14 :               rtx mem = shallow_copy_rtx (op1);
    7761              : 
    7762           14 :               if (MEM_ALIAS_SET (op1) != MEM_ALIAS_SET (op2))
    7763            1 :                 set_mem_alias_set (mem, 0);
    7764              : 
    7765           14 :               if (!mem_expr_equal_p (MEM_EXPR (op1), MEM_EXPR (op2)))
    7766              :                 {
    7767           14 :                   set_mem_expr (mem, NULL_TREE);
    7768           14 :                   clear_mem_offset (mem);
    7769              :                 }
    7770            0 :               else if (MEM_OFFSET_KNOWN_P (op1) != MEM_OFFSET_KNOWN_P (op2)
    7771            0 :                        || (MEM_OFFSET_KNOWN_P (op1)
    7772            0 :                            && maybe_ne (MEM_OFFSET (op1), MEM_OFFSET (op2))))
    7773            0 :                 clear_mem_offset (mem);
    7774              : 
    7775              :               /* Unlike merge_memattrs, which fixes up two references that
    7776              :                  both stay in the stream, this returns a single reference
    7777              :                  that stands in for either arm, so keep the size only when
    7778              :                  both agree rather than taking the larger one.  */
    7779           28 :               if (!MEM_SIZE_KNOWN_P (op1) || !MEM_SIZE_KNOWN_P (op2)
    7780           28 :                   || maybe_ne (MEM_SIZE (op1), MEM_SIZE (op2)))
    7781            0 :                 clear_mem_size (mem);
    7782              : 
    7783           14 :               set_mem_align (mem, MIN (MEM_ALIGN (op1), MEM_ALIGN (op2)));
    7784              : 
    7785              :               /* MEM_READONLY_P, MEM_NOTRAP_P and MEM_POINTER are rtx flag
    7786              :                  bits rather than MEM_ATTRS fields, so shallow_copy_rtx has
    7787              :                  already taken them from OP1 and they need clearing by hand.
    7788              :                  Each asserts something about the reference, so the copy may
    7789              :                  only keep it when both operands do, as merge_memattrs does
    7790              :                  for the first two.  */
    7791           14 :               if (MEM_READONLY_P (op1) != MEM_READONLY_P (op2))
    7792            0 :                 MEM_READONLY_P (mem) = 0;
    7793           14 :               if (MEM_NOTRAP_P (op1) != MEM_NOTRAP_P (op2))
    7794            0 :                 MEM_NOTRAP_P (mem) = 0;
    7795           14 :               if (MEM_POINTER (op1) != MEM_POINTER (op2))
    7796            0 :                 MEM_POINTER (mem) = 0;
    7797              : 
    7798              :               return mem;
    7799              :             }
    7800              :         }
    7801              : 
    7802              :       /* Convert a != b ? a : b into "a".  */
    7803     42348605 :       if (GET_CODE (op0) == NE
    7804     16485704 :           && ! side_effects_p (op0)
    7805     16436923 :           && ! HONOR_NANS (mode)
    7806     16246468 :           && ! HONOR_SIGNED_ZEROS (mode)
    7807     58595073 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7808       114243 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7809     16246151 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7810         3785 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7811              :         return op1;
    7812              : 
    7813              :       /* Convert a == b ? a : b into "b".  */
    7814     42348059 :       if (GET_CODE (op0) == EQ
    7815     13238339 :           && ! side_effects_p (op0)
    7816     13219164 :           && ! HONOR_NANS (mode)
    7817     13194038 :           && ! HONOR_SIGNED_ZEROS (mode)
    7818     55542097 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7819        15439 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7820     13194035 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7821         8090 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7822              :         return op2;
    7823              : 
    7824              :       /* Convert a != 0 ? -a : 0 into "-a".  */
    7825     42348038 :       if (GET_CODE (op0) == NE
    7826     16485158 :           && ! side_effects_p (op0)
    7827     16436377 :           && ! HONOR_NANS (mode)
    7828     16245922 :           && ! HONOR_SIGNED_ZEROS (mode)
    7829     16245922 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7830     12327382 :           && op2 == CONST0_RTX (mode)
    7831       189372 :           && GET_CODE (op1) == NEG
    7832     42348087 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
    7833              :         return op1;
    7834              : 
    7835              :       /* Convert a == 0 ? 0 : -a into "-a".  */
    7836     42348029 :       if (GET_CODE (op0) == EQ
    7837     13238318 :           && ! side_effects_p (op0)
    7838     13219143 :           && ! HONOR_NANS (mode)
    7839     13194017 :           && ! HONOR_SIGNED_ZEROS (mode)
    7840     13194017 :           && op1 == CONST0_RTX (mode)
    7841        43285 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7842        22615 :           && GET_CODE (op2) == NEG
    7843     42348035 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
    7844              :         return op2;
    7845              : 
    7846              :       /* Convert (!c) != {0,...,0} ? a : b into
    7847              :          c != {0,...,0} ? b : a for vector modes.  */
    7848     42348023 :       if (VECTOR_MODE_P (GET_MODE (op1))
    7849        14643 :           && GET_CODE (op0) == NE
    7850          373 :           && GET_CODE (XEXP (op0, 0)) == NOT
    7851            0 :           && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
    7852              :         {
    7853            0 :           rtx cv = XEXP (op0, 1);
    7854            0 :           int nunits;
    7855            0 :           bool ok = true;
    7856            0 :           if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
    7857              :             ok = false;
    7858              :           else
    7859            0 :             for (int i = 0; i < nunits; ++i)
    7860            0 :               if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
    7861              :                 {
    7862              :                   ok = false;
    7863              :                   break;
    7864              :                 }
    7865            0 :           if (ok)
    7866              :             {
    7867            0 :               rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
    7868              :                                         XEXP (XEXP (op0, 0), 0),
    7869              :                                         XEXP (op0, 1));
    7870            0 :               rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
    7871            0 :               return retval;
    7872              :             }
    7873              :         }
    7874              : 
    7875              :       /* Convert x == 0 ? N : clz (x) into clz (x) when
    7876              :          CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
    7877              :          Similarly for ctz (x).  */
    7878     42347028 :       if (COMPARISON_P (op0) && !side_effects_p (op0)
    7879     84594477 :           && XEXP (op0, 1) == const0_rtx)
    7880              :         {
    7881     31992514 :           rtx simplified
    7882     31992514 :             = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
    7883              :                                      op1, op2);
    7884     31992514 :           if (simplified)
    7885              :             return simplified;
    7886              :         }
    7887              : 
    7888     42348023 :       if (COMPARISON_P (op0) && ! side_effects_p (op0))
    7889              :         {
    7890     84574050 :           machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
    7891     42246454 :                                         ? GET_MODE (XEXP (op0, 1))
    7892              :                                         : GET_MODE (XEXP (op0, 0)));
    7893     42246454 :           rtx temp;
    7894              : 
    7895              :           /* Look for happy constants in op1 and op2.  */
    7896     42246454 :           if (CONST_INT_P (op1) && CONST_INT_P (op2))
    7897              :             {
    7898       234793 :               HOST_WIDE_INT t = INTVAL (op1);
    7899       234793 :               HOST_WIDE_INT f = INTVAL (op2);
    7900              : 
    7901       234793 :               if (t == STORE_FLAG_VALUE && f == 0)
    7902        55240 :                 code = GET_CODE (op0);
    7903       179553 :               else if (t == 0 && f == STORE_FLAG_VALUE)
    7904              :                 {
    7905        31377 :                   enum rtx_code tmp;
    7906        31377 :                   tmp = reversed_comparison_code (op0, NULL);
    7907        31377 :                   if (tmp == UNKNOWN)
    7908              :                     break;
    7909              :                   code = tmp;
    7910              :                 }
    7911              :               else
    7912              :                 break;
    7913              : 
    7914        81389 :               return simplify_gen_relational (code, mode, cmp_mode,
    7915        81389 :                                               XEXP (op0, 0), XEXP (op0, 1));
    7916              :             }
    7917              : 
    7918     42011661 :           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
    7919              :                                                 cmp_mode, XEXP (op0, 0),
    7920              :                                                 XEXP (op0, 1));
    7921              : 
    7922              :           /* See if any simplifications were possible.  */
    7923     42011661 :           if (temp)
    7924              :             {
    7925         7161 :               if (CONST_INT_P (temp))
    7926          827 :                 return temp == const0_rtx ? op2 : op1;
    7927         6334 :               else if (temp)
    7928         6334 :                 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
    7929              :             }
    7930              :         }
    7931              :       break;
    7932              : 
    7933      1067165 :     case VEC_MERGE:
    7934      1067165 :       gcc_assert (GET_MODE (op0) == mode);
    7935      1067165 :       gcc_assert (GET_MODE (op1) == mode);
    7936      1067165 :       gcc_assert (VECTOR_MODE_P (mode));
    7937      1067165 :       trueop2 = avoid_constant_pool_reference (op2);
    7938      1067165 :       if (CONST_INT_P (trueop2)
    7939      1807787 :           && GET_MODE_NUNITS (mode).is_constant (&n_elts))
    7940              :         {
    7941       740622 :           unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
    7942       740622 :           unsigned HOST_WIDE_INT mask;
    7943       740622 :           if (n_elts == HOST_BITS_PER_WIDE_INT)
    7944              :             mask = -1;
    7945              :           else
    7946       738143 :             mask = (HOST_WIDE_INT_1U << n_elts) - 1;
    7947              : 
    7948       740622 :           if (!(sel & mask) && !side_effects_p (op0))
    7949              :             return op1;
    7950       740197 :           if ((sel & mask) == mask && !side_effects_p (op1))
    7951              :             return op0;
    7952              : 
    7953       729087 :           rtx trueop0 = avoid_constant_pool_reference (op0);
    7954       729087 :           rtx trueop1 = avoid_constant_pool_reference (op1);
    7955       729087 :           if (GET_CODE (trueop0) == CONST_VECTOR
    7956        11150 :               && GET_CODE (trueop1) == CONST_VECTOR)
    7957              :             {
    7958         6790 :               rtvec v = rtvec_alloc (n_elts);
    7959         6790 :               unsigned int i;
    7960              : 
    7961        66426 :               for (i = 0; i < n_elts; i++)
    7962        52846 :                 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
    7963        52846 :                                     ? CONST_VECTOR_ELT (trueop0, i)
    7964        31009 :                                     : CONST_VECTOR_ELT (trueop1, i));
    7965         6790 :               return gen_rtx_CONST_VECTOR (mode, v);
    7966              :             }
    7967              : 
    7968       722297 :           if (swap_commutative_operands_p (op0, op1)
    7969              :               /* Two operands have same precedence, then first bit of mask
    7970              :                  select first operand.  */
    7971       722297 :               || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
    7972        34631 :             return simplify_gen_ternary (code, mode, mode, op1, op0,
    7973        69262 :                                          GEN_INT (~sel & mask));
    7974              : 
    7975              :           /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
    7976              :              if no element from a appears in the result.  */
    7977       687666 :           if (GET_CODE (op0) == VEC_MERGE)
    7978              :             {
    7979        51244 :               tem = avoid_constant_pool_reference (XEXP (op0, 2));
    7980        51244 :               if (CONST_INT_P (tem))
    7981              :                 {
    7982        35521 :                   unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
    7983        35521 :                   if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
    7984           99 :                     return simplify_gen_ternary (code, mode, mode,
    7985           99 :                                                  XEXP (op0, 1), op1, op2);
    7986        35422 :                   if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
    7987          815 :                     return simplify_gen_ternary (code, mode, mode,
    7988          815 :                                                  XEXP (op0, 0), op1, op2);
    7989              : 
    7990              :                   /* Replace (vec_merge (vec_merge a b m) a n) with
    7991              :                      (vec_merge a b (m|~n)).  */
    7992        34607 :                   if (rtx_equal_p (XEXP (op0, 0), op1)
    7993        34607 :                       && ! side_effects_p (op1))
    7994          463 :                     return simplify_gen_ternary (code, mode, mode,
    7995              :                                                  op1, XEXP (op0, 1),
    7996          926 :                                                  GEN_INT ((sel0 | ~sel) & mask));
    7997              :                   /* Replace (vec_merge (vec_merge b a m) a n) with
    7998              :                      (vec_merge b a (m&n)).  */
    7999        34144 :                   if (rtx_equal_p (XEXP (op0, 1), op1)
    8000        34144 :                       && ! side_effects_p (op1))
    8001           57 :                     return simplify_gen_ternary (code, mode, mode,
    8002              :                                                  XEXP (op0, 0), op1,
    8003           57 :                                                  GEN_INT (sel & sel0 & mask));
    8004              :                 }
    8005              :             }
    8006       686232 :           if (GET_CODE (op1) == VEC_MERGE)
    8007              :             {
    8008          580 :               tem = avoid_constant_pool_reference (XEXP (op1, 2));
    8009          580 :               if (CONST_INT_P (tem))
    8010              :                 {
    8011          549 :                   unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
    8012          549 :                   if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
    8013          518 :                     return simplify_gen_ternary (code, mode, mode,
    8014          518 :                                                  op0, XEXP (op1, 1), op2);
    8015           31 :                   if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
    8016            4 :                     return simplify_gen_ternary (code, mode, mode,
    8017            4 :                                                  op0, XEXP (op1, 0), op2);
    8018              : 
    8019              :                   /* Replace (vec_merge a (vec_merge a b m) n) with
    8020              :                      (vec_merge a b (m|n)).  */
    8021           27 :                   if (rtx_equal_p (XEXP (op1, 0), op0)
    8022           27 :                       && ! side_effects_p (op0))
    8023            1 :                     return simplify_gen_ternary (code, mode, mode,
    8024              :                                                  op0, XEXP (op1, 1),
    8025            1 :                                                  GEN_INT ((sel | sel1) & mask));
    8026              : 
    8027              :                   /* Replace (vec_merge a (vec_merge b a m) n) with
    8028              :                      (vec_merge a b (~m|n)).  */
    8029           26 :                   if (rtx_equal_p (XEXP (op1, 1), op0)
    8030           26 :                       && ! side_effects_p (op0))
    8031            0 :                     return simplify_gen_ternary (code, mode, mode,
    8032              :                                                  op0, XEXP (op1, 0),
    8033            0 :                                                  GEN_INT ((sel | ~sel1) & mask));
    8034              :                 }
    8035              :             }
    8036              : 
    8037              :           /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
    8038              :              with a.  */
    8039       685709 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8040       375751 :               && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
    8041         1351 :               && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
    8042       688411 :               && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
    8043              :             {
    8044         1283 :               tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
    8045         1283 :               if (CONST_INT_P (tem) && CONST_INT_P (op2))
    8046              :                 {
    8047         1283 :                   if (XEXP (XEXP (op0, 0), 0) == op1
    8048            2 :                       && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
    8049              :                     return op1;
    8050              :                 }
    8051              :             }
    8052              :           /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
    8053              :              (const_int N))
    8054              :              with (vec_concat (X) (B)) if N == 1 or
    8055              :              (vec_concat (A) (X)) if N == 2.  */
    8056       685707 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8057       375749 :               && GET_CODE (op1) == CONST_VECTOR
    8058       536608 :               && known_eq (CONST_VECTOR_NUNITS (op1), 2)
    8059         1800 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8060       686607 :               && IN_RANGE (sel, 1, 2))
    8061              :             {
    8062          898 :               rtx newop0 = XEXP (op0, 0);
    8063          898 :               rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
    8064          898 :               if (sel == 2)
    8065          111 :                 std::swap (newop0, newop1);
    8066          898 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8067              :             }
    8068              :           /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
    8069              :              with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
    8070              :              Only applies for vectors of two elements.  */
    8071       684809 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8072       374851 :               && GET_CODE (op1) == VEC_CONCAT
    8073            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8074            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8075       684809 :               && IN_RANGE (sel, 1, 2))
    8076              :             {
    8077            0 :               rtx newop0 = XEXP (op0, 0);
    8078            0 :               rtx newop1 = XEXP (op1, 2 - sel);
    8079            0 :               rtx otherop = XEXP (op1, sel - 1);
    8080            0 :               if (sel == 2)
    8081            0 :                 std::swap (newop0, newop1);
    8082              :               /* Don't want to throw away the other part of the vec_concat if
    8083              :                  it has side-effects.  */
    8084            0 :               if (!side_effects_p (otherop))
    8085            0 :                 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8086              :             }
    8087              : 
    8088              :           /* Replace:
    8089              : 
    8090              :               (vec_merge:outer (vec_duplicate:outer x:inner)
    8091              :                                (subreg:outer y:inner 0)
    8092              :                                (const_int N))
    8093              : 
    8094              :              with (vec_concat:outer x:inner y:inner) if N == 1,
    8095              :              or (vec_concat:outer y:inner x:inner) if N == 2.
    8096              : 
    8097              :              Implicitly, this means we have a paradoxical subreg, but such
    8098              :              a check is cheap, so make it anyway.
    8099              : 
    8100              :              Only applies for vectors of two elements.  */
    8101       684809 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8102       374851 :               && GET_CODE (op1) == SUBREG
    8103        35321 :               && GET_MODE (op1) == GET_MODE (op0)
    8104        35321 :               && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
    8105            0 :               && paradoxical_subreg_p (op1)
    8106            0 :               && subreg_lowpart_p (op1)
    8107            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8108            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8109       684809 :               && IN_RANGE (sel, 1, 2))
    8110              :             {
    8111            0 :               rtx newop0 = XEXP (op0, 0);
    8112            0 :               rtx newop1 = SUBREG_REG (op1);
    8113            0 :               if (sel == 2)
    8114            0 :                 std::swap (newop0, newop1);
    8115            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8116              :             }
    8117              : 
    8118              :           /* Same as above but with switched operands:
    8119              :                 Replace (vec_merge:outer (subreg:outer x:inner 0)
    8120              :                                          (vec_duplicate:outer y:inner)
    8121              :                                (const_int N))
    8122              : 
    8123              :              with (vec_concat:outer x:inner y:inner) if N == 1,
    8124              :              or (vec_concat:outer y:inner x:inner) if N == 2.  */
    8125       684809 :           if (GET_CODE (op1) == VEC_DUPLICATE
    8126        57856 :               && GET_CODE (op0) == SUBREG
    8127        21064 :               && GET_MODE (op0) == GET_MODE (op1)
    8128        21064 :               && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
    8129            0 :               && paradoxical_subreg_p (op0)
    8130            0 :               && subreg_lowpart_p (op0)
    8131            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8132            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8133       684809 :               && IN_RANGE (sel, 1, 2))
    8134              :             {
    8135            0 :               rtx newop0 = SUBREG_REG (op0);
    8136            0 :               rtx newop1 = XEXP (op1, 0);
    8137            0 :               if (sel == 2)
    8138            0 :                 std::swap (newop0, newop1);
    8139            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8140              :             }
    8141              : 
    8142              :           /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
    8143              :                                  (const_int n))
    8144              :              with (vec_concat x y) or (vec_concat y x) depending on value
    8145              :              of N.  */
    8146       684809 :           if (GET_CODE (op0) == VEC_DUPLICATE
    8147       374851 :               && GET_CODE (op1) == VEC_DUPLICATE
    8148          208 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    8149            0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    8150       684809 :               && IN_RANGE (sel, 1, 2))
    8151              :             {
    8152            0 :               rtx newop0 = XEXP (op0, 0);
    8153            0 :               rtx newop1 = XEXP (op1, 0);
    8154            0 :               if (sel == 2)
    8155            0 :                 std::swap (newop0, newop1);
    8156              : 
    8157            0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    8158              :             }
    8159              :         }
    8160              : 
    8161      1011352 :       if (rtx_equal_p (op0, op1)
    8162      1011352 :           && !side_effects_p (op2) && !side_effects_p (op1))
    8163              :         return op0;
    8164              : 
    8165      1011054 :       if (!side_effects_p (op2))
    8166              :         {
    8167      1007266 :           rtx top0
    8168      1007266 :             = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
    8169      1007266 :           rtx top1
    8170      1007266 :             = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
    8171      1007266 :           if (top0 || top1)
    8172          998 :             return simplify_gen_ternary (code, mode, mode,
    8173              :                                          top0 ? top0 : op0,
    8174          819 :                                          top1 ? top1 : op1, op2);
    8175              :         }
    8176              : 
    8177              :       break;
    8178              : 
    8179            0 :     default:
    8180            0 :       gcc_unreachable ();
    8181              :     }
    8182              : 
    8183              :   return 0;
    8184              : }
    8185              : 
    8186              : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
    8187              :    starting at byte FIRST_BYTE.  Return true on success and add the
    8188              :    bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
    8189              :    that the bytes follow target memory order.  Leave BYTES unmodified
    8190              :    on failure.
    8191              : 
    8192              :    MODE is the mode of X.  The caller must reserve NUM_BYTES bytes in
    8193              :    BYTES before calling this function.  */
    8194              : 
    8195              : bool
    8196     14083583 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
    8197              :                    unsigned int first_byte, unsigned int num_bytes)
    8198              : {
    8199              :   /* Check the mode is sensible.  */
    8200     14083583 :   gcc_assert (GET_MODE (x) == VOIDmode
    8201              :               ? is_a <scalar_int_mode> (mode)
    8202              :               : mode == GET_MODE (x));
    8203              : 
    8204     14083583 :   if (GET_CODE (x) == CONST_VECTOR)
    8205              :     {
    8206              :       /* CONST_VECTOR_ELT follows target memory order, so no shuffling
    8207              :          is necessary.  The only complication is that MODE_VECTOR_BOOL
    8208              :          vectors can have several elements per byte.  */
    8209      1154438 :       unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8210              :                                                    GET_MODE_NUNITS (mode));
    8211       577219 :       unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
    8212       577219 :       if (elt_bits < BITS_PER_UNIT)
    8213              :         {
    8214              :           /* This is the only case in which elements can be smaller than
    8215              :              a byte.  */
    8216            0 :           gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    8217            0 :           auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
    8218            0 :           for (unsigned int i = 0; i < num_bytes; ++i)
    8219              :             {
    8220            0 :               target_unit value = 0;
    8221            0 :               for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
    8222              :                 {
    8223            0 :                   if (INTVAL (CONST_VECTOR_ELT (x, elt)))
    8224            0 :                     value |= mask << j;
    8225            0 :                   elt += 1;
    8226              :                 }
    8227            0 :               bytes.quick_push (value);
    8228              :             }
    8229              :           return true;
    8230              :         }
    8231              : 
    8232       577219 :       unsigned int start = bytes.length ();
    8233       577219 :       unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
    8234              :       /* Make FIRST_BYTE relative to ELT.  */
    8235       577219 :       first_byte %= elt_bytes;
    8236      2845846 :       while (num_bytes > 0)
    8237              :         {
    8238              :           /* Work out how many bytes we want from element ELT.  */
    8239      2268627 :           unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
    8240      4537254 :           if (!native_encode_rtx (GET_MODE_INNER (mode),
    8241              :                                   CONST_VECTOR_ELT (x, elt), bytes,
    8242              :                                   first_byte, chunk_bytes))
    8243              :             {
    8244            0 :               bytes.truncate (start);
    8245            0 :               return false;
    8246              :             }
    8247      2268627 :           elt += 1;
    8248      2268627 :           first_byte = 0;
    8249      2268627 :           num_bytes -= chunk_bytes;
    8250              :         }
    8251              :       return true;
    8252              :     }
    8253              : 
    8254              :   /* All subsequent cases are limited to scalars.  */
    8255     13506364 :   scalar_mode smode;
    8256     13506364 :   if (!is_a <scalar_mode> (mode, &smode))
    8257              :     return false;
    8258              : 
    8259              :   /* Make sure that the region is in range.  */
    8260     13506364 :   unsigned int end_byte = first_byte + num_bytes;
    8261     13506364 :   unsigned int mode_bytes = GET_MODE_SIZE (smode);
    8262     13506364 :   gcc_assert (end_byte <= mode_bytes);
    8263              : 
    8264     13506364 :   if (CONST_SCALAR_INT_P (x))
    8265              :     {
    8266              :       /* The target memory layout is affected by both BYTES_BIG_ENDIAN
    8267              :          and WORDS_BIG_ENDIAN.  Use the subreg machinery to get the lsb
    8268              :          position of each byte.  */
    8269     12823396 :       rtx_mode_t value (x, smode);
    8270     12823396 :       wide_int_ref value_wi (value);
    8271     67574777 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8272              :         {
    8273              :           /* Always constant because the inputs are.  */
    8274     41927985 :           unsigned int lsb
    8275     41927985 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8276              :           /* Operate directly on the encoding rather than using
    8277              :              wi::extract_uhwi, so that we preserve the sign or zero
    8278              :              extension for modes that are not a whole number of bits in
    8279              :              size.  (Zero extension is only used for the combination of
    8280              :              innermode == BImode && STORE_FLAG_VALUE == 1).  */
    8281     41927985 :           unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
    8282     41927985 :           unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
    8283     41927985 :           unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
    8284     41927985 :           bytes.quick_push (uhwi >> shift);
    8285              :         }
    8286     12823396 :       return true;
    8287              :     }
    8288              : 
    8289       682968 :   if (CONST_DOUBLE_P (x))
    8290              :     {
    8291              :       /* real_to_target produces an array of integers in target memory order.
    8292              :          All integers before the last one have 32 bits; the last one may
    8293              :          have 32 bits or fewer, depending on whether the mode bitsize
    8294              :          is divisible by 32.  Each of these integers is then laid out
    8295              :          in target memory as any other integer would be.  */
    8296       654766 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    8297       654766 :       real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
    8298              : 
    8299              :       /* The (maximum) number of target bytes per element of el32.  */
    8300       654766 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    8301       654766 :       gcc_assert (bytes_per_el32 != 0);
    8302              : 
    8303              :       /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
    8304              :          handling above.  */
    8305      4483569 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8306              :         {
    8307      3828803 :           unsigned int index = byte / bytes_per_el32;
    8308      3828803 :           unsigned int subbyte = byte % bytes_per_el32;
    8309      3828803 :           unsigned int int_bytes = MIN (bytes_per_el32,
    8310              :                                         mode_bytes - index * bytes_per_el32);
    8311              :           /* Always constant because the inputs are.  */
    8312      3828803 :           unsigned int lsb
    8313      3828803 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    8314      3828803 :           bytes.quick_push ((unsigned long) el32[index] >> lsb);
    8315              :         }
    8316       654766 :       return true;
    8317              :     }
    8318              : 
    8319        28202 :   if (GET_CODE (x) == CONST_FIXED)
    8320              :     {
    8321            0 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    8322              :         {
    8323              :           /* Always constant because the inputs are.  */
    8324            0 :           unsigned int lsb
    8325            0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8326            0 :           unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
    8327            0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    8328              :             {
    8329            0 :               lsb -= HOST_BITS_PER_WIDE_INT;
    8330            0 :               piece = CONST_FIXED_VALUE_HIGH (x);
    8331              :             }
    8332            0 :           bytes.quick_push (piece >> lsb);
    8333              :         }
    8334              :       return true;
    8335              :     }
    8336              : 
    8337              :   return false;
    8338              : }
    8339              : 
    8340              : /* Read a vector of mode MODE from the target memory image given by BYTES,
    8341              :    starting at byte FIRST_BYTE.  The vector is known to be encodable using
    8342              :    NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
    8343              :    and BYTES is known to have enough bytes to supply NPATTERNS *
    8344              :    NELTS_PER_PATTERN vector elements.  Each element of BYTES contains
    8345              :    BITS_PER_UNIT bits and the bytes are in target memory order.
    8346              : 
    8347              :    Return the vector on success, otherwise return NULL_RTX.  */
    8348              : 
    8349              : rtx
    8350       309044 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
    8351              :                           unsigned int first_byte, unsigned int npatterns,
    8352              :                           unsigned int nelts_per_pattern)
    8353              : {
    8354       309044 :   rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
    8355              : 
    8356       618088 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8357              :                                                GET_MODE_NUNITS (mode));
    8358       309044 :   if (elt_bits < BITS_PER_UNIT)
    8359              :     {
    8360              :       /* This is the only case in which elements can be smaller than a byte.
    8361              :          Element 0 is always in the lsb of the containing byte.  */
    8362            0 :       gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    8363            0 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    8364              :         {
    8365            0 :           unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
    8366            0 :           unsigned int byte_index = bit_index / BITS_PER_UNIT;
    8367            0 :           unsigned int lsb = bit_index % BITS_PER_UNIT;
    8368            0 :           unsigned int value = bytes[byte_index] >> lsb;
    8369            0 :           builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
    8370              :         }
    8371              :     }
    8372              :   else
    8373              :     {
    8374      1236107 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    8375              :         {
    8376      1854126 :           rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
    8377       927063 :           if (!x)
    8378            0 :             return NULL_RTX;
    8379       927063 :           builder.quick_push (x);
    8380       927063 :           first_byte += elt_bits / BITS_PER_UNIT;
    8381              :         }
    8382              :     }
    8383       309044 :   return builder.build ();
    8384       309044 : }
    8385              : 
    8386              : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
    8387              :    of target memory image BYTES.  */
    8388              : 
    8389              : wide_int
    8390     11948511 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
    8391              :                    unsigned int size, unsigned int precision)
    8392              : {
    8393              :   /* Pull the bytes msb first, so that we can use simple
    8394              :      shift-and-insert wide_int operations.  */
    8395     11948511 :   wide_int result (wi::zero (precision));
    8396     55343487 :   for (unsigned int i = 0; i < size; ++i)
    8397              :     {
    8398     43394976 :       unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
    8399              :       /* Always constant because the inputs are.  */
    8400     43394976 :       unsigned int subbyte
    8401     43394976 :         = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
    8402     43394976 :       result <<= BITS_PER_UNIT;
    8403     43394976 :       result |= bytes[first_byte + subbyte];
    8404              :     }
    8405     11948511 :   return result;
    8406              : }
    8407              : 
    8408              : /* Read an rtx of mode MODE from the target memory image given by BYTES,
    8409              :    starting at byte FIRST_BYTE.  Each element of BYTES contains BITS_PER_UNIT
    8410              :    bits and the bytes are in target memory order.  The image has enough
    8411              :    values to specify all bytes of MODE.
    8412              : 
    8413              :    Return the rtx on success, otherwise return NULL_RTX.  */
    8414              : 
    8415              : rtx
    8416     12288703 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
    8417              :                    unsigned int first_byte)
    8418              : {
    8419     12288703 :   if (VECTOR_MODE_P (mode))
    8420              :     {
    8421              :       /* If we know at compile time how many elements there are,
    8422              :          pull each element directly from BYTES.  */
    8423        94494 :       unsigned int nelts;
    8424       188988 :       if (GET_MODE_NUNITS (mode).is_constant (&nelts))
    8425        94494 :         return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
    8426              :       return NULL_RTX;
    8427              :     }
    8428              : 
    8429     12194209 :   scalar_int_mode imode;
    8430     12194209 :   if (is_a <scalar_int_mode> (mode, &imode)
    8431     11948511 :       && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
    8432              :     {
    8433     11948511 :       auto result = native_decode_int (bytes, first_byte,
    8434     11948511 :                                        GET_MODE_SIZE (imode),
    8435     23897022 :                                        GET_MODE_PRECISION (imode));
    8436     11948511 :       return immed_wide_int_const (result, imode);
    8437     11948511 :     }
    8438              : 
    8439       245698 :   scalar_float_mode fmode;
    8440       245698 :   if (is_a <scalar_float_mode> (mode, &fmode))
    8441              :     {
    8442              :       /* We need to build an array of integers in target memory order.
    8443              :          All integers before the last one have 32 bits; the last one may
    8444              :          have 32 bits or fewer, depending on whether the mode bitsize
    8445              :          is divisible by 32.  */
    8446       245668 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    8447       245668 :       unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
    8448       245668 :       memset (el32, 0, num_el32 * sizeof (long));
    8449              : 
    8450              :       /* The (maximum) number of target bytes per element of el32.  */
    8451       245668 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    8452       245668 :       gcc_assert (bytes_per_el32 != 0);
    8453              : 
    8454       245668 :       unsigned int mode_bytes = GET_MODE_SIZE (fmode);
    8455      1708530 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    8456              :         {
    8457      1462862 :           unsigned int index = byte / bytes_per_el32;
    8458      1462862 :           unsigned int subbyte = byte % bytes_per_el32;
    8459      1462862 :           unsigned int int_bytes = MIN (bytes_per_el32,
    8460              :                                         mode_bytes - index * bytes_per_el32);
    8461              :           /* Always constant because the inputs are.  */
    8462      1462862 :           unsigned int lsb
    8463      1462862 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    8464      1462862 :           el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
    8465              :         }
    8466       245668 :       REAL_VALUE_TYPE r;
    8467       245668 :       real_from_target (&r, el32, fmode);
    8468       245668 :       return const_double_from_real_value (r, fmode);
    8469              :     }
    8470              : 
    8471           30 :   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
    8472              :     {
    8473            0 :       scalar_mode smode = as_a <scalar_mode> (mode);
    8474            0 :       FIXED_VALUE_TYPE f;
    8475            0 :       f.data.low = 0;
    8476            0 :       f.data.high = 0;
    8477            0 :       f.mode = smode;
    8478              : 
    8479            0 :       unsigned int mode_bytes = GET_MODE_SIZE (smode);
    8480            0 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    8481              :         {
    8482              :           /* Always constant because the inputs are.  */
    8483            0 :           unsigned int lsb
    8484            0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    8485            0 :           unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
    8486            0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    8487            0 :             f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
    8488              :           else
    8489            0 :             f.data.low |= unit << lsb;
    8490              :         }
    8491            0 :       return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
    8492              :     }
    8493              : 
    8494              :   return NULL_RTX;
    8495              : }
    8496              : 
    8497              : /* Simplify a byte offset BYTE into CONST_VECTOR X.  The main purpose
    8498              :    is to convert a runtime BYTE value into a constant one.  */
    8499              : 
    8500              : static poly_uint64
    8501       364304 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
    8502              : {
    8503              :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    8504       364304 :   machine_mode mode = GET_MODE (x);
    8505       728608 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    8506              :                                                GET_MODE_NUNITS (mode));
    8507              :   /* The number of bits needed to encode one element from each pattern.  */
    8508       364304 :   unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
    8509              : 
    8510              :   /* Identify the start point in terms of a sequence number and a byte offset
    8511              :      within that sequence.  */
    8512       364304 :   poly_uint64 first_sequence;
    8513       364304 :   unsigned HOST_WIDE_INT subbit;
    8514       364304 :   if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
    8515              :                        &first_sequence, &subbit))
    8516              :     {
    8517       364304 :       unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    8518       364304 :       if (nelts_per_pattern == 1)
    8519              :         /* This is a duplicated vector, so the value of FIRST_SEQUENCE
    8520              :            doesn't matter.  */
    8521       280851 :         byte = subbit / BITS_PER_UNIT;
    8522        83453 :       else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
    8523              :         {
    8524              :           /* The subreg drops the first element from each pattern and
    8525              :              only uses the second element.  Find the first sequence
    8526              :              that starts on a byte boundary.  */
    8527         5568 :           subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
    8528         5568 :           byte = subbit / BITS_PER_UNIT;
    8529              :         }
    8530              :     }
    8531       364304 :   return byte;
    8532              : }
    8533              : 
    8534              : /* Subroutine of simplify_subreg in which:
    8535              : 
    8536              :    - X is known to be a CONST_VECTOR
    8537              :    - OUTERMODE is known to be a vector mode
    8538              : 
    8539              :    Try to handle the subreg by operating on the CONST_VECTOR encoding
    8540              :    rather than on each individual element of the CONST_VECTOR.
    8541              : 
    8542              :    Return the simplified subreg on success, otherwise return NULL_RTX.  */
    8543              : 
    8544              : static rtx
    8545       222710 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
    8546              :                               machine_mode innermode, unsigned int first_byte)
    8547              : {
    8548              :   /* Paradoxical subregs of vectors have dubious semantics.  */
    8549       222710 :   if (paradoxical_subreg_p (outermode, innermode))
    8550              :     return NULL_RTX;
    8551              : 
    8552              :   /* We can only preserve the semantics of a stepped pattern if the new
    8553              :      vector element is the same as the original one.  */
    8554       222539 :   if (CONST_VECTOR_STEPPED_P (x)
    8555       243741 :       && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
    8556              :     return NULL_RTX;
    8557              : 
    8558              :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    8559       214550 :   unsigned int x_elt_bits
    8560       214550 :     = vector_element_size (GET_MODE_PRECISION (innermode),
    8561              :                            GET_MODE_NUNITS (innermode));
    8562       214550 :   unsigned int out_elt_bits
    8563       214550 :     = vector_element_size (GET_MODE_PRECISION (outermode),
    8564              :                            GET_MODE_NUNITS (outermode));
    8565              : 
    8566              :   /* The number of bits needed to encode one element from every pattern
    8567              :      of the original vector.  */
    8568       214550 :   unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
    8569              : 
    8570              :   /* The number of bits needed to encode one element from every pattern
    8571              :      of the result.  */
    8572       214550 :   unsigned int out_sequence_bits
    8573       214550 :     = least_common_multiple (x_sequence_bits, out_elt_bits);
    8574              : 
    8575              :   /* Work out the number of interleaved patterns in the output vector
    8576              :      and the number of encoded elements per pattern.  */
    8577       214550 :   unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
    8578       214550 :   unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    8579              : 
    8580              :   /* The encoding scheme requires the number of elements to be a multiple
    8581              :      of the number of patterns, so that each pattern appears at least once
    8582              :      and so that the same number of elements appear from each pattern.  */
    8583       429100 :   bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
    8584       214550 :   unsigned int const_nunits;
    8585       429100 :   if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
    8586       214550 :       && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
    8587              :     {
    8588              :       /* Either the encoding is invalid, or applying it would give us
    8589              :          more elements than we need.  Just encode each element directly.  */
    8590              :       out_npatterns = const_nunits;
    8591              :       nelts_per_pattern = 1;
    8592              :     }
    8593              :   else if (!ok_p)
    8594              :     return NULL_RTX;
    8595              : 
    8596              :   /* Get enough bytes of X to form the new encoding.  */
    8597       214550 :   unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
    8598       214550 :   unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
    8599       214550 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8600       214550 :   if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
    8601              :     return NULL_RTX;
    8602              : 
    8603              :   /* Re-encode the bytes as OUTERMODE.  */
    8604       214550 :   return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
    8605       214550 :                                    nelts_per_pattern);
    8606       214550 : }
    8607              : 
    8608              : /* Try to simplify a subreg of a constant by encoding the subreg region
    8609              :    as a sequence of target bytes and reading them back in the new mode.
    8610              :    Return the new value on success, otherwise return null.
    8611              : 
    8612              :    The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
    8613              :    and byte offset FIRST_BYTE.  */
    8614              : 
    8615              : static rtx
    8616     11065285 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
    8617              :                        machine_mode innermode, unsigned int first_byte)
    8618              : {
    8619     11065285 :   unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
    8620     11065285 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8621              : 
    8622              :   /* Some ports misuse CCmode.  */
    8623     11065285 :   if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
    8624              :     return x;
    8625              : 
    8626              :   /* Paradoxical subregs read undefined values for bytes outside of the
    8627              :      inner value.  However, we have traditionally always sign-extended
    8628              :      integer constants and zero-extended others.  */
    8629     11063279 :   unsigned int inner_bytes = buffer_bytes;
    8630     11063279 :   if (paradoxical_subreg_p (outermode, innermode))
    8631              :     {
    8632      1091934 :       if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
    8633            0 :         return NULL_RTX;
    8634              : 
    8635       545967 :       target_unit filler = 0;
    8636       545967 :       if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
    8637        67918 :         filler = -1;
    8638              : 
    8639              :       /* Add any leading bytes due to big-endian layout.  The number of
    8640              :          bytes must be constant because both modes have constant size.  */
    8641       545967 :       unsigned int leading_bytes
    8642       545967 :         = -byte_lowpart_offset (outermode, innermode).to_constant ();
    8643       545967 :       for (unsigned int i = 0; i < leading_bytes; ++i)
    8644            0 :         buffer.quick_push (filler);
    8645              : 
    8646       545967 :       if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8647            0 :         return NULL_RTX;
    8648              : 
    8649              :       /* Add any trailing bytes due to little-endian layout.  */
    8650      7142774 :       while (buffer.length () < buffer_bytes)
    8651      3025420 :         buffer.quick_push (filler);
    8652              :     }
    8653     10517312 :   else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8654              :     return NULL_RTX;
    8655     11063279 :   rtx ret = native_decode_rtx (outermode, buffer, 0);
    8656     11063279 :   if (ret && FLOAT_MODE_P (outermode))
    8657              :     {
    8658       129941 :       auto_vec<target_unit, 128> buffer2 (buffer_bytes);
    8659       129941 :       if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
    8660              :         return NULL_RTX;
    8661      1430040 :       for (unsigned int i = 0; i < buffer_bytes; ++i)
    8662      1300134 :         if (buffer[i] != buffer2[i])
    8663              :           return NULL_RTX;
    8664       129941 :     }
    8665              :   return ret;
    8666     11065285 : }
    8667              : 
    8668              : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
    8669              :    Return 0 if no simplifications are possible.  */
    8670              : rtx
    8671     74901677 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
    8672              :                                    machine_mode innermode, poly_uint64 byte)
    8673              : {
    8674              :   /* Little bit of sanity checking.  */
    8675     74901677 :   gcc_assert (innermode != VOIDmode);
    8676     74901677 :   gcc_assert (outermode != VOIDmode);
    8677     74901677 :   gcc_assert (innermode != BLKmode);
    8678     74901677 :   gcc_assert (outermode != BLKmode);
    8679              : 
    8680     74901677 :   gcc_assert (GET_MODE (op) == innermode
    8681              :               || GET_MODE (op) == VOIDmode);
    8682              : 
    8683    149803354 :   poly_uint64 outersize = GET_MODE_SIZE (outermode);
    8684     74901677 :   if (!multiple_p (byte, outersize))
    8685              :     return NULL_RTX;
    8686              : 
    8687    149803314 :   poly_uint64 innersize = GET_MODE_SIZE (innermode);
    8688     74901657 :   if (maybe_ge (byte, innersize))
    8689              :     return NULL_RTX;
    8690              : 
    8691     74901657 :   if (outermode == innermode && known_eq (byte, 0U))
    8692      4583707 :     return op;
    8693              : 
    8694     70317950 :   if (GET_CODE (op) == CONST_VECTOR)
    8695       364304 :     byte = simplify_const_vector_byte_offset (op, byte);
    8696              : 
    8697    140635900 :   if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
    8698              :     {
    8699     64287798 :       rtx elt;
    8700              : 
    8701     54950524 :       if (VECTOR_MODE_P (outermode)
    8702     28011822 :           && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
    8703     66340937 :           && vec_duplicate_p (op, &elt))
    8704        13730 :         return gen_vec_duplicate (outermode, elt);
    8705              : 
    8706     64282342 :       if (outermode == GET_MODE_INNER (innermode)
    8707     64282342 :           && vec_duplicate_p (op, &elt))
    8708         8274 :         return elt;
    8709              :     }
    8710              : 
    8711     70304220 :   if (CONST_SCALAR_INT_P (op)
    8712     59437980 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    8713     59380635 :       || CONST_FIXED_P (op)
    8714     59380635 :       || GET_CODE (op) == CONST_VECTOR)
    8715              :     {
    8716     11279835 :       unsigned HOST_WIDE_INT cbyte;
    8717     11279835 :       if (byte.is_constant (&cbyte))
    8718              :         {
    8719     11279835 :           if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
    8720              :             {
    8721       222710 :               rtx tmp = simplify_const_vector_subreg (outermode, op,
    8722              :                                                       innermode, cbyte);
    8723       222710 :               if (tmp)
    8724     11279835 :                 return tmp;
    8725              :             }
    8726              : 
    8727     11065285 :           fixed_size_mode fs_outermode;
    8728     11065285 :           if (is_a <fixed_size_mode> (outermode, &fs_outermode))
    8729     11065285 :             return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
    8730              :         }
    8731              :     }
    8732              : 
    8733              :   /* Changing mode twice with SUBREG => just change it once,
    8734              :      or not at all if changing back op starting mode.  */
    8735     59024385 :   if (GET_CODE (op) == SUBREG)
    8736              :     {
    8737      1623608 :       machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
    8738      3247216 :       poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
    8739      1623608 :       rtx newx;
    8740              : 
    8741              :       /* Make sure that the relationship between the two subregs is
    8742              :          known at compile time.  */
    8743      1623608 :       if (!ordered_p (outersize, innermostsize))
    8744              :         return NULL_RTX;
    8745              : 
    8746      1623608 :       if (outermode == innermostmode
    8747       955884 :           && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
    8748      2579485 :           && known_eq (SUBREG_BYTE (op),
    8749              :                        subreg_lowpart_offset (innermode, innermostmode)))
    8750       955877 :         return SUBREG_REG (op);
    8751              : 
    8752              :       /* Work out the memory offset of the final OUTERMODE value relative
    8753              :          to the inner value of OP.  */
    8754       667731 :       poly_int64 mem_offset = subreg_memory_offset (outermode,
    8755              :                                                     innermode, byte);
    8756       667731 :       poly_int64 op_mem_offset = subreg_memory_offset (op);
    8757       667731 :       poly_int64 final_offset = mem_offset + op_mem_offset;
    8758              : 
    8759              :       /* See whether resulting subreg will be paradoxical.  */
    8760       667731 :       if (!paradoxical_subreg_p (outermode, innermostmode))
    8761              :         {
    8762              :           /* Bail out in case resulting subreg would be incorrect.  */
    8763      1061406 :           if (maybe_lt (final_offset, 0)
    8764      1061399 :               || maybe_ge (poly_uint64 (final_offset), innermostsize)
    8765      1061399 :               || !multiple_p (final_offset, outersize))
    8766              :             return NULL_RTX;
    8767              :         }
    8768              :       else
    8769              :         {
    8770       137028 :           poly_int64 required_offset = subreg_memory_offset (outermode,
    8771              :                                                              innermostmode, 0);
    8772       137028 :           if (maybe_ne (final_offset, required_offset))
    8773            1 :             return NULL_RTX;
    8774              :           /* Paradoxical subregs always have byte offset 0.  */
    8775       137027 :           final_offset = 0;
    8776              :         }
    8777              : 
    8778              :       /* Recurse for further possible simplifications.  */
    8779       667715 :       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
    8780       667715 :                               final_offset);
    8781       667715 :       if (newx)
    8782              :         return newx;
    8783       667304 :       if (validate_subreg (outermode, innermostmode,
    8784       667304 :                            SUBREG_REG (op), final_offset))
    8785              :         {
    8786       611622 :           newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
    8787       611622 :           if (SUBREG_PROMOTED_VAR_P (op)
    8788          738 :               && SUBREG_PROMOTED_SIGN (op) >= 0
    8789          738 :               && GET_MODE_CLASS (outermode) == MODE_INT
    8790          734 :               && known_ge (outersize, innersize)
    8791          315 :               && known_le (outersize, innermostsize)
    8792       611632 :               && subreg_lowpart_p (newx))
    8793              :             {
    8794           10 :               SUBREG_PROMOTED_VAR_P (newx) = 1;
    8795           10 :               SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
    8796              :             }
    8797              :           return newx;
    8798              :         }
    8799              :       return NULL_RTX;
    8800              :     }
    8801              : 
    8802              :   /* SUBREG of a hard register => just change the register number
    8803              :      and/or mode.  If the hard register is not valid in that mode,
    8804              :      suppress this simplification.  If the hard register is the stack,
    8805              :      frame, or argument pointer, leave this as a SUBREG.  */
    8806              : 
    8807     57400777 :   if (REG_P (op) && HARD_REGISTER_P (op))
    8808              :     {
    8809     11037339 :       unsigned int regno, final_regno;
    8810              : 
    8811     11037339 :       regno = REGNO (op);
    8812     11037339 :       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
    8813     11037339 :       if (HARD_REGISTER_NUM_P (final_regno))
    8814              :         {
    8815     11012324 :           rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
    8816              :                                       subreg_memory_offset (outermode,
    8817              :                                                             innermode, byte));
    8818              : 
    8819              :           /* Propagate original regno.  We don't have any way to specify
    8820              :              the offset inside original regno, so do so only for lowpart.
    8821              :              The information is used only by alias analysis that cannot
    8822              :              grog partial register anyway.  */
    8823              : 
    8824     11012324 :           if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
    8825      8232878 :             ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
    8826              :           return x;
    8827              :         }
    8828              :     }
    8829              : 
    8830              :   /* If we have a SUBREG of a register that we are replacing and we are
    8831              :      replacing it with a MEM, make a new MEM and try replacing the
    8832              :      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
    8833              :      or if we would be widening it.  */
    8834              : 
    8835     46388453 :   if (MEM_P (op)
    8836      1667628 :       && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
    8837              :       /* Allow splitting of volatile memory references in case we don't
    8838              :          have instruction to move the whole thing.  */
    8839      1667625 :       && (! MEM_VOLATILE_P (op)
    8840        45542 :           || ! have_insn_for (SET, innermode))
    8841              :       && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
    8842      1622083 :       && known_le (outersize, innersize)
    8843              :       /* You can't get the Nth element of a vector of addresses (i.e.
    8844              :          gather/scatter) by adding an offset to the base.  */
    8845     47213157 :       && !VECTOR_MODE_P (GET_MODE (XEXP (op, 0))))
    8846       824704 :     return adjust_address_nv (op, outermode, byte);
    8847              : 
    8848              :   /* Simplify (subreg:<m> (mem:<vec_m> (reg:<vec_p> addr)) x)
    8849              :      to (mem:<m> (subreg:<p> (reg:<vec_p>)) y)  */
    8850     45563749 :   if (MEM_P (op)
    8851       842924 :       && VECTOR_MODE_P (innermode)
    8852        12935 :       && VECTOR_MODE_P (GET_MODE (XEXP (op, 0)))
    8853     45563749 :       && GET_MODE_INNER (innermode) == outermode)
    8854              :     {
    8855            0 :       poly_uint64 index;
    8856            0 :       if (multiple_p (byte, GET_MODE_SIZE (outermode), &index))
    8857              :         {
    8858            0 :           rtx addr = XEXP (op, 0);
    8859            0 :           machine_mode addrmode = GET_MODE (addr);
    8860            0 :           scalar_mode addr_elt_mode = GET_MODE_INNER (addrmode);
    8861            0 :           poly_uint64 addr_byte = index * GET_MODE_SIZE (addr_elt_mode);
    8862              : 
    8863            0 :           rtx new_addr = simplify_gen_subreg (addr_elt_mode, addr, addrmode,
    8864              :                                               addr_byte);
    8865            0 :           if (new_addr)
    8866            0 :             return change_address_nv (op, outermode, new_addr);
    8867              :         }
    8868              :     }
    8869              : 
    8870              :   /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
    8871              :      of two parts.  */
    8872     45563749 :   if (GET_CODE (op) == CONCAT
    8873     45563749 :       || GET_CODE (op) == VEC_CONCAT)
    8874              :     {
    8875       257809 :       poly_uint64 final_offset;
    8876       257809 :       rtx part, res;
    8877              : 
    8878       257809 :       machine_mode part_mode = GET_MODE (XEXP (op, 0));
    8879       257809 :       if (part_mode == VOIDmode)
    8880           21 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8881       515618 :       poly_uint64 part_size = GET_MODE_SIZE (part_mode);
    8882       257809 :       if (known_lt (byte, part_size))
    8883              :         {
    8884       256319 :           part = XEXP (op, 0);
    8885       256319 :           final_offset = byte;
    8886              :         }
    8887         1490 :       else if (known_ge (byte, part_size))
    8888              :         {
    8889         1490 :           part = XEXP (op, 1);
    8890         1490 :           final_offset = byte - part_size;
    8891              :         }
    8892              :       else
    8893              :         return NULL_RTX;
    8894              : 
    8895       257809 :       if (maybe_gt (final_offset + outersize, part_size))
    8896              :         return NULL_RTX;
    8897              : 
    8898       128858 :       part_mode = GET_MODE (part);
    8899       128858 :       if (part_mode == VOIDmode)
    8900            0 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8901       128858 :       res = simplify_subreg (outermode, part, part_mode, final_offset);
    8902       128858 :       if (res)
    8903              :         return res;
    8904          333 :       if (GET_MODE (part) != VOIDmode
    8905          333 :           && validate_subreg (outermode, part_mode, part, final_offset))
    8906          333 :         return gen_rtx_SUBREG (outermode, part, final_offset);
    8907              :       return NULL_RTX;
    8908              :     }
    8909              : 
    8910              :   /* Simplify
    8911              :         (subreg (vec_merge (X)
    8912              :                            (vector)
    8913              :                            (const_int ((1 << N) | M)))
    8914              :                 (N * sizeof (outermode)))
    8915              :      to
    8916              :         (subreg (X) (N * sizeof (outermode)))
    8917              :    */
    8918     45305940 :   unsigned int idx;
    8919     90611880 :   if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
    8920     45305940 :       && idx < HOST_BITS_PER_WIDE_INT
    8921     45305940 :       && GET_CODE (op) == VEC_MERGE
    8922       538506 :       && GET_MODE_INNER (innermode) == outermode
    8923         4849 :       && CONST_INT_P (XEXP (op, 2))
    8924     45310216 :       && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
    8925         4267 :     return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
    8926              : 
    8927              :   /* A SUBREG resulting from a zero extension may fold to zero if
    8928              :      it extracts higher bits that the ZERO_EXTEND's source bits.  */
    8929     45301673 :   if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
    8930              :     {
    8931       233819 :       poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
    8932       233819 :       if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
    8933        55623 :         return CONST0_RTX (outermode);
    8934              :     }
    8935              : 
    8936              :   /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant.  */
    8937     45246050 :   if (GET_CODE (op) == ASHIFT
    8938      1076174 :       && SCALAR_INT_MODE_P (innermode)
    8939       993257 :       && CONST_INT_P (XEXP (op, 1))
    8940       911458 :       && INTVAL (XEXP (op, 1)) > 0
    8941     47233682 :       && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
    8942              :     {
    8943       911458 :       HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
    8944              :       /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero.  */
    8945       911458 :       if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
    8946      1785410 :           && known_le (GET_MODE_BITSIZE (outermode), val))
    8947       194118 :         return CONST0_RTX (outermode);
    8948              :       /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND).  */
    8949       751630 :       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
    8950        34952 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
    8951        69546 :           && known_eq (GET_MODE_BITSIZE (outermode), val)
    8952        68580 :           && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
    8953       786582 :           && known_eq (subreg_highpart_offset (outermode, innermode), byte))
    8954        34290 :         return XEXP (XEXP (op, 0), 0);
    8955              :     }
    8956              : 
    8957     46662975 :   auto distribute_subreg = [&](rtx op)
    8958              :     {
    8959      1611043 :       return simplify_subreg (outermode, op, innermode, byte);
    8960     45051932 :     };
    8961              : 
    8962              :   /* Try distributing the subreg through logic operations, if that
    8963              :      leads to all subexpressions being simplified.  For example,
    8964              :      distributing the outer subreg in:
    8965              : 
    8966              :        (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
    8967              : 
    8968              :      gives:
    8969              : 
    8970              :        (not:SI (reg:SI X))
    8971              : 
    8972              :      This should be a win if the outermode is word_mode, since logical
    8973              :      operations on word_mode should (a) be no more expensive than logical
    8974              :      operations on subword modes and (b) are likely to be cheaper than
    8975              :      logical operations on multiword modes.
    8976              : 
    8977              :      Otherwise, handle the case where the subreg is non-narrowing and does
    8978              :      not change the number of words.  The non-narrowing condition ensures
    8979              :      that we don't convert word_mode operations to subword operations.  */
    8980     45051932 :   scalar_int_mode int_outermode, int_innermode;
    8981     45051932 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8982     37959789 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8983     81496593 :       && (outermode == word_mode
    8984     22213945 :           || ((GET_MODE_PRECISION (int_outermode)
    8985     22213945 :                >= GET_MODE_PRECISION (int_innermode))
    8986      4372186 :               && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
    8987      4302496 :                   <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
    8988     18472672 :     switch (GET_CODE (op))
    8989              :       {
    8990        34938 :       case NOT:
    8991        34938 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8992         1893 :           return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
    8993              :         break;
    8994              : 
    8995       469760 :       case AND:
    8996       469760 :       case IOR:
    8997       469760 :       case XOR:
    8998       469760 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8999       207181 :           if (rtx op1 = distribute_subreg (XEXP (op, 1)))
    9000       202554 :             return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
    9001              :         break;
    9002              : 
    9003              :       default:
    9004              :         break;
    9005              :       }
    9006              : 
    9007     44847485 :   if (is_a <scalar_int_mode> (outermode)
    9008     37755342 :       && is_a <scalar_int_mode> (innermode)
    9009     82602827 :       && known_eq (byte,
    9010              :                    subreg_lowpart_offset (as_a <scalar_int_mode> (outermode),
    9011              :                                           as_a <scalar_int_mode> (innermode))))
    9012              :     {
    9013     33976693 :       scalar_int_mode int_outermode = as_a <scalar_int_mode> (outermode);
    9014     33976693 :       scalar_int_mode int_innermode = as_a <scalar_int_mode> (innermode);
    9015              : 
    9016              :       /* Handle polynomial integers.  The upper bits of a paradoxical
    9017              :          subreg are undefined, so this is safe regardless of whether
    9018              :          we're truncating or extending.  */
    9019     33976693 :       if (CONST_POLY_INT_P (op))
    9020              :         {
    9021              :           poly_wide_int val
    9022              :             = poly_wide_int::from (const_poly_int_value (op),
    9023              :                                    GET_MODE_PRECISION (int_outermode),
    9024              :                                    SIGNED);
    9025              :           return immed_wide_int_const (val, int_outermode);
    9026              :         }
    9027              : 
    9028     33976693 :       if (GET_MODE_PRECISION (int_outermode)
    9029     33976693 :           < GET_MODE_PRECISION (int_innermode))
    9030              :         {
    9031     21390711 :           rtx tem = simplify_truncation (int_outermode, op, int_innermode);
    9032     21390711 :           if (tem)
    9033              :             return tem;
    9034              :         }
    9035              :     }
    9036              : 
    9037              :   /* If the outer mode is not integral, try taking a subreg with the equivalent
    9038              :      integer outer mode and then bitcasting the result.
    9039              :      Other simplifications rely on integer to integer subregs and we'd
    9040              :      potentially miss out on optimizations otherwise.  */
    9041     86095932 :   if (known_gt (GET_MODE_SIZE (innermode),
    9042              :                 GET_MODE_SIZE (outermode))
    9043     23208359 :       && SCALAR_INT_MODE_P (innermode)
    9044     21931836 :       && !SCALAR_INT_MODE_P (outermode)
    9045     66410571 :       && int_mode_for_size (GET_MODE_BITSIZE (outermode),
    9046        77123 :                             0).exists (&int_outermode))
    9047              :     {
    9048        77123 :       rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
    9049        77123 :       if (tem)
    9050         1974 :         return lowpart_subreg (outermode, tem, int_outermode);
    9051              :     }
    9052              : 
    9053              :   /* If OP is a vector comparison and the subreg is not changing the
    9054              :      number of elements or the size of the elements, change the result
    9055              :      of the comparison to the new mode.  */
    9056     43045992 :   if (COMPARISON_P (op)
    9057       305477 :       && VECTOR_MODE_P (outermode)
    9058       216696 :       && VECTOR_MODE_P (innermode)
    9059       650064 :       && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
    9060     43447206 :       && known_eq (GET_MODE_UNIT_SIZE (outermode),
    9061              :                    GET_MODE_UNIT_SIZE (innermode)))
    9062       133394 :     return simplify_gen_relational (GET_CODE (op), outermode, innermode,
    9063       133394 :                                     XEXP (op, 0), XEXP (op, 1));
    9064              : 
    9065              :   /* Distribute non-paradoxical subregs through logic ops in cases where
    9066              :      one term disappears.
    9067              : 
    9068              :      (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
    9069              :      (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
    9070              :      (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
    9071              : 
    9072              :      if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
    9073              : 
    9074              :      (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
    9075              :      (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
    9076              : 
    9077              :      if M2 is no smaller than M1 and (subreg:M1 C2) is zero.  */
    9078     42912598 :   if (known_ge (innersize, outersize)
    9079     29744590 :       && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
    9080     27411352 :       && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
    9081     44627722 :       && CONSTANT_P (XEXP (op, 1)))
    9082              :     {
    9083       891884 :       rtx op1_subreg = distribute_subreg (XEXP (op, 1));
    9084       891884 :       if (op1_subreg == CONSTM1_RTX (outermode))
    9085              :         {
    9086       121609 :           if (GET_CODE (op) == IOR)
    9087              :             return op1_subreg;
    9088       121375 :           rtx op0 = XEXP (op, 0);
    9089       121375 :           if (GET_CODE (op) == XOR)
    9090          889 :             op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
    9091       121375 :           return simplify_gen_subreg (outermode, op0, innermode, byte);
    9092              :         }
    9093              : 
    9094       770275 :       if (op1_subreg == CONST0_RTX (outermode))
    9095        12435 :         return (GET_CODE (op) == AND
    9096        12435 :                 ? op1_subreg
    9097         7280 :                 : distribute_subreg (XEXP (op, 0)));
    9098              :     }
    9099              : 
    9100              :   return NULL_RTX;
    9101              : }
    9102              : 
    9103              : /* Make a SUBREG operation or equivalent if it folds.  */
    9104              : 
    9105              : rtx
    9106     46260194 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
    9107              :                                        machine_mode innermode,
    9108              :                                        poly_uint64 byte)
    9109              : {
    9110     46260194 :   rtx newx;
    9111              : 
    9112     46260194 :   newx = simplify_subreg (outermode, op, innermode, byte);
    9113     46260194 :   if (newx)
    9114              :     return newx;
    9115              : 
    9116     21864275 :   if (GET_CODE (op) == SUBREG
    9117     21864275 :       || GET_CODE (op) == CONCAT
    9118     21830490 :       || CONST_SCALAR_INT_P (op)
    9119     21830464 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    9120     21830464 :       || CONST_FIXED_P (op)
    9121     21830464 :       || GET_CODE (op) == CONST_VECTOR)
    9122              :     return NULL_RTX;
    9123              : 
    9124     21830454 :   if (validate_subreg (outermode, innermode, op, byte))
    9125     21798300 :     return gen_rtx_SUBREG (outermode, op, byte);
    9126              : 
    9127              :   return NULL_RTX;
    9128              : }
    9129              : 
    9130              : /* Generates a subreg to get the least significant part of EXPR (in mode
    9131              :    INNER_MODE) to OUTER_MODE.  */
    9132              : 
    9133              : rtx
    9134     34030853 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
    9135              :                                   machine_mode inner_mode)
    9136              : {
    9137     34030853 :   return simplify_gen_subreg (outer_mode, expr, inner_mode,
    9138     34030853 :                               subreg_lowpart_offset (outer_mode, inner_mode));
    9139              : }
    9140              : 
    9141              : /* Generate RTX to select element at INDEX out of vector OP.  */
    9142              : 
    9143              : rtx
    9144       678362 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
    9145              : {
    9146       678362 :   gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
    9147              : 
    9148       678362 :   scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
    9149              : 
    9150      1356724 :   if (known_eq (index * GET_MODE_SIZE (imode),
    9151              :                 subreg_lowpart_offset (imode, GET_MODE (op))))
    9152              :     {
    9153       678212 :       rtx res = lowpart_subreg (imode, op, GET_MODE (op));
    9154       678212 :       if (res)
    9155              :         return res;
    9156              :     }
    9157              : 
    9158          671 :   rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
    9159          671 :   return gen_rtx_VEC_SELECT (imode, op, tmp);
    9160              : }
    9161              : 
    9162              : 
    9163              : /* Simplify X, an rtx expression.
    9164              : 
    9165              :    Return the simplified expression or NULL if no simplifications
    9166              :    were possible.
    9167              : 
    9168              :    This is the preferred entry point into the simplification routines;
    9169              :    however, we still allow passes to call the more specific routines.
    9170              : 
    9171              :    Right now GCC has three (yes, three) major bodies of RTL simplification
    9172              :    code that need to be unified.
    9173              : 
    9174              :         1. fold_rtx in cse.cc.  This code uses various CSE specific
    9175              :            information to aid in RTL simplification.
    9176              : 
    9177              :         2. simplify_rtx in combine.cc.  Similar to fold_rtx, except that
    9178              :            it uses combine specific information to aid in RTL
    9179              :            simplification.
    9180              : 
    9181              :         3. The routines in this file.
    9182              : 
    9183              : 
    9184              :    Long term we want to only have one body of simplification code; to
    9185              :    get to that state I recommend the following steps:
    9186              : 
    9187              :         1. Pour over fold_rtx & simplify_rtx and move any simplifications
    9188              :            which are not pass dependent state into these routines.
    9189              : 
    9190              :         2. As code is moved by #1, change fold_rtx & simplify_rtx to
    9191              :            use this routine whenever possible.
    9192              : 
    9193              :         3. Allow for pass dependent state to be provided to these
    9194              :            routines and add simplifications based on the pass dependent
    9195              :            state.  Remove code from cse.cc & combine.cc that becomes
    9196              :            redundant/dead.
    9197              : 
    9198              :     It will take time, but ultimately the compiler will be easier to
    9199              :     maintain and improve.  It's totally silly that when we add a
    9200              :     simplification that it needs to be added to 4 places (3 for RTL
    9201              :     simplification and 1 for tree simplification.  */
    9202              : 
    9203              : rtx
    9204     48079032 : simplify_rtx (const_rtx x)
    9205              : {
    9206     48079032 :   const enum rtx_code code = GET_CODE (x);
    9207     48079032 :   const machine_mode mode = GET_MODE (x);
    9208              : 
    9209     48079032 :   switch (GET_RTX_CLASS (code))
    9210              :     {
    9211       782621 :     case RTX_UNARY:
    9212      1565242 :       return simplify_unary_operation (code, mode,
    9213       782621 :                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
    9214     27536857 :     case RTX_COMM_ARITH:
    9215     27536857 :       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    9216       432781 :         return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    9217              : 
    9218              :       /* Fall through.  */
    9219              : 
    9220     33837349 :     case RTX_BIN_ARITH:
    9221     33837349 :       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
    9222              : 
    9223        84255 :     case RTX_TERNARY:
    9224        84255 :     case RTX_BITFIELD_OPS:
    9225        84255 :       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
    9226        84255 :                                          XEXP (x, 0), XEXP (x, 1),
    9227        84255 :                                          XEXP (x, 2));
    9228              : 
    9229       207577 :     case RTX_COMPARE:
    9230       207577 :     case RTX_COMM_COMPARE:
    9231       207577 :       return simplify_relational_operation (code, mode,
    9232       207577 :                                             ((GET_MODE (XEXP (x, 0))
    9233              :                                              != VOIDmode)
    9234              :                                             ? GET_MODE (XEXP (x, 0))
    9235          354 :                                             : GET_MODE (XEXP (x, 1))),
    9236       207577 :                                             XEXP (x, 0),
    9237       415154 :                                             XEXP (x, 1));
    9238              : 
    9239       226600 :     case RTX_EXTRA:
    9240       226600 :       if (code == SUBREG)
    9241         2135 :         return simplify_subreg (mode, SUBREG_REG (x),
    9242         2135 :                                 GET_MODE (SUBREG_REG (x)),
    9243         2135 :                                 SUBREG_BYTE (x));
    9244              :       break;
    9245              : 
    9246      6727634 :     case RTX_OBJ:
    9247      6727634 :       if (code == LO_SUM)
    9248              :         {
    9249              :           /* Convert (lo_sum (high FOO) FOO) to FOO.  */
    9250            0 :           if (GET_CODE (XEXP (x, 0)) == HIGH
    9251            0 :               && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
    9252            0 :           return XEXP (x, 1);
    9253              :         }
    9254              :       break;
    9255              : 
    9256              :     default:
    9257              :       break;
    9258              :     }
    9259              :   return NULL;
    9260              : }
    9261              : 
    9262              : #if CHECKING_P
    9263              : 
    9264              : namespace selftest {
    9265              : 
    9266              : /* Make a unique pseudo REG of mode MODE for use by selftests.  */
    9267              : 
    9268              : static rtx
    9269         2672 : make_test_reg (machine_mode mode)
    9270              : {
    9271         2672 :   static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
    9272              : 
    9273         2672 :   return gen_rtx_REG (mode, test_reg_num++);
    9274              : }
    9275              : 
    9276              : static void
    9277           40 : test_scalar_int_ops (machine_mode mode)
    9278              : {
    9279           40 :   rtx op0 = make_test_reg (mode);
    9280           40 :   rtx op1 = make_test_reg (mode);
    9281           40 :   rtx six = GEN_INT (6);
    9282              : 
    9283           40 :   rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
    9284           40 :   rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
    9285           40 :   rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
    9286              : 
    9287           40 :   rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
    9288           40 :   rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
    9289           40 :   rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
    9290              : 
    9291           40 :   rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
    9292           40 :   rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
    9293              : 
    9294              :   /* Test some binary identities.  */
    9295           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
    9296           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
    9297           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
    9298           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
    9299           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
    9300           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
    9301           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
    9302           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
    9303           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
    9304           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
    9305           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
    9306           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
    9307           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
    9308           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
    9309           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
    9310           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
    9311           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
    9312              : 
    9313              :   /* Test some self-inverse operations.  */
    9314           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
    9315           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
    9316           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
    9317              : 
    9318              :   /* Test some reflexive operations.  */
    9319           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
    9320           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
    9321           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
    9322           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
    9323           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
    9324           40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
    9325              : 
    9326           40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
    9327           40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
    9328              : 
    9329              :   /* Test simplify_distributive_operation.  */
    9330           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
    9331              :                  simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
    9332           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
    9333              :                  simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
    9334           40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
    9335              :                  simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
    9336              : 
    9337              :   /* Test useless extensions are eliminated.  */
    9338           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
    9339           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
    9340           40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
    9341           40 :   ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
    9342           40 : }
    9343              : 
    9344              : /* Verify some simplifications of integer extension/truncation.
    9345              :    Machine mode BMODE is the guaranteed wider than SMODE.  */
    9346              : 
    9347              : static void
    9348           24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
    9349              : {
    9350           24 :   rtx sreg = make_test_reg (smode);
    9351              : 
    9352              :   /* Check truncation of extension.  */
    9353           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9354              :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    9355              :                                                          sreg, smode),
    9356              :                                      bmode),
    9357              :                  sreg);
    9358           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9359              :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    9360              :                                                          sreg, smode),
    9361              :                                      bmode),
    9362              :                  sreg);
    9363           24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9364              :                                      lowpart_subreg (bmode, sreg, smode),
    9365              :                                      bmode),
    9366              :                  sreg);
    9367              : 
    9368              :   /* Test extensions, followed by logic ops, followed by truncations.  */
    9369           24 :   rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
    9370           24 :   rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
    9371           24 :   rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
    9372           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9373              :                                  simplify_gen_binary (AND, bmode,
    9374              :                                                       bsubreg, smask),
    9375              :                                  bmode),
    9376              :                  sreg);
    9377           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9378              :                                  simplify_gen_binary (AND, bmode,
    9379              :                                                       bsubreg, inv_smask),
    9380              :                                  bmode),
    9381              :                  const0_rtx);
    9382           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9383              :                                  simplify_gen_binary (IOR, bmode,
    9384              :                                                       bsubreg, smask),
    9385              :                                  bmode),
    9386              :                  constm1_rtx);
    9387           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9388              :                                  simplify_gen_binary (IOR, bmode,
    9389              :                                                       bsubreg, inv_smask),
    9390              :                                  bmode),
    9391              :                  sreg);
    9392           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9393              :                                  simplify_gen_binary (XOR, bmode,
    9394              :                                                       bsubreg, smask),
    9395              :                                  bmode),
    9396              :                  lowpart_subreg (smode,
    9397              :                                  gen_rtx_NOT (bmode, bsubreg),
    9398              :                                  bmode));
    9399           24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    9400              :                                  simplify_gen_binary (XOR, bmode,
    9401              :                                                       bsubreg, inv_smask),
    9402              :                                  bmode),
    9403              :                  sreg);
    9404              : 
    9405           24 :   if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
    9406              :     {
    9407           24 :       rtx breg1 = make_test_reg (bmode);
    9408           24 :       rtx breg2 = make_test_reg (bmode);
    9409           24 :       rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
    9410           24 :       rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
    9411           24 :       rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
    9412           24 :       rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
    9413           24 :       rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
    9414           24 :       rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
    9415           24 :       rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
    9416           24 :       rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
    9417           24 :       rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
    9418           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
    9419              :                      gen_rtx_NOT (bmode, breg1));
    9420           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
    9421              :                      gen_rtx_AND (bmode, breg1, breg2));
    9422           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
    9423              :                      gen_rtx_IOR (bmode, breg1, breg2));
    9424           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
    9425              :                      gen_rtx_XOR (bmode, breg1, breg2));
    9426           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
    9427              :                      gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    9428           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
    9429              :                      gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    9430           24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
    9431              :                      gen_rtx_XOR (bmode,
    9432              :                                   gen_rtx_XOR (bmode, breg1, breg2),
    9433              :                                   const1_rtx));
    9434              :     }
    9435           24 : }
    9436              : 
    9437              : /* Verify more simplifications of integer extension/truncation.
    9438              :    BMODE is wider than MMODE which is wider than SMODE.  */
    9439              : 
    9440              : static void
    9441           16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
    9442              :                           machine_mode smode)
    9443              : {
    9444           16 :   rtx breg = make_test_reg (bmode);
    9445           16 :   rtx mreg = make_test_reg (mmode);
    9446           16 :   rtx sreg = make_test_reg (smode);
    9447              : 
    9448              :   /* Check truncate of truncate.  */
    9449           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9450              :                                      simplify_gen_unary (TRUNCATE, mmode,
    9451              :                                                          breg, bmode),
    9452              :                                      mmode),
    9453              :                  simplify_gen_unary (TRUNCATE, smode, breg, bmode));
    9454              : 
    9455              :   /* Check extension of extension.  */
    9456           16 :   ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
    9457              :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    9458              :                                                          sreg, smode),
    9459              :                                      mmode),
    9460              :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    9461           16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    9462              :                                      simplify_gen_unary (SIGN_EXTEND, mmode,
    9463              :                                                          sreg, smode),
    9464              :                                      mmode),
    9465              :                  simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
    9466           16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    9467              :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    9468              :                                                          sreg, smode),
    9469              :                                      mmode),
    9470              :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    9471              : 
    9472              :   /* Check truncation of extension.  */
    9473           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9474              :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    9475              :                                                          mreg, mmode),
    9476              :                                      bmode),
    9477              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9478           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9479              :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    9480              :                                                          mreg, mmode),
    9481              :                                      bmode),
    9482              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9483           16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    9484              :                                      lowpart_subreg (bmode, mreg, mmode),
    9485              :                                      bmode),
    9486              :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    9487           16 : }
    9488              : 
    9489              : /* Test comparisons of comparisons, with the inner comparisons being
    9490              :    between values of mode MODE2 and producing results of mode MODE1,
    9491              :    and with the outer comparisons producing results of mode MODE0.  */
    9492              : 
    9493              : static void
    9494            4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
    9495              : {
    9496            4 :   rtx reg0 = make_test_reg (mode2);
    9497            4 :   rtx reg1 = make_test_reg (mode2);
    9498              : 
    9499            4 :   static const rtx_code codes[] = {
    9500              :     EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
    9501              :   };
    9502            4 :   constexpr auto num_codes = ARRAY_SIZE (codes);
    9503            4 :   rtx cmps[num_codes];
    9504            4 :   rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
    9505              : 
    9506           44 :   for (unsigned int i = 0; i < num_codes; ++i)
    9507           40 :     cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
    9508              : 
    9509           44 :   for (auto code : codes)
    9510          440 :     for (unsigned int i0 = 0; i0 < num_codes; ++i0)
    9511         4400 :       for (unsigned int i1 = 0; i1 < num_codes; ++i1)
    9512              :         {
    9513         4000 :           rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
    9514              :                                                        cmps[i0], cmps[i1]);
    9515         4000 :           if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
    9516         1280 :             ASSERT_TRUE (cmp_res == NULL_RTX);
    9517              :           else
    9518              :             {
    9519         2720 :               ASSERT_TRUE (cmp_res != NULL_RTX
    9520              :                            && (CONSTANT_P (cmp_res)
    9521              :                                || (COMPARISON_P (cmp_res)
    9522              :                                    && GET_MODE (cmp_res) == mode0
    9523              :                                    && REG_P (XEXP (cmp_res, 0))
    9524              :                                    && REG_P (XEXP (cmp_res, 1)))));
    9525        10880 :               for (rtx reg0_val : vals)
    9526        32640 :                 for (rtx reg1_val : vals)
    9527              :                   {
    9528        24480 :                     rtx val0 = simplify_const_relational_operation
    9529        24480 :                       (codes[i0], mode1, reg0_val, reg1_val);
    9530        24480 :                     rtx val1 = simplify_const_relational_operation
    9531        24480 :                       (codes[i1], mode1, reg0_val, reg1_val);
    9532        24480 :                     rtx val = simplify_const_relational_operation
    9533        24480 :                       (code, mode0, val0, val1);
    9534        24480 :                     rtx folded = cmp_res;
    9535        24480 :                     if (COMPARISON_P (cmp_res))
    9536        16704 :                       folded = simplify_const_relational_operation
    9537        16704 :                         (GET_CODE (cmp_res), mode0,
    9538        16704 :                          XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
    9539        16704 :                          XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
    9540        24480 :                     ASSERT_RTX_EQ (val, folded);
    9541              :                   }
    9542              :             }
    9543              :         }
    9544            4 : }
    9545              : 
    9546              : 
    9547              : /* Verify some simplifications involving scalar expressions.  */
    9548              : 
    9549              : static void
    9550            4 : test_scalar_ops ()
    9551              : {
    9552          500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    9553              :     {
    9554          496 :       machine_mode mode = (machine_mode) i;
    9555          496 :       if (SCALAR_INT_MODE_P (mode) && mode != BImode)
    9556           40 :         test_scalar_int_ops (mode);
    9557              :     }
    9558              : 
    9559            4 :   test_scalar_int_ext_ops (HImode, QImode);
    9560            4 :   test_scalar_int_ext_ops (SImode, QImode);
    9561            4 :   test_scalar_int_ext_ops (SImode, HImode);
    9562            4 :   test_scalar_int_ext_ops (DImode, QImode);
    9563            4 :   test_scalar_int_ext_ops (DImode, HImode);
    9564            4 :   test_scalar_int_ext_ops (DImode, SImode);
    9565              : 
    9566            4 :   test_scalar_int_ext_ops2 (SImode, HImode, QImode);
    9567            4 :   test_scalar_int_ext_ops2 (DImode, HImode, QImode);
    9568            4 :   test_scalar_int_ext_ops2 (DImode, SImode, QImode);
    9569            4 :   test_scalar_int_ext_ops2 (DImode, SImode, HImode);
    9570              : 
    9571            4 :   test_comparisons (QImode, HImode, SImode);
    9572            4 : }
    9573              : 
    9574              : /* Test vector simplifications involving VEC_DUPLICATE in which the
    9575              :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9576              :    register that holds one element of MODE.  */
    9577              : 
    9578              : static void
    9579          224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
    9580              : {
    9581          224 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9582          224 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9583          448 :   poly_uint64 nunits = GET_MODE_NUNITS (mode);
    9584          224 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    9585              :     {
    9586              :       /* Test some simple unary cases with VEC_DUPLICATE arguments.  */
    9587          124 :       rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
    9588          124 :       rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
    9589          124 :       ASSERT_RTX_EQ (duplicate,
    9590              :                      simplify_unary_operation (NOT, mode,
    9591              :                                                duplicate_not, mode));
    9592              : 
    9593          124 :       rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9594          124 :       rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
    9595          124 :       ASSERT_RTX_EQ (duplicate,
    9596              :                      simplify_unary_operation (NEG, mode,
    9597              :                                                duplicate_neg, mode));
    9598              : 
    9599              :       /* Test some simple binary cases with VEC_DUPLICATE arguments.  */
    9600          124 :       ASSERT_RTX_EQ (duplicate,
    9601              :                      simplify_binary_operation (PLUS, mode, duplicate,
    9602              :                                                 CONST0_RTX (mode)));
    9603              : 
    9604          124 :       ASSERT_RTX_EQ (duplicate,
    9605              :                      simplify_binary_operation (MINUS, mode, duplicate,
    9606              :                                                 CONST0_RTX (mode)));
    9607              : 
    9608          124 :       ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
    9609              :                          simplify_binary_operation (MINUS, mode, duplicate,
    9610              :                                                     duplicate));
    9611              :     }
    9612              : 
    9613              :   /* Test a scalar VEC_SELECT of a VEC_DUPLICATE.  */
    9614          224 :   rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
    9615          224 :   ASSERT_RTX_PTR_EQ (scalar_reg,
    9616              :                      simplify_binary_operation (VEC_SELECT, inner_mode,
    9617              :                                                 duplicate, zero_par));
    9618              : 
    9619          224 :   unsigned HOST_WIDE_INT const_nunits;
    9620          224 :   if (nunits.is_constant (&const_nunits))
    9621              :     {
    9622              :       /* And again with the final element.  */
    9623          224 :       rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
    9624          224 :       rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
    9625          224 :       ASSERT_RTX_PTR_EQ (scalar_reg,
    9626              :                          simplify_binary_operation (VEC_SELECT, inner_mode,
    9627              :                                                     duplicate, last_par));
    9628              : 
    9629              :       /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE.  */
    9630              :       /* Skip this test for vectors of booleans, because offset is in bytes,
    9631              :          while vec_merge indices are in elements (usually bits).  */
    9632          224 :       if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
    9633              :         {
    9634          224 :           rtx vector_reg = make_test_reg (mode);
    9635         3732 :           for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
    9636              :             {
    9637         3288 :               if (i >= HOST_BITS_PER_WIDE_INT)
    9638              :                 break;
    9639         3284 :               rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
    9640         3284 :               rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
    9641         6568 :               poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
    9642              : 
    9643         3284 :               ASSERT_RTX_EQ (scalar_reg,
    9644              :                              simplify_gen_subreg (inner_mode, vm,
    9645              :                                                   mode, offset));
    9646              :             }
    9647              :         }
    9648              :     }
    9649              : 
    9650              :   /* Test a scalar subreg of a VEC_DUPLICATE.  */
    9651          224 :   poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
    9652          224 :   ASSERT_RTX_EQ (scalar_reg,
    9653              :                  simplify_gen_subreg (inner_mode, duplicate,
    9654              :                                       mode, offset));
    9655              : 
    9656          224 :   machine_mode narrower_mode;
    9657          224 :   if (maybe_ne (nunits, 2U)
    9658          184 :       && multiple_p (nunits, 2)
    9659          396 :       && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
    9660          396 :       && VECTOR_MODE_P (narrower_mode))
    9661              :     {
    9662              :       /* Test VEC_DUPLICATE of a vector.  */
    9663          172 :       rtx_vector_builder nbuilder (narrower_mode, 2, 1);
    9664          172 :       nbuilder.quick_push (const0_rtx);
    9665          172 :       nbuilder.quick_push (const1_rtx);
    9666          172 :       rtx_vector_builder builder (mode, 2, 1);
    9667          172 :       builder.quick_push (const0_rtx);
    9668          172 :       builder.quick_push (const1_rtx);
    9669          172 :       ASSERT_RTX_EQ (builder.build (),
    9670              :                      simplify_unary_operation (VEC_DUPLICATE, mode,
    9671              :                                                nbuilder.build (),
    9672              :                                                narrower_mode));
    9673              : 
    9674              :       /* Test VEC_SELECT of a vector.  */
    9675          172 :       rtx vec_par
    9676          172 :         = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
    9677          172 :       rtx narrower_duplicate
    9678          172 :         = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
    9679          172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9680              :                      simplify_binary_operation (VEC_SELECT, narrower_mode,
    9681              :                                                 duplicate, vec_par));
    9682              : 
    9683              :       /* Test a vector subreg of a VEC_DUPLICATE.  */
    9684          172 :       poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
    9685          172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9686              :                      simplify_gen_subreg (narrower_mode, duplicate,
    9687              :                                           mode, offset));
    9688          172 :     }
    9689          224 : }
    9690              : 
    9691              : /* Test vector simplifications involving VEC_SERIES in which the
    9692              :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9693              :    register that holds one element of MODE.  */
    9694              : 
    9695              : static void
    9696           92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
    9697              : {
    9698              :   /* Test unary cases with VEC_SERIES arguments.  */
    9699           92 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9700           92 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9701           92 :   rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9702           92 :   rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
    9703           92 :   rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
    9704           92 :   rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
    9705           92 :   rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
    9706           92 :   rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
    9707           92 :   rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
    9708              :                                          neg_scalar_reg);
    9709           92 :   ASSERT_RTX_EQ (series_0_r,
    9710              :                  simplify_unary_operation (NEG, mode, series_0_nr, mode));
    9711           92 :   ASSERT_RTX_EQ (series_r_m1,
    9712              :                  simplify_unary_operation (NEG, mode, series_nr_1, mode));
    9713           92 :   ASSERT_RTX_EQ (series_r_r,
    9714              :                  simplify_unary_operation (NEG, mode, series_nr_nr, mode));
    9715              : 
    9716              :   /* Test that a VEC_SERIES with a zero step is simplified away.  */
    9717           92 :   ASSERT_RTX_EQ (duplicate,
    9718              :                  simplify_binary_operation (VEC_SERIES, mode,
    9719              :                                             scalar_reg, const0_rtx));
    9720              : 
    9721              :   /* Test PLUS and MINUS with VEC_SERIES.  */
    9722           92 :   rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
    9723           92 :   rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
    9724           92 :   rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
    9725           92 :   ASSERT_RTX_EQ (series_r_r,
    9726              :                  simplify_binary_operation (PLUS, mode, series_0_r,
    9727              :                                             duplicate));
    9728           92 :   ASSERT_RTX_EQ (series_r_1,
    9729              :                  simplify_binary_operation (PLUS, mode, duplicate,
    9730              :                                             series_0_1));
    9731           92 :   ASSERT_RTX_EQ (series_r_m1,
    9732              :                  simplify_binary_operation (PLUS, mode, duplicate,
    9733              :                                             series_0_m1));
    9734           92 :   ASSERT_RTX_EQ (series_0_r,
    9735              :                  simplify_binary_operation (MINUS, mode, series_r_r,
    9736              :                                             duplicate));
    9737           92 :   ASSERT_RTX_EQ (series_r_m1,
    9738              :                  simplify_binary_operation (MINUS, mode, duplicate,
    9739              :                                             series_0_1));
    9740           92 :   ASSERT_RTX_EQ (series_r_1,
    9741              :                  simplify_binary_operation (MINUS, mode, duplicate,
    9742              :                                             series_0_m1));
    9743           92 :   ASSERT_RTX_EQ (series_0_m1,
    9744              :                  simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
    9745              :                                             constm1_rtx));
    9746              : 
    9747              :   /* Test NEG on constant vector series.  */
    9748           92 :   ASSERT_RTX_EQ (series_0_m1,
    9749              :                  simplify_unary_operation (NEG, mode, series_0_1, mode));
    9750           92 :   ASSERT_RTX_EQ (series_0_1,
    9751              :                  simplify_unary_operation (NEG, mode, series_0_m1, mode));
    9752              : 
    9753              :   /* Test PLUS and MINUS on constant vector series.  */
    9754           92 :   rtx scalar2 = gen_int_mode (2, inner_mode);
    9755           92 :   rtx scalar3 = gen_int_mode (3, inner_mode);
    9756           92 :   rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
    9757           92 :   rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
    9758           92 :   rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
    9759           92 :   ASSERT_RTX_EQ (series_1_1,
    9760              :                  simplify_binary_operation (PLUS, mode, series_0_1,
    9761              :                                             CONST1_RTX (mode)));
    9762           92 :   ASSERT_RTX_EQ (series_0_m1,
    9763              :                  simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
    9764              :                                             series_0_m1));
    9765           92 :   ASSERT_RTX_EQ (series_1_3,
    9766              :                  simplify_binary_operation (PLUS, mode, series_1_1,
    9767              :                                             series_0_2));
    9768           92 :   ASSERT_RTX_EQ (series_0_1,
    9769              :                  simplify_binary_operation (MINUS, mode, series_1_1,
    9770              :                                             CONST1_RTX (mode)));
    9771           92 :   ASSERT_RTX_EQ (series_1_1,
    9772              :                  simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
    9773              :                                             series_0_m1));
    9774           92 :   ASSERT_RTX_EQ (series_1_1,
    9775              :                  simplify_binary_operation (MINUS, mode, series_1_3,
    9776              :                                             series_0_2));
    9777              : 
    9778              :   /* Test MULT between constant vectors.  */
    9779           92 :   rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
    9780           92 :   rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
    9781           92 :   rtx scalar9 = gen_int_mode (9, inner_mode);
    9782           92 :   rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
    9783           92 :   ASSERT_RTX_EQ (series_0_2,
    9784              :                  simplify_binary_operation (MULT, mode, series_0_1, vec2));
    9785           92 :   ASSERT_RTX_EQ (series_3_9,
    9786              :                  simplify_binary_operation (MULT, mode, vec3, series_1_3));
    9787           92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9788              :     ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
    9789              :                                              series_0_1));
    9790              : 
    9791              :   /* Test ASHIFT between constant vectors.  */
    9792           92 :   ASSERT_RTX_EQ (series_0_2,
    9793              :                  simplify_binary_operation (ASHIFT, mode, series_0_1,
    9794              :                                             CONST1_RTX (mode)));
    9795           92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9796              :     ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
    9797              :                                              series_0_1));
    9798           92 : }
    9799              : 
    9800              : static rtx
    9801         3136 : simplify_merge_mask (rtx x, rtx mask, int op)
    9802              : {
    9803            0 :   return simplify_context ().simplify_merge_mask (x, mask, op);
    9804              : }
    9805              : 
    9806              : /* Verify simplify_merge_mask works correctly.  */
    9807              : 
    9808              : static void
    9809          224 : test_vec_merge (machine_mode mode)
    9810              : {
    9811          224 :   rtx op0 = make_test_reg (mode);
    9812          224 :   rtx op1 = make_test_reg (mode);
    9813          224 :   rtx op2 = make_test_reg (mode);
    9814          224 :   rtx op3 = make_test_reg (mode);
    9815          224 :   rtx op4 = make_test_reg (mode);
    9816          224 :   rtx op5 = make_test_reg (mode);
    9817          224 :   rtx mask1 = make_test_reg (SImode);
    9818          224 :   rtx mask2 = make_test_reg (SImode);
    9819          224 :   rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
    9820          224 :   rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
    9821          224 :   rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
    9822              : 
    9823              :   /* Simple vec_merge.  */
    9824          224 :   ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
    9825          224 :   ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
    9826          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
    9827          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
    9828              : 
    9829              :   /* Nested vec_merge.
    9830              :      It's tempting to make this simplify right down to opN, but we don't
    9831              :      because all the simplify_* functions assume that the operands have
    9832              :      already been simplified.  */
    9833          224 :   rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
    9834          224 :   ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
    9835          224 :   ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
    9836              : 
    9837              :   /* Intermediate unary op. */
    9838          224 :   rtx unop = gen_rtx_NOT (mode, vm1);
    9839          224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
    9840              :                  simplify_merge_mask (unop, mask1, 0));
    9841          224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
    9842              :                  simplify_merge_mask (unop, mask1, 1));
    9843              : 
    9844              :   /* Intermediate binary op. */
    9845          224 :   rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
    9846          224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
    9847              :                  simplify_merge_mask (binop, mask1, 0));
    9848          224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
    9849              :                  simplify_merge_mask (binop, mask1, 1));
    9850              : 
    9851              :   /* Intermediate ternary op. */
    9852          224 :   rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
    9853          224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
    9854              :                  simplify_merge_mask (tenop, mask1, 0));
    9855          224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
    9856              :                  simplify_merge_mask (tenop, mask1, 1));
    9857              : 
    9858              :   /* Side effects.  */
    9859          224 :   rtx badop0 = gen_rtx_PRE_INC (mode, op0);
    9860          224 :   rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
    9861          224 :   ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
    9862          224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
    9863              : 
    9864              :   /* Called indirectly.  */
    9865          224 :   ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
    9866              :                  simplify_rtx (nvm));
    9867          224 : }
    9868              : 
    9869              : /* Test that vector rotate formation works at RTL level.  Try various
    9870              :    combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)).  */
    9871              : 
    9872              : static void
    9873           92 : test_vector_rotate (rtx reg)
    9874              : {
    9875           92 :   machine_mode mode = GET_MODE (reg);
    9876           92 :   unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
    9877           92 :   rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
    9878           92 :   rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
    9879           92 :   lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
    9880           92 :   rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9881           92 :   rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
    9882              :   /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x).  */
    9883           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9884              :              simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
    9885           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9886              :              simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
    9887           92 :   ASSERT_RTX_EQ (rotate_rtx,
    9888              :              simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
    9889              : 
    9890              :   /* Don't go through every possible rotate amount to save execution time.
    9891              :      Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
    9892              :      other bswap operations sometimes. Go through just the odd amounts.  */
    9893         1380 :   for (unsigned i = 3; i < bitwidth - 2; i += 2)
    9894              :     {
    9895         1288 :       rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
    9896         1288 :       rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
    9897         1288 :       lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
    9898         1288 :       lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9899         1288 :       rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
    9900         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9901              :                  simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
    9902         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9903              :                  simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
    9904         1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9905              :                  simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
    9906              :     }
    9907           92 : }
    9908              : 
    9909              : /* Test subregs of integer vector constant X, trying elements in
    9910              :    the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
    9911              :    where NELTS is the number of elements in X.  Subregs involving
    9912              :    elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail.  */
    9913              : 
    9914              : static void
    9915          276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
    9916              :                            unsigned int first_valid = 0)
    9917              : {
    9918          276 :   machine_mode inner_mode = GET_MODE (x);
    9919          276 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9920              : 
    9921        34500 :   for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
    9922              :     {
    9923        34224 :       machine_mode outer_mode = (machine_mode) modei;
    9924        34224 :       if (!VECTOR_MODE_P (outer_mode))
    9925        18768 :         continue;
    9926              : 
    9927        15456 :       unsigned int outer_nunits;
    9928        15456 :       if (GET_MODE_INNER (outer_mode) == int_mode
    9929         1932 :           && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
    9930        20412 :           && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
    9931              :         {
    9932              :           /* Test subregs in which the outer mode is a smaller,
    9933              :              constant-sized vector of the same element type.  */
    9934         1092 :           unsigned int limit
    9935         1092 :             = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
    9936         8028 :           for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
    9937              :             {
    9938         6936 :               rtx expected = NULL_RTX;
    9939         6936 :               if (elt >= first_valid)
    9940              :                 {
    9941         6936 :                   rtx_vector_builder builder (outer_mode, outer_nunits, 1);
    9942        46704 :                   for (unsigned int i = 0; i < outer_nunits; ++i)
    9943        32832 :                     builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
    9944         6936 :                   expected = builder.build ();
    9945         6936 :                 }
    9946        13872 :               poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
    9947         6936 :               ASSERT_RTX_EQ (expected,
    9948              :                              simplify_subreg (outer_mode, x,
    9949              :                                               inner_mode, byte));
    9950              :             }
    9951              :         }
    9952        28728 :       else if (known_eq (GET_MODE_SIZE (outer_mode),
    9953              :                          GET_MODE_SIZE (inner_mode))
    9954         2040 :                && known_eq (elt_bias, 0U)
    9955         2040 :                && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
    9956            0 :                    || known_eq (GET_MODE_BITSIZE (outer_mode),
    9957              :                                 GET_MODE_NUNITS (outer_mode)))
    9958         2040 :                && (!FLOAT_MODE_P (outer_mode)
    9959        15876 :                    || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
    9960         1104 :                        == GET_MODE_UNIT_PRECISION (outer_mode)))
    9961        14364 :                && (GET_MODE_SIZE (inner_mode).is_constant ()
    9962              :                    || !CONST_VECTOR_STEPPED_P (x)))
    9963              :         {
    9964              :           /* Try converting to OUTER_MODE and back.  */
    9965         1800 :           rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
    9966         1800 :           ASSERT_TRUE (outer_x != NULL_RTX);
    9967         1800 :           ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
    9968              :                                              outer_mode, 0));
    9969              :         }
    9970              :     }
    9971              : 
    9972          276 :   if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
    9973              :     {
    9974              :       /* Test each byte in the element range.  */
    9975          276 :       unsigned int limit
    9976          276 :         = constant_lower_bound (GET_MODE_SIZE (inner_mode));
    9977        14604 :       for (unsigned int i = 0; i < limit; ++i)
    9978              :         {
    9979        14328 :           unsigned int elt = i / GET_MODE_SIZE (int_mode);
    9980        14328 :           rtx expected = NULL_RTX;
    9981        14328 :           if (elt >= first_valid)
    9982              :             {
    9983        14328 :               unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
    9984        14328 :               if (BYTES_BIG_ENDIAN)
    9985              :                 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
    9986        14328 :               rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
    9987        14328 :               wide_int shifted_elt
    9988        14328 :                 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
    9989        14328 :               expected = immed_wide_int_const (shifted_elt, QImode);
    9990        14328 :             }
    9991        28656 :           poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
    9992        14328 :           ASSERT_RTX_EQ (expected,
    9993              :                          simplify_subreg (QImode, x, inner_mode, byte));
    9994              :         }
    9995              :     }
    9996          276 : }
    9997              : 
    9998              : /* Test constant subregs of integer vector mode INNER_MODE, using 1
    9999              :    element per pattern.  */
   10000              : 
   10001              : static void
   10002           92 : test_vector_subregs_repeating (machine_mode inner_mode)
   10003              : {
   10004          184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
   10005           92 :   unsigned int min_nunits = constant_lower_bound (nunits);
   10006           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
   10007           92 :   unsigned int count = gcd (min_nunits, 8);
   10008              : 
   10009           92 :   rtx_vector_builder builder (inner_mode, count, 1);
   10010          776 :   for (unsigned int i = 0; i < count; ++i)
   10011          592 :     builder.quick_push (gen_int_mode (8 - i, int_mode));
   10012           92 :   rtx x = builder.build ();
   10013              : 
   10014           92 :   test_vector_subregs_modes (x);
   10015           92 :   if (!nunits.is_constant ())
   10016              :     test_vector_subregs_modes (x, nunits - min_nunits);
   10017           92 : }
   10018              : 
   10019              : /* Test constant subregs of integer vector mode INNER_MODE, using 2
   10020              :    elements per pattern.  */
   10021              : 
   10022              : static void
   10023           92 : test_vector_subregs_fore_back (machine_mode inner_mode)
   10024              : {
   10025          184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
   10026           92 :   unsigned int min_nunits = constant_lower_bound (nunits);
   10027           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
   10028           92 :   unsigned int count = gcd (min_nunits, 4);
   10029              : 
   10030           92 :   rtx_vector_builder builder (inner_mode, count, 2);
   10031          536 :   for (unsigned int i = 0; i < count; ++i)
   10032          352 :     builder.quick_push (gen_int_mode (i, int_mode));
   10033          444 :   for (unsigned int i = 0; i < count; ++i)
   10034          352 :     builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
   10035           92 :   rtx x = builder.build ();
   10036              : 
   10037           92 :   test_vector_subregs_modes (x);
   10038           92 :   if (!nunits.is_constant ())
   10039              :     test_vector_subregs_modes (x, nunits - min_nunits, count);
   10040           92 : }
   10041              : 
   10042              : /* Test constant subregs of integer vector mode INNER_MODE, using 3
   10043              :    elements per pattern.  */
   10044              : 
   10045              : static void
   10046           92 : test_vector_subregs_stepped (machine_mode inner_mode)
   10047              : {
   10048              :   /* Build { 0, 1, 2, 3, ... }.  */
   10049           92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
   10050           92 :   rtx_vector_builder builder (inner_mode, 1, 3);
   10051          460 :   for (unsigned int i = 0; i < 3; ++i)
   10052          276 :     builder.quick_push (gen_int_mode (i, int_mode));
   10053           92 :   rtx x = builder.build ();
   10054              : 
   10055           92 :   test_vector_subregs_modes (x);
   10056           92 : }
   10057              : 
   10058              : /* Test constant subregs of integer vector mode INNER_MODE.  */
   10059              : 
   10060              : static void
   10061           92 : test_vector_subregs (machine_mode inner_mode)
   10062              : {
   10063           92 :   test_vector_subregs_repeating (inner_mode);
   10064           92 :   test_vector_subregs_fore_back (inner_mode);
   10065           92 :   test_vector_subregs_stepped (inner_mode);
   10066           92 : }
   10067              : 
   10068              : /* Verify some simplifications involving vectors.  */
   10069              : 
   10070              : static void
   10071            4 : test_vector_ops ()
   10072              : {
   10073          500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
   10074              :     {
   10075          496 :       machine_mode mode = (machine_mode) i;
   10076          496 :       if (VECTOR_MODE_P (mode))
   10077              :         {
   10078          448 :           rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
   10079          224 :           test_vector_ops_duplicate (mode, scalar_reg);
   10080          224 :           rtx vector_reg = make_test_reg (mode);
   10081          224 :           if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   10082          348 :               && maybe_gt (GET_MODE_NUNITS (mode), 2))
   10083              :             {
   10084           92 :               test_vector_ops_series (mode, scalar_reg);
   10085           92 :               test_vector_subregs (mode);
   10086           92 :               test_vector_rotate (vector_reg);
   10087              :             }
   10088          224 :           test_vec_merge (mode);
   10089              :         }
   10090              :     }
   10091            4 : }
   10092              : 
   10093              : template<unsigned int N>
   10094              : struct simplify_const_poly_int_tests
   10095              : {
   10096              :   static void run ();
   10097              : };
   10098              : 
   10099              : template<>
   10100              : struct simplify_const_poly_int_tests<1>
   10101              : {
   10102              :   static void run () {}
   10103              : };
   10104              : 
   10105              : /* Test various CONST_POLY_INT properties.  */
   10106              : 
   10107              : template<unsigned int N>
   10108              : void
   10109              : simplify_const_poly_int_tests<N>::run ()
   10110              : {
   10111              :   using poly_int64 = poly_int<N, HOST_WIDE_INT>;
   10112              :   rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
   10113              :   rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
   10114              :   rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
   10115              :   rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
   10116              :   rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
   10117              :   rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
   10118              :   rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
   10119              :   rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
   10120              :   rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
   10121              :   rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
   10122              :   rtx two = GEN_INT (2);
   10123              :   rtx six = GEN_INT (6);
   10124              :   poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
   10125              : 
   10126              :   /* These tests only try limited operation combinations.  Fuller arithmetic
   10127              :      testing is done directly on poly_ints.  */
   10128              :   ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
   10129              :   ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
   10130              :   ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
   10131              :   ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
   10132              :   ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
   10133              :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
   10134              :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
   10135              :   ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
   10136              :   ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
   10137              :   ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
   10138              :   ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
   10139              : }
   10140              : 
   10141              : /* Run all of the selftests within this file.  */
   10142              : 
   10143              : void
   10144            4 : simplify_rtx_cc_tests ()
   10145              : {
   10146            4 :   test_scalar_ops ();
   10147            4 :   test_vector_ops ();
   10148            4 :   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
   10149            4 : }
   10150              : 
   10151              : } // namespace selftest
   10152              : 
   10153              : #endif /* CHECKING_P */
        

Generated by: LCOV version 2.5.0-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.