LCOV - code coverage report
Current view: top level - gcc - simplify-rtx.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.2 % 4684 4179
Test Date: 2025-09-20 13:40:47 Functions: 96.2 % 79 76
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* RTL simplification functions for GNU compiler.
       2                 :             :    Copyright (C) 1987-2025 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                 :     9009748 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
      56                 :             : {
      57                 :     9009748 :   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                 :     6341547 : mode_signbit_p (machine_mode mode, const_rtx x)
      65                 :             : {
      66                 :     6341547 :   unsigned HOST_WIDE_INT val;
      67                 :     6341547 :   unsigned int width;
      68                 :     6341547 :   scalar_int_mode int_mode;
      69                 :             : 
      70                 :     6341547 :   if (!is_int_mode (mode, &int_mode))
      71                 :             :     return false;
      72                 :             : 
      73                 :     6341539 :   width = GET_MODE_PRECISION (int_mode);
      74                 :     6341539 :   if (width == 0)
      75                 :             :     return false;
      76                 :             : 
      77                 :     6341539 :   if (width <= HOST_BITS_PER_WIDE_INT
      78                 :     6340003 :       && CONST_INT_P (x))
      79                 :     6221537 :     val = INTVAL (x);
      80                 :             : #if TARGET_SUPPORTS_WIDE_INT
      81                 :      120002 :   else if (CONST_WIDE_INT_P (x))
      82                 :             :     {
      83                 :         474 :       unsigned int i;
      84                 :         474 :       unsigned int elts = CONST_WIDE_INT_NUNITS (x);
      85                 :         474 :       if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
      86                 :             :         return false;
      87                 :         888 :       for (i = 0; i < elts - 1; i++)
      88                 :         474 :         if (CONST_WIDE_INT_ELT (x, i) != 0)
      89                 :             :           return false;
      90                 :         414 :       val = CONST_WIDE_INT_ELT (x, elts - 1);
      91                 :         414 :       width %= HOST_BITS_PER_WIDE_INT;
      92                 :         414 :       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                 :     6221537 :   if (width < HOST_BITS_PER_WIDE_INT)
     109                 :     5620432 :     val &= (HOST_WIDE_INT_1U << width) - 1;
     110                 :     6221951 :   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                 :     3763386 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     119                 :             : {
     120                 :     3763386 :   unsigned int width;
     121                 :     3763386 :   scalar_int_mode int_mode;
     122                 :             : 
     123                 :     3763386 :   if (!is_int_mode (mode, &int_mode))
     124                 :             :     return false;
     125                 :             : 
     126                 :     3763350 :   width = GET_MODE_PRECISION (int_mode);
     127                 :     3763350 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     128                 :             :     return false;
     129                 :             : 
     130                 :     3758760 :   val &= GET_MODE_MASK (int_mode);
     131                 :     3758760 :   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                 :     2712202 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     138                 :             : {
     139                 :     2712202 :   unsigned int width;
     140                 :             : 
     141                 :     2712202 :   scalar_int_mode int_mode;
     142                 :     2712202 :   if (!is_int_mode (mode, &int_mode))
     143                 :             :     return false;
     144                 :             : 
     145                 :     2679378 :   width = GET_MODE_PRECISION (int_mode);
     146                 :     2679378 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     147                 :             :     return false;
     148                 :             : 
     149                 :     2679378 :   val &= HOST_WIDE_INT_1U << (width - 1);
     150                 :     2679378 :   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                 :     7597985 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
     157                 :             : {
     158                 :     7597985 :   unsigned int width;
     159                 :             : 
     160                 :     7597985 :   scalar_int_mode int_mode;
     161                 :     7597985 :   if (!is_int_mode (mode, &int_mode))
     162                 :             :     return false;
     163                 :             : 
     164                 :     7279079 :   width = GET_MODE_PRECISION (int_mode);
     165                 :     7279079 :   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
     166                 :             :     return false;
     167                 :             : 
     168                 :     7168761 :   val &= HOST_WIDE_INT_1U << (width - 1);
     169                 :     7168761 :   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                 :   115500016 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
     177                 :             :                                        rtx op0, rtx op1)
     178                 :             : {
     179                 :   115500016 :   rtx tem;
     180                 :             : 
     181                 :             :   /* If this simplifies, do it.  */
     182                 :   115500016 :   tem = simplify_binary_operation (code, mode, op0, op1);
     183                 :   115500016 :   if (tem)
     184                 :             :     return tem;
     185                 :             : 
     186                 :             :   /* Put complex operands first and constants second if commutative.  */
     187                 :    72899567 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
     188                 :    72899567 :       && swap_commutative_operands_p (op0, op1))
     189                 :             :     std::swap (op0, op1);
     190                 :             : 
     191                 :    72899567 :   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                 :  2739971094 : avoid_constant_pool_reference (rtx x)
     198                 :             : {
     199                 :  2739971094 :   rtx c, tmp, addr;
     200                 :  2739971094 :   machine_mode cmode;
     201                 :  2739971094 :   poly_int64 offset = 0;
     202                 :             : 
     203                 :  2739971094 :   switch (GET_CODE (x))
     204                 :             :     {
     205                 :   255803526 :     case MEM:
     206                 :   255803526 :       break;
     207                 :             : 
     208                 :      909297 :     case FLOAT_EXTEND:
     209                 :             :       /* Handle float extensions of constant pool references.  */
     210                 :      909297 :       tmp = XEXP (x, 0);
     211                 :      909297 :       c = avoid_constant_pool_reference (tmp);
     212                 :      909297 :       if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
     213                 :      122526 :         return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
     214                 :      122526 :                                              GET_MODE (x));
     215                 :             :       return x;
     216                 :             : 
     217                 :             :     default:
     218                 :             :       return x;
     219                 :             :     }
     220                 :             : 
     221                 :   255803526 :   if (GET_MODE (x) == BLKmode)
     222                 :             :     return x;
     223                 :             : 
     224                 :   253653335 :   addr = XEXP (x, 0);
     225                 :             : 
     226                 :             :   /* Call target hook to avoid the effects of -fpic etc....  */
     227                 :   253653335 :   addr = targetm.delegitimize_address (addr);
     228                 :             : 
     229                 :             :   /* Split the address into a base and integer offset.  */
     230                 :   253653335 :   addr = strip_offset (addr, &offset);
     231                 :             : 
     232                 :   253653335 :   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                 :   253653335 :   if (GET_CODE (addr) == SYMBOL_REF
     238                 :   253653335 :       && CONSTANT_POOL_ADDRESS_P (addr))
     239                 :             :     {
     240                 :     5398702 :       c = get_pool_constant (addr);
     241                 :     5398702 :       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                 :     5398702 :       if (known_eq (offset, 0) && cmode == GET_MODE (x))
     247                 :             :         return c;
     248                 :       15546 :       else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
     249                 :             :         {
     250                 :        7773 :           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
     251                 :        7773 :           if (tem && CONSTANT_P (tem))
     252                 :             :             return tem;
     253                 :             :         }
     254                 :             :     }
     255                 :             : 
     256                 :             :   return x;
     257                 :             : }
     258                 :             : 
     259                 :             : /* Simplify a MEM based on its attributes.  This is the default
     260                 :             :    delegitimize_address target hook, and it's recommended that every
     261                 :             :    overrider call it.  */
     262                 :             : 
     263                 :             : rtx
     264                 :  3516703295 : 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                 :  3516703295 :   if (MEM_P (x)
     269                 :    62183860 :       && MEM_EXPR (x)
     270                 :  3554968234 :       && MEM_OFFSET_KNOWN_P (x))
     271                 :             :     {
     272                 :    35296107 :       tree decl = MEM_EXPR (x);
     273                 :    35296107 :       machine_mode mode = GET_MODE (x);
     274                 :    35296107 :       poly_int64 offset = 0;
     275                 :             : 
     276                 :    35296107 :       switch (TREE_CODE (decl))
     277                 :             :         {
     278                 :             :         default:
     279                 :             :           decl = NULL;
     280                 :             :           break;
     281                 :             : 
     282                 :             :         case VAR_DECL:
     283                 :             :           break;
     284                 :             : 
     285                 :    10110467 :         case ARRAY_REF:
     286                 :    10110467 :         case ARRAY_RANGE_REF:
     287                 :    10110467 :         case COMPONENT_REF:
     288                 :    10110467 :         case BIT_FIELD_REF:
     289                 :    10110467 :         case REALPART_EXPR:
     290                 :    10110467 :         case IMAGPART_EXPR:
     291                 :    10110467 :         case VIEW_CONVERT_EXPR:
     292                 :    10110467 :           {
     293                 :    10110467 :             poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
     294                 :    10110467 :             tree toffset;
     295                 :    10110467 :             int unsignedp, reversep, volatilep = 0;
     296                 :             : 
     297                 :    10110467 :             decl
     298                 :    10110467 :               = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
     299                 :             :                                      &unsignedp, &reversep, &volatilep);
     300                 :    20220934 :             if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
     301                 :    10388640 :                 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
     302                 :    19769382 :                 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
     303                 :             :               decl = NULL;
     304                 :             :             else
     305                 :     9380742 :               offset += bytepos + toffset_val;
     306                 :    10110467 :             break;
     307                 :             :           }
     308                 :             :         }
     309                 :             : 
     310                 :      729725 :       if (decl
     311                 :    20770492 :           && mode == GET_MODE (x)
     312                 :    20488426 :           && VAR_P (decl)
     313                 :    13324141 :           && (TREE_STATIC (decl)
     314                 :    12111854 :               || DECL_THREAD_LOCAL_P (decl))
     315                 :     1246498 :           && DECL_RTL_SET_P (decl)
     316                 :    10626737 :           && MEM_P (DECL_RTL (decl)))
     317                 :             :         {
     318                 :     1245995 :           rtx newx;
     319                 :             : 
     320                 :     1245995 :           offset += MEM_OFFSET (x);
     321                 :             : 
     322                 :     1245995 :           newx = DECL_RTL (decl);
     323                 :             : 
     324                 :     1245995 :           if (MEM_P (newx))
     325                 :             :             {
     326                 :     1245995 :               rtx n = XEXP (newx, 0), o = XEXP (x, 0);
     327                 :     1245995 :               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                 :     1245995 :               n = strip_offset (n, &n_offset);
     336                 :     1245995 :               o = strip_offset (o, &o_offset);
     337                 :     2464929 :               if (!(known_eq (o_offset, n_offset + offset)
     338                 :     1218934 :                     && rtx_equal_p (o, n)))
     339                 :      206749 :                 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                 :  3516703295 :   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                 :     5300733 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
     355                 :             :                                       machine_mode op_mode)
     356                 :             : {
     357                 :     5300733 :   rtx tem;
     358                 :             : 
     359                 :             :   /* If this simplifies, use it.  */
     360                 :     5300733 :   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
     361                 :             :     return tem;
     362                 :             : 
     363                 :     2005627 :   return gen_rtx_fmt_e (code, mode, op);
     364                 :             : }
     365                 :             : 
     366                 :             : /* Likewise for ternary operations.  */
     367                 :             : 
     368                 :             : rtx
     369                 :     2181392 : 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                 :     2181392 :   rtx tem;
     374                 :             : 
     375                 :             :   /* If this simplifies, use it.  */
     376                 :     2181392 :   if ((tem = simplify_ternary_operation (code, mode, op0_mode,
     377                 :             :                                          op0, op1, op2)) != 0)
     378                 :             :     return tem;
     379                 :             : 
     380                 :     1934934 :   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                 :    21078876 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
     388                 :             :                                            machine_mode cmp_mode,
     389                 :             :                                            rtx op0, rtx op1)
     390                 :             : {
     391                 :    21078876 :   rtx tem;
     392                 :             : 
     393                 :    21078876 :   if ((tem = simplify_relational_operation (code, mode, cmp_mode,
     394                 :             :                                             op0, op1)) != 0)
     395                 :             :     return tem;
     396                 :             : 
     397                 :    18848431 :   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                 :   488152683 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
     407                 :             :                          rtx (*fn) (rtx, const_rtx, void *), void *data)
     408                 :             : {
     409                 :   488152683 :   enum rtx_code code = GET_CODE (x);
     410                 :   488152683 :   machine_mode mode = GET_MODE (x);
     411                 :   488152683 :   machine_mode op_mode;
     412                 :   488152683 :   const char *fmt;
     413                 :   488152683 :   rtx op0, op1, op2, newx, op;
     414                 :   488152683 :   rtvec vec, newvec;
     415                 :   488152683 :   int i, j;
     416                 :             : 
     417                 :   488152683 :   if (UNLIKELY (fn != NULL))
     418                 :             :     {
     419                 :   425837630 :       newx = fn (x, old_rtx, data);
     420                 :   425837630 :       if (newx)
     421                 :             :         return newx;
     422                 :             :     }
     423                 :    62315053 :   else if (rtx_equal_p (x, old_rtx))
     424                 :     5217974 :     return copy_rtx ((rtx) data);
     425                 :             : 
     426                 :   382975868 :   switch (GET_RTX_CLASS (code))
     427                 :             :     {
     428                 :     2129244 :     case RTX_UNARY:
     429                 :     2129244 :       op0 = XEXP (x, 0);
     430                 :     2129244 :       op_mode = GET_MODE (op0);
     431                 :     2129244 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     432                 :     2129244 :       if (op0 == XEXP (x, 0))
     433                 :             :         return x;
     434                 :      675317 :       return simplify_gen_unary (code, mode, op0, op_mode);
     435                 :             : 
     436                 :    76318432 :     case RTX_BIN_ARITH:
     437                 :    76318432 :     case RTX_COMM_ARITH:
     438                 :    76318432 :       op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     439                 :    76318432 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     440                 :    76318432 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     441                 :             :         return x;
     442                 :    23525159 :       return simplify_gen_binary (code, mode, op0, op1);
     443                 :             : 
     444                 :     9718665 :     case RTX_COMPARE:
     445                 :     9718665 :     case RTX_COMM_COMPARE:
     446                 :     9718665 :       op0 = XEXP (x, 0);
     447                 :     9718665 :       op1 = XEXP (x, 1);
     448                 :     9718665 :       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
     449                 :     9718665 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     450                 :     9718665 :       op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
     451                 :     9718665 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
     452                 :             :         return x;
     453                 :     2303527 :       return simplify_gen_relational (code, mode, op_mode, op0, op1);
     454                 :             : 
     455                 :     5730540 :     case RTX_TERNARY:
     456                 :     5730540 :     case RTX_BITFIELD_OPS:
     457                 :     5730540 :       op0 = XEXP (x, 0);
     458                 :     5730540 :       op_mode = GET_MODE (op0);
     459                 :     5730540 :       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
     460                 :     5730540 :       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
     461                 :     5730540 :       op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
     462                 :     5730540 :       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
     463                 :             :         return x;
     464                 :     1636199 :       if (op_mode == VOIDmode)
     465                 :     1616379 :         op_mode = GET_MODE (op0);
     466                 :     1636199 :       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
     467                 :             : 
     468                 :    83314398 :     case RTX_EXTRA:
     469                 :    83314398 :       if (code == SUBREG)
     470                 :             :         {
     471                 :      693537 :           op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
     472                 :      693537 :           if (op0 == SUBREG_REG (x))
     473                 :             :             return x;
     474                 :      107514 :           op0 = simplify_gen_subreg (GET_MODE (x), op0,
     475                 :       53757 :                                      GET_MODE (SUBREG_REG (x)),
     476                 :       53757 :                                      SUBREG_BYTE (x));
     477                 :       53757 :           return op0 ? op0 : x;
     478                 :             :         }
     479                 :             :       break;
     480                 :             : 
     481                 :    62100950 :     case RTX_OBJ:
     482                 :    62100950 :       if (code == MEM)
     483                 :             :         {
     484                 :    11012789 :           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
     485                 :    11012789 :           if (op0 == XEXP (x, 0))
     486                 :             :             return x;
     487                 :      162762 :           return replace_equiv_address_nv (x, op0);
     488                 :             :         }
     489                 :    51088161 :       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                 :   277372661 :   newx = x;
     515                 :   277372661 :   fmt = GET_RTX_FORMAT (code);
     516                 :   598456672 :   for (i = 0; fmt[i]; i++)
     517                 :   321084011 :     switch (fmt[i])
     518                 :             :       {
     519                 :     2994455 :       case 'E':
     520                 :     2994455 :         vec = XVEC (x, i);
     521                 :     2994455 :         newvec = XVEC (newx, i);
     522                 :    12168268 :         for (j = 0; j < GET_NUM_ELEM (vec); j++)
     523                 :             :           {
     524                 :     9173813 :             op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
     525                 :             :                                           old_rtx, fn, data);
     526                 :     9173813 :             if (op != RTVEC_ELT (vec, j))
     527                 :             :               {
     528                 :      332877 :                 if (newvec == vec)
     529                 :             :                   {
     530                 :      326035 :                     newvec = shallow_copy_rtvec (vec);
     531                 :      326035 :                     if (x == newx)
     532                 :      326035 :                       newx = shallow_copy_rtx (x);
     533                 :      326035 :                     XVEC (newx, i) = newvec;
     534                 :             :                   }
     535                 :      332877 :                 RTVEC_ELT (newvec, j) = op;
     536                 :             :               }
     537                 :             :           }
     538                 :             :         break;
     539                 :             : 
     540                 :    74892787 :       case 'e':
     541                 :    74892787 :         if (XEXP (x, i))
     542                 :             :           {
     543                 :    74892787 :             op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
     544                 :    74892787 :             if (op != XEXP (x, i))
     545                 :             :               {
     546                 :     4496219 :                 if (x == newx)
     547                 :     4493058 :                   newx = shallow_copy_rtx (x);
     548                 :     4496219 :                 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                 :    12800506 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
     561                 :             : {
     562                 :    12800506 :   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                 :    18510760 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
     614                 :             :                                        machine_mode op_mode)
     615                 :             : {
     616                 :    18510760 :   unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
     617                 :    18510760 :   unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
     618                 :    18510760 :   scalar_int_mode int_mode, int_op_mode, subreg_mode;
     619                 :             : 
     620                 :    18510760 :   gcc_assert (precision <= op_precision);
     621                 :             : 
     622                 :             :   /* Optimize truncations of zero and sign extended values.  */
     623                 :    18510760 :   if (GET_CODE (op) == ZERO_EXTEND
     624                 :    18510760 :       || 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                 :      286142 :       machine_mode origmode = GET_MODE (XEXP (op, 0));
     633                 :      286142 :       if (mode == origmode)
     634                 :             :         return XEXP (op, 0);
     635                 :       19688 :       else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
     636                 :        6459 :         return simplify_gen_unary (TRUNCATE, mode,
     637                 :        6459 :                                    XEXP (op, 0), origmode);
     638                 :             :       else
     639                 :        3385 :         return simplify_gen_unary (GET_CODE (op), mode,
     640                 :        3385 :                                    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                 :    18224618 :   if (1
     647                 :             :       && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
     648                 :             :       && (GET_CODE (op) == PLUS
     649                 :             :           || GET_CODE (op) == MINUS
     650                 :    18224618 :           || GET_CODE (op) == MULT))
     651                 :             :     {
     652                 :      806073 :       rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
     653                 :      806073 :       if (op0)
     654                 :             :         {
     655                 :      806073 :           rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
     656                 :      806073 :           if (op1)
     657                 :      806073 :             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                 :    17418545 :   if ((GET_CODE (op) == LSHIFTRT
     665                 :    17418545 :        || 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                 :     1717126 :       && 2 * precision <= op_precision
     671                 :     1717126 :       && CONST_INT_P (XEXP (op, 1))
     672                 :     1617027 :       && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
     673                 :          23 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     674                 :          20 :       && UINTVAL (XEXP (op, 1)) < precision)
     675                 :          16 :     return simplify_gen_binary (ASHIFTRT, mode,
     676                 :          16 :                                 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                 :    17418529 :   if ((GET_CODE (op) == LSHIFTRT
     682                 :             :        || GET_CODE (op) == ASHIFTRT)
     683                 :     1717110 :       && CONST_INT_P (XEXP (op, 1))
     684                 :     1617011 :       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     685                 :         671 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     686                 :         671 :       && UINTVAL (XEXP (op, 1)) < precision)
     687                 :         661 :     return simplify_gen_binary (LSHIFTRT, mode,
     688                 :         661 :                                 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                 :    17417868 :   if (GET_CODE (op) == ASHIFT
     694                 :      468141 :       && CONST_INT_P (XEXP (op, 1))
     695                 :      409210 :       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
     696                 :      409210 :           || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
     697                 :         489 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
     698                 :         478 :       && UINTVAL (XEXP (op, 1)) < precision)
     699                 :         470 :     return simplify_gen_binary (ASHIFT, mode,
     700                 :         470 :                                 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                 :    17417398 :   if (GET_CODE (op) == AND
     706                 :      592783 :       && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
     707                 :      592783 :           || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
     708                 :       30198 :       && CONST_INT_P (XEXP (XEXP (op, 0), 1))
     709                 :       30092 :       && CONST_INT_P (XEXP (op, 1)))
     710                 :             :     {
     711                 :       30092 :       rtx op0 = (XEXP (XEXP (op, 0), 0));
     712                 :       30092 :       rtx shift_op = XEXP (XEXP (op, 0), 1);
     713                 :       30092 :       rtx mask_op = XEXP (op, 1);
     714                 :       30092 :       unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
     715                 :       30092 :       unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
     716                 :             : 
     717                 :       30092 :       if (shift < precision
     718                 :             :           /* If doing this transform works for an X with all bits set,
     719                 :             :              it works for any X.  */
     720                 :       17367 :           && ((GET_MODE_MASK (mode) >> shift) & mask)
     721                 :       17367 :              == ((GET_MODE_MASK (op_mode) >> shift) & mask)
     722                 :        2980 :           && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
     723                 :       33072 :           && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
     724                 :             :         {
     725                 :        2980 :           mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
     726                 :        2980 :           return simplify_gen_binary (AND, mode, op0, mask_op);
     727                 :             :         }
     728                 :             :     }
     729                 :             : 
     730                 :             :   /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
     731                 :             :      (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
     732                 :             :      changing len.  */
     733                 :    17414418 :   if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
     734                 :      417937 :       && REG_P (XEXP (op, 0))
     735                 :      281962 :       && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
     736                 :      281155 :       && CONST_INT_P (XEXP (op, 1))
     737                 :      281155 :       && CONST_INT_P (XEXP (op, 2)))
     738                 :             :     {
     739                 :      240762 :       rtx op0 = XEXP (op, 0);
     740                 :      240762 :       unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
     741                 :      240762 :       unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
     742                 :      240762 :       if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
     743                 :             :         {
     744                 :             :           op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     745                 :             :           if (op0)
     746                 :             :             {
     747                 :             :               pos -= op_precision - precision;
     748                 :             :               return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     749                 :             :                                            XEXP (op, 1), GEN_INT (pos));
     750                 :             :             }
     751                 :             :         }
     752                 :      240762 :       else if (!BITS_BIG_ENDIAN && precision >= len + pos)
     753                 :             :         {
     754                 :        7607 :           op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
     755                 :        7607 :           if (op0)
     756                 :        7607 :             return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
     757                 :        7607 :                                          XEXP (op, 1), XEXP (op, 2));
     758                 :             :         }
     759                 :             :     }
     760                 :             : 
     761                 :             :   /* Recognize a word extraction from a multi-word subreg.  */
     762                 :    17406811 :   if ((GET_CODE (op) == LSHIFTRT
     763                 :    17406811 :        || GET_CODE (op) == ASHIFTRT)
     764                 :     1716449 :       && SCALAR_INT_MODE_P (mode)
     765                 :     1713507 :       && SCALAR_INT_MODE_P (op_mode)
     766                 :     1848200 :       && precision >= BITS_PER_WORD
     767                 :       64501 :       && 2 * precision <= op_precision
     768                 :       64501 :       && CONST_INT_P (XEXP (op, 1))
     769                 :       56415 :       && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
     770                 :        1899 :       && UINTVAL (XEXP (op, 1)) < op_precision)
     771                 :             :     {
     772                 :        1899 :       poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
     773                 :        1899 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     774                 :        1899 :       return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
     775                 :             :                                   (WORDS_BIG_ENDIAN
     776                 :        1899 :                                    ? byte - shifted_bytes
     777                 :        1899 :                                    : 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                 :    17404912 :   if ((GET_CODE (op) == LSHIFTRT
     784                 :             :        || GET_CODE (op) == ASHIFTRT)
     785                 :     1711608 :       && is_a <scalar_int_mode> (mode, &int_mode)
     786                 :    19115321 :       && is_a <scalar_int_mode> (op_mode, &int_op_mode)
     787                 :     1711608 :       && MEM_P (XEXP (op, 0))
     788                 :       11043 :       && CONST_INT_P (XEXP (op, 1))
     789                 :       20544 :       && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
     790                 :        1238 :       && INTVAL (XEXP (op, 1)) > 0
     791                 :        2476 :       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
     792                 :        1238 :       && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
     793                 :        1238 :                                      MEM_ADDR_SPACE (XEXP (op, 0)))
     794                 :        1238 :       && ! MEM_VOLATILE_P (XEXP (op, 0))
     795                 :    17404912 :       && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
     796                 :             :           || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
     797                 :             :     {
     798                 :        1199 :       poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
     799                 :        1199 :       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
     800                 :        1199 :       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                 :    17403713 :   if ((GET_CODE (op) == ABS
     809                 :    17403713 :        || GET_CODE (op) == NEG)
     810                 :       27469 :       && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
     811                 :       27469 :           || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
     812                 :          18 :       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
     813                 :           2 :     return simplify_gen_unary (GET_CODE (op), mode,
     814                 :           2 :                                XEXP (XEXP (op, 0), 0), mode);
     815                 :             : 
     816                 :             :   /* Simplifications of (truncate:A (subreg:B X 0)).  */
     817                 :    17403711 :   if (GET_CODE (op) == SUBREG
     818                 :    17403809 :       && is_a <scalar_int_mode> (mode, &int_mode)
     819                 :       37270 :       && SCALAR_INT_MODE_P (op_mode)
     820                 :       37270 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
     821                 :    17440919 :       && subreg_lowpart_p (op))
     822                 :             :     {
     823                 :             :       /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X).  */
     824                 :       37205 :       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                 :       37205 :       if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
     841                 :             :         {
     842                 :       37205 :           unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
     843                 :       37205 :           unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
     844                 :       37205 :           if (int_op_prec > subreg_prec)
     845                 :             :             {
     846                 :        1340 :               if (int_mode == subreg_mode)
     847                 :             :                 return SUBREG_REG (op);
     848                 :          60 :               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                 :       35865 :           else if (int_op_prec < subreg_prec
     855                 :       35865 :                    && GET_MODE_PRECISION (int_mode) < int_op_prec)
     856                 :       35865 :             return simplify_gen_unary (TRUNCATE, int_mode,
     857                 :       35865 :                                        SUBREG_REG (op), subreg_mode);
     858                 :             :         }
     859                 :             :     }
     860                 :             : 
     861                 :             :   /* (truncate:A (truncate:B X)) is (truncate:A X).  */
     862                 :    17366539 :   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                 :    17366539 :   if (GET_CODE (op) == IOR
     869                 :       34456 :       && SCALAR_INT_MODE_P (mode)
     870                 :       34456 :       && SCALAR_INT_MODE_P (op_mode)
     871                 :       34456 :       && CONST_INT_P (XEXP (op, 1))
     872                 :    17374859 :       && 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                 :    27768168 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
     883                 :             :                                             rtx op, machine_mode op_mode)
     884                 :             : {
     885                 :    27768168 :   rtx trueop, tem;
     886                 :             : 
     887                 :    27768168 :   trueop = avoid_constant_pool_reference (op);
     888                 :             : 
     889                 :    27768168 :   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
     890                 :    27768168 :   if (tem)
     891                 :             :     return tem;
     892                 :             : 
     893                 :    22728868 :   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                 :        2700 : exact_int_to_float_conversion_p (const_rtx op)
     901                 :             : {
     902                 :        2700 :   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                 :        2700 :   if (op0_mode == VOIDmode)
     906                 :             :     return false;
     907                 :        5398 :   int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
     908                 :        2699 :   int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
     909                 :        2699 :   int in_bits = in_prec;
     910                 :        2699 :   if (HWI_COMPUTABLE_MODE_P (op0_mode))
     911                 :             :     {
     912                 :        2609 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
     913                 :        2609 :       if (GET_CODE (op) == FLOAT)
     914                 :        2475 :         in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
     915                 :         134 :       else if (GET_CODE (op) == UNSIGNED_FLOAT)
     916                 :         134 :         in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
     917                 :             :       else
     918                 :           0 :         gcc_unreachable ();
     919                 :        2609 :       in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
     920                 :             :     }
     921                 :        2699 :   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                 :    22728868 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
     928                 :             :                                               rtx op)
     929                 :             : {
     930                 :    22728868 :   enum rtx_code reversed;
     931                 :    22728868 :   rtx temp, elt, base, step;
     932                 :    22728868 :   scalar_int_mode inner, int_mode, op_mode, op0_mode;
     933                 :             : 
     934                 :    22728868 :   switch (code)
     935                 :             :     {
     936                 :     1807727 :     case NOT:
     937                 :             :       /* (not (not X)) == X.  */
     938                 :     1807727 :       if (GET_CODE (op) == NOT)
     939                 :        4035 :         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                 :     1803692 :       if (COMPARISON_P (op)
     944                 :       11037 :           && (mode == BImode || STORE_FLAG_VALUE == -1)
     945                 :     1803692 :           && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
     946                 :           0 :         return simplify_gen_relational (reversed, mode, VOIDmode,
     947                 :           0 :                                         XEXP (op, 0), XEXP (op, 1));
     948                 :             : 
     949                 :             :       /* (not (plus X -1)) can become (neg X).  */
     950                 :     1803692 :       if (GET_CODE (op) == PLUS
     951                 :      290692 :           && XEXP (op, 1) == constm1_rtx)
     952                 :        7484 :         return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
     953                 :             : 
     954                 :             :       /* Similarly, (not (neg X)) is (plus X -1).  Only do this for
     955                 :             :          modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
     956                 :             :          and MODE_VECTOR_INT.  */
     957                 :     1796208 :       if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
     958                 :       72345 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
     959                 :       72345 :                                     CONSTM1_RTX (mode));
     960                 :             : 
     961                 :             :       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
     962                 :     1723863 :       if (GET_CODE (op) == XOR
     963                 :       15418 :           && CONST_INT_P (XEXP (op, 1))
     964                 :     1727870 :           && (temp = simplify_unary_operation (NOT, mode,
     965                 :             :                                                XEXP (op, 1), mode)) != 0)
     966                 :        4007 :         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
     967                 :             : 
     968                 :             :       /* (not (plus X C)) for signbit C is (xor X D) with D = ~C.  */
     969                 :     1719856 :       if (GET_CODE (op) == PLUS
     970                 :      283208 :           && CONST_INT_P (XEXP (op, 1))
     971                 :      166030 :           && mode_signbit_p (mode, XEXP (op, 1))
     972                 :     1725108 :           && (temp = simplify_unary_operation (NOT, mode,
     973                 :             :                                                XEXP (op, 1), mode)) != 0)
     974                 :        5252 :         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
     975                 :             : 
     976                 :             : 
     977                 :             :       /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for
     978                 :             :          operands other than 1, but that is not valid.  We could do a
     979                 :             :          similar simplification for (not (lshiftrt C X)) where C is
     980                 :             :          just the sign bit, but this doesn't seem common enough to
     981                 :             :          bother with.  */
     982                 :     1714604 :       if (GET_CODE (op) == ASHIFT
     983                 :       46652 :           && XEXP (op, 0) == const1_rtx)
     984                 :             :         {
     985                 :        1079 :           temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
     986                 :        1079 :           return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
     987                 :             :         }
     988                 :             : 
     989                 :             :       /* (not (ashiftrt foo C)) where C is the number of bits in FOO
     990                 :             :          minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
     991                 :             :          so we can perform the above simplification.  */
     992                 :     1713525 :       if (STORE_FLAG_VALUE == -1
     993                 :             :           && is_a <scalar_int_mode> (mode, &int_mode)
     994                 :             :           && GET_CODE (op) == ASHIFTRT
     995                 :             :           && CONST_INT_P (XEXP (op, 1))
     996                 :             :           && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
     997                 :             :         return simplify_gen_relational (GE, int_mode, VOIDmode,
     998                 :             :                                         XEXP (op, 0), const0_rtx);
     999                 :             : 
    1000                 :             : 
    1001                 :     1713525 :       if (partial_subreg_p (op)
    1002                 :       71387 :           && subreg_lowpart_p (op)
    1003                 :       71073 :           && GET_CODE (SUBREG_REG (op)) == ASHIFT
    1004                 :       94459 :           && XEXP (SUBREG_REG (op), 0) == const1_rtx)
    1005                 :             :         {
    1006                 :         164 :           machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
    1007                 :         164 :           rtx x;
    1008                 :             : 
    1009                 :         164 :           x = gen_rtx_ROTATE (inner_mode,
    1010                 :             :                               simplify_gen_unary (NOT, inner_mode, const1_rtx,
    1011                 :             :                                                   inner_mode),
    1012                 :             :                               XEXP (SUBREG_REG (op), 1));
    1013                 :         164 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
    1014                 :         164 :           if (temp)
    1015                 :             :             return temp;
    1016                 :             :         }
    1017                 :             : 
    1018                 :             :       /* Apply De Morgan's laws to reduce number of patterns for machines
    1019                 :             :          with negating logical insns (and-not, nand, etc.).  If result has
    1020                 :             :          only one NOT, put it first, since that is how the patterns are
    1021                 :             :          coded.  */
    1022                 :     1713361 :       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
    1023                 :             :         {
    1024                 :       11439 :           rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
    1025                 :       11439 :           machine_mode op_mode;
    1026                 :             : 
    1027                 :       11439 :           op_mode = GET_MODE (in1);
    1028                 :       11439 :           in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
    1029                 :             : 
    1030                 :       11439 :           op_mode = GET_MODE (in2);
    1031                 :       11439 :           if (op_mode == VOIDmode)
    1032                 :        5478 :             op_mode = mode;
    1033                 :       11439 :           in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
    1034                 :             : 
    1035                 :       11439 :           if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
    1036                 :             :             std::swap (in1, in2);
    1037                 :             : 
    1038                 :       22878 :           return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
    1039                 :             :                                  mode, in1, in2);
    1040                 :             :         }
    1041                 :             : 
    1042                 :             :       /* (not (bswap x)) -> (bswap (not x)).  */
    1043                 :     1701922 :       if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
    1044                 :             :         {
    1045                 :           0 :           rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1046                 :           0 :           return simplify_gen_unary (GET_CODE (op), mode, x, mode);
    1047                 :             :         }
    1048                 :             :       break;
    1049                 :             : 
    1050                 :     1644547 :     case NEG:
    1051                 :             :       /* (neg (neg X)) == X.  */
    1052                 :     1644547 :       if (GET_CODE (op) == NEG)
    1053                 :        6754 :         return XEXP (op, 0);
    1054                 :             : 
    1055                 :             :       /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
    1056                 :             :          If comparison is not reversible use
    1057                 :             :          x ? y : (neg y).  */
    1058                 :     1637793 :       if (GET_CODE (op) == IF_THEN_ELSE)
    1059                 :             :         {
    1060                 :        2460 :           rtx cond = XEXP (op, 0);
    1061                 :        2460 :           rtx true_rtx = XEXP (op, 1);
    1062                 :        2460 :           rtx false_rtx = XEXP (op, 2);
    1063                 :             : 
    1064                 :        2460 :           if ((GET_CODE (true_rtx) == NEG
    1065                 :           0 :                && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
    1066                 :        2460 :                || (GET_CODE (false_rtx) == NEG
    1067                 :           0 :                    && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
    1068                 :             :             {
    1069                 :           0 :               if (reversed_comparison_code (cond, NULL) != UNKNOWN)
    1070                 :           0 :                 temp = reversed_comparison (cond, mode);
    1071                 :             :               else
    1072                 :             :                 {
    1073                 :             :                   temp = cond;
    1074                 :             :                   std::swap (true_rtx, false_rtx);
    1075                 :             :                 }
    1076                 :           0 :               return simplify_gen_ternary (IF_THEN_ELSE, mode,
    1077                 :           0 :                                             mode, temp, true_rtx, false_rtx);
    1078                 :             :             }
    1079                 :             :         }
    1080                 :             : 
    1081                 :             :       /* (neg (plus X 1)) can become (not X).  */
    1082                 :     1637793 :       if (GET_CODE (op) == PLUS
    1083                 :      134514 :           && XEXP (op, 1) == const1_rtx)
    1084                 :       53186 :         return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
    1085                 :             : 
    1086                 :             :       /* Similarly, (neg (not X)) is (plus X 1).  */
    1087                 :     1584607 :       if (GET_CODE (op) == NOT)
    1088                 :         782 :         return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
    1089                 :         782 :                                     CONST1_RTX (mode));
    1090                 :             : 
    1091                 :             :       /* (neg (minus X Y)) can become (minus Y X).  This transformation
    1092                 :             :          isn't safe for modes with signed zeros, since if X and Y are
    1093                 :             :          both +0, (minus Y X) is the same as (minus X Y).  If the
    1094                 :             :          rounding mode is towards +infinity (or -infinity) then the two
    1095                 :             :          expressions will be rounded differently.  */
    1096                 :     1583825 :       if (GET_CODE (op) == MINUS
    1097                 :       24016 :           && !HONOR_SIGNED_ZEROS (mode)
    1098                 :     1606431 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1099                 :       22606 :         return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
    1100                 :             : 
    1101                 :     1561219 :       if (GET_CODE (op) == PLUS
    1102                 :       81328 :           && !HONOR_SIGNED_ZEROS (mode)
    1103                 :     1642187 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1104                 :             :         {
    1105                 :             :           /* (neg (plus A C)) is simplified to (minus -C A).  */
    1106                 :       80968 :           if (CONST_SCALAR_INT_P (XEXP (op, 1))
    1107                 :        5056 :               || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
    1108                 :             :             {
    1109                 :       75912 :               temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
    1110                 :       75912 :               if (temp)
    1111                 :       75912 :                 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
    1112                 :             :             }
    1113                 :             : 
    1114                 :             :           /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
    1115                 :        5056 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
    1116                 :        5056 :           return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
    1117                 :             :         }
    1118                 :             : 
    1119                 :             :       /* (neg (mult A B)) becomes (mult A (neg B)).
    1120                 :             :          This works even for floating-point values.  */
    1121                 :     1480251 :       if (GET_CODE (op) == MULT
    1122                 :     1480251 :           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    1123                 :             :         {
    1124                 :       20167 :           temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
    1125                 :       20167 :           return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
    1126                 :             :         }
    1127                 :             : 
    1128                 :             :       /* NEG commutes with ASHIFT since it is multiplication.  Only do
    1129                 :             :          this if we can then eliminate the NEG (e.g., if the operand
    1130                 :             :          is a constant).  */
    1131                 :     1460084 :       if (GET_CODE (op) == ASHIFT)
    1132                 :             :         {
    1133                 :       52349 :           temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
    1134                 :       52349 :           if (temp)
    1135                 :       12666 :             return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
    1136                 :             :         }
    1137                 :             : 
    1138                 :             :       /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
    1139                 :             :          C is equal to the width of MODE minus 1.  */
    1140                 :     1447418 :       if (GET_CODE (op) == ASHIFTRT
    1141                 :       25801 :           && CONST_INT_P (XEXP (op, 1))
    1142                 :     1498924 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1143                 :         420 :         return simplify_gen_binary (LSHIFTRT, mode,
    1144                 :         420 :                                     XEXP (op, 0), XEXP (op, 1));
    1145                 :             : 
    1146                 :             :       /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
    1147                 :             :          C is equal to the width of MODE minus 1.  */
    1148                 :     1446998 :       if (GET_CODE (op) == LSHIFTRT
    1149                 :        7548 :           && CONST_INT_P (XEXP (op, 1))
    1150                 :     1461934 :           && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
    1151                 :        2428 :         return simplify_gen_binary (ASHIFTRT, mode,
    1152                 :        2428 :                                     XEXP (op, 0), XEXP (op, 1));
    1153                 :             : 
    1154                 :             :       /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
    1155                 :     1444570 :       if (GET_CODE (op) == XOR
    1156                 :       23321 :           && XEXP (op, 1) == const1_rtx
    1157                 :     1444708 :           && nonzero_bits (XEXP (op, 0), mode) == 1)
    1158                 :          40 :         return plus_constant (mode, XEXP (op, 0), -1);
    1159                 :             : 
    1160                 :             :       /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1.  */
    1161                 :             :       /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1.  */
    1162                 :     1444530 :       if (GET_CODE (op) == LT
    1163                 :        2335 :           && XEXP (op, 1) == const0_rtx
    1164                 :     1445912 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
    1165                 :             :         {
    1166                 :         264 :           int_mode = as_a <scalar_int_mode> (mode);
    1167                 :         264 :           int isize = GET_MODE_PRECISION (inner);
    1168                 :         264 :           if (STORE_FLAG_VALUE == 1)
    1169                 :             :             {
    1170                 :         264 :               temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
    1171                 :             :                                           gen_int_shift_amount (inner,
    1172                 :         264 :                                                                 isize - 1));
    1173                 :         264 :               if (int_mode == inner)
    1174                 :             :                 return temp;
    1175                 :         169 :               if (GET_MODE_PRECISION (int_mode) > isize)
    1176                 :         104 :                 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
    1177                 :          65 :               return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
    1178                 :             :             }
    1179                 :             :           else if (STORE_FLAG_VALUE == -1)
    1180                 :             :             {
    1181                 :             :               temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
    1182                 :             :                                           gen_int_shift_amount (inner,
    1183                 :             :                                                                 isize - 1));
    1184                 :             :               if (int_mode == inner)
    1185                 :             :                 return temp;
    1186                 :             :               if (GET_MODE_PRECISION (int_mode) > isize)
    1187                 :             :                 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
    1188                 :             :               return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
    1189                 :             :             }
    1190                 :             :         }
    1191                 :             : 
    1192                 :     1444266 :       if (vec_series_p (op, &base, &step))
    1193                 :             :         {
    1194                 :             :           /* Only create a new series if we can simplify both parts.  In other
    1195                 :             :              cases this isn't really a simplification, and it's not necessarily
    1196                 :             :              a win to replace a vector operation with a scalar operation.  */
    1197                 :         276 :           scalar_mode inner_mode = GET_MODE_INNER (mode);
    1198                 :         276 :           base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
    1199                 :         276 :           if (base)
    1200                 :             :             {
    1201                 :         276 :               step = simplify_unary_operation (NEG, inner_mode,
    1202                 :             :                                                step, inner_mode);
    1203                 :         276 :               if (step)
    1204                 :         276 :                 return gen_vec_series (mode, base, step);
    1205                 :             :             }
    1206                 :             :         }
    1207                 :             :       break;
    1208                 :             : 
    1209                 :     1346299 :     case TRUNCATE:
    1210                 :             :       /* Don't optimize (lshiftrt (mult ...)) as it would interfere
    1211                 :             :          with the umulXi3_highpart patterns.  */
    1212                 :     1346299 :       if (GET_CODE (op) == LSHIFTRT
    1213                 :       18121 :           && GET_CODE (XEXP (op, 0)) == MULT)
    1214                 :             :         break;
    1215                 :             : 
    1216                 :     1338943 :       if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
    1217                 :             :         {
    1218                 :          12 :           if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
    1219                 :             :             {
    1220                 :          12 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1221                 :          12 :               if (temp)
    1222                 :             :                 return temp;
    1223                 :             :             }
    1224                 :             :           /* We can't handle truncation to a partial integer mode here
    1225                 :             :              because we don't know the real bitsize of the partial
    1226                 :             :              integer mode.  */
    1227                 :             :           break;
    1228                 :             :         }
    1229                 :             : 
    1230                 :     1338931 :       if (GET_MODE (op) != VOIDmode)
    1231                 :             :         {
    1232                 :     1338931 :           temp = simplify_truncation (mode, op, GET_MODE (op));
    1233                 :     1338931 :           if (temp)
    1234                 :             :             return temp;
    1235                 :             :         }
    1236                 :             : 
    1237                 :             :       /* If we know that the value is already truncated, we can
    1238                 :             :          replace the TRUNCATE with a SUBREG.  */
    1239                 :     1205660 :       if (known_eq (GET_MODE_NUNITS (mode), 1)
    1240                 :     1205660 :           && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
    1241                 :           0 :               || truncated_to_mode (mode, op)))
    1242                 :             :         {
    1243                 :     1194529 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1244                 :     1194529 :           if (temp)
    1245                 :             :             return temp;
    1246                 :             :         }
    1247                 :             : 
    1248                 :             :       /* A truncate of a comparison can be replaced with a subreg if
    1249                 :             :          STORE_FLAG_VALUE permits.  This is like the previous test,
    1250                 :             :          but it works even if the comparison is done in a mode larger
    1251                 :             :          than HOST_BITS_PER_WIDE_INT.  */
    1252                 :       11315 :       if (HWI_COMPUTABLE_MODE_P (mode)
    1253                 :         184 :           && COMPARISON_P (op)
    1254                 :           0 :           && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
    1255                 :       11315 :           && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
    1256                 :             :         {
    1257                 :           0 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1258                 :           0 :           if (temp)
    1259                 :             :             return temp;
    1260                 :             :         }
    1261                 :             : 
    1262                 :             :       /* A truncate of a memory is just loading the low part of the memory
    1263                 :             :          if we are not changing the meaning of the address. */
    1264                 :       11315 :       if (GET_CODE (op) == MEM
    1265                 :         296 :           && !VECTOR_MODE_P (mode)
    1266                 :         182 :           && !MEM_VOLATILE_P (op)
    1267                 :       11497 :           && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
    1268                 :             :         {
    1269                 :         182 :           temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
    1270                 :         182 :           if (temp)
    1271                 :             :             return temp;
    1272                 :             :         }
    1273                 :             : 
    1274                 :             :       /* Check for useless truncation.  */
    1275                 :       11315 :       if (GET_MODE (op) == mode)
    1276                 :             :         return op;
    1277                 :             :       break;
    1278                 :             : 
    1279                 :      171632 :     case FLOAT_TRUNCATE:
    1280                 :             :       /* Check for useless truncation.  */
    1281                 :      171632 :       if (GET_MODE (op) == mode)
    1282                 :             :         return op;
    1283                 :             : 
    1284                 :      171632 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1285                 :             :         break;
    1286                 :             : 
    1287                 :             :       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
    1288                 :      171478 :       if (GET_CODE (op) == FLOAT_EXTEND
    1289                 :           2 :           && GET_MODE (XEXP (op, 0)) == mode)
    1290                 :             :         return XEXP (op, 0);
    1291                 :             : 
    1292                 :             :       /* (float_truncate:SF (float_truncate:DF foo:XF))
    1293                 :             :          = (float_truncate:SF foo:XF).
    1294                 :             :          This may eliminate double rounding, so it is unsafe.
    1295                 :             : 
    1296                 :             :          (float_truncate:SF (float_extend:XF foo:DF))
    1297                 :             :          = (float_truncate:SF foo:DF).
    1298                 :             : 
    1299                 :             :          (float_truncate:DF (float_extend:XF foo:SF))
    1300                 :             :          = (float_extend:DF foo:SF).  */
    1301                 :      171478 :       if ((GET_CODE (op) == FLOAT_TRUNCATE
    1302                 :         133 :            && flag_unsafe_math_optimizations)
    1303                 :      171474 :           || GET_CODE (op) == FLOAT_EXTEND)
    1304                 :          12 :         return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
    1305                 :           6 :                                    > GET_MODE_UNIT_SIZE (mode)
    1306                 :             :                                    ? FLOAT_TRUNCATE : FLOAT_EXTEND,
    1307                 :             :                                    mode,
    1308                 :          12 :                                    XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1309                 :             : 
    1310                 :             :       /*  (float_truncate (float x)) is (float x)  */
    1311                 :      171472 :       if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1312                 :      171472 :           && (flag_unsafe_math_optimizations
    1313                 :        1419 :               || exact_int_to_float_conversion_p (op)))
    1314                 :        1418 :         return simplify_gen_unary (GET_CODE (op), mode,
    1315                 :             :                                    XEXP (op, 0),
    1316                 :        1418 :                                    GET_MODE (XEXP (op, 0)));
    1317                 :             : 
    1318                 :             :       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
    1319                 :             :          (OP:SF foo:SF) if OP is NEG or ABS.  */
    1320                 :      170054 :       if ((GET_CODE (op) == ABS
    1321                 :      170054 :            || GET_CODE (op) == NEG)
    1322                 :         209 :           && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
    1323                 :          28 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
    1324                 :          28 :         return simplify_gen_unary (GET_CODE (op), mode,
    1325                 :          28 :                                    XEXP (XEXP (op, 0), 0), mode);
    1326                 :             : 
    1327                 :             :       /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
    1328                 :             :          is (float_truncate:SF x).  */
    1329                 :      170026 :       if (GET_CODE (op) == SUBREG
    1330                 :         308 :           && subreg_lowpart_p (op)
    1331                 :      170331 :           && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
    1332                 :             :         return SUBREG_REG (op);
    1333                 :             :       break;
    1334                 :             : 
    1335                 :      593396 :     case FLOAT_EXTEND:
    1336                 :             :       /* Check for useless extension.  */
    1337                 :      593396 :       if (GET_MODE (op) == mode)
    1338                 :             :         return op;
    1339                 :             : 
    1340                 :      593396 :       if (DECIMAL_FLOAT_MODE_P (mode))
    1341                 :             :         break;
    1342                 :             : 
    1343                 :             :       /*  (float_extend (float_extend x)) is (float_extend x)
    1344                 :             : 
    1345                 :             :           (float_extend (float x)) is (float x) assuming that double
    1346                 :             :           rounding can't happen.
    1347                 :             :           */
    1348                 :      593293 :       if (GET_CODE (op) == FLOAT_EXTEND
    1349                 :      593293 :           || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
    1350                 :        1281 :               && exact_int_to_float_conversion_p (op)))
    1351                 :         560 :         return simplify_gen_unary (GET_CODE (op), mode,
    1352                 :             :                                    XEXP (op, 0),
    1353                 :         560 :                                    GET_MODE (XEXP (op, 0)));
    1354                 :             : 
    1355                 :             :       break;
    1356                 :             : 
    1357                 :      280001 :     case ABS:
    1358                 :             :       /* (abs (neg <foo>)) -> (abs <foo>) */
    1359                 :      280001 :       if (GET_CODE (op) == NEG)
    1360                 :          42 :         return simplify_gen_unary (ABS, mode, XEXP (op, 0),
    1361                 :          42 :                                    GET_MODE (XEXP (op, 0)));
    1362                 :             : 
    1363                 :             :       /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
    1364                 :             :          do nothing.  */
    1365                 :      279959 :       if (GET_MODE (op) == VOIDmode)
    1366                 :             :         break;
    1367                 :             : 
    1368                 :             :       /* If operand is something known to be positive, ignore the ABS.  */
    1369                 :      279959 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1370                 :             :                                      nonzero_bits (op, GET_MODE (op))))
    1371                 :             :         return op;
    1372                 :             : 
    1373                 :             :       /* Using nonzero_bits doesn't (currently) work for modes wider than
    1374                 :             :          HOST_WIDE_INT, so the following transformations help simplify
    1375                 :             :          ABS for TImode and wider.  */
    1376                 :      279775 :       switch (GET_CODE (op))
    1377                 :             :         {
    1378                 :             :         case ABS:
    1379                 :             :         case CLRSB:
    1380                 :             :         case FFS:
    1381                 :             :         case PARITY:
    1382                 :             :         case POPCOUNT:
    1383                 :             :         case SS_ABS:
    1384                 :             :           return op;
    1385                 :             : 
    1386                 :           0 :         case LSHIFTRT:
    1387                 :           0 :           if (CONST_INT_P (XEXP (op, 1))
    1388                 :           0 :               && INTVAL (XEXP (op, 1)) > 0
    1389                 :      279775 :               && is_a <scalar_int_mode> (mode, &int_mode)
    1390                 :           0 :               && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
    1391                 :             :             return op;
    1392                 :             :           break;
    1393                 :             : 
    1394                 :             :         default:
    1395                 :             :           break;
    1396                 :             :         }
    1397                 :             : 
    1398                 :             :       /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
    1399                 :      279775 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    1400                 :       35403 :           && (num_sign_bit_copies (op, int_mode)
    1401                 :       35403 :               == GET_MODE_PRECISION (int_mode)))
    1402                 :           4 :         return gen_rtx_NEG (int_mode, op);
    1403                 :             : 
    1404                 :             :       break;
    1405                 :             : 
    1406                 :           0 :     case FFS:
    1407                 :             :       /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)).  */
    1408                 :           0 :       if (GET_CODE (op) == SIGN_EXTEND
    1409                 :           0 :           || GET_CODE (op) == ZERO_EXTEND)
    1410                 :             :         {
    1411                 :           0 :           temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
    1412                 :           0 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1413                 :           0 :           return simplify_gen_unary (GET_CODE (op), mode, temp,
    1414                 :           0 :                                      GET_MODE (temp));
    1415                 :             :         }
    1416                 :             :       break;
    1417                 :             : 
    1418                 :        3250 :     case POPCOUNT:
    1419                 :        3250 :       switch (GET_CODE (op))
    1420                 :             :         {
    1421                 :           0 :         case BSWAP:
    1422                 :           0 :         case BITREVERSE:
    1423                 :             :           /* (popcount (bswap <X>)) = (popcount <X>).  */
    1424                 :           0 :           return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
    1425                 :           0 :                                      GET_MODE (XEXP (op, 0)));
    1426                 :             : 
    1427                 :          34 :         case ZERO_EXTEND:
    1428                 :             :           /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)).  */
    1429                 :          68 :           temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
    1430                 :          34 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1431                 :          34 :           return simplify_gen_unary (ZERO_EXTEND, mode, temp,
    1432                 :          34 :                                      GET_MODE (temp));
    1433                 :             : 
    1434                 :           0 :         case ROTATE:
    1435                 :           0 :         case ROTATERT:
    1436                 :             :           /* Rotations don't affect popcount.  */
    1437                 :           0 :           if (!side_effects_p (XEXP (op, 1)))
    1438                 :           0 :             return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
    1439                 :           0 :                                        GET_MODE (XEXP (op, 0)));
    1440                 :             :           break;
    1441                 :             : 
    1442                 :             :         default:
    1443                 :             :           break;
    1444                 :             :         }
    1445                 :             :       break;
    1446                 :             : 
    1447                 :           0 :     case PARITY:
    1448                 :           0 :       switch (GET_CODE (op))
    1449                 :             :         {
    1450                 :           0 :         case NOT:
    1451                 :           0 :         case BSWAP:
    1452                 :           0 :         case BITREVERSE:
    1453                 :           0 :           return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
    1454                 :           0 :                                      GET_MODE (XEXP (op, 0)));
    1455                 :             : 
    1456                 :           0 :         case ZERO_EXTEND:
    1457                 :           0 :         case SIGN_EXTEND:
    1458                 :           0 :           temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
    1459                 :           0 :                                      XEXP (op, 0), GET_MODE (XEXP (op, 0)));
    1460                 :           0 :           return simplify_gen_unary (GET_CODE (op), mode, temp,
    1461                 :           0 :                                      GET_MODE (temp));
    1462                 :             : 
    1463                 :           0 :         case ROTATE:
    1464                 :           0 :         case ROTATERT:
    1465                 :             :           /* Rotations don't affect parity.  */
    1466                 :           0 :           if (!side_effects_p (XEXP (op, 1)))
    1467                 :           0 :             return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
    1468                 :           0 :                                        GET_MODE (XEXP (op, 0)));
    1469                 :             :           break;
    1470                 :             : 
    1471                 :             :         case PARITY:
    1472                 :             :           /* (parity (parity x)) -> parity (x).  */
    1473                 :             :           return op;
    1474                 :             : 
    1475                 :             :         default:
    1476                 :             :           break;
    1477                 :             :         }
    1478                 :             :       break;
    1479                 :             : 
    1480                 :       28964 :     case BSWAP:
    1481                 :             :       /* (bswap (bswap x)) -> x.  */
    1482                 :       28964 :       if (GET_CODE (op) == BSWAP)
    1483                 :         128 :         return XEXP (op, 0);
    1484                 :             :       break;
    1485                 :             : 
    1486                 :           0 :     case BITREVERSE:
    1487                 :             :       /* (bitreverse (bitreverse x)) -> x.  */
    1488                 :           0 :       if (GET_CODE (op) == BITREVERSE)
    1489                 :           0 :         return XEXP (op, 0);
    1490                 :             :       break;
    1491                 :             : 
    1492                 :      928448 :     case FLOAT:
    1493                 :             :       /* (float (sign_extend <X>)) = (float <X>).  */
    1494                 :      928448 :       if (GET_CODE (op) == SIGN_EXTEND)
    1495                 :       10918 :         return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
    1496                 :       10918 :                                    GET_MODE (XEXP (op, 0)));
    1497                 :             :       break;
    1498                 :             : 
    1499                 :     3212735 :     case SIGN_EXTEND:
    1500                 :             :       /* Check for useless extension.  */
    1501                 :     3212735 :       if (GET_MODE (op) == mode)
    1502                 :             :         return op;
    1503                 :             : 
    1504                 :             :       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
    1505                 :             :          becomes just the MINUS if its mode is MODE.  This allows
    1506                 :             :          folding switch statements on machines using casesi (such as
    1507                 :             :          the VAX).  */
    1508                 :     3212695 :       if (GET_CODE (op) == TRUNCATE
    1509                 :          62 :           && GET_MODE (XEXP (op, 0)) == mode
    1510                 :          62 :           && GET_CODE (XEXP (op, 0)) == MINUS
    1511                 :           0 :           && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
    1512                 :           0 :           && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
    1513                 :             :         return XEXP (op, 0);
    1514                 :             : 
    1515                 :             :       /* Extending a widening multiplication should be canonicalized to
    1516                 :             :          a wider widening multiplication.  */
    1517                 :     3212695 :       if (GET_CODE (op) == MULT)
    1518                 :             :         {
    1519                 :       67317 :           rtx lhs = XEXP (op, 0);
    1520                 :       67317 :           rtx rhs = XEXP (op, 1);
    1521                 :       67317 :           enum rtx_code lcode = GET_CODE (lhs);
    1522                 :       67317 :           enum rtx_code rcode = GET_CODE (rhs);
    1523                 :             : 
    1524                 :             :           /* Widening multiplies usually extend both operands, but sometimes
    1525                 :             :              they use a shift to extract a portion of a register.  */
    1526                 :       67317 :           if ((lcode == SIGN_EXTEND
    1527                 :       67168 :                || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1528                 :         876 :               && (rcode == SIGN_EXTEND
    1529                 :         832 :                   || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1530                 :             :             {
    1531                 :         165 :               machine_mode lmode = GET_MODE (lhs);
    1532                 :         165 :               machine_mode rmode = GET_MODE (rhs);
    1533                 :         165 :               int bits;
    1534                 :             : 
    1535                 :         165 :               if (lcode == ASHIFTRT)
    1536                 :             :                 /* Number of bits not shifted off the end.  */
    1537                 :         125 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1538                 :         125 :                         - INTVAL (XEXP (lhs, 1)));
    1539                 :             :               else /* lcode == SIGN_EXTEND */
    1540                 :             :                 /* Size of inner mode.  */
    1541                 :          80 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1542                 :             : 
    1543                 :         165 :               if (rcode == ASHIFTRT)
    1544                 :         121 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1545                 :         121 :                          - INTVAL (XEXP (rhs, 1)));
    1546                 :             :               else /* rcode == SIGN_EXTEND */
    1547                 :          88 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1548                 :             : 
    1549                 :             :               /* We can only widen multiplies if the result is mathematiclly
    1550                 :             :                  equivalent.  I.e. if overflow was impossible.  */
    1551                 :         330 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1552                 :         108 :                 return simplify_gen_binary
    1553                 :         108 :                          (MULT, mode,
    1554                 :             :                           simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
    1555                 :         108 :                           simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
    1556                 :             :             }
    1557                 :             :         }
    1558                 :             : 
    1559                 :             :       /* Check for a sign extension of a subreg of a promoted
    1560                 :             :          variable, where the promotion is sign-extended, and the
    1561                 :             :          target mode is the same as the variable's promotion.  */
    1562                 :     3212587 :       if (GET_CODE (op) == SUBREG
    1563                 :      171816 :           && SUBREG_PROMOTED_VAR_P (op)
    1564                 :     3217529 :           && SUBREG_PROMOTED_SIGNED_P (op))
    1565                 :             :         {
    1566                 :           0 :           rtx subreg = SUBREG_REG (op);
    1567                 :           0 :           machine_mode subreg_mode = GET_MODE (subreg);
    1568                 :           0 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1569                 :             :             {
    1570                 :           0 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1571                 :           0 :               if (temp)
    1572                 :             :                 {
    1573                 :             :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1574                 :           0 :                   if (partial_subreg_p (temp))
    1575                 :             :                     {
    1576                 :           0 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1577                 :           0 :                       SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
    1578                 :             :                     }
    1579                 :           0 :                   return temp;
    1580                 :             :                 }
    1581                 :             :             }
    1582                 :             :           else
    1583                 :             :             /* Sign-extending a sign-extended subreg.  */
    1584                 :           0 :             return simplify_gen_unary (SIGN_EXTEND, mode,
    1585                 :           0 :                                        subreg, subreg_mode);
    1586                 :             :         }
    1587                 :             : 
    1588                 :             :       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
    1589                 :             :          (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1590                 :     3212587 :       if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
    1591                 :             :         {
    1592                 :       17994 :           gcc_assert (GET_MODE_UNIT_PRECISION (mode)
    1593                 :             :                       > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
    1594                 :        5998 :           return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
    1595                 :        5998 :                                      GET_MODE (XEXP (op, 0)));
    1596                 :             :         }
    1597                 :             : 
    1598                 :             :       /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1599                 :             :          is (sign_extend:M (subreg:O <X>)) if there is mode with
    1600                 :             :          GET_MODE_BITSIZE (N) - I bits.
    1601                 :             :          (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1602                 :             :          is similarly (zero_extend:M (subreg:O <X>)).  */
    1603                 :     3206589 :       if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
    1604                 :       84242 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1605                 :     3209085 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1606                 :        4834 :           && CONST_INT_P (XEXP (op, 1))
    1607                 :        4834 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1608                 :     3211297 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1609                 :        4708 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1610                 :             :         {
    1611                 :        4708 :           scalar_int_mode tmode;
    1612                 :        4708 :           gcc_assert (GET_MODE_PRECISION (int_mode)
    1613                 :             :                       > GET_MODE_PRECISION (op_mode));
    1614                 :        4708 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1615                 :        7078 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1616                 :             :             {
    1617                 :        2338 :               rtx inner =
    1618                 :        2338 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1619                 :        2338 :               if (inner)
    1620                 :        2338 :                 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
    1621                 :             :                                            ? SIGN_EXTEND : ZERO_EXTEND,
    1622                 :        2338 :                                            int_mode, inner, tmode);
    1623                 :             :             }
    1624                 :             :         }
    1625                 :             : 
    1626                 :             :       /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
    1627                 :             :          (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0.  */
    1628                 :     3204251 :       if (GET_CODE (op) == LSHIFTRT
    1629                 :         192 :           && CONST_INT_P (XEXP (op, 1))
    1630                 :         192 :           && XEXP (op, 1) != const0_rtx)
    1631                 :         192 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1632                 :             : 
    1633                 :             :       /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
    1634                 :             :          I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
    1635                 :             :          (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
    1636                 :             :          (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
    1637                 :             :          O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
    1638                 :             :          wider than O.  */
    1639                 :     3204059 :       if (GET_CODE (op) == TRUNCATE
    1640                 :          62 :           && GET_CODE (XEXP (op, 0)) == LSHIFTRT
    1641                 :           0 :           && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
    1642                 :             :         {
    1643                 :           0 :           scalar_int_mode m_mode, n_mode, o_mode;
    1644                 :           0 :           rtx old_shift = XEXP (op, 0);
    1645                 :           0 :           if (is_a <scalar_int_mode> (mode, &m_mode)
    1646                 :           0 :               && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
    1647                 :           0 :               && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
    1648                 :           0 :               && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
    1649                 :           0 :                  == INTVAL (XEXP (old_shift, 1)))
    1650                 :             :             {
    1651                 :           0 :               rtx new_shift = simplify_gen_binary (ASHIFTRT,
    1652                 :             :                                                    GET_MODE (old_shift),
    1653                 :             :                                                    XEXP (old_shift, 0),
    1654                 :             :                                                    XEXP (old_shift, 1));
    1655                 :           0 :               if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
    1656                 :           0 :                 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
    1657                 :           0 :                                            GET_MODE (new_shift));
    1658                 :           0 :               if (mode != GET_MODE (new_shift))
    1659                 :           0 :                 return simplify_gen_unary (TRUNCATE, mode, new_shift,
    1660                 :           0 :                                            GET_MODE (new_shift));
    1661                 :             :               return new_shift;
    1662                 :             :             }
    1663                 :             :         }
    1664                 :             : 
    1665                 :             :       /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
    1666                 :             :          we know the sign bit of OP must be clear.  */
    1667                 :     3204059 :       if (val_signbit_known_clear_p (GET_MODE (op),
    1668                 :     3204059 :                                      nonzero_bits (op, GET_MODE (op))))
    1669                 :       43762 :         return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
    1670                 :             : 
    1671                 :             :       /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1672                 :     3160297 :       if (GET_CODE (op) == SUBREG
    1673                 :      171263 :           && subreg_lowpart_p (op)
    1674                 :      171132 :           && GET_MODE (SUBREG_REG (op)) == mode
    1675                 :     3303915 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1676                 :      150396 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1677                 :      150396 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1678                 :      148570 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1679                 :     3308867 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1680                 :      148570 :               & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
    1681                 :        6778 :         return SUBREG_REG (op);
    1682                 :             : 
    1683                 :             : #if defined(POINTERS_EXTEND_UNSIGNED)
    1684                 :             :       /* As we do not know which address space the pointer is referring to,
    1685                 :             :          we can do this only if the target does not support different pointer
    1686                 :             :          or address modes depending on the address space.  */
    1687                 :     3153519 :       if (target_default_pointer_address_modes_p ()
    1688                 :             :           && ! POINTERS_EXTEND_UNSIGNED
    1689                 :             :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1690                 :             :           && (CONSTANT_P (op)
    1691                 :             :               || (GET_CODE (op) == SUBREG
    1692                 :             :                   && REG_P (SUBREG_REG (op))
    1693                 :             :                   && REG_POINTER (SUBREG_REG (op))
    1694                 :             :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1695                 :             :           && !targetm.have_ptr_extend ())
    1696                 :             :         {
    1697                 :             :           temp
    1698                 :             :             = convert_memory_address_addr_space_1 (Pmode, op,
    1699                 :             :                                                    ADDR_SPACE_GENERIC, false,
    1700                 :             :                                                    true);
    1701                 :             :           if (temp)
    1702                 :             :             return temp;
    1703                 :             :         }
    1704                 :             : #endif
    1705                 :             :       break;
    1706                 :             : 
    1707                 :    11807828 :     case ZERO_EXTEND:
    1708                 :             :       /* Check for useless extension.  */
    1709                 :    11807828 :       if (GET_MODE (op) == mode)
    1710                 :             :         return op;
    1711                 :             : 
    1712                 :             :       /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
    1713                 :             :          where const does not sign bit set. */
    1714                 :    11807788 :       if (GET_CODE (op) == AND
    1715                 :      130427 :           && CONST_INT_P (XEXP (op, 1))
    1716                 :      104421 :           && INTVAL (XEXP (op, 1)) > 0)
    1717                 :             :         {
    1718                 :       97592 :           rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
    1719                 :       97592 :           if (tem)
    1720                 :       80991 :             return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
    1721                 :             :         }
    1722                 :             : 
    1723                 :             :       /* Check for a zero extension of a subreg of a promoted
    1724                 :             :          variable, where the promotion is zero-extended, and the
    1725                 :             :          target mode is the same as the variable's promotion.  */
    1726                 :    11726797 :       if (GET_CODE (op) == SUBREG
    1727                 :     1477084 :           && SUBREG_PROMOTED_VAR_P (op)
    1728                 :    11727271 :           && SUBREG_PROMOTED_UNSIGNED_P (op))
    1729                 :             :         {
    1730                 :         474 :           rtx subreg = SUBREG_REG (op);
    1731                 :         474 :           machine_mode subreg_mode = GET_MODE (subreg);
    1732                 :         474 :           if (!paradoxical_subreg_p (mode, subreg_mode))
    1733                 :             :             {
    1734                 :         322 :               temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
    1735                 :         322 :               if (temp)
    1736                 :             :                 {
    1737                 :             :                   /* Preserve SUBREG_PROMOTED_VAR_P.  */
    1738                 :         322 :                   if (partial_subreg_p (temp))
    1739                 :             :                     {
    1740                 :         129 :                       SUBREG_PROMOTED_VAR_P (temp) = 1;
    1741                 :         129 :                       SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
    1742                 :             :                     }
    1743                 :         322 :                   return temp;
    1744                 :             :                 }
    1745                 :             :             }
    1746                 :             :           else
    1747                 :             :             /* Zero-extending a zero-extended subreg.  */
    1748                 :         152 :             return simplify_gen_unary (ZERO_EXTEND, mode,
    1749                 :         152 :                                        subreg, subreg_mode);
    1750                 :             :         }
    1751                 :             : 
    1752                 :             :       /* Extending a widening multiplication should be canonicalized to
    1753                 :             :          a wider widening multiplication.  */
    1754                 :    11726323 :       if (GET_CODE (op) == MULT)
    1755                 :             :         {
    1756                 :      176249 :           rtx lhs = XEXP (op, 0);
    1757                 :      176249 :           rtx rhs = XEXP (op, 1);
    1758                 :      176249 :           enum rtx_code lcode = GET_CODE (lhs);
    1759                 :      176249 :           enum rtx_code rcode = GET_CODE (rhs);
    1760                 :             : 
    1761                 :             :           /* Widening multiplies usually extend both operands, but sometimes
    1762                 :             :              they use a shift to extract a portion of a register.  */
    1763                 :      176249 :           if ((lcode == ZERO_EXTEND
    1764                 :      175513 :                || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
    1765                 :         784 :               && (rcode == ZERO_EXTEND
    1766                 :         672 :                   || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
    1767                 :             :             {
    1768                 :         112 :               machine_mode lmode = GET_MODE (lhs);
    1769                 :         112 :               machine_mode rmode = GET_MODE (rhs);
    1770                 :         112 :               int bits;
    1771                 :             : 
    1772                 :         112 :               if (lcode == LSHIFTRT)
    1773                 :             :                 /* Number of bits not shifted off the end.  */
    1774                 :           0 :                 bits = (GET_MODE_UNIT_PRECISION (lmode)
    1775                 :           0 :                         - INTVAL (XEXP (lhs, 1)));
    1776                 :             :               else /* lcode == ZERO_EXTEND */
    1777                 :             :                 /* Size of inner mode.  */
    1778                 :         224 :                 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
    1779                 :             : 
    1780                 :         112 :               if (rcode == LSHIFTRT)
    1781                 :           0 :                 bits += (GET_MODE_UNIT_PRECISION (rmode)
    1782                 :           0 :                          - INTVAL (XEXP (rhs, 1)));
    1783                 :             :               else /* rcode == ZERO_EXTEND */
    1784                 :         224 :                 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
    1785                 :             : 
    1786                 :             :               /* We can only widen multiplies if the result is mathematiclly
    1787                 :             :                  equivalent.  I.e. if overflow was impossible.  */
    1788                 :         224 :               if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
    1789                 :         112 :                 return simplify_gen_binary
    1790                 :         112 :                          (MULT, mode,
    1791                 :             :                           simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
    1792                 :         112 :                           simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
    1793                 :             :             }
    1794                 :             :         }
    1795                 :             : 
    1796                 :             :       /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
    1797                 :    11726211 :       if (GET_CODE (op) == ZERO_EXTEND)
    1798                 :       23783 :         return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
    1799                 :       23783 :                                    GET_MODE (XEXP (op, 0)));
    1800                 :             : 
    1801                 :             :       /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
    1802                 :             :          is (zero_extend:M (subreg:O <X>)) if there is mode with
    1803                 :             :          GET_MODE_PRECISION (N) - I bits.  */
    1804                 :    11702428 :       if (GET_CODE (op) == LSHIFTRT
    1805                 :       80288 :           && GET_CODE (XEXP (op, 0)) == ASHIFT
    1806                 :    11702451 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1807                 :          23 :           && CONST_INT_P (XEXP (op, 1))
    1808                 :          18 :           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
    1809                 :    11702428 :           && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
    1810                 :           0 :               GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
    1811                 :             :         {
    1812                 :           0 :           scalar_int_mode tmode;
    1813                 :           0 :           if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
    1814                 :           0 :                                  - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
    1815                 :             :             {
    1816                 :           0 :               rtx inner =
    1817                 :           0 :                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
    1818                 :           0 :               if (inner)
    1819                 :           0 :                 return simplify_gen_unary (ZERO_EXTEND, int_mode,
    1820                 :           0 :                                            inner, tmode);
    1821                 :             :             }
    1822                 :             :         }
    1823                 :             : 
    1824                 :             :       /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
    1825                 :             :          (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
    1826                 :             :          of mode N.  E.g.
    1827                 :             :          (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
    1828                 :             :          (and:SI (reg:SI) (const_int 63)).  */
    1829                 :    11702428 :       if (partial_subreg_p (op)
    1830                 :    13134718 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1831                 :     1458240 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
    1832                 :     1457686 :           && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
    1833                 :     1006939 :           && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
    1834                 :      984322 :           && subreg_lowpart_p (op)
    1835                 :     2149159 :           && (nonzero_bits (SUBREG_REG (op), op0_mode)
    1836                 :      672549 :               & ~GET_MODE_MASK (GET_MODE (op))) == 0)
    1837                 :             :         {
    1838                 :       25950 :           if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
    1839                 :       15828 :             return SUBREG_REG (op);
    1840                 :       10122 :           return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
    1841                 :       10122 :                                      op0_mode);
    1842                 :             :         }
    1843                 :             : 
    1844                 :             :       /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...).  */
    1845                 :    11676478 :       if (GET_CODE (op) == SUBREG
    1846                 :     1450660 :           && subreg_lowpart_p (op)
    1847                 :      757909 :           && GET_MODE (SUBREG_REG (op)) == mode
    1848                 :    12353714 :           && is_a <scalar_int_mode> (mode, &int_mode)
    1849                 :      677236 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1850                 :      677236 :           && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
    1851                 :      608316 :           && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
    1852                 :    12284794 :           && (nonzero_bits (SUBREG_REG (op), mode)
    1853                 :      608316 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1854                 :           0 :         return SUBREG_REG (op);
    1855                 :             : 
    1856                 :             :       /* Trying to optimize:
    1857                 :             :          (zero_extend:M (subreg:N (not:M (X:M)))) ->
    1858                 :             :          (xor:M (zero_extend:M (subreg:N (X:M)), mask))
    1859                 :             :          where the mask is GET_MODE_MASK (N).
    1860                 :             :          For the cases when X:M doesn't have any non-zero bits
    1861                 :             :          outside of mode N, (zero_extend:M (subreg:N (X:M))
    1862                 :             :          will be simplified to just (X:M)
    1863                 :             :          and whole optimization will be -> (xor:M (X:M, mask)).  */
    1864                 :    11676478 :       if (partial_subreg_p (op)
    1865                 :     1432290 :           && GET_CODE (XEXP (op, 0)) == NOT
    1866                 :        1901 :           && GET_MODE (XEXP (op, 0)) == mode
    1867                 :        1898 :           && subreg_lowpart_p (op)
    1868                 :    11676761 :           && HWI_COMPUTABLE_MODE_P (mode)
    1869                 :         284 :           && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
    1870                 :     1450944 :           && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
    1871                 :         284 :               & ~GET_MODE_MASK (op_mode)) == 0)
    1872                 :             :       {
    1873                 :           1 :         unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
    1874                 :           2 :         return simplify_gen_binary (XOR, mode,
    1875                 :           1 :                                     XEXP (XEXP (op, 0), 0),
    1876                 :           1 :                                     gen_int_mode (mask, mode));
    1877                 :             :       }
    1878                 :             : 
    1879                 :             : #if defined(POINTERS_EXTEND_UNSIGNED)
    1880                 :             :       /* As we do not know which address space the pointer is referring to,
    1881                 :             :          we can do this only if the target does not support different pointer
    1882                 :             :          or address modes depending on the address space.  */
    1883                 :    11676477 :       if (target_default_pointer_address_modes_p ()
    1884                 :             :           && POINTERS_EXTEND_UNSIGNED > 0
    1885                 :    12978340 :           && mode == Pmode && GET_MODE (op) == ptr_mode
    1886                 :         677 :           && (CONSTANT_P (op)
    1887                 :         656 :               || (GET_CODE (op) == SUBREG
    1888                 :           0 :                   && REG_P (SUBREG_REG (op))
    1889                 :           0 :                   && REG_POINTER (SUBREG_REG (op))
    1890                 :           0 :                   && GET_MODE (SUBREG_REG (op)) == Pmode))
    1891                 :    11676498 :           && !targetm.have_ptr_extend ())
    1892                 :             :         {
    1893                 :          21 :           temp
    1894                 :          21 :             = convert_memory_address_addr_space_1 (Pmode, op,
    1895                 :             :                                                    ADDR_SPACE_GENERIC, false,
    1896                 :             :                                                    true);
    1897                 :          21 :           if (temp)
    1898                 :             :             return temp;
    1899                 :             :         }
    1900                 :             : #endif
    1901                 :             :       break;
    1902                 :             : 
    1903                 :             :     default:
    1904                 :             :       break;
    1905                 :             :     }
    1906                 :             : 
    1907                 :    19453304 :   if (VECTOR_MODE_P (mode)
    1908                 :     1437664 :       && vec_duplicate_p (op, &elt)
    1909                 :    20896440 :       && code != VEC_DUPLICATE)
    1910                 :             :     {
    1911                 :        5468 :       if (code == SIGN_EXTEND || code == ZERO_EXTEND)
    1912                 :             :         /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
    1913                 :             :            operations by promoting VEC_DUPLICATE to the root of the expression
    1914                 :             :            (as far as possible).  */
    1915                 :        4413 :         temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
    1916                 :        8826 :                                    elt, GET_MODE_INNER (GET_MODE (op)));
    1917                 :             :       else
    1918                 :             :         /* Try applying the operator to ELT and see if that simplifies.
    1919                 :             :            We can duplicate the result if so.
    1920                 :             : 
    1921                 :             :            The reason we traditionally haven't used simplify_gen_unary
    1922                 :             :            for these codes is that it didn't necessarily seem to be a
    1923                 :             :            win to convert things like:
    1924                 :             : 
    1925                 :             :              (neg:V (vec_duplicate:V (reg:S R)))
    1926                 :             : 
    1927                 :             :            to:
    1928                 :             : 
    1929                 :             :              (vec_duplicate:V (neg:S (reg:S R)))
    1930                 :             : 
    1931                 :             :            The first might be done entirely in vector registers while the
    1932                 :             :            second might need a move between register files.
    1933                 :             : 
    1934                 :             :            However, there also cases where promoting the vec_duplicate is
    1935                 :             :            more efficient, and there is definite value in having a canonical
    1936                 :             :            form when matching instruction patterns.  We should consider
    1937                 :             :            extending the simplify_gen_unary code above to more cases.  */
    1938                 :        1055 :         temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
    1939                 :        2110 :                                          elt, GET_MODE_INNER (GET_MODE (op)));
    1940                 :        5468 :       if (temp)
    1941                 :        4987 :         return gen_vec_duplicate (mode, temp);
    1942                 :             :     }
    1943                 :             : 
    1944                 :             :   return 0;
    1945                 :             : }
    1946                 :             : 
    1947                 :             : /* Try to compute the value of a unary operation CODE whose output mode is to
    1948                 :             :    be MODE with input operand OP whose mode was originally OP_MODE.
    1949                 :             :    Return zero if the value cannot be computed.  */
    1950                 :             : rtx
    1951                 :    27769053 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
    1952                 :             :                                 rtx op, machine_mode op_mode)
    1953                 :             : {
    1954                 :    27769053 :   scalar_int_mode result_mode;
    1955                 :             : 
    1956                 :    27769053 :   if (code == VEC_DUPLICATE)
    1957                 :             :     {
    1958                 :     1570382 :       gcc_assert (VECTOR_MODE_P (mode));
    1959                 :     1570382 :       if (GET_MODE (op) != VOIDmode)
    1960                 :             :       {
    1961                 :      514244 :         if (!VECTOR_MODE_P (GET_MODE (op)))
    1962                 :     1015300 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
    1963                 :             :         else
    1964                 :       19782 :           gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
    1965                 :             :                                                 (GET_MODE (op)));
    1966                 :             :       }
    1967                 :     1570382 :       if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
    1968                 :     1091314 :         return gen_const_vec_duplicate (mode, op);
    1969                 :      479068 :       if (GET_CODE (op) == CONST_VECTOR
    1970                 :      479068 :           && (CONST_VECTOR_DUPLICATE_P (op)
    1971                 :             :               || CONST_VECTOR_NUNITS (op).is_constant ()))
    1972                 :             :         {
    1973                 :         755 :           unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
    1974                 :         755 :                                     ? CONST_VECTOR_NPATTERNS (op)
    1975                 :        1509 :                                     : CONST_VECTOR_NUNITS (op).to_constant ());
    1976                 :        2265 :           gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
    1977                 :         755 :           rtx_vector_builder builder (mode, npatterns, 1);
    1978                 :        3130 :           for (unsigned i = 0; i < npatterns; i++)
    1979                 :        2375 :             builder.quick_push (CONST_VECTOR_ELT (op, i));
    1980                 :         755 :           return builder.build ();
    1981                 :         755 :         }
    1982                 :             :     }
    1983                 :             : 
    1984                 :    25516602 :   if (VECTOR_MODE_P (mode)
    1985                 :     1495372 :       && GET_CODE (op) == CONST_VECTOR
    1986                 :    26833089 :       && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
    1987                 :             :     {
    1988                 :       52035 :       gcc_assert (GET_MODE (op) == op_mode);
    1989                 :             : 
    1990                 :       52035 :       rtx_vector_builder builder;
    1991                 :       52035 :       if (!builder.new_unary_operation (mode, op, false))
    1992                 :             :         return 0;
    1993                 :             : 
    1994                 :       52035 :       unsigned int count = builder.encoded_nelts ();
    1995                 :      201958 :       for (unsigned int i = 0; i < count; i++)
    1996                 :             :         {
    1997                 :      300884 :           rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
    1998                 :             :                                             CONST_VECTOR_ELT (op, i),
    1999                 :      300884 :                                             GET_MODE_INNER (op_mode));
    2000                 :      150442 :           if (!x || !valid_for_const_vector_p (mode, x))
    2001                 :         519 :             return 0;
    2002                 :      149923 :           builder.quick_push (x);
    2003                 :             :         }
    2004                 :       51516 :       return builder.build ();
    2005                 :       52035 :     }
    2006                 :             : 
    2007                 :             :   /* The order of these tests is critical so that, for example, we don't
    2008                 :             :      check the wrong mode (input vs. output) for a conversion operation,
    2009                 :             :      such as FIX.  At some point, this should be simplified.  */
    2010                 :             : 
    2011                 :    26624949 :   if (code == FLOAT && CONST_SCALAR_INT_P (op))
    2012                 :             :     {
    2013                 :        7139 :       REAL_VALUE_TYPE d;
    2014                 :             : 
    2015                 :        7139 :       if (op_mode == VOIDmode)
    2016                 :             :         {
    2017                 :             :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2018                 :             :              the bits of the constant are significant, though, this is
    2019                 :             :              a dangerous assumption as many times CONST_INTs are
    2020                 :             :              created and used with garbage in the bits outside of the
    2021                 :             :              precision of the implied mode of the const_int.  */
    2022                 :          63 :           op_mode = MAX_MODE_INT;
    2023                 :             :         }
    2024                 :             : 
    2025                 :        7139 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
    2026                 :             : 
    2027                 :             :       /* Avoid the folding if flag_signaling_nans is on and
    2028                 :             :          operand is a signaling NaN.  */
    2029                 :        7139 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2030                 :             :         return 0;
    2031                 :             : 
    2032                 :        7139 :       d = real_value_truncate (mode, d);
    2033                 :             : 
    2034                 :             :       /* Avoid the folding if flag_rounding_math is on and the
    2035                 :             :          conversion is not exact.  */
    2036                 :        7139 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2037                 :             :         {
    2038                 :        1003 :           bool fail = false;
    2039                 :        1003 :           wide_int w = real_to_integer (&d, &fail,
    2040                 :             :                                         GET_MODE_PRECISION
    2041                 :        1003 :                                           (as_a <scalar_int_mode> (op_mode)));
    2042                 :        2006 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2043                 :         897 :             return 0;
    2044                 :        1003 :         }
    2045                 :             : 
    2046                 :        6242 :       return const_double_from_real_value (d, mode);
    2047                 :             :     }
    2048                 :    26617810 :   else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
    2049                 :             :     {
    2050                 :        2147 :       REAL_VALUE_TYPE d;
    2051                 :             : 
    2052                 :        2147 :       if (op_mode == VOIDmode)
    2053                 :             :         {
    2054                 :             :           /* CONST_INT have VOIDmode as the mode.  We assume that all
    2055                 :             :              the bits of the constant are significant, though, this is
    2056                 :             :              a dangerous assumption as many times CONST_INTs are
    2057                 :             :              created and used with garbage in the bits outside of the
    2058                 :             :              precision of the implied mode of the const_int.  */
    2059                 :           8 :           op_mode = MAX_MODE_INT;
    2060                 :             :         }
    2061                 :             : 
    2062                 :        2147 :       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
    2063                 :             : 
    2064                 :             :       /* Avoid the folding if flag_signaling_nans is on and
    2065                 :             :          operand is a signaling NaN.  */
    2066                 :        2147 :       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2067                 :             :         return 0;
    2068                 :             : 
    2069                 :        2147 :       d = real_value_truncate (mode, d);
    2070                 :             : 
    2071                 :             :       /* Avoid the folding if flag_rounding_math is on and the
    2072                 :             :          conversion is not exact.  */
    2073                 :        2147 :       if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    2074                 :             :         {
    2075                 :          16 :           bool fail = false;
    2076                 :          16 :           wide_int w = real_to_integer (&d, &fail,
    2077                 :             :                                         GET_MODE_PRECISION
    2078                 :          16 :                                           (as_a <scalar_int_mode> (op_mode)));
    2079                 :          28 :           if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
    2080                 :          16 :             return 0;
    2081                 :          16 :         }
    2082                 :             : 
    2083                 :        2131 :       return const_double_from_real_value (d, mode);
    2084                 :             :     }
    2085                 :             : 
    2086                 :    26615663 :   if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
    2087                 :             :     {
    2088                 :     3405671 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2089                 :     3405671 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2090                 :             :         return 0;
    2091                 :             : 
    2092                 :     3405671 :       wide_int result;
    2093                 :     3405671 :       scalar_int_mode imode = (op_mode == VOIDmode
    2094                 :     3405671 :                                ? result_mode
    2095                 :     3405434 :                                : as_a <scalar_int_mode> (op_mode));
    2096                 :     3405671 :       rtx_mode_t op0 = rtx_mode_t (op, imode);
    2097                 :     3405671 :       int int_value;
    2098                 :             : 
    2099                 :             : #if TARGET_SUPPORTS_WIDE_INT == 0
    2100                 :             :       /* This assert keeps the simplification from producing a result
    2101                 :             :          that cannot be represented in a CONST_DOUBLE but a lot of
    2102                 :             :          upstream callers expect that this function never fails to
    2103                 :             :          simplify something and so you if you added this to the test
    2104                 :             :          above the code would die later anyway.  If this assert
    2105                 :             :          happens, you just need to make the port support wide int.  */
    2106                 :             :       gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
    2107                 :             : #endif
    2108                 :             : 
    2109                 :     3405671 :       switch (code)
    2110                 :             :         {
    2111                 :      181317 :         case NOT:
    2112                 :      181317 :           result = wi::bit_not (op0);
    2113                 :      181317 :           break;
    2114                 :             : 
    2115                 :     1894830 :         case NEG:
    2116                 :     1894830 :           result = wi::neg (op0);
    2117                 :     1894830 :           break;
    2118                 :             : 
    2119                 :        7142 :         case ABS:
    2120                 :        7142 :           result = wi::abs (op0);
    2121                 :        7142 :           break;
    2122                 :             : 
    2123                 :           0 :         case FFS:
    2124                 :           0 :           result = wi::shwi (wi::ffs (op0), result_mode);
    2125                 :           0 :           break;
    2126                 :             : 
    2127                 :         211 :         case CLZ:
    2128                 :         211 :           if (wi::ne_p (op0, 0))
    2129                 :          20 :             int_value = wi::clz (op0);
    2130                 :         382 :           else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2131                 :             :             return NULL_RTX;
    2132                 :          20 :           result = wi::shwi (int_value, result_mode);
    2133                 :          20 :           break;
    2134                 :             : 
    2135                 :           0 :         case CLRSB:
    2136                 :           0 :           result = wi::shwi (wi::clrsb (op0), result_mode);
    2137                 :           0 :           break;
    2138                 :             : 
    2139                 :           0 :         case CTZ:
    2140                 :           0 :           if (wi::ne_p (op0, 0))
    2141                 :           0 :             int_value = wi::ctz (op0);
    2142                 :           0 :           else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
    2143                 :             :             return NULL_RTX;
    2144                 :           0 :           result = wi::shwi (int_value, result_mode);
    2145                 :           0 :           break;
    2146                 :             : 
    2147                 :         171 :         case POPCOUNT:
    2148                 :         171 :           result = wi::shwi (wi::popcount (op0), result_mode);
    2149                 :         171 :           break;
    2150                 :             : 
    2151                 :           0 :         case PARITY:
    2152                 :           0 :           result = wi::shwi (wi::parity (op0), result_mode);
    2153                 :           0 :           break;
    2154                 :             : 
    2155                 :        2014 :         case BSWAP:
    2156                 :        2014 :           result = wi::bswap (op0);
    2157                 :        2014 :           break;
    2158                 :             : 
    2159                 :           0 :         case BITREVERSE:
    2160                 :           0 :           result = wi::bitreverse (op0);
    2161                 :           0 :           break;
    2162                 :             : 
    2163                 :     1155667 :         case TRUNCATE:
    2164                 :     1155667 :         case ZERO_EXTEND:
    2165                 :     1155667 :           result = wide_int::from (op0, width, UNSIGNED);
    2166                 :     1155667 :           break;
    2167                 :             : 
    2168                 :       14254 :         case US_TRUNCATE:
    2169                 :       14254 :         case SS_TRUNCATE:
    2170                 :       14254 :           {
    2171                 :       14254 :             signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
    2172                 :       14254 :             wide_int nmax
    2173                 :       14254 :               = wide_int::from (wi::max_value (width, sgn),
    2174                 :       28508 :                                 GET_MODE_PRECISION (imode), sgn);
    2175                 :       14254 :             wide_int nmin
    2176                 :       14254 :               = wide_int::from (wi::min_value (width, sgn),
    2177                 :       28508 :                                 GET_MODE_PRECISION (imode), sgn);
    2178                 :       14254 :             result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
    2179                 :       14254 :             result = wide_int::from (result, width, sgn);
    2180                 :       14254 :             break;
    2181                 :       14254 :           }
    2182                 :      150065 :         case SIGN_EXTEND:
    2183                 :      150065 :           result = wide_int::from (op0, width, SIGNED);
    2184                 :      150065 :           break;
    2185                 :             : 
    2186                 :           0 :         case SS_NEG:
    2187                 :           0 :           if (wi::only_sign_bit_p (op0))
    2188                 :           0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2189                 :             :           else
    2190                 :           0 :             result = wi::neg (op0);
    2191                 :             :           break;
    2192                 :             : 
    2193                 :           0 :         case SS_ABS:
    2194                 :           0 :           if (wi::only_sign_bit_p (op0))
    2195                 :           0 :             result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
    2196                 :             :           else
    2197                 :           0 :             result = wi::abs (op0);
    2198                 :             :           break;
    2199                 :             : 
    2200                 :             :         case SQRT:
    2201                 :             :         default:
    2202                 :             :           return 0;
    2203                 :             :         }
    2204                 :             : 
    2205                 :     3405480 :       return immed_wide_int_const (result, result_mode);
    2206                 :     3405671 :     }
    2207                 :             : 
    2208                 :    23209992 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2209                 :      485479 :            && SCALAR_FLOAT_MODE_P (mode)
    2210                 :      483483 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
    2211                 :             :     {
    2212                 :      483483 :       REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
    2213                 :      483483 :       switch (code)
    2214                 :             :         {
    2215                 :             :         case SQRT:
    2216                 :             :           return 0;
    2217                 :       23068 :         case ABS:
    2218                 :       23068 :           d = real_value_abs (&d);
    2219                 :       23068 :           break;
    2220                 :       15725 :         case NEG:
    2221                 :       15725 :           d = real_value_negate (&d);
    2222                 :       15725 :           break;
    2223                 :         923 :         case FLOAT_TRUNCATE:
    2224                 :             :           /* Don't perform the operation if flag_signaling_nans is on
    2225                 :             :              and the operand is a signaling NaN.  */
    2226                 :         923 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2227                 :             :             return NULL_RTX;
    2228                 :             :           /* Or if flag_rounding_math is on and the truncation is not
    2229                 :             :              exact.  */
    2230                 :         923 :           if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    2231                 :         923 :               && !exact_real_truncate (mode, &d))
    2232                 :         231 :             return NULL_RTX;
    2233                 :         692 :           d = real_value_truncate (mode, d);
    2234                 :         692 :           break;
    2235                 :      395111 :         case FLOAT_EXTEND:
    2236                 :             :           /* Don't perform the operation if flag_signaling_nans is on
    2237                 :             :              and the operand is a signaling NaN.  */
    2238                 :      395111 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2239                 :             :             return NULL_RTX;
    2240                 :             :           /* All this does is change the mode, unless changing
    2241                 :             :              mode class.  */
    2242                 :      395109 :           if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
    2243                 :           0 :             real_convert (&d, mode, &d);
    2244                 :             :           break;
    2245                 :           0 :         case FIX:
    2246                 :             :           /* Don't perform the operation if flag_signaling_nans is on
    2247                 :             :              and the operand is a signaling NaN.  */
    2248                 :           0 :           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
    2249                 :             :             return NULL_RTX;
    2250                 :           0 :           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
    2251                 :           0 :           break;
    2252                 :       48054 :         case NOT:
    2253                 :       48054 :           {
    2254                 :       48054 :             long tmp[4];
    2255                 :       48054 :             int i;
    2256                 :             : 
    2257                 :       48054 :             real_to_target (tmp, &d, GET_MODE (op));
    2258                 :      240270 :             for (i = 0; i < 4; i++)
    2259                 :      192216 :               tmp[i] = ~tmp[i];
    2260                 :       48054 :             real_from_target (&d, tmp, mode);
    2261                 :       48054 :             break;
    2262                 :             :           }
    2263                 :           0 :         default:
    2264                 :           0 :           gcc_unreachable ();
    2265                 :             :         }
    2266                 :      482648 :       return const_double_from_real_value (d, mode);
    2267                 :             :     }
    2268                 :        1996 :   else if (CONST_DOUBLE_AS_FLOAT_P (op)
    2269                 :        1996 :            && SCALAR_FLOAT_MODE_P (GET_MODE (op))
    2270                 :    22728505 :            && is_int_mode (mode, &result_mode))
    2271                 :             :     {
    2272                 :        1996 :       unsigned int width = GET_MODE_PRECISION (result_mode);
    2273                 :        1996 :       if (width > MAX_BITSIZE_MODE_ANY_INT)
    2274                 :             :         return 0;
    2275                 :             : 
    2276                 :             :       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
    2277                 :             :          operators are intentionally left unspecified (to ease implementation
    2278                 :             :          by target backends), for consistency, this routine implements the
    2279                 :             :          same semantics for constant folding as used by the middle-end.  */
    2280                 :             : 
    2281                 :             :       /* This was formerly used only for non-IEEE float.
    2282                 :             :          eggert@twinsun.com says it is safe for IEEE also.  */
    2283                 :        1996 :       REAL_VALUE_TYPE t;
    2284                 :        1996 :       const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
    2285                 :        1996 :       wide_int wmax, wmin;
    2286                 :             :       /* This is part of the abi to real_to_integer, but we check
    2287                 :             :          things before making this call.  */
    2288                 :        1996 :       bool fail;
    2289                 :             : 
    2290                 :        1996 :       switch (code)
    2291                 :             :         {
    2292                 :        1988 :         case FIX:
    2293                 :             :           /* According to IEEE standard, for conversions from floating point to
    2294                 :             :              integer. When a NaN or infinite operand cannot be represented in
    2295                 :             :              the destination format and this cannot otherwise be indicated, the
    2296                 :             :              invalid operation exception shall be signaled. When a numeric
    2297                 :             :              operand would convert to an integer outside the range of the
    2298                 :             :              destination format, the invalid operation exception shall be
    2299                 :             :              signaled if this situation cannot otherwise be indicated.  */
    2300                 :        1988 :           if (REAL_VALUE_ISNAN (*x))
    2301                 :         941 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2302                 :             : 
    2303                 :        1047 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2304                 :             :             return NULL_RTX;
    2305                 :             : 
    2306                 :             :           /* Test against the signed upper bound.  */
    2307                 :         101 :           wmax = wi::max_value (width, SIGNED);
    2308                 :         101 :           real_from_integer (&t, VOIDmode, wmax, SIGNED);
    2309                 :         101 :           if (real_less (&t, x))
    2310                 :           3 :             return (flag_trapping_math
    2311                 :           3 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2312                 :             : 
    2313                 :             :           /* Test against the signed lower bound.  */
    2314                 :          98 :           wmin = wi::min_value (width, SIGNED);
    2315                 :          98 :           real_from_integer (&t, VOIDmode, wmin, SIGNED);
    2316                 :          98 :           if (real_less (x, &t))
    2317                 :           8 :             return immed_wide_int_const (wmin, mode);
    2318                 :             : 
    2319                 :          90 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2320                 :             :                                        mode);
    2321                 :             : 
    2322                 :           8 :         case UNSIGNED_FIX:
    2323                 :           8 :           if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
    2324                 :           6 :             return flag_trapping_math ? NULL_RTX : const0_rtx;
    2325                 :             : 
    2326                 :           2 :           if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
    2327                 :             :             return NULL_RTX;
    2328                 :             : 
    2329                 :             :           /* Test against the unsigned upper bound.  */
    2330                 :           0 :           wmax = wi::max_value (width, UNSIGNED);
    2331                 :           0 :           real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
    2332                 :           0 :           if (real_less (&t, x))
    2333                 :           0 :             return (flag_trapping_math
    2334                 :           0 :                     ? NULL_RTX : immed_wide_int_const (wmax, mode));
    2335                 :             : 
    2336                 :           0 :           return immed_wide_int_const (real_to_integer (x, &fail, width),
    2337                 :             :                                        mode);
    2338                 :             : 
    2339                 :           0 :         default:
    2340                 :           0 :           gcc_unreachable ();
    2341                 :             :         }
    2342                 :        1996 :     }
    2343                 :             : 
    2344                 :             :   /* Handle polynomial integers.  */
    2345                 :             :   else if (CONST_POLY_INT_P (op))
    2346                 :             :     {
    2347                 :             :       poly_wide_int result;
    2348                 :             :       switch (code)
    2349                 :             :         {
    2350                 :             :         case NEG:
    2351                 :             :           result = -const_poly_int_value (op);
    2352                 :             :           break;
    2353                 :             : 
    2354                 :             :         case NOT:
    2355                 :             :           result = ~const_poly_int_value (op);
    2356                 :             :           break;
    2357                 :             : 
    2358                 :             :         default:
    2359                 :             :           return NULL_RTX;
    2360                 :             :         }
    2361                 :             :       return immed_wide_int_const (result, mode);
    2362                 :             :     }
    2363                 :             : 
    2364                 :             :   return NULL_RTX;
    2365                 :             : }
    2366                 :             : 
    2367                 :             : /* Subroutine of simplify_binary_operation to simplify a binary operation
    2368                 :             :    CODE that can commute with byte swapping, with result mode MODE and
    2369                 :             :    operating on OP0 and OP1.  CODE is currently one of AND, IOR or XOR.
    2370                 :             :    Return zero if no simplification or canonicalization is possible.  */
    2371                 :             : 
    2372                 :             : rtx
    2373                 :    39308379 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
    2374                 :             :                                                     machine_mode mode,
    2375                 :             :                                                     rtx op0, rtx op1)
    2376                 :             : {
    2377                 :    39308379 :   rtx tem;
    2378                 :             : 
    2379                 :             :   /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped.  */
    2380                 :    39308379 :   if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
    2381                 :             :     {
    2382                 :         503 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
    2383                 :             :                                  simplify_gen_unary (BSWAP, mode, op1, mode));
    2384                 :         503 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2385                 :             :     }
    2386                 :             : 
    2387                 :             :   /* (op (bswap x) (bswap y)) -> (bswap (op x y)).  */
    2388                 :    39307876 :   if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
    2389                 :             :     {
    2390                 :           0 :       tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
    2391                 :           0 :       return simplify_gen_unary (BSWAP, mode, tem, mode);
    2392                 :             :     }
    2393                 :             : 
    2394                 :             :   return NULL_RTX;
    2395                 :             : }
    2396                 :             : 
    2397                 :             : /* Subroutine of simplify_binary_operation to simplify a commutative,
    2398                 :             :    associative binary operation CODE with result mode MODE, operating
    2399                 :             :    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
    2400                 :             :    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
    2401                 :             :    canonicalization is possible.  */
    2402                 :             : 
    2403                 :             : rtx
    2404                 :    48850920 : simplify_context::simplify_associative_operation (rtx_code code,
    2405                 :             :                                                   machine_mode mode,
    2406                 :             :                                                   rtx op0, rtx op1)
    2407                 :             : {
    2408                 :    48850920 :   rtx tem;
    2409                 :             : 
    2410                 :             :   /* Normally expressions simplified by simplify-rtx.cc are combined
    2411                 :             :      at most from a few machine instructions and therefore the
    2412                 :             :      expressions should be fairly small.  During var-tracking
    2413                 :             :      we can see arbitrarily large expressions though and reassociating
    2414                 :             :      those can be quadratic, so punt after encountering max_assoc_count
    2415                 :             :      simplify_associative_operation calls during outermost simplify_*
    2416                 :             :      call.  */
    2417                 :    48850920 :   if (++assoc_count >= max_assoc_count)
    2418                 :             :     return NULL_RTX;
    2419                 :             : 
    2420                 :             :   /* Linearize the operator to the left.  */
    2421                 :    48849562 :   if (GET_CODE (op1) == code)
    2422                 :             :     {
    2423                 :             :       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
    2424                 :       26994 :       if (GET_CODE (op0) == code)
    2425                 :             :         {
    2426                 :        5614 :           tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
    2427                 :        5614 :           return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
    2428                 :             :         }
    2429                 :             : 
    2430                 :             :       /* "a op (b op c)" becomes "(b op c) op a".  */
    2431                 :       21380 :       if (! swap_commutative_operands_p (op1, op0))
    2432                 :       21380 :         return simplify_gen_binary (code, mode, op1, op0);
    2433                 :             : 
    2434                 :             :       std::swap (op0, op1);
    2435                 :             :     }
    2436                 :             : 
    2437                 :    48822568 :   if (GET_CODE (op0) == code)
    2438                 :             :     {
    2439                 :             :       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
    2440                 :     1547804 :       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
    2441                 :             :         {
    2442                 :      309737 :           tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
    2443                 :      309737 :           return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2444                 :             :         }
    2445                 :             : 
    2446                 :             :       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
    2447                 :     1238067 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
    2448                 :     1238067 :       if (tem != 0)
    2449                 :       90716 :         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
    2450                 :             : 
    2451                 :             :       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
    2452                 :     1147351 :       tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
    2453                 :     1147351 :       if (tem != 0)
    2454                 :       10193 :         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
    2455                 :             :     }
    2456                 :             : 
    2457                 :             :   return 0;
    2458                 :             : }
    2459                 :             : 
    2460                 :             : /* If COMPARISON can be treated as an unsigned comparison, return a mask
    2461                 :             :    that represents it (8 if it includes <, 4 if it includes > and 2
    2462                 :             :    if it includes ==).  Return 0 otherwise.  */
    2463                 :             : static int
    2464                 :       18730 : unsigned_comparison_to_mask (rtx_code comparison)
    2465                 :             : {
    2466                 :           0 :   switch (comparison)
    2467                 :             :     {
    2468                 :             :     case LTU:
    2469                 :             :       return 8;
    2470                 :             :     case GTU:
    2471                 :             :       return 4;
    2472                 :             :     case EQ:
    2473                 :             :       return 2;
    2474                 :             : 
    2475                 :             :     case LEU:
    2476                 :             :       return 10;
    2477                 :             :     case GEU:
    2478                 :             :       return 6;
    2479                 :             : 
    2480                 :             :     case NE:
    2481                 :             :       return 12;
    2482                 :             : 
    2483                 :             :     default:
    2484                 :             :       return 0;
    2485                 :             :     }
    2486                 :             : }
    2487                 :             : 
    2488                 :             : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
    2489                 :             :    to comparisons.  */
    2490                 :             : static rtx_code
    2491                 :        6528 : mask_to_unsigned_comparison (int mask)
    2492                 :             : {
    2493                 :        6528 :   switch (mask)
    2494                 :             :     {
    2495                 :             :     case 8:
    2496                 :             :       return LTU;
    2497                 :         160 :     case 4:
    2498                 :         160 :       return GTU;
    2499                 :        2535 :     case 2:
    2500                 :        2535 :       return EQ;
    2501                 :             : 
    2502                 :         160 :     case 10:
    2503                 :         160 :       return LEU;
    2504                 :         160 :     case 6:
    2505                 :         160 :       return GEU;
    2506                 :             : 
    2507                 :        3353 :     case 12:
    2508                 :        3353 :       return NE;
    2509                 :             : 
    2510                 :           0 :     default:
    2511                 :           0 :       gcc_unreachable ();
    2512                 :             :     }
    2513                 :             : }
    2514                 :             : 
    2515                 :             : /* Return a mask describing the COMPARISON.  */
    2516                 :             : static int
    2517                 :        2666 : comparison_to_mask (enum rtx_code comparison)
    2518                 :             : {
    2519                 :        2666 :   switch (comparison)
    2520                 :             :     {
    2521                 :             :     case LT:
    2522                 :             :       return 8;
    2523                 :         472 :     case GT:
    2524                 :         472 :       return 4;
    2525                 :         419 :     case EQ:
    2526                 :         419 :       return 2;
    2527                 :          19 :     case UNORDERED:
    2528                 :          19 :       return 1;
    2529                 :             : 
    2530                 :           0 :     case LTGT:
    2531                 :           0 :       return 12;
    2532                 :         441 :     case LE:
    2533                 :         441 :       return 10;
    2534                 :         441 :     case GE:
    2535                 :         441 :       return 6;
    2536                 :           0 :     case UNLT:
    2537                 :           0 :       return 9;
    2538                 :           0 :     case UNGT:
    2539                 :           0 :       return 5;
    2540                 :           0 :     case UNEQ:
    2541                 :           0 :       return 3;
    2542                 :             : 
    2543                 :           0 :     case ORDERED:
    2544                 :           0 :       return 14;
    2545                 :         400 :     case NE:
    2546                 :         400 :       return 13;
    2547                 :           0 :     case UNLE:
    2548                 :           0 :       return 11;
    2549                 :           0 :     case UNGE:
    2550                 :           0 :       return 7;
    2551                 :             : 
    2552                 :           0 :     default:
    2553                 :           0 :       gcc_unreachable ();
    2554                 :             :     }
    2555                 :             : }
    2556                 :             : 
    2557                 :             : /* Return a comparison corresponding to the MASK.  */
    2558                 :             : static enum rtx_code
    2559                 :        1014 : mask_to_comparison (int mask)
    2560                 :             : {
    2561                 :        1014 :   switch (mask)
    2562                 :             :     {
    2563                 :             :     case 8:
    2564                 :             :       return LT;
    2565                 :             :     case 4:
    2566                 :             :       return GT;
    2567                 :             :     case 2:
    2568                 :             :       return EQ;
    2569                 :             :     case 1:
    2570                 :             :       return UNORDERED;
    2571                 :             : 
    2572                 :             :     case 12:
    2573                 :             :       return LTGT;
    2574                 :             :     case 10:
    2575                 :             :       return LE;
    2576                 :             :     case 6:
    2577                 :             :       return GE;
    2578                 :             :     case 9:
    2579                 :             :       return UNLT;
    2580                 :             :     case 5:
    2581                 :             :       return UNGT;
    2582                 :             :     case 3:
    2583                 :             :       return UNEQ;
    2584                 :             : 
    2585                 :             :     case 14:
    2586                 :             :       return ORDERED;
    2587                 :             :     case 13:
    2588                 :             :       return NE;
    2589                 :             :     case 11:
    2590                 :             :       return UNLE;
    2591                 :             :     case 7:
    2592                 :             :       return UNGE;
    2593                 :             : 
    2594                 :           0 :     default:
    2595                 :           0 :       gcc_unreachable ();
    2596                 :             :     }
    2597                 :             : }
    2598                 :             : 
    2599                 :             : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
    2600                 :             :    false/true value of comparison with MODE where comparison operands
    2601                 :             :    have CMP_MODE.  */
    2602                 :             : 
    2603                 :             : static rtx
    2604                 :      846544 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
    2605                 :             : {
    2606                 :      846544 :   if (SCALAR_FLOAT_MODE_P (mode))
    2607                 :             :     {
    2608                 :         202 :       if (res == const0_rtx)
    2609                 :         198 :         return CONST0_RTX (mode);
    2610                 :             : #ifdef FLOAT_STORE_FLAG_VALUE
    2611                 :             :       REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
    2612                 :             :       return const_double_from_real_value (val, mode);
    2613                 :             : #else
    2614                 :             :       return NULL_RTX;
    2615                 :             : #endif
    2616                 :             :     }
    2617                 :      846342 :   if (VECTOR_MODE_P (mode))
    2618                 :             :     {
    2619                 :         350 :       if (res == const0_rtx)
    2620                 :          51 :         return CONST0_RTX (mode);
    2621                 :             : #ifdef VECTOR_STORE_FLAG_VALUE
    2622                 :         299 :       rtx val = VECTOR_STORE_FLAG_VALUE (mode);
    2623                 :         299 :       if (val == NULL_RTX)
    2624                 :             :         return NULL_RTX;
    2625                 :         299 :       if (val == const1_rtx)
    2626                 :           0 :         return CONST1_RTX (mode);
    2627                 :             : 
    2628                 :         299 :       return gen_const_vec_duplicate (mode, val);
    2629                 :             : #else
    2630                 :             :       return NULL_RTX;
    2631                 :             : #endif
    2632                 :             :     }
    2633                 :             :   /* For vector comparison with scalar int result, it is unknown
    2634                 :             :      if the target means here a comparison into an integral bitmask,
    2635                 :             :      or comparison where all comparisons true mean const_true_rtx
    2636                 :             :      whole result, or where any comparisons true mean const_true_rtx
    2637                 :             :      whole result.  For const0_rtx all the cases are the same.  */
    2638                 :      845992 :   if (VECTOR_MODE_P (cmp_mode)
    2639                 :           0 :       && SCALAR_INT_MODE_P (mode)
    2640                 :           0 :       && res == const_true_rtx)
    2641                 :           0 :     return NULL_RTX;
    2642                 :             : 
    2643                 :             :   return res;
    2644                 :             : }
    2645                 :             : 
    2646                 :             : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
    2647                 :             :    and OP1, in the case where both are relational operations.  Assume that
    2648                 :             :    OP0 is inverted if INVERT0_P is true.
    2649                 :             : 
    2650                 :             :    Return 0 if no such simplification is possible.  */
    2651                 :             : rtx
    2652                 :    15023759 : simplify_context::simplify_logical_relational_operation (rtx_code code,
    2653                 :             :                                                          machine_mode mode,
    2654                 :             :                                                          rtx op0, rtx op1,
    2655                 :             :                                                          bool invert0_p)
    2656                 :             : {
    2657                 :    15023759 :   if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
    2658                 :             :     return 0;
    2659                 :             : 
    2660                 :       21688 :   if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2661                 :        9860 :         && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
    2662                 :        2463 :     return 0;
    2663                 :             : 
    2664                 :        9365 :   if (side_effects_p (op0))
    2665                 :             :     return 0;
    2666                 :             : 
    2667                 :        9365 :   enum rtx_code code0 = GET_CODE (op0);
    2668                 :        9365 :   enum rtx_code code1 = GET_CODE (op1);
    2669                 :        9365 :   machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
    2670                 :        9365 :   if (cmp_mode == VOIDmode)
    2671                 :           0 :     cmp_mode = GET_MODE (XEXP (op0, 1));
    2672                 :             : 
    2673                 :             :   /* Assume at first that the comparisons are on integers, and that the
    2674                 :             :      operands are therefore ordered.  */
    2675                 :        9365 :   int all = 14;
    2676                 :        9365 :   int mask0 = unsigned_comparison_to_mask (code0);
    2677                 :        9365 :   int mask1 = unsigned_comparison_to_mask (code1);
    2678                 :       18730 :   bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
    2679                 :        9365 :                      || IN_RANGE (mask1 & 12, 4, 8));
    2680                 :        1333 :   if (unsigned_p)
    2681                 :             :     {
    2682                 :             :       /* We only reach here when comparing integers.  Reject mixtures of signed
    2683                 :             :          and unsigned comparisons.  */
    2684                 :        8032 :       if (mask0 == 0 || mask1 == 0)
    2685                 :             :         return 0;
    2686                 :             :     }
    2687                 :             :   else
    2688                 :             :     {
    2689                 :             :       /* See whether the operands might be unordered.  Assume that all
    2690                 :             :          results are possible for CC modes, and punt later if we don't get an
    2691                 :             :          always-true or always-false answer.  */
    2692                 :        1333 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
    2693                 :             :         all = 15;
    2694                 :        1333 :       mask0 = comparison_to_mask (code0) & all;
    2695                 :        1333 :       mask1 = comparison_to_mask (code1) & all;
    2696                 :             :     }
    2697                 :             : 
    2698                 :        8085 :   if (invert0_p)
    2699                 :        4603 :     mask0 = mask0 ^ all;
    2700                 :             : 
    2701                 :        8085 :   int mask;
    2702                 :        8085 :   if (code == AND)
    2703                 :         960 :     mask = mask0 & mask1;
    2704                 :        7125 :   else if (code == IOR)
    2705                 :         948 :     mask = mask0 | mask1;
    2706                 :        6177 :   else if (code == XOR)
    2707                 :        6177 :     mask = mask0 ^ mask1;
    2708                 :             :   else
    2709                 :             :     return 0;
    2710                 :             : 
    2711                 :        8085 :   if (mask == all)
    2712                 :         232 :     return relational_result (mode, GET_MODE (op0), const_true_rtx);
    2713                 :             : 
    2714                 :        7853 :   if (mask == 0)
    2715                 :         232 :     return relational_result (mode, GET_MODE (op0), const0_rtx);
    2716                 :             : 
    2717                 :        7621 :   if (unsigned_p)
    2718                 :        6528 :     code = mask_to_unsigned_comparison (mask);
    2719                 :             :   else
    2720                 :             :     {
    2721                 :        1093 :       if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    2722                 :             :         return 0;
    2723                 :             : 
    2724                 :        1014 :       code = mask_to_comparison (mask);
    2725                 :             :       /* LTGT and NE are arithmetically equivalent for ordered operands,
    2726                 :             :          with NE being the canonical choice.  */
    2727                 :        1014 :       if (code == LTGT && all == 14)
    2728                 :         184 :         code = NE;
    2729                 :             :     }
    2730                 :             : 
    2731                 :        7542 :   op0 = XEXP (op1, 0);
    2732                 :        7542 :   op1 = XEXP (op1, 1);
    2733                 :             : 
    2734                 :        7542 :   return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
    2735                 :             : }
    2736                 :             : 
    2737                 :             : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
    2738                 :             :    and OP1.  Return 0 if no simplification is possible.
    2739                 :             : 
    2740                 :             :    Don't use this for relational operations such as EQ or LT.
    2741                 :             :    Use simplify_relational_operation instead.  */
    2742                 :             : rtx
    2743                 :   472770640 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
    2744                 :             :                                              rtx op0, rtx op1)
    2745                 :             : {
    2746                 :   472770640 :   rtx trueop0, trueop1;
    2747                 :   472770640 :   rtx tem;
    2748                 :             : 
    2749                 :             :   /* Relational operations don't work here.  We must know the mode
    2750                 :             :      of the operands in order to do the comparison correctly.
    2751                 :             :      Assuming a full word can give incorrect results.
    2752                 :             :      Consider comparing 128 with -128 in QImode.  */
    2753                 :   472770640 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
    2754                 :   472770640 :   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
    2755                 :             : 
    2756                 :             :   /* Make sure the constant is second.  */
    2757                 :   472770640 :   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
    2758                 :   472770640 :       && swap_commutative_operands_p (op0, op1))
    2759                 :             :     std::swap (op0, op1);
    2760                 :             : 
    2761                 :   472770640 :   trueop0 = avoid_constant_pool_reference (op0);
    2762                 :   472770640 :   trueop1 = avoid_constant_pool_reference (op1);
    2763                 :             : 
    2764                 :   472770640 :   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
    2765                 :   472770640 :   if (tem)
    2766                 :             :     return tem;
    2767                 :   442613280 :   tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
    2768                 :             : 
    2769                 :   442613280 :   if (tem)
    2770                 :             :     return tem;
    2771                 :             : 
    2772                 :             :   /* If the above steps did not result in a simplification and op0 or op1
    2773                 :             :      were constant pool references, use the referenced constants directly.  */
    2774                 :   380559006 :   if (trueop0 != op0 || trueop1 != op1)
    2775                 :      579533 :     return simplify_gen_binary (code, mode, trueop0, trueop1);
    2776                 :             : 
    2777                 :             :   return NULL_RTX;
    2778                 :             : }
    2779                 :             : 
    2780                 :             : /* Subroutine of simplify_binary_operation_1 that looks for cases in
    2781                 :             :    which OP0 and OP1 are both vector series or vector duplicates
    2782                 :             :    (which are really just series with a step of 0).  If so, try to
    2783                 :             :    form a new series by applying CODE to the bases and to the steps.
    2784                 :             :    Return null if no simplification is possible.
    2785                 :             : 
    2786                 :             :    MODE is the mode of the operation and is known to be a vector
    2787                 :             :    integer mode.  */
    2788                 :             : 
    2789                 :             : rtx
    2790                 :     2229819 : simplify_context::simplify_binary_operation_series (rtx_code code,
    2791                 :             :                                                     machine_mode mode,
    2792                 :             :                                                     rtx op0, rtx op1)
    2793                 :             : {
    2794                 :     2229819 :   rtx base0, step0;
    2795                 :     2229819 :   if (vec_duplicate_p (op0, &base0))
    2796                 :       64961 :     step0 = const0_rtx;
    2797                 :     2164858 :   else if (!vec_series_p (op0, &base0, &step0))
    2798                 :             :     return NULL_RTX;
    2799                 :             : 
    2800                 :       65277 :   rtx base1, step1;
    2801                 :       65277 :   if (vec_duplicate_p (op1, &base1))
    2802                 :         376 :     step1 = const0_rtx;
    2803                 :       64901 :   else if (!vec_series_p (op1, &base1, &step1))
    2804                 :             :     return NULL_RTX;
    2805                 :             : 
    2806                 :             :   /* Only create a new series if we can simplify both parts.  In other
    2807                 :             :      cases this isn't really a simplification, and it's not necessarily
    2808                 :             :      a win to replace a vector operation with a scalar operation.  */
    2809                 :        3362 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    2810                 :        3362 :   rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
    2811                 :        3362 :   if (!new_base)
    2812                 :             :     return NULL_RTX;
    2813                 :             : 
    2814                 :        3101 :   rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
    2815                 :        3101 :   if (!new_step)
    2816                 :             :     return NULL_RTX;
    2817                 :             : 
    2818                 :        3101 :   return gen_vec_series (mode, new_base, new_step);
    2819                 :             : }
    2820                 :             : 
    2821                 :             : /* Subroutine of simplify_binary_operation_1.  Un-distribute a binary
    2822                 :             :    operation CODE with result mode MODE, operating on OP0 and OP1.
    2823                 :             :    e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
    2824                 :             :    Returns NULL_RTX if no simplification is possible.  */
    2825                 :             : 
    2826                 :             : rtx
    2827                 :     1493184 : simplify_context::simplify_distributive_operation (rtx_code code,
    2828                 :             :                                                    machine_mode mode,
    2829                 :             :                                                    rtx op0, rtx op1)
    2830                 :             : {
    2831                 :     1493184 :   enum rtx_code op = GET_CODE (op0);
    2832                 :     1493184 :   gcc_assert (GET_CODE (op1) == op);
    2833                 :             : 
    2834                 :     1493184 :   if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
    2835                 :     1493184 :       && ! side_effects_p (XEXP (op0, 1)))
    2836                 :      317043 :     return simplify_gen_binary (op, mode,
    2837                 :             :                                 simplify_gen_binary (code, mode,
    2838                 :             :                                                      XEXP (op0, 0),
    2839                 :             :                                                      XEXP (op1, 0)),
    2840                 :      317043 :                                 XEXP (op0, 1));
    2841                 :             : 
    2842                 :     1176141 :   if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
    2843                 :             :     {
    2844                 :     1148308 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    2845                 :     1148308 :           && ! side_effects_p (XEXP (op0, 0)))
    2846                 :      523936 :         return simplify_gen_binary (op, mode,
    2847                 :             :                                     simplify_gen_binary (code, mode,
    2848                 :             :                                                          XEXP (op0, 1),
    2849                 :             :                                                          XEXP (op1, 1)),
    2850                 :      523936 :                                     XEXP (op0, 0));
    2851                 :      624372 :       if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
    2852                 :      624372 :           && ! side_effects_p (XEXP (op0, 0)))
    2853                 :          52 :         return simplify_gen_binary (op, mode,
    2854                 :             :                                     simplify_gen_binary (code, mode,
    2855                 :             :                                                          XEXP (op0, 1),
    2856                 :             :                                                          XEXP (op1, 0)),
    2857                 :          52 :                                     XEXP (op0, 0));
    2858                 :      624320 :       if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
    2859                 :      624320 :           && ! side_effects_p (XEXP (op0, 1)))
    2860                 :      322540 :         return simplify_gen_binary (op, mode,
    2861                 :             :                                     simplify_gen_binary (code, mode,
    2862                 :             :                                                          XEXP (op0, 0),
    2863                 :             :                                                          XEXP (op1, 1)),
    2864                 :      322540 :                                     XEXP (op0, 1));
    2865                 :             :     }
    2866                 :             : 
    2867                 :             :   return NULL_RTX;
    2868                 :             : }
    2869                 :             : 
    2870                 :             : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
    2871                 :             :    should be reversed.
    2872                 :             : 
    2873                 :             :    If the rotate should not be reversed, return FALSE.
    2874                 :             : 
    2875                 :             :    LEFT indicates if this is a rotate left or a rotate right.  */
    2876                 :             : 
    2877                 :             : bool
    2878                 :      142145 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
    2879                 :             : {
    2880                 :      142145 :   if (!CONST_INT_P (op1))
    2881                 :             :     return false;
    2882                 :             : 
    2883                 :             :   /* Some targets may only be able to rotate by a constant
    2884                 :             :      in one direction.  So we need to query the optab interface
    2885                 :             :      to see what is possible.  */
    2886                 :      110495 :   optab binoptab = left ? rotl_optab : rotr_optab;
    2887                 :       46199 :   optab re_binoptab = left ? rotr_optab : rotl_optab;
    2888                 :      110495 :   enum insn_code icode = optab_handler (binoptab, mode);
    2889                 :      110495 :   enum insn_code re_icode = optab_handler (re_binoptab, mode);
    2890                 :             : 
    2891                 :             :   /* If the target can not support the reversed optab, then there
    2892                 :             :      is nothing to do.  */
    2893                 :      110495 :   if (re_icode == CODE_FOR_nothing)
    2894                 :             :     return false;
    2895                 :             : 
    2896                 :             :   /* If the target does not support the requested rotate-by-immediate,
    2897                 :             :      then we want to try reversing the rotate.  We also want to try
    2898                 :             :      reversing to minimize the count.  */
    2899                 :      107995 :   if ((icode == CODE_FOR_nothing)
    2900                 :      107995 :       || (!insn_operand_matches (icode, 2, op1))
    2901                 :      539975 :       || (IN_RANGE (INTVAL (op1),
    2902                 :             :                     GET_MODE_UNIT_PRECISION (mode) / 2 + left,
    2903                 :             :                     GET_MODE_UNIT_PRECISION (mode) - 1)))
    2904                 :       14078 :     return (insn_operand_matches (re_icode, 2, op1));
    2905                 :             :   return false;
    2906                 :             : }
    2907                 :             : 
    2908                 :             : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
    2909                 :             :    and return the expression to be shifted in SHIFT_OPND and the shift amount
    2910                 :             :    in SHIFT_AMNT.  This is primarily used to group handling of ASHIFT (X, CST)
    2911                 :             :    and (PLUS (X, X)) in one place.  If the expression is not equivalent to an
    2912                 :             :    ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL.  */
    2913                 :             : 
    2914                 :             : static bool
    2915                 :   523717161 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
    2916                 :             : {
    2917                 :   523717161 :   if (GET_CODE (x) == ASHIFT)
    2918                 :             :     {
    2919                 :    13681666 :       *shift_opnd = XEXP (x, 0);
    2920                 :    13681666 :       *shift_amnt = XEXP (x, 1);
    2921                 :    13681666 :       return true;
    2922                 :             :     }
    2923                 :   510035495 :   if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
    2924                 :             :     {
    2925                 :       10426 :       *shift_opnd = XEXP (x, 0);
    2926                 :       10426 :       *shift_amnt = CONST1_RTX (GET_MODE (x));
    2927                 :       10426 :       return true;
    2928                 :             :     }
    2929                 :   510025069 :   *shift_opnd = NULL_RTX;
    2930                 :   510025069 :   *shift_amnt = NULL_RTX;
    2931                 :   510025069 :   return false;
    2932                 :             : }
    2933                 :             : 
    2934                 :             : /* OP0 and OP1 are combined under an operation of mode MODE that can
    2935                 :             :    potentially result in a ROTATE expression.  Analyze the OP0 and OP1
    2936                 :             :    and return the resulting ROTATE expression if so.  Return NULL otherwise.
    2937                 :             :    This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
    2938                 :             :    C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
    2939                 :             :    (X << C1) and (C >> C2) would be OP0 and OP1.  */
    2940                 :             : 
    2941                 :             : static rtx
    2942                 :   264008263 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
    2943                 :             : {
    2944                 :             :   /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    2945                 :             :      mode size to (rotate A CX).  */
    2946                 :             : 
    2947                 :   264008263 :   rtx opleft = op0;
    2948                 :   264008263 :   rtx opright = op1;
    2949                 :   264008263 :   rtx ashift_opnd, ashift_amnt;
    2950                 :             :   /* In some cases the ASHIFT is not a direct ASHIFT.  Look deeper and extract
    2951                 :             :      the relevant operands here.  */
    2952                 :   264008263 :   bool ashift_op_p
    2953                 :   264008263 :     = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
    2954                 :             : 
    2955                 :   264008263 :   if (ashift_op_p
    2956                 :   262317880 :      || GET_CODE (op1) == SUBREG)
    2957                 :             :     {
    2958                 :             :       opleft = op1;
    2959                 :             :       opright = op0;
    2960                 :             :     }
    2961                 :             :   else
    2962                 :             :     {
    2963                 :   259708898 :       opright = op1;
    2964                 :   259708898 :       opleft = op0;
    2965                 :   259708898 :       ashift_op_p
    2966                 :   259708898 :         = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
    2967                 :             :     }
    2968                 :             : 
    2969                 :    13692092 :   if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
    2970                 :   262360442 :       && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
    2971                 :             :     {
    2972                 :        9793 :       rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
    2973                 :        9793 :       rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
    2974                 :             : 
    2975                 :        5963 :       if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
    2976                 :       15756 :           && (INTVAL (leftcst) + INTVAL (rightcst)
    2977                 :        5963 :               == GET_MODE_UNIT_PRECISION (mode)))
    2978                 :        5358 :         return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
    2979                 :             :     }
    2980                 :             : 
    2981                 :             :   /* Same, but for ashift that has been "simplified" to a wider mode
    2982                 :             :      by simplify_shift_const.  */
    2983                 :   264002905 :   scalar_int_mode int_mode, inner_mode;
    2984                 :             : 
    2985                 :   264002905 :   if (GET_CODE (opleft) == SUBREG
    2986                 :   267800984 :       && is_a <scalar_int_mode> (mode, &int_mode)
    2987                 :     3792721 :       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
    2988                 :             :                                  &inner_mode)
    2989                 :     3764593 :       && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
    2990                 :      109868 :       && GET_CODE (opright) == LSHIFTRT
    2991                 :        1174 :       && GET_CODE (XEXP (opright, 0)) == SUBREG
    2992                 :         141 :       && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
    2993                 :         278 :       && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
    2994                 :         125 :       && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
    2995                 :         125 :                       SUBREG_REG (XEXP (opright, 0)))
    2996                 :          19 :       && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
    2997                 :          19 :       && CONST_INT_P (XEXP (opright, 1))
    2998                 :   264002905 :       && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
    2999                 :          19 :             + INTVAL (XEXP (opright, 1))
    3000                 :          19 :          == GET_MODE_PRECISION (int_mode)))
    3001                 :          15 :         return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
    3002                 :             :                                XEXP (SUBREG_REG (opleft), 1));
    3003                 :             :   return NULL_RTX;
    3004                 :             : }
    3005                 :             : 
    3006                 :             : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
    3007                 :             :    and the pattern can be simplified (there are no side effects).  */
    3008                 :             : 
    3009                 :             : static bool
    3010                 :    41443482 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
    3011                 :             : {
    3012                 :             :   /* Remove SUBREG from OP0 and OP1, if needed.  */
    3013                 :    41443482 :   if (GET_CODE (op0) == SUBREG
    3014                 :     7256313 :       && GET_CODE (op1) == SUBREG
    3015                 :      281221 :       && subreg_lowpart_p (op0)
    3016                 :    41723309 :       && subreg_lowpart_p (op1))
    3017                 :             :     {
    3018                 :      279818 :       op0 = XEXP (op0, 0);
    3019                 :      279818 :       op1 = XEXP (op1, 0);
    3020                 :             :     }
    3021                 :             : 
    3022                 :             :   /* Check for the pattern (OP (plus (A - 1)) (neg A)).  */
    3023                 :    41443482 :   if (((GET_CODE (op1) == NEG
    3024                 :        3580 :         && GET_CODE (op0) == PLUS
    3025                 :        2179 :         && XEXP (op0, 1) == CONSTM1_RTX (mode))
    3026                 :    41442833 :        || (GET_CODE (op0) == NEG
    3027                 :       77146 :            && GET_CODE (op1) == PLUS
    3028                 :           0 :            && XEXP (op1, 1) == CONSTM1_RTX (mode)))
    3029                 :         649 :       && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3030                 :    41443484 :       && !side_effects_p (XEXP (op0, 0)))
    3031                 :             :     return true;
    3032                 :             :   return false;
    3033                 :             : }
    3034                 :             : 
    3035                 :             : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
    3036                 :             :    non-paradoxical.  */
    3037                 :             : 
    3038                 :             : static bool
    3039                 :    78619116 : non_paradoxical_subreg_not_p (rtx op)
    3040                 :             : {
    3041                 :    78619116 :   return GET_CODE (op) == SUBREG
    3042                 :     8688954 :          && !paradoxical_subreg_p (op)
    3043                 :    81532145 :          && GET_CODE (SUBREG_REG (op)) == NOT;
    3044                 :             : }
    3045                 :             : 
    3046                 :             : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
    3047                 :             :    (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
    3048                 :             :    opportunities to combine another binary logical operation with NOT.  */
    3049                 :             : 
    3050                 :             : static rtx
    3051                 :    39310764 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
    3052                 :             : {
    3053                 :    39310764 :   rtx opn = NULL_RTX;
    3054                 :    39310764 :   if (non_paradoxical_subreg_not_p (op0))
    3055                 :             :     opn = op0;
    3056                 :    39308352 :   else if (non_paradoxical_subreg_not_p (op1))
    3057                 :             :     opn = op1;
    3058                 :             : 
    3059                 :        2415 :   if (opn == NULL_RTX)
    3060                 :             :     return NULL_RTX;
    3061                 :             : 
    3062                 :        4830 :   rtx new_subreg = simplify_gen_subreg (mode,
    3063                 :             :                                         XEXP (SUBREG_REG (opn), 0),
    3064                 :        2415 :                                         GET_MODE (SUBREG_REG (opn)),
    3065                 :        2415 :                                         SUBREG_BYTE (opn));
    3066                 :             : 
    3067                 :        2415 :   if (!new_subreg)
    3068                 :             :     return NULL_RTX;
    3069                 :             : 
    3070                 :        2385 :   rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
    3071                 :        2385 :   if (opn == op0)
    3072                 :        2382 :     return simplify_gen_binary (binop, mode, new_not, op1);
    3073                 :             :   else
    3074                 :           3 :     return simplify_gen_binary (binop, mode, op0, new_not);
    3075                 :             : }
    3076                 :             : 
    3077                 :             : /* Subroutine of simplify_binary_operation.  Simplify a binary operation
    3078                 :             :    CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
    3079                 :             :    OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
    3080                 :             :    actual constants.  */
    3081                 :             : 
    3082                 :             : rtx
    3083                 :   442613280 : simplify_context::simplify_binary_operation_1 (rtx_code code,
    3084                 :             :                                                machine_mode mode,
    3085                 :             :                                                rtx op0, rtx op1,
    3086                 :             :                                                rtx trueop0, rtx trueop1)
    3087                 :             : {
    3088                 :   442613280 :   rtx tem, reversed, elt0, elt1;
    3089                 :   442613280 :   HOST_WIDE_INT val;
    3090                 :   442613280 :   scalar_int_mode int_mode, inner_mode;
    3091                 :   442613280 :   poly_int64 offset;
    3092                 :             : 
    3093                 :             :   /* Even if we can't compute a constant result,
    3094                 :             :      there are some cases worth simplifying.  */
    3095                 :             : 
    3096                 :   442613280 :   switch (code)
    3097                 :             :     {
    3098                 :   251501527 :     case PLUS:
    3099                 :             :       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
    3100                 :             :          when x is NaN, infinite, or finite and nonzero.  They aren't
    3101                 :             :          when x is -0 and the rounding mode is not towards -infinity,
    3102                 :             :          since (-0) + 0 is then 0.  */
    3103                 :   499093223 :       if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
    3104                 :   499093211 :           && trueop1 == CONST0_RTX (mode))
    3105                 :             :         return op0;
    3106                 :             : 
    3107                 :             :       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
    3108                 :             :          transformations are safe even for IEEE.  */
    3109                 :   250201554 :       if (GET_CODE (op0) == NEG)
    3110                 :       28589 :         return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
    3111                 :   250172965 :       else if (GET_CODE (op1) == NEG)
    3112                 :        7527 :         return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
    3113                 :             : 
    3114                 :             :       /* (~a) + 1 -> -a */
    3115                 :   250165438 :       if (INTEGRAL_MODE_P (mode)
    3116                 :   245404365 :           && GET_CODE (op0) == NOT
    3117                 :      616460 :           && trueop1 == const1_rtx)
    3118                 :        3481 :         return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
    3119                 :             : 
    3120                 :             :       /* Handle both-operands-constant cases.  We can only add
    3121                 :             :          CONST_INTs to constants since the sum of relocatable symbols
    3122                 :             :          can't be handled by most assemblers.  Don't add CONST_INT
    3123                 :             :          to CONST_INT since overflow won't be computed properly if wider
    3124                 :             :          than HOST_BITS_PER_WIDE_INT.  */
    3125                 :             : 
    3126                 :   250161957 :       if ((GET_CODE (op0) == CONST
    3127                 :   250161957 :            || GET_CODE (op0) == SYMBOL_REF
    3128                 :   247708519 :            || GET_CODE (op0) == LABEL_REF)
    3129                 :   250161957 :           && poly_int_rtx_p (op1, &offset))
    3130                 :     2452464 :         return plus_constant (mode, op0, offset);
    3131                 :   247709493 :       else if ((GET_CODE (op1) == CONST
    3132                 :   247709493 :                 || GET_CODE (op1) == SYMBOL_REF
    3133                 :   244049784 :                 || GET_CODE (op1) == LABEL_REF)
    3134                 :   247709493 :                && poly_int_rtx_p (op0, &offset))
    3135                 :           0 :         return plus_constant (mode, op1, offset);
    3136                 :             : 
    3137                 :             :       /* See if this is something like X * C - X or vice versa or
    3138                 :             :          if the multiplication is written as a shift.  If so, we can
    3139                 :             :          distribute and make a new multiply, shift, or maybe just
    3140                 :             :          have X (if C is 2 in the example above).  But don't make
    3141                 :             :          something more expensive than we had before.  */
    3142                 :             : 
    3143                 :   247709493 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3144                 :             :         {
    3145                 :   240945456 :           rtx lhs = op0, rhs = op1;
    3146                 :             : 
    3147                 :   240945456 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3148                 :   240945456 :           wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3149                 :             : 
    3150                 :   240945456 :           if (GET_CODE (lhs) == NEG)
    3151                 :             :             {
    3152                 :           0 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3153                 :           0 :               lhs = XEXP (lhs, 0);
    3154                 :             :             }
    3155                 :   240945456 :           else if (GET_CODE (lhs) == MULT
    3156                 :     6638327 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3157                 :             :             {
    3158                 :     5546260 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3159                 :     5546260 :               lhs = XEXP (lhs, 0);
    3160                 :             :             }
    3161                 :   235399196 :           else if (GET_CODE (lhs) == ASHIFT
    3162                 :    10612092 :                    && CONST_INT_P (XEXP (lhs, 1))
    3163                 :    10540721 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3164                 :   245939905 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3165                 :             :             {
    3166                 :    10540709 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3167                 :    21081418 :                                             GET_MODE_PRECISION (int_mode));
    3168                 :    10540709 :               lhs = XEXP (lhs, 0);
    3169                 :             :             }
    3170                 :             : 
    3171                 :   240945456 :           if (GET_CODE (rhs) == NEG)
    3172                 :             :             {
    3173                 :           0 :               coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3174                 :           0 :               rhs = XEXP (rhs, 0);
    3175                 :             :             }
    3176                 :   240945456 :           else if (GET_CODE (rhs) == MULT
    3177                 :      274721 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3178                 :             :             {
    3179                 :      174572 :               coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
    3180                 :      174572 :               rhs = XEXP (rhs, 0);
    3181                 :             :             }
    3182                 :   240770884 :           else if (GET_CODE (rhs) == ASHIFT
    3183                 :      503072 :                    && CONST_INT_P (XEXP (rhs, 1))
    3184                 :      493300 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3185                 :   241264184 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3186                 :             :             {
    3187                 :      493300 :               coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3188                 :      986600 :                                             GET_MODE_PRECISION (int_mode));
    3189                 :      493300 :               rhs = XEXP (rhs, 0);
    3190                 :             :             }
    3191                 :             : 
    3192                 :   240945456 :           if (rtx_equal_p (lhs, rhs))
    3193                 :             :             {
    3194                 :      730005 :               rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
    3195                 :      730005 :               rtx coeff;
    3196                 :      730005 :               bool speed = optimize_function_for_speed_p (cfun);
    3197                 :             : 
    3198                 :      730005 :               coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
    3199                 :             : 
    3200                 :      730005 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3201                 :      730005 :               return (set_src_cost (tem, int_mode, speed)
    3202                 :      730005 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3203                 :             :             }
    3204                 :             : 
    3205                 :             :           /* Optimize (X - 1) * Y + Y to X * Y.  */
    3206                 :   240215451 :           lhs = op0;
    3207                 :   240215451 :           rhs = op1;
    3208                 :   240215451 :           if (GET_CODE (op0) == MULT)
    3209                 :             :             {
    3210                 :     6616516 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3211                 :      277638 :                     && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
    3212                 :     6575098 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3213                 :       34169 :                        && XEXP (XEXP (op0, 0), 1) == const1_rtx))
    3214                 :     6657934 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3215                 :         111 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3216                 :     6616405 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3217                 :        1626 :                          && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
    3218                 :     6616370 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3219                 :         267 :                             && XEXP (XEXP (op0, 1), 1) == const1_rtx))
    3220                 :     6616440 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3221                 :           0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3222                 :             :             }
    3223                 :   233598935 :           else if (GET_CODE (op1) == MULT)
    3224                 :             :             {
    3225                 :      127354 :               if (((GET_CODE (XEXP (op1, 0)) == PLUS
    3226                 :          84 :                     && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
    3227                 :      127352 :                    || (GET_CODE (XEXP (op1, 0)) == MINUS
    3228                 :          27 :                        && XEXP (XEXP (op1, 0), 1) == const1_rtx))
    3229                 :      127356 :                   && rtx_equal_p (XEXP (op1, 1), op0))
    3230                 :           0 :                 rhs = XEXP (XEXP (op1, 0), 0);
    3231                 :      127354 :               else if (((GET_CODE (XEXP (op1, 1)) == PLUS
    3232                 :          45 :                          && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
    3233                 :      127354 :                         || (GET_CODE (XEXP (op1, 1)) == MINUS
    3234                 :           0 :                             && XEXP (XEXP (op1, 1), 1) == const1_rtx))
    3235                 :      127354 :                        && rtx_equal_p (XEXP (op1, 0), op0))
    3236                 :           0 :                 rhs = XEXP (XEXP (op1, 1), 0);
    3237                 :             :             }
    3238                 :   240215451 :           if (lhs != op0 || rhs != op1)
    3239                 :         111 :             return simplify_gen_binary (MULT, int_mode, lhs, rhs);
    3240                 :   240945456 :         }
    3241                 :             : 
    3242                 :             :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
    3243                 :   246979377 :       if (CONST_SCALAR_INT_P (op1)
    3244                 :   192038724 :           && GET_CODE (op0) == XOR
    3245                 :       23371 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3246                 :   246994275 :           && mode_signbit_p (mode, op1))
    3247                 :         121 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3248                 :             :                                     simplify_gen_binary (XOR, mode, op1,
    3249                 :         121 :                                                          XEXP (op0, 1)));
    3250                 :             : 
    3251                 :             :       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
    3252                 :             :          2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
    3253                 :   246979256 :       if (CONST_SCALAR_INT_P (op1)
    3254                 :   192038603 :           && GET_CODE (op0) == XOR
    3255                 :       23250 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3256                 :       14777 :           && nonzero_bits (XEXP (op0, 0), mode) == 1
    3257                 :         193 :           && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
    3258                 :   246979259 :           && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
    3259                 :           3 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3260                 :             :                                     simplify_gen_binary (XOR, mode, op1,
    3261                 :           3 :                                                          XEXP (op0, 1)));
    3262                 :             : 
    3263                 :             :       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
    3264                 :   246979253 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3265                 :   246976775 :           && GET_CODE (op0) == MULT
    3266                 :   253956402 :           && GET_CODE (XEXP (op0, 0)) == NEG)
    3267                 :             :         {
    3268                 :        5504 :           rtx in1, in2;
    3269                 :             : 
    3270                 :        5504 :           in1 = XEXP (XEXP (op0, 0), 0);
    3271                 :        5504 :           in2 = XEXP (op0, 1);
    3272                 :        5504 :           return simplify_gen_binary (MINUS, mode, op1,
    3273                 :             :                                       simplify_gen_binary (MULT, mode,
    3274                 :        5504 :                                                            in1, in2));
    3275                 :             :         }
    3276                 :             : 
    3277                 :             :       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
    3278                 :             :          C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
    3279                 :             :          is 1.  */
    3280                 :   246973749 :       if (COMPARISON_P (op0)
    3281                 :     1507302 :           && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
    3282                 :     1507302 :               || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
    3283                 :   247025968 :           && (reversed = reversed_comparison (op0, mode)))
    3284                 :       51903 :         return
    3285                 :       51903 :           simplify_gen_unary (NEG, mode, reversed, mode);
    3286                 :             : 
    3287                 :             :       /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3288                 :             :          mode size to (rotate A CX).  */
    3289                 :   246921846 :       if ((tem = simplify_rotate_op (op0, op1, mode)))
    3290                 :             :         return tem;
    3291                 :             : 
    3292                 :             :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3293                 :             :          simplify this by the associative law.
    3294                 :             :          Don't use the associative law for floating point.
    3295                 :             :          The inaccuracy makes it nonassociative,
    3296                 :             :          and subtle programs can break if operations are associated.  */
    3297                 :             : 
    3298                 :   246920376 :       if (INTEGRAL_MODE_P (mode)
    3299                 :   242159352 :           && (plus_minus_operand_p (op0)
    3300                 :   208805432 :               || plus_minus_operand_p (op1))
    3301                 :    34344987 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3302                 :             :         return tem;
    3303                 :             : 
    3304                 :             :       /* Reassociate floating point addition only when the user
    3305                 :             :          specifies associative math operations.  */
    3306                 :   213265613 :       if (FLOAT_MODE_P (mode)
    3307                 :     4761024 :           && flag_associative_math)
    3308                 :             :         {
    3309                 :      851171 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3310                 :      851171 :           if (tem)
    3311                 :             :             return tem;
    3312                 :             :         }
    3313                 :             : 
    3314                 :             :       /* Handle vector series.  */
    3315                 :   213251271 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3316                 :             :         {
    3317                 :     1846690 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3318                 :     1846690 :           if (tem)
    3319                 :             :             return tem;
    3320                 :             :         }
    3321                 :             :       break;
    3322                 :             : 
    3323                 :             :     case COMPARE:
    3324                 :             :       break;
    3325                 :             : 
    3326                 :    41786786 :     case MINUS:
    3327                 :             :       /* We can't assume x-x is 0 even with non-IEEE floating point,
    3328                 :             :          but since it is zero except in very strange circumstances, we
    3329                 :             :          will treat it as zero with -ffinite-math-only.  */
    3330                 :    41786786 :       if (rtx_equal_p (trueop0, trueop1)
    3331                 :      221712 :           && ! side_effects_p (op0)
    3332                 :    42007266 :           && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
    3333                 :      218098 :         return CONST0_RTX (mode);
    3334                 :             : 
    3335                 :             :       /* Change subtraction from zero into negation.  (0 - x) is the
    3336                 :             :          same as -x when x is NaN, infinite, or finite and nonzero.
    3337                 :             :          But if the mode has signed zeros, and does not round towards
    3338                 :             :          -infinity, then 0 - 0 is 0, not -0.  */
    3339                 :    41568688 :       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
    3340                 :      294006 :         return simplify_gen_unary (NEG, mode, op1, mode);
    3341                 :             : 
    3342                 :             :       /* (-1 - a) is ~a, unless the expression contains symbolic
    3343                 :             :          constants, in which case not retaining additions and
    3344                 :             :          subtractions could cause invalid assembly to be produced.  */
    3345                 :    41274682 :       if (trueop0 == CONSTM1_RTX (mode)
    3346                 :    41274682 :           && !contains_symbolic_reference_p (op1))
    3347                 :      361303 :         return simplify_gen_unary (NOT, mode, op1, mode);
    3348                 :             : 
    3349                 :             :       /* Subtracting 0 has no effect unless the mode has signalling NaNs,
    3350                 :             :          or has signed zeros and supports rounding towards -infinity.
    3351                 :             :          In such a case, 0 - 0 is -0.  */
    3352                 :    41610324 :       if (!(HONOR_SIGNED_ZEROS (mode)
    3353                 :      696945 :             && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
    3354                 :    40912201 :           && !HONOR_SNANS (mode)
    3355                 :    81825544 :           && trueop1 == CONST0_RTX (mode))
    3356                 :             :         return op0;
    3357                 :             : 
    3358                 :             :       /* See if this is something like X * C - X or vice versa or
    3359                 :             :          if the multiplication is written as a shift.  If so, we can
    3360                 :             :          distribute and make a new multiply, shift, or maybe just
    3361                 :             :          have X (if C is 2 in the example above).  But don't make
    3362                 :             :          something more expensive than we had before.  */
    3363                 :             : 
    3364                 :    39959505 :       if (is_a <scalar_int_mode> (mode, &int_mode))
    3365                 :             :         {
    3366                 :    38739783 :           rtx lhs = op0, rhs = op1;
    3367                 :             : 
    3368                 :    38739783 :           wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
    3369                 :    38739783 :           wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3370                 :             : 
    3371                 :    38739783 :           if (GET_CODE (lhs) == NEG)
    3372                 :             :             {
    3373                 :      116975 :               coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
    3374                 :      116975 :               lhs = XEXP (lhs, 0);
    3375                 :             :             }
    3376                 :    38622808 :           else if (GET_CODE (lhs) == MULT
    3377                 :      189274 :                    && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
    3378                 :             :             {
    3379                 :       79581 :               coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
    3380                 :       79581 :               lhs = XEXP (lhs, 0);
    3381                 :             :             }
    3382                 :    38543227 :           else if (GET_CODE (lhs) == ASHIFT
    3383                 :      323350 :                    && CONST_INT_P (XEXP (lhs, 1))
    3384                 :      320269 :                    && INTVAL (XEXP (lhs, 1)) >= 0
    3385                 :    38863475 :                    && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
    3386                 :             :             {
    3387                 :      320248 :               coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
    3388                 :      640496 :                                             GET_MODE_PRECISION (int_mode));
    3389                 :      320248 :               lhs = XEXP (lhs, 0);
    3390                 :             :             }
    3391                 :             : 
    3392                 :    38739783 :           if (GET_CODE (rhs) == NEG)
    3393                 :             :             {
    3394                 :        7288 :               negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
    3395                 :        7288 :               rhs = XEXP (rhs, 0);
    3396                 :             :             }
    3397                 :    38732495 :           else if (GET_CODE (rhs) == MULT
    3398                 :      166859 :                    && CONST_INT_P (XEXP (rhs, 1)))
    3399                 :             :             {
    3400                 :      133219 :               negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
    3401                 :      133219 :               rhs = XEXP (rhs, 0);
    3402                 :             :             }
    3403                 :    38599276 :           else if (GET_CODE (rhs) == ASHIFT
    3404                 :      390067 :                    && CONST_INT_P (XEXP (rhs, 1))
    3405                 :      389628 :                    && INTVAL (XEXP (rhs, 1)) >= 0
    3406                 :    38988904 :                    && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
    3407                 :             :             {
    3408                 :      389628 :               negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
    3409                 :      779256 :                                                GET_MODE_PRECISION (int_mode));
    3410                 :      389628 :               negcoeff1 = -negcoeff1;
    3411                 :      389628 :               rhs = XEXP (rhs, 0);
    3412                 :             :             }
    3413                 :             : 
    3414                 :    38739783 :           if (rtx_equal_p (lhs, rhs))
    3415                 :             :             {
    3416                 :      103978 :               rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
    3417                 :      103978 :               rtx coeff;
    3418                 :      103978 :               bool speed = optimize_function_for_speed_p (cfun);
    3419                 :             : 
    3420                 :      103978 :               coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
    3421                 :             : 
    3422                 :      103978 :               tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
    3423                 :      103978 :               return (set_src_cost (tem, int_mode, speed)
    3424                 :      103978 :                       <= set_src_cost (orig, int_mode, speed) ? tem : 0);
    3425                 :             :             }
    3426                 :             : 
    3427                 :             :           /* Optimize (X + 1) * Y - Y to X * Y.  */
    3428                 :    38635805 :           lhs = op0;
    3429                 :    38635805 :           if (GET_CODE (op0) == MULT)
    3430                 :             :             {
    3431                 :      189173 :               if (((GET_CODE (XEXP (op0, 0)) == PLUS
    3432                 :        4509 :                     && XEXP (XEXP (op0, 0), 1) == const1_rtx)
    3433                 :      187802 :                    || (GET_CODE (XEXP (op0, 0)) == MINUS
    3434                 :        2012 :                        && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
    3435                 :      190544 :                   && rtx_equal_p (XEXP (op0, 1), op1))
    3436                 :           2 :                 lhs = XEXP (XEXP (op0, 0), 0);
    3437                 :      189171 :               else if (((GET_CODE (XEXP (op0, 1)) == PLUS
    3438                 :          16 :                          && XEXP (XEXP (op0, 1), 1) == const1_rtx)
    3439                 :      189167 :                         || (GET_CODE (XEXP (op0, 1)) == MINUS
    3440                 :          46 :                             && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
    3441                 :      189175 :                        && rtx_equal_p (XEXP (op0, 0), op1))
    3442                 :           0 :                 lhs = XEXP (XEXP (op0, 1), 0);
    3443                 :             :             }
    3444                 :    38635805 :           if (lhs != op0)
    3445                 :           2 :             return simplify_gen_binary (MULT, int_mode, lhs, op1);
    3446                 :    38739783 :         }
    3447                 :             : 
    3448                 :             :       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
    3449                 :    39855525 :       if (GET_CODE (op1) == NEG)
    3450                 :        7250 :         return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
    3451                 :             : 
    3452                 :             :       /* (-x - c) may be simplified as (-c - x).  */
    3453                 :    39848275 :       if (GET_CODE (op0) == NEG
    3454                 :      121143 :           && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
    3455                 :             :         {
    3456                 :         615 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    3457                 :         615 :           if (tem)
    3458                 :         615 :             return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
    3459                 :             :         }
    3460                 :             : 
    3461                 :    39847660 :       if ((GET_CODE (op0) == CONST
    3462                 :    39847660 :            || GET_CODE (op0) == SYMBOL_REF
    3463                 :    34107684 :            || GET_CODE (op0) == LABEL_REF)
    3464                 :    39847660 :           && poly_int_rtx_p (op1, &offset))
    3465                 :       45316 :         return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
    3466                 :             : 
    3467                 :             :       /* Don't let a relocatable value get a negative coeff.  */
    3468                 :    39802344 :       if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
    3469                 :     7170000 :         return simplify_gen_binary (PLUS, mode,
    3470                 :             :                                     op0,
    3471                 :     7170000 :                                     neg_poly_int_rtx (mode, op1));
    3472                 :             : 
    3473                 :             :       /* (x - (x & y)) -> (x & ~y) */
    3474                 :    32632344 :       if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
    3475                 :             :         {
    3476                 :      309893 :           if (rtx_equal_p (op0, XEXP (op1, 0)))
    3477                 :             :             {
    3478                 :         526 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
    3479                 :         263 :                                         GET_MODE (XEXP (op1, 1)));
    3480                 :         263 :               return simplify_gen_binary (AND, mode, op0, tem);
    3481                 :             :             }
    3482                 :      309630 :           if (rtx_equal_p (op0, XEXP (op1, 1)))
    3483                 :             :             {
    3484                 :        2308 :               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
    3485                 :        1154 :                                         GET_MODE (XEXP (op1, 0)));
    3486                 :        1154 :               return simplify_gen_binary (AND, mode, op0, tem);
    3487                 :             :             }
    3488                 :             :         }
    3489                 :             : 
    3490                 :             :       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
    3491                 :             :          by reversing the comparison code if valid.  */
    3492                 :    32630927 :       if (STORE_FLAG_VALUE == 1
    3493                 :    32630927 :           && trueop0 == const1_rtx
    3494                 :     1034688 :           && COMPARISON_P (op1)
    3495                 :    32711341 :           && (reversed = reversed_comparison (op1, mode)))
    3496                 :             :         return reversed;
    3497                 :             : 
    3498                 :             :       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
    3499                 :    32550536 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3500                 :    32549157 :           && GET_CODE (op1) == MULT
    3501                 :    32816855 :           && GET_CODE (XEXP (op1, 0)) == NEG)
    3502                 :             :         {
    3503                 :         165 :           rtx in1, in2;
    3504                 :             : 
    3505                 :         165 :           in1 = XEXP (XEXP (op1, 0), 0);
    3506                 :         165 :           in2 = XEXP (op1, 1);
    3507                 :         165 :           return simplify_gen_binary (PLUS, mode,
    3508                 :             :                                       simplify_gen_binary (MULT, mode,
    3509                 :             :                                                            in1, in2),
    3510                 :         165 :                                       op0);
    3511                 :             :         }
    3512                 :             : 
    3513                 :             :       /* Canonicalize (minus (neg A) (mult B C)) to
    3514                 :             :          (minus (mult (neg B) C) A).  */
    3515                 :    32550371 :       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
    3516                 :    32548992 :           && GET_CODE (op1) == MULT
    3517                 :    32816525 :           && GET_CODE (op0) == NEG)
    3518                 :             :         {
    3519                 :         656 :           rtx in1, in2;
    3520                 :             : 
    3521                 :         656 :           in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
    3522                 :         656 :           in2 = XEXP (op1, 1);
    3523                 :         656 :           return simplify_gen_binary (MINUS, mode,
    3524                 :             :                                       simplify_gen_binary (MULT, mode,
    3525                 :             :                                                            in1, in2),
    3526                 :         656 :                                       XEXP (op0, 0));
    3527                 :             :         }
    3528                 :             : 
    3529                 :             :       /* If one of the operands is a PLUS or a MINUS, see if we can
    3530                 :             :          simplify this by the associative law.  This will, for example,
    3531                 :             :          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
    3532                 :             :          Don't use the associative law for floating point.
    3533                 :             :          The inaccuracy makes it nonassociative,
    3534                 :             :          and subtle programs can break if operations are associated.  */
    3535                 :             : 
    3536                 :    32549715 :       if (INTEGRAL_MODE_P (mode)
    3537                 :    31733349 :           && (plus_minus_operand_p (op0)
    3538                 :    29376134 :               || plus_minus_operand_p (op1))
    3539                 :     3576921 :           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
    3540                 :             :         return tem;
    3541                 :             : 
    3542                 :             :       /* Handle vector series.  */
    3543                 :    29099476 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    3544                 :             :         {
    3545                 :      383129 :           tem = simplify_binary_operation_series (code, mode, op0, op1);
    3546                 :      383129 :           if (tem)
    3547                 :             :             return tem;
    3548                 :             :         }
    3549                 :             :       break;
    3550                 :             : 
    3551                 :    12074885 :     case MULT:
    3552                 :    12074885 :       if (trueop1 == constm1_rtx)
    3553                 :       32005 :         return simplify_gen_unary (NEG, mode, op0, mode);
    3554                 :             : 
    3555                 :    12042880 :       if (GET_CODE (op0) == NEG)
    3556                 :             :         {
    3557                 :       32674 :           rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
    3558                 :             :           /* If op1 is a MULT as well and simplify_unary_operation
    3559                 :             :              just moved the NEG to the second operand, simplify_gen_binary
    3560                 :             :              below could through simplify_associative_operation move
    3561                 :             :              the NEG around again and recurse endlessly.  */
    3562                 :       32674 :           if (temp
    3563                 :        1461 :               && GET_CODE (op1) == MULT
    3564                 :           0 :               && GET_CODE (temp) == MULT
    3565                 :           0 :               && XEXP (op1, 0) == XEXP (temp, 0)
    3566                 :           0 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3567                 :           0 :               && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
    3568                 :             :             temp = NULL_RTX;
    3569                 :             :           if (temp)
    3570                 :        1461 :             return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
    3571                 :             :         }
    3572                 :    12041419 :       if (GET_CODE (op1) == NEG)
    3573                 :             :         {
    3574                 :         951 :           rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
    3575                 :             :           /* If op0 is a MULT as well and simplify_unary_operation
    3576                 :             :              just moved the NEG to the second operand, simplify_gen_binary
    3577                 :             :              below could through simplify_associative_operation move
    3578                 :             :              the NEG around again and recurse endlessly.  */
    3579                 :         951 :           if (temp
    3580                 :         384 :               && GET_CODE (op0) == MULT
    3581                 :         304 :               && GET_CODE (temp) == MULT
    3582                 :         304 :               && XEXP (op0, 0) == XEXP (temp, 0)
    3583                 :           6 :               && GET_CODE (XEXP (temp, 1)) == NEG
    3584                 :           5 :               && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
    3585                 :             :             temp = NULL_RTX;
    3586                 :             :           if (temp)
    3587                 :         379 :             return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
    3588                 :             :         }
    3589                 :             : 
    3590                 :             :       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
    3591                 :             :          x is NaN, since x * 0 is then also NaN.  Nor is it valid
    3592                 :             :          when the mode has signed zeros, since multiplying a negative
    3593                 :             :          number by 0 will give -0, not 0.  */
    3594                 :    12041040 :       if (!HONOR_NANS (mode)
    3595                 :    11088311 :           && !HONOR_SIGNED_ZEROS (mode)
    3596                 :    11088256 :           && trueop1 == CONST0_RTX (mode)
    3597                 :    12105332 :           && ! side_effects_p (op0))
    3598                 :             :         return op1;
    3599                 :             : 
    3600                 :             :       /* In IEEE floating point, x*1 is not equivalent to x for
    3601                 :             :          signalling NaNs.  */
    3602                 :    11977981 :       if (!HONOR_SNANS (mode)
    3603                 :    11977981 :           && trueop1 == CONST1_RTX (mode))
    3604                 :             :         return op0;
    3605                 :             : 
    3606                 :             :       /* Convert multiply by constant power of two into shift.  */
    3607                 :    11427187 :       if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
    3608                 :             :         {
    3609                 :     6209343 :           val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
    3610                 :     6209343 :           if (val >= 0)
    3611                 :     2899830 :             return simplify_gen_binary (ASHIFT, mode, op0,
    3612                 :     2899830 :                                         gen_int_shift_amount (mode, val));
    3613                 :             :         }
    3614                 :             : 
    3615                 :             :       /* x*2 is x+x and x*(-1) is -x */
    3616                 :     8527357 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    3617                 :      167958 :           && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
    3618                 :      167958 :           && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
    3619                 :      167674 :           && GET_MODE (op0) == mode)
    3620                 :             :         {
    3621                 :      167674 :           const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    3622                 :             : 
    3623                 :      167674 :           if (real_equal (d1, &dconst2))
    3624                 :         613 :             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
    3625                 :             : 
    3626                 :      167061 :           if (!HONOR_SNANS (mode)
    3627                 :      167061 :               && real_equal (d1, &dconstm1))
    3628                 :          24 :             return simplify_gen_unary (NEG, mode, op0, mode);
    3629                 :             :         }
    3630                 :             : 
    3631                 :             :       /* Optimize -x * -x as x * x.  */
    3632                 :     8526720 :       if (FLOAT_MODE_P (mode)
    3633                 :     1373656 :           && GET_CODE (op0) == NEG
    3634                 :        7920 :           && GET_CODE (op1) == NEG
    3635                 :           0 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3636                 :           0 :           && !side_effects_p (XEXP (op0, 0)))
    3637                 :           0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3638                 :             : 
    3639                 :             :       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
    3640                 :     8526720 :       if (SCALAR_FLOAT_MODE_P (mode)
    3641                 :     1087523 :           && GET_CODE (op0) == ABS
    3642                 :        1340 :           && GET_CODE (op1) == ABS
    3643                 :           0 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
    3644                 :     8526720 :           && !side_effects_p (XEXP (op0, 0)))
    3645                 :           0 :         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
    3646                 :             : 
    3647                 :             :       /* Reassociate multiplication, but for floating point MULTs
    3648                 :             :          only when the user specifies unsafe math optimizations.  */
    3649                 :     8526720 :       if (! FLOAT_MODE_P (mode)
    3650                 :     1373656 :           || flag_unsafe_math_optimizations)
    3651                 :             :         {
    3652                 :     7575150 :           tem = simplify_associative_operation (code, mode, op0, op1);
    3653                 :     7575150 :           if (tem)
    3654                 :             :             return tem;
    3655                 :             :         }
    3656                 :             :       break;
    3657                 :             : 
    3658                 :    16807810 :     case IOR:
    3659                 :    16807810 :       if (trueop1 == CONST0_RTX (mode))
    3660                 :             :         return op0;
    3661                 :    15918835 :       if (INTEGRAL_MODE_P (mode)
    3662                 :    15682612 :           && trueop1 == CONSTM1_RTX (mode)
    3663                 :        5071 :           && !side_effects_p (op0))
    3664                 :             :         return op1;
    3665                 :    15913764 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    3666                 :             :         return op0;
    3667                 :             :       /* A | (~A) -> -1 */
    3668                 :       73295 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    3669                 :    15893633 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    3670                 :          10 :           && ! side_effects_p (op0)
    3671                 :    15893653 :           && GET_MODE_CLASS (mode) != MODE_CC)
    3672                 :          10 :         return CONSTM1_RTX (mode);
    3673                 :             : 
    3674                 :             :       /* Convert (ior (plus (A - 1)) (neg A)) to -1.  */
    3675                 :    15893633 :       if (match_plus_neg_pattern (op0, op1, mode))
    3676                 :           0 :         return CONSTM1_RTX (mode);
    3677                 :             : 
    3678                 :             :       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
    3679                 :    15893633 :       if (CONST_INT_P (op1)
    3680                 :     4204599 :           && HWI_COMPUTABLE_MODE_P (mode)
    3681                 :     4166367 :           && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
    3682                 :    16254669 :           && !side_effects_p (op0))
    3683                 :             :         return op1;
    3684                 :             : 
    3685                 :             :       /* Canonicalize (X & C1) | C2.  */
    3686                 :    15532597 :       if (GET_CODE (op0) == AND
    3687                 :     4387909 :           && CONST_INT_P (trueop1)
    3688                 :      726707 :           && CONST_INT_P (XEXP (op0, 1)))
    3689                 :             :         {
    3690                 :      586682 :           HOST_WIDE_INT mask = GET_MODE_MASK (mode);
    3691                 :      586682 :           HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
    3692                 :      586682 :           HOST_WIDE_INT c2 = INTVAL (trueop1);
    3693                 :             : 
    3694                 :             :           /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2.  */
    3695                 :      586682 :           if ((c1 & c2) == c1
    3696                 :      586682 :               && !side_effects_p (XEXP (op0, 0)))
    3697                 :             :             return trueop1;
    3698                 :             : 
    3699                 :             :           /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
    3700                 :      586682 :           if (((c1|c2) & mask) == mask)
    3701                 :       81457 :             return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
    3702                 :             : 
    3703                 :             :           /* If (C1|C2) has a single bit clear, then adjust C1 so that
    3704                 :             :              when split it'll match a single bit clear style insn.
    3705                 :             : 
    3706                 :             :              This could have been done with a target dependent splitter, but
    3707                 :             :              then every target with single bit manipulation insns would need
    3708                 :             :              to implement such splitters.  */
    3709                 :      505225 :           if (exact_log2 (~(c1 | c2)) >= 0)
    3710                 :             :             {
    3711                 :       34138 :               rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
    3712                 :       34138 :               temp = gen_rtx_IOR (mode, temp, trueop1);
    3713                 :       34138 :               return temp;
    3714                 :             :             }
    3715                 :             :         }
    3716                 :             : 
    3717                 :             :       /* Convert (A & B) | A to A.  */
    3718                 :    15417002 :       if (GET_CODE (op0) == AND
    3719                 :     4272314 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    3720                 :     4272209 :               || rtx_equal_p (XEXP (op0, 1), op1))
    3721                 :        3643 :           && ! side_effects_p (XEXP (op0, 0))
    3722                 :    15420645 :           && ! side_effects_p (XEXP (op0, 1)))
    3723                 :             :         return op1;
    3724                 :             : 
    3725                 :             :       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    3726                 :             :          mode size to (rotate A CX).  */
    3727                 :    15413359 :       tem = simplify_rotate_op (op0, op1, mode);
    3728                 :    15413359 :       if (tem)
    3729                 :             :         return tem;
    3730                 :             : 
    3731                 :             :       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
    3732                 :             :          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
    3733                 :             :          the PLUS does not affect any of the bits in OP1: then we can do
    3734                 :             :          the IOR as a PLUS and we can associate.  This is valid if OP1
    3735                 :             :          can be safely shifted left C bits.  */
    3736                 :    15410836 :       if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
    3737                 :        6584 :           && GET_CODE (XEXP (op0, 0)) == PLUS
    3738                 :         141 :           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
    3739                 :          87 :           && CONST_INT_P (XEXP (op0, 1))
    3740                 :          87 :           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
    3741                 :             :         {
    3742                 :          87 :           int count = INTVAL (XEXP (op0, 1));
    3743                 :          87 :           HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
    3744                 :             : 
    3745                 :          87 :           if (mask >> count == INTVAL (trueop1)
    3746                 :          80 :               && trunc_int_for_mode (mask, mode) == mask
    3747                 :         154 :               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
    3748                 :           0 :             return simplify_gen_binary (ASHIFTRT, mode,
    3749                 :             :                                         plus_constant (mode, XEXP (op0, 0),
    3750                 :           0 :                                                        mask),
    3751                 :             :                                         XEXP (op0, 1));
    3752                 :             :         }
    3753                 :             : 
    3754                 :             :       /* The following happens with bitfield merging.
    3755                 :             :          (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
    3756                 :    15410836 :       if (GET_CODE (op0) == AND
    3757                 :     4268671 :           && GET_CODE (op1) == AND
    3758                 :      335809 :           && CONST_INT_P (XEXP (op0, 1))
    3759                 :      175994 :           && CONST_INT_P (XEXP (op1, 1))
    3760                 :      170347 :           && (INTVAL (XEXP (op0, 1))
    3761                 :      170347 :               == ~INTVAL (XEXP (op1, 1))))
    3762                 :             :         {
    3763                 :             :           /* The IOR may be on both sides.  */
    3764                 :       37470 :           rtx top0 = NULL_RTX, top1 = NULL_RTX;
    3765                 :       37470 :           if (GET_CODE (XEXP (op1, 0)) == IOR)
    3766                 :             :             top0 = op0, top1 = op1;
    3767                 :       37416 :           else if (GET_CODE (XEXP (op0, 0)) == IOR)
    3768                 :           3 :             top0 = op1, top1 = op0;
    3769                 :       37470 :           if (top0 && top1)
    3770                 :             :             {
    3771                 :             :               /* X may be on either side of the inner IOR.  */
    3772                 :          57 :               rtx tem = NULL_RTX;
    3773                 :          57 :               if (rtx_equal_p (XEXP (top0, 0),
    3774                 :          57 :                                XEXP (XEXP (top1, 0), 0)))
    3775                 :          43 :                 tem = XEXP (XEXP (top1, 0), 1);
    3776                 :          14 :               else if (rtx_equal_p (XEXP (top0, 0),
    3777                 :          14 :                                     XEXP (XEXP (top1, 0), 1)))
    3778                 :           5 :                 tem = XEXP (XEXP (top1, 0), 0);
    3779                 :          48 :               if (tem)
    3780                 :          48 :                 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
    3781                 :             :                                             simplify_gen_binary
    3782                 :          48 :                                               (AND, mode, tem, XEXP (top1, 1)));
    3783                 :             :             }
    3784                 :             :         }
    3785                 :             : 
    3786                 :             :       /* Convert (ior (and A C) (and B C)) into (and (ior A B) C).  */
    3787                 :    15410788 :       if (GET_CODE (op0) == GET_CODE (op1)
    3788                 :     3809986 :           && (GET_CODE (op0) == AND
    3789                 :             :               || GET_CODE (op0) == IOR
    3790                 :     3809986 :               || GET_CODE (op0) == LSHIFTRT
    3791                 :     3472382 :               || GET_CODE (op0) == ASHIFTRT
    3792                 :     3472289 :               || GET_CODE (op0) == ASHIFT
    3793                 :     3446090 :               || GET_CODE (op0) == ROTATE
    3794                 :     3446090 :               || GET_CODE (op0) == ROTATERT))
    3795                 :             :         {
    3796                 :      363896 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    3797                 :      363896 :           if (tem)
    3798                 :             :             return tem;
    3799                 :             :         }
    3800                 :             : 
    3801                 :             :       /* Convert (ior (and (not A) B) A) into A | B.  */
    3802                 :    15325961 :       if (GET_CODE (op0) == AND
    3803                 :     4183936 :           && GET_CODE (XEXP (op0, 0)) == NOT
    3804                 :    15475019 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1))
    3805                 :        3179 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    3806                 :             : 
    3807                 :    15322782 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    3808                 :    15322782 :       if (tem)
    3809                 :             :         return tem;
    3810                 :             : 
    3811                 :    15322777 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    3812                 :    15322777 :       if (tem)
    3813                 :             :         return tem;
    3814                 :             : 
    3815                 :    15322747 :       tem = simplify_associative_operation (code, mode, op0, op1);
    3816                 :    15322747 :       if (tem)
    3817                 :             :         return tem;
    3818                 :             : 
    3819                 :    15013853 :       tem = simplify_logical_relational_operation (code, mode, op0, op1);
    3820                 :    15013853 :       if (tem)
    3821                 :             :         return tem;
    3822                 :             :       break;
    3823                 :             : 
    3824                 :     1969192 :     case XOR:
    3825                 :     1969192 :       if (trueop1 == CONST0_RTX (mode))
    3826                 :             :         return op0;
    3827                 :     1892219 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    3828                 :       23868 :         return simplify_gen_unary (NOT, mode, op0, mode);
    3829                 :     1868351 :       if (rtx_equal_p (trueop0, trueop1)
    3830                 :        2633 :           && ! side_effects_p (op0)
    3831                 :     1870984 :           && GET_MODE_CLASS (mode) != MODE_CC)
    3832                 :        2633 :          return CONST0_RTX (mode);
    3833                 :             : 
    3834                 :             :       /* Canonicalize XOR of the most significant bit to PLUS.  */
    3835                 :     1865718 :       if (CONST_SCALAR_INT_P (op1)
    3836                 :     1865718 :           && mode_signbit_p (mode, op1))
    3837                 :       41902 :         return simplify_gen_binary (PLUS, mode, op0, op1);
    3838                 :             :       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
    3839                 :     1823816 :       if (CONST_SCALAR_INT_P (op1)
    3840                 :      692995 :           && GET_CODE (op0) == PLUS
    3841                 :        2445 :           && CONST_SCALAR_INT_P (XEXP (op0, 1))
    3842                 :     1825354 :           && mode_signbit_p (mode, XEXP (op0, 1)))
    3843                 :         189 :         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
    3844                 :             :                                     simplify_gen_binary (XOR, mode, op1,
    3845                 :         189 :                                                          XEXP (op0, 1)));
    3846                 :             : 
    3847                 :             :       /* If we are XORing two things that have no bits in common,
    3848                 :             :          convert them into an IOR.  This helps to detect rotation encoded
    3849                 :             :          using those methods and possibly other simplifications.  */
    3850                 :             : 
    3851                 :     1823627 :       if (HWI_COMPUTABLE_MODE_P (mode)
    3852                 :     1555800 :           && (nonzero_bits (op0, mode)
    3853                 :     1555800 :               & nonzero_bits (op1, mode)) == 0)
    3854                 :       12082 :         return (simplify_gen_binary (IOR, mode, op0, op1));
    3855                 :             : 
    3856                 :             :       /* Convert (xor (plus (A - 1)) (neg A)) to -1.  */
    3857                 :     1811545 :       if (match_plus_neg_pattern (op0, op1, mode))
    3858                 :           0 :         return CONSTM1_RTX (mode);
    3859                 :             : 
    3860                 :             :       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
    3861                 :             :          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
    3862                 :             :          (NOT y).  */
    3863                 :     1811545 :       {
    3864                 :     1811545 :         int num_negated = 0;
    3865                 :             : 
    3866                 :     1811545 :         if (GET_CODE (op0) == NOT)
    3867                 :        1053 :           num_negated++, op0 = XEXP (op0, 0);
    3868                 :     1811545 :         if (GET_CODE (op1) == NOT)
    3869                 :           0 :           num_negated++, op1 = XEXP (op1, 0);
    3870                 :             : 
    3871                 :           0 :         if (num_negated == 2)
    3872                 :           0 :           return simplify_gen_binary (XOR, mode, op0, op1);
    3873                 :     1811545 :         else if (num_negated == 1)
    3874                 :        1053 :           return simplify_gen_unary (NOT, mode,
    3875                 :             :                                      simplify_gen_binary (XOR, mode, op0, op1),
    3876                 :        1053 :                                      mode);
    3877                 :             :       }
    3878                 :             : 
    3879                 :             :       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
    3880                 :             :          correspond to a machine insn or result in further simplifications
    3881                 :             :          if B is a constant.  */
    3882                 :             : 
    3883                 :     1810492 :       if (GET_CODE (op0) == AND
    3884                 :      174967 :           && rtx_equal_p (XEXP (op0, 1), op1)
    3885                 :     1844739 :           && ! side_effects_p (op1))
    3886                 :       34247 :         return simplify_gen_binary (AND, mode,
    3887                 :             :                                     simplify_gen_unary (NOT, mode,
    3888                 :             :                                                         XEXP (op0, 0), mode),
    3889                 :       34247 :                                     op1);
    3890                 :             : 
    3891                 :     1776245 :       else if (GET_CODE (op0) == AND
    3892                 :      140720 :                && rtx_equal_p (XEXP (op0, 0), op1)
    3893                 :     1777521 :                && ! side_effects_p (op1))
    3894                 :        1276 :         return simplify_gen_binary (AND, mode,
    3895                 :             :                                     simplify_gen_unary (NOT, mode,
    3896                 :             :                                                         XEXP (op0, 1), mode),
    3897                 :        1276 :                                     op1);
    3898                 :             : 
    3899                 :             :       /* Given (xor (ior (xor A B) C) D), where B, C and D are
    3900                 :             :          constants, simplify to (xor (ior A C) (B&~C)^D), canceling
    3901                 :             :          out bits inverted twice and not set by C.  Similarly, given
    3902                 :             :          (xor (and (xor A B) C) D), simplify without inverting C in
    3903                 :             :          the xor operand: (xor (and A C) (B&C)^D).
    3904                 :             :       */
    3905                 :     1774969 :       else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
    3906                 :      160484 :                && GET_CODE (XEXP (op0, 0)) == XOR
    3907                 :        5805 :                && CONST_INT_P (op1)
    3908                 :         135 :                && CONST_INT_P (XEXP (op0, 1))
    3909                 :          90 :                && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
    3910                 :             :         {
    3911                 :          90 :           enum rtx_code op = GET_CODE (op0);
    3912                 :          90 :           rtx a = XEXP (XEXP (op0, 0), 0);
    3913                 :          90 :           rtx b = XEXP (XEXP (op0, 0), 1);
    3914                 :          90 :           rtx c = XEXP (op0, 1);
    3915                 :          90 :           rtx d = op1;
    3916                 :          90 :           HOST_WIDE_INT bval = INTVAL (b);
    3917                 :          90 :           HOST_WIDE_INT cval = INTVAL (c);
    3918                 :          90 :           HOST_WIDE_INT dval = INTVAL (d);
    3919                 :          90 :           HOST_WIDE_INT xcval;
    3920                 :             : 
    3921                 :          90 :           if (op == IOR)
    3922                 :           8 :             xcval = ~cval;
    3923                 :             :           else
    3924                 :             :             xcval = cval;
    3925                 :             : 
    3926                 :          90 :           return simplify_gen_binary (XOR, mode,
    3927                 :             :                                       simplify_gen_binary (op, mode, a, c),
    3928                 :          90 :                                       gen_int_mode ((bval & xcval) ^ dval,
    3929                 :             :                                                     mode));
    3930                 :             :         }
    3931                 :             : 
    3932                 :             :       /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
    3933                 :             :          we can transform like this:
    3934                 :             :             (A&B)^C == ~(A&B)&C | ~C&(A&B)
    3935                 :             :                     == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
    3936                 :             :                     == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
    3937                 :             :          Attempt a few simplifications when B and C are both constants.  */
    3938                 :     1774879 :       if (GET_CODE (op0) == AND
    3939                 :      139362 :           && CONST_INT_P (op1)
    3940                 :       12895 :           && CONST_INT_P (XEXP (op0, 1)))
    3941                 :             :         {
    3942                 :       11035 :           rtx a = XEXP (op0, 0);
    3943                 :       11035 :           rtx b = XEXP (op0, 1);
    3944                 :       11035 :           rtx c = op1;
    3945                 :       11035 :           HOST_WIDE_INT bval = INTVAL (b);
    3946                 :       11035 :           HOST_WIDE_INT cval = INTVAL (c);
    3947                 :             : 
    3948                 :             :           /* Instead of computing ~A&C, we compute its negated value,
    3949                 :             :              ~(A|~C).  If it yields -1, ~A&C is zero, so we can
    3950                 :             :              optimize for sure.  If it does not simplify, we still try
    3951                 :             :              to compute ~A&C below, but since that always allocates
    3952                 :             :              RTL, we don't try that before committing to returning a
    3953                 :             :              simplified expression.  */
    3954                 :       11035 :           rtx n_na_c = simplify_binary_operation (IOR, mode, a,
    3955                 :             :                                                   GEN_INT (~cval));
    3956                 :             : 
    3957                 :       11035 :           if ((~cval & bval) == 0)
    3958                 :             :             {
    3959                 :         437 :               rtx na_c = NULL_RTX;
    3960                 :         437 :               if (n_na_c)
    3961                 :           0 :                 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
    3962                 :             :               else
    3963                 :             :                 {
    3964                 :             :                   /* If ~A does not simplify, don't bother: we don't
    3965                 :             :                      want to simplify 2 operations into 3, and if na_c
    3966                 :             :                      were to simplify with na, n_na_c would have
    3967                 :             :                      simplified as well.  */
    3968                 :         437 :                   rtx na = simplify_unary_operation (NOT, mode, a, mode);
    3969                 :         437 :                   if (na)
    3970                 :           0 :                     na_c = simplify_gen_binary (AND, mode, na, c);
    3971                 :             :                 }
    3972                 :             : 
    3973                 :             :               /* Try to simplify ~A&C | ~B&C.  */
    3974                 :           0 :               if (na_c != NULL_RTX)
    3975                 :           0 :                 return simplify_gen_binary (IOR, mode, na_c,
    3976                 :           0 :                                             gen_int_mode (~bval & cval, mode));
    3977                 :             :             }
    3978                 :             :           else
    3979                 :             :             {
    3980                 :             :               /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
    3981                 :       10598 :               if (n_na_c == CONSTM1_RTX (mode))
    3982                 :             :                 {
    3983                 :           0 :                   rtx a_nc_b = simplify_gen_binary (AND, mode, a,
    3984                 :           0 :                                                     gen_int_mode (~cval & bval,
    3985                 :             :                                                                   mode));
    3986                 :           0 :                   return simplify_gen_binary (IOR, mode, a_nc_b,
    3987                 :           0 :                                               gen_int_mode (~bval & cval,
    3988                 :             :                                                             mode));
    3989                 :             :                 }
    3990                 :             :             }
    3991                 :             :         }
    3992                 :             : 
    3993                 :             :       /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
    3994                 :             :          do (ior (and A ~C) (and B C)) which is a machine instruction on some
    3995                 :             :          machines, and also has shorter instruction path length.  */
    3996                 :     1774879 :       if (GET_CODE (op0) == AND
    3997                 :      139362 :           && GET_CODE (XEXP (op0, 0)) == XOR
    3998                 :        5277 :           && CONST_INT_P (XEXP (op0, 1))
    3999                 :     1776953 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
    4000                 :             :         {
    4001                 :           7 :           rtx a = trueop1;
    4002                 :           7 :           rtx b = XEXP (XEXP (op0, 0), 1);
    4003                 :           7 :           rtx c = XEXP (op0, 1);
    4004                 :           7 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4005                 :           7 :           rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
    4006                 :           7 :           rtx bc = simplify_gen_binary (AND, mode, b, c);
    4007                 :           7 :           return simplify_gen_binary (IOR, mode, a_nc, bc);
    4008                 :             :         }
    4009                 :             :       /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C))  */
    4010                 :     1774872 :       else if (GET_CODE (op0) == AND
    4011                 :      139355 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4012                 :        5270 :           && CONST_INT_P (XEXP (op0, 1))
    4013                 :     1776939 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
    4014                 :             :         {
    4015                 :           8 :           rtx a = XEXP (XEXP (op0, 0), 0);
    4016                 :           8 :           rtx b = trueop1;
    4017                 :           8 :           rtx c = XEXP (op0, 1);
    4018                 :           8 :           rtx nc = simplify_gen_unary (NOT, mode, c, mode);
    4019                 :           8 :           rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
    4020                 :           8 :           rtx ac = simplify_gen_binary (AND, mode, a, c);
    4021                 :           8 :           return simplify_gen_binary (IOR, mode, ac, b_nc);
    4022                 :             :         }
    4023                 :             : 
    4024                 :             :       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
    4025                 :             :          comparison if STORE_FLAG_VALUE is 1.  */
    4026                 :     1774864 :       if (STORE_FLAG_VALUE == 1
    4027                 :     1774864 :           && trueop1 == const1_rtx
    4028                 :      266551 :           && COMPARISON_P (op0)
    4029                 :     1784144 :           && (reversed = reversed_comparison (op0, mode)))
    4030                 :             :         return reversed;
    4031                 :             : 
    4032                 :             :       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
    4033                 :             :          is (lt foo (const_int 0)), so we can perform the above
    4034                 :             :          simplification if STORE_FLAG_VALUE is 1.  */
    4035                 :             : 
    4036                 :     1765672 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4037                 :             :           && STORE_FLAG_VALUE == 1
    4038                 :     1502008 :           && trueop1 == const1_rtx
    4039                 :      257359 :           && GET_CODE (op0) == LSHIFTRT
    4040                 :       35494 :           && CONST_INT_P (XEXP (op0, 1))
    4041                 :       35494 :           && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    4042                 :       34588 :         return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
    4043                 :             : 
    4044                 :             :       /* (xor (comparison foo bar) (const_int sign-bit))
    4045                 :             :          when STORE_FLAG_VALUE is the sign bit.  */
    4046                 :     1731084 :       if (is_a <scalar_int_mode> (mode, &int_mode)
    4047                 :     1467420 :           && val_signbit_p (int_mode, STORE_FLAG_VALUE)
    4048                 :           0 :           && trueop1 == const_true_rtx
    4049                 :           0 :           && COMPARISON_P (op0)
    4050                 :           0 :           && (reversed = reversed_comparison (op0, int_mode)))
    4051                 :             :         return reversed;
    4052                 :             : 
    4053                 :             :       /* Convert (xor (and A C) (and B C)) into (and (xor A B) C).  */
    4054                 :     1731084 :       if (GET_CODE (op0) == GET_CODE (op1)
    4055                 :      529844 :           && (GET_CODE (op0) == AND
    4056                 :      529844 :               || GET_CODE (op0) == LSHIFTRT
    4057                 :      468311 :               || GET_CODE (op0) == ASHIFTRT
    4058                 :      468261 :               || GET_CODE (op0) == ASHIFT
    4059                 :      468101 :               || GET_CODE (op0) == ROTATE
    4060                 :      468001 :               || GET_CODE (op0) == ROTATERT))
    4061                 :             :         {
    4062                 :       62375 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4063                 :       62375 :           if (tem)
    4064                 :             :             return tem;
    4065                 :             :         }
    4066                 :             : 
    4067                 :             :       /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
    4068                 :             :          mode size to (rotate A CX).  */
    4069                 :     1673058 :       tem = simplify_rotate_op (op0, op1, mode);
    4070                 :     1673058 :       if (tem)
    4071                 :             :         return tem;
    4072                 :             : 
    4073                 :             :       /* Convert (xor (and (not A) B) A) into A | B.  */
    4074                 :     1671678 :       if (GET_CODE (op0) == AND
    4075                 :       81592 :           && GET_CODE (XEXP (op0, 0)) == NOT
    4076                 :     1676670 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1))
    4077                 :           1 :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4078                 :             : 
    4079                 :             :       /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
    4080                 :             :          into B | (1 << A).  */
    4081                 :     1671677 :       if (SHIFT_COUNT_TRUNCATED
    4082                 :             :           && GET_CODE (op0) == AND
    4083                 :             :           && GET_CODE (XEXP (op0, 0)) == ROTATE
    4084                 :             :           && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
    4085                 :             :           && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
    4086                 :             :           && GET_CODE (op1) == ASHIFT
    4087                 :             :           && CONST_INT_P (XEXP (op1, 0))
    4088                 :             :           && INTVAL (XEXP (op1, 0)) == 1
    4089                 :             :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
    4090                 :             :           && !side_effects_p (XEXP (op1, 1)))
    4091                 :             :         return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
    4092                 :             : 
    4093                 :     1671677 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4094                 :     1671677 :       if (tem)
    4095                 :             :         return tem;
    4096                 :             : 
    4097                 :     1671677 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4098                 :     1671677 :       if (tem)
    4099                 :             :         return tem;
    4100                 :             : 
    4101                 :     1671677 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4102                 :     1671677 :       if (tem)
    4103                 :             :         return tem;
    4104                 :             :       break;
    4105                 :             : 
    4106                 :    24740978 :     case AND:
    4107                 :    24740978 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    4108                 :             :         return trueop1;
    4109                 :    24514692 :       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
    4110                 :             :         return op0;
    4111                 :    24159304 :       if (HWI_COMPUTABLE_MODE_P (mode))
    4112                 :             :         {
    4113                 :             :           /* When WORD_REGISTER_OPERATIONS is true, we need to know the
    4114                 :             :              nonzero bits in WORD_MODE rather than MODE.  */
    4115                 :    21407342 :           scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
    4116                 :    21407342 :           if (WORD_REGISTER_OPERATIONS
    4117                 :             :               && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
    4118                 :             :             tmode = word_mode;
    4119                 :    21407342 :           HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
    4120                 :    21407342 :           HOST_WIDE_INT nzop1;
    4121                 :    21407342 :           if (CONST_INT_P (trueop1))
    4122                 :             :             {
    4123                 :    18305848 :               HOST_WIDE_INT val1 = INTVAL (trueop1);
    4124                 :             :               /* If we are turning off bits already known off in OP0, we need
    4125                 :             :                  not do an AND.  */
    4126                 :    18305848 :               if ((nzop0 & ~val1) == 0)
    4127                 :      413492 :                 return op0;
    4128                 :             :             }
    4129                 :    21056402 :           nzop1 = nonzero_bits (trueop1, mode);
    4130                 :             :           /* If we are clearing all the nonzero bits, the result is zero.  */
    4131                 :    21056402 :           if ((nzop1 & nzop0) == 0
    4132                 :    21056402 :               && !side_effects_p (op0) && !side_effects_p (op1))
    4133                 :       62552 :             return CONST0_RTX (mode);
    4134                 :             :         }
    4135                 :    23749321 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
    4136                 :    23749321 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4137                 :             :         return op0;
    4138                 :             :       /* A & (~A) -> 0 */
    4139                 :      660320 :       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
    4140                 :    23738350 :            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
    4141                 :        3999 :           && ! side_effects_p (op0)
    4142                 :    23746302 :           && GET_MODE_CLASS (mode) != MODE_CC)
    4143                 :        3999 :         return CONST0_RTX (mode);
    4144                 :             : 
    4145                 :             :       /* Convert (and (plus (A - 1)) (neg A)) to 0.  */
    4146                 :    23738304 :       if (match_plus_neg_pattern (op0, op1, mode))
    4147                 :           2 :         return CONST0_RTX (mode);
    4148                 :             : 
    4149                 :             :       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
    4150                 :             :          there are no nonzero bits of C outside of X's mode.  */
    4151                 :    47476604 :       if ((GET_CODE (op0) == SIGN_EXTEND
    4152                 :    23738302 :            || GET_CODE (op0) == ZERO_EXTEND)
    4153                 :       99977 :           && CONST_SCALAR_INT_P (trueop1)
    4154                 :       85977 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4155                 :       85977 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4156                 :    23824279 :           && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
    4157                 :       85977 :                         GET_MODE_PRECISION (int_mode))
    4158                 :    23824279 :               & rtx_mode_t (trueop1, mode)) == 0)
    4159                 :             :         {
    4160                 :       83455 :           machine_mode imode = GET_MODE (XEXP (op0, 0));
    4161                 :       83455 :           tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
    4162                 :       83455 :           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
    4163                 :       83455 :           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
    4164                 :             :         }
    4165                 :             : 
    4166                 :             :       /* Transform (and (truncate X) C) into (truncate (and X C)).  This way
    4167                 :             :          we might be able to further simplify the AND with X and potentially
    4168                 :             :          remove the truncation altogether.  */
    4169                 :    23654847 :       if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
    4170                 :             :         {
    4171                 :           6 :           rtx x = XEXP (op0, 0);
    4172                 :           6 :           machine_mode xmode = GET_MODE (x);
    4173                 :           6 :           tem = simplify_gen_binary (AND, xmode, x,
    4174                 :           6 :                                      gen_int_mode (INTVAL (trueop1), xmode));
    4175                 :           6 :           return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
    4176                 :             :         }
    4177                 :             : 
    4178                 :             :       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
    4179                 :    23654841 :       if (GET_CODE (op0) == IOR
    4180                 :     1526066 :           && CONST_INT_P (trueop1)
    4181                 :      233464 :           && CONST_INT_P (XEXP (op0, 1)))
    4182                 :             :         {
    4183                 :      146234 :           HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
    4184                 :      146234 :           return simplify_gen_binary (IOR, mode,
    4185                 :             :                                       simplify_gen_binary (AND, mode,
    4186                 :             :                                                            XEXP (op0, 0), op1),
    4187                 :      146234 :                                       gen_int_mode (tmp, mode));
    4188                 :             :         }
    4189                 :             : 
    4190                 :             :       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
    4191                 :             :          insn (and may simplify more).  */
    4192                 :    23508607 :       if (GET_CODE (op0) == XOR
    4193                 :      125025 :           && rtx_equal_p (XEXP (op0, 0), op1)
    4194                 :    23510005 :           && ! side_effects_p (op1))
    4195                 :        1398 :         return simplify_gen_binary (AND, mode,
    4196                 :             :                                     simplify_gen_unary (NOT, mode,
    4197                 :             :                                                         XEXP (op0, 1), mode),
    4198                 :        1398 :                                     op1);
    4199                 :             : 
    4200                 :    23507209 :       if (GET_CODE (op0) == XOR
    4201                 :      123627 :           && rtx_equal_p (XEXP (op0, 1), op1)
    4202                 :    23510494 :           && ! side_effects_p (op1))
    4203                 :        3285 :         return simplify_gen_binary (AND, mode,
    4204                 :             :                                     simplify_gen_unary (NOT, mode,
    4205                 :             :                                                         XEXP (op0, 0), mode),
    4206                 :        3285 :                                     op1);
    4207                 :             : 
    4208                 :             :       /* Similarly for (~(A ^ B)) & A.  */
    4209                 :    23503924 :       if (GET_CODE (op0) == NOT
    4210                 :      656367 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4211                 :        3303 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
    4212                 :    23503978 :           && ! side_effects_p (op1))
    4213                 :          54 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
    4214                 :             : 
    4215                 :    23503870 :       if (GET_CODE (op0) == NOT
    4216                 :      656313 :           && GET_CODE (XEXP (op0, 0)) == XOR
    4217                 :        3249 :           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
    4218                 :    23503907 :           && ! side_effects_p (op1))
    4219                 :          37 :         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
    4220                 :             : 
    4221                 :             :       /* Convert (A | B) & A to A.  */
    4222                 :    23503833 :       if (GET_CODE (op0) == IOR
    4223                 :     1379832 :           && (rtx_equal_p (XEXP (op0, 0), op1)
    4224                 :     1379284 :               || rtx_equal_p (XEXP (op0, 1), op1))
    4225                 :         723 :           && ! side_effects_p (XEXP (op0, 0))
    4226                 :    23504556 :           && ! side_effects_p (XEXP (op0, 1)))
    4227                 :             :         return op1;
    4228                 :             : 
    4229                 :             :       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
    4230                 :             :          ((A & N) + B) & M -> (A + B) & M
    4231                 :             :          Similarly if (N & M) == 0,
    4232                 :             :          ((A | N) + B) & M -> (A + B) & M
    4233                 :             :          and for - instead of + and/or ^ instead of |.
    4234                 :             :          Also, if (N & M) == 0, then
    4235                 :             :          (A +- N) & M -> A & M.  */
    4236                 :    23503110 :       if (CONST_INT_P (trueop1)
    4237                 :    17766898 :           && HWI_COMPUTABLE_MODE_P (mode)
    4238                 :    17739115 :           && ~UINTVAL (trueop1)
    4239                 :    17739115 :           && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
    4240                 :    34664242 :           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
    4241                 :             :         {
    4242                 :     1001440 :           rtx pmop[2];
    4243                 :     1001440 :           int which;
    4244                 :             : 
    4245                 :     1001440 :           pmop[0] = XEXP (op0, 0);
    4246                 :     1001440 :           pmop[1] = XEXP (op0, 1);
    4247                 :             : 
    4248                 :     1001440 :           if (CONST_INT_P (pmop[1])
    4249                 :      544147 :               && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
    4250                 :      166014 :             return simplify_gen_binary (AND, mode, pmop[0], op1);
    4251                 :             : 
    4252                 :     2530824 :           for (which = 0; which < 2; which++)
    4253                 :             :             {
    4254                 :     1687216 :               tem = pmop[which];
    4255                 :     1687216 :               switch (GET_CODE (tem))
    4256                 :             :                 {
    4257                 :       12422 :                 case AND:
    4258                 :       12422 :                   if (CONST_INT_P (XEXP (tem, 1))
    4259                 :       10936 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
    4260                 :             :                       == UINTVAL (trueop1))
    4261                 :        8043 :                     pmop[which] = XEXP (tem, 0);
    4262                 :             :                   break;
    4263                 :        1664 :                 case IOR:
    4264                 :        1664 :                 case XOR:
    4265                 :        1664 :                   if (CONST_INT_P (XEXP (tem, 1))
    4266                 :         653 :                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
    4267                 :         139 :                     pmop[which] = XEXP (tem, 0);
    4268                 :             :                   break;
    4269                 :             :                 default:
    4270                 :             :                   break;
    4271                 :             :                 }
    4272                 :             :             }
    4273                 :             : 
    4274                 :      843608 :           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
    4275                 :             :             {
    4276                 :        8182 :               tem = simplify_gen_binary (GET_CODE (op0), mode,
    4277                 :             :                                          pmop[0], pmop[1]);
    4278                 :        8182 :               return simplify_gen_binary (code, mode, tem, op1);
    4279                 :             :             }
    4280                 :             :         }
    4281                 :             : 
    4282                 :             :       /* (and X (ior (not X) Y) -> (and X Y) */
    4283                 :    23337096 :       if (GET_CODE (op1) == IOR
    4284                 :     1067290 :           && GET_CODE (XEXP (op1, 0)) == NOT
    4285                 :    23342426 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
    4286                 :           0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
    4287                 :             : 
    4288                 :             :       /* (and (ior (not X) Y) X) -> (and X Y) */
    4289                 :    23337096 :       if (GET_CODE (op0) == IOR
    4290                 :     1379109 :           && GET_CODE (XEXP (op0, 0)) == NOT
    4291                 :    23387063 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
    4292                 :           6 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
    4293                 :             : 
    4294                 :             :       /* (and X (ior Y (not X)) -> (and X Y) */
    4295                 :    23337090 :       if (GET_CODE (op1) == IOR
    4296                 :     1067290 :           && GET_CODE (XEXP (op1, 1)) == NOT
    4297                 :    23337355 :           && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
    4298                 :           0 :        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
    4299                 :             : 
    4300                 :             :       /* (and (ior Y (not X)) X) -> (and X Y) */
    4301                 :    23337090 :       if (GET_CODE (op0) == IOR
    4302                 :     1379103 :           && GET_CODE (XEXP (op0, 1)) == NOT
    4303                 :    23345320 :           && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
    4304                 :           6 :         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
    4305                 :             : 
    4306                 :             :       /* (and (ior/xor (X Y) (not Y)) -> X & ~Y */
    4307                 :    23337084 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4308                 :     1499439 :           && GET_CODE (op1) == NOT
    4309                 :    23448311 :           && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 1)))
    4310                 :          15 :         return simplify_gen_binary (AND, mode, XEXP (op0, 0),
    4311                 :             :                                     simplify_gen_unary (NOT, mode,
    4312                 :             :                                                         XEXP (op1, 0),
    4313                 :          15 :                                                         mode));
    4314                 :             :       /* (and (ior/xor (Y X) (not Y)) -> X & ~Y */
    4315                 :    23337069 :       if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
    4316                 :     1499424 :           && GET_CODE (op1) == NOT
    4317                 :    23448281 :           && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 0)))
    4318                 :           4 :         return simplify_gen_binary (AND, mode, XEXP (op0, 1),
    4319                 :             :                                     simplify_gen_unary (NOT, mode,
    4320                 :             :                                                         XEXP (op1, 0),
    4321                 :           4 :                                                         mode));
    4322                 :             : 
    4323                 :             :       /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C).  */
    4324                 :    23337065 :       if (GET_CODE (op0) == GET_CODE (op1)
    4325                 :     2224840 :           && (GET_CODE (op0) == AND
    4326                 :             :               || GET_CODE (op0) == IOR
    4327                 :     2224840 :               || GET_CODE (op0) == LSHIFTRT
    4328                 :     1158153 :               || GET_CODE (op0) == ASHIFTRT
    4329                 :     1158056 :               || GET_CODE (op0) == ASHIFT
    4330                 :     1157927 :               || GET_CODE (op0) == ROTATE
    4331                 :     1157927 :               || GET_CODE (op0) == ROTATERT))
    4332                 :             :         {
    4333                 :     1066913 :           tem = simplify_distributive_operation (code, mode, op0, op1);
    4334                 :     1066913 :           if (tem)
    4335                 :             :             return tem;
    4336                 :             :         }
    4337                 :             : 
    4338                 :             :       /* (and:v4si
    4339                 :             :            (ashiftrt:v4si A 16)
    4340                 :             :            (const_vector: 0xffff x4))
    4341                 :             :          is just (lshiftrt:v4si A 16).  */
    4342                 :    22316347 :       if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
    4343                 :        4558 :           && (CONST_INT_P (XEXP (op0, 1))
    4344                 :        1850 :               || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
    4345                 :          92 :                   && const_vec_duplicate_p (XEXP (op0, 1))
    4346                 :           0 :                   && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
    4347                 :        2708 :           && GET_CODE (op1) == CONST_VECTOR
    4348                 :    22316365 :           && const_vec_duplicate_p (op1)
    4349                 :    22316407 :           && CONST_INT_P (XVECEXP (op1, 0, 0)))
    4350                 :             :         {
    4351                 :         116 :           unsigned HOST_WIDE_INT shift_count
    4352                 :             :             = (CONST_INT_P (XEXP (op0, 1))
    4353                 :          58 :                ? UINTVAL (XEXP (op0, 1))
    4354                 :           0 :                : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
    4355                 :          58 :           unsigned HOST_WIDE_INT inner_prec
    4356                 :         116 :             = GET_MODE_PRECISION (GET_MODE_INNER (mode));
    4357                 :             : 
    4358                 :             :           /* Avoid UD shift count.  */
    4359                 :          58 :           if (shift_count < inner_prec
    4360                 :          58 :               && (UINTVAL (XVECEXP (op1, 0, 0))
    4361                 :          58 :                   == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
    4362                 :          42 :             return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
    4363                 :             :         }
    4364                 :             : 
    4365                 :    22316305 :       tem = simplify_with_subreg_not (code, mode, op0, op1);
    4366                 :    22316305 :       if (tem)
    4367                 :             :         return tem;
    4368                 :             : 
    4369                 :    22313925 :       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
    4370                 :    22313925 :       if (tem)
    4371                 :             :         return tem;
    4372                 :             : 
    4373                 :    22313452 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4374                 :    22313452 :       if (tem)
    4375                 :             :         return tem;
    4376                 :             :       break;
    4377                 :             : 
    4378                 :      946005 :     case UDIV:
    4379                 :             :       /* 0/x is 0 (or x&0 if x has side-effects).  */
    4380                 :      946005 :       if (trueop0 == CONST0_RTX (mode)
    4381                 :         340 :           && !cfun->can_throw_non_call_exceptions)
    4382                 :             :         {
    4383                 :         340 :           if (side_effects_p (op1))
    4384                 :           0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4385                 :             :           return trueop0;
    4386                 :             :         }
    4387                 :             :       /* x/1 is x.  */
    4388                 :      945665 :       if (trueop1 == CONST1_RTX (mode))
    4389                 :             :         {
    4390                 :      241574 :           tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4391                 :      241574 :           if (tem)
    4392                 :             :             return tem;
    4393                 :             :         }
    4394                 :             :       /* Convert divide by power of two into shift.  */
    4395                 :      704091 :       if (CONST_INT_P (trueop1)
    4396                 :     1041164 :           && (val = exact_log2 (UINTVAL (trueop1))) > 0)
    4397                 :      337073 :         return simplify_gen_binary (LSHIFTRT, mode, op0,
    4398                 :      337073 :                                     gen_int_shift_amount (mode, val));
    4399                 :             :       break;
    4400                 :             : 
    4401                 :     1148683 :     case DIV:
    4402                 :             :       /* Handle floating point and integers separately.  */
    4403                 :     1148683 :       if (SCALAR_FLOAT_MODE_P (mode))
    4404                 :             :         {
    4405                 :             :           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
    4406                 :             :              safe for modes with NaNs, since 0.0 / 0.0 will then be
    4407                 :             :              NaN rather than 0.0.  Nor is it safe for modes with signed
    4408                 :             :              zeros, since dividing 0 by a negative number gives -0.0  */
    4409                 :      331249 :           if (trueop0 == CONST0_RTX (mode)
    4410                 :        2900 :               && !HONOR_NANS (mode)
    4411                 :          14 :               && !HONOR_SIGNED_ZEROS (mode)
    4412                 :      331263 :               && ! side_effects_p (op1))
    4413                 :             :             return op0;
    4414                 :             :           /* x/1.0 is x.  */
    4415                 :      331235 :           if (trueop1 == CONST1_RTX (mode)
    4416                 :      331235 :               && !HONOR_SNANS (mode))
    4417                 :             :             return op0;
    4418                 :             : 
    4419                 :      331230 :           if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
    4420                 :       28372 :               && trueop1 != CONST0_RTX (mode))
    4421                 :             :             {
    4422                 :       22222 :               const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    4423                 :             : 
    4424                 :             :               /* x/-1.0 is -x.  */
    4425                 :       22222 :               if (real_equal (d1, &dconstm1)
    4426                 :       22222 :                   && !HONOR_SNANS (mode))
    4427                 :           0 :                 return simplify_gen_unary (NEG, mode, op0, mode);
    4428                 :             : 
    4429                 :             :               /* Change FP division by a constant into multiplication.
    4430                 :             :                  Only do this with -freciprocal-math.  */
    4431                 :       22222 :               if (flag_reciprocal_math
    4432                 :       22222 :                   && !real_equal (d1, &dconst0))
    4433                 :             :                 {
    4434                 :           7 :                   REAL_VALUE_TYPE d;
    4435                 :           7 :                   real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
    4436                 :           7 :                   tem = const_double_from_real_value (d, mode);
    4437                 :           7 :                   return simplify_gen_binary (MULT, mode, op0, tem);
    4438                 :             :                 }
    4439                 :             :             }
    4440                 :             :         }
    4441                 :      817434 :       else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    4442                 :             :         {
    4443                 :             :           /* 0/x is 0 (or x&0 if x has side-effects).  */
    4444                 :      796313 :           if (trueop0 == CONST0_RTX (mode)
    4445                 :         635 :               && !cfun->can_throw_non_call_exceptions)
    4446                 :             :             {
    4447                 :         558 :               if (side_effects_p (op1))
    4448                 :           8 :                 return simplify_gen_binary (AND, mode, op1, trueop0);
    4449                 :             :               return trueop0;
    4450                 :             :             }
    4451                 :             :           /* x/1 is x.  */
    4452                 :      795755 :           if (trueop1 == CONST1_RTX (mode))
    4453                 :             :             {
    4454                 :         287 :               tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4455                 :         287 :               if (tem)
    4456                 :             :                 return tem;
    4457                 :             :             }
    4458                 :             :           /* x/-1 is -x.  */
    4459                 :      795468 :           if (trueop1 == CONSTM1_RTX (mode))
    4460                 :             :             {
    4461                 :         215 :               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
    4462                 :         215 :               if (x)
    4463                 :         215 :                 return simplify_gen_unary (NEG, mode, x, mode);
    4464                 :             :             }
    4465                 :             :         }
    4466                 :             :       break;
    4467                 :             : 
    4468                 :      922959 :     case UMOD:
    4469                 :             :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4470                 :      922959 :       if (trueop0 == CONST0_RTX (mode))
    4471                 :             :         {
    4472                 :         818 :           if (side_effects_p (op1))
    4473                 :           0 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4474                 :             :           return trueop0;
    4475                 :             :         }
    4476                 :             :       /* x%1 is 0 (of x&0 if x has side-effects).  */
    4477                 :      922141 :       if (trueop1 == CONST1_RTX (mode))
    4478                 :             :         {
    4479                 :      276658 :           if (side_effects_p (op0))
    4480                 :           0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4481                 :      276658 :           return CONST0_RTX (mode);
    4482                 :             :         }
    4483                 :             :       /* Implement modulus by power of two as AND.  */
    4484                 :      645483 :       if (CONST_INT_P (trueop1)
    4485                 :      956080 :           && exact_log2 (UINTVAL (trueop1)) > 0)
    4486                 :      310597 :         return simplify_gen_binary (AND, mode, op0,
    4487                 :      310597 :                                     gen_int_mode (UINTVAL (trueop1) - 1,
    4488                 :             :                                                   mode));
    4489                 :             :       break;
    4490                 :             : 
    4491                 :      325721 :     case MOD:
    4492                 :             :       /* 0%x is 0 (or x&0 if x has side-effects).  */
    4493                 :      325721 :       if (trueop0 == CONST0_RTX (mode))
    4494                 :             :         {
    4495                 :         637 :           if (side_effects_p (op1))
    4496                 :           8 :             return simplify_gen_binary (AND, mode, op1, trueop0);
    4497                 :             :           return trueop0;
    4498                 :             :         }
    4499                 :             :       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
    4500                 :      325084 :       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
    4501                 :             :         {
    4502                 :         400 :           if (side_effects_p (op0))
    4503                 :           0 :             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
    4504                 :         400 :           return CONST0_RTX (mode);
    4505                 :             :         }
    4506                 :             :       break;
    4507                 :             : 
    4508                 :      134421 :     case ROTATERT:
    4509                 :      134421 :     case ROTATE:
    4510                 :      134421 :       if (trueop1 == CONST0_RTX (mode))
    4511                 :             :         return op0;
    4512                 :             :       /* Canonicalize rotates by constant amount.  If the condition of
    4513                 :             :          reversing direction is met, then reverse the direction. */
    4514                 :             : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
    4515                 :      134331 :       if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
    4516                 :             :         {
    4517                 :       11178 :           int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
    4518                 :       11178 :           rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
    4519                 :       11558 :           return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
    4520                 :             :                                       mode, op0, new_amount_rtx);
    4521                 :             :         }
    4522                 :             : #endif
    4523                 :             :       /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X).  Other combinations
    4524                 :             :          such as SImode with a count of 16 do not correspond to RTL BSWAP
    4525                 :             :          semantics.  */
    4526                 :      123153 :       tem = unwrap_const_vec_duplicate (trueop1);
    4527                 :      123153 :       if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
    4528                 :      123153 :           && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
    4529                 :         435 :         return simplify_gen_unary (BSWAP, mode, op0, mode);
    4530                 :             : 
    4531                 :             :       /* FALLTHRU */
    4532                 :     5043571 :     case ASHIFTRT:
    4533                 :     5043571 :       if (trueop1 == CONST0_RTX (mode))
    4534                 :             :         return op0;
    4535                 :     5041788 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4536                 :             :         return op0;
    4537                 :             :       /* Rotating ~0 always results in ~0.  */
    4538                 :     5041631 :       if (CONST_INT_P (trueop0)
    4539                 :       15117 :           && HWI_COMPUTABLE_MODE_P (mode)
    4540                 :       15069 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4541                 :     5041631 :           && ! side_effects_p (op1))
    4542                 :             :         return op0;
    4543                 :             : 
    4544                 :    30794998 :     canonicalize_shift:
    4545                 :             :       /* Given:
    4546                 :             :          scalar modes M1, M2
    4547                 :             :          scalar constants c1, c2
    4548                 :             :          size (M2) > size (M1)
    4549                 :             :          c1 == size (M2) - size (M1)
    4550                 :             :          optimize:
    4551                 :             :          ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
    4552                 :             :                                  <low_part>)
    4553                 :             :                       (const_int <c2>))
    4554                 :             :          to:
    4555                 :             :          (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
    4556                 :             :                     <low_part>).  */
    4557                 :    30794998 :       if ((code == ASHIFTRT || code == LSHIFTRT)
    4558                 :    11619907 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4559                 :    10872886 :           && SUBREG_P (op0)
    4560                 :      954967 :           && CONST_INT_P (op1)
    4561                 :      953963 :           && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
    4562                 :       23265 :           && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
    4563                 :             :                                      &inner_mode)
    4564                 :       23265 :           && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
    4565                 :       46224 :           && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
    4566                 :       23112 :           && (INTVAL (XEXP (SUBREG_REG (op0), 1))
    4567                 :       46224 :               == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
    4568                 :    30817854 :           && subreg_lowpart_p (op0))
    4569                 :             :         {
    4570                 :       22856 :           rtx tmp = gen_int_shift_amount
    4571                 :       22856 :             (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
    4572                 :             : 
    4573                 :             :          /* Combine would usually zero out the value when combining two
    4574                 :             :             local shifts and the range becomes larger or equal to the mode.
    4575                 :             :             However since we fold away one of the shifts here combine won't
    4576                 :             :             see it so we should immediately zero the result if it's out of
    4577                 :             :             range.  */
    4578                 :       22856 :          if (code == LSHIFTRT
    4579                 :       42194 :              && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
    4580                 :           0 :           tmp = const0_rtx;
    4581                 :             :          else
    4582                 :       22856 :            tmp = simplify_gen_binary (code,
    4583                 :             :                                       inner_mode,
    4584                 :       22856 :                                       XEXP (SUBREG_REG (op0), 0),
    4585                 :             :                                       tmp);
    4586                 :             : 
    4587                 :       22856 :           return lowpart_subreg (int_mode, tmp, inner_mode);
    4588                 :             :         }
    4589                 :             : 
    4590                 :    30772142 :       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
    4591                 :             :         {
    4592                 :             :           val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
    4593                 :             :           if (val != INTVAL (op1))
    4594                 :             :             return simplify_gen_binary (code, mode, op0,
    4595                 :             :                                         gen_int_shift_amount (mode, val));
    4596                 :             :         }
    4597                 :             : 
    4598                 :             :       /* Simplify:
    4599                 :             : 
    4600                 :             :            (code:M1
    4601                 :             :              (subreg:M1
    4602                 :             :                ([al]shiftrt:M2
    4603                 :             :                  (subreg:M2
    4604                 :             :                    (ashift:M1 X C1))
    4605                 :             :                  C2))
    4606                 :             :              C3)
    4607                 :             : 
    4608                 :             :          to:
    4609                 :             : 
    4610                 :             :            (code:M1
    4611                 :             :              ([al]shiftrt:M1
    4612                 :             :                (ashift:M1 X C1+N)
    4613                 :             :                C2+N)
    4614                 :             :              C3)
    4615                 :             : 
    4616                 :             :          where M1 is N bits wider than M2.  Optimizing the (subreg:M1 ...)
    4617                 :             :          directly would be arithmetically correct, but restricting the
    4618                 :             :          simplification to shifts by constants is more conservative,
    4619                 :             :          since it is more likely to lead to further simplifications.  */
    4620                 :    30772142 :       if (is_a<scalar_int_mode> (mode, &int_mode)
    4621                 :     5297859 :           && paradoxical_subreg_p (op0)
    4622                 :     4874159 :           && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
    4623                 :     4874073 :           && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
    4624                 :     4874073 :               || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
    4625                 :      134414 :           && CONST_INT_P (op1))
    4626                 :             :         {
    4627                 :      134414 :           auto xcode = GET_CODE (SUBREG_REG (op0));
    4628                 :      134414 :           rtx xop0 = XEXP (SUBREG_REG (op0), 0);
    4629                 :      134414 :           rtx xop1 = XEXP (SUBREG_REG (op0), 1);
    4630                 :      134414 :           if (SUBREG_P (xop0)
    4631                 :        7016 :               && GET_MODE (SUBREG_REG (xop0)) == mode
    4632                 :        6988 :               && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
    4633                 :         605 :               && CONST_INT_P (xop1)
    4634                 :      135019 :               && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
    4635                 :             :             {
    4636                 :         605 :               rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
    4637                 :         605 :               rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
    4638                 :         605 :               if (CONST_INT_P (yop1)
    4639                 :         605 :                   && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
    4640                 :             :                 {
    4641                 :        1210 :                   auto bias = (GET_MODE_BITSIZE (int_mode)
    4642                 :         605 :                                - GET_MODE_BITSIZE (inner_mode));
    4643                 :         605 :                   tem = simplify_gen_binary (ASHIFT, mode, yop0,
    4644                 :         605 :                                              GEN_INT (INTVAL (yop1) + bias));
    4645                 :         605 :                   tem = simplify_gen_binary (xcode, mode, tem,
    4646                 :         605 :                                              GEN_INT (INTVAL (xop1) + bias));
    4647                 :         605 :                   return simplify_gen_binary (code, mode, tem, op1);
    4648                 :             :                 }
    4649                 :             :             }
    4650                 :             :         }
    4651                 :             :       break;
    4652                 :             : 
    4653                 :           0 :     case SS_ASHIFT:
    4654                 :           0 :       if (CONST_INT_P (trueop0)
    4655                 :           0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4656                 :           0 :           && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
    4657                 :           0 :               || mode_signbit_p (mode, trueop0))
    4658                 :           0 :           && ! side_effects_p (op1))
    4659                 :             :         return op0;
    4660                 :           0 :       goto simplify_ashift;
    4661                 :             : 
    4662                 :           0 :     case US_ASHIFT:
    4663                 :           0 :       if (CONST_INT_P (trueop0)
    4664                 :           0 :           && HWI_COMPUTABLE_MODE_P (mode)
    4665                 :           0 :           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
    4666                 :           0 :           && ! side_effects_p (op1))
    4667                 :             :         return op0;
    4668                 :             :       /* FALLTHRU */
    4669                 :             : 
    4670                 :    19488288 :     case ASHIFT:
    4671                 :    19488288 : simplify_ashift:
    4672                 :    19488288 :       if (trueop1 == CONST0_RTX (mode))
    4673                 :             :         return op0;
    4674                 :    19321202 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4675                 :             :         return op0;
    4676                 :    19295009 :       if (mem_depth
    4677                 :      242621 :           && code == ASHIFT
    4678                 :      242621 :           && CONST_INT_P (trueop1)
    4679                 :      242613 :           && is_a <scalar_int_mode> (mode, &int_mode)
    4680                 :    19537610 :           && IN_RANGE (UINTVAL (trueop1),
    4681                 :             :                        1, GET_MODE_PRECISION (int_mode) - 1))
    4682                 :             :         {
    4683                 :      242601 :           auto c = (wi::one (GET_MODE_PRECISION (int_mode))
    4684                 :      242601 :                     << UINTVAL (trueop1));
    4685                 :      242601 :           rtx new_op1 = immed_wide_int_const (c, int_mode);
    4686                 :      242601 :           return simplify_gen_binary (MULT, int_mode, op0, new_op1);
    4687                 :      242601 :         }
    4688                 :    19052408 :       goto canonicalize_shift;
    4689                 :             : 
    4690                 :     8500017 :     case LSHIFTRT:
    4691                 :     8500017 :       if (trueop1 == CONST0_RTX (mode))
    4692                 :             :         return op0;
    4693                 :     6702335 :       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
    4694                 :             :         return op0;
    4695                 :             :       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
    4696                 :     6700959 :       if (GET_CODE (op0) == CLZ
    4697                 :           0 :           && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
    4698                 :           0 :           && CONST_INT_P (trueop1)
    4699                 :             :           && STORE_FLAG_VALUE == 1
    4700                 :     6700959 :           && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
    4701                 :             :         {
    4702                 :           0 :           unsigned HOST_WIDE_INT zero_val = 0;
    4703                 :             : 
    4704                 :           0 :           if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
    4705                 :           0 :               && zero_val == GET_MODE_PRECISION (inner_mode)
    4706                 :           0 :               && INTVAL (trueop1) == exact_log2 (zero_val))
    4707                 :           0 :             return simplify_gen_relational (EQ, mode, inner_mode,
    4708                 :           0 :                                             XEXP (op0, 0), const0_rtx);
    4709                 :             :         }
    4710                 :     6700959 :       goto canonicalize_shift;
    4711                 :             : 
    4712                 :      198949 :     case SMIN:
    4713                 :      198949 :       if (HWI_COMPUTABLE_MODE_P (mode)
    4714                 :      178995 :           && mode_signbit_p (mode, trueop1)
    4715                 :           0 :           && ! side_effects_p (op0))
    4716                 :             :         return op1;
    4717                 :      198949 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    4718                 :             :         return op0;
    4719                 :      198812 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4720                 :      198812 :       if (tem)
    4721                 :             :         return tem;
    4722                 :             :       break;
    4723                 :             : 
    4724                 :      452961 :     case SMAX:
    4725                 :      452961 :       if (HWI_COMPUTABLE_MODE_P (mode)
    4726                 :      426397 :           && CONST_INT_P (trueop1)
    4727                 :      398690 :           && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
    4728                 :           0 :           && ! side_effects_p (op0))
    4729                 :             :         return op1;
    4730                 :      452961 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    4731                 :             :         return op0;
    4732                 :      452856 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4733                 :      452856 :       if (tem)
    4734                 :             :         return tem;
    4735                 :             :       break;
    4736                 :             : 
    4737                 :      238367 :     case UMIN:
    4738                 :      238367 :       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
    4739                 :             :         return op1;
    4740                 :      238346 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    4741                 :             :         return op0;
    4742                 :      238245 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4743                 :      238245 :       if (tem)
    4744                 :             :         return tem;
    4745                 :             :       break;
    4746                 :             : 
    4747                 :      226900 :     case UMAX:
    4748                 :      226900 :       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
    4749                 :             :         return op1;
    4750                 :      226900 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    4751                 :             :         return op0;
    4752                 :      226810 :       tem = simplify_associative_operation (code, mode, op0, op1);
    4753                 :      226810 :       if (tem)
    4754                 :             :         return tem;
    4755                 :             :       break;
    4756                 :             : 
    4757                 :       11167 :     case SS_PLUS:
    4758                 :       11167 :     case US_PLUS:
    4759                 :       11167 :     case SS_MINUS:
    4760                 :       11167 :     case US_MINUS:
    4761                 :             :       /* Simplify x +/- 0 to x, if possible.  */
    4762                 :       11167 :       if (trueop1 == CONST0_RTX (mode))
    4763                 :             :         return op0;
    4764                 :             :       return 0;
    4765                 :             : 
    4766                 :           0 :     case SS_MULT:
    4767                 :           0 :     case US_MULT:
    4768                 :             :       /* Simplify x * 0 to 0, if possible.  */
    4769                 :           0 :       if (trueop1 == CONST0_RTX (mode)
    4770                 :           0 :           && !side_effects_p (op0))
    4771                 :             :         return op1;
    4772                 :             : 
    4773                 :             :       /* Simplify x * 1 to x, if possible.  */
    4774                 :           0 :       if (trueop1 == CONST1_RTX (mode))
    4775                 :             :         return op0;
    4776                 :             :       return 0;
    4777                 :             : 
    4778                 :      524636 :     case SMUL_HIGHPART:
    4779                 :      524636 :     case UMUL_HIGHPART:
    4780                 :             :       /* Simplify x * 0 to 0, if possible.  */
    4781                 :      524636 :       if (trueop1 == CONST0_RTX (mode)
    4782                 :      524636 :           && !side_effects_p (op0))
    4783                 :             :         return op1;
    4784                 :             :       return 0;
    4785                 :             : 
    4786                 :           0 :     case SS_DIV:
    4787                 :           0 :     case US_DIV:
    4788                 :             :       /* Simplify x / 1 to x, if possible.  */
    4789                 :           0 :       if (trueop1 == CONST1_RTX (mode))
    4790                 :             :         return op0;
    4791                 :             :       return 0;
    4792                 :             : 
    4793                 :           0 :     case COPYSIGN:
    4794                 :           0 :       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
    4795                 :             :         return op0;
    4796                 :           0 :       if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
    4797                 :             :         {
    4798                 :           0 :           REAL_VALUE_TYPE f1;
    4799                 :           0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
    4800                 :           0 :           rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
    4801                 :           0 :           if (REAL_VALUE_NEGATIVE (f1))
    4802                 :           0 :             tmp = simplify_unary_operation (NEG, mode, tmp, mode);
    4803                 :           0 :           return tmp;
    4804                 :             :         }
    4805                 :           0 :       if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
    4806                 :           0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    4807                 :           0 :       if (GET_CODE (op1) == ABS
    4808                 :           0 :           && ! side_effects_p (op1))
    4809                 :           0 :         return simplify_gen_unary (ABS, mode, op0, mode);
    4810                 :           0 :       if (GET_CODE (op0) == COPYSIGN
    4811                 :           0 :           && ! side_effects_p (XEXP (op0, 1)))
    4812                 :           0 :         return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
    4813                 :           0 :       if (GET_CODE (op1) == COPYSIGN
    4814                 :           0 :           && ! side_effects_p (XEXP (op1, 0)))
    4815                 :           0 :         return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
    4816                 :             :       return 0;
    4817                 :             : 
    4818                 :        1297 :     case VEC_SERIES:
    4819                 :        2594 :       if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
    4820                 :          92 :         return gen_vec_duplicate (mode, op0);
    4821                 :        1205 :       if (valid_for_const_vector_p (mode, op0)
    4822                 :        1205 :           && valid_for_const_vector_p (mode, op1))
    4823                 :          93 :         return gen_const_vec_series (mode, op0, op1);
    4824                 :             :       return 0;
    4825                 :             : 
    4826                 :     3306972 :     case VEC_SELECT:
    4827                 :     3306972 :       if (!VECTOR_MODE_P (mode))
    4828                 :             :         {
    4829                 :      876562 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    4830                 :     1753124 :           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
    4831                 :      876562 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    4832                 :      876562 :           gcc_assert (XVECLEN (trueop1, 0) == 1);
    4833                 :             : 
    4834                 :             :           /* We can't reason about selections made at runtime.  */
    4835                 :      876562 :           if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    4836                 :   442613280 :             return 0;
    4837                 :             : 
    4838                 :      876562 :           if (vec_duplicate_p (trueop0, &elt0))
    4839                 :        1733 :             return elt0;
    4840                 :             : 
    4841                 :      874829 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    4842                 :        7093 :             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
    4843                 :             :                                                       (trueop1, 0, 0)));
    4844                 :             : 
    4845                 :             :           /* Extract a scalar element from a nested VEC_SELECT expression
    4846                 :             :              (with optional nested VEC_CONCAT expression).  Some targets
    4847                 :             :              (i386) extract scalar element from a vector using chain of
    4848                 :             :              nested VEC_SELECT expressions.  When input operand is a memory
    4849                 :             :              operand, this operation can be simplified to a simple scalar
    4850                 :             :              load from an offseted memory address.  */
    4851                 :      867736 :           int n_elts;
    4852                 :      867736 :           if (GET_CODE (trueop0) == VEC_SELECT
    4853                 :      935649 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    4854                 :       67913 :                   .is_constant (&n_elts)))
    4855                 :             :             {
    4856                 :       67913 :               rtx op0 = XEXP (trueop0, 0);
    4857                 :       67913 :               rtx op1 = XEXP (trueop0, 1);
    4858                 :             : 
    4859                 :       67913 :               int i = INTVAL (XVECEXP (trueop1, 0, 0));
    4860                 :       67913 :               int elem;
    4861                 :             : 
    4862                 :       67913 :               rtvec vec;
    4863                 :       67913 :               rtx tmp_op, tmp;
    4864                 :             : 
    4865                 :       67913 :               gcc_assert (GET_CODE (op1) == PARALLEL);
    4866                 :       67913 :               gcc_assert (i < n_elts);
    4867                 :             : 
    4868                 :             :               /* Select element, pointed by nested selector.  */
    4869                 :       67913 :               elem = INTVAL (XVECEXP (op1, 0, i));
    4870                 :             : 
    4871                 :             :               /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
    4872                 :       67913 :               if (GET_CODE (op0) == VEC_CONCAT)
    4873                 :             :                 {
    4874                 :       27276 :                   rtx op00 = XEXP (op0, 0);
    4875                 :       27276 :                   rtx op01 = XEXP (op0, 1);
    4876                 :             : 
    4877                 :       27276 :                   machine_mode mode00, mode01;
    4878                 :       27276 :                   int n_elts00, n_elts01;
    4879                 :             : 
    4880                 :       27276 :                   mode00 = GET_MODE (op00);
    4881                 :       27276 :                   mode01 = GET_MODE (op01);
    4882                 :             : 
    4883                 :             :                   /* Find out the number of elements of each operand.
    4884                 :             :                      Since the concatenated result has a constant number
    4885                 :             :                      of elements, the operands must too.  */
    4886                 :       27276 :                   n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
    4887                 :       27276 :                   n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
    4888                 :             : 
    4889                 :       27276 :                   gcc_assert (n_elts == n_elts00 + n_elts01);
    4890                 :             : 
    4891                 :             :                   /* Select correct operand of VEC_CONCAT
    4892                 :             :                      and adjust selector. */
    4893                 :       27276 :                   if (elem < n_elts01)
    4894                 :             :                     tmp_op = op00;
    4895                 :             :                   else
    4896                 :             :                     {
    4897                 :          42 :                       tmp_op = op01;
    4898                 :          42 :                       elem -= n_elts00;
    4899                 :             :                     }
    4900                 :             :                 }
    4901                 :             :               else
    4902                 :             :                 tmp_op = op0;
    4903                 :             : 
    4904                 :       67913 :               vec = rtvec_alloc (1);
    4905                 :       67913 :               RTVEC_ELT (vec, 0) = GEN_INT (elem);
    4906                 :             : 
    4907                 :       67913 :               tmp = gen_rtx_fmt_ee (code, mode,
    4908                 :             :                                     tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
    4909                 :       67913 :               return tmp;
    4910                 :             :             }
    4911                 :             :         }
    4912                 :             :       else
    4913                 :             :         {
    4914                 :     2430410 :           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
    4915                 :     7291230 :           gcc_assert (GET_MODE_INNER (mode)
    4916                 :             :                       == GET_MODE_INNER (GET_MODE (trueop0)));
    4917                 :     2430410 :           gcc_assert (GET_CODE (trueop1) == PARALLEL);
    4918                 :             : 
    4919                 :     2430410 :           if (vec_duplicate_p (trueop0, &elt0))
    4920                 :             :             /* It doesn't matter which elements are selected by trueop1,
    4921                 :             :                because they are all the same.  */
    4922                 :       14284 :             return gen_vec_duplicate (mode, elt0);
    4923                 :             : 
    4924                 :     2416126 :           if (GET_CODE (trueop0) == CONST_VECTOR)
    4925                 :             :             {
    4926                 :       16766 :               unsigned n_elts = XVECLEN (trueop1, 0);
    4927                 :       16766 :               rtvec v = rtvec_alloc (n_elts);
    4928                 :       16766 :               unsigned int i;
    4929                 :             : 
    4930                 :       33532 :               gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
    4931                 :       86738 :               for (i = 0; i < n_elts; i++)
    4932                 :             :                 {
    4933                 :       69972 :                   rtx x = XVECEXP (trueop1, 0, i);
    4934                 :             : 
    4935                 :       69972 :                   if (!CONST_INT_P (x))
    4936                 :             :                     return 0;
    4937                 :             : 
    4938                 :       69972 :                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
    4939                 :             :                                                        INTVAL (x));
    4940                 :             :                 }
    4941                 :             : 
    4942                 :       16766 :               return gen_rtx_CONST_VECTOR (mode, v);
    4943                 :             :             }
    4944                 :             : 
    4945                 :             :           /* Recognize the identity.  */
    4946                 :     2399360 :           if (GET_MODE (trueop0) == mode)
    4947                 :             :             {
    4948                 :      589042 :               bool maybe_ident = true;
    4949                 :      589042 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    4950                 :             :                 {
    4951                 :      588679 :                   rtx j = XVECEXP (trueop1, 0, i);
    4952                 :      588679 :                   if (!CONST_INT_P (j) || INTVAL (j) != i)
    4953                 :             :                     {
    4954                 :             :                       maybe_ident = false;
    4955                 :             :                       break;
    4956                 :             :                     }
    4957                 :             :                 }
    4958                 :      369712 :               if (maybe_ident)
    4959                 :             :                 return trueop0;
    4960                 :             :             }
    4961                 :             : 
    4962                 :             :           /* If we select a low-part subreg, return that.  */
    4963                 :     2398997 :           if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
    4964                 :             :             {
    4965                 :           0 :               rtx new_rtx = lowpart_subreg (mode, trueop0,
    4966                 :           0 :                                             GET_MODE (trueop0));
    4967                 :           0 :               if (new_rtx != NULL_RTX)
    4968                 :             :                 return new_rtx;
    4969                 :             :             }
    4970                 :             : 
    4971                 :             :           /* If we build {a,b} then permute it, build the result directly.  */
    4972                 :     2398997 :           if (XVECLEN (trueop1, 0) == 2
    4973                 :      580361 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    4974                 :      580361 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    4975                 :      580361 :               && GET_CODE (trueop0) == VEC_CONCAT
    4976                 :      168517 :               && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
    4977                 :          79 :               && GET_MODE (XEXP (trueop0, 0)) == mode
    4978                 :          79 :               && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
    4979                 :          56 :               && GET_MODE (XEXP (trueop0, 1)) == mode)
    4980                 :             :             {
    4981                 :          56 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    4982                 :          56 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    4983                 :          56 :               rtx subop0, subop1;
    4984                 :             : 
    4985                 :          56 :               gcc_assert (i0 < 4 && i1 < 4);
    4986                 :          56 :               subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
    4987                 :          56 :               subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
    4988                 :             : 
    4989                 :          56 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    4990                 :             :             }
    4991                 :             : 
    4992                 :     2398941 :           if (XVECLEN (trueop1, 0) == 2
    4993                 :      580305 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    4994                 :      580305 :               && CONST_INT_P (XVECEXP (trueop1, 0, 1))
    4995                 :      580305 :               && GET_CODE (trueop0) == VEC_CONCAT
    4996                 :      168461 :               && GET_MODE (trueop0) == mode)
    4997                 :             :             {
    4998                 :           2 :               unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    4999                 :           2 :               unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
    5000                 :           2 :               rtx subop0, subop1;
    5001                 :             : 
    5002                 :           2 :               gcc_assert (i0 < 2 && i1 < 2);
    5003                 :           2 :               subop0 = XEXP (trueop0, i0);
    5004                 :           2 :               subop1 = XEXP (trueop0, i1);
    5005                 :             : 
    5006                 :           2 :               return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
    5007                 :             :             }
    5008                 :             : 
    5009                 :             :           /* If we select one half of a vec_concat, return that.  */
    5010                 :     2398939 :           int l0, l1;
    5011                 :     2398939 :           if (GET_CODE (trueop0) == VEC_CONCAT
    5012                 :     2929592 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
    5013                 :     1464796 :                   .is_constant (&l0))
    5014                 :     2929592 :               && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
    5015                 :     1464796 :                   .is_constant (&l1))
    5016                 :     3863735 :               && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
    5017                 :             :             {
    5018                 :     1464796 :               rtx subop0 = XEXP (trueop0, 0);
    5019                 :     1464796 :               rtx subop1 = XEXP (trueop0, 1);
    5020                 :     1464796 :               machine_mode mode0 = GET_MODE (subop0);
    5021                 :     1464796 :               machine_mode mode1 = GET_MODE (subop1);
    5022                 :     1464796 :               int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
    5023                 :     1464796 :               if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
    5024                 :             :                 {
    5025                 :      928996 :                   bool success = true;
    5026                 :      928996 :                   for (int i = 1; i < l0; ++i)
    5027                 :             :                     {
    5028                 :      928661 :                       rtx j = XVECEXP (trueop1, 0, i);
    5029                 :      928661 :                       if (!CONST_INT_P (j) || INTVAL (j) != i)
    5030                 :             :                         {
    5031                 :             :                           success = false;
    5032                 :             :                           break;
    5033                 :             :                         }
    5034                 :             :                     }
    5035                 :      847743 :                   if (success)
    5036                 :             :                     return subop0;
    5037                 :             :                 }
    5038                 :     1464461 :               if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
    5039                 :             :                 {
    5040                 :         532 :                   bool success = true;
    5041                 :         532 :                   for (int i = 1; i < l1; ++i)
    5042                 :             :                     {
    5043                 :         485 :                       rtx j = XVECEXP (trueop1, 0, i);
    5044                 :         485 :                       if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
    5045                 :             :                         {
    5046                 :             :                           success = false;
    5047                 :             :                           break;
    5048                 :             :                         }
    5049                 :             :                     }
    5050                 :          76 :                   if (success)
    5051                 :             :                     return subop1;
    5052                 :             :                 }
    5053                 :             :             }
    5054                 :             : 
    5055                 :             :           /* Simplify vec_select of a subreg of X to just a vec_select of X
    5056                 :             :              when X has same component mode as vec_select.  */
    5057                 :     2398557 :           unsigned HOST_WIDE_INT subreg_offset = 0;
    5058                 :     2398557 :           if (GET_CODE (trueop0) == SUBREG
    5059                 :      352344 :               && GET_MODE_INNER (mode)
    5060                 :      704688 :                  == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
    5061                 :       28142 :               && GET_MODE_NUNITS (mode).is_constant (&l1)
    5062                 :     2750901 :               && constant_multiple_p (subreg_memory_offset (trueop0),
    5063                 :       28142 :                                       GET_MODE_UNIT_BITSIZE (mode),
    5064                 :             :                                       &subreg_offset))
    5065                 :             :             {
    5066                 :       14071 :               poly_uint64 nunits
    5067                 :       28142 :                 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
    5068                 :       14071 :               bool success = true;
    5069                 :       80433 :               for (int i = 0; i != l1; i++)
    5070                 :             :                 {
    5071                 :       76783 :                   rtx idx = XVECEXP (trueop1, 0, i);
    5072                 :       76783 :                   if (!CONST_INT_P (idx)
    5073                 :       76783 :                       || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
    5074                 :             :                     {
    5075                 :             :                       success = false;
    5076                 :             :                       break;
    5077                 :             :                     }
    5078                 :             :                 }
    5079                 :             : 
    5080                 :       14071 :               if (success)
    5081                 :             :                 {
    5082                 :        3650 :                   rtx par = trueop1;
    5083                 :        3650 :                   if (subreg_offset)
    5084                 :             :                     {
    5085                 :           0 :                       rtvec vec = rtvec_alloc (l1);
    5086                 :           0 :                       for (int i = 0; i < l1; i++)
    5087                 :           0 :                         RTVEC_ELT (vec, i)
    5088                 :           0 :                           = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
    5089                 :             :                                      + subreg_offset);
    5090                 :           0 :                       par = gen_rtx_PARALLEL (VOIDmode, vec);
    5091                 :             :                     }
    5092                 :        3650 :                   return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
    5093                 :             :                 }
    5094                 :             :             }
    5095                 :             :         }
    5096                 :             : 
    5097                 :     3194730 :       if (XVECLEN (trueop1, 0) == 1
    5098                 :      799907 :           && CONST_INT_P (XVECEXP (trueop1, 0, 0))
    5099                 :      799907 :           && GET_CODE (trueop0) == VEC_CONCAT)
    5100                 :             :         {
    5101                 :        1282 :           rtx vec = trueop0;
    5102                 :        2564 :           offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
    5103                 :             : 
    5104                 :             :           /* Try to find the element in the VEC_CONCAT.  */
    5105                 :        1282 :           while (GET_MODE (vec) != mode
    5106                 :        2564 :                  && GET_CODE (vec) == VEC_CONCAT)
    5107                 :             :             {
    5108                 :        1282 :               poly_int64 vec_size;
    5109                 :             : 
    5110                 :        1282 :               if (CONST_INT_P (XEXP (vec, 0)))
    5111                 :             :                 {
    5112                 :             :                   /* vec_concat of two const_ints doesn't make sense with
    5113                 :             :                      respect to modes.  */
    5114                 :           1 :                   if (CONST_INT_P (XEXP (vec, 1)))
    5115                 :   379912240 :                     return 0;
    5116                 :             : 
    5117                 :           1 :                   vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
    5118                 :           3 :                              - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
    5119                 :             :                 }
    5120                 :             :               else
    5121                 :        2562 :                 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
    5122                 :             : 
    5123                 :        1282 :               if (known_lt (offset, vec_size))
    5124                 :             :                 vec = XEXP (vec, 0);
    5125                 :         317 :               else if (known_ge (offset, vec_size))
    5126                 :             :                 {
    5127                 :         317 :                   offset -= vec_size;
    5128                 :         317 :                   vec = XEXP (vec, 1);
    5129                 :             :                 }
    5130                 :             :               else
    5131                 :             :                 break;
    5132                 :        1282 :               vec = avoid_constant_pool_reference (vec);
    5133                 :             :             }
    5134                 :             : 
    5135                 :        1282 :           if (GET_MODE (vec) == mode)
    5136                 :             :             return vec;
    5137                 :             :         }
    5138                 :             : 
    5139                 :             :       /* If we select elements in a vec_merge that all come from the same
    5140                 :             :          operand, select from that operand directly.  */
    5141                 :     3193621 :       if (GET_CODE (op0) == VEC_MERGE)
    5142                 :             :         {
    5143                 :        7511 :           rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
    5144                 :        7511 :           if (CONST_INT_P (trueop02))
    5145                 :             :             {
    5146                 :        2459 :               unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
    5147                 :        2459 :               bool all_operand0 = true;
    5148                 :        2459 :               bool all_operand1 = true;
    5149                 :        8987 :               for (int i = 0; i < XVECLEN (trueop1, 0); i++)
    5150                 :             :                 {
    5151                 :        6528 :                   rtx j = XVECEXP (trueop1, 0, i);
    5152                 :        6528 :                   if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
    5153                 :             :                     all_operand1 = false;
    5154                 :             :                   else
    5155                 :        3190 :                     all_operand0 = false;
    5156                 :             :                 }
    5157                 :        2459 :               if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
    5158                 :         713 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
    5159                 :        1746 :               if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
    5160                 :          47 :                 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
    5161                 :             :             }
    5162                 :             :         }
    5163                 :             : 
    5164                 :             :       /* If we have two nested selects that are inverses of each
    5165                 :             :          other, replace them with the source operand.  */
    5166                 :     3192861 :       if (GET_CODE (trueop0) == VEC_SELECT
    5167                 :       67139 :           && GET_MODE (XEXP (trueop0, 0)) == mode)
    5168                 :             :         {
    5169                 :        1275 :           rtx op0_subop1 = XEXP (trueop0, 1);
    5170                 :        1275 :           gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
    5171                 :        2550 :           gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
    5172                 :             : 
    5173                 :             :           /* Apply the outer ordering vector to the inner one.  (The inner
    5174                 :             :              ordering vector is expressly permitted to be of a different
    5175                 :             :              length than the outer one.)  If the result is { 0, 1, ..., n-1 }
    5176                 :             :              then the two VEC_SELECTs cancel.  */
    5177                 :        1581 :           for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
    5178                 :             :             {
    5179                 :        1581 :               rtx x = XVECEXP (trueop1, 0, i);
    5180                 :        1581 :               if (!CONST_INT_P (x))
    5181                 :             :                 return 0;
    5182                 :        1581 :               rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
    5183                 :        1581 :               if (!CONST_INT_P (y) || i != INTVAL (y))
    5184                 :             :                 return 0;
    5185                 :             :             }
    5186                 :             :           return XEXP (trueop0, 0);
    5187                 :             :         }
    5188                 :             : 
    5189                 :             :       return 0;
    5190                 :     4142375 :     case VEC_CONCAT:
    5191                 :     4142375 :       {
    5192                 :     4142375 :         machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
    5193                 :     4142375 :                                       ? GET_MODE (trueop0)
    5194                 :     4142375 :                                       : GET_MODE_INNER (mode));
    5195                 :     4142375 :         machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
    5196                 :     4142375 :                                       ? GET_MODE (trueop1)
    5197                 :     4142375 :                                       : GET_MODE_INNER (mode));
    5198                 :             : 
    5199                 :     4142375 :         gcc_assert (VECTOR_MODE_P (mode));
    5200                 :    16569500 :         gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
    5201                 :             :                               + GET_MODE_SIZE (op1_mode),
    5202                 :             :                               GET_MODE_SIZE (mode)));
    5203                 :             : 
    5204                 :     4142375 :         if (VECTOR_MODE_P (op0_mode))
    5205                 :     5546388 :           gcc_assert (GET_MODE_INNER (mode)
    5206                 :             :                       == GET_MODE_INNER (op0_mode));
    5207                 :             :         else
    5208                 :     4587158 :           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
    5209                 :             : 
    5210                 :     4142375 :         if (VECTOR_MODE_P (op1_mode))
    5211                 :     5546388 :           gcc_assert (GET_MODE_INNER (mode)
    5212                 :             :                       == GET_MODE_INNER (op1_mode));
    5213                 :             :         else
    5214                 :     4587158 :           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
    5215                 :             : 
    5216                 :     4142375 :         unsigned int n_elts, in_n_elts;
    5217                 :     4142375 :         if ((GET_CODE (trueop0) == CONST_VECTOR
    5218                 :     4142375 :              || CONST_SCALAR_INT_P (trueop0)
    5219                 :     3967693 :              || CONST_DOUBLE_AS_FLOAT_P (trueop0))
    5220                 :      176120 :             && (GET_CODE (trueop1) == CONST_VECTOR
    5221                 :      176120 :                 || CONST_SCALAR_INT_P (trueop1)
    5222                 :      169106 :                 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
    5223                 :       14028 :             && GET_MODE_NUNITS (mode).is_constant (&n_elts)
    5224                 :     4149389 :             && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
    5225                 :             :           {
    5226                 :        7014 :             rtvec v = rtvec_alloc (n_elts);
    5227                 :        7014 :             unsigned int i;
    5228                 :      120868 :             for (i = 0; i < n_elts; i++)
    5229                 :             :               {
    5230                 :      106840 :                 if (i < in_n_elts)
    5231                 :             :                   {
    5232                 :       53324 :                     if (!VECTOR_MODE_P (op0_mode))
    5233                 :           0 :                       RTVEC_ELT (v, i) = trueop0;
    5234                 :             :                     else
    5235                 :       53324 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
    5236                 :             :                   }
    5237                 :             :                 else
    5238                 :             :                   {
    5239                 :       53516 :                     if (!VECTOR_MODE_P (op1_mode))
    5240                 :           0 :                       RTVEC_ELT (v, i) = trueop1;
    5241                 :             :                     else
    5242                 :       53516 :                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
    5243                 :             :                                                            i - in_n_elts);
    5244                 :             :                   }
    5245                 :             :               }
    5246                 :             : 
    5247                 :        7014 :             return gen_rtx_CONST_VECTOR (mode, v);
    5248                 :             :           }
    5249                 :             : 
    5250                 :             :         /* Try to merge two VEC_SELECTs from the same vector into a single one.
    5251                 :             :            Restrict the transformation to avoid generating a VEC_SELECT with a
    5252                 :             :            mode unrelated to its operand.  */
    5253                 :     4135361 :         if (GET_CODE (trueop0) == VEC_SELECT
    5254                 :      128249 :             && GET_CODE (trueop1) == VEC_SELECT
    5255                 :       27811 :             && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
    5256                 :     4151094 :             && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
    5257                 :       31466 :                == GET_MODE_INNER(mode))
    5258                 :             :           {
    5259                 :       15733 :             rtx par0 = XEXP (trueop0, 1);
    5260                 :       15733 :             rtx par1 = XEXP (trueop1, 1);
    5261                 :       15733 :             int len0 = XVECLEN (par0, 0);
    5262                 :       15733 :             int len1 = XVECLEN (par1, 0);
    5263                 :       15733 :             rtvec vec = rtvec_alloc (len0 + len1);
    5264                 :       96331 :             for (int i = 0; i < len0; i++)
    5265                 :       80598 :               RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
    5266                 :       96331 :             for (int i = 0; i < len1; i++)
    5267                 :       80598 :               RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
    5268                 :       15733 :             return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
    5269                 :       15733 :                                         gen_rtx_PARALLEL (VOIDmode, vec));
    5270                 :             :           }
    5271                 :             :         /* (vec_concat:
    5272                 :             :              (subreg_lowpart:N OP)
    5273                 :             :              (vec_select:N OP P))  -->  OP when P selects the high half
    5274                 :             :             of the OP.  */
    5275                 :     4119628 :         if (GET_CODE (trueop0) == SUBREG
    5276                 :      461053 :             && subreg_lowpart_p (trueop0)
    5277                 :      460820 :             && GET_CODE (trueop1) == VEC_SELECT
    5278                 :           9 :             && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
    5279                 :           0 :             && !side_effects_p (XEXP (trueop1, 0))
    5280                 :     4119628 :             && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
    5281                 :           0 :           return XEXP (trueop1, 0);
    5282                 :             :       }
    5283                 :             :       return 0;
    5284                 :             : 
    5285                 :           0 :     default:
    5286                 :           0 :       gcc_unreachable ();
    5287                 :             :     }
    5288                 :             : 
    5289                 :   372062900 :   if (mode == GET_MODE (op0)
    5290                 :   318280991 :       && mode == GET_MODE (op1)
    5291                 :    96114156 :       && vec_duplicate_p (op0, &elt0)
    5292                 :   372172007 :       && vec_duplicate_p (op1, &elt1))
    5293                 :             :     {
    5294                 :             :       /* Try applying the operator to ELT and see if that simplifies.
    5295                 :             :          We can duplicate the result if so.
    5296                 :             : 
    5297                 :             :          The reason we don't use simplify_gen_binary is that it isn't
    5298                 :             :          necessarily a win to convert things like:
    5299                 :             : 
    5300                 :             :            (plus:V (vec_duplicate:V (reg:S R1))
    5301                 :             :                    (vec_duplicate:V (reg:S R2)))
    5302                 :             : 
    5303                 :             :          to:
    5304                 :             : 
    5305                 :             :            (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
    5306                 :             : 
    5307                 :             :          The first might be done entirely in vector registers while the
    5308                 :             :          second might need a move between register files.  */
    5309                 :         118 :       tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5310                 :             :                                        elt0, elt1);
    5311                 :          59 :       if (tem)
    5312                 :           2 :         return gen_vec_duplicate (mode, tem);
    5313                 :             :     }
    5314                 :             : 
    5315                 :             :   return 0;
    5316                 :             : }
    5317                 :             : 
    5318                 :             : /* Return true if binary operation OP distributes over addition in operand
    5319                 :             :    OPNO, with the other operand being held constant.  OPNO counts from 1.  */
    5320                 :             : 
    5321                 :             : static bool
    5322                 :       24593 : distributes_over_addition_p (rtx_code op, int opno)
    5323                 :             : {
    5324                 :           0 :   switch (op)
    5325                 :             :     {
    5326                 :             :     case PLUS:
    5327                 :             :     case MINUS:
    5328                 :             :     case MULT:
    5329                 :             :       return true;
    5330                 :             : 
    5331                 :           0 :     case ASHIFT:
    5332                 :           0 :       return opno == 1;
    5333                 :             : 
    5334                 :           0 :     default:
    5335                 :           0 :       return false;
    5336                 :             :     }
    5337                 :             : }
    5338                 :             : 
    5339                 :             : rtx
    5340                 :   476415590 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
    5341                 :             :                                  rtx op0, rtx op1)
    5342                 :             : {
    5343                 :   476415590 :   if (VECTOR_MODE_P (mode)
    5344                 :    14227688 :       && code != VEC_CONCAT
    5345                 :    10083375 :       && GET_CODE (op0) == CONST_VECTOR
    5346                 :      201835 :       && GET_CODE (op1) == CONST_VECTOR)
    5347                 :             :     {
    5348                 :       25308 :       bool step_ok_p;
    5349                 :       25308 :       if (CONST_VECTOR_STEPPED_P (op0)
    5350                 :       25308 :           && CONST_VECTOR_STEPPED_P (op1))
    5351                 :             :         /* We can operate directly on the encoding if:
    5352                 :             : 
    5353                 :             :               a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
    5354                 :             :             implies
    5355                 :             :               (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
    5356                 :             : 
    5357                 :             :            Addition and subtraction are the supported operators
    5358                 :             :            for which this is true.  */
    5359                 :         715 :         step_ok_p = (code == PLUS || code == MINUS);
    5360                 :       24593 :       else if (CONST_VECTOR_STEPPED_P (op0))
    5361                 :             :         /* We can operate directly on stepped encodings if:
    5362                 :             : 
    5363                 :             :              a3 - a2 == a2 - a1
    5364                 :             :            implies:
    5365                 :             :              (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
    5366                 :             : 
    5367                 :             :            which is true if (x -> x op c) distributes over addition.  */
    5368                 :        1044 :         step_ok_p = distributes_over_addition_p (code, 1);
    5369                 :             :       else
    5370                 :             :         /* Similarly in reverse.  */
    5371                 :       23549 :         step_ok_p = distributes_over_addition_p (code, 2);
    5372                 :       25308 :       rtx_vector_builder builder;
    5373                 :       25308 :       if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
    5374                 :             :         return 0;
    5375                 :             : 
    5376                 :       25308 :       unsigned int count = builder.encoded_nelts ();
    5377                 :      103653 :       for (unsigned int i = 0; i < count; i++)
    5378                 :             :         {
    5379                 :      156960 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5380                 :             :                                              CONST_VECTOR_ELT (op0, i),
    5381                 :       78480 :                                              CONST_VECTOR_ELT (op1, i));
    5382                 :       78480 :           if (!x || !valid_for_const_vector_p (mode, x))
    5383                 :         135 :             return 0;
    5384                 :       78345 :           builder.quick_push (x);
    5385                 :             :         }
    5386                 :       25173 :       return builder.build ();
    5387                 :       25308 :     }
    5388                 :             : 
    5389                 :   476390282 :   if (VECTOR_MODE_P (mode)
    5390                 :    14202380 :       && code == VEC_CONCAT
    5391                 :     4144313 :       && (CONST_SCALAR_INT_P (op0)
    5392                 :     3988721 :           || CONST_FIXED_P (op0)
    5393                 :     3988721 :           || CONST_DOUBLE_AS_FLOAT_P (op0))
    5394                 :      158290 :       && (CONST_SCALAR_INT_P (op1)
    5395                 :      157612 :           || CONST_DOUBLE_AS_FLOAT_P (op1)
    5396                 :      156352 :           || CONST_FIXED_P (op1)))
    5397                 :             :     {
    5398                 :             :       /* Both inputs have a constant number of elements, so the result
    5399                 :             :          must too.  */
    5400                 :        1938 :       unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
    5401                 :        1938 :       rtvec v = rtvec_alloc (n_elts);
    5402                 :             : 
    5403                 :        1938 :       gcc_assert (n_elts >= 2);
    5404                 :        1938 :       if (n_elts == 2)
    5405                 :             :         {
    5406                 :        1938 :           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
    5407                 :        1938 :           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
    5408                 :             : 
    5409                 :        1938 :           RTVEC_ELT (v, 0) = op0;
    5410                 :        1938 :           RTVEC_ELT (v, 1) = op1;
    5411                 :             :         }
    5412                 :             :       else
    5413                 :             :         {
    5414                 :           0 :           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
    5415                 :           0 :           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
    5416                 :           0 :           unsigned i;
    5417                 :             : 
    5418                 :           0 :           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
    5419                 :           0 :           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
    5420                 :           0 :           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
    5421                 :             : 
    5422                 :           0 :           for (i = 0; i < op0_n_elts; ++i)
    5423                 :           0 :             RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
    5424                 :           0 :           for (i = 0; i < op1_n_elts; ++i)
    5425                 :           0 :             RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
    5426                 :             :         }
    5427                 :             : 
    5428                 :        1938 :       return gen_rtx_CONST_VECTOR (mode, v);
    5429                 :             :     }
    5430                 :             : 
    5431                 :   465223221 :   if (VECTOR_MODE_P (mode)
    5432                 :    14200442 :       && GET_CODE (op0) == CONST_VECTOR
    5433                 :      196295 :       && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
    5434                 :   476388344 :       && (CONST_VECTOR_DUPLICATE_P (op0)
    5435                 :             :           || CONST_VECTOR_NUNITS (op0).is_constant ()))
    5436                 :             :     {
    5437                 :      137008 :       switch (code)
    5438                 :             :         {
    5439                 :      137008 :         case PLUS:
    5440                 :      137008 :         case MINUS:
    5441                 :      137008 :         case MULT:
    5442                 :      137008 :         case DIV:
    5443                 :      137008 :         case MOD:
    5444                 :      137008 :         case UDIV:
    5445                 :      137008 :         case UMOD:
    5446                 :      137008 :         case AND:
    5447                 :      137008 :         case IOR:
    5448                 :      137008 :         case XOR:
    5449                 :      137008 :         case SMIN:
    5450                 :      137008 :         case SMAX:
    5451                 :      137008 :         case UMIN:
    5452                 :      137008 :         case UMAX:
    5453                 :      137008 :         case LSHIFTRT:
    5454                 :      137008 :         case ASHIFTRT:
    5455                 :      137008 :         case ASHIFT:
    5456                 :      137008 :         case ROTATE:
    5457                 :      137008 :         case ROTATERT:
    5458                 :      137008 :         case SS_PLUS:
    5459                 :      137008 :         case US_PLUS:
    5460                 :      137008 :         case SS_MINUS:
    5461                 :      137008 :         case US_MINUS:
    5462                 :      137008 :         case SS_ASHIFT:
    5463                 :      137008 :         case US_ASHIFT:
    5464                 :      137008 :         case COPYSIGN:
    5465                 :      137008 :           break;
    5466                 :             :         default:
    5467                 :             :           return NULL_RTX;
    5468                 :             :         }
    5469                 :             : 
    5470                 :      137008 :       unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
    5471                 :      137008 :                                 ? CONST_VECTOR_NPATTERNS (op0)
    5472                 :      144564 :                                 : CONST_VECTOR_NUNITS (op0).to_constant ());
    5473                 :      137008 :       rtx_vector_builder builder (mode, npatterns, 1);
    5474                 :      286868 :       for (unsigned i = 0; i < npatterns; i++)
    5475                 :             :         {
    5476                 :      299720 :           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
    5477                 :      149860 :                                              CONST_VECTOR_ELT (op0, i), op1);
    5478                 :      149860 :           if (!x || !valid_for_const_vector_p (mode, x))
    5479                 :           0 :             return 0;
    5480                 :      149860 :           builder.quick_push (x);
    5481                 :             :         }
    5482                 :      137008 :       return builder.build ();
    5483                 :             :     }
    5484                 :             : 
    5485                 :   476251336 :   if (SCALAR_FLOAT_MODE_P (mode)
    5486                 :     6418894 :       && CONST_DOUBLE_AS_FLOAT_P (op0)
    5487                 :      112575 :       && CONST_DOUBLE_AS_FLOAT_P (op1)
    5488                 :       47925 :       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
    5489                 :             :     {
    5490                 :       47925 :       if (code == AND
    5491                 :             :           || code == IOR
    5492                 :       47925 :           || code == XOR)
    5493                 :             :         {
    5494                 :       38795 :           long tmp0[4];
    5495                 :       38795 :           long tmp1[4];
    5496                 :       38795 :           REAL_VALUE_TYPE r;
    5497                 :       38795 :           int i;
    5498                 :             : 
    5499                 :       38795 :           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
    5500                 :       38795 :                           GET_MODE (op0));
    5501                 :       38795 :           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
    5502                 :       38795 :                           GET_MODE (op1));
    5503                 :      193975 :           for (i = 0; i < 4; i++)
    5504                 :             :             {
    5505                 :      155180 :               switch (code)
    5506                 :             :               {
    5507                 :      150116 :               case AND:
    5508                 :      150116 :                 tmp0[i] &= tmp1[i];
    5509                 :      150116 :                 break;
    5510                 :        2784 :               case IOR:
    5511                 :        2784 :                 tmp0[i] |= tmp1[i];
    5512                 :        2784 :                 break;
    5513                 :        2280 :               case XOR:
    5514                 :        2280 :                 tmp0[i] ^= tmp1[i];
    5515                 :        2280 :                 break;
    5516                 :             :               default:
    5517                 :             :                 gcc_unreachable ();
    5518                 :             :               }
    5519                 :             :             }
    5520                 :       38795 :            real_from_target (&r, tmp0, mode);
    5521                 :       38795 :            return const_double_from_real_value (r, mode);
    5522                 :             :         }
    5523                 :        9130 :       else if (code == COPYSIGN)
    5524                 :             :         {
    5525                 :           0 :           REAL_VALUE_TYPE f0, f1;
    5526                 :           0 :           real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
    5527                 :           0 :           real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
    5528                 :           0 :           real_copysign (&f0, &f1);
    5529                 :           0 :           return const_double_from_real_value (f0, mode);
    5530                 :             :         }
    5531                 :             :       else
    5532                 :             :         {
    5533                 :        9130 :           REAL_VALUE_TYPE f0, f1, value, result;
    5534                 :        9130 :           const REAL_VALUE_TYPE *opr0, *opr1;
    5535                 :        9130 :           bool inexact;
    5536                 :             : 
    5537                 :        9130 :           opr0 = CONST_DOUBLE_REAL_VALUE (op0);
    5538                 :        9130 :           opr1 = CONST_DOUBLE_REAL_VALUE (op1);
    5539                 :             : 
    5540                 :        9130 :           if (HONOR_SNANS (mode)
    5541                 :        9130 :               && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
    5542                 :         803 :                   || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
    5543                 :          10 :             return 0;
    5544                 :             : 
    5545                 :        9120 :           real_convert (&f0, mode, opr0);
    5546                 :        9120 :           real_convert (&f1, mode, opr1);
    5547                 :             : 
    5548                 :        9120 :           if (code == DIV
    5549                 :        4173 :               && real_equal (&f1, &dconst0)
    5550                 :       12825 :               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
    5551                 :        3701 :             return 0;
    5552                 :             : 
    5553                 :       26995 :           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5554                 :        5328 :               && flag_trapping_math
    5555                 :        5252 :               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
    5556                 :             :             {
    5557                 :           9 :               int s0 = REAL_VALUE_NEGATIVE (f0);
    5558                 :           9 :               int s1 = REAL_VALUE_NEGATIVE (f1);
    5559                 :             : 
    5560                 :           9 :               switch (code)
    5561                 :             :                 {
    5562                 :           0 :                 case PLUS:
    5563                 :             :                   /* Inf + -Inf = NaN plus exception.  */
    5564                 :           0 :                   if (s0 != s1)
    5565                 :             :                     return 0;
    5566                 :             :                   break;
    5567                 :           0 :                 case MINUS:
    5568                 :             :                   /* Inf - Inf = NaN plus exception.  */
    5569                 :           0 :                   if (s0 == s1)
    5570                 :             :                     return 0;
    5571                 :             :                   break;
    5572                 :             :                 case DIV:
    5573                 :             :                   /* Inf / Inf = NaN plus exception.  */
    5574                 :             :                   return 0;
    5575                 :             :                 default:
    5576                 :             :                   break;
    5577                 :             :                 }
    5578                 :             :             }
    5579                 :             : 
    5580                 :        8104 :           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
    5581                 :        1993 :               && flag_trapping_math
    5582                 :        7357 :               && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
    5583                 :        1939 :                   || (REAL_VALUE_ISINF (f1)
    5584                 :          16 :                       && real_equal (&f0, &dconst0))))
    5585                 :             :             /* Inf * 0 = NaN plus exception.  */
    5586                 :          24 :             return 0;
    5587                 :             : 
    5588                 :        5386 :           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
    5589                 :             :                                      &f0, &f1);
    5590                 :        5386 :           real_convert (&result, mode, &value);
    5591                 :             : 
    5592                 :             :           /* Don't constant fold this floating point operation if
    5593                 :             :              the result has overflowed and flag_trapping_math.  */
    5594                 :             : 
    5595                 :        5386 :           if (flag_trapping_math
    5596                 :       20876 :               && MODE_HAS_INFINITIES (mode)
    5597                 :        5219 :               && REAL_VALUE_ISINF (result)
    5598                 :        1104 :               && !REAL_VALUE_ISINF (f0)
    5599                 :        6476 :               && !REAL_VALUE_ISINF (f1))
    5600                 :             :             /* Overflow plus exception.  */
    5601                 :        1090 :             return 0;
    5602                 :             : 
    5603                 :             :           /* Don't constant fold this floating point operation if the
    5604                 :             :              result may dependent upon the run-time rounding mode and
    5605                 :             :              flag_rounding_math is set, or if GCC's software emulation
    5606                 :             :              is unable to accurately represent the result.  */
    5607                 :             : 
    5608                 :        4296 :           if ((flag_rounding_math
    5609                 :       27391 :                || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
    5610                 :        4296 :               && (inexact || !real_identical (&result, &value)))
    5611                 :         378 :             return NULL_RTX;
    5612                 :             : 
    5613                 :        3918 :           return const_double_from_real_value (result, mode);
    5614                 :             :         }
    5615                 :             :     }
    5616                 :             : 
    5617                 :             :   /* We can fold some multi-word operations.  */
    5618                 :   476203411 :   scalar_int_mode int_mode;
    5619                 :   476203411 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    5620                 :   407527463 :       && CONST_SCALAR_INT_P (op0)
    5621                 :    40069473 :       && CONST_SCALAR_INT_P (op1)
    5622                 :    33596207 :       && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
    5623                 :             :     {
    5624                 :    33596207 :       wide_int result;
    5625                 :    33596207 :       wi::overflow_type overflow;
    5626                 :    33596207 :       rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
    5627                 :    33596207 :       rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
    5628                 :             : 
    5629                 :             : #if TARGET_SUPPORTS_WIDE_INT == 0
    5630                 :             :       /* This assert keeps the simplification from producing a result
    5631                 :             :          that cannot be represented in a CONST_DOUBLE but a lot of
    5632                 :             :          upstream callers expect that this function never fails to
    5633                 :             :          simplify something and so you if you added this to the test
    5634                 :             :          above the code would die later anyway.  If this assert
    5635                 :             :          happens, you just need to make the port support wide int.  */
    5636                 :             :       gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
    5637                 :             : #endif
    5638                 :    33596207 :       switch (code)
    5639                 :             :         {
    5640                 :     1109608 :         case MINUS:
    5641                 :     1109608 :           result = wi::sub (pop0, pop1);
    5642                 :     1109608 :           break;
    5643                 :             : 
    5644                 :    26556378 :         case PLUS:
    5645                 :    26556378 :           result = wi::add (pop0, pop1);
    5646                 :    26556378 :           break;
    5647                 :             : 
    5648                 :      308154 :         case MULT:
    5649                 :      308154 :           result = wi::mul (pop0, pop1);
    5650                 :      308154 :           break;
    5651                 :             : 
    5652                 :        5397 :         case DIV:
    5653                 :        5397 :           result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
    5654                 :        5397 :           if (overflow)
    5655                 :             :             return NULL_RTX;
    5656                 :             :           break;
    5657                 :             : 
    5658                 :         218 :         case MOD:
    5659                 :         218 :           result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
    5660                 :         218 :           if (overflow)
    5661                 :             :             return NULL_RTX;
    5662                 :             :           break;
    5663                 :             : 
    5664                 :        6795 :         case UDIV:
    5665                 :        6795 :           result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
    5666                 :        6795 :           if (overflow)
    5667                 :             :             return NULL_RTX;
    5668                 :             :           break;
    5669                 :             : 
    5670                 :       13835 :         case UMOD:
    5671                 :       13835 :           result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
    5672                 :       13835 :           if (overflow)
    5673                 :             :             return NULL_RTX;
    5674                 :             :           break;
    5675                 :             : 
    5676                 :      552946 :         case AND:
    5677                 :      552946 :           result = wi::bit_and (pop0, pop1);
    5678                 :      552946 :           break;
    5679                 :             : 
    5680                 :      221105 :         case IOR:
    5681                 :      221105 :           result = wi::bit_or (pop0, pop1);
    5682                 :      221105 :           break;
    5683                 :             : 
    5684                 :       89945 :         case XOR:
    5685                 :       89945 :           result = wi::bit_xor (pop0, pop1);
    5686                 :       89945 :           break;
    5687                 :             : 
    5688                 :        1759 :         case SMIN:
    5689                 :        1759 :           result = wi::smin (pop0, pop1);
    5690                 :        1759 :           break;
    5691                 :             : 
    5692                 :        1833 :         case SMAX:
    5693                 :        1833 :           result = wi::smax (pop0, pop1);
    5694                 :        1833 :           break;
    5695                 :             : 
    5696                 :        3130 :         case UMIN:
    5697                 :        3130 :           result = wi::umin (pop0, pop1);
    5698                 :        3130 :           break;
    5699                 :             : 
    5700                 :        2801 :         case UMAX:
    5701                 :        2801 :           result = wi::umax (pop0, pop1);
    5702                 :        2801 :           break;
    5703                 :             : 
    5704                 :     4679790 :         case LSHIFTRT:
    5705                 :     4679790 :         case ASHIFTRT:
    5706                 :     4679790 :         case ASHIFT:
    5707                 :     4679790 :         case SS_ASHIFT:
    5708                 :     4679790 :         case US_ASHIFT:
    5709                 :     4679790 :           {
    5710                 :             :             /* The shift count might be in SImode while int_mode might
    5711                 :             :                be narrower.  On IA-64 it is even DImode.  If the shift
    5712                 :             :                count is too large and doesn't fit into int_mode, we'd
    5713                 :             :                ICE.  So, if int_mode is narrower than word, use
    5714                 :             :                word_mode for the shift count.  */
    5715                 :     4679790 :             if (GET_MODE (op1) == VOIDmode
    5716                 :     5032700 :                 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
    5717                 :     1537256 :               pop1 = rtx_mode_t (op1, word_mode);
    5718                 :             : 
    5719                 :     4679790 :             wide_int wop1 = pop1;
    5720                 :     4679790 :             if (SHIFT_COUNT_TRUNCATED)
    5721                 :             :               wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
    5722                 :     4679790 :             else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
    5723                 :         124 :               return NULL_RTX;
    5724                 :             : 
    5725                 :     4679666 :             switch (code)
    5726                 :             :               {
    5727                 :     2667340 :               case LSHIFTRT:
    5728                 :     2667340 :                 result = wi::lrshift (pop0, wop1);
    5729                 :     2667340 :                 break;
    5730                 :             : 
    5731                 :       57265 :               case ASHIFTRT:
    5732                 :       57265 :                 result = wi::arshift (pop0, wop1);
    5733                 :       57265 :                 break;
    5734                 :             : 
    5735                 :     1955061 :               case ASHIFT:
    5736                 :     1955061 :                 result = wi::lshift (pop0, wop1);
    5737                 :     1955061 :                 break;
    5738                 :             : 
    5739                 :           0 :               case SS_ASHIFT:
    5740                 :           0 :                 if (wi::leu_p (wop1, wi::clrsb (pop0)))
    5741                 :           0 :                   result = wi::lshift (pop0, wop1);
    5742                 :           0 :                 else if (wi::neg_p (pop0))
    5743                 :           0 :                   result = wi::min_value (int_mode, SIGNED);
    5744                 :             :                 else
    5745                 :           0 :                   result = wi::max_value (int_mode, SIGNED);
    5746                 :             :                 break;
    5747                 :             : 
    5748                 :           0 :               case US_ASHIFT:
    5749                 :           0 :                 if (wi::eq_p (pop0, 0))
    5750                 :           0 :                   result = pop0;
    5751                 :           0 :                 else if (wi::leu_p (wop1, wi::clz (pop0)))
    5752                 :           0 :                   result = wi::lshift (pop0, wop1);
    5753                 :             :                 else
    5754                 :           0 :                   result = wi::max_value (int_mode, UNSIGNED);
    5755                 :             :                 break;
    5756                 :             : 
    5757                 :           0 :               default:
    5758                 :           0 :                 gcc_unreachable ();
    5759                 :             :               }
    5760                 :     4679666 :             break;
    5761                 :     4679790 :           }
    5762                 :       33949 :         case ROTATE:
    5763                 :       33949 :         case ROTATERT:
    5764                 :       33949 :           {
    5765                 :             :             /* The rotate count might be in SImode while int_mode might
    5766                 :             :                be narrower.  On IA-64 it is even DImode.  If the shift
    5767                 :             :                count is too large and doesn't fit into int_mode, we'd
    5768                 :             :                ICE.  So, if int_mode is narrower than word, use
    5769                 :             :                word_mode for the shift count.  */
    5770                 :       33949 :             if (GET_MODE (op1) == VOIDmode
    5771                 :       42724 :                 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
    5772                 :       20047 :               pop1 = rtx_mode_t (op1, word_mode);
    5773                 :             : 
    5774                 :       33949 :             if (wi::neg_p (pop1))
    5775                 :             :               return NULL_RTX;
    5776                 :             : 
    5777                 :       33879 :             switch (code)
    5778                 :             :               {
    5779                 :       11399 :               case ROTATE:
    5780                 :       11399 :                 result = wi::lrotate (pop0, pop1);
    5781                 :       11399 :                 break;
    5782                 :             : 
    5783                 :       22480 :               case ROTATERT:
    5784                 :       22480 :                 result = wi::rrotate (pop0, pop1);
    5785                 :       22480 :                 break;
    5786                 :             : 
    5787                 :           0 :               default:
    5788                 :           0 :                 gcc_unreachable ();
    5789                 :             :               }
    5790                 :             :             break;
    5791                 :             :           }
    5792                 :             : 
    5793                 :        2270 :         case SS_PLUS:
    5794                 :        2270 :           result = wi::add (pop0, pop1, SIGNED, &overflow);
    5795                 :        4484 :  clamp_signed_saturation:
    5796                 :        4484 :           if (overflow == wi::OVF_OVERFLOW)
    5797                 :         314 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
    5798                 :        4170 :           else if (overflow == wi::OVF_UNDERFLOW)
    5799                 :         278 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
    5800                 :        3892 :           else if (overflow != wi::OVF_NONE)
    5801                 :             :             return NULL_RTX;
    5802                 :             :           break;
    5803                 :             : 
    5804                 :        2220 :         case US_PLUS:
    5805                 :        2220 :           result = wi::add (pop0, pop1, UNSIGNED, &overflow);
    5806                 :        2220 :  clamp_unsigned_saturation:
    5807                 :        2220 :           if (overflow != wi::OVF_NONE)
    5808                 :         461 :             result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    5809                 :             :           break;
    5810                 :             : 
    5811                 :        2214 :         case SS_MINUS:
    5812                 :        2214 :           result = wi::sub (pop0, pop1, SIGNED, &overflow);
    5813                 :        2214 :           goto clamp_signed_saturation;
    5814                 :             : 
    5815                 :        1852 :         case US_MINUS:
    5816                 :        1852 :           result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
    5817                 :        1852 :           if (overflow != wi::OVF_NONE)
    5818                 :        1203 :             result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
    5819                 :             :           break;
    5820                 :             : 
    5821                 :           0 :         case SS_MULT:
    5822                 :           0 :           result = wi::mul (pop0, pop1, SIGNED, &overflow);
    5823                 :           0 :           goto clamp_signed_saturation;
    5824                 :             : 
    5825                 :           0 :         case US_MULT:
    5826                 :           0 :           result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
    5827                 :           0 :           goto clamp_unsigned_saturation;
    5828                 :             : 
    5829                 :           8 :         case SMUL_HIGHPART:
    5830                 :           8 :           result = wi::mul_high (pop0, pop1, SIGNED);
    5831                 :           8 :           break;
    5832                 :             : 
    5833                 :           0 :         case UMUL_HIGHPART:
    5834                 :           0 :           result = wi::mul_high (pop0, pop1, UNSIGNED);
    5835                 :           0 :           break;
    5836                 :             : 
    5837                 :             :         default:
    5838                 :             :           return NULL_RTX;
    5839                 :             :         }
    5840                 :    33595478 :       return immed_wide_int_const (result, int_mode);
    5841                 :    33596207 :     }
    5842                 :             : 
    5843                 :             :   /* Handle polynomial integers.  */
    5844                 :             :   if (NUM_POLY_INT_COEFFS > 1
    5845                 :             :       && is_a <scalar_int_mode> (mode, &int_mode)
    5846                 :             :       && poly_int_rtx_p (op0)
    5847                 :             :       && poly_int_rtx_p (op1))
    5848                 :             :     {
    5849                 :             :       poly_wide_int result;
    5850                 :             :       switch (code)
    5851                 :             :         {
    5852                 :             :         case PLUS:
    5853                 :             :           result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
    5854                 :             :           break;
    5855                 :             : 
    5856                 :             :         case MINUS:
    5857                 :             :           result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
    5858                 :             :           break;
    5859                 :             : 
    5860                 :             :         case MULT:
    5861                 :             :           if (CONST_SCALAR_INT_P (op1))
    5862                 :             :             result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
    5863                 :             :           else
    5864                 :             :             return NULL_RTX;
    5865                 :             :           break;
    5866                 :             : 
    5867                 :             :         case ASHIFT:
    5868                 :             :           if (CONST_SCALAR_INT_P (op1))
    5869                 :             :             {
    5870                 :             :               wide_int shift
    5871                 :             :                 = rtx_mode_t (op1,
    5872                 :             :                               GET_MODE (op1) == VOIDmode
    5873                 :             :                               && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
    5874                 :             :                               ? word_mode : mode);
    5875                 :             :               if (SHIFT_COUNT_TRUNCATED)
    5876                 :             :                 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
    5877                 :             :               else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
    5878                 :             :                 return NULL_RTX;
    5879                 :             :               result = wi::to_poly_wide (op0, mode) << shift;
    5880                 :             :             }
    5881                 :             :           else
    5882                 :             :             return NULL_RTX;
    5883                 :             :           break;
    5884                 :             : 
    5885                 :             :         case IOR:
    5886                 :             :           if (!CONST_SCALAR_INT_P (op1)
    5887                 :             :               || !can_ior_p (wi::to_poly_wide (op0, mode),
    5888                 :             :                              rtx_mode_t (op1, mode), &result))
    5889                 :             :             return NULL_RTX;
    5890                 :             :           break;
    5891                 :             : 
    5892                 :             :         default:
    5893                 :             :           return NULL_RTX;
    5894                 :             :         }
    5895                 :             :       return immed_wide_int_const (result, int_mode);
    5896                 :             :     }
    5897                 :             : 
    5898                 :             :   return NULL_RTX;
    5899                 :             : }
    5900                 :             : 
    5901                 :             : 
    5902                 :             : 
    5903                 :             : /* Return a positive integer if X should sort after Y.  The value
    5904                 :             :    returned is 1 if and only if X and Y are both regs.  */
    5905                 :             : 
    5906                 :             : static int
    5907                 :   112954139 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
    5908                 :             : {
    5909                 :   112954139 :   int result;
    5910                 :             : 
    5911                 :   112954139 :   result = (commutative_operand_precedence (y)
    5912                 :   112954139 :             - commutative_operand_precedence (x));
    5913                 :   112954139 :   if (result)
    5914                 :    78900827 :     return result + result;
    5915                 :             : 
    5916                 :             :   /* Group together equal REGs to do more simplification.  */
    5917                 :    34053312 :   if (REG_P (x) && REG_P (y))
    5918                 :     8279786 :     return REGNO (x) > REGNO (y);
    5919                 :             : 
    5920                 :             :   return 0;
    5921                 :             : }
    5922                 :             : 
    5923                 :             : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
    5924                 :             :    operands may be another PLUS or MINUS.
    5925                 :             : 
    5926                 :             :    Rather than test for specific case, we do this by a brute-force method
    5927                 :             :    and do all possible simplifications until no more changes occur.  Then
    5928                 :             :    we rebuild the operation.
    5929                 :             : 
    5930                 :             :    May return NULL_RTX when no changes were made.  */
    5931                 :             : 
    5932                 :             : rtx
    5933                 :    37921908 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
    5934                 :             :                                        rtx op0, rtx op1)
    5935                 :             : {
    5936                 :    37921908 :   struct simplify_plus_minus_op_data
    5937                 :             :   {
    5938                 :             :     rtx op;
    5939                 :             :     short neg;
    5940                 :             :   } ops[16];
    5941                 :    37921908 :   rtx result, tem;
    5942                 :    37921908 :   int n_ops = 2;
    5943                 :    37921908 :   int changed, n_constants, canonicalized = 0;
    5944                 :    37921908 :   int i, j;
    5945                 :             : 
    5946                 :    37921908 :   memset (ops, 0, sizeof ops);
    5947                 :             : 
    5948                 :             :   /* Set up the two operands and then expand them until nothing has been
    5949                 :             :      changed.  If we run out of room in our array, give up; this should
    5950                 :             :      almost never happen.  */
    5951                 :             : 
    5952                 :    37921908 :   ops[0].op = op0;
    5953                 :    37921908 :   ops[0].neg = 0;
    5954                 :    37921908 :   ops[1].op = op1;
    5955                 :    37921908 :   ops[1].neg = (code == MINUS);
    5956                 :             : 
    5957                 :    77144752 :   do
    5958                 :             :     {
    5959                 :    77144752 :       changed = 0;
    5960                 :    77144752 :       n_constants = 0;
    5961                 :             : 
    5962                 :   312326005 :       for (i = 0; i < n_ops; i++)
    5963                 :             :         {
    5964                 :   235181267 :           rtx this_op = ops[i].op;
    5965                 :   235181267 :           int this_neg = ops[i].neg;
    5966                 :   235181267 :           enum rtx_code this_code = GET_CODE (this_op);
    5967                 :             : 
    5968                 :   235181267 :           switch (this_code)
    5969                 :             :             {
    5970                 :    38373673 :             case PLUS:
    5971                 :    38373673 :             case MINUS:
    5972                 :    38373673 :               if (n_ops == ARRAY_SIZE (ops))
    5973                 :             :                 return NULL_RTX;
    5974                 :             : 
    5975                 :    38373659 :               ops[n_ops].op = XEXP (this_op, 1);
    5976                 :    38373659 :               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
    5977                 :    38373659 :               n_ops++;
    5978                 :             : 
    5979                 :    38373659 :               ops[i].op = XEXP (this_op, 0);
    5980                 :    38373659 :               changed = 1;
    5981                 :             :               /* If this operand was negated then we will potentially
    5982                 :             :                  canonicalize the expression.  Similarly if we don't
    5983                 :             :                  place the operands adjacent we're re-ordering the
    5984                 :             :                  expression and thus might be performing a
    5985                 :             :                  canonicalization.  Ignore register re-ordering.
    5986                 :             :                  ??? It might be better to shuffle the ops array here,
    5987                 :             :                  but then (plus (plus (A, B), plus (C, D))) wouldn't
    5988                 :             :                  be seen as non-canonical.  */
    5989                 :    38373659 :               if (this_neg
    5990                 :    37650230 :                   || (i != n_ops - 2
    5991                 :    36972510 :                       && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
    5992                 :   235181253 :                 canonicalized = 1;
    5993                 :             :               break;
    5994                 :             : 
    5995                 :        1724 :             case NEG:
    5996                 :        1724 :               ops[i].op = XEXP (this_op, 0);
    5997                 :        1724 :               ops[i].neg = ! this_neg;
    5998                 :        1724 :               changed = 1;
    5999                 :        1724 :               canonicalized = 1;
    6000                 :        1724 :               break;
    6001                 :             : 
    6002                 :     1468618 :             case CONST:
    6003                 :     1468618 :               if (n_ops != ARRAY_SIZE (ops)
    6004                 :     1468618 :                   && GET_CODE (XEXP (this_op, 0)) == PLUS
    6005                 :     1349529 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
    6006                 :     1326312 :                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
    6007                 :             :                 {
    6008                 :     1326312 :                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
    6009                 :     1326312 :                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
    6010                 :     1326312 :                   ops[n_ops].neg = this_neg;
    6011                 :     1326312 :                   n_ops++;
    6012                 :     1326312 :                   changed = 1;
    6013                 :     1326312 :                   canonicalized = 1;
    6014                 :             :                 }
    6015                 :             :               break;
    6016                 :             : 
    6017                 :       40966 :             case NOT:
    6018                 :             :               /* ~a -> (-a - 1) */
    6019                 :       40966 :               if (n_ops != ARRAY_SIZE (ops))
    6020                 :             :                 {
    6021                 :       40966 :                   ops[n_ops].op = CONSTM1_RTX (mode);
    6022                 :       40966 :                   ops[n_ops++].neg = this_neg;
    6023                 :       40966 :                   ops[i].op = XEXP (this_op, 0);
    6024                 :       40966 :                   ops[i].neg = !this_neg;
    6025                 :       40966 :                   changed = 1;
    6026                 :       40966 :                   canonicalized = 1;
    6027                 :             :                 }
    6028                 :             :               break;
    6029                 :             : 
    6030                 :   119453453 :             CASE_CONST_SCALAR_INT:
    6031                 :   119453453 :             case CONST_POLY_INT:
    6032                 :   119453453 :               n_constants++;
    6033                 :   119453453 :               if (this_neg)
    6034                 :             :                 {
    6035                 :     1168142 :                   ops[i].op = neg_poly_int_rtx (mode, this_op);
    6036                 :     1168142 :                   ops[i].neg = 0;
    6037                 :     1168142 :                   changed = 1;
    6038                 :     1168142 :                   canonicalized = 1;
    6039                 :             :                 }
    6040                 :             :               break;
    6041                 :             : 
    6042                 :             :             default:
    6043                 :             :               break;
    6044                 :             :             }
    6045                 :             :         }
    6046                 :             :     }
    6047                 :    77144738 :   while (changed);
    6048                 :             : 
    6049                 :    37921894 :   if (n_constants > 1)
    6050                 :    24075191 :     canonicalized = 1;
    6051                 :             : 
    6052                 :    37921894 :   gcc_assert (n_ops >= 2);
    6053                 :             : 
    6054                 :             :   /* If we only have two operands, we can avoid the loops.  */
    6055                 :    37921894 :   if (n_ops == 2)
    6056                 :             :     {
    6057                 :           0 :       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
    6058                 :           0 :       rtx lhs, rhs;
    6059                 :             : 
    6060                 :             :       /* Get the two operands.  Be careful with the order, especially for
    6061                 :             :          the cases where code == MINUS.  */
    6062                 :           0 :       if (ops[0].neg && ops[1].neg)
    6063                 :             :         {
    6064                 :           0 :           lhs = gen_rtx_NEG (mode, ops[0].op);
    6065                 :           0 :           rhs = ops[1].op;
    6066                 :             :         }
    6067                 :           0 :       else if (ops[0].neg)
    6068                 :             :         {
    6069                 :           0 :           lhs = ops[1].op;
    6070                 :           0 :           rhs = ops[0].op;
    6071                 :             :         }
    6072                 :             :       else
    6073                 :             :         {
    6074                 :           0 :           lhs = ops[0].op;
    6075                 :           0 :           rhs = ops[1].op;
    6076                 :             :         }
    6077                 :             : 
    6078                 :           0 :       return simplify_const_binary_operation (code, mode, lhs, rhs);
    6079                 :             :     }
    6080                 :             : 
    6081                 :             :   /* Now simplify each pair of operands until nothing changes.  */
    6082                 :    62782580 :   while (1)
    6083                 :             :     {
    6084                 :             :       /* Insertion sort is good enough for a small array.  */
    6085                 :   165730899 :       for (i = 1; i < n_ops; i++)
    6086                 :             :         {
    6087                 :   102948319 :           struct simplify_plus_minus_op_data save;
    6088                 :   102948319 :           int cmp;
    6089                 :             : 
    6090                 :   102948319 :           j = i - 1;
    6091                 :   102948319 :           cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
    6092                 :   102948319 :           if (cmp <= 0)
    6093                 :    91189255 :             continue;
    6094                 :             :           /* Just swapping registers doesn't count as canonicalization.  */
    6095                 :    11759064 :           if (cmp != 1)
    6096                 :     8912842 :             canonicalized = 1;
    6097                 :             : 
    6098                 :    11759064 :           save = ops[i];
    6099                 :    14117258 :           do
    6100                 :    14117258 :             ops[j + 1] = ops[j];
    6101                 :    14117258 :           while (j--
    6102                 :    25876322 :                  && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
    6103                 :    11759064 :           ops[j + 1] = save;
    6104                 :             :         }
    6105                 :             : 
    6106                 :    62782580 :       changed = 0;
    6107                 :   165730899 :       for (i = n_ops - 1; i > 0; i--)
    6108                 :   246931796 :         for (j = i - 1; j >= 0; j--)
    6109                 :             :           {
    6110                 :   144792946 :             rtx lhs = ops[j].op, rhs = ops[i].op;
    6111                 :   144792946 :             int lneg = ops[j].neg, rneg = ops[i].neg;
    6112                 :             : 
    6113                 :   144792946 :             if (lhs != 0 && rhs != 0)
    6114                 :             :               {
    6115                 :   119150634 :                 enum rtx_code ncode = PLUS;
    6116                 :             : 
    6117                 :   119150634 :                 if (lneg != rneg)
    6118                 :             :                   {
    6119                 :    10149411 :                     ncode = MINUS;
    6120                 :    10149411 :                     if (lneg)
    6121                 :     6577574 :                       std::swap (lhs, rhs);
    6122                 :             :                   }
    6123                 :   109001223 :                 else if (swap_commutative_operands_p (lhs, rhs))
    6124                 :      208496 :                   std::swap (lhs, rhs);
    6125                 :             : 
    6126                 :   119150634 :                 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
    6127                 :    28409199 :                     && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
    6128                 :             :                   {
    6129                 :    24226428 :                     rtx tem_lhs, tem_rhs;
    6130                 :             : 
    6131                 :    24226428 :                     tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
    6132                 :    24226428 :                     tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
    6133                 :    24226428 :                     tem = simplify_binary_operation (ncode, mode, tem_lhs,
    6134                 :             :                                                      tem_rhs);
    6135                 :             : 
    6136                 :    24226428 :                     if (tem && !CONSTANT_P (tem))
    6137                 :        1742 :                       tem = gen_rtx_CONST (GET_MODE (tem), tem);
    6138                 :             :                   }
    6139                 :             :                 else
    6140                 :    94924206 :                   tem = simplify_binary_operation (ncode, mode, lhs, rhs);
    6141                 :             : 
    6142                 :    94925948 :                 if (tem)
    6143                 :             :                   {
    6144                 :             :                     /* Reject "simplifications" that just wrap the two
    6145                 :             :                        arguments in a CONST.  Failure to do so can result
    6146                 :             :                        in infinite recursion with simplify_binary_operation
    6147                 :             :                        when it calls us to simplify CONST operations.
    6148                 :             :                        Also, if we find such a simplification, don't try
    6149                 :             :                        any more combinations with this rhs:  We must have
    6150                 :             :                        something like symbol+offset, ie. one of the
    6151                 :             :                        trivial CONST expressions we handle later.  */
    6152                 :    26157203 :                     if (GET_CODE (tem) == CONST
    6153                 :      811211 :                         && GET_CODE (XEXP (tem, 0)) == ncode
    6154                 :      810663 :                         && XEXP (XEXP (tem, 0), 0) == lhs
    6155                 :      809469 :                         && XEXP (XEXP (tem, 0), 1) == rhs)
    6156                 :             :                       break;
    6157                 :    25347734 :                     lneg &= rneg;
    6158                 :    25347734 :                     if (GET_CODE (tem) == NEG)
    6159                 :       45134 :                       tem = XEXP (tem, 0), lneg = !lneg;
    6160                 :    25347734 :                     if (poly_int_rtx_p (tem) && lneg)
    6161                 :           0 :                       tem = neg_poly_int_rtx (mode, tem), lneg = 0;
    6162                 :             : 
    6163                 :    25347734 :                     ops[i].op = tem;
    6164                 :    25347734 :                     ops[i].neg = lneg;
    6165                 :    25347734 :                     ops[j].op = NULL_RTX;
    6166                 :    25347734 :                     changed = 1;
    6167                 :    25347734 :                     canonicalized = 1;
    6168                 :             :                   }
    6169                 :             :               }
    6170                 :             :           }
    6171                 :             : 
    6172                 :    62782580 :       if (!changed)
    6173                 :             :         break;
    6174                 :             : 
    6175                 :             :       /* Pack all the operands to the lower-numbered entries.  */
    6176                 :   100354790 :       for (i = 0, j = 0; j < n_ops; j++)
    6177                 :    75494104 :         if (ops[j].op)
    6178                 :             :           {
    6179                 :    50146370 :             ops[i] = ops[j];
    6180                 :    50146370 :             i++;
    6181                 :             :           }
    6182                 :             :       n_ops = i;
    6183                 :             :     }
    6184                 :             : 
    6185                 :             :   /* If nothing changed, check that rematerialization of rtl instructions
    6186                 :             :      is still required.  */
    6187                 :    37921894 :   if (!canonicalized)
    6188                 :             :     {
    6189                 :             :       /* Perform rematerialization if only all operands are registers and
    6190                 :             :          all operations are PLUS.  */
    6191                 :             :       /* ??? Also disallow (non-global, non-frame) fixed registers to work
    6192                 :             :          around rs6000 and how it uses the CA register.  See PR67145.  */
    6193                 :     4952891 :       for (i = 0; i < n_ops; i++)
    6194                 :     3989159 :         if (ops[i].neg
    6195                 :     3737774 :             || !REG_P (ops[i].op)
    6196                 :     7161426 :             || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
    6197                 :      309479 :                 && fixed_regs[REGNO (ops[i].op)]
    6198                 :         226 :                 && !global_regs[REGNO (ops[i].op)]
    6199                 :         226 :                 && ops[i].op != frame_pointer_rtx
    6200                 :         121 :                 && ops[i].op != arg_pointer_rtx
    6201                 :         107 :                 && ops[i].op != stack_pointer_rtx))
    6202                 :             :           return NULL_RTX;
    6203                 :      963732 :       goto gen_result;
    6204                 :             :     }
    6205                 :             : 
    6206                 :             :   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
    6207                 :    36141270 :   if (n_ops == 2
    6208                 :    23191407 :       && CONST_INT_P (ops[1].op)
    6209                 :    22740298 :       && CONSTANT_P (ops[0].op)
    6210                 :         210 :       && ops[0].neg)
    6211                 :         104 :     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
    6212                 :             : 
    6213                 :             :   /* We suppressed creation of trivial CONST expressions in the
    6214                 :             :      combination loop to avoid recursion.  Create one manually now.
    6215                 :             :      The combination loop should have ensured that there is exactly
    6216                 :             :      one CONST_INT, and the sort will have ensured that it is last
    6217                 :             :      in the array and that any other constant will be next-to-last.  */
    6218                 :             : 
    6219                 :    36141166 :   if (n_ops > 1
    6220                 :    35588320 :       && poly_int_rtx_p (ops[n_ops - 1].op)
    6221                 :    69554597 :       && CONSTANT_P (ops[n_ops - 2].op))
    6222                 :             :     {
    6223                 :     1394750 :       rtx value = ops[n_ops - 1].op;
    6224                 :     1394750 :       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
    6225                 :      671606 :         value = neg_poly_int_rtx (mode, value);
    6226                 :     1394750 :       if (CONST_INT_P (value))
    6227                 :             :         {
    6228                 :     2789500 :           ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
    6229                 :     1394750 :                                              INTVAL (value));
    6230                 :     1394750 :           n_ops--;
    6231                 :             :         }
    6232                 :             :     }
    6233                 :             : 
    6234                 :             :   /* Put a non-negated operand first, if possible.  */
    6235                 :             : 
    6236                 :    37814796 :   for (i = 0; i < n_ops && ops[i].neg; i++)
    6237                 :     1673630 :     continue;
    6238                 :    36141166 :   if (i == n_ops)
    6239                 :        9477 :     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
    6240                 :    36131689 :   else if (i != 0)
    6241                 :             :     {
    6242                 :     1573890 :       tem = ops[0].op;
    6243                 :     1573890 :       ops[0] = ops[i];
    6244                 :     1573890 :       ops[i].op = tem;
    6245                 :     1573890 :       ops[i].neg = 1;
    6246                 :             :     }
    6247                 :             : 
    6248                 :             :   /* Now make the result by performing the requested operations.  */
    6249                 :    34557799 :  gen_result:
    6250                 :    37104898 :   result = ops[0].op;
    6251                 :    86389363 :   for (i = 1; i < n_ops; i++)
    6252                 :    98568930 :     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
    6253                 :             :                              mode, result, ops[i].op);
    6254                 :             : 
    6255                 :             :   return result;
    6256                 :     1673630 : }
    6257                 :             : 
    6258                 :             : /* Check whether an operand is suitable for calling simplify_plus_minus.  */
    6259                 :             : static bool
    6260                 :   512074267 : plus_minus_operand_p (const_rtx x)
    6261                 :             : {
    6262                 :   512074267 :   return GET_CODE (x) == PLUS
    6263                 :   512074267 :          || GET_CODE (x) == MINUS
    6264                 :   512074267 :          || (GET_CODE (x) == CONST
    6265                 :     1835820 :              && GET_CODE (XEXP (x, 0)) == PLUS
    6266                 :     1240143 :              && CONSTANT_P (XEXP (XEXP (x, 0), 0))
    6267                 :     1163529 :              && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
    6268                 :             : }
    6269                 :             : 
    6270                 :             : /* Like simplify_binary_operation except used for relational operators.
    6271                 :             :    MODE is the mode of the result. If MODE is VOIDmode, both operands must
    6272                 :             :    not also be VOIDmode.
    6273                 :             : 
    6274                 :             :    CMP_MODE specifies in which mode the comparison is done in, so it is
    6275                 :             :    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
    6276                 :             :    the operands or, if both are VOIDmode, the operands are compared in
    6277                 :             :    "infinite precision".  */
    6278                 :             : rtx
    6279                 :   128186833 : simplify_context::simplify_relational_operation (rtx_code code,
    6280                 :             :                                                  machine_mode mode,
    6281                 :             :                                                  machine_mode cmp_mode,
    6282                 :             :                                                  rtx op0, rtx op1)
    6283                 :             : {
    6284                 :   128186833 :   rtx tem, trueop0, trueop1;
    6285                 :             : 
    6286                 :   128186833 :   if (cmp_mode == VOIDmode)
    6287                 :    28165932 :     cmp_mode = GET_MODE (op0);
    6288                 :    28165932 :   if (cmp_mode == VOIDmode)
    6289                 :      455140 :     cmp_mode = GET_MODE (op1);
    6290                 :             : 
    6291                 :   128186833 :   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
    6292                 :   128186833 :   if (tem)
    6293                 :      846080 :     return relational_result (mode, cmp_mode, tem);
    6294                 :             : 
    6295                 :             :   /* For the following tests, ensure const0_rtx is op1.  */
    6296                 :   127340753 :   if (swap_commutative_operands_p (op0, op1)
    6297                 :   127340753 :       || (op0 == const0_rtx && op1 != const0_rtx))
    6298                 :     2616404 :     std::swap (op0, op1), code = swap_condition (code);
    6299                 :             : 
    6300                 :             :   /* If op0 is a compare, extract the comparison arguments from it.  */
    6301                 :   127340753 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    6302                 :    13687336 :     return simplify_gen_relational (code, mode, VOIDmode,
    6303                 :    13687336 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6304                 :             : 
    6305                 :   113653417 :   if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
    6306                 :             :     return NULL_RTX;
    6307                 :             : 
    6308                 :    83407084 :   trueop0 = avoid_constant_pool_reference (op0);
    6309                 :    83407084 :   trueop1 = avoid_constant_pool_reference (op1);
    6310                 :    83407084 :   return simplify_relational_operation_1 (code, mode, cmp_mode,
    6311                 :    83407084 :                                           trueop0, trueop1);
    6312                 :             : }
    6313                 :             : 
    6314                 :             : /* This part of simplify_relational_operation is only used when CMP_MODE
    6315                 :             :    is not in class MODE_CC (i.e. it is a real comparison).
    6316                 :             : 
    6317                 :             :    MODE is the mode of the result, while CMP_MODE specifies in which
    6318                 :             :    mode the comparison is done in, so it is the mode of the operands.  */
    6319                 :             : 
    6320                 :             : rtx
    6321                 :    83407084 : simplify_context::simplify_relational_operation_1 (rtx_code code,
    6322                 :             :                                                    machine_mode mode,
    6323                 :             :                                                    machine_mode cmp_mode,
    6324                 :             :                                                    rtx op0, rtx op1)
    6325                 :             : {
    6326                 :    83407084 :   enum rtx_code op0code = GET_CODE (op0);
    6327                 :             : 
    6328                 :    83407084 :   if (op1 == const0_rtx && COMPARISON_P (op0))
    6329                 :             :     {
    6330                 :             :       /* If op0 is a comparison, extract the comparison arguments
    6331                 :             :          from it.  */
    6332                 :      469613 :       if (code == NE)
    6333                 :             :         {
    6334                 :      217036 :           if (GET_MODE (op0) == mode)
    6335                 :         164 :             return simplify_rtx (op0);
    6336                 :             :           else
    6337                 :      216872 :             return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
    6338                 :      216872 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6339                 :             :         }
    6340                 :      252577 :       else if (code == EQ)
    6341                 :             :         {
    6342                 :      127248 :           enum rtx_code new_code = reversed_comparison_code (op0, NULL);
    6343                 :      127248 :           if (new_code != UNKNOWN)
    6344                 :      126932 :             return simplify_gen_relational (new_code, mode, VOIDmode,
    6345                 :      126932 :                                             XEXP (op0, 0), XEXP (op0, 1));
    6346                 :             :         }
    6347                 :             :     }
    6348                 :             : 
    6349                 :             :   /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
    6350                 :             :      (GEU/LTU a -C).  Likewise for (LTU/GEU (PLUS a C) a).  */
    6351                 :    83063116 :   if ((code == LTU || code == GEU)
    6352                 :     4775530 :       && GET_CODE (op0) == PLUS
    6353                 :      670880 :       && CONST_INT_P (XEXP (op0, 1))
    6354                 :      448890 :       && (rtx_equal_p (op1, XEXP (op0, 0))
    6355                 :      330783 :           || rtx_equal_p (op1, XEXP (op0, 1)))
    6356                 :             :       /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
    6357                 :    83248524 :       && XEXP (op0, 1) != const0_rtx)
    6358                 :             :     {
    6359                 :      185408 :       rtx new_cmp
    6360                 :      185408 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6361                 :      187639 :       return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
    6362                 :      185408 :                                       cmp_mode, XEXP (op0, 0), new_cmp);
    6363                 :             :     }
    6364                 :             : 
    6365                 :             :   /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
    6366                 :             :      transformed into (LTU a -C).  */
    6367                 :    82877708 :   if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
    6368                 :      358816 :       && CONST_INT_P (XEXP (op0, 1))
    6369                 :      289457 :       && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
    6370                 :       28861 :       && XEXP (op0, 1) != const0_rtx)
    6371                 :             :     {
    6372                 :       28861 :       rtx new_cmp
    6373                 :       28861 :         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
    6374                 :       28861 :       return simplify_gen_relational (LTU, mode, cmp_mode,
    6375                 :       28861 :                                        XEXP (op0, 0), new_cmp);
    6376                 :             :     }
    6377                 :             : 
    6378                 :             :   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
    6379                 :    82848847 :   if ((code == LTU || code == GEU)
    6380                 :     4590122 :       && GET_CODE (op0) == PLUS
    6381                 :      485472 :       && rtx_equal_p (op1, XEXP (op0, 1))
    6382                 :             :       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
    6383                 :    82854048 :       && !rtx_equal_p (op1, XEXP (op0, 0)))
    6384                 :        5201 :     return simplify_gen_relational (code, mode, cmp_mode, op0,
    6385                 :        5201 :                                     copy_rtx (XEXP (op0, 0)));
    6386                 :             : 
    6387                 :    82843646 :   if (op1 == const0_rtx)
    6388                 :             :     {
    6389                 :             :       /* Canonicalize (GTU x 0) as (NE x 0).  */
    6390                 :    37212093 :       if (code == GTU)
    6391                 :      175368 :         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
    6392                 :             :       /* Canonicalize (LEU x 0) as (EQ x 0).  */
    6393                 :    37036725 :       if (code == LEU)
    6394                 :       50877 :         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
    6395                 :             :     }
    6396                 :    45631553 :   else if (op1 == const1_rtx)
    6397                 :             :     {
    6398                 :     3134547 :       switch (code)
    6399                 :             :         {
    6400                 :        8791 :         case GE:
    6401                 :             :           /* Canonicalize (GE x 1) as (GT x 0).  */
    6402                 :        8791 :           return simplify_gen_relational (GT, mode, cmp_mode,
    6403                 :        8791 :                                           op0, const0_rtx);
    6404                 :      174554 :         case GEU:
    6405                 :             :           /* Canonicalize (GEU x 1) as (NE x 0).  */
    6406                 :      174554 :           return simplify_gen_relational (NE, mode, cmp_mode,
    6407                 :      174554 :                                           op0, const0_rtx);
    6408                 :       10684 :         case LT:
    6409                 :             :           /* Canonicalize (LT x 1) as (LE x 0).  */
    6410                 :       10684 :           return simplify_gen_relational (LE, mode, cmp_mode,
    6411                 :       10684 :                                           op0, const0_rtx);
    6412                 :       43001 :         case LTU:
    6413                 :             :           /* Canonicalize (LTU x 1) as (EQ x 0).  */
    6414                 :       43001 :           return simplify_gen_relational (EQ, mode, cmp_mode,
    6415                 :       43001 :                                           op0, const0_rtx);
    6416                 :             :         default:
    6417                 :             :           break;
    6418                 :             :         }
    6419                 :             :     }
    6420                 :    42497006 :   else if (op1 == constm1_rtx)
    6421                 :             :     {
    6422                 :             :       /* Canonicalize (LE x -1) as (LT x 0).  */
    6423                 :     1153991 :       if (code == LE)
    6424                 :        1576 :         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
    6425                 :             :       /* Canonicalize (GT x -1) as (GE x 0).  */
    6426                 :     1152415 :       if (code == GT)
    6427                 :        4941 :         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
    6428                 :             :     }
    6429                 :             : 
    6430                 :             :   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
    6431                 :    82373854 :   if ((code == EQ || code == NE)
    6432                 :    62232031 :       && (op0code == PLUS || op0code == MINUS)
    6433                 :     2284582 :       && CONSTANT_P (op1)
    6434                 :      945608 :       && CONSTANT_P (XEXP (op0, 1))
    6435                 :      526122 :       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
    6436                 :             :     {
    6437                 :      526090 :       rtx x = XEXP (op0, 0);
    6438                 :      526090 :       rtx c = XEXP (op0, 1);
    6439                 :      526090 :       enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
    6440                 :      526090 :       rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
    6441                 :             : 
    6442                 :             :       /* Detect an infinite recursive condition, where we oscillate at this
    6443                 :             :          simplification case between:
    6444                 :             :             A + B == C  <--->  C - B == A,
    6445                 :             :          where A, B, and C are all constants with non-simplifiable expressions,
    6446                 :             :          usually SYMBOL_REFs.  */
    6447                 :      526090 :       if (GET_CODE (tem) == invcode
    6448                 :          46 :           && CONSTANT_P (x)
    6449                 :      526108 :           && rtx_equal_p (c, XEXP (tem, 1)))
    6450                 :             :         return NULL_RTX;
    6451                 :             : 
    6452                 :      526072 :       return simplify_gen_relational (code, mode, cmp_mode, x, tem);
    6453                 :             :     }
    6454                 :             : 
    6455                 :             :   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
    6456                 :             :      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
    6457                 :    61705941 :   scalar_int_mode int_mode, int_cmp_mode;
    6458                 :    61705941 :   if (code == NE
    6459                 :    32641489 :       && op1 == const0_rtx
    6460                 :     2192391 :       && is_int_mode (mode, &int_mode)
    6461                 :    81792965 :       && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
    6462                 :             :       /* ??? Work-around BImode bugs in the ia64 backend.  */
    6463                 :     2192391 :       && int_mode != BImode
    6464                 :     2192367 :       && int_cmp_mode != BImode
    6465                 :     2192367 :       && nonzero_bits (op0, int_cmp_mode) == 1
    6466                 :    61705941 :       && STORE_FLAG_VALUE == 1)
    6467                 :      109598 :     return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
    6468                 :       54799 :            ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
    6469                 :       22575 :            : lowpart_subreg (int_mode, op0, int_cmp_mode);
    6470                 :             : 
    6471                 :             :   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
    6472                 :    81792965 :   if ((code == EQ || code == NE)
    6473                 :    61651142 :       && op1 == const0_rtx
    6474                 :    33310724 :       && op0code == XOR)
    6475                 :       14122 :     return simplify_gen_relational (code, mode, cmp_mode,
    6476                 :       14122 :                                     XEXP (op0, 0), XEXP (op0, 1));
    6477                 :             : 
    6478                 :             :   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
    6479                 :    61637020 :   if ((code == EQ || code == NE)
    6480                 :    61637020 :       && op0code == XOR
    6481                 :        5309 :       && rtx_equal_p (XEXP (op0, 0), op1)
    6482                 :           0 :       && !side_effects_p (XEXP (op0, 0)))
    6483                 :           0 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
    6484                 :           0 :                                     CONST0_RTX (mode));
    6485                 :             : 
    6486                 :             :   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
    6487                 :    81778843 :   if ((code == EQ || code == NE)
    6488                 :    61637020 :       && op0code == XOR
    6489                 :        5309 :       && rtx_equal_p (XEXP (op0, 1), op1)
    6490                 :    81778977 :       && !side_effects_p (XEXP (op0, 1)))
    6491                 :         134 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6492                 :         134 :                                     CONST0_RTX (mode));
    6493                 :             : 
    6494                 :             :   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
    6495                 :    81778709 :   if ((code == EQ || code == NE)
    6496                 :    61636886 :       && op0code == XOR
    6497                 :        5175 :       && CONST_SCALAR_INT_P (op1)
    6498                 :        1918 :       && CONST_SCALAR_INT_P (XEXP (op0, 1)))
    6499                 :        1388 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6500                 :             :                                     simplify_gen_binary (XOR, cmp_mode,
    6501                 :        1388 :                                                          XEXP (op0, 1), op1));
    6502                 :             : 
    6503                 :             :   /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
    6504                 :             :      constant folding if x/y is a constant.  */
    6505                 :    61635498 :   if ((code == EQ || code == NE)
    6506                 :    61635498 :       && (op0code == AND || op0code == IOR)
    6507                 :     3903549 :       && !side_effects_p (op1)
    6508                 :     3903505 :       && op1 != CONST0_RTX (cmp_mode))
    6509                 :             :     {
    6510                 :             :       /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
    6511                 :             :          (eq/ne (and (not y) x) 0).  */
    6512                 :      516367 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
    6513                 :     1029664 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
    6514                 :             :         {
    6515                 :       25171 :           rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
    6516                 :             :                                           cmp_mode);
    6517                 :       25171 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
    6518                 :             : 
    6519                 :       25171 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6520                 :       25171 :                                           CONST0_RTX (cmp_mode));
    6521                 :             :         }
    6522                 :             : 
    6523                 :             :       /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
    6524                 :             :          (eq/ne (and (not x) y) 0).  */
    6525                 :      491264 :       if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
    6526                 :      962997 :           || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
    6527                 :             :         {
    6528                 :       41516 :           rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
    6529                 :             :                                           cmp_mode);
    6530                 :       41516 :           rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
    6531                 :             : 
    6532                 :       41516 :           return simplify_gen_relational (code, mode, cmp_mode, lhs,
    6533                 :       41516 :                                           CONST0_RTX (cmp_mode));
    6534                 :             :         }
    6535                 :             :     }
    6536                 :             : 
    6537                 :             :   /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped.  */
    6538                 :    81710634 :   if ((code == EQ || code == NE)
    6539                 :    61568811 :       && GET_CODE (op0) == BSWAP
    6540                 :         324 :       && CONST_SCALAR_INT_P (op1))
    6541                 :          93 :     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
    6542                 :             :                                     simplify_gen_unary (BSWAP, cmp_mode,
    6543                 :          93 :                                                         op1, cmp_mode));
    6544                 :             : 
    6545                 :             :   /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y).  */
    6546                 :    61568718 :   if ((code == EQ || code == NE)
    6547                 :    61568718 :       && GET_CODE (op0) == BSWAP
    6548                 :         231 :       && GET_CODE (op1) == BSWAP)
    6549                 :          18 :     return simplify_gen_relational (code, mode, cmp_mode,
    6550                 :          18 :                                     XEXP (op0, 0), XEXP (op1, 0));
    6551                 :             : 
    6552                 :    81710523 :   if (op0code == POPCOUNT && op1 == const0_rtx)
    6553                 :           0 :     switch (code)
    6554                 :             :       {
    6555                 :           0 :       case EQ:
    6556                 :           0 :       case LE:
    6557                 :           0 :       case LEU:
    6558                 :             :         /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
    6559                 :           0 :         return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
    6560                 :             :                                         XEXP (op0, 0),
    6561                 :           0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    6562                 :             : 
    6563                 :           0 :       case NE:
    6564                 :           0 :       case GT:
    6565                 :           0 :       case GTU:
    6566                 :             :         /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
    6567                 :           0 :         return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
    6568                 :             :                                         XEXP (op0, 0),
    6569                 :           0 :                                         CONST0_RTX (GET_MODE (XEXP (op0, 0))));
    6570                 :             : 
    6571                 :             :       default:
    6572                 :             :         break;
    6573                 :             :       }
    6574                 :             : 
    6575                 :             :   /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1).  */
    6576                 :    81710523 :   if (code == NE
    6577                 :    32542687 :       && op1 == const0_rtx
    6578                 :    16588072 :       && (op0code == TRUNCATE
    6579                 :      153079 :           || (partial_subreg_p (op0)
    6580                 :      152418 :               && subreg_lowpart_p (op0)))
    6581                 :      128674 :       && SCALAR_INT_MODE_P (mode)
    6582                 :    81710523 :       && STORE_FLAG_VALUE == 1)
    6583                 :             :     {
    6584                 :       29535 :       rtx tmp = XEXP (op0, 0);
    6585                 :       29535 :       if (GET_CODE (tmp) == ASHIFT
    6586                 :        1826 :           && GET_MODE (tmp) == mode
    6587                 :         188 :           && CONST_INT_P (XEXP (tmp, 1))
    6588                 :         188 :           && is_int_mode (GET_MODE (op0), &int_mode)
    6589                 :       29723 :           && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
    6590                 :         188 :         return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
    6591                 :             :     }
    6592                 :             : 
    6593                 :             :   /* For two unsigned booleans A and B:
    6594                 :             : 
    6595                 :             :      A >  B == ~B & A
    6596                 :             :      A >= B == ~B | A
    6597                 :             :      A <  B == ~A & B
    6598                 :             :      A <= B == ~A | B
    6599                 :             :      A == B == ~A ^ B (== ~B ^ A)
    6600                 :             :      A != B ==  A ^ B
    6601                 :             : 
    6602                 :             :      For signed comparisons, we have to take STORE_FLAG_VALUE into account,
    6603                 :             :      with the rules above applying for positive STORE_FLAG_VALUE and with
    6604                 :             :      the relations reversed for negative STORE_FLAG_VALUE.  */
    6605                 :    81710335 :   if (is_a<scalar_int_mode> (cmp_mode)
    6606                 :    79323176 :       && COMPARISON_P (op0)
    6607                 :    81775768 :       && COMPARISON_P (op1))
    6608                 :             :     {
    6609                 :        9906 :       rtx t = NULL_RTX;
    6610                 :        9906 :       if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
    6611                 :         755 :         t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
    6612                 :             :       else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
    6613                 :         720 :         t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
    6614                 :             :       else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
    6615                 :         720 :         t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
    6616                 :             :       else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
    6617                 :         720 :         t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
    6618                 :             :       else if (code == EQ)
    6619                 :        3194 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
    6620                 :             :       else if (code == NE)
    6621                 :        3797 :         t = simplify_logical_relational_operation (XOR, mode, op0, op1);
    6622                 :        9906 :       if (t)
    6623                 :             :         return t;
    6624                 :             :     }
    6625                 :             : 
    6626                 :             :   return NULL_RTX;
    6627                 :             : }
    6628                 :             : 
    6629                 :             : enum
    6630                 :             : {
    6631                 :             :   CMP_EQ = 1,
    6632                 :             :   CMP_LT = 2,
    6633                 :             :   CMP_GT = 4,
    6634                 :             :   CMP_LTU = 8,
    6635                 :             :   CMP_GTU = 16
    6636                 :             : };
    6637                 :             : 
    6638                 :             : 
    6639                 :             : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
    6640                 :             :    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
    6641                 :             :    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
    6642                 :             :    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
    6643                 :             :    For floating-point comparisons, assume that the operands were ordered.  */
    6644                 :             : 
    6645                 :             : static rtx
    6646                 :      681948 : comparison_result (enum rtx_code code, int known_results)
    6647                 :             : {
    6648                 :      681948 :   switch (code)
    6649                 :             :     {
    6650                 :      128883 :     case EQ:
    6651                 :      128883 :     case UNEQ:
    6652                 :      128883 :       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
    6653                 :      444813 :     case NE:
    6654                 :      444813 :     case LTGT:
    6655                 :      444813 :       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
    6656                 :             : 
    6657                 :        9530 :     case LT:
    6658                 :        9530 :     case UNLT:
    6659                 :        9530 :       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
    6660                 :        8554 :     case GE:
    6661                 :        8554 :     case UNGE:
    6662                 :        8554 :       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
    6663                 :             : 
    6664                 :       13029 :     case GT:
    6665                 :       13029 :     case UNGT:
    6666                 :       13029 :       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
    6667                 :       14539 :     case LE:
    6668                 :       14539 :     case UNLE:
    6669                 :       14539 :       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
    6670                 :             : 
    6671                 :       10246 :     case LTU:
    6672                 :       10246 :       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
    6673                 :        8997 :     case GEU:
    6674                 :        8997 :       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
    6675                 :             : 
    6676                 :       32728 :     case GTU:
    6677                 :       32728 :       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
    6678                 :       10621 :     case LEU:
    6679                 :       10621 :       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
    6680                 :             : 
    6681                 :           0 :     case ORDERED:
    6682                 :           0 :       return const_true_rtx;
    6683                 :           8 :     case UNORDERED:
    6684                 :           8 :       return const0_rtx;
    6685                 :           0 :     default:
    6686                 :           0 :       gcc_unreachable ();
    6687                 :             :     }
    6688                 :             : }
    6689                 :             : 
    6690                 :             : /* Check if the given comparison (done in the given MODE) is actually
    6691                 :             :    a tautology or a contradiction.  If the mode is VOIDmode, the
    6692                 :             :    comparison is done in "infinite precision".  If no simplification
    6693                 :             :    is possible, this function returns zero.  Otherwise, it returns
    6694                 :             :    either const_true_rtx or const0_rtx.  */
    6695                 :             : 
    6696                 :             : rtx
    6697                 :   128276977 : simplify_const_relational_operation (enum rtx_code code,
    6698                 :             :                                      machine_mode mode,
    6699                 :             :                                      rtx op0, rtx op1)
    6700                 :             : {
    6701                 :   134954624 :   rtx tem;
    6702                 :   134954624 :   rtx trueop0;
    6703                 :   134954624 :   rtx trueop1;
    6704                 :             : 
    6705                 :   134954624 :   gcc_assert (mode != VOIDmode
    6706                 :             :               || (GET_MODE (op0) == VOIDmode
    6707                 :             :                   && GET_MODE (op1) == VOIDmode));
    6708                 :             : 
    6709                 :             :   /* We only handle MODE_CC comparisons that are COMPARE against zero.  */
    6710                 :   134954624 :   if (GET_MODE_CLASS (mode) == MODE_CC
    6711                 :    43938415 :       && (op1 != const0_rtx
    6712                 :    43938415 :           || GET_CODE (op0) != COMPARE))
    6713                 :             :     return NULL_RTX;
    6714                 :             : 
    6715                 :             :   /* If op0 is a compare, extract the comparison arguments from it.  */
    6716                 :   104708291 :   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
    6717                 :             :     {
    6718                 :    13692082 :       op1 = XEXP (op0, 1);
    6719                 :    13692082 :       op0 = XEXP (op0, 0);
    6720                 :             : 
    6721                 :    13692082 :       if (GET_MODE (op0) != VOIDmode)
    6722                 :    13579212 :         mode = GET_MODE (op0);
    6723                 :      112870 :       else if (GET_MODE (op1) != VOIDmode)
    6724                 :      103378 :         mode = GET_MODE (op1);
    6725                 :             :       else
    6726                 :             :         return 0;
    6727                 :             :     }
    6728                 :             : 
    6729                 :             :   /* We can't simplify MODE_CC values since we don't know what the
    6730                 :             :      actual comparison is.  */
    6731                 :   104698799 :   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
    6732                 :             :     return 0;
    6733                 :             : 
    6734                 :             :   /* Make sure the constant is second.  */
    6735                 :   104698799 :   if (swap_commutative_operands_p (op0, op1))
    6736                 :             :     {
    6737                 :     3107844 :       std::swap (op0, op1);
    6738                 :     3107844 :       code = swap_condition (code);
    6739                 :             :     }
    6740                 :             : 
    6741                 :   104698799 :   trueop0 = avoid_constant_pool_reference (op0);
    6742                 :   104698799 :   trueop1 = avoid_constant_pool_reference (op1);
    6743                 :             : 
    6744                 :             :   /* For integer comparisons of A and B maybe we can simplify A - B and can
    6745                 :             :      then simplify a comparison of that with zero.  If A and B are both either
    6746                 :             :      a register or a CONST_INT, this can't help; testing for these cases will
    6747                 :             :      prevent infinite recursion here and speed things up.
    6748                 :             : 
    6749                 :             :      We can only do this for EQ and NE comparisons as otherwise we may
    6750                 :             :      lose or introduce overflow which we cannot disregard as undefined as
    6751                 :             :      we do not know the signedness of the operation on either the left or
    6752                 :             :      the right hand side of the comparison.  */
    6753                 :             : 
    6754                 :   104698799 :   if (INTEGRAL_MODE_P (mode)
    6755                 :   102389248 :       && trueop1 != CONST0_RTX (mode)
    6756                 :    51927045 :       && (code == EQ || code == NE)
    6757                 :    33368410 :       && ! ((REG_P (op0)
    6758                 :     9350032 :              || CONST_SCALAR_INT_P (trueop0)
    6759                 :     9324247 :              || CONST_VECTOR_P (trueop0))
    6760                 :    24044183 :             && (REG_P (op1)
    6761                 :    14377490 :                 || CONST_SCALAR_INT_P (trueop1)
    6762                 :     2970373 :                 || CONST_VECTOR_P (trueop1)))
    6763                 :    12292803 :       && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
    6764                 :             :       /* We cannot do this if tem is a nonzero address.  */
    6765                 :     6677649 :       && ! nonzero_address_p (tem))
    6766                 :     6677647 :     return simplify_const_relational_operation (signed_condition (code),
    6767                 :     6677647 :                                                 mode, tem, CONST0_RTX (mode));
    6768                 :             : 
    6769                 :    98021152 :   if (! HONOR_NANS (mode) && code == ORDERED)
    6770                 :           0 :     return const_true_rtx;
    6771                 :             : 
    6772                 :    98021152 :   if (! HONOR_NANS (mode) && code == UNORDERED)
    6773                 :           8 :     return const0_rtx;
    6774                 :             : 
    6775                 :             :   /* For modes without NaNs, if the two operands are equal, we know the
    6776                 :             :      result except if they have side-effects.  Even with NaNs we know
    6777                 :             :      the result of unordered comparisons and, if signaling NaNs are
    6778                 :             :      irrelevant, also the result of LT/GT/LTGT.  */
    6779                 :    98021144 :   if ((! HONOR_NANS (trueop0)
    6780                 :     2094762 :        || code == UNEQ || code == UNLE || code == UNGE
    6781                 :             :        || ((code == LT || code == GT || code == LTGT)
    6782                 :      831741 :            && ! HONOR_SNANS (trueop0)))
    6783                 :    96869516 :       && rtx_equal_p (trueop0, trueop1)
    6784                 :    98504848 :       && ! side_effects_p (trueop0))
    6785                 :      483696 :     return comparison_result (code, CMP_EQ);
    6786                 :             : 
    6787                 :             :   /* If the operands are floating-point constants, see if we can fold
    6788                 :             :      the result.  */
    6789                 :    97537448 :   if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
    6790                 :        1298 :       && CONST_DOUBLE_AS_FLOAT_P (trueop1)
    6791                 :        1298 :       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
    6792                 :             :     {
    6793                 :        1298 :       const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
    6794                 :        1298 :       const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
    6795                 :             : 
    6796                 :             :       /* Comparisons are unordered iff at least one of the values is NaN.  */
    6797                 :        1298 :       if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
    6798                 :         180 :         switch (code)
    6799                 :             :           {
    6800                 :           0 :           case UNEQ:
    6801                 :           0 :           case UNLT:
    6802                 :           0 :           case UNGT:
    6803                 :           0 :           case UNLE:
    6804                 :           0 :           case UNGE:
    6805                 :           0 :           case NE:
    6806                 :           0 :           case UNORDERED:
    6807                 :           0 :             return const_true_rtx;
    6808                 :         180 :           case EQ:
    6809                 :         180 :           case LT:
    6810                 :         180 :           case GT:
    6811                 :         180 :           case LE:
    6812                 :         180 :           case GE:
    6813                 :         180 :           case LTGT:
    6814                 :         180 :           case ORDERED:
    6815                 :         180 :             return const0_rtx;
    6816                 :             :           default:
    6817                 :             :             return 0;
    6818                 :             :           }
    6819                 :             : 
    6820                 :        1207 :       return comparison_result (code,
    6821                 :        1207 :                                 (real_equal (d0, d1) ? CMP_EQ :
    6822                 :        1207 :                                  real_less (d0, d1) ? CMP_LT : CMP_GT));
    6823                 :             :     }
    6824                 :             : 
    6825                 :             :   /* Otherwise, see if the operands are both integers.  */
    6826                 :    97536150 :   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
    6827                 :    94851402 :       && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
    6828                 :             :     {
    6829                 :             :       /* It would be nice if we really had a mode here.  However, the
    6830                 :             :          largest int representable on the target is as good as
    6831                 :             :          infinite.  */
    6832                 :      197134 :       machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
    6833                 :      197134 :       rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
    6834                 :      197134 :       rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
    6835                 :             : 
    6836                 :      197134 :       if (wi::eq_p (ptrueop0, ptrueop1))
    6837                 :           0 :         return comparison_result (code, CMP_EQ);
    6838                 :             :       else
    6839                 :             :         {
    6840                 :      197134 :           int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
    6841                 :      197134 :           cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
    6842                 :      197134 :           return comparison_result (code, cr);
    6843                 :             :         }
    6844                 :             :     }
    6845                 :             : 
    6846                 :             :   /* Optimize comparisons with upper and lower bounds.  */
    6847                 :    97339016 :   scalar_int_mode int_mode;
    6848                 :    97339016 :   if (CONST_INT_P (trueop1)
    6849                 :    69002112 :       && is_a <scalar_int_mode> (mode, &int_mode)
    6850                 :    69002112 :       && HWI_COMPUTABLE_MODE_P (int_mode)
    6851                 :   165811273 :       && !side_effects_p (trueop0))
    6852                 :             :     {
    6853                 :    68385135 :       int sign;
    6854                 :    68385135 :       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
    6855                 :    68385135 :       HOST_WIDE_INT val = INTVAL (trueop1);
    6856                 :    68385135 :       HOST_WIDE_INT mmin, mmax;
    6857                 :             : 
    6858                 :    68385135 :       if (code == GEU
    6859                 :    68385135 :           || code == LEU
    6860                 :    65366373 :           || code == GTU
    6861                 :    65366373 :           || code == LTU)
    6862                 :             :         sign = 0;
    6863                 :             :       else
    6864                 :    68385135 :         sign = 1;
    6865                 :             : 
    6866                 :             :       /* Get a reduced range if the sign bit is zero.  */
    6867                 :    68385135 :       if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
    6868                 :             :         {
    6869                 :     6844443 :           mmin = 0;
    6870                 :     6844443 :           mmax = nonzero;
    6871                 :             :         }
    6872                 :             :       else
    6873                 :             :         {
    6874                 :    61540692 :           rtx mmin_rtx, mmax_rtx;
    6875                 :    61540692 :           get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
    6876                 :             : 
    6877                 :    61540692 :           mmin = INTVAL (mmin_rtx);
    6878                 :    61540692 :           mmax = INTVAL (mmax_rtx);
    6879                 :    61540692 :           if (sign)
    6880                 :             :             {
    6881                 :    55949865 :               unsigned int sign_copies
    6882                 :    55949865 :                 = num_sign_bit_copies (trueop0, int_mode);
    6883                 :             : 
    6884                 :    55949865 :               mmin >>= (sign_copies - 1);
    6885                 :    55949865 :               mmax >>= (sign_copies - 1);
    6886                 :             :             }
    6887                 :             :         }
    6888                 :             : 
    6889                 :    68385135 :       switch (code)
    6890                 :             :         {
    6891                 :             :         /* x >= y is always true for y <= mmin, always false for y > mmax.  */
    6892                 :      481725 :         case GEU:
    6893                 :      481725 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    6894                 :       11190 :             return const_true_rtx;
    6895                 :      470535 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    6896                 :          48 :             return const0_rtx;
    6897                 :             :           break;
    6898                 :      931759 :         case GE:
    6899                 :      931759 :           if (val <= mmin)
    6900                 :        2254 :             return const_true_rtx;
    6901                 :      929505 :           if (val > mmax)
    6902                 :           0 :             return const0_rtx;
    6903                 :             :           break;
    6904                 :             : 
    6905                 :             :         /* x <= y is always true for y >= mmax, always false for y < mmin.  */
    6906                 :     2537037 :         case LEU:
    6907                 :     2537037 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    6908                 :       16951 :             return const_true_rtx;
    6909                 :     2520086 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    6910                 :           0 :             return const0_rtx;
    6911                 :             :           break;
    6912                 :     2022536 :         case LE:
    6913                 :     2022536 :           if (val >= mmax)
    6914                 :         434 :             return const_true_rtx;
    6915                 :     2022102 :           if (val < mmin)
    6916                 :           0 :             return const0_rtx;
    6917                 :             :           break;
    6918                 :             : 
    6919                 :    25699572 :         case EQ:
    6920                 :             :           /* x == y is always false for y out of range.  */
    6921                 :    25699572 :           if (val < mmin || val > mmax)
    6922                 :         408 :             return const0_rtx;
    6923                 :             :           break;
    6924                 :             : 
    6925                 :             :         /* x > y is always false for y >= mmax, always true for y < mmin.  */
    6926                 :     2428966 :         case GTU:
    6927                 :     2428966 :           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
    6928                 :      127716 :             return const0_rtx;
    6929                 :     2301250 :           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
    6930                 :           0 :             return const_true_rtx;
    6931                 :             :           break;
    6932                 :     1984050 :         case GT:
    6933                 :     1984050 :           if (val >= mmax)
    6934                 :         270 :             return const0_rtx;
    6935                 :     1983780 :           if (val < mmin)
    6936                 :           5 :             return const_true_rtx;
    6937                 :             :           break;
    6938                 :             : 
    6939                 :             :         /* x < y is always false for y <= mmin, always true for y > mmax.  */
    6940                 :      720945 :         case LTU:
    6941                 :      720945 :           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
    6942                 :        2741 :             return const0_rtx;
    6943                 :      718204 :           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
    6944                 :       85370 :             return const_true_rtx;
    6945                 :             :           break;
    6946                 :     1096057 :         case LT:
    6947                 :     1096057 :           if (val <= mmin)
    6948                 :        2301 :             return const0_rtx;
    6949                 :     1093756 :           if (val > mmax)
    6950                 :        3501 :             return const_true_rtx;
    6951                 :             :           break;
    6952                 :             : 
    6953                 :    30482488 :         case NE:
    6954                 :             :           /* x != y is always true for y out of range.  */
    6955                 :    30482488 :           if (val < mmin || val > mmax)
    6956                 :         145 :             return const_true_rtx;
    6957                 :             :           break;
    6958                 :             : 
    6959                 :             :         default:
    6960                 :             :           break;
    6961                 :             :         }
    6962                 :             :     }
    6963                 :             : 
    6964                 :             :   /* Optimize integer comparisons with zero.  */
    6965                 :    97085682 :   if (is_a <scalar_int_mode> (mode, &int_mode)
    6966                 :    94443459 :       && trueop1 == const0_rtx
    6967                 :    49749715 :       && !side_effects_p (trueop0))
    6968                 :             :     {
    6969                 :             :       /* Some addresses are known to be nonzero.  We don't know
    6970                 :             :          their sign, but equality comparisons are known.  */
    6971                 :    49661131 :       if (nonzero_address_p (trueop0))
    6972                 :             :         {
    6973                 :         552 :           if (code == EQ || code == LEU)
    6974                 :         297 :             return const0_rtx;
    6975                 :         255 :           if (code == NE || code == GTU)
    6976                 :         255 :             return const_true_rtx;
    6977                 :             :         }
    6978                 :             : 
    6979                 :             :       /* See if the first operand is an IOR with a constant.  If so, we
    6980                 :             :          may be able to determine the result of this comparison.  */
    6981                 :    49660579 :       if (GET_CODE (op0) == IOR)
    6982                 :             :         {
    6983                 :      599003 :           rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
    6984                 :      599003 :           if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
    6985                 :             :             {
    6986                 :         288 :               int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
    6987                 :         576 :               int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
    6988                 :         288 :                               && (UINTVAL (inner_const)
    6989                 :         288 :                                   & (HOST_WIDE_INT_1U
    6990                 :             :                                      << sign_bitnum)));
    6991                 :             : 
    6992                 :         288 :               switch (code)
    6993                 :             :                 {
    6994                 :             :                 case EQ:
    6995                 :             :                 case LEU:
    6996                 :             :                   return const0_rtx;
    6997                 :           4 :                 case NE:
    6998                 :           4 :                 case GTU:
    6999                 :           4 :                   return const_true_rtx;
    7000                 :          70 :                 case LT:
    7001                 :          70 :                 case LE:
    7002                 :          70 :                   if (has_sign)
    7003                 :           2 :                     return const_true_rtx;
    7004                 :             :                   break;
    7005                 :         210 :                 case GT:
    7006                 :         210 :                 case GE:
    7007                 :         210 :                   if (has_sign)
    7008                 :             :                     return const0_rtx;
    7009                 :             :                   break;
    7010                 :             :                 default:
    7011                 :             :                   break;
    7012                 :             :                 }
    7013                 :             :             }
    7014                 :             :         }
    7015                 :             :     }
    7016                 :             : 
    7017                 :             :   /* Optimize comparison of ABS with zero.  */
    7018                 :    50061684 :   if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
    7019                 :   147057799 :       && (GET_CODE (trueop0) == ABS
    7020                 :    49972348 :           || (GET_CODE (trueop0) == FLOAT_EXTEND
    7021                 :          34 :               && GET_CODE (XEXP (trueop0, 0)) == ABS)))
    7022                 :             :     {
    7023                 :         523 :       switch (code)
    7024                 :             :         {
    7025                 :          48 :         case LT:
    7026                 :             :           /* Optimize abs(x) < 0.0.  */
    7027                 :          48 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
    7028                 :           0 :             return const0_rtx;
    7029                 :             :           break;
    7030                 :             : 
    7031                 :          42 :         case GE:
    7032                 :             :           /* Optimize abs(x) >= 0.0.  */
    7033                 :          42 :           if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
    7034                 :           0 :             return const_true_rtx;
    7035                 :             :           break;
    7036                 :             : 
    7037                 :           0 :         case UNGE:
    7038                 :             :           /* Optimize ! (abs(x) < 0.0).  */
    7039                 :           0 :           return const_true_rtx;
    7040                 :             : 
    7041                 :             :         default:
    7042                 :             :           break;
    7043                 :             :         }
    7044                 :             :     }
    7045                 :             : 
    7046                 :             :   return 0;
    7047                 :             : }
    7048                 :             : 
    7049                 :             : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
    7050                 :             :    where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
    7051                 :             :    or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
    7052                 :             :    can be simplified to that or NULL_RTX if not.
    7053                 :             :    Assume X is compared against zero with CMP_CODE and the true
    7054                 :             :    arm is TRUE_VAL and the false arm is FALSE_VAL.  */
    7055                 :             : 
    7056                 :             : rtx
    7057                 :    30748301 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
    7058                 :             :                                          rtx true_val, rtx false_val)
    7059                 :             : {
    7060                 :    30748301 :   if (cmp_code != EQ && cmp_code != NE)
    7061                 :             :     return NULL_RTX;
    7062                 :             : 
    7063                 :             :   /* Result on X == 0 and X !=0 respectively.  */
    7064                 :    22491859 :   rtx on_zero, on_nonzero;
    7065                 :    22491859 :   if (cmp_code == EQ)
    7066                 :             :     {
    7067                 :             :       on_zero = true_val;
    7068                 :             :       on_nonzero = false_val;
    7069                 :             :     }
    7070                 :             :   else
    7071                 :             :     {
    7072                 :    11916283 :       on_zero = false_val;
    7073                 :    11916283 :       on_nonzero = true_val;
    7074                 :             :     }
    7075                 :             : 
    7076                 :    22491859 :   rtx_code op_code = GET_CODE (on_nonzero);
    7077                 :    22491859 :   if ((op_code != CLZ && op_code != CTZ)
    7078                 :        1805 :       || !rtx_equal_p (XEXP (on_nonzero, 0), x)
    7079                 :    22492778 :       || !CONST_INT_P (on_zero))
    7080                 :    22491572 :     return NULL_RTX;
    7081                 :             : 
    7082                 :         287 :   HOST_WIDE_INT op_val;
    7083                 :         287 :   scalar_int_mode mode ATTRIBUTE_UNUSED
    7084                 :         287 :     = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
    7085                 :           0 :   if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
    7086                 :         574 :        || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
    7087                 :         311 :       && op_val == INTVAL (on_zero))
    7088                 :             :     return on_nonzero;
    7089                 :             : 
    7090                 :             :   return NULL_RTX;
    7091                 :             : }
    7092                 :             : 
    7093                 :             : /* Try to simplify X given that it appears within operand OP of a
    7094                 :             :    VEC_MERGE operation whose mask is MASK.  X need not use the same
    7095                 :             :    vector mode as the VEC_MERGE, but it must have the same number of
    7096                 :             :    elements.
    7097                 :             : 
    7098                 :             :    Return the simplified X on success, otherwise return NULL_RTX.  */
    7099                 :             : 
    7100                 :             : rtx
    7101                 :     1497635 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
    7102                 :             : {
    7103                 :     1497635 :   gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
    7104                 :     2995270 :   poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
    7105                 :     1497635 :   if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
    7106                 :             :     {
    7107                 :        5144 :       if (side_effects_p (XEXP (x, 1 - op)))
    7108                 :             :         return NULL_RTX;
    7109                 :             : 
    7110                 :        4920 :       return XEXP (x, op);
    7111                 :             :     }
    7112                 :     1492491 :   if (UNARY_P (x)
    7113                 :      176074 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7114                 :     1549363 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
    7115                 :             :     {
    7116                 :       23867 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7117                 :       23867 :       if (top0)
    7118                 :         448 :         return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
    7119                 :         448 :                                    GET_MODE (XEXP (x, 0)));
    7120                 :             :     }
    7121                 :     1492043 :   if (BINARY_P (x)
    7122                 :      193416 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7123                 :      386734 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7124                 :      168351 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7125                 :     1762835 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
    7126                 :             :     {
    7127                 :      135396 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7128                 :      135396 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7129                 :      135396 :       if (top0 || top1)
    7130                 :             :         {
    7131                 :         790 :           if (COMPARISON_P (x))
    7132                 :           0 :             return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
    7133                 :           0 :                                             GET_MODE (XEXP (x, 0)) != VOIDmode
    7134                 :             :                                             ? GET_MODE (XEXP (x, 0))
    7135                 :           0 :                                             : GET_MODE (XEXP (x, 1)),
    7136                 :             :                                             top0 ? top0 : XEXP (x, 0),
    7137                 :           0 :                                             top1 ? top1 : XEXP (x, 1));
    7138                 :             :           else
    7139                 :         790 :             return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
    7140                 :             :                                         top0 ? top0 : XEXP (x, 0),
    7141                 :         790 :                                         top1 ? top1 : XEXP (x, 1));
    7142                 :             :         }
    7143                 :             :     }
    7144                 :     1491253 :   if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
    7145                 :       28952 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
    7146                 :       57904 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
    7147                 :       28952 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
    7148                 :       57904 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
    7149                 :       28952 :       && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
    7150                 :     1511031 :       && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
    7151                 :             :     {
    7152                 :        9889 :       rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
    7153                 :        9889 :       rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
    7154                 :        9889 :       rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
    7155                 :        9889 :       if (top0 || top1 || top2)
    7156                 :         448 :         return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
    7157                 :         448 :                                      GET_MODE (XEXP (x, 0)),
    7158                 :             :                                      top0 ? top0 : XEXP (x, 0),
    7159                 :             :                                      top1 ? top1 : XEXP (x, 1),
    7160                 :         448 :                                      top2 ? top2 : XEXP (x, 2));
    7161                 :             :     }
    7162                 :             :   return NULL_RTX;
    7163                 :             : }
    7164                 :             : 
    7165                 :             : 
    7166                 :             : /* Simplify CODE, an operation with result mode MODE and three operands,
    7167                 :             :    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
    7168                 :             :    a constant.  Return 0 if no simplifications is possible.  */
    7169                 :             : 
    7170                 :             : rtx
    7171                 :    41921321 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
    7172                 :             :                                               machine_mode op0_mode,
    7173                 :             :                                               rtx op0, rtx op1, rtx op2)
    7174                 :             : {
    7175                 :    41921321 :   bool any_change = false;
    7176                 :    41921321 :   rtx tem, trueop2;
    7177                 :    41921321 :   scalar_int_mode int_mode, int_op0_mode;
    7178                 :    41921321 :   unsigned int n_elts;
    7179                 :             : 
    7180                 :    41921321 :   switch (code)
    7181                 :             :     {
    7182                 :      336741 :     case FMA:
    7183                 :             :       /* Simplify negations around the multiplication.  */
    7184                 :             :       /* -a * -b + c  =>  a * b + c.  */
    7185                 :      336741 :       if (GET_CODE (op0) == NEG)
    7186                 :             :         {
    7187                 :       79913 :           tem = simplify_unary_operation (NEG, mode, op1, mode);
    7188                 :       79913 :           if (tem)
    7189                 :         231 :             op1 = tem, op0 = XEXP (op0, 0), any_change = true;
    7190                 :             :         }
    7191                 :      256828 :       else if (GET_CODE (op1) == NEG)
    7192                 :             :         {
    7193                 :        1026 :           tem = simplify_unary_operation (NEG, mode, op0, mode);
    7194                 :        1026 :           if (tem)
    7195                 :           0 :             op0 = tem, op1 = XEXP (op1, 0), any_change = true;
    7196                 :             :         }
    7197                 :             : 
    7198                 :             :       /* Canonicalize the two multiplication operands.  */
    7199                 :             :       /* a * -b + c  =>  -b * a + c.  */
    7200                 :      336741 :       if (swap_commutative_operands_p (op0, op1))
    7201                 :             :         std::swap (op0, op1), any_change = true;
    7202                 :             : 
    7203                 :      307839 :       if (any_change)
    7204                 :       29123 :         return gen_rtx_FMA (mode, op0, op1, op2);
    7205                 :             :       return NULL_RTX;
    7206                 :             : 
    7207                 :      651024 :     case SIGN_EXTRACT:
    7208                 :      651024 :     case ZERO_EXTRACT:
    7209                 :      651024 :       if (CONST_INT_P (op0)
    7210                 :       23222 :           && CONST_INT_P (op1)
    7211                 :       23222 :           && CONST_INT_P (op2)
    7212                 :    41921354 :           && is_a <scalar_int_mode> (mode, &int_mode)
    7213                 :          33 :           && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
    7214                 :      651057 :           && HWI_COMPUTABLE_MODE_P (int_mode))
    7215                 :             :         {
    7216                 :             :           /* Extracting a bit-field from a constant */
    7217                 :          33 :           unsigned HOST_WIDE_INT val = UINTVAL (op0);
    7218                 :          33 :           HOST_WIDE_INT op1val = INTVAL (op1);
    7219                 :          33 :           HOST_WIDE_INT op2val = INTVAL (op2);
    7220                 :          33 :           if (!BITS_BIG_ENDIAN)
    7221                 :          33 :             val >>= op2val;
    7222                 :             :           else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
    7223                 :             :             val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
    7224                 :             :           else
    7225                 :             :             /* Not enough information to calculate the bit position.  */
    7226                 :             :             break;
    7227                 :             : 
    7228                 :          33 :           if (HOST_BITS_PER_WIDE_INT != op1val)
    7229                 :             :             {
    7230                 :             :               /* First zero-extend.  */
    7231                 :          30 :               val &= (HOST_WIDE_INT_1U << op1val) - 1;
    7232                 :             :               /* If desired, propagate sign bit.  */
    7233                 :          30 :               if (code == SIGN_EXTRACT
    7234                 :           5 :                   && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
    7235                 :           5 :                      != 0)
    7236                 :           2 :                 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
    7237                 :             :             }
    7238                 :             : 
    7239                 :          33 :           return gen_int_mode (val, int_mode);
    7240                 :             :         }
    7241                 :             :       break;
    7242                 :             : 
    7243                 :    40230379 :     case IF_THEN_ELSE:
    7244                 :    40230379 :       if (CONST_INT_P (op0))
    7245                 :      285013 :         return op0 != const0_rtx ? op1 : op2;
    7246                 :             : 
    7247                 :             :       /* Convert c ? a : a into "a".  */
    7248                 :    40038521 :       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
    7249                 :             :         return op1;
    7250                 :             : 
    7251                 :             :       /* Convert a != b ? a : b into "a".  */
    7252                 :    40035080 :       if (GET_CODE (op0) == NE
    7253                 :    15652660 :           && ! side_effects_p (op0)
    7254                 :    15614897 :           && ! HONOR_NANS (mode)
    7255                 :    15610737 :           && ! HONOR_SIGNED_ZEROS (mode)
    7256                 :    55645817 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7257                 :       74462 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7258                 :    15610709 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7259                 :        4828 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7260                 :         123 :         return op1;
    7261                 :             : 
    7262                 :             :       /* Convert a == b ? a : b into "b".  */
    7263                 :    40034957 :       if (GET_CODE (op0) == EQ
    7264                 :    12965660 :           && ! side_effects_p (op0)
    7265                 :    12955357 :           && ! HONOR_NANS (mode)
    7266                 :    12854468 :           && ! HONOR_SIGNED_ZEROS (mode)
    7267                 :    52889425 :           && ((rtx_equal_p (XEXP (op0, 0), op1)
    7268                 :       14640 :                && rtx_equal_p (XEXP (op0, 1), op2))
    7269                 :    12854460 :               || (rtx_equal_p (XEXP (op0, 0), op2)
    7270                 :        8010 :                   && rtx_equal_p (XEXP (op0, 1), op1))))
    7271                 :          21 :         return op2;
    7272                 :             : 
    7273                 :             :       /* Convert a != 0 ? -a : 0 into "-a".  */
    7274                 :    40034936 :       if (GET_CODE (op0) == NE
    7275                 :    15652537 :           && ! side_effects_p (op0)
    7276                 :    15614774 :           && ! HONOR_NANS (mode)
    7277                 :    15610614 :           && ! HONOR_SIGNED_ZEROS (mode)
    7278                 :    15610614 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7279                 :    11912123 :           && op2 == CONST0_RTX (mode)
    7280                 :       96176 :           && GET_CODE (op1) == NEG
    7281                 :    40034987 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
    7282                 :             :         return op1;
    7283                 :             : 
    7284                 :             :       /* Convert a == 0 ? 0 : -a into "-a".  */
    7285                 :    40034931 :       if (GET_CODE (op0) == EQ
    7286                 :    12965639 :           && ! side_effects_p (op0)
    7287                 :    12955336 :           && ! HONOR_NANS (mode)
    7288                 :    12854447 :           && ! HONOR_SIGNED_ZEROS (mode)
    7289                 :    12854447 :           && op1 == CONST0_RTX (mode)
    7290                 :       33125 :           && XEXP (op0, 1) == CONST0_RTX (mode)
    7291                 :       15320 :           && GET_CODE (op2) == NEG
    7292                 :    40034935 :           && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
    7293                 :             :         return op2;
    7294                 :             : 
    7295                 :             :       /* Convert (!c) != {0,...,0} ? a : b into
    7296                 :             :          c != {0,...,0} ? b : a for vector modes.  */
    7297                 :    40034927 :       if (VECTOR_MODE_P (GET_MODE (op1))
    7298                 :       11868 :           && GET_CODE (op0) == NE
    7299                 :         511 :           && GET_CODE (XEXP (op0, 0)) == NOT
    7300                 :           0 :           && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
    7301                 :             :         {
    7302                 :           0 :           rtx cv = XEXP (op0, 1);
    7303                 :           0 :           int nunits;
    7304                 :           0 :           bool ok = true;
    7305                 :           0 :           if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
    7306                 :             :             ok = false;
    7307                 :             :           else
    7308                 :           0 :             for (int i = 0; i < nunits; ++i)
    7309                 :           0 :               if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
    7310                 :             :                 {
    7311                 :             :                   ok = false;
    7312                 :             :                   break;
    7313                 :             :                 }
    7314                 :           0 :           if (ok)
    7315                 :             :             {
    7316                 :           0 :               rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
    7317                 :             :                                         XEXP (XEXP (op0, 0), 0),
    7318                 :             :                                         XEXP (op0, 1));
    7319                 :           0 :               rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
    7320                 :           0 :               return retval;
    7321                 :             :             }
    7322                 :             :         }
    7323                 :             : 
    7324                 :             :       /* Convert x == 0 ? N : clz (x) into clz (x) when
    7325                 :             :          CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
    7326                 :             :          Similarly for ctz (x).  */
    7327                 :    40033761 :       if (COMPARISON_P (op0) && !side_effects_p (op0)
    7328                 :    79983806 :           && XEXP (op0, 1) == const0_rtx)
    7329                 :             :         {
    7330                 :    30748301 :           rtx simplified
    7331                 :    30748301 :             = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
    7332                 :             :                                      op1, op2);
    7333                 :    30748301 :           if (simplified)
    7334                 :             :             return simplified;
    7335                 :             :         }
    7336                 :             : 
    7337                 :    40034927 :       if (COMPARISON_P (op0) && ! side_effects_p (op0))
    7338                 :             :         {
    7339                 :    79967980 :           machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
    7340                 :    39948879 :                                         ? GET_MODE (XEXP (op0, 1))
    7341                 :             :                                         : GET_MODE (XEXP (op0, 0)));
    7342                 :    39948879 :           rtx temp;
    7343                 :             : 
    7344                 :             :           /* Look for happy constants in op1 and op2.  */
    7345                 :    39948879 :           if (CONST_INT_P (op1) && CONST_INT_P (op2))
    7346                 :             :             {
    7347                 :      208210 :               HOST_WIDE_INT t = INTVAL (op1);
    7348                 :      208210 :               HOST_WIDE_INT f = INTVAL (op2);
    7349                 :             : 
    7350                 :      208210 :               if (t == STORE_FLAG_VALUE && f == 0)
    7351                 :       53094 :                 code = GET_CODE (op0);
    7352                 :      155116 :               else if (t == 0 && f == STORE_FLAG_VALUE)
    7353                 :             :                 {
    7354                 :       31735 :                   enum rtx_code tmp;
    7355                 :       31735 :                   tmp = reversed_comparison_code (op0, NULL);
    7356                 :       31735 :                   if (tmp == UNKNOWN)
    7357                 :             :                     break;
    7358                 :             :                   code = tmp;
    7359                 :             :                 }
    7360                 :             :               else
    7361                 :             :                 break;
    7362                 :             : 
    7363                 :       79460 :               return simplify_gen_relational (code, mode, cmp_mode,
    7364                 :       79460 :                                               XEXP (op0, 0), XEXP (op0, 1));
    7365                 :             :             }
    7366                 :             : 
    7367                 :    39740669 :           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
    7368                 :             :                                                 cmp_mode, XEXP (op0, 0),
    7369                 :             :                                                 XEXP (op0, 1));
    7370                 :             : 
    7371                 :             :           /* See if any simplifications were possible.  */
    7372                 :    39740669 :           if (temp)
    7373                 :             :             {
    7374                 :        6767 :               if (CONST_INT_P (temp))
    7375                 :         864 :                 return temp == const0_rtx ? op2 : op1;
    7376                 :        5944 :               else if (temp)
    7377                 :        5944 :                 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
    7378                 :             :             }
    7379                 :             :         }
    7380                 :             :       break;
    7381                 :             : 
    7382                 :      703177 :     case VEC_MERGE:
    7383                 :      703177 :       gcc_assert (GET_MODE (op0) == mode);
    7384                 :      703177 :       gcc_assert (GET_MODE (op1) == mode);
    7385                 :      703177 :       gcc_assert (VECTOR_MODE_P (mode));
    7386                 :      703177 :       trueop2 = avoid_constant_pool_reference (op2);
    7387                 :      703177 :       if (CONST_INT_P (trueop2)
    7388                 :     1122656 :           && GET_MODE_NUNITS (mode).is_constant (&n_elts))
    7389                 :             :         {
    7390                 :      419479 :           unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
    7391                 :      419479 :           unsigned HOST_WIDE_INT mask;
    7392                 :      419479 :           if (n_elts == HOST_BITS_PER_WIDE_INT)
    7393                 :             :             mask = -1;
    7394                 :             :           else
    7395                 :      418355 :             mask = (HOST_WIDE_INT_1U << n_elts) - 1;
    7396                 :             : 
    7397                 :      419479 :           if (!(sel & mask) && !side_effects_p (op0))
    7398                 :             :             return op1;
    7399                 :      419042 :           if ((sel & mask) == mask && !side_effects_p (op1))
    7400                 :             :             return op0;
    7401                 :             : 
    7402                 :      408892 :           rtx trueop0 = avoid_constant_pool_reference (op0);
    7403                 :      408892 :           rtx trueop1 = avoid_constant_pool_reference (op1);
    7404                 :      408892 :           if (GET_CODE (trueop0) == CONST_VECTOR
    7405                 :        8615 :               && GET_CODE (trueop1) == CONST_VECTOR)
    7406                 :             :             {
    7407                 :        4574 :               rtvec v = rtvec_alloc (n_elts);
    7408                 :        4574 :               unsigned int i;
    7409                 :             : 
    7410                 :       52286 :               for (i = 0; i < n_elts; i++)
    7411                 :       43138 :                 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
    7412                 :       43138 :                                     ? CONST_VECTOR_ELT (trueop0, i)
    7413                 :       24052 :                                     : CONST_VECTOR_ELT (trueop1, i));
    7414                 :        4574 :               return gen_rtx_CONST_VECTOR (mode, v);
    7415                 :             :             }
    7416                 :             : 
    7417                 :      404318 :           if (swap_commutative_operands_p (op0, op1)
    7418                 :             :               /* Two operands have same precedence, then first bit of mask
    7419                 :             :                  select first operand.  */
    7420                 :      404318 :               || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
    7421                 :       29094 :             return simplify_gen_ternary (code, mode, mode, op1, op0,
    7422                 :       58188 :                                          GEN_INT (~sel & mask));
    7423                 :             : 
    7424                 :             :           /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
    7425                 :             :              if no element from a appears in the result.  */
    7426                 :      375224 :           if (GET_CODE (op0) == VEC_MERGE)
    7427                 :             :             {
    7428                 :       17056 :               tem = avoid_constant_pool_reference (XEXP (op0, 2));
    7429                 :       17056 :               if (CONST_INT_P (tem))
    7430                 :             :                 {
    7431                 :        1302 :                   unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
    7432                 :        1302 :                   if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
    7433                 :          99 :                     return simplify_gen_ternary (code, mode, mode,
    7434                 :          99 :                                                  XEXP (op0, 1), op1, op2);
    7435                 :        1203 :                   if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
    7436                 :         757 :                     return simplify_gen_ternary (code, mode, mode,
    7437                 :         757 :                                                  XEXP (op0, 0), op1, op2);
    7438                 :             :                 }
    7439                 :             :             }
    7440                 :      374368 :           if (GET_CODE (op1) == VEC_MERGE)
    7441                 :             :             {
    7442                 :         157 :               tem = avoid_constant_pool_reference (XEXP (op1, 2));
    7443                 :         157 :               if (CONST_INT_P (tem))
    7444                 :             :                 {
    7445                 :         142 :                   unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
    7446                 :         142 :                   if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
    7447                 :         113 :                     return simplify_gen_ternary (code, mode, mode,
    7448                 :         113 :                                                  op0, XEXP (op1, 1), op2);
    7449                 :          29 :                   if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
    7450                 :           2 :                     return simplify_gen_ternary (code, mode, mode,
    7451                 :           2 :                                                  op0, XEXP (op1, 0), op2);
    7452                 :             :                 }
    7453                 :             :             }
    7454                 :             : 
    7455                 :             :           /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
    7456                 :             :              with a.  */
    7457                 :      374253 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7458                 :      129753 :               && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
    7459                 :         620 :               && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
    7460                 :      375493 :               && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
    7461                 :             :             {
    7462                 :         552 :               tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
    7463                 :         552 :               if (CONST_INT_P (tem) && CONST_INT_P (op2))
    7464                 :             :                 {
    7465                 :         552 :                   if (XEXP (XEXP (op0, 0), 0) == op1
    7466                 :           2 :                       && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
    7467                 :             :                     return op1;
    7468                 :             :                 }
    7469                 :             :             }
    7470                 :             :           /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
    7471                 :             :              (const_int N))
    7472                 :             :              with (vec_concat (X) (B)) if N == 1 or
    7473                 :             :              (vec_concat (A) (X)) if N == 2.  */
    7474                 :      374251 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7475                 :      129751 :               && GET_CODE (op1) == CONST_VECTOR
    7476                 :      137572 :               && known_eq (CONST_VECTOR_NUNITS (op1), 2)
    7477                 :        1724 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7478                 :      375113 :               && IN_RANGE (sel, 1, 2))
    7479                 :             :             {
    7480                 :         860 :               rtx newop0 = XEXP (op0, 0);
    7481                 :         860 :               rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
    7482                 :         860 :               if (sel == 2)
    7483                 :         123 :                 std::swap (newop0, newop1);
    7484                 :         860 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7485                 :             :             }
    7486                 :             :           /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
    7487                 :             :              with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
    7488                 :             :              Only applies for vectors of two elements.  */
    7489                 :      373391 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7490                 :      128891 :               && GET_CODE (op1) == VEC_CONCAT
    7491                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7492                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7493                 :      373391 :               && IN_RANGE (sel, 1, 2))
    7494                 :             :             {
    7495                 :           0 :               rtx newop0 = XEXP (op0, 0);
    7496                 :           0 :               rtx newop1 = XEXP (op1, 2 - sel);
    7497                 :           0 :               rtx otherop = XEXP (op1, sel - 1);
    7498                 :           0 :               if (sel == 2)
    7499                 :           0 :                 std::swap (newop0, newop1);
    7500                 :             :               /* Don't want to throw away the other part of the vec_concat if
    7501                 :             :                  it has side-effects.  */
    7502                 :           0 :               if (!side_effects_p (otherop))
    7503                 :           0 :                 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7504                 :             :             }
    7505                 :             : 
    7506                 :             :           /* Replace:
    7507                 :             : 
    7508                 :             :               (vec_merge:outer (vec_duplicate:outer x:inner)
    7509                 :             :                                (subreg:outer y:inner 0)
    7510                 :             :                                (const_int N))
    7511                 :             : 
    7512                 :             :              with (vec_concat:outer x:inner y:inner) if N == 1,
    7513                 :             :              or (vec_concat:outer y:inner x:inner) if N == 2.
    7514                 :             : 
    7515                 :             :              Implicitly, this means we have a paradoxical subreg, but such
    7516                 :             :              a check is cheap, so make it anyway.
    7517                 :             : 
    7518                 :             :              Only applies for vectors of two elements.  */
    7519                 :      373391 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7520                 :      128891 :               && GET_CODE (op1) == SUBREG
    7521                 :       40576 :               && GET_MODE (op1) == GET_MODE (op0)
    7522                 :       40576 :               && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
    7523                 :           0 :               && paradoxical_subreg_p (op1)
    7524                 :           0 :               && subreg_lowpart_p (op1)
    7525                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7526                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7527                 :      373391 :               && IN_RANGE (sel, 1, 2))
    7528                 :             :             {
    7529                 :           0 :               rtx newop0 = XEXP (op0, 0);
    7530                 :           0 :               rtx newop1 = SUBREG_REG (op1);
    7531                 :           0 :               if (sel == 2)
    7532                 :           0 :                 std::swap (newop0, newop1);
    7533                 :           0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7534                 :             :             }
    7535                 :             : 
    7536                 :             :           /* Same as above but with switched operands:
    7537                 :             :                 Replace (vec_merge:outer (subreg:outer x:inner 0)
    7538                 :             :                                          (vec_duplicate:outer y:inner)
    7539                 :             :                                (const_int N))
    7540                 :             : 
    7541                 :             :              with (vec_concat:outer x:inner y:inner) if N == 1,
    7542                 :             :              or (vec_concat:outer y:inner x:inner) if N == 2.  */
    7543                 :      373391 :           if (GET_CODE (op1) == VEC_DUPLICATE
    7544                 :       26534 :               && GET_CODE (op0) == SUBREG
    7545                 :       23997 :               && GET_MODE (op0) == GET_MODE (op1)
    7546                 :       23997 :               && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
    7547                 :           0 :               && paradoxical_subreg_p (op0)
    7548                 :           0 :               && subreg_lowpart_p (op0)
    7549                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7550                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7551                 :      373391 :               && IN_RANGE (sel, 1, 2))
    7552                 :             :             {
    7553                 :           0 :               rtx newop0 = SUBREG_REG (op0);
    7554                 :           0 :               rtx newop1 = XEXP (op1, 0);
    7555                 :           0 :               if (sel == 2)
    7556                 :           0 :                 std::swap (newop0, newop1);
    7557                 :           0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7558                 :             :             }
    7559                 :             : 
    7560                 :             :           /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
    7561                 :             :                                  (const_int n))
    7562                 :             :              with (vec_concat x y) or (vec_concat y x) depending on value
    7563                 :             :              of N.  */
    7564                 :      373391 :           if (GET_CODE (op0) == VEC_DUPLICATE
    7565                 :      128891 :               && GET_CODE (op1) == VEC_DUPLICATE
    7566                 :         198 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
    7567                 :           0 :               && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
    7568                 :      373391 :               && IN_RANGE (sel, 1, 2))
    7569                 :             :             {
    7570                 :           0 :               rtx newop0 = XEXP (op0, 0);
    7571                 :           0 :               rtx newop1 = XEXP (op1, 0);
    7572                 :           0 :               if (sel == 2)
    7573                 :           0 :                 std::swap (newop0, newop1);
    7574                 :             : 
    7575                 :           0 :               return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
    7576                 :             :             }
    7577                 :             :         }
    7578                 :             : 
    7579                 :      657089 :       if (rtx_equal_p (op0, op1)
    7580                 :      657089 :           && !side_effects_p (op2) && !side_effects_p (op1))
    7581                 :             :         return op0;
    7582                 :             : 
    7583                 :      656815 :       if (!side_effects_p (op2))
    7584                 :             :         {
    7585                 :      653726 :           rtx top0
    7586                 :      653726 :             = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
    7587                 :      653726 :           rtx top1
    7588                 :      653726 :             = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
    7589                 :      653726 :           if (top0 || top1)
    7590                 :         787 :             return simplify_gen_ternary (code, mode, mode,
    7591                 :             :                                          top0 ? top0 : op0,
    7592                 :         633 :                                          top1 ? top1 : op1, op2);
    7593                 :             :         }
    7594                 :             : 
    7595                 :             :       break;
    7596                 :             : 
    7597                 :           0 :     default:
    7598                 :           0 :       gcc_unreachable ();
    7599                 :             :     }
    7600                 :             : 
    7601                 :             :   return 0;
    7602                 :             : }
    7603                 :             : 
    7604                 :             : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
    7605                 :             :    starting at byte FIRST_BYTE.  Return true on success and add the
    7606                 :             :    bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
    7607                 :             :    that the bytes follow target memory order.  Leave BYTES unmodified
    7608                 :             :    on failure.
    7609                 :             : 
    7610                 :             :    MODE is the mode of X.  The caller must reserve NUM_BYTES bytes in
    7611                 :             :    BYTES before calling this function.  */
    7612                 :             : 
    7613                 :             : bool
    7614                 :    13278870 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
    7615                 :             :                    unsigned int first_byte, unsigned int num_bytes)
    7616                 :             : {
    7617                 :             :   /* Check the mode is sensible.  */
    7618                 :    13278870 :   gcc_assert (GET_MODE (x) == VOIDmode
    7619                 :             :               ? is_a <scalar_int_mode> (mode)
    7620                 :             :               : mode == GET_MODE (x));
    7621                 :             : 
    7622                 :    13278870 :   if (GET_CODE (x) == CONST_VECTOR)
    7623                 :             :     {
    7624                 :             :       /* CONST_VECTOR_ELT follows target memory order, so no shuffling
    7625                 :             :          is necessary.  The only complication is that MODE_VECTOR_BOOL
    7626                 :             :          vectors can have several elements per byte.  */
    7627                 :      877608 :       unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    7628                 :             :                                                    GET_MODE_NUNITS (mode));
    7629                 :      438804 :       unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
    7630                 :      438804 :       if (elt_bits < BITS_PER_UNIT)
    7631                 :             :         {
    7632                 :             :           /* This is the only case in which elements can be smaller than
    7633                 :             :              a byte.  */
    7634                 :           0 :           gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    7635                 :           0 :           auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
    7636                 :           0 :           for (unsigned int i = 0; i < num_bytes; ++i)
    7637                 :             :             {
    7638                 :           0 :               target_unit value = 0;
    7639                 :           0 :               for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
    7640                 :             :                 {
    7641                 :           0 :                   if (INTVAL (CONST_VECTOR_ELT (x, elt)))
    7642                 :           0 :                     value |= mask << j;
    7643                 :           0 :                   elt += 1;
    7644                 :             :                 }
    7645                 :           0 :               bytes.quick_push (value);
    7646                 :             :             }
    7647                 :             :           return true;
    7648                 :             :         }
    7649                 :             : 
    7650                 :      438804 :       unsigned int start = bytes.length ();
    7651                 :      438804 :       unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
    7652                 :             :       /* Make FIRST_BYTE relative to ELT.  */
    7653                 :      438804 :       first_byte %= elt_bytes;
    7654                 :     2308443 :       while (num_bytes > 0)
    7655                 :             :         {
    7656                 :             :           /* Work out how many bytes we want from element ELT.  */
    7657                 :     1869639 :           unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
    7658                 :     3739278 :           if (!native_encode_rtx (GET_MODE_INNER (mode),
    7659                 :             :                                   CONST_VECTOR_ELT (x, elt), bytes,
    7660                 :             :                                   first_byte, chunk_bytes))
    7661                 :             :             {
    7662                 :           0 :               bytes.truncate (start);
    7663                 :           0 :               return false;
    7664                 :             :             }
    7665                 :     1869639 :           elt += 1;
    7666                 :     1869639 :           first_byte = 0;
    7667                 :     1869639 :           num_bytes -= chunk_bytes;
    7668                 :             :         }
    7669                 :             :       return true;
    7670                 :             :     }
    7671                 :             : 
    7672                 :             :   /* All subsequent cases are limited to scalars.  */
    7673                 :    12840066 :   scalar_mode smode;
    7674                 :    12871635 :   if (!is_a <scalar_mode> (mode, &smode))
    7675                 :             :     return false;
    7676                 :             : 
    7677                 :             :   /* Make sure that the region is in range.  */
    7678                 :    12840066 :   unsigned int end_byte = first_byte + num_bytes;
    7679                 :    12840066 :   unsigned int mode_bytes = GET_MODE_SIZE (smode);
    7680                 :    12840066 :   gcc_assert (end_byte <= mode_bytes);
    7681                 :             : 
    7682                 :    12840066 :   if (CONST_SCALAR_INT_P (x))
    7683                 :             :     {
    7684                 :             :       /* The target memory layout is affected by both BYTES_BIG_ENDIAN
    7685                 :             :          and WORDS_BIG_ENDIAN.  Use the subreg machinery to get the lsb
    7686                 :             :          position of each byte.  */
    7687                 :    12321645 :       rtx_mode_t value (x, smode);
    7688                 :    12321645 :       wide_int_ref value_wi (value);
    7689                 :    52595814 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    7690                 :             :         {
    7691                 :             :           /* Always constant because the inputs are.  */
    7692                 :    40274169 :           unsigned int lsb
    7693                 :    40274169 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    7694                 :             :           /* Operate directly on the encoding rather than using
    7695                 :             :              wi::extract_uhwi, so that we preserve the sign or zero
    7696                 :             :              extension for modes that are not a whole number of bits in
    7697                 :             :              size.  (Zero extension is only used for the combination of
    7698                 :             :              innermode == BImode && STORE_FLAG_VALUE == 1).  */
    7699                 :    40274169 :           unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
    7700                 :    40274169 :           unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
    7701                 :    40274169 :           unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
    7702                 :    40274169 :           bytes.quick_push (uhwi >> shift);
    7703                 :             :         }
    7704                 :    12321645 :       return true;
    7705                 :             :     }
    7706                 :             : 
    7707                 :      518421 :   if (CONST_DOUBLE_P (x))
    7708                 :             :     {
    7709                 :             :       /* real_to_target produces an array of integers in target memory order.
    7710                 :             :          All integers before the last one have 32 bits; the last one may
    7711                 :             :          have 32 bits or fewer, depending on whether the mode bitsize
    7712                 :             :          is divisible by 32.  Each of these integers is then laid out
    7713                 :             :          in target memory as any other integer would be.  */
    7714                 :      486852 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    7715                 :      486852 :       real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
    7716                 :             : 
    7717                 :             :       /* The (maximum) number of target bytes per element of el32.  */
    7718                 :      486852 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    7719                 :      486852 :       gcc_assert (bytes_per_el32 != 0);
    7720                 :             : 
    7721                 :             :       /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
    7722                 :             :          handling above.  */
    7723                 :     3373523 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    7724                 :             :         {
    7725                 :     2886671 :           unsigned int index = byte / bytes_per_el32;
    7726                 :     2886671 :           unsigned int subbyte = byte % bytes_per_el32;
    7727                 :     2886671 :           unsigned int int_bytes = MIN (bytes_per_el32,
    7728                 :             :                                         mode_bytes - index * bytes_per_el32);
    7729                 :             :           /* Always constant because the inputs are.  */
    7730                 :     2886671 :           unsigned int lsb
    7731                 :     2886671 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    7732                 :     2886671 :           bytes.quick_push ((unsigned long) el32[index] >> lsb);
    7733                 :             :         }
    7734                 :      486852 :       return true;
    7735                 :             :     }
    7736                 :             : 
    7737                 :       31569 :   if (GET_CODE (x) == CONST_FIXED)
    7738                 :             :     {
    7739                 :           0 :       for (unsigned int byte = first_byte; byte < end_byte; ++byte)
    7740                 :             :         {
    7741                 :             :           /* Always constant because the inputs are.  */
    7742                 :           0 :           unsigned int lsb
    7743                 :           0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    7744                 :           0 :           unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
    7745                 :           0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    7746                 :             :             {
    7747                 :           0 :               lsb -= HOST_BITS_PER_WIDE_INT;
    7748                 :           0 :               piece = CONST_FIXED_VALUE_HIGH (x);
    7749                 :             :             }
    7750                 :           0 :           bytes.quick_push (piece >> lsb);
    7751                 :             :         }
    7752                 :             :       return true;
    7753                 :             :     }
    7754                 :             : 
    7755                 :             :   return false;
    7756                 :             : }
    7757                 :             : 
    7758                 :             : /* Read a vector of mode MODE from the target memory image given by BYTES,
    7759                 :             :    starting at byte FIRST_BYTE.  The vector is known to be encodable using
    7760                 :             :    NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
    7761                 :             :    and BYTES is known to have enough bytes to supply NPATTERNS *
    7762                 :             :    NELTS_PER_PATTERN vector elements.  Each element of BYTES contains
    7763                 :             :    BITS_PER_UNIT bits and the bytes are in target memory order.
    7764                 :             : 
    7765                 :             :    Return the vector on success, otherwise return NULL_RTX.  */
    7766                 :             : 
    7767                 :             : rtx
    7768                 :      184593 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
    7769                 :             :                           unsigned int first_byte, unsigned int npatterns,
    7770                 :             :                           unsigned int nelts_per_pattern)
    7771                 :             : {
    7772                 :      184593 :   rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
    7773                 :             : 
    7774                 :      369186 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    7775                 :             :                                                GET_MODE_NUNITS (mode));
    7776                 :      184593 :   if (elt_bits < BITS_PER_UNIT)
    7777                 :             :     {
    7778                 :             :       /* This is the only case in which elements can be smaller than a byte.
    7779                 :             :          Element 0 is always in the lsb of the containing byte.  */
    7780                 :           0 :       gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
    7781                 :           0 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    7782                 :             :         {
    7783                 :           0 :           unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
    7784                 :           0 :           unsigned int byte_index = bit_index / BITS_PER_UNIT;
    7785                 :           0 :           unsigned int lsb = bit_index % BITS_PER_UNIT;
    7786                 :           0 :           unsigned int value = bytes[byte_index] >> lsb;
    7787                 :           0 :           builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
    7788                 :             :         }
    7789                 :             :     }
    7790                 :             :   else
    7791                 :             :     {
    7792                 :      720579 :       for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    7793                 :             :         {
    7794                 :     1071972 :           rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
    7795                 :      535986 :           if (!x)
    7796                 :           0 :             return NULL_RTX;
    7797                 :      535986 :           builder.quick_push (x);
    7798                 :      535986 :           first_byte += elt_bits / BITS_PER_UNIT;
    7799                 :             :         }
    7800                 :             :     }
    7801                 :      184593 :   return builder.build ();
    7802                 :      184593 : }
    7803                 :             : 
    7804                 :             : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
    7805                 :             :    of target memory image BYTES.  */
    7806                 :             : 
    7807                 :             : wide_int
    7808                 :    11489808 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
    7809                 :             :                    unsigned int size, unsigned int precision)
    7810                 :             : {
    7811                 :             :   /* Pull the bytes msb first, so that we can use simple
    7812                 :             :      shift-and-insert wide_int operations.  */
    7813                 :    11489808 :   wide_int result (wi::zero (precision));
    7814                 :    52541501 :   for (unsigned int i = 0; i < size; ++i)
    7815                 :             :     {
    7816                 :    41051693 :       unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
    7817                 :             :       /* Always constant because the inputs are.  */
    7818                 :    41051693 :       unsigned int subbyte
    7819                 :    41051693 :         = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
    7820                 :    41051693 :       result <<= BITS_PER_UNIT;
    7821                 :    41051693 :       result |= bytes[first_byte + subbyte];
    7822                 :             :     }
    7823                 :    11489808 :   return result;
    7824                 :             : }
    7825                 :             : 
    7826                 :             : /* Read an rtx of mode MODE from the target memory image given by BYTES,
    7827                 :             :    starting at byte FIRST_BYTE.  Each element of BYTES contains BITS_PER_UNIT
    7828                 :             :    bits and the bytes are in target memory order.  The image has enough
    7829                 :             :    values to specify all bytes of MODE.
    7830                 :             : 
    7831                 :             :    Return the rtx on success, otherwise return NULL_RTX.  */
    7832                 :             : 
    7833                 :             : rtx
    7834                 :    11619345 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
    7835                 :             :                    unsigned int first_byte)
    7836                 :             : {
    7837                 :    11619345 :   if (VECTOR_MODE_P (mode))
    7838                 :             :     {
    7839                 :             :       /* If we know at compile time how many elements there are,
    7840                 :             :          pull each element directly from BYTES.  */
    7841                 :       24966 :       unsigned int nelts;
    7842                 :       49932 :       if (GET_MODE_NUNITS (mode).is_constant (&nelts))
    7843                 :       24966 :         return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
    7844                 :             :       return NULL_RTX;
    7845                 :             :     }
    7846                 :             : 
    7847                 :    11594379 :   scalar_int_mode imode;
    7848                 :    11594379 :   if (is_a <scalar_int_mode> (mode, &imode)
    7849                 :    11489808 :       && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
    7850                 :             :     {
    7851                 :    11489808 :       auto result = native_decode_int (bytes, first_byte,
    7852                 :    11489808 :                                        GET_MODE_SIZE (imode),
    7853                 :    22979616 :                                        GET_MODE_PRECISION (imode));
    7854                 :    11489808 :       return immed_wide_int_const (result, imode);
    7855                 :    11489808 :     }
    7856                 :             : 
    7857                 :      104571 :   scalar_float_mode fmode;
    7858                 :      104571 :   if (is_a <scalar_float_mode> (mode, &fmode))
    7859                 :             :     {
    7860                 :             :       /* We need to build an array of integers in target memory order.
    7861                 :             :          All integers before the last one have 32 bits; the last one may
    7862                 :             :          have 32 bits or fewer, depending on whether the mode bitsize
    7863                 :             :          is divisible by 32.  */
    7864                 :      104541 :       long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
    7865                 :      104541 :       unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
    7866                 :      104541 :       memset (el32, 0, num_el32 * sizeof (long));
    7867                 :             : 
    7868                 :             :       /* The (maximum) number of target bytes per element of el32.  */
    7869                 :      104541 :       unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
    7870                 :      104541 :       gcc_assert (bytes_per_el32 != 0);
    7871                 :             : 
    7872                 :      104541 :       unsigned int mode_bytes = GET_MODE_SIZE (fmode);
    7873                 :      771353 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    7874                 :             :         {
    7875                 :      666812 :           unsigned int index = byte / bytes_per_el32;
    7876                 :      666812 :           unsigned int subbyte = byte % bytes_per_el32;
    7877                 :      666812 :           unsigned int int_bytes = MIN (bytes_per_el32,
    7878                 :             :                                         mode_bytes - index * bytes_per_el32);
    7879                 :             :           /* Always constant because the inputs are.  */
    7880                 :      666812 :           unsigned int lsb
    7881                 :      666812 :             = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
    7882                 :      666812 :           el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
    7883                 :             :         }
    7884                 :      104541 :       REAL_VALUE_TYPE r;
    7885                 :      104541 :       real_from_target (&r, el32, fmode);
    7886                 :      104541 :       return const_double_from_real_value (r, fmode);
    7887                 :             :     }
    7888                 :             : 
    7889                 :          30 :   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
    7890                 :             :     {
    7891                 :           0 :       scalar_mode smode = as_a <scalar_mode> (mode);
    7892                 :           0 :       FIXED_VALUE_TYPE f;
    7893                 :           0 :       f.data.low = 0;
    7894                 :           0 :       f.data.high = 0;
    7895                 :           0 :       f.mode = smode;
    7896                 :             : 
    7897                 :           0 :       unsigned int mode_bytes = GET_MODE_SIZE (smode);
    7898                 :           0 :       for (unsigned int byte = 0; byte < mode_bytes; ++byte)
    7899                 :             :         {
    7900                 :             :           /* Always constant because the inputs are.  */
    7901                 :           0 :           unsigned int lsb
    7902                 :           0 :             = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
    7903                 :           0 :           unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
    7904                 :           0 :           if (lsb >= HOST_BITS_PER_WIDE_INT)
    7905                 :           0 :             f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
    7906                 :             :           else
    7907                 :           0 :             f.data.low |= unit << lsb;
    7908                 :             :         }
    7909                 :           0 :       return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
    7910                 :             :     }
    7911                 :             : 
    7912                 :             :   return NULL_RTX;
    7913                 :             : }
    7914                 :             : 
    7915                 :             : /* Simplify a byte offset BYTE into CONST_VECTOR X.  The main purpose
    7916                 :             :    is to convert a runtime BYTE value into a constant one.  */
    7917                 :             : 
    7918                 :             : static poly_uint64
    7919                 :      259597 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
    7920                 :             : {
    7921                 :             :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    7922                 :      259597 :   machine_mode mode = GET_MODE (x);
    7923                 :      519194 :   unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
    7924                 :             :                                                GET_MODE_NUNITS (mode));
    7925                 :             :   /* The number of bits needed to encode one element from each pattern.  */
    7926                 :      259597 :   unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
    7927                 :             : 
    7928                 :             :   /* Identify the start point in terms of a sequence number and a byte offset
    7929                 :             :      within that sequence.  */
    7930                 :      259597 :   poly_uint64 first_sequence;
    7931                 :      259597 :   unsigned HOST_WIDE_INT subbit;
    7932                 :      259597 :   if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
    7933                 :             :                        &first_sequence, &subbit))
    7934                 :             :     {
    7935                 :      259597 :       unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    7936                 :      259597 :       if (nelts_per_pattern == 1)
    7937                 :             :         /* This is a duplicated vector, so the value of FIRST_SEQUENCE
    7938                 :             :            doesn't matter.  */
    7939                 :      210711 :         byte = subbit / BITS_PER_UNIT;
    7940                 :       48886 :       else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
    7941                 :             :         {
    7942                 :             :           /* The subreg drops the first element from each pattern and
    7943                 :             :              only uses the second element.  Find the first sequence
    7944                 :             :              that starts on a byte boundary.  */
    7945                 :        5568 :           subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
    7946                 :        5568 :           byte = subbit / BITS_PER_UNIT;
    7947                 :             :         }
    7948                 :             :     }
    7949                 :      259597 :   return byte;
    7950                 :             : }
    7951                 :             : 
    7952                 :             : /* Subroutine of simplify_subreg in which:
    7953                 :             : 
    7954                 :             :    - X is known to be a CONST_VECTOR
    7955                 :             :    - OUTERMODE is known to be a vector mode
    7956                 :             : 
    7957                 :             :    Try to handle the subreg by operating on the CONST_VECTOR encoding
    7958                 :             :    rather than on each individual element of the CONST_VECTOR.
    7959                 :             : 
    7960                 :             :    Return the simplified subreg on success, otherwise return NULL_RTX.  */
    7961                 :             : 
    7962                 :             : static rtx
    7963                 :      167128 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
    7964                 :             :                               machine_mode innermode, unsigned int first_byte)
    7965                 :             : {
    7966                 :             :   /* Paradoxical subregs of vectors have dubious semantics.  */
    7967                 :      167128 :   if (paradoxical_subreg_p (outermode, innermode))
    7968                 :             :     return NULL_RTX;
    7969                 :             : 
    7970                 :             :   /* We can only preserve the semantics of a stepped pattern if the new
    7971                 :             :      vector element is the same as the original one.  */
    7972                 :      167056 :   if (CONST_VECTOR_STEPPED_P (x)
    7973                 :      187138 :       && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
    7974                 :             :     return NULL_RTX;
    7975                 :             : 
    7976                 :             :   /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes.  */
    7977                 :      159627 :   unsigned int x_elt_bits
    7978                 :      159627 :     = vector_element_size (GET_MODE_PRECISION (innermode),
    7979                 :             :                            GET_MODE_NUNITS (innermode));
    7980                 :      159627 :   unsigned int out_elt_bits
    7981                 :      159627 :     = vector_element_size (GET_MODE_PRECISION (outermode),
    7982                 :             :                            GET_MODE_NUNITS (outermode));
    7983                 :             : 
    7984                 :             :   /* The number of bits needed to encode one element from every pattern
    7985                 :             :      of the original vector.  */
    7986                 :      159627 :   unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
    7987                 :             : 
    7988                 :             :   /* The number of bits needed to encode one element from every pattern
    7989                 :             :      of the result.  */
    7990                 :      159627 :   unsigned int out_sequence_bits
    7991                 :      159627 :     = least_common_multiple (x_sequence_bits, out_elt_bits);
    7992                 :             : 
    7993                 :             :   /* Work out the number of interleaved patterns in the output vector
    7994                 :             :      and the number of encoded elements per pattern.  */
    7995                 :      159627 :   unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
    7996                 :      159627 :   unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
    7997                 :             : 
    7998                 :             :   /* The encoding scheme requires the number of elements to be a multiple
    7999                 :             :      of the number of patterns, so that each pattern appears at least once
    8000                 :             :      and so that the same number of elements appear from each pattern.  */
    8001                 :      319254 :   bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
    8002                 :      159627 :   unsigned int const_nunits;
    8003                 :      319254 :   if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
    8004                 :      159627 :       && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
    8005                 :             :     {
    8006                 :             :       /* Either the encoding is invalid, or applying it would give us
    8007                 :             :          more elements than we need.  Just encode each element directly.  */
    8008                 :             :       out_npatterns = const_nunits;
    8009                 :             :       nelts_per_pattern = 1;
    8010                 :             :     }
    8011                 :             :   else if (!ok_p)
    8012                 :             :     return NULL_RTX;
    8013                 :             : 
    8014                 :             :   /* Get enough bytes of X to form the new encoding.  */
    8015                 :      159627 :   unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
    8016                 :      159627 :   unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
    8017                 :      159627 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8018                 :      159627 :   if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
    8019                 :             :     return NULL_RTX;
    8020                 :             : 
    8021                 :             :   /* Reencode the bytes as OUTERMODE.  */
    8022                 :      159627 :   return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
    8023                 :      159627 :                                    nelts_per_pattern);
    8024                 :      159627 : }
    8025                 :             : 
    8026                 :             : /* Try to simplify a subreg of a constant by encoding the subreg region
    8027                 :             :    as a sequence of target bytes and reading them back in the new mode.
    8028                 :             :    Return the new value on success, otherwise return null.
    8029                 :             : 
    8030                 :             :    The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
    8031                 :             :    and byte offset FIRST_BYTE.  */
    8032                 :             : 
    8033                 :             : static rtx
    8034                 :    10776493 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
    8035                 :             :                        machine_mode innermode, unsigned int first_byte)
    8036                 :             : {
    8037                 :    10776493 :   unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
    8038                 :    10776493 :   auto_vec<target_unit, 128> buffer (buffer_bytes);
    8039                 :             : 
    8040                 :             :   /* Some ports misuse CCmode.  */
    8041                 :    10776493 :   if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
    8042                 :             :     return x;
    8043                 :             : 
    8044                 :             :   /* Paradoxical subregs read undefined values for bytes outside of the
    8045                 :             :      inner value.  However, we have traditionally always sign-extended
    8046                 :             :      integer constants and zero-extended others.  */
    8047                 :    10775865 :   unsigned int inner_bytes = buffer_bytes;
    8048                 :    10775865 :   if (paradoxical_subreg_p (outermode, innermode))
    8049                 :             :     {
    8050                 :      635146 :       if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
    8051                 :           0 :         return NULL_RTX;
    8052                 :             : 
    8053                 :      317573 :       target_unit filler = 0;
    8054                 :      317573 :       if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
    8055                 :       28545 :         filler = -1;
    8056                 :             : 
    8057                 :             :       /* Add any leading bytes due to big-endian layout.  The number of
    8058                 :             :          bytes must be constant because both modes have constant size.  */
    8059                 :      317573 :       unsigned int leading_bytes
    8060                 :      317573 :         = -byte_lowpart_offset (outermode, innermode).to_constant ();
    8061                 :      317573 :       for (unsigned int i = 0; i < leading_bytes; ++i)
    8062                 :           0 :         buffer.quick_push (filler);
    8063                 :             : 
    8064                 :      317573 :       if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8065                 :           0 :         return NULL_RTX;
    8066                 :             : 
    8067                 :             :       /* Add any trailing bytes due to little-endian layout.  */
    8068                 :     3557052 :       while (buffer.length () < buffer_bytes)
    8069                 :     1460953 :         buffer.quick_push (filler);
    8070                 :             :     }
    8071                 :    10458292 :   else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
    8072                 :             :     return NULL_RTX;
    8073                 :    10775865 :   rtx ret = native_decode_rtx (outermode, buffer, 0);
    8074                 :    10775865 :   if (ret && FLOAT_MODE_P (outermode))
    8075                 :             :     {
    8076                 :       68916 :       auto_vec<target_unit, 128> buffer2 (buffer_bytes);
    8077                 :       68916 :       if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
    8078                 :             :         return NULL_RTX;
    8079                 :      655849 :       for (unsigned int i = 0; i < buffer_bytes; ++i)
    8080                 :      586968 :         if (buffer[i] != buffer2[i])
    8081                 :             :           return NULL_RTX;
    8082                 :       68916 :     }
    8083                 :             :   return ret;
    8084                 :    10776493 : }
    8085                 :             : 
    8086                 :             : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
    8087                 :             :    Return 0 if no simplifications are possible.  */
    8088                 :             : rtx
    8089                 :    68845188 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
    8090                 :             :                                    machine_mode innermode, poly_uint64 byte)
    8091                 :             : {
    8092                 :             :   /* Little bit of sanity checking.  */
    8093                 :    68845188 :   gcc_assert (innermode != VOIDmode);
    8094                 :    68845188 :   gcc_assert (outermode != VOIDmode);
    8095                 :    68845188 :   gcc_assert (innermode != BLKmode);
    8096                 :    68845188 :   gcc_assert (outermode != BLKmode);
    8097                 :             : 
    8098                 :    68845188 :   gcc_assert (GET_MODE (op) == innermode
    8099                 :             :               || GET_MODE (op) == VOIDmode);
    8100                 :             : 
    8101                 :   137690376 :   poly_uint64 outersize = GET_MODE_SIZE (outermode);
    8102                 :    68845188 :   if (!multiple_p (byte, outersize))
    8103                 :             :     return NULL_RTX;
    8104                 :             : 
    8105                 :   137690368 :   poly_uint64 innersize = GET_MODE_SIZE (innermode);
    8106                 :    68845184 :   if (maybe_ge (byte, innersize))
    8107                 :             :     return NULL_RTX;
    8108                 :             : 
    8109                 :    68845184 :   if (outermode == innermode && known_eq (byte, 0U))
    8110                 :     4652703 :     return op;
    8111                 :             : 
    8112                 :    64192481 :   if (GET_CODE (op) == CONST_VECTOR)
    8113                 :      259597 :     byte = simplify_const_vector_byte_offset (op, byte);
    8114                 :             : 
    8115                 :   128384962 :   if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
    8116                 :             :     {
    8117                 :    58252614 :       rtx elt;
    8118                 :             : 
    8119                 :    50195050 :       if (VECTOR_MODE_P (outermode)
    8120                 :    24172692 :           && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
    8121                 :    59789222 :           && vec_duplicate_p (op, &elt))
    8122                 :       11030 :         return gen_vec_duplicate (outermode, elt);
    8123                 :             : 
    8124                 :    58248979 :       if (outermode == GET_MODE_INNER (innermode)
    8125                 :    58248979 :           && vec_duplicate_p (op, &elt))
    8126                 :        7395 :         return elt;
    8127                 :             :     }
    8128                 :             : 
    8129                 :    64181451 :   if (CONST_SCALAR_INT_P (op)
    8130                 :    53522821 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    8131                 :    53499073 :       || CONST_FIXED_P (op)
    8132                 :    53499073 :       || GET_CODE (op) == CONST_VECTOR)
    8133                 :             :     {
    8134                 :    10936120 :       unsigned HOST_WIDE_INT cbyte;
    8135                 :    10936120 :       if (byte.is_constant (&cbyte))
    8136                 :             :         {
    8137                 :    10936120 :           if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
    8138                 :             :             {
    8139                 :      167128 :               rtx tmp = simplify_const_vector_subreg (outermode, op,
    8140                 :             :                                                       innermode, cbyte);
    8141                 :      167128 :               if (tmp)
    8142                 :    10936120 :                 return tmp;
    8143                 :             :             }
    8144                 :             : 
    8145                 :    10776493 :           fixed_size_mode fs_outermode;
    8146                 :    10776493 :           if (is_a <fixed_size_mode> (outermode, &fs_outermode))
    8147                 :    10776493 :             return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
    8148                 :             :         }
    8149                 :             :     }
    8150                 :             : 
    8151                 :             :   /* Changing mode twice with SUBREG => just change it once,
    8152                 :             :      or not at all if changing back op starting mode.  */
    8153                 :    53245331 :   if (GET_CODE (op) == SUBREG)
    8154                 :             :     {
    8155                 :     1286201 :       machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
    8156                 :     2572402 :       poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
    8157                 :     1286201 :       rtx newx;
    8158                 :             : 
    8159                 :             :       /* Make sure that the relationship between the two subregs is
    8160                 :             :          known at compile time.  */
    8161                 :     1286201 :       if (!ordered_p (outersize, innermostsize))
    8162                 :             :         return NULL_RTX;
    8163                 :             : 
    8164                 :     1286201 :       if (outermode == innermostmode
    8165                 :      700928 :           && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
    8166                 :     1987128 :           && known_eq (SUBREG_BYTE (op),
    8167                 :             :                        subreg_lowpart_offset (innermode, innermostmode)))
    8168                 :      700927 :         return SUBREG_REG (op);
    8169                 :             : 
    8170                 :             :       /* Work out the memory offset of the final OUTERMODE value relative
    8171                 :             :          to the inner value of OP.  */
    8172                 :      585274 :       poly_int64 mem_offset = subreg_memory_offset (outermode,
    8173                 :             :                                                     innermode, byte);
    8174                 :      585274 :       poly_int64 op_mem_offset = subreg_memory_offset (op);
    8175                 :      585274 :       poly_int64 final_offset = mem_offset + op_mem_offset;
    8176                 :             : 
    8177                 :             :       /* See whether resulting subreg will be paradoxical.  */
    8178                 :      585274 :       if (!paradoxical_subreg_p (outermode, innermostmode))
    8179                 :             :         {
    8180                 :             :           /* Bail out in case resulting subreg would be incorrect.  */
    8181                 :      988986 :           if (maybe_lt (final_offset, 0)
    8182                 :      988981 :               || maybe_ge (poly_uint64 (final_offset), innermostsize)
    8183                 :      988985 :               || !multiple_p (final_offset, outersize))
    8184                 :           5 :             return NULL_RTX;
    8185                 :             :         }
    8186                 :             :       else
    8187                 :             :         {
    8188                 :       90781 :           poly_int64 required_offset = subreg_memory_offset (outermode,
    8189                 :             :                                                              innermostmode, 0);
    8190                 :       90781 :           if (maybe_ne (final_offset, required_offset))
    8191                 :           0 :             return NULL_RTX;
    8192                 :             :           /* Paradoxical subregs always have byte offset 0.  */
    8193                 :       90781 :           final_offset = 0;
    8194                 :             :         }
    8195                 :             : 
    8196                 :             :       /* Recurse for further possible simplifications.  */
    8197                 :      585269 :       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
    8198                 :      585269 :                               final_offset);
    8199                 :      585269 :       if (newx)
    8200                 :             :         return newx;
    8201                 :      584889 :       if (validate_subreg (outermode, innermostmode,
    8202                 :      584889 :                            SUBREG_REG (op), final_offset))
    8203                 :             :         {
    8204                 :      532508 :           newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
    8205                 :      532508 :           if (SUBREG_PROMOTED_VAR_P (op)
    8206                 :         298 :               && SUBREG_PROMOTED_SIGN (op) >= 0
    8207                 :         298 :               && GET_MODE_CLASS (outermode) == MODE_INT
    8208                 :         293 :               && known_ge (outersize, innersize)
    8209                 :         292 :               && known_le (outersize, innermostsize)
    8210                 :      532512 :               && subreg_lowpart_p (newx))
    8211                 :             :             {
    8212                 :           4 :               SUBREG_PROMOTED_VAR_P (newx) = 1;
    8213                 :           4 :               SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
    8214                 :             :             }
    8215                 :      532508 :           return newx;
    8216                 :             :         }
    8217                 :             :       return NULL_RTX;
    8218                 :             :     }
    8219                 :             : 
    8220                 :             :   /* SUBREG of a hard register => just change the register number
    8221                 :             :      and/or mode.  If the hard register is not valid in that mode,
    8222                 :             :      suppress this simplification.  If the hard register is the stack,
    8223                 :             :      frame, or argument pointer, leave this as a SUBREG.  */
    8224                 :             : 
    8225                 :    51959130 :   if (REG_P (op) && HARD_REGISTER_P (op))
    8226                 :             :     {
    8227                 :    10785987 :       unsigned int regno, final_regno;
    8228                 :             : 
    8229                 :    10785987 :       regno = REGNO (op);
    8230                 :    10785987 :       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
    8231                 :    10785987 :       if (HARD_REGISTER_NUM_P (final_regno))
    8232                 :             :         {
    8233                 :    10762135 :           rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
    8234                 :             :                                       subreg_memory_offset (outermode,
    8235                 :             :                                                             innermode, byte));
    8236                 :             : 
    8237                 :             :           /* Propagate original regno.  We don't have any way to specify
    8238                 :             :              the offset inside original regno, so do so only for lowpart.
    8239                 :             :              The information is used only by alias analysis that cannot
    8240                 :             :              grog partial register anyway.  */
    8241                 :             : 
    8242                 :    10762135 :           if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
    8243                 :     8063183 :             ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
    8244                 :    10762135 :           return x;
    8245                 :             :         }
    8246                 :             :     }
    8247                 :             : 
    8248                 :             :   /* If we have a SUBREG of a register that we are replacing and we are
    8249                 :             :      replacing it with a MEM, make a new MEM and try replacing the
    8250                 :             :      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
    8251                 :             :      or if we would be widening it.  */
    8252                 :             : 
    8253                 :    41196995 :   if (MEM_P (op)
    8254                 :     1701070 :       && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
    8255                 :             :       /* Allow splitting of volatile memory references in case we don't
    8256                 :             :          have instruction to move the whole thing.  */
    8257                 :     1701067 :       && (! MEM_VOLATILE_P (op)
    8258                 :       44157 :           || ! have_insn_for (SET, innermode))
    8259                 :             :       && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
    8260                 :    42853905 :       && known_le (outersize, innersize))
    8261                 :      815134 :     return adjust_address_nv (op, outermode, byte);
    8262                 :             : 
    8263                 :             :   /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
    8264                 :             :      of two parts.  */
    8265                 :    40381861 :   if (GET_CODE (op) == CONCAT
    8266                 :    40381861 :       || GET_CODE (op) == VEC_CONCAT)
    8267                 :             :     {
    8268                 :      190246 :       poly_uint64 final_offset;
    8269                 :      190246 :       rtx part, res;
    8270                 :             : 
    8271                 :      190246 :       machine_mode part_mode = GET_MODE (XEXP (op, 0));
    8272                 :      190246 :       if (part_mode == VOIDmode)
    8273                 :           1 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8274                 :      380492 :       poly_uint64 part_size = GET_MODE_SIZE (part_mode);
    8275                 :      190246 :       if (known_lt (byte, part_size))
    8276                 :             :         {
    8277                 :      188536 :           part = XEXP (op, 0);
    8278                 :      188536 :           final_offset = byte;
    8279                 :             :         }
    8280                 :        1710 :       else if (known_ge (byte, part_size))
    8281                 :             :         {
    8282                 :        1710 :           part = XEXP (op, 1);
    8283                 :        1710 :           final_offset = byte - part_size;
    8284                 :             :         }
    8285                 :             :       else
    8286                 :             :         return NULL_RTX;
    8287                 :             : 
    8288                 :      190246 :       if (maybe_gt (final_offset + outersize, part_size))
    8289                 :             :         return NULL_RTX;
    8290                 :             : 
    8291                 :      129468 :       part_mode = GET_MODE (part);
    8292                 :      129468 :       if (part_mode == VOIDmode)
    8293                 :           0 :         part_mode = GET_MODE_INNER (GET_MODE (op));
    8294                 :      129468 :       res = simplify_subreg (outermode, part, part_mode, final_offset);
    8295                 :      129468 :       if (res)
    8296                 :             :         return res;
    8297                 :         231 :       if (validate_subreg (outermode, part_mode, part, final_offset))
    8298                 :         231 :         return gen_rtx_SUBREG (outermode, part, final_offset);
    8299                 :             :       return NULL_RTX;
    8300                 :             :     }
    8301                 :             : 
    8302                 :             :   /* Simplify
    8303                 :             :         (subreg (vec_merge (X)
    8304                 :             :                            (vector)
    8305                 :             :                            (const_int ((1 << N) | M)))
    8306                 :             :                 (N * sizeof (outermode)))
    8307                 :             :      to
    8308                 :             :         (subreg (X) (N * sizeof (outermode)))
    8309                 :             :    */
    8310                 :    40191615 :   unsigned int idx;
    8311                 :    80383230 :   if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
    8312                 :    40191615 :       && idx < HOST_BITS_PER_WIDE_INT
    8313                 :    40191615 :       && GET_CODE (op) == VEC_MERGE
    8314                 :      598116 :       && GET_MODE_INNER (innermode) == outermode
    8315                 :        4713 :       && CONST_INT_P (XEXP (op, 2))
    8316                 :    40195855 :       && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
    8317                 :        4231 :     return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
    8318                 :             : 
    8319                 :             :   /* A SUBREG resulting from a zero extension may fold to zero if
    8320                 :             :      it extracts higher bits that the ZERO_EXTEND's source bits.  */
    8321                 :    40187384 :   if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
    8322                 :             :     {
    8323                 :      223791 :       poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
    8324                 :      223791 :       if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
    8325                 :       56247 :         return CONST0_RTX (outermode);
    8326                 :             :     }
    8327                 :             : 
    8328                 :             :   /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant.  */
    8329                 :    40131137 :   if (GET_CODE (op) == ASHIFT
    8330                 :      739094 :       && SCALAR_INT_MODE_P (innermode)
    8331                 :      712161 :       && CONST_INT_P (XEXP (op, 1))
    8332                 :      637131 :       && INTVAL (XEXP (op, 1)) > 0
    8333                 :    41507312 :       && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
    8334                 :             :     {
    8335                 :      637081 :       HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
    8336                 :             :       /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero.  */
    8337                 :      637081 :       if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
    8338                 :     1235613 :           && known_le (GET_MODE_BITSIZE (outermode), val))
    8339                 :      207830 :         return CONST0_RTX (outermode);
    8340                 :             :       /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND).  */
    8341                 :      465692 :       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
    8342                 :       37013 :           && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
    8343                 :       73816 :           && known_eq (GET_MODE_BITSIZE (outermode), val)
    8344                 :       72882 :           && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
    8345                 :      502705 :           && known_eq (subreg_highpart_offset (outermode, innermode), byte))
    8346                 :       36441 :         return XEXP (XEXP (op, 0), 0);
    8347                 :             :     }
    8348                 :             : 
    8349                 :    41411387 :   auto distribute_subreg = [&](rtx op)
    8350                 :             :     {
    8351                 :     1488080 :       return simplify_subreg (outermode, op, innermode, byte);
    8352                 :    39923307 :     };
    8353                 :             : 
    8354                 :             :   /* Try distributing the subreg through logic operations, if that
    8355                 :             :      leads to all subexpressions being simplified.  For example,
    8356                 :             :      distributing the outer subreg in:
    8357                 :             : 
    8358                 :             :        (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
    8359                 :             : 
    8360                 :             :      gives:
    8361                 :             : 
    8362                 :             :        (not:SI (reg:SI X))
    8363                 :             : 
    8364                 :             :      This should be a win if the outermode is word_mode, since logical
    8365                 :             :      operations on word_mode should (a) be no more expensive than logical
    8366                 :             :      operations on subword modes and (b) are likely to be cheaper than
    8367                 :             :      logical operations on multiword modes.
    8368                 :             : 
    8369                 :             :      Otherwise, handle the case where the subreg is non-narrowing and does
    8370                 :             :      not change the number of words.  The non-narrowing condition ensures
    8371                 :             :      that we don't convert word_mode operations to subword operations.  */
    8372                 :    39923307 :   scalar_int_mode int_outermode, int_innermode;
    8373                 :    39923307 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8374                 :    33552856 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8375                 :    72457217 :       && (outermode == word_mode
    8376                 :    18234223 :           || ((GET_MODE_PRECISION (int_outermode)
    8377                 :    18234223 :                >= GET_MODE_PRECISION (int_innermode))
    8378                 :     4569341 :               && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
    8379                 :     4492420 :                   <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
    8380                 :    18730545 :     switch (GET_CODE (op))
    8381                 :             :       {
    8382                 :       34381 :       case NOT:
    8383                 :       34381 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8384                 :        1348 :           return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
    8385                 :             :         break;
    8386                 :             : 
    8387                 :      485707 :       case AND:
    8388                 :      485707 :       case IOR:
    8389                 :      485707 :       case XOR:
    8390                 :      485707 :         if (rtx op0 = distribute_subreg (XEXP (op, 0)))
    8391                 :      217595 :           if (rtx op1 = distribute_subreg (XEXP (op, 1)))
    8392                 :      213670 :             return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
    8393                 :             :         break;
    8394                 :             : 
    8395                 :             :       default:
    8396                 :             :         break;
    8397                 :             :       }
    8398                 :             : 
    8399                 :    39708289 :   if (is_a <scalar_int_mode> (outermode, &int_outermode)
    8400                 :    33337838 :       && is_a <scalar_int_mode> (innermode, &int_innermode)
    8401                 :    73046127 :       && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
    8402                 :             :     {
    8403                 :             :       /* Handle polynomial integers.  The upper bits of a paradoxical
    8404                 :             :          subreg are undefined, so this is safe regardless of whether
    8405                 :             :          we're truncating or extending.  */
    8406                 :    30063592 :       if (CONST_POLY_INT_P (op))
    8407                 :             :         {
    8408                 :             :           poly_wide_int val
    8409                 :             :             = poly_wide_int::from (const_poly_int_value (op),
    8410                 :             :                                    GET_MODE_PRECISION (int_outermode),
    8411                 :             :                                    SIGNED);
    8412                 :             :           return immed_wide_int_const (val, int_outermode);
    8413                 :             :         }
    8414                 :             : 
    8415                 :    30063592 :       if (GET_MODE_PRECISION (int_outermode)
    8416                 :    30063592 :           < GET_MODE_PRECISION (int_innermode))
    8417                 :             :         {
    8418                 :    17171829 :           rtx tem = simplify_truncation (int_outermode, op, int_innermode);
    8419                 :    17171829 :           if (tem)
    8420                 :             :             return tem;
    8421                 :             :         }
    8422                 :             :     }
    8423                 :             : 
    8424                 :             :   /* If the outer mode is not integral, try taking a subreg with the equivalent
    8425                 :             :      integer outer mode and then bitcasting the result.
    8426                 :             :      Other simplifications rely on integer to integer subregs and we'd
    8427                 :             :      potentially miss out on optimizations otherwise.  */
    8428                 :    77394594 :   if (known_gt (GET_MODE_SIZE (innermode),
    8429                 :             :                 GET_MODE_SIZE (outermode))
    8430                 :    19471367 :       && SCALAR_INT_MODE_P (innermode)
    8431                 :    18501645 :       && !SCALAR_INT_MODE_P (outermode)
    8432                 :    58339680 :       && int_mode_for_size (GET_MODE_BITSIZE (outermode),
    8433                 :       85508 :                             0).exists (&int_outermode))
    8434                 :             :     {
    8435                 :       85508 :       rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
    8436                 :       85508 :       if (tem)
    8437                 :        1973 :         return lowpart_subreg (outermode, tem, int_outermode);
    8438                 :             :     }
    8439                 :             : 
    8440                 :             :   /* If OP is a vector comparison and the subreg is not changing the
    8441                 :             :      number of elements or the size of the elements, change the result
    8442                 :             :      of the comparison to the new mode.  */
    8443                 :    38695324 :   if (COMPARISON_P (op)
    8444                 :      236225 :       && VECTOR_MODE_P (outermode)
    8445                 :      176842 :       && VECTOR_MODE_P (innermode)
    8446                 :      530502 :       && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
    8447                 :    39046969 :       && known_eq (GET_MODE_UNIT_SIZE (outermode),
    8448                 :             :                    GET_MODE_UNIT_SIZE (innermode)))
    8449                 :      116871 :     return simplify_gen_relational (GET_CODE (op), outermode, innermode,
    8450                 :      116871 :                                     XEXP (op, 0), XEXP (op, 1));
    8451                 :             : 
    8452                 :             :   /* Distribute non-paradoxical subregs through logic ops in cases where
    8453                 :             :      one term disappears.
    8454                 :             : 
    8455                 :             :      (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
    8456                 :             :      (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
    8457                 :             :      (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
    8458                 :             : 
    8459                 :             :      if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
    8460                 :             : 
    8461                 :             :      (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
    8462                 :             :      (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
    8463                 :             : 
    8464                 :             :      if M2 is no smaller than M1 and (subreg:M1 C2) is zero.  */
    8465                 :    38578453 :   if (known_ge (innersize, outersize)
    8466                 :    25317596 :       && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
    8467                 :    23499792 :       && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
    8468                 :    40093093 :       && CONSTANT_P (XEXP (op, 1)))
    8469                 :             :     {
    8470                 :      743670 :       rtx op1_subreg = distribute_subreg (XEXP (op, 1));
    8471                 :      743670 :       if (op1_subreg == CONSTM1_RTX (outermode))
    8472                 :             :         {
    8473                 :      121498 :           if (GET_CODE (op) == IOR)
    8474                 :             :             return op1_subreg;
    8475                 :      121264 :           rtx op0 = XEXP (op, 0);
    8476                 :      121264 :           if (GET_CODE (op) == XOR)
    8477                 :         777 :             op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
    8478                 :      121264 :           return simplify_gen_subreg (outermode, op0, innermode, byte);
    8479                 :             :         }
    8480                 :             : 
    8481                 :      622172 :       if (op1_subreg == CONST0_RTX (outermode))
    8482                 :       12530 :         return (GET_CODE (op) == AND
    8483                 :       12530 :                 ? op1_subreg
    8484                 :        6727 :                 : distribute_subreg (XEXP (op, 0)));
    8485                 :             :     }
    8486                 :             : 
    8487                 :             :   return NULL_RTX;
    8488                 :             : }
    8489                 :             : 
    8490                 :             : /* Make a SUBREG operation or equivalent if it folds.  */
    8491                 :             : 
    8492                 :             : rtx
    8493                 :    43765819 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
    8494                 :             :                                        machine_mode innermode,
    8495                 :             :                                        poly_uint64 byte)
    8496                 :             : {
    8497                 :    43765819 :   rtx newx;
    8498                 :             : 
    8499                 :    43765819 :   newx = simplify_subreg (outermode, op, innermode, byte);
    8500                 :    43765819 :   if (newx)
    8501                 :             :     return newx;
    8502                 :             : 
    8503                 :    20438674 :   if (GET_CODE (op) == SUBREG
    8504                 :    20438674 :       || GET_CODE (op) == CONCAT
    8505                 :    20408937 :       || CONST_SCALAR_INT_P (op)
    8506                 :    20408911 :       || CONST_DOUBLE_AS_FLOAT_P (op)
    8507                 :    20408911 :       || CONST_FIXED_P (op)
    8508                 :    20408911 :       || GET_CODE (op) == CONST_VECTOR)
    8509                 :             :     return NULL_RTX;
    8510                 :             : 
    8511                 :    20408901 :   if (validate_subreg (outermode, innermode, op, byte))
    8512                 :    20376857 :     return gen_rtx_SUBREG (outermode, op, byte);
    8513                 :             : 
    8514                 :             :   return NULL_RTX;
    8515                 :             : }
    8516                 :             : 
    8517                 :             : /* Generates a subreg to get the least significant part of EXPR (in mode
    8518                 :             :    INNER_MODE) to OUTER_MODE.  */
    8519                 :             : 
    8520                 :             : rtx
    8521                 :    32650158 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
    8522                 :             :                                   machine_mode inner_mode)
    8523                 :             : {
    8524                 :    32650158 :   return simplify_gen_subreg (outer_mode, expr, inner_mode,
    8525                 :    32650158 :                               subreg_lowpart_offset (outer_mode, inner_mode));
    8526                 :             : }
    8527                 :             : 
    8528                 :             : /* Generate RTX to select element at INDEX out of vector OP.  */
    8529                 :             : 
    8530                 :             : rtx
    8531                 :      605950 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
    8532                 :             : {
    8533                 :      605950 :   gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
    8534                 :             : 
    8535                 :      605950 :   scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
    8536                 :             : 
    8537                 :     1211900 :   if (known_eq (index * GET_MODE_SIZE (imode),
    8538                 :             :                 subreg_lowpart_offset (imode, GET_MODE (op))))
    8539                 :             :     {
    8540                 :      605800 :       rtx res = lowpart_subreg (imode, op, GET_MODE (op));
    8541                 :      605800 :       if (res)
    8542                 :             :         return res;
    8543                 :             :     }
    8544                 :             : 
    8545                 :         215 :   rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
    8546                 :         215 :   return gen_rtx_VEC_SELECT (imode, op, tmp);
    8547                 :             : }
    8548                 :             : 
    8549                 :             : 
    8550                 :             : /* Simplify X, an rtx expression.
    8551                 :             : 
    8552                 :             :    Return the simplified expression or NULL if no simplifications
    8553                 :             :    were possible.
    8554                 :             : 
    8555                 :             :    This is the preferred entry point into the simplification routines;
    8556                 :             :    however, we still allow passes to call the more specific routines.
    8557                 :             : 
    8558                 :             :    Right now GCC has three (yes, three) major bodies of RTL simplification
    8559                 :             :    code that need to be unified.
    8560                 :             : 
    8561                 :             :         1. fold_rtx in cse.cc.  This code uses various CSE specific
    8562                 :             :            information to aid in RTL simplification.
    8563                 :             : 
    8564                 :             :         2. simplify_rtx in combine.cc.  Similar to fold_rtx, except that
    8565                 :             :            it uses combine specific information to aid in RTL
    8566                 :             :            simplification.
    8567                 :             : 
    8568                 :             :         3. The routines in this file.
    8569                 :             : 
    8570                 :             : 
    8571                 :             :    Long term we want to only have one body of simplification code; to
    8572                 :             :    get to that state I recommend the following steps:
    8573                 :             : 
    8574                 :             :         1. Pour over fold_rtx & simplify_rtx and move any simplifications
    8575                 :             :            which are not pass dependent state into these routines.
    8576                 :             : 
    8577                 :             :         2. As code is moved by #1, change fold_rtx & simplify_rtx to
    8578                 :             :            use this routine whenever possible.
    8579                 :             : 
    8580                 :             :         3. Allow for pass dependent state to be provided to these
    8581                 :             :            routines and add simplifications based on the pass dependent
    8582                 :             :            state.  Remove code from cse.cc & combine.cc that becomes
    8583                 :             :            redundant/dead.
    8584                 :             : 
    8585                 :             :     It will take time, but ultimately the compiler will be easier to
    8586                 :             :     maintain and improve.  It's totally silly that when we add a
    8587                 :             :     simplification that it needs to be added to 4 places (3 for RTL
    8588                 :             :     simplification and 1 for tree simplification.  */
    8589                 :             : 
    8590                 :             : rtx
    8591                 :    47376209 : simplify_rtx (const_rtx x)
    8592                 :             : {
    8593                 :    47376209 :   const enum rtx_code code = GET_CODE (x);
    8594                 :    47376209 :   const machine_mode mode = GET_MODE (x);
    8595                 :             : 
    8596                 :    47376209 :   switch (GET_RTX_CLASS (code))
    8597                 :             :     {
    8598                 :      901809 :     case RTX_UNARY:
    8599                 :     1803618 :       return simplify_unary_operation (code, mode,
    8600                 :      901809 :                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
    8601                 :    26859013 :     case RTX_COMM_ARITH:
    8602                 :    26859013 :       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    8603                 :      524120 :         return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
    8604                 :             : 
    8605                 :             :       /* Fall through.  */
    8606                 :             : 
    8607                 :    33095659 :     case RTX_BIN_ARITH:
    8608                 :    33095659 :       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
    8609                 :             : 
    8610                 :       61860 :     case RTX_TERNARY:
    8611                 :       61860 :     case RTX_BITFIELD_OPS:
    8612                 :       61860 :       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
    8613                 :       61860 :                                          XEXP (x, 0), XEXP (x, 1),
    8614                 :       61860 :                                          XEXP (x, 2));
    8615                 :             : 
    8616                 :      174830 :     case RTX_COMPARE:
    8617                 :      174830 :     case RTX_COMM_COMPARE:
    8618                 :      174830 :       return simplify_relational_operation (code, mode,
    8619                 :      174830 :                                             ((GET_MODE (XEXP (x, 0))
    8620                 :             :                                              != VOIDmode)
    8621                 :             :                                             ? GET_MODE (XEXP (x, 0))
    8622                 :         465 :                                             : GET_MODE (XEXP (x, 1))),
    8623                 :      174830 :                                             XEXP (x, 0),
    8624                 :      349660 :                                             XEXP (x, 1));
    8625                 :             : 
    8626                 :      226668 :     case RTX_EXTRA:
    8627                 :      226668 :       if (code == SUBREG)
    8628                 :        2432 :         return simplify_subreg (mode, SUBREG_REG (x),
    8629                 :        2432 :                                 GET_MODE (SUBREG_REG (x)),
    8630                 :        2432 :                                 SUBREG_BYTE (x));
    8631                 :             :       break;
    8632                 :             : 
    8633                 :     6676247 :     case RTX_OBJ:
    8634                 :     6676247 :       if (code == LO_SUM)
    8635                 :             :         {
    8636                 :             :           /* Convert (lo_sum (high FOO) FOO) to FOO.  */
    8637                 :           0 :           if (GET_CODE (XEXP (x, 0)) == HIGH
    8638                 :           0 :               && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
    8639                 :           0 :           return XEXP (x, 1);
    8640                 :             :         }
    8641                 :             :       break;
    8642                 :             : 
    8643                 :             :     default:
    8644                 :             :       break;
    8645                 :             :     }
    8646                 :             :   return NULL;
    8647                 :             : }
    8648                 :             : 
    8649                 :             : #if CHECKING_P
    8650                 :             : 
    8651                 :             : namespace selftest {
    8652                 :             : 
    8653                 :             : /* Make a unique pseudo REG of mode MODE for use by selftests.  */
    8654                 :             : 
    8655                 :             : static rtx
    8656                 :        2672 : make_test_reg (machine_mode mode)
    8657                 :             : {
    8658                 :        2672 :   static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
    8659                 :             : 
    8660                 :        2672 :   return gen_rtx_REG (mode, test_reg_num++);
    8661                 :             : }
    8662                 :             : 
    8663                 :             : static void
    8664                 :          40 : test_scalar_int_ops (machine_mode mode)
    8665                 :             : {
    8666                 :          40 :   rtx op0 = make_test_reg (mode);
    8667                 :          40 :   rtx op1 = make_test_reg (mode);
    8668                 :          40 :   rtx six = GEN_INT (6);
    8669                 :             : 
    8670                 :          40 :   rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
    8671                 :          40 :   rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
    8672                 :          40 :   rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
    8673                 :             : 
    8674                 :          40 :   rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
    8675                 :          40 :   rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
    8676                 :          40 :   rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
    8677                 :             : 
    8678                 :          40 :   rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
    8679                 :          40 :   rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
    8680                 :             : 
    8681                 :             :   /* Test some binary identities.  */
    8682                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
    8683                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
    8684                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
    8685                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
    8686                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
    8687                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
    8688                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
    8689                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
    8690                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
    8691                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
    8692                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
    8693                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
    8694                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
    8695                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
    8696                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
    8697                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
    8698                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
    8699                 :             : 
    8700                 :             :   /* Test some self-inverse operations.  */
    8701                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
    8702                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
    8703                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
    8704                 :             : 
    8705                 :             :   /* Test some reflexive operations.  */
    8706                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
    8707                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
    8708                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
    8709                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
    8710                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
    8711                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
    8712                 :             : 
    8713                 :          40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
    8714                 :          40 :   ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
    8715                 :             : 
    8716                 :             :   /* Test simplify_distributive_operation.  */
    8717                 :          40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
    8718                 :             :                  simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
    8719                 :          40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
    8720                 :             :                  simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
    8721                 :          40 :   ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
    8722                 :             :                  simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
    8723                 :             : 
    8724                 :             :   /* Test useless extensions are eliminated.  */
    8725                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
    8726                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
    8727                 :          40 :   ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
    8728                 :          40 :   ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
    8729                 :          40 : }
    8730                 :             : 
    8731                 :             : /* Verify some simplifications of integer extension/truncation.
    8732                 :             :    Machine mode BMODE is the guaranteed wider than SMODE.  */
    8733                 :             : 
    8734                 :             : static void
    8735                 :          24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
    8736                 :             : {
    8737                 :          24 :   rtx sreg = make_test_reg (smode);
    8738                 :             : 
    8739                 :             :   /* Check truncation of extension.  */
    8740                 :          24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8741                 :             :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    8742                 :             :                                                          sreg, smode),
    8743                 :             :                                      bmode),
    8744                 :             :                  sreg);
    8745                 :          24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8746                 :             :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    8747                 :             :                                                          sreg, smode),
    8748                 :             :                                      bmode),
    8749                 :             :                  sreg);
    8750                 :          24 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8751                 :             :                                      lowpart_subreg (bmode, sreg, smode),
    8752                 :             :                                      bmode),
    8753                 :             :                  sreg);
    8754                 :             : 
    8755                 :             :   /* Test extensions, followed by logic ops, followed by truncations.  */
    8756                 :          24 :   rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
    8757                 :          24 :   rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
    8758                 :          24 :   rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
    8759                 :          24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    8760                 :             :                                  simplify_gen_binary (AND, bmode,
    8761                 :             :                                                       bsubreg, smask),
    8762                 :             :                                  bmode),
    8763                 :             :                  sreg);
    8764                 :          24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    8765                 :             :                                  simplify_gen_binary (AND, bmode,
    8766                 :             :                                                       bsubreg, inv_smask),
    8767                 :             :                                  bmode),
    8768                 :             :                  const0_rtx);
    8769                 :          24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    8770                 :             :                                  simplify_gen_binary (IOR, bmode,
    8771                 :             :                                                       bsubreg, smask),
    8772                 :             :                                  bmode),
    8773                 :             :                  constm1_rtx);
    8774                 :          24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    8775                 :             :                                  simplify_gen_binary (IOR, bmode,
    8776                 :             :                                                       bsubreg, inv_smask),
    8777                 :             :                                  bmode),
    8778                 :             :                  sreg);
    8779                 :          24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    8780                 :             :                                  simplify_gen_binary (XOR, bmode,
    8781                 :             :                                                       bsubreg, smask),
    8782                 :             :                                  bmode),
    8783                 :             :                  lowpart_subreg (smode,
    8784                 :             :                                  gen_rtx_NOT (bmode, bsubreg),
    8785                 :             :                                  bmode));
    8786                 :          24 :   ASSERT_RTX_EQ (lowpart_subreg (smode,
    8787                 :             :                                  simplify_gen_binary (XOR, bmode,
    8788                 :             :                                                       bsubreg, inv_smask),
    8789                 :             :                                  bmode),
    8790                 :             :                  sreg);
    8791                 :             : 
    8792                 :          24 :   if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
    8793                 :             :     {
    8794                 :          24 :       rtx breg1 = make_test_reg (bmode);
    8795                 :          24 :       rtx breg2 = make_test_reg (bmode);
    8796                 :          24 :       rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
    8797                 :          24 :       rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
    8798                 :          24 :       rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
    8799                 :          24 :       rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
    8800                 :          24 :       rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
    8801                 :          24 :       rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
    8802                 :          24 :       rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
    8803                 :          24 :       rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
    8804                 :          24 :       rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
    8805                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
    8806                 :             :                      gen_rtx_NOT (bmode, breg1));
    8807                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
    8808                 :             :                      gen_rtx_AND (bmode, breg1, breg2));
    8809                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
    8810                 :             :                      gen_rtx_IOR (bmode, breg1, breg2));
    8811                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
    8812                 :             :                      gen_rtx_XOR (bmode, breg1, breg2));
    8813                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
    8814                 :             :                      gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    8815                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
    8816                 :             :                      gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
    8817                 :          24 :       ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
    8818                 :             :                      gen_rtx_XOR (bmode,
    8819                 :             :                                   gen_rtx_XOR (bmode, breg1, breg2),
    8820                 :             :                                   const1_rtx));
    8821                 :             :     }
    8822                 :          24 : }
    8823                 :             : 
    8824                 :             : /* Verify more simplifications of integer extension/truncation.
    8825                 :             :    BMODE is wider than MMODE which is wider than SMODE.  */
    8826                 :             : 
    8827                 :             : static void
    8828                 :          16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
    8829                 :             :                           machine_mode smode)
    8830                 :             : {
    8831                 :          16 :   rtx breg = make_test_reg (bmode);
    8832                 :          16 :   rtx mreg = make_test_reg (mmode);
    8833                 :          16 :   rtx sreg = make_test_reg (smode);
    8834                 :             : 
    8835                 :             :   /* Check truncate of truncate.  */
    8836                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8837                 :             :                                      simplify_gen_unary (TRUNCATE, mmode,
    8838                 :             :                                                          breg, bmode),
    8839                 :             :                                      mmode),
    8840                 :             :                  simplify_gen_unary (TRUNCATE, smode, breg, bmode));
    8841                 :             : 
    8842                 :             :   /* Check extension of extension.  */
    8843                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
    8844                 :             :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    8845                 :             :                                                          sreg, smode),
    8846                 :             :                                      mmode),
    8847                 :             :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    8848                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    8849                 :             :                                      simplify_gen_unary (SIGN_EXTEND, mmode,
    8850                 :             :                                                          sreg, smode),
    8851                 :             :                                      mmode),
    8852                 :             :                  simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
    8853                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
    8854                 :             :                                      simplify_gen_unary (ZERO_EXTEND, mmode,
    8855                 :             :                                                          sreg, smode),
    8856                 :             :                                      mmode),
    8857                 :             :                  simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
    8858                 :             : 
    8859                 :             :   /* Check truncation of extension.  */
    8860                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8861                 :             :                                      simplify_gen_unary (ZERO_EXTEND, bmode,
    8862                 :             :                                                          mreg, mmode),
    8863                 :             :                                      bmode),
    8864                 :             :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    8865                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8866                 :             :                                      simplify_gen_unary (SIGN_EXTEND, bmode,
    8867                 :             :                                                          mreg, mmode),
    8868                 :             :                                      bmode),
    8869                 :             :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    8870                 :          16 :   ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
    8871                 :             :                                      lowpart_subreg (bmode, mreg, mmode),
    8872                 :             :                                      bmode),
    8873                 :             :                  simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
    8874                 :          16 : }
    8875                 :             : 
    8876                 :             : /* Test comparisons of comparisons, with the inner comparisons being
    8877                 :             :    between values of mode MODE2 and producing results of mode MODE1,
    8878                 :             :    and with the outer comparisons producing results of mode MODE0.  */
    8879                 :             : 
    8880                 :             : static void
    8881                 :           4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
    8882                 :             : {
    8883                 :           4 :   rtx reg0 = make_test_reg (mode2);
    8884                 :           4 :   rtx reg1 = make_test_reg (mode2);
    8885                 :             : 
    8886                 :           4 :   static const rtx_code codes[] = {
    8887                 :             :     EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
    8888                 :             :   };
    8889                 :           4 :   constexpr auto num_codes = ARRAY_SIZE (codes);
    8890                 :           4 :   rtx cmps[num_codes];
    8891                 :           4 :   rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
    8892                 :             : 
    8893                 :          44 :   for (unsigned int i = 0; i < num_codes; ++i)
    8894                 :          40 :     cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
    8895                 :             : 
    8896                 :          44 :   for (auto code : codes)
    8897                 :         440 :     for (unsigned int i0 = 0; i0 < num_codes; ++i0)
    8898                 :        4400 :       for (unsigned int i1 = 0; i1 < num_codes; ++i1)
    8899                 :             :         {
    8900                 :        4000 :           rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
    8901                 :             :                                                        cmps[i0], cmps[i1]);
    8902                 :        4000 :           if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
    8903                 :        1280 :             ASSERT_TRUE (cmp_res == NULL_RTX);
    8904                 :             :           else
    8905                 :             :             {
    8906                 :        2720 :               ASSERT_TRUE (cmp_res != NULL_RTX
    8907                 :             :                            && (CONSTANT_P (cmp_res)
    8908                 :             :                                || (COMPARISON_P (cmp_res)
    8909                 :             :                                    && GET_MODE (cmp_res) == mode0
    8910                 :             :                                    && REG_P (XEXP (cmp_res, 0))
    8911                 :             :                                    && REG_P (XEXP (cmp_res, 1)))));
    8912                 :       10880 :               for (rtx reg0_val : vals)
    8913                 :       32640 :                 for (rtx reg1_val : vals)
    8914                 :             :                   {
    8915                 :       24480 :                     rtx val0 = simplify_const_relational_operation
    8916                 :       24480 :                       (codes[i0], mode1, reg0_val, reg1_val);
    8917                 :       24480 :                     rtx val1 = simplify_const_relational_operation
    8918                 :       24480 :                       (codes[i1], mode1, reg0_val, reg1_val);
    8919                 :       24480 :                     rtx val = simplify_const_relational_operation
    8920                 :       24480 :                       (code, mode0, val0, val1);
    8921                 :       24480 :                     rtx folded = cmp_res;
    8922                 :       24480 :                     if (COMPARISON_P (cmp_res))
    8923                 :       16704 :                       folded = simplify_const_relational_operation
    8924                 :       16704 :                         (GET_CODE (cmp_res), mode0,
    8925                 :       16704 :                          XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
    8926                 :       16704 :                          XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
    8927                 :       24480 :                     ASSERT_RTX_EQ (val, folded);
    8928                 :             :                   }
    8929                 :             :             }
    8930                 :             :         }
    8931                 :           4 : }
    8932                 :             : 
    8933                 :             : 
    8934                 :             : /* Verify some simplifications involving scalar expressions.  */
    8935                 :             : 
    8936                 :             : static void
    8937                 :           4 : test_scalar_ops ()
    8938                 :             : {
    8939                 :         500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    8940                 :             :     {
    8941                 :         496 :       machine_mode mode = (machine_mode) i;
    8942                 :         496 :       if (SCALAR_INT_MODE_P (mode) && mode != BImode)
    8943                 :          40 :         test_scalar_int_ops (mode);
    8944                 :             :     }
    8945                 :             : 
    8946                 :           4 :   test_scalar_int_ext_ops (HImode, QImode);
    8947                 :           4 :   test_scalar_int_ext_ops (SImode, QImode);
    8948                 :           4 :   test_scalar_int_ext_ops (SImode, HImode);
    8949                 :           4 :   test_scalar_int_ext_ops (DImode, QImode);
    8950                 :           4 :   test_scalar_int_ext_ops (DImode, HImode);
    8951                 :           4 :   test_scalar_int_ext_ops (DImode, SImode);
    8952                 :             : 
    8953                 :           4 :   test_scalar_int_ext_ops2 (SImode, HImode, QImode);
    8954                 :           4 :   test_scalar_int_ext_ops2 (DImode, HImode, QImode);
    8955                 :           4 :   test_scalar_int_ext_ops2 (DImode, SImode, QImode);
    8956                 :           4 :   test_scalar_int_ext_ops2 (DImode, SImode, HImode);
    8957                 :             : 
    8958                 :           4 :   test_comparisons (QImode, HImode, SImode);
    8959                 :           4 : }
    8960                 :             : 
    8961                 :             : /* Test vector simplifications involving VEC_DUPLICATE in which the
    8962                 :             :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    8963                 :             :    register that holds one element of MODE.  */
    8964                 :             : 
    8965                 :             : static void
    8966                 :         224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
    8967                 :             : {
    8968                 :         224 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    8969                 :         224 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    8970                 :         448 :   poly_uint64 nunits = GET_MODE_NUNITS (mode);
    8971                 :         224 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
    8972                 :             :     {
    8973                 :             :       /* Test some simple unary cases with VEC_DUPLICATE arguments.  */
    8974                 :         124 :       rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
    8975                 :         124 :       rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
    8976                 :         124 :       ASSERT_RTX_EQ (duplicate,
    8977                 :             :                      simplify_unary_operation (NOT, mode,
    8978                 :             :                                                duplicate_not, mode));
    8979                 :             : 
    8980                 :         124 :       rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    8981                 :         124 :       rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
    8982                 :         124 :       ASSERT_RTX_EQ (duplicate,
    8983                 :             :                      simplify_unary_operation (NEG, mode,
    8984                 :             :                                                duplicate_neg, mode));
    8985                 :             : 
    8986                 :             :       /* Test some simple binary cases with VEC_DUPLICATE arguments.  */
    8987                 :         124 :       ASSERT_RTX_EQ (duplicate,
    8988                 :             :                      simplify_binary_operation (PLUS, mode, duplicate,
    8989                 :             :                                                 CONST0_RTX (mode)));
    8990                 :             : 
    8991                 :         124 :       ASSERT_RTX_EQ (duplicate,
    8992                 :             :                      simplify_binary_operation (MINUS, mode, duplicate,
    8993                 :             :                                                 CONST0_RTX (mode)));
    8994                 :             : 
    8995                 :         124 :       ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
    8996                 :             :                          simplify_binary_operation (MINUS, mode, duplicate,
    8997                 :             :                                                     duplicate));
    8998                 :             :     }
    8999                 :             : 
    9000                 :             :   /* Test a scalar VEC_SELECT of a VEC_DUPLICATE.  */
    9001                 :         224 :   rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
    9002                 :         224 :   ASSERT_RTX_PTR_EQ (scalar_reg,
    9003                 :             :                      simplify_binary_operation (VEC_SELECT, inner_mode,
    9004                 :             :                                                 duplicate, zero_par));
    9005                 :             : 
    9006                 :         224 :   unsigned HOST_WIDE_INT const_nunits;
    9007                 :         224 :   if (nunits.is_constant (&const_nunits))
    9008                 :             :     {
    9009                 :             :       /* And again with the final element.  */
    9010                 :         224 :       rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
    9011                 :         224 :       rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
    9012                 :         224 :       ASSERT_RTX_PTR_EQ (scalar_reg,
    9013                 :             :                          simplify_binary_operation (VEC_SELECT, inner_mode,
    9014                 :             :                                                     duplicate, last_par));
    9015                 :             : 
    9016                 :             :       /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE.  */
    9017                 :             :       /* Skip this test for vectors of booleans, because offset is in bytes,
    9018                 :             :          while vec_merge indices are in elements (usually bits).  */
    9019                 :         224 :       if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
    9020                 :             :         {
    9021                 :         224 :           rtx vector_reg = make_test_reg (mode);
    9022                 :        3508 :           for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
    9023                 :             :             {
    9024                 :        3288 :               if (i >= HOST_BITS_PER_WIDE_INT)
    9025                 :             :                 break;
    9026                 :        3284 :               rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
    9027                 :        3284 :               rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
    9028                 :        6568 :               poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
    9029                 :             : 
    9030                 :        3284 :               ASSERT_RTX_EQ (scalar_reg,
    9031                 :             :                              simplify_gen_subreg (inner_mode, vm,
    9032                 :             :                                                   mode, offset));
    9033                 :             :             }
    9034                 :             :         }
    9035                 :             :     }
    9036                 :             : 
    9037                 :             :   /* Test a scalar subreg of a VEC_DUPLICATE.  */
    9038                 :         224 :   poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
    9039                 :         224 :   ASSERT_RTX_EQ (scalar_reg,
    9040                 :             :                  simplify_gen_subreg (inner_mode, duplicate,
    9041                 :             :                                       mode, offset));
    9042                 :             : 
    9043                 :         224 :   machine_mode narrower_mode;
    9044                 :         224 :   if (maybe_ne (nunits, 2U)
    9045                 :         184 :       && multiple_p (nunits, 2)
    9046                 :         396 :       && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
    9047                 :         396 :       && VECTOR_MODE_P (narrower_mode))
    9048                 :             :     {
    9049                 :             :       /* Test VEC_DUPLICATE of a vector.  */
    9050                 :         172 :       rtx_vector_builder nbuilder (narrower_mode, 2, 1);
    9051                 :         172 :       nbuilder.quick_push (const0_rtx);
    9052                 :         172 :       nbuilder.quick_push (const1_rtx);
    9053                 :         172 :       rtx_vector_builder builder (mode, 2, 1);
    9054                 :         172 :       builder.quick_push (const0_rtx);
    9055                 :         172 :       builder.quick_push (const1_rtx);
    9056                 :         172 :       ASSERT_RTX_EQ (builder.build (),
    9057                 :             :                      simplify_unary_operation (VEC_DUPLICATE, mode,
    9058                 :             :                                                nbuilder.build (),
    9059                 :             :                                                narrower_mode));
    9060                 :             : 
    9061                 :             :       /* Test VEC_SELECT of a vector.  */
    9062                 :         172 :       rtx vec_par
    9063                 :         172 :         = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
    9064                 :         172 :       rtx narrower_duplicate
    9065                 :         172 :         = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
    9066                 :         172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9067                 :             :                      simplify_binary_operation (VEC_SELECT, narrower_mode,
    9068                 :             :                                                 duplicate, vec_par));
    9069                 :             : 
    9070                 :             :       /* Test a vector subreg of a VEC_DUPLICATE.  */
    9071                 :         172 :       poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
    9072                 :         172 :       ASSERT_RTX_EQ (narrower_duplicate,
    9073                 :             :                      simplify_gen_subreg (narrower_mode, duplicate,
    9074                 :             :                                           mode, offset));
    9075                 :         172 :     }
    9076                 :         224 : }
    9077                 :             : 
    9078                 :             : /* Test vector simplifications involving VEC_SERIES in which the
    9079                 :             :    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
    9080                 :             :    register that holds one element of MODE.  */
    9081                 :             : 
    9082                 :             : static void
    9083                 :          92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
    9084                 :             : {
    9085                 :             :   /* Test unary cases with VEC_SERIES arguments.  */
    9086                 :          92 :   scalar_mode inner_mode = GET_MODE_INNER (mode);
    9087                 :          92 :   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
    9088                 :          92 :   rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
    9089                 :          92 :   rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
    9090                 :          92 :   rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
    9091                 :          92 :   rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
    9092                 :          92 :   rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
    9093                 :          92 :   rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
    9094                 :          92 :   rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
    9095                 :             :                                          neg_scalar_reg);
    9096                 :          92 :   ASSERT_RTX_EQ (series_0_r,
    9097                 :             :                  simplify_unary_operation (NEG, mode, series_0_nr, mode));
    9098                 :          92 :   ASSERT_RTX_EQ (series_r_m1,
    9099                 :             :                  simplify_unary_operation (NEG, mode, series_nr_1, mode));
    9100                 :          92 :   ASSERT_RTX_EQ (series_r_r,
    9101                 :             :                  simplify_unary_operation (NEG, mode, series_nr_nr, mode));
    9102                 :             : 
    9103                 :             :   /* Test that a VEC_SERIES with a zero step is simplified away.  */
    9104                 :          92 :   ASSERT_RTX_EQ (duplicate,
    9105                 :             :                  simplify_binary_operation (VEC_SERIES, mode,
    9106                 :             :                                             scalar_reg, const0_rtx));
    9107                 :             : 
    9108                 :             :   /* Test PLUS and MINUS with VEC_SERIES.  */
    9109                 :          92 :   rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
    9110                 :          92 :   rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
    9111                 :          92 :   rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
    9112                 :          92 :   ASSERT_RTX_EQ (series_r_r,
    9113                 :             :                  simplify_binary_operation (PLUS, mode, series_0_r,
    9114                 :             :                                             duplicate));
    9115                 :          92 :   ASSERT_RTX_EQ (series_r_1,
    9116                 :             :                  simplify_binary_operation (PLUS, mode, duplicate,
    9117                 :             :                                             series_0_1));
    9118                 :          92 :   ASSERT_RTX_EQ (series_r_m1,
    9119                 :             :                  simplify_binary_operation (PLUS, mode, duplicate,
    9120                 :             :                                             series_0_m1));
    9121                 :          92 :   ASSERT_RTX_EQ (series_0_r,
    9122                 :             :                  simplify_binary_operation (MINUS, mode, series_r_r,
    9123                 :             :                                             duplicate));
    9124                 :          92 :   ASSERT_RTX_EQ (series_r_m1,
    9125                 :             :                  simplify_binary_operation (MINUS, mode, duplicate,
    9126                 :             :                                             series_0_1));
    9127                 :          92 :   ASSERT_RTX_EQ (series_r_1,
    9128                 :             :                  simplify_binary_operation (MINUS, mode, duplicate,
    9129                 :             :                                             series_0_m1));
    9130                 :          92 :   ASSERT_RTX_EQ (series_0_m1,
    9131                 :             :                  simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
    9132                 :             :                                             constm1_rtx));
    9133                 :             : 
    9134                 :             :   /* Test NEG on constant vector series.  */
    9135                 :          92 :   ASSERT_RTX_EQ (series_0_m1,
    9136                 :             :                  simplify_unary_operation (NEG, mode, series_0_1, mode));
    9137                 :          92 :   ASSERT_RTX_EQ (series_0_1,
    9138                 :             :                  simplify_unary_operation (NEG, mode, series_0_m1, mode));
    9139                 :             : 
    9140                 :             :   /* Test PLUS and MINUS on constant vector series.  */
    9141                 :          92 :   rtx scalar2 = gen_int_mode (2, inner_mode);
    9142                 :          92 :   rtx scalar3 = gen_int_mode (3, inner_mode);
    9143                 :          92 :   rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
    9144                 :          92 :   rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
    9145                 :          92 :   rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
    9146                 :          92 :   ASSERT_RTX_EQ (series_1_1,
    9147                 :             :                  simplify_binary_operation (PLUS, mode, series_0_1,
    9148                 :             :                                             CONST1_RTX (mode)));
    9149                 :          92 :   ASSERT_RTX_EQ (series_0_m1,
    9150                 :             :                  simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
    9151                 :             :                                             series_0_m1));
    9152                 :          92 :   ASSERT_RTX_EQ (series_1_3,
    9153                 :             :                  simplify_binary_operation (PLUS, mode, series_1_1,
    9154                 :             :                                             series_0_2));
    9155                 :          92 :   ASSERT_RTX_EQ (series_0_1,
    9156                 :             :                  simplify_binary_operation (MINUS, mode, series_1_1,
    9157                 :             :                                             CONST1_RTX (mode)));
    9158                 :          92 :   ASSERT_RTX_EQ (series_1_1,
    9159                 :             :                  simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
    9160                 :             :                                             series_0_m1));
    9161                 :          92 :   ASSERT_RTX_EQ (series_1_1,
    9162                 :             :                  simplify_binary_operation (MINUS, mode, series_1_3,
    9163                 :             :                                             series_0_2));
    9164                 :             : 
    9165                 :             :   /* Test MULT between constant vectors.  */
    9166                 :          92 :   rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
    9167                 :          92 :   rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
    9168                 :          92 :   rtx scalar9 = gen_int_mode (9, inner_mode);
    9169                 :          92 :   rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
    9170                 :          92 :   ASSERT_RTX_EQ (series_0_2,
    9171                 :             :                  simplify_binary_operation (MULT, mode, series_0_1, vec2));
    9172                 :          92 :   ASSERT_RTX_EQ (series_3_9,
    9173                 :             :                  simplify_binary_operation (MULT, mode, vec3, series_1_3));
    9174                 :          92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9175                 :             :     ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
    9176                 :             :                                              series_0_1));
    9177                 :             : 
    9178                 :             :   /* Test ASHIFT between constant vectors.  */
    9179                 :          92 :   ASSERT_RTX_EQ (series_0_2,
    9180                 :             :                  simplify_binary_operation (ASHIFT, mode, series_0_1,
    9181                 :             :                                             CONST1_RTX (mode)));
    9182                 :          92 :   if (!GET_MODE_NUNITS (mode).is_constant ())
    9183                 :             :     ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
    9184                 :             :                                              series_0_1));
    9185                 :          92 : }
    9186                 :             : 
    9187                 :             : static rtx
    9188                 :        3136 : simplify_merge_mask (rtx x, rtx mask, int op)
    9189                 :             : {
    9190                 :           0 :   return simplify_context ().simplify_merge_mask (x, mask, op);
    9191                 :             : }
    9192                 :             : 
    9193                 :             : /* Verify simplify_merge_mask works correctly.  */
    9194                 :             : 
    9195                 :             : static void
    9196                 :         224 : test_vec_merge (machine_mode mode)
    9197                 :             : {
    9198                 :         224 :   rtx op0 = make_test_reg (mode);
    9199                 :         224 :   rtx op1 = make_test_reg (mode);
    9200                 :         224 :   rtx op2 = make_test_reg (mode);
    9201                 :         224 :   rtx op3 = make_test_reg (mode);
    9202                 :         224 :   rtx op4 = make_test_reg (mode);
    9203                 :         224 :   rtx op5 = make_test_reg (mode);
    9204                 :         224 :   rtx mask1 = make_test_reg (SImode);
    9205                 :         224 :   rtx mask2 = make_test_reg (SImode);
    9206                 :         224 :   rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
    9207                 :         224 :   rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
    9208                 :         224 :   rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
    9209                 :             : 
    9210                 :             :   /* Simple vec_merge.  */
    9211                 :         224 :   ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
    9212                 :         224 :   ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
    9213                 :         224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
    9214                 :         224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
    9215                 :             : 
    9216                 :             :   /* Nested vec_merge.
    9217                 :             :      It's tempting to make this simplify right down to opN, but we don't
    9218                 :             :      because all the simplify_* functions assume that the operands have
    9219                 :             :      already been simplified.  */
    9220                 :         224 :   rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
    9221                 :         224 :   ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
    9222                 :         224 :   ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
    9223                 :             : 
    9224                 :             :   /* Intermediate unary op. */
    9225                 :         224 :   rtx unop = gen_rtx_NOT (mode, vm1);
    9226                 :         224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
    9227                 :             :                  simplify_merge_mask (unop, mask1, 0));
    9228                 :         224 :   ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
    9229                 :             :                  simplify_merge_mask (unop, mask1, 1));
    9230                 :             : 
    9231                 :             :   /* Intermediate binary op. */
    9232                 :         224 :   rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
    9233                 :         224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
    9234                 :             :                  simplify_merge_mask (binop, mask1, 0));
    9235                 :         224 :   ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
    9236                 :             :                  simplify_merge_mask (binop, mask1, 1));
    9237                 :             : 
    9238                 :             :   /* Intermediate ternary op. */
    9239                 :         224 :   rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
    9240                 :         224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
    9241                 :             :                  simplify_merge_mask (tenop, mask1, 0));
    9242                 :         224 :   ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
    9243                 :             :                  simplify_merge_mask (tenop, mask1, 1));
    9244                 :             : 
    9245                 :             :   /* Side effects.  */
    9246                 :         224 :   rtx badop0 = gen_rtx_PRE_INC (mode, op0);
    9247                 :         224 :   rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
    9248                 :         224 :   ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
    9249                 :         224 :   ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
    9250                 :             : 
    9251                 :             :   /* Called indirectly.  */
    9252                 :         224 :   ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
    9253                 :             :                  simplify_rtx (nvm));
    9254                 :         224 : }
    9255                 :             : 
    9256                 :             : /* Test that vector rotate formation works at RTL level.  Try various
    9257                 :             :    combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)).  */
    9258                 :             : 
    9259                 :             : static void
    9260                 :          92 : test_vector_rotate (rtx reg)
    9261                 :             : {
    9262                 :          92 :   machine_mode mode = GET_MODE (reg);
    9263                 :          92 :   unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
    9264                 :          92 :   rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
    9265                 :          92 :   rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
    9266                 :          92 :   lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
    9267                 :          92 :   rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9268                 :          92 :   rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
    9269                 :             :   /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x).  */
    9270                 :          92 :   ASSERT_RTX_EQ (rotate_rtx,
    9271                 :             :              simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
    9272                 :          92 :   ASSERT_RTX_EQ (rotate_rtx,
    9273                 :             :              simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
    9274                 :          92 :   ASSERT_RTX_EQ (rotate_rtx,
    9275                 :             :              simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
    9276                 :             : 
    9277                 :             :   /* Don't go through every possible rotate amount to save execution time.
    9278                 :             :      Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
    9279                 :             :      other bswap operations sometimes. Go through just the odd amounts.  */
    9280                 :        1380 :   for (unsigned i = 3; i < bitwidth - 2; i += 2)
    9281                 :             :     {
    9282                 :        1288 :       rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
    9283                 :        1288 :       rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
    9284                 :        1288 :       lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
    9285                 :        1288 :       lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
    9286                 :        1288 :       rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
    9287                 :        1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9288                 :             :                  simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
    9289                 :        1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9290                 :             :                  simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
    9291                 :        1288 :       ASSERT_RTX_EQ (rotate_rtx,
    9292                 :             :                  simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
    9293                 :             :     }
    9294                 :          92 : }
    9295                 :             : 
    9296                 :             : /* Test subregs of integer vector constant X, trying elements in
    9297                 :             :    the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
    9298                 :             :    where NELTS is the number of elements in X.  Subregs involving
    9299                 :             :    elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail.  */
    9300                 :             : 
    9301                 :             : static void
    9302                 :         276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
    9303                 :             :                            unsigned int first_valid = 0)
    9304                 :             : {
    9305                 :         276 :   machine_mode inner_mode = GET_MODE (x);
    9306                 :         276 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9307                 :             : 
    9308                 :       34500 :   for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
    9309                 :             :     {
    9310                 :       34224 :       machine_mode outer_mode = (machine_mode) modei;
    9311                 :       34224 :       if (!VECTOR_MODE_P (outer_mode))
    9312                 :       18768 :         continue;
    9313                 :             : 
    9314                 :       15456 :       unsigned int outer_nunits;
    9315                 :       15456 :       if (GET_MODE_INNER (outer_mode) == int_mode
    9316                 :        1932 :           && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
    9317                 :       20412 :           && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
    9318                 :             :         {
    9319                 :             :           /* Test subregs in which the outer mode is a smaller,
    9320                 :             :              constant-sized vector of the same element type.  */
    9321                 :        1092 :           unsigned int limit
    9322                 :        1092 :             = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
    9323                 :        8028 :           for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
    9324                 :             :             {
    9325                 :        6936 :               rtx expected = NULL_RTX;
    9326                 :        6936 :               if (elt >= first_valid)
    9327                 :             :                 {
    9328                 :        6936 :                   rtx_vector_builder builder (outer_mode, outer_nunits, 1);
    9329                 :       39768 :                   for (unsigned int i = 0; i < outer_nunits; ++i)
    9330                 :       32832 :                     builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
    9331                 :        6936 :                   expected = builder.build ();
    9332                 :        6936 :                 }
    9333                 :       13872 :               poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
    9334                 :        6936 :               ASSERT_RTX_EQ (expected,
    9335                 :             :                              simplify_subreg (outer_mode, x,
    9336                 :             :                                               inner_mode, byte));
    9337                 :             :             }
    9338                 :             :         }
    9339                 :       28728 :       else if (known_eq (GET_MODE_SIZE (outer_mode),
    9340                 :             :                          GET_MODE_SIZE (inner_mode))
    9341                 :        2040 :                && known_eq (elt_bias, 0U)
    9342                 :        2040 :                && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
    9343                 :           0 :                    || known_eq (GET_MODE_BITSIZE (outer_mode),
    9344                 :             :                                 GET_MODE_NUNITS (outer_mode)))
    9345                 :        2040 :                && (!FLOAT_MODE_P (outer_mode)
    9346                 :       15876 :                    || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
    9347                 :        1104 :                        == GET_MODE_UNIT_PRECISION (outer_mode)))
    9348                 :       14364 :                && (GET_MODE_SIZE (inner_mode).is_constant ()
    9349                 :             :                    || !CONST_VECTOR_STEPPED_P (x)))
    9350                 :             :         {
    9351                 :             :           /* Try converting to OUTER_MODE and back.  */
    9352                 :        1800 :           rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
    9353                 :        1800 :           ASSERT_TRUE (outer_x != NULL_RTX);
    9354                 :        1800 :           ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
    9355                 :             :                                              outer_mode, 0));
    9356                 :             :         }
    9357                 :             :     }
    9358                 :             : 
    9359                 :         276 :   if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
    9360                 :             :     {
    9361                 :             :       /* Test each byte in the element range.  */
    9362                 :         276 :       unsigned int limit
    9363                 :         276 :         = constant_lower_bound (GET_MODE_SIZE (inner_mode));
    9364                 :       14604 :       for (unsigned int i = 0; i < limit; ++i)
    9365                 :             :         {
    9366                 :       14328 :           unsigned int elt = i / GET_MODE_SIZE (int_mode);
    9367                 :       14328 :           rtx expected = NULL_RTX;
    9368                 :       14328 :           if (elt >= first_valid)
    9369                 :             :             {
    9370                 :       14328 :               unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
    9371                 :       14328 :               if (BYTES_BIG_ENDIAN)
    9372                 :             :                 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
    9373                 :       14328 :               rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
    9374                 :       14328 :               wide_int shifted_elt
    9375                 :       14328 :                 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
    9376                 :       14328 :               expected = immed_wide_int_const (shifted_elt, QImode);
    9377                 :       14328 :             }
    9378                 :       28656 :           poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
    9379                 :       14328 :           ASSERT_RTX_EQ (expected,
    9380                 :             :                          simplify_subreg (QImode, x, inner_mode, byte));
    9381                 :             :         }
    9382                 :             :     }
    9383                 :         276 : }
    9384                 :             : 
    9385                 :             : /* Test constant subregs of integer vector mode INNER_MODE, using 1
    9386                 :             :    element per pattern.  */
    9387                 :             : 
    9388                 :             : static void
    9389                 :          92 : test_vector_subregs_repeating (machine_mode inner_mode)
    9390                 :             : {
    9391                 :         184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
    9392                 :          92 :   unsigned int min_nunits = constant_lower_bound (nunits);
    9393                 :          92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9394                 :          92 :   unsigned int count = gcd (min_nunits, 8);
    9395                 :             : 
    9396                 :          92 :   rtx_vector_builder builder (inner_mode, count, 1);
    9397                 :         684 :   for (unsigned int i = 0; i < count; ++i)
    9398                 :         592 :     builder.quick_push (gen_int_mode (8 - i, int_mode));
    9399                 :          92 :   rtx x = builder.build ();
    9400                 :             : 
    9401                 :          92 :   test_vector_subregs_modes (x);
    9402                 :          92 :   if (!nunits.is_constant ())
    9403                 :             :     test_vector_subregs_modes (x, nunits - min_nunits);
    9404                 :          92 : }
    9405                 :             : 
    9406                 :             : /* Test constant subregs of integer vector mode INNER_MODE, using 2
    9407                 :             :    elements per pattern.  */
    9408                 :             : 
    9409                 :             : static void
    9410                 :          92 : test_vector_subregs_fore_back (machine_mode inner_mode)
    9411                 :             : {
    9412                 :         184 :   poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
    9413                 :          92 :   unsigned int min_nunits = constant_lower_bound (nunits);
    9414                 :          92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9415                 :          92 :   unsigned int count = gcd (min_nunits, 4);
    9416                 :             : 
    9417                 :          92 :   rtx_vector_builder builder (inner_mode, count, 2);
    9418                 :         444 :   for (unsigned int i = 0; i < count; ++i)
    9419                 :         352 :     builder.quick_push (gen_int_mode (i, int_mode));
    9420                 :         444 :   for (unsigned int i = 0; i < count; ++i)
    9421                 :         352 :     builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
    9422                 :          92 :   rtx x = builder.build ();
    9423                 :             : 
    9424                 :          92 :   test_vector_subregs_modes (x);
    9425                 :          92 :   if (!nunits.is_constant ())
    9426                 :             :     test_vector_subregs_modes (x, nunits - min_nunits, count);
    9427                 :          92 : }
    9428                 :             : 
    9429                 :             : /* Test constant subregs of integer vector mode INNER_MODE, using 3
    9430                 :             :    elements per pattern.  */
    9431                 :             : 
    9432                 :             : static void
    9433                 :          92 : test_vector_subregs_stepped (machine_mode inner_mode)
    9434                 :             : {
    9435                 :             :   /* Build { 0, 1, 2, 3, ... }.  */
    9436                 :          92 :   scalar_mode int_mode = GET_MODE_INNER (inner_mode);
    9437                 :          92 :   rtx_vector_builder builder (inner_mode, 1, 3);
    9438                 :         368 :   for (unsigned int i = 0; i < 3; ++i)
    9439                 :         276 :     builder.quick_push (gen_int_mode (i, int_mode));
    9440                 :          92 :   rtx x = builder.build ();
    9441                 :             : 
    9442                 :          92 :   test_vector_subregs_modes (x);
    9443                 :          92 : }
    9444                 :             : 
    9445                 :             : /* Test constant subregs of integer vector mode INNER_MODE.  */
    9446                 :             : 
    9447                 :             : static void
    9448                 :          92 : test_vector_subregs (machine_mode inner_mode)
    9449                 :             : {
    9450                 :          92 :   test_vector_subregs_repeating (inner_mode);
    9451                 :          92 :   test_vector_subregs_fore_back (inner_mode);
    9452                 :          92 :   test_vector_subregs_stepped (inner_mode);
    9453                 :          92 : }
    9454                 :             : 
    9455                 :             : /* Verify some simplifications involving vectors.  */
    9456                 :             : 
    9457                 :             : static void
    9458                 :           4 : test_vector_ops ()
    9459                 :             : {
    9460                 :         500 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
    9461                 :             :     {
    9462                 :         496 :       machine_mode mode = (machine_mode) i;
    9463                 :         496 :       if (VECTOR_MODE_P (mode))
    9464                 :             :         {
    9465                 :         448 :           rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
    9466                 :         224 :           test_vector_ops_duplicate (mode, scalar_reg);
    9467                 :         224 :           rtx vector_reg = make_test_reg (mode);
    9468                 :         224 :           if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
    9469                 :         348 :               && maybe_gt (GET_MODE_NUNITS (mode), 2))
    9470                 :             :             {
    9471                 :          92 :               test_vector_ops_series (mode, scalar_reg);
    9472                 :          92 :               test_vector_subregs (mode);
    9473                 :          92 :               test_vector_rotate (vector_reg);
    9474                 :             :             }
    9475                 :         224 :           test_vec_merge (mode);
    9476                 :             :         }
    9477                 :             :     }
    9478                 :           4 : }
    9479                 :             : 
    9480                 :             : template<unsigned int N>
    9481                 :             : struct simplify_const_poly_int_tests
    9482                 :             : {
    9483                 :             :   static void run ();
    9484                 :             : };
    9485                 :             : 
    9486                 :             : template<>
    9487                 :             : struct simplify_const_poly_int_tests<1>
    9488                 :             : {
    9489                 :             :   static void run () {}
    9490                 :             : };
    9491                 :             : 
    9492                 :             : /* Test various CONST_POLY_INT properties.  */
    9493                 :             : 
    9494                 :             : template<unsigned int N>
    9495                 :             : void
    9496                 :             : simplify_const_poly_int_tests<N>::run ()
    9497                 :             : {
    9498                 :             :   using poly_int64 = poly_int<N, HOST_WIDE_INT>;
    9499                 :             :   rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
    9500                 :             :   rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
    9501                 :             :   rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
    9502                 :             :   rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
    9503                 :             :   rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
    9504                 :             :   rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
    9505                 :             :   rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
    9506                 :             :   rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
    9507                 :             :   rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
    9508                 :             :   rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
    9509                 :             :   rtx two = GEN_INT (2);
    9510                 :             :   rtx six = GEN_INT (6);
    9511                 :             :   poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
    9512                 :             : 
    9513                 :             :   /* These tests only try limited operation combinations.  Fuller arithmetic
    9514                 :             :      testing is done directly on poly_ints.  */
    9515                 :             :   ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
    9516                 :             :   ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
    9517                 :             :   ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
    9518                 :             :   ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
    9519                 :             :   ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
    9520                 :             :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
    9521                 :             :   ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
    9522                 :             :   ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
    9523                 :             :   ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
    9524                 :             :   ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
    9525                 :             :   ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
    9526                 :             : }
    9527                 :             : 
    9528                 :             : /* Run all of the selftests within this file.  */
    9529                 :             : 
    9530                 :             : void
    9531                 :           4 : simplify_rtx_cc_tests ()
    9532                 :             : {
    9533                 :           4 :   test_scalar_ops ();
    9534                 :           4 :   test_vector_ops ();
    9535                 :           4 :   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
    9536                 :           4 : }
    9537                 :             : 
    9538                 :             : } // namespace selftest
    9539                 :             : 
    9540                 :             : #endif /* CHECKING_P */
        

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