xref: /dragonfly/contrib/gcc-8.0/gcc/simplify-rtx.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1 /* RTL simplification functions for GNU compiler.
2    Copyright (C) 1987-2018 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 
39 /* Simplification and canonicalization of RTL.  */
40 
41 /* Much code operates on (low, high) pairs; the low value is an
42    unsigned wide int, the high value a signed wide int.  We
43    occasionally need to sign extend from low to high as if low were a
44    signed wide int.  */
45 #define HWI_SIGN_EXTEND(low) \
46   ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
47 
48 static rtx neg_const_int (machine_mode, const_rtx);
49 static bool plus_minus_operand_p (const_rtx);
50 static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx);
51 static rtx simplify_associative_operation (enum rtx_code, machine_mode,
52                                                      rtx, rtx);
53 static rtx simplify_relational_operation_1 (enum rtx_code, machine_mode,
54                                                       machine_mode, rtx, rtx);
55 static rtx simplify_unary_operation_1 (enum rtx_code, machine_mode, rtx);
56 static rtx simplify_binary_operation_1 (enum rtx_code, machine_mode,
57                                                   rtx, rtx, rtx, rtx);
58 
59 /* Negate a CONST_INT rtx.  */
60 static rtx
neg_const_int(machine_mode mode,const_rtx i)61 neg_const_int (machine_mode mode, const_rtx i)
62 {
63   unsigned HOST_WIDE_INT val = -UINTVAL (i);
64 
65   if (!HWI_COMPUTABLE_MODE_P (mode)
66       && val == UINTVAL (i))
67     return simplify_const_unary_operation (NEG, mode, CONST_CAST_RTX (i),
68                                                      mode);
69   return gen_int_mode (val, mode);
70 }
71 
72 /* Test whether expression, X, is an immediate constant that represents
73    the most significant bit of machine mode MODE.  */
74 
75 bool
mode_signbit_p(machine_mode mode,const_rtx x)76 mode_signbit_p (machine_mode mode, const_rtx x)
77 {
78   unsigned HOST_WIDE_INT val;
79   unsigned int width;
80   scalar_int_mode int_mode;
81 
82   if (!is_int_mode (mode, &int_mode))
83     return false;
84 
85   width = GET_MODE_PRECISION (int_mode);
86   if (width == 0)
87     return false;
88 
89   if (width <= HOST_BITS_PER_WIDE_INT
90       && CONST_INT_P (x))
91     val = INTVAL (x);
92 #if TARGET_SUPPORTS_WIDE_INT
93   else if (CONST_WIDE_INT_P (x))
94     {
95       unsigned int i;
96       unsigned int elts = CONST_WIDE_INT_NUNITS (x);
97       if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
98           return false;
99       for (i = 0; i < elts - 1; i++)
100           if (CONST_WIDE_INT_ELT (x, i) != 0)
101             return false;
102       val = CONST_WIDE_INT_ELT (x, elts - 1);
103       width %= HOST_BITS_PER_WIDE_INT;
104       if (width == 0)
105           width = HOST_BITS_PER_WIDE_INT;
106     }
107 #else
108   else if (width <= HOST_BITS_PER_DOUBLE_INT
109              && CONST_DOUBLE_AS_INT_P (x)
110              && CONST_DOUBLE_LOW (x) == 0)
111     {
112       val = CONST_DOUBLE_HIGH (x);
113       width -= HOST_BITS_PER_WIDE_INT;
114     }
115 #endif
116   else
117     /* X is not an integer constant.  */
118     return false;
119 
120   if (width < HOST_BITS_PER_WIDE_INT)
121     val &= (HOST_WIDE_INT_1U << width) - 1;
122   return val == (HOST_WIDE_INT_1U << (width - 1));
123 }
124 
125 /* Test whether VAL is equal to the most significant bit of mode MODE
126    (after masking with the mode mask of MODE).  Returns false if the
127    precision of MODE is too large to handle.  */
128 
129 bool
val_signbit_p(machine_mode mode,unsigned HOST_WIDE_INT val)130 val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
131 {
132   unsigned int width;
133   scalar_int_mode int_mode;
134 
135   if (!is_int_mode (mode, &int_mode))
136     return false;
137 
138   width = GET_MODE_PRECISION (int_mode);
139   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
140     return false;
141 
142   val &= GET_MODE_MASK (int_mode);
143   return val == (HOST_WIDE_INT_1U << (width - 1));
144 }
145 
146 /* Test whether the most significant bit of mode MODE is set in VAL.
147    Returns false if the precision of MODE is too large to handle.  */
148 bool
val_signbit_known_set_p(machine_mode mode,unsigned HOST_WIDE_INT val)149 val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
150 {
151   unsigned int width;
152 
153   scalar_int_mode int_mode;
154   if (!is_int_mode (mode, &int_mode))
155     return false;
156 
157   width = GET_MODE_PRECISION (int_mode);
158   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
159     return false;
160 
161   val &= HOST_WIDE_INT_1U << (width - 1);
162   return val != 0;
163 }
164 
165 /* Test whether the most significant bit of mode MODE is clear in VAL.
166    Returns false if the precision of MODE is too large to handle.  */
167 bool
val_signbit_known_clear_p(machine_mode mode,unsigned HOST_WIDE_INT val)168 val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
169 {
170   unsigned int width;
171 
172   scalar_int_mode int_mode;
173   if (!is_int_mode (mode, &int_mode))
174     return false;
175 
176   width = GET_MODE_PRECISION (int_mode);
177   if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
178     return false;
179 
180   val &= HOST_WIDE_INT_1U << (width - 1);
181   return val == 0;
182 }
183 
184 /* Make a binary operation by properly ordering the operands and
185    seeing if the expression folds.  */
186 
187 rtx
simplify_gen_binary(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)188 simplify_gen_binary (enum rtx_code code, machine_mode mode, rtx op0,
189                          rtx op1)
190 {
191   rtx tem;
192 
193   /* If this simplifies, do it.  */
194   tem = simplify_binary_operation (code, mode, op0, op1);
195   if (tem)
196     return tem;
197 
198   /* Put complex operands first and constants second if commutative.  */
199   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
200       && swap_commutative_operands_p (op0, op1))
201     std::swap (op0, op1);
202 
203   return gen_rtx_fmt_ee (code, mode, op0, op1);
204 }
205 
206 /* If X is a MEM referencing the constant pool, return the real value.
207    Otherwise return X.  */
208 rtx
avoid_constant_pool_reference(rtx x)209 avoid_constant_pool_reference (rtx x)
210 {
211   rtx c, tmp, addr;
212   machine_mode cmode;
213   HOST_WIDE_INT offset = 0;
214 
215   switch (GET_CODE (x))
216     {
217     case MEM:
218       break;
219 
220     case FLOAT_EXTEND:
221       /* Handle float extensions of constant pool references.  */
222       tmp = XEXP (x, 0);
223       c = avoid_constant_pool_reference (tmp);
224       if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
225           return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
226                                                        GET_MODE (x));
227       return x;
228 
229     default:
230       return x;
231     }
232 
233   if (GET_MODE (x) == BLKmode)
234     return x;
235 
236   addr = XEXP (x, 0);
237 
238   /* Call target hook to avoid the effects of -fpic etc....  */
239   addr = targetm.delegitimize_address (addr);
240 
241   /* Split the address into a base and integer offset.  */
242   if (GET_CODE (addr) == CONST
243       && GET_CODE (XEXP (addr, 0)) == PLUS
244       && CONST_INT_P (XEXP (XEXP (addr, 0), 1)))
245     {
246       offset = INTVAL (XEXP (XEXP (addr, 0), 1));
247       addr = XEXP (XEXP (addr, 0), 0);
248     }
249 
250   if (GET_CODE (addr) == LO_SUM)
251     addr = XEXP (addr, 1);
252 
253   /* If this is a constant pool reference, we can turn it into its
254      constant and hope that simplifications happen.  */
255   if (GET_CODE (addr) == SYMBOL_REF
256       && CONSTANT_POOL_ADDRESS_P (addr))
257     {
258       c = get_pool_constant (addr);
259       cmode = get_pool_mode (addr);
260 
261       /* If we're accessing the constant in a different mode than it was
262          originally stored, attempt to fix that up via subreg simplifications.
263          If that fails we have no choice but to return the original memory.  */
264       if (offset == 0 && cmode == GET_MODE (x))
265           return c;
266       else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
267         {
268           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
269           if (tem && CONSTANT_P (tem))
270             return tem;
271         }
272     }
273 
274   return x;
275 }
276 
277 /* Simplify a MEM based on its attributes.  This is the default
278    delegitimize_address target hook, and it's recommended that every
279    overrider call it.  */
280 
281 rtx
delegitimize_mem_from_attrs(rtx x)282 delegitimize_mem_from_attrs (rtx x)
283 {
284   /* MEMs without MEM_OFFSETs may have been offset, so we can't just
285      use their base addresses as equivalent.  */
286   if (MEM_P (x)
287       && MEM_EXPR (x)
288       && MEM_OFFSET_KNOWN_P (x))
289     {
290       tree decl = MEM_EXPR (x);
291       machine_mode mode = GET_MODE (x);
292       poly_int64 offset = 0;
293 
294       switch (TREE_CODE (decl))
295           {
296           default:
297             decl = NULL;
298             break;
299 
300           case VAR_DECL:
301             break;
302 
303           case ARRAY_REF:
304           case ARRAY_RANGE_REF:
305           case COMPONENT_REF:
306           case BIT_FIELD_REF:
307           case REALPART_EXPR:
308           case IMAGPART_EXPR:
309           case VIEW_CONVERT_EXPR:
310             {
311               poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
312               tree toffset;
313               int unsignedp, reversep, volatilep = 0;
314 
315               decl
316                 = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
317                                              &unsignedp, &reversep, &volatilep);
318               if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
319                     || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
320                     || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
321                 decl = NULL;
322               else
323                 offset += bytepos + toffset_val;
324               break;
325             }
326           }
327 
328       if (decl
329             && mode == GET_MODE (x)
330             && VAR_P (decl)
331             && (TREE_STATIC (decl)
332                 || DECL_THREAD_LOCAL_P (decl))
333             && DECL_RTL_SET_P (decl)
334             && MEM_P (DECL_RTL (decl)))
335           {
336             rtx newx;
337 
338             offset += MEM_OFFSET (x);
339 
340             newx = DECL_RTL (decl);
341 
342             if (MEM_P (newx))
343               {
344                 rtx n = XEXP (newx, 0), o = XEXP (x, 0);
345                 poly_int64 n_offset, o_offset;
346 
347                 /* Avoid creating a new MEM needlessly if we already had
348                      the same address.  We do if there's no OFFSET and the
349                      old address X is identical to NEWX, or if X is of the
350                      form (plus NEWX OFFSET), or the NEWX is of the form
351                      (plus Y (const_int Z)) and X is that with the offset
352                      added: (plus Y (const_int Z+OFFSET)).  */
353                 n = strip_offset (n, &n_offset);
354                 o = strip_offset (o, &o_offset);
355                 if (!(known_eq (o_offset, n_offset + offset)
356                         && rtx_equal_p (o, n)))
357                     x = adjust_address_nv (newx, mode, offset);
358               }
359             else if (GET_MODE (x) == GET_MODE (newx)
360                        && known_eq (offset, 0))
361               x = newx;
362           }
363     }
364 
365   return x;
366 }
367 
368 /* Make a unary operation by first seeing if it folds and otherwise making
369    the specified operation.  */
370 
371 rtx
simplify_gen_unary(enum rtx_code code,machine_mode mode,rtx op,machine_mode op_mode)372 simplify_gen_unary (enum rtx_code code, machine_mode mode, rtx op,
373                         machine_mode op_mode)
374 {
375   rtx tem;
376 
377   /* If this simplifies, use it.  */
378   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
379     return tem;
380 
381   return gen_rtx_fmt_e (code, mode, op);
382 }
383 
384 /* Likewise for ternary operations.  */
385 
386 rtx
simplify_gen_ternary(enum rtx_code code,machine_mode mode,machine_mode op0_mode,rtx op0,rtx op1,rtx op2)387 simplify_gen_ternary (enum rtx_code code, machine_mode mode,
388                           machine_mode op0_mode, rtx op0, rtx op1, rtx op2)
389 {
390   rtx tem;
391 
392   /* If this simplifies, use it.  */
393   if ((tem = simplify_ternary_operation (code, mode, op0_mode,
394                                                    op0, op1, op2)) != 0)
395     return tem;
396 
397   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
398 }
399 
400 /* Likewise, for relational operations.
401    CMP_MODE specifies mode comparison is done in.  */
402 
403 rtx
simplify_gen_relational(enum rtx_code code,machine_mode mode,machine_mode cmp_mode,rtx op0,rtx op1)404 simplify_gen_relational (enum rtx_code code, machine_mode mode,
405                                machine_mode cmp_mode, rtx op0, rtx op1)
406 {
407   rtx tem;
408 
409   if ((tem = simplify_relational_operation (code, mode, cmp_mode,
410                                                       op0, op1)) != 0)
411     return tem;
412 
413   return gen_rtx_fmt_ee (code, mode, op0, op1);
414 }
415 
416 /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
417    and simplify the result.  If FN is non-NULL, call this callback on each
418    X, if it returns non-NULL, replace X with its return value and simplify the
419    result.  */
420 
421 rtx
simplify_replace_fn_rtx(rtx x,const_rtx old_rtx,rtx (* fn)(rtx,const_rtx,void *),void * data)422 simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
423                                rtx (*fn) (rtx, const_rtx, void *), void *data)
424 {
425   enum rtx_code code = GET_CODE (x);
426   machine_mode mode = GET_MODE (x);
427   machine_mode op_mode;
428   const char *fmt;
429   rtx op0, op1, op2, newx, op;
430   rtvec vec, newvec;
431   int i, j;
432 
433   if (__builtin_expect (fn != NULL, 0))
434     {
435       newx = fn (x, old_rtx, data);
436       if (newx)
437           return newx;
438     }
439   else if (rtx_equal_p (x, old_rtx))
440     return copy_rtx ((rtx) data);
441 
442   switch (GET_RTX_CLASS (code))
443     {
444     case RTX_UNARY:
445       op0 = XEXP (x, 0);
446       op_mode = GET_MODE (op0);
447       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
448       if (op0 == XEXP (x, 0))
449           return x;
450       return simplify_gen_unary (code, mode, op0, op_mode);
451 
452     case RTX_BIN_ARITH:
453     case RTX_COMM_ARITH:
454       op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
455       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
456       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
457           return x;
458       return simplify_gen_binary (code, mode, op0, op1);
459 
460     case RTX_COMPARE:
461     case RTX_COMM_COMPARE:
462       op0 = XEXP (x, 0);
463       op1 = XEXP (x, 1);
464       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
465       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
466       op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
467       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
468           return x;
469       return simplify_gen_relational (code, mode, op_mode, op0, op1);
470 
471     case RTX_TERNARY:
472     case RTX_BITFIELD_OPS:
473       op0 = XEXP (x, 0);
474       op_mode = GET_MODE (op0);
475       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
476       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
477       op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
478       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
479           return x;
480       if (op_mode == VOIDmode)
481           op_mode = GET_MODE (op0);
482       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
483 
484     case RTX_EXTRA:
485       if (code == SUBREG)
486           {
487             op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
488             if (op0 == SUBREG_REG (x))
489               return x;
490             op0 = simplify_gen_subreg (GET_MODE (x), op0,
491                                              GET_MODE (SUBREG_REG (x)),
492                                              SUBREG_BYTE (x));
493             return op0 ? op0 : x;
494           }
495       break;
496 
497     case RTX_OBJ:
498       if (code == MEM)
499           {
500             op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
501             if (op0 == XEXP (x, 0))
502               return x;
503             return replace_equiv_address_nv (x, op0);
504           }
505       else if (code == LO_SUM)
506           {
507             op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
508             op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
509 
510             /* (lo_sum (high x) y) -> y where x and y have the same base.  */
511             if (GET_CODE (op0) == HIGH)
512               {
513                 rtx base0, base1, offset0, offset1;
514                 split_const (XEXP (op0, 0), &base0, &offset0);
515                 split_const (op1, &base1, &offset1);
516                 if (rtx_equal_p (base0, base1))
517                     return op1;
518               }
519 
520             if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
521               return x;
522             return gen_rtx_LO_SUM (mode, op0, op1);
523           }
524       break;
525 
526     default:
527       break;
528     }
529 
530   newx = x;
531   fmt = GET_RTX_FORMAT (code);
532   for (i = 0; fmt[i]; i++)
533     switch (fmt[i])
534       {
535       case 'E':
536           vec = XVEC (x, i);
537           newvec = XVEC (newx, i);
538           for (j = 0; j < GET_NUM_ELEM (vec); j++)
539             {
540               op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
541                                                     old_rtx, fn, data);
542               if (op != RTVEC_ELT (vec, j))
543                 {
544                     if (newvec == vec)
545                       {
546                         newvec = shallow_copy_rtvec (vec);
547                         if (x == newx)
548                           newx = shallow_copy_rtx (x);
549                         XVEC (newx, i) = newvec;
550                       }
551                     RTVEC_ELT (newvec, j) = op;
552                 }
553             }
554           break;
555 
556       case 'e':
557           if (XEXP (x, i))
558             {
559               op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
560               if (op != XEXP (x, i))
561                 {
562                     if (x == newx)
563                       newx = shallow_copy_rtx (x);
564                     XEXP (newx, i) = op;
565                 }
566             }
567           break;
568       }
569   return newx;
570 }
571 
572 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
573    resulting RTX.  Return a new RTX which is as simplified as possible.  */
574 
575 rtx
simplify_replace_rtx(rtx x,const_rtx old_rtx,rtx new_rtx)576 simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
577 {
578   return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
579 }
580 
581 /* Try to simplify a MODE truncation of OP, which has OP_MODE.
582    Only handle cases where the truncated value is inherently an rvalue.
583 
584    RTL provides two ways of truncating a value:
585 
586    1. a lowpart subreg.  This form is only a truncation when both
587       the outer and inner modes (here MODE and OP_MODE respectively)
588       are scalar integers, and only then when the subreg is used as
589       an rvalue.
590 
591       It is only valid to form such truncating subregs if the
592       truncation requires no action by the target.  The onus for
593       proving this is on the creator of the subreg -- e.g. the
594       caller to simplify_subreg or simplify_gen_subreg -- and typically
595       involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
596 
597    2. a TRUNCATE.  This form handles both scalar and compound integers.
598 
599    The first form is preferred where valid.  However, the TRUNCATE
600    handling in simplify_unary_operation turns the second form into the
601    first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
602    so it is generally safe to form rvalue truncations using:
603 
604       simplify_gen_unary (TRUNCATE, ...)
605 
606    and leave simplify_unary_operation to work out which representation
607    should be used.
608 
609    Because of the proof requirements on (1), simplify_truncation must
610    also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
611    regardless of whether the outer truncation came from a SUBREG or a
612    TRUNCATE.  For example, if the caller has proven that an SImode
613    truncation of:
614 
615       (and:DI X Y)
616 
617    is a no-op and can be represented as a subreg, it does not follow
618    that SImode truncations of X and Y are also no-ops.  On a target
619    like 64-bit MIPS that requires SImode values to be stored in
620    sign-extended form, an SImode truncation of:
621 
622       (and:DI (reg:DI X) (const_int 63))
623 
624    is trivially a no-op because only the lower 6 bits can be set.
625    However, X is still an arbitrary 64-bit number and so we cannot
626    assume that truncating it too is a no-op.  */
627 
628 static rtx
simplify_truncation(machine_mode mode,rtx op,machine_mode op_mode)629 simplify_truncation (machine_mode mode, rtx op,
630                          machine_mode op_mode)
631 {
632   unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
633   unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
634   scalar_int_mode int_mode, int_op_mode, subreg_mode;
635 
636   gcc_assert (precision <= op_precision);
637 
638   /* Optimize truncations of zero and sign extended values.  */
639   if (GET_CODE (op) == ZERO_EXTEND
640       || GET_CODE (op) == SIGN_EXTEND)
641     {
642       /* There are three possibilities.  If MODE is the same as the
643            origmode, we can omit both the extension and the subreg.
644            If MODE is not larger than the origmode, we can apply the
645            truncation without the extension.  Finally, if the outermode
646            is larger than the origmode, we can just extend to the appropriate
647            mode.  */
648       machine_mode origmode = GET_MODE (XEXP (op, 0));
649       if (mode == origmode)
650           return XEXP (op, 0);
651       else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
652           return simplify_gen_unary (TRUNCATE, mode,
653                                            XEXP (op, 0), origmode);
654       else
655           return simplify_gen_unary (GET_CODE (op), mode,
656                                            XEXP (op, 0), origmode);
657     }
658 
659   /* If the machine can perform operations in the truncated mode, distribute
660      the truncation, i.e. simplify (truncate:QI (op:SI (x:SI) (y:SI))) into
661      (op:QI (truncate:QI (x:SI)) (truncate:QI (y:SI))).  */
662   if (1
663       && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
664       && (GET_CODE (op) == PLUS
665             || GET_CODE (op) == MINUS
666             || GET_CODE (op) == MULT))
667     {
668       rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
669       if (op0)
670           {
671             rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
672             if (op1)
673               return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
674           }
675     }
676 
677   /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
678      to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
679      the outer subreg is effectively a truncation to the original mode.  */
680   if ((GET_CODE (op) == LSHIFTRT
681        || GET_CODE (op) == ASHIFTRT)
682       /* Ensure that OP_MODE is at least twice as wide as MODE
683            to avoid the possibility that an outer LSHIFTRT shifts by more
684            than the sign extension's sign_bit_copies and introduces zeros
685            into the high bits of the result.  */
686       && 2 * precision <= op_precision
687       && CONST_INT_P (XEXP (op, 1))
688       && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
689       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
690       && UINTVAL (XEXP (op, 1)) < precision)
691     return simplify_gen_binary (ASHIFTRT, mode,
692                                         XEXP (XEXP (op, 0), 0), XEXP (op, 1));
693 
694   /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
695      to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
696      the outer subreg is effectively a truncation to the original mode.  */
697   if ((GET_CODE (op) == LSHIFTRT
698        || GET_CODE (op) == ASHIFTRT)
699       && CONST_INT_P (XEXP (op, 1))
700       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
701       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
702       && UINTVAL (XEXP (op, 1)) < precision)
703     return simplify_gen_binary (LSHIFTRT, mode,
704                                         XEXP (XEXP (op, 0), 0), XEXP (op, 1));
705 
706   /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
707      to (ashift:QI (x:QI) C), where C is a suitable small constant and
708      the outer subreg is effectively a truncation to the original mode.  */
709   if (GET_CODE (op) == ASHIFT
710       && CONST_INT_P (XEXP (op, 1))
711       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
712             || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
713       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
714       && UINTVAL (XEXP (op, 1)) < precision)
715     return simplify_gen_binary (ASHIFT, mode,
716                                         XEXP (XEXP (op, 0), 0), XEXP (op, 1));
717 
718   /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into
719      (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C
720      and C2.  */
721   if (GET_CODE (op) == AND
722       && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
723             || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
724       && CONST_INT_P (XEXP (XEXP (op, 0), 1))
725       && CONST_INT_P (XEXP (op, 1)))
726     {
727       rtx op0 = (XEXP (XEXP (op, 0), 0));
728       rtx shift_op = XEXP (XEXP (op, 0), 1);
729       rtx mask_op = XEXP (op, 1);
730       unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
731       unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
732 
733       if (shift < precision
734             /* If doing this transform works for an X with all bits set,
735                it works for any X.  */
736             && ((GET_MODE_MASK (mode) >> shift) & mask)
737                == ((GET_MODE_MASK (op_mode) >> shift) & mask)
738             && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
739             && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
740           {
741             mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
742             return simplify_gen_binary (AND, mode, op0, mask_op);
743           }
744     }
745 
746   /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
747      (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
748      changing len.  */
749   if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
750       && REG_P (XEXP (op, 0))
751       && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
752       && CONST_INT_P (XEXP (op, 1))
753       && CONST_INT_P (XEXP (op, 2)))
754     {
755       rtx op0 = XEXP (op, 0);
756       unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
757       unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
758       if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
759           {
760             op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
761             if (op0)
762               {
763                 pos -= op_precision - precision;
764                 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
765                                                      XEXP (op, 1), GEN_INT (pos));
766               }
767           }
768       else if (!BITS_BIG_ENDIAN && precision >= len + pos)
769           {
770             op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
771             if (op0)
772               return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
773                                                    XEXP (op, 1), XEXP (op, 2));
774           }
775     }
776 
777   /* Recognize a word extraction from a multi-word subreg.  */
778   if ((GET_CODE (op) == LSHIFTRT
779        || GET_CODE (op) == ASHIFTRT)
780       && SCALAR_INT_MODE_P (mode)
781       && SCALAR_INT_MODE_P (op_mode)
782       && precision >= BITS_PER_WORD
783       && 2 * precision <= op_precision
784       && CONST_INT_P (XEXP (op, 1))
785       && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
786       && UINTVAL (XEXP (op, 1)) < op_precision)
787     {
788       poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
789       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
790       return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
791                                           (WORDS_BIG_ENDIAN
792                                            ? byte - shifted_bytes
793                                            : byte + shifted_bytes));
794     }
795 
796   /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
797      and try replacing the TRUNCATE and shift with it.  Don't do this
798      if the MEM has a mode-dependent address.  */
799   if ((GET_CODE (op) == LSHIFTRT
800        || GET_CODE (op) == ASHIFTRT)
801       && is_a <scalar_int_mode> (mode, &int_mode)
802       && is_a <scalar_int_mode> (op_mode, &int_op_mode)
803       && MEM_P (XEXP (op, 0))
804       && CONST_INT_P (XEXP (op, 1))
805       && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
806       && INTVAL (XEXP (op, 1)) > 0
807       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
808       && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
809                                              MEM_ADDR_SPACE (XEXP (op, 0)))
810       && ! MEM_VOLATILE_P (XEXP (op, 0))
811       && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
812             || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
813     {
814       poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
815       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
816       return adjust_address_nv (XEXP (op, 0), int_mode,
817                                         (WORDS_BIG_ENDIAN
818                                          ? byte - shifted_bytes
819                                          : byte + shifted_bytes));
820     }
821 
822   /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
823      (OP:SI foo:SI) if OP is NEG or ABS.  */
824   if ((GET_CODE (op) == ABS
825        || GET_CODE (op) == NEG)
826       && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
827             || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
828       && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
829     return simplify_gen_unary (GET_CODE (op), mode,
830                                      XEXP (XEXP (op, 0), 0), mode);
831 
832   /* (truncate:A (subreg:B (truncate:C X) 0)) is
833      (truncate:A X).  */
834   if (GET_CODE (op) == SUBREG
835       && is_a <scalar_int_mode> (mode, &int_mode)
836       && SCALAR_INT_MODE_P (op_mode)
837       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
838       && GET_CODE (SUBREG_REG (op)) == TRUNCATE
839       && subreg_lowpart_p (op))
840     {
841       rtx inner = XEXP (SUBREG_REG (op), 0);
842       if (GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (subreg_mode))
843           return simplify_gen_unary (TRUNCATE, int_mode, inner,
844                                            GET_MODE (inner));
845       else
846           /* If subreg above is paradoxical and C is narrower
847              than A, return (subreg:A (truncate:C X) 0).  */
848           return simplify_gen_subreg (int_mode, SUBREG_REG (op), subreg_mode, 0);
849     }
850 
851   /* (truncate:A (truncate:B X)) is (truncate:A X).  */
852   if (GET_CODE (op) == TRUNCATE)
853     return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
854                                      GET_MODE (XEXP (op, 0)));
855 
856   /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
857      in mode A.  */
858   if (GET_CODE (op) == IOR
859       && SCALAR_INT_MODE_P (mode)
860       && SCALAR_INT_MODE_P (op_mode)
861       && CONST_INT_P (XEXP (op, 1))
862       && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
863     return constm1_rtx;
864 
865   return NULL_RTX;
866 }
867 
868 /* Try to simplify a unary operation CODE whose output mode is to be
869    MODE with input operand OP whose mode was originally OP_MODE.
870    Return zero if no simplification can be made.  */
871 rtx
simplify_unary_operation(enum rtx_code code,machine_mode mode,rtx op,machine_mode op_mode)872 simplify_unary_operation (enum rtx_code code, machine_mode mode,
873                                 rtx op, machine_mode op_mode)
874 {
875   rtx trueop, tem;
876 
877   trueop = avoid_constant_pool_reference (op);
878 
879   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
880   if (tem)
881     return tem;
882 
883   return simplify_unary_operation_1 (code, mode, op);
884 }
885 
886 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
887    to be exact.  */
888 
889 static bool
exact_int_to_float_conversion_p(const_rtx op)890 exact_int_to_float_conversion_p (const_rtx op)
891 {
892   int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
893   machine_mode op0_mode = GET_MODE (XEXP (op, 0));
894   /* Constants shouldn't reach here.  */
895   gcc_assert (op0_mode != VOIDmode);
896   int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
897   int in_bits = in_prec;
898   if (HWI_COMPUTABLE_MODE_P (op0_mode))
899     {
900       unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
901       if (GET_CODE (op) == FLOAT)
902           in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
903       else if (GET_CODE (op) == UNSIGNED_FLOAT)
904           in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
905       else
906           gcc_unreachable ();
907       in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
908     }
909   return in_bits <= out_bits;
910 }
911 
912 /* Perform some simplifications we can do even if the operands
913    aren't constant.  */
914 static rtx
simplify_unary_operation_1(enum rtx_code code,machine_mode mode,rtx op)915 simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
916 {
917   enum rtx_code reversed;
918   rtx temp, elt, base, step;
919   scalar_int_mode inner, int_mode, op_mode, op0_mode;
920 
921   switch (code)
922     {
923     case NOT:
924       /* (not (not X)) == X.  */
925       if (GET_CODE (op) == NOT)
926           return XEXP (op, 0);
927 
928       /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
929            comparison is all ones.   */
930       if (COMPARISON_P (op)
931             && (mode == BImode || STORE_FLAG_VALUE == -1)
932             && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
933           return simplify_gen_relational (reversed, mode, VOIDmode,
934                                                   XEXP (op, 0), XEXP (op, 1));
935 
936       /* (not (plus X -1)) can become (neg X).  */
937       if (GET_CODE (op) == PLUS
938             && XEXP (op, 1) == constm1_rtx)
939           return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
940 
941       /* Similarly, (not (neg X)) is (plus X -1).  Only do this for
942            modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
943            and MODE_VECTOR_INT.  */
944       if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
945           return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
946                                             CONSTM1_RTX (mode));
947 
948       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
949       if (GET_CODE (op) == XOR
950             && CONST_INT_P (XEXP (op, 1))
951             && (temp = simplify_unary_operation (NOT, mode,
952                                                          XEXP (op, 1), mode)) != 0)
953           return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
954 
955       /* (not (plus X C)) for signbit C is (xor X D) with D = ~C.  */
956       if (GET_CODE (op) == PLUS
957             && CONST_INT_P (XEXP (op, 1))
958             && mode_signbit_p (mode, XEXP (op, 1))
959             && (temp = simplify_unary_operation (NOT, mode,
960                                                          XEXP (op, 1), mode)) != 0)
961           return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
962 
963 
964       /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for
965            operands other than 1, but that is not valid.  We could do a
966            similar simplification for (not (lshiftrt C X)) where C is
967            just the sign bit, but this doesn't seem common enough to
968            bother with.  */
969       if (GET_CODE (op) == ASHIFT
970             && XEXP (op, 0) == const1_rtx)
971           {
972             temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
973             return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
974           }
975 
976       /* (not (ashiftrt foo C)) where C is the number of bits in FOO
977            minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
978            so we can perform the above simplification.  */
979       if (STORE_FLAG_VALUE == -1
980             && is_a <scalar_int_mode> (mode, &int_mode)
981             && GET_CODE (op) == ASHIFTRT
982             && CONST_INT_P (XEXP (op, 1))
983             && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
984           return simplify_gen_relational (GE, int_mode, VOIDmode,
985                                                   XEXP (op, 0), const0_rtx);
986 
987 
988       if (partial_subreg_p (op)
989             && subreg_lowpart_p (op)
990             && GET_CODE (SUBREG_REG (op)) == ASHIFT
991             && XEXP (SUBREG_REG (op), 0) == const1_rtx)
992           {
993             machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
994             rtx x;
995 
996             x = gen_rtx_ROTATE (inner_mode,
997                                     simplify_gen_unary (NOT, inner_mode, const1_rtx,
998                                                               inner_mode),
999                                     XEXP (SUBREG_REG (op), 1));
1000             temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1001             if (temp)
1002               return temp;
1003           }
1004 
1005       /* Apply De Morgan's laws to reduce number of patterns for machines
1006            with negating logical insns (and-not, nand, etc.).  If result has
1007            only one NOT, put it first, since that is how the patterns are
1008            coded.  */
1009       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1010           {
1011             rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1012             machine_mode op_mode;
1013 
1014             op_mode = GET_MODE (in1);
1015             in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1016 
1017             op_mode = GET_MODE (in2);
1018             if (op_mode == VOIDmode)
1019               op_mode = mode;
1020             in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1021 
1022             if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1023               std::swap (in1, in2);
1024 
1025             return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1026                                          mode, in1, in2);
1027           }
1028 
1029       /* (not (bswap x)) -> (bswap (not x)).  */
1030       if (GET_CODE (op) == BSWAP)
1031           {
1032             rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1033             return simplify_gen_unary (BSWAP, mode, x, mode);
1034           }
1035       break;
1036 
1037     case NEG:
1038       /* (neg (neg X)) == X.  */
1039       if (GET_CODE (op) == NEG)
1040           return XEXP (op, 0);
1041 
1042       /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1043            If comparison is not reversible use
1044            x ? y : (neg y).  */
1045       if (GET_CODE (op) == IF_THEN_ELSE)
1046           {
1047             rtx cond = XEXP (op, 0);
1048             rtx true_rtx = XEXP (op, 1);
1049             rtx false_rtx = XEXP (op, 2);
1050 
1051             if ((GET_CODE (true_rtx) == NEG
1052                  && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1053                  || (GET_CODE (false_rtx) == NEG
1054                        && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1055               {
1056                 if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1057                     temp = reversed_comparison (cond, mode);
1058                 else
1059                     {
1060                       temp = cond;
1061                       std::swap (true_rtx, false_rtx);
1062                     }
1063                 return simplify_gen_ternary (IF_THEN_ELSE, mode,
1064                                                       mode, temp, true_rtx, false_rtx);
1065               }
1066           }
1067 
1068       /* (neg (plus X 1)) can become (not X).  */
1069       if (GET_CODE (op) == PLUS
1070             && XEXP (op, 1) == const1_rtx)
1071           return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1072 
1073       /* Similarly, (neg (not X)) is (plus X 1).  */
1074       if (GET_CODE (op) == NOT)
1075           return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1076                                             CONST1_RTX (mode));
1077 
1078       /* (neg (minus X Y)) can become (minus Y X).  This transformation
1079            isn't safe for modes with signed zeros, since if X and Y are
1080            both +0, (minus Y X) is the same as (minus X Y).  If the
1081            rounding mode is towards +infinity (or -infinity) then the two
1082            expressions will be rounded differently.  */
1083       if (GET_CODE (op) == MINUS
1084             && !HONOR_SIGNED_ZEROS (mode)
1085             && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1086           return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1087 
1088       if (GET_CODE (op) == PLUS
1089             && !HONOR_SIGNED_ZEROS (mode)
1090             && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1091           {
1092             /* (neg (plus A C)) is simplified to (minus -C A).  */
1093             if (CONST_SCALAR_INT_P (XEXP (op, 1))
1094                 || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1095               {
1096                 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1097                 if (temp)
1098                     return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1099               }
1100 
1101             /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
1102             temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1103             return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1104           }
1105 
1106       /* (neg (mult A B)) becomes (mult A (neg B)).
1107            This works even for floating-point values.  */
1108       if (GET_CODE (op) == MULT
1109             && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1110           {
1111             temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1112             return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1113           }
1114 
1115       /* NEG commutes with ASHIFT since it is multiplication.  Only do
1116            this if we can then eliminate the NEG (e.g., if the operand
1117            is a constant).  */
1118       if (GET_CODE (op) == ASHIFT)
1119           {
1120             temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1121             if (temp)
1122               return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1123           }
1124 
1125       /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1126            C is equal to the width of MODE minus 1.  */
1127       if (GET_CODE (op) == ASHIFTRT
1128             && CONST_INT_P (XEXP (op, 1))
1129             && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1130           return simplify_gen_binary (LSHIFTRT, mode,
1131                                             XEXP (op, 0), XEXP (op, 1));
1132 
1133       /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1134            C is equal to the width of MODE minus 1.  */
1135       if (GET_CODE (op) == LSHIFTRT
1136             && CONST_INT_P (XEXP (op, 1))
1137             && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1138           return simplify_gen_binary (ASHIFTRT, mode,
1139                                             XEXP (op, 0), XEXP (op, 1));
1140 
1141       /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
1142       if (GET_CODE (op) == XOR
1143             && XEXP (op, 1) == const1_rtx
1144             && nonzero_bits (XEXP (op, 0), mode) == 1)
1145           return plus_constant (mode, XEXP (op, 0), -1);
1146 
1147       /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1.  */
1148       /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1.  */
1149       if (GET_CODE (op) == LT
1150             && XEXP (op, 1) == const0_rtx
1151             && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1152           {
1153             int_mode = as_a <scalar_int_mode> (mode);
1154             int isize = GET_MODE_PRECISION (inner);
1155             if (STORE_FLAG_VALUE == 1)
1156               {
1157                 temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1158                                                     gen_int_shift_amount (inner,
1159                                                                                 isize - 1));
1160                 if (int_mode == inner)
1161                     return temp;
1162                 if (GET_MODE_PRECISION (int_mode) > isize)
1163                     return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1164                 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1165               }
1166             else if (STORE_FLAG_VALUE == -1)
1167               {
1168                 temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1169                                                     gen_int_shift_amount (inner,
1170                                                                                 isize - 1));
1171                 if (int_mode == inner)
1172                     return temp;
1173                 if (GET_MODE_PRECISION (int_mode) > isize)
1174                     return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1175                 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1176               }
1177           }
1178 
1179       if (vec_series_p (op, &base, &step))
1180           {
1181             /* Only create a new series if we can simplify both parts.  In other
1182                cases this isn't really a simplification, and it's not necessarily
1183                a win to replace a vector operation with a scalar operation.  */
1184             scalar_mode inner_mode = GET_MODE_INNER (mode);
1185             base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1186             if (base)
1187               {
1188                 step = simplify_unary_operation (NEG, inner_mode,
1189                                                          step, inner_mode);
1190                 if (step)
1191                     return gen_vec_series (mode, base, step);
1192               }
1193           }
1194       break;
1195 
1196     case TRUNCATE:
1197       /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1198            with the umulXi3_highpart patterns.  */
1199       if (GET_CODE (op) == LSHIFTRT
1200             && GET_CODE (XEXP (op, 0)) == MULT)
1201           break;
1202 
1203       if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1204           {
1205             if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1206               {
1207                 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1208                 if (temp)
1209                     return temp;
1210               }
1211             /* We can't handle truncation to a partial integer mode here
1212                because we don't know the real bitsize of the partial
1213                integer mode.  */
1214             break;
1215           }
1216 
1217       if (GET_MODE (op) != VOIDmode)
1218           {
1219             temp = simplify_truncation (mode, op, GET_MODE (op));
1220             if (temp)
1221               return temp;
1222           }
1223 
1224       /* If we know that the value is already truncated, we can
1225            replace the TRUNCATE with a SUBREG.  */
1226       if (known_eq (GET_MODE_NUNITS (mode), 1)
1227             && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1228                 || truncated_to_mode (mode, op)))
1229           {
1230             temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1231             if (temp)
1232               return temp;
1233           }
1234 
1235       /* A truncate of a comparison can be replaced with a subreg if
1236          STORE_FLAG_VALUE permits.  This is like the previous test,
1237          but it works even if the comparison is done in a mode larger
1238          than HOST_BITS_PER_WIDE_INT.  */
1239       if (HWI_COMPUTABLE_MODE_P (mode)
1240             && COMPARISON_P (op)
1241             && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
1242           {
1243             temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244             if (temp)
1245               return temp;
1246           }
1247 
1248       /* A truncate of a memory is just loading the low part of the memory
1249            if we are not changing the meaning of the address. */
1250       if (GET_CODE (op) == MEM
1251             && !VECTOR_MODE_P (mode)
1252             && !MEM_VOLATILE_P (op)
1253             && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1254           {
1255             temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1256             if (temp)
1257               return temp;
1258           }
1259 
1260       break;
1261 
1262     case FLOAT_TRUNCATE:
1263       if (DECIMAL_FLOAT_MODE_P (mode))
1264           break;
1265 
1266       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
1267       if (GET_CODE (op) == FLOAT_EXTEND
1268             && GET_MODE (XEXP (op, 0)) == mode)
1269           return XEXP (op, 0);
1270 
1271       /* (float_truncate:SF (float_truncate:DF foo:XF))
1272          = (float_truncate:SF foo:XF).
1273            This may eliminate double rounding, so it is unsafe.
1274 
1275          (float_truncate:SF (float_extend:XF foo:DF))
1276          = (float_truncate:SF foo:DF).
1277 
1278          (float_truncate:DF (float_extend:XF foo:SF))
1279          = (float_extend:DF foo:SF).  */
1280       if ((GET_CODE (op) == FLOAT_TRUNCATE
1281              && flag_unsafe_math_optimizations)
1282             || GET_CODE (op) == FLOAT_EXTEND)
1283           return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1284                                            > GET_MODE_UNIT_SIZE (mode)
1285                                            ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1286                                            mode,
1287                                            XEXP (op, 0), mode);
1288 
1289       /*  (float_truncate (float x)) is (float x)  */
1290       if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1291             && (flag_unsafe_math_optimizations
1292                 || exact_int_to_float_conversion_p (op)))
1293           return simplify_gen_unary (GET_CODE (op), mode,
1294                                            XEXP (op, 0),
1295                                            GET_MODE (XEXP (op, 0)));
1296 
1297       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1298            (OP:SF foo:SF) if OP is NEG or ABS.  */
1299       if ((GET_CODE (op) == ABS
1300              || GET_CODE (op) == NEG)
1301             && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1302             && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1303           return simplify_gen_unary (GET_CODE (op), mode,
1304                                            XEXP (XEXP (op, 0), 0), mode);
1305 
1306       /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1307            is (float_truncate:SF x).  */
1308       if (GET_CODE (op) == SUBREG
1309             && subreg_lowpart_p (op)
1310             && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1311           return SUBREG_REG (op);
1312       break;
1313 
1314     case FLOAT_EXTEND:
1315       if (DECIMAL_FLOAT_MODE_P (mode))
1316           break;
1317 
1318       /*  (float_extend (float_extend x)) is (float_extend x)
1319 
1320             (float_extend (float x)) is (float x) assuming that double
1321             rounding can't happen.
1322           */
1323       if (GET_CODE (op) == FLOAT_EXTEND
1324             || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1325                 && exact_int_to_float_conversion_p (op)))
1326           return simplify_gen_unary (GET_CODE (op), mode,
1327                                            XEXP (op, 0),
1328                                            GET_MODE (XEXP (op, 0)));
1329 
1330       break;
1331 
1332     case ABS:
1333       /* (abs (neg <foo>)) -> (abs <foo>) */
1334       if (GET_CODE (op) == NEG)
1335           return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1336                                            GET_MODE (XEXP (op, 0)));
1337 
1338       /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1339          do nothing.  */
1340       if (GET_MODE (op) == VOIDmode)
1341           break;
1342 
1343       /* If operand is something known to be positive, ignore the ABS.  */
1344       if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
1345             || val_signbit_known_clear_p (GET_MODE (op),
1346                                                   nonzero_bits (op, GET_MODE (op))))
1347           return op;
1348 
1349       /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
1350       if (is_a <scalar_int_mode> (mode, &int_mode)
1351             && (num_sign_bit_copies (op, int_mode)
1352                 == GET_MODE_PRECISION (int_mode)))
1353           return gen_rtx_NEG (int_mode, op);
1354 
1355       break;
1356 
1357     case FFS:
1358       /* (ffs (*_extend <X>)) = (ffs <X>) */
1359       if (GET_CODE (op) == SIGN_EXTEND
1360             || GET_CODE (op) == ZERO_EXTEND)
1361           return simplify_gen_unary (FFS, mode, XEXP (op, 0),
1362                                            GET_MODE (XEXP (op, 0)));
1363       break;
1364 
1365     case POPCOUNT:
1366       switch (GET_CODE (op))
1367           {
1368           case BSWAP:
1369           case ZERO_EXTEND:
1370             /* (popcount (zero_extend <X>)) = (popcount <X>) */
1371             return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1372                                              GET_MODE (XEXP (op, 0)));
1373 
1374           case ROTATE:
1375           case ROTATERT:
1376             /* Rotations don't affect popcount.  */
1377             if (!side_effects_p (XEXP (op, 1)))
1378               return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1379                                                GET_MODE (XEXP (op, 0)));
1380             break;
1381 
1382           default:
1383             break;
1384           }
1385       break;
1386 
1387     case PARITY:
1388       switch (GET_CODE (op))
1389           {
1390           case NOT:
1391           case BSWAP:
1392           case ZERO_EXTEND:
1393           case SIGN_EXTEND:
1394             return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1395                                              GET_MODE (XEXP (op, 0)));
1396 
1397           case ROTATE:
1398           case ROTATERT:
1399             /* Rotations don't affect parity.  */
1400             if (!side_effects_p (XEXP (op, 1)))
1401               return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1402                                                GET_MODE (XEXP (op, 0)));
1403             break;
1404 
1405           default:
1406             break;
1407           }
1408       break;
1409 
1410     case BSWAP:
1411       /* (bswap (bswap x)) -> x.  */
1412       if (GET_CODE (op) == BSWAP)
1413           return XEXP (op, 0);
1414       break;
1415 
1416     case FLOAT:
1417       /* (float (sign_extend <X>)) = (float <X>).  */
1418       if (GET_CODE (op) == SIGN_EXTEND)
1419           return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1420                                            GET_MODE (XEXP (op, 0)));
1421       break;
1422 
1423     case SIGN_EXTEND:
1424       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1425            becomes just the MINUS if its mode is MODE.  This allows
1426            folding switch statements on machines using casesi (such as
1427            the VAX).  */
1428       if (GET_CODE (op) == TRUNCATE
1429             && GET_MODE (XEXP (op, 0)) == mode
1430             && GET_CODE (XEXP (op, 0)) == MINUS
1431             && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1432             && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1433           return XEXP (op, 0);
1434 
1435       /* Extending a widening multiplication should be canonicalized to
1436            a wider widening multiplication.  */
1437       if (GET_CODE (op) == MULT)
1438           {
1439             rtx lhs = XEXP (op, 0);
1440             rtx rhs = XEXP (op, 1);
1441             enum rtx_code lcode = GET_CODE (lhs);
1442             enum rtx_code rcode = GET_CODE (rhs);
1443 
1444             /* Widening multiplies usually extend both operands, but sometimes
1445                they use a shift to extract a portion of a register.  */
1446             if ((lcode == SIGN_EXTEND
1447                  || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1448                 && (rcode == SIGN_EXTEND
1449                       || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1450               {
1451                 machine_mode lmode = GET_MODE (lhs);
1452                 machine_mode rmode = GET_MODE (rhs);
1453                 int bits;
1454 
1455                 if (lcode == ASHIFTRT)
1456                     /* Number of bits not shifted off the end.  */
1457                     bits = (GET_MODE_UNIT_PRECISION (lmode)
1458                               - INTVAL (XEXP (lhs, 1)));
1459                 else /* lcode == SIGN_EXTEND */
1460                     /* Size of inner mode.  */
1461                     bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1462 
1463                 if (rcode == ASHIFTRT)
1464                     bits += (GET_MODE_UNIT_PRECISION (rmode)
1465                                - INTVAL (XEXP (rhs, 1)));
1466                 else /* rcode == SIGN_EXTEND */
1467                     bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1468 
1469                 /* We can only widen multiplies if the result is mathematiclly
1470                      equivalent.  I.e. if overflow was impossible.  */
1471                 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1472                     return simplify_gen_binary
1473                                (MULT, mode,
1474                                 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1475                                 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1476               }
1477           }
1478 
1479       /* Check for a sign extension of a subreg of a promoted
1480            variable, where the promotion is sign-extended, and the
1481            target mode is the same as the variable's promotion.  */
1482       if (GET_CODE (op) == SUBREG
1483             && SUBREG_PROMOTED_VAR_P (op)
1484             && SUBREG_PROMOTED_SIGNED_P (op)
1485             && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
1486           {
1487             temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1488             if (temp)
1489               return temp;
1490           }
1491 
1492       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1493            (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
1494       if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1495           {
1496             gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1497                           > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1498             return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1499                                              GET_MODE (XEXP (op, 0)));
1500           }
1501 
1502       /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1503            is (sign_extend:M (subreg:O <X>)) if there is mode with
1504            GET_MODE_BITSIZE (N) - I bits.
1505            (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1506            is similarly (zero_extend:M (subreg:O <X>)).  */
1507       if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1508             && GET_CODE (XEXP (op, 0)) == ASHIFT
1509             && is_a <scalar_int_mode> (mode, &int_mode)
1510             && CONST_INT_P (XEXP (op, 1))
1511             && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1512             && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1513                 GET_MODE_BITSIZE (op_mode) > INTVAL (XEXP (op, 1))))
1514           {
1515             scalar_int_mode tmode;
1516             gcc_assert (GET_MODE_BITSIZE (int_mode)
1517                           > GET_MODE_BITSIZE (op_mode));
1518             if (int_mode_for_size (GET_MODE_BITSIZE (op_mode)
1519                                          - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1520               {
1521                 rtx inner =
1522                     rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1523                 if (inner)
1524                     return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1525                                                      ? SIGN_EXTEND : ZERO_EXTEND,
1526                                                      int_mode, inner, tmode);
1527               }
1528           }
1529 
1530       /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1531          (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0.  */
1532       if (GET_CODE (op) == LSHIFTRT
1533             && CONST_INT_P (XEXP (op, 1))
1534             && XEXP (op, 1) != const0_rtx)
1535           return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1536 
1537 #if defined(POINTERS_EXTEND_UNSIGNED)
1538       /* As we do not know which address space the pointer is referring to,
1539            we can do this only if the target does not support different pointer
1540            or address modes depending on the address space.  */
1541       if (target_default_pointer_address_modes_p ()
1542             && ! POINTERS_EXTEND_UNSIGNED
1543             && mode == Pmode && GET_MODE (op) == ptr_mode
1544             && (CONSTANT_P (op)
1545                 || (GET_CODE (op) == SUBREG
1546                       && REG_P (SUBREG_REG (op))
1547                       && REG_POINTER (SUBREG_REG (op))
1548                       && GET_MODE (SUBREG_REG (op)) == Pmode))
1549             && !targetm.have_ptr_extend ())
1550           {
1551             temp
1552               = convert_memory_address_addr_space_1 (Pmode, op,
1553                                                                ADDR_SPACE_GENERIC, false,
1554                                                                true);
1555             if (temp)
1556               return temp;
1557           }
1558 #endif
1559       break;
1560 
1561     case ZERO_EXTEND:
1562       /* Check for a zero extension of a subreg of a promoted
1563            variable, where the promotion is zero-extended, and the
1564            target mode is the same as the variable's promotion.  */
1565       if (GET_CODE (op) == SUBREG
1566             && SUBREG_PROMOTED_VAR_P (op)
1567             && SUBREG_PROMOTED_UNSIGNED_P (op)
1568             && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
1569           {
1570             temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1571             if (temp)
1572               return temp;
1573           }
1574 
1575       /* Extending a widening multiplication should be canonicalized to
1576            a wider widening multiplication.  */
1577       if (GET_CODE (op) == MULT)
1578           {
1579             rtx lhs = XEXP (op, 0);
1580             rtx rhs = XEXP (op, 1);
1581             enum rtx_code lcode = GET_CODE (lhs);
1582             enum rtx_code rcode = GET_CODE (rhs);
1583 
1584             /* Widening multiplies usually extend both operands, but sometimes
1585                they use a shift to extract a portion of a register.  */
1586             if ((lcode == ZERO_EXTEND
1587                  || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1588                 && (rcode == ZERO_EXTEND
1589                       || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1590               {
1591                 machine_mode lmode = GET_MODE (lhs);
1592                 machine_mode rmode = GET_MODE (rhs);
1593                 int bits;
1594 
1595                 if (lcode == LSHIFTRT)
1596                     /* Number of bits not shifted off the end.  */
1597                     bits = (GET_MODE_UNIT_PRECISION (lmode)
1598                               - INTVAL (XEXP (lhs, 1)));
1599                 else /* lcode == ZERO_EXTEND */
1600                     /* Size of inner mode.  */
1601                     bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1602 
1603                 if (rcode == LSHIFTRT)
1604                     bits += (GET_MODE_UNIT_PRECISION (rmode)
1605                                - INTVAL (XEXP (rhs, 1)));
1606                 else /* rcode == ZERO_EXTEND */
1607                     bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1608 
1609                 /* We can only widen multiplies if the result is mathematiclly
1610                      equivalent.  I.e. if overflow was impossible.  */
1611                 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1612                     return simplify_gen_binary
1613                                (MULT, mode,
1614                                 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1615                                 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1616               }
1617           }
1618 
1619       /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
1620       if (GET_CODE (op) == ZERO_EXTEND)
1621           return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1622                                            GET_MODE (XEXP (op, 0)));
1623 
1624       /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1625            is (zero_extend:M (subreg:O <X>)) if there is mode with
1626            GET_MODE_PRECISION (N) - I bits.  */
1627       if (GET_CODE (op) == LSHIFTRT
1628             && GET_CODE (XEXP (op, 0)) == ASHIFT
1629             && is_a <scalar_int_mode> (mode, &int_mode)
1630             && CONST_INT_P (XEXP (op, 1))
1631             && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1632             && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1633                 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1634           {
1635             scalar_int_mode tmode;
1636             if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1637                                          - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1638               {
1639                 rtx inner =
1640                     rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1641                 if (inner)
1642                     return simplify_gen_unary (ZERO_EXTEND, int_mode,
1643                                                      inner, tmode);
1644               }
1645           }
1646 
1647       /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1648            (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1649            of mode N.  E.g.
1650            (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1651            (and:SI (reg:SI) (const_int 63)).  */
1652       if (partial_subreg_p (op)
1653             && is_a <scalar_int_mode> (mode, &int_mode)
1654             && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1655             && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1656             && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1657             && subreg_lowpart_p (op)
1658             && (nonzero_bits (SUBREG_REG (op), op0_mode)
1659                 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1660           {
1661             if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1662               return SUBREG_REG (op);
1663             return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1664                                              op0_mode);
1665           }
1666 
1667 #if defined(POINTERS_EXTEND_UNSIGNED)
1668       /* As we do not know which address space the pointer is referring to,
1669            we can do this only if the target does not support different pointer
1670            or address modes depending on the address space.  */
1671       if (target_default_pointer_address_modes_p ()
1672             && POINTERS_EXTEND_UNSIGNED > 0
1673             && mode == Pmode && GET_MODE (op) == ptr_mode
1674             && (CONSTANT_P (op)
1675                 || (GET_CODE (op) == SUBREG
1676                       && REG_P (SUBREG_REG (op))
1677                       && REG_POINTER (SUBREG_REG (op))
1678                       && GET_MODE (SUBREG_REG (op)) == Pmode))
1679             && !targetm.have_ptr_extend ())
1680           {
1681             temp
1682               = convert_memory_address_addr_space_1 (Pmode, op,
1683                                                                ADDR_SPACE_GENERIC, false,
1684                                                                true);
1685             if (temp)
1686               return temp;
1687           }
1688 #endif
1689       break;
1690 
1691     default:
1692       break;
1693     }
1694 
1695   if (VECTOR_MODE_P (mode)
1696       && vec_duplicate_p (op, &elt)
1697       && code != VEC_DUPLICATE)
1698     {
1699       /* Try applying the operator to ELT and see if that simplifies.
1700            We can duplicate the result if so.
1701 
1702            The reason we don't use simplify_gen_unary is that it isn't
1703            necessarily a win to convert things like:
1704 
1705              (neg:V (vec_duplicate:V (reg:S R)))
1706 
1707            to:
1708 
1709              (vec_duplicate:V (neg:S (reg:S R)))
1710 
1711            The first might be done entirely in vector registers while the
1712            second might need a move between register files.  */
1713       temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1714                                                elt, GET_MODE_INNER (GET_MODE (op)));
1715       if (temp)
1716           return gen_vec_duplicate (mode, temp);
1717     }
1718 
1719   return 0;
1720 }
1721 
1722 /* Try to compute the value of a unary operation CODE whose output mode is to
1723    be MODE with input operand OP whose mode was originally OP_MODE.
1724    Return zero if the value cannot be computed.  */
1725 rtx
simplify_const_unary_operation(enum rtx_code code,machine_mode mode,rtx op,machine_mode op_mode)1726 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1727                                         rtx op, machine_mode op_mode)
1728 {
1729   scalar_int_mode result_mode;
1730 
1731   if (code == VEC_DUPLICATE)
1732     {
1733       gcc_assert (VECTOR_MODE_P (mode));
1734       if (GET_MODE (op) != VOIDmode)
1735       {
1736           if (!VECTOR_MODE_P (GET_MODE (op)))
1737             gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1738           else
1739             gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1740                                                             (GET_MODE (op)));
1741       }
1742       if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1743           return gen_const_vec_duplicate (mode, op);
1744       unsigned int n_elts;
1745       if (GET_CODE (op) == CONST_VECTOR
1746             && GET_MODE_NUNITS (mode).is_constant (&n_elts))
1747           {
1748             /* This must be constant if we're duplicating it to a constant
1749                number of elements.  */
1750             unsigned int in_n_elts = CONST_VECTOR_NUNITS (op).to_constant ();
1751             gcc_assert (in_n_elts < n_elts);
1752             gcc_assert ((n_elts % in_n_elts) == 0);
1753             rtvec v = rtvec_alloc (n_elts);
1754             for (unsigned i = 0; i < n_elts; i++)
1755               RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts);
1756             return gen_rtx_CONST_VECTOR (mode, v);
1757           }
1758     }
1759 
1760   if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
1761     {
1762       unsigned int n_elts;
1763       if (!CONST_VECTOR_NUNITS (op).is_constant (&n_elts))
1764           return NULL_RTX;
1765 
1766       machine_mode opmode = GET_MODE (op);
1767       gcc_assert (known_eq (GET_MODE_NUNITS (mode), n_elts));
1768       gcc_assert (known_eq (GET_MODE_NUNITS (opmode), n_elts));
1769 
1770       rtvec v = rtvec_alloc (n_elts);
1771       unsigned int i;
1772 
1773       for (i = 0; i < n_elts; i++)
1774           {
1775             rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1776                                                       CONST_VECTOR_ELT (op, i),
1777                                                       GET_MODE_INNER (opmode));
1778             if (!x || !valid_for_const_vector_p (mode, x))
1779               return 0;
1780             RTVEC_ELT (v, i) = x;
1781           }
1782       return gen_rtx_CONST_VECTOR (mode, v);
1783     }
1784 
1785   /* The order of these tests is critical so that, for example, we don't
1786      check the wrong mode (input vs. output) for a conversion operation,
1787      such as FIX.  At some point, this should be simplified.  */
1788 
1789   if (code == FLOAT && CONST_SCALAR_INT_P (op))
1790     {
1791       REAL_VALUE_TYPE d;
1792 
1793       if (op_mode == VOIDmode)
1794           {
1795             /* CONST_INT have VOIDmode as the mode.  We assume that all
1796                the bits of the constant are significant, though, this is
1797                a dangerous assumption as many times CONST_INTs are
1798                created and used with garbage in the bits outside of the
1799                precision of the implied mode of the const_int.  */
1800             op_mode = MAX_MODE_INT;
1801           }
1802 
1803       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1804 
1805       /* Avoid the folding if flag_signaling_nans is on and
1806          operand is a signaling NaN.  */
1807       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1808         return 0;
1809 
1810       d = real_value_truncate (mode, d);
1811       return const_double_from_real_value (d, mode);
1812     }
1813   else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
1814     {
1815       REAL_VALUE_TYPE d;
1816 
1817       if (op_mode == VOIDmode)
1818           {
1819             /* CONST_INT have VOIDmode as the mode.  We assume that all
1820                the bits of the constant are significant, though, this is
1821                a dangerous assumption as many times CONST_INTs are
1822                created and used with garbage in the bits outside of the
1823                precision of the implied mode of the const_int.  */
1824             op_mode = MAX_MODE_INT;
1825           }
1826 
1827       real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
1828 
1829       /* Avoid the folding if flag_signaling_nans is on and
1830          operand is a signaling NaN.  */
1831       if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1832         return 0;
1833 
1834       d = real_value_truncate (mode, d);
1835       return const_double_from_real_value (d, mode);
1836     }
1837 
1838   if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
1839     {
1840       unsigned int width = GET_MODE_PRECISION (result_mode);
1841       wide_int result;
1842       scalar_int_mode imode = (op_mode == VOIDmode
1843                                      ? result_mode
1844                                      : as_a <scalar_int_mode> (op_mode));
1845       rtx_mode_t op0 = rtx_mode_t (op, imode);
1846       int int_value;
1847 
1848 #if TARGET_SUPPORTS_WIDE_INT == 0
1849       /* This assert keeps the simplification from producing a result
1850            that cannot be represented in a CONST_DOUBLE but a lot of
1851            upstream callers expect that this function never fails to
1852            simplify something and so you if you added this to the test
1853            above the code would die later anyway.  If this assert
1854            happens, you just need to make the port support wide int.  */
1855       gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
1856 #endif
1857 
1858       switch (code)
1859           {
1860           case NOT:
1861             result = wi::bit_not (op0);
1862             break;
1863 
1864           case NEG:
1865             result = wi::neg (op0);
1866             break;
1867 
1868           case ABS:
1869             result = wi::abs (op0);
1870             break;
1871 
1872           case FFS:
1873             result = wi::shwi (wi::ffs (op0), result_mode);
1874             break;
1875 
1876           case CLZ:
1877             if (wi::ne_p (op0, 0))
1878               int_value = wi::clz (op0);
1879             else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1880               return NULL_RTX;
1881             result = wi::shwi (int_value, result_mode);
1882             break;
1883 
1884           case CLRSB:
1885             result = wi::shwi (wi::clrsb (op0), result_mode);
1886             break;
1887 
1888           case CTZ:
1889             if (wi::ne_p (op0, 0))
1890               int_value = wi::ctz (op0);
1891             else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1892               return NULL_RTX;
1893             result = wi::shwi (int_value, result_mode);
1894             break;
1895 
1896           case POPCOUNT:
1897             result = wi::shwi (wi::popcount (op0), result_mode);
1898             break;
1899 
1900           case PARITY:
1901             result = wi::shwi (wi::parity (op0), result_mode);
1902             break;
1903 
1904           case BSWAP:
1905             result = wide_int (op0).bswap ();
1906             break;
1907 
1908           case TRUNCATE:
1909           case ZERO_EXTEND:
1910             result = wide_int::from (op0, width, UNSIGNED);
1911             break;
1912 
1913           case SIGN_EXTEND:
1914             result = wide_int::from (op0, width, SIGNED);
1915             break;
1916 
1917           case SQRT:
1918           default:
1919             return 0;
1920           }
1921 
1922       return immed_wide_int_const (result, result_mode);
1923     }
1924 
1925   else if (CONST_DOUBLE_AS_FLOAT_P (op)
1926              && SCALAR_FLOAT_MODE_P (mode)
1927              && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
1928     {
1929       REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
1930       switch (code)
1931           {
1932           case SQRT:
1933             return 0;
1934           case ABS:
1935             d = real_value_abs (&d);
1936             break;
1937           case NEG:
1938             d = real_value_negate (&d);
1939             break;
1940           case FLOAT_TRUNCATE:
1941             /* Don't perform the operation if flag_signaling_nans is on
1942                and the operand is a signaling NaN.  */
1943             if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1944               return NULL_RTX;
1945             d = real_value_truncate (mode, d);
1946             break;
1947           case FLOAT_EXTEND:
1948             /* Don't perform the operation if flag_signaling_nans is on
1949                and the operand is a signaling NaN.  */
1950             if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1951               return NULL_RTX;
1952             /* All this does is change the mode, unless changing
1953                mode class.  */
1954             if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
1955               real_convert (&d, mode, &d);
1956             break;
1957           case FIX:
1958             /* Don't perform the operation if flag_signaling_nans is on
1959                and the operand is a signaling NaN.  */
1960             if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1961               return NULL_RTX;
1962             real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
1963             break;
1964           case NOT:
1965             {
1966               long tmp[4];
1967               int i;
1968 
1969               real_to_target (tmp, &d, GET_MODE (op));
1970               for (i = 0; i < 4; i++)
1971                 tmp[i] = ~tmp[i];
1972               real_from_target (&d, tmp, mode);
1973               break;
1974             }
1975           default:
1976             gcc_unreachable ();
1977           }
1978       return const_double_from_real_value (d, mode);
1979     }
1980   else if (CONST_DOUBLE_AS_FLOAT_P (op)
1981              && SCALAR_FLOAT_MODE_P (GET_MODE (op))
1982              && is_int_mode (mode, &result_mode))
1983     {
1984       unsigned int width = GET_MODE_PRECISION (result_mode);
1985       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
1986            operators are intentionally left unspecified (to ease implementation
1987            by target backends), for consistency, this routine implements the
1988            same semantics for constant folding as used by the middle-end.  */
1989 
1990       /* This was formerly used only for non-IEEE float.
1991            eggert@twinsun.com says it is safe for IEEE also.  */
1992       REAL_VALUE_TYPE t;
1993       const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
1994       wide_int wmax, wmin;
1995       /* This is part of the abi to real_to_integer, but we check
1996            things before making this call.  */
1997       bool fail;
1998 
1999       switch (code)
2000           {
2001           case FIX:
2002             if (REAL_VALUE_ISNAN (*x))
2003               return const0_rtx;
2004 
2005             /* Test against the signed upper bound.  */
2006             wmax = wi::max_value (width, SIGNED);
2007             real_from_integer (&t, VOIDmode, wmax, SIGNED);
2008             if (real_less (&t, x))
2009               return immed_wide_int_const (wmax, mode);
2010 
2011             /* Test against the signed lower bound.  */
2012             wmin = wi::min_value (width, SIGNED);
2013             real_from_integer (&t, VOIDmode, wmin, SIGNED);
2014             if (real_less (x, &t))
2015               return immed_wide_int_const (wmin, mode);
2016 
2017             return immed_wide_int_const (real_to_integer (x, &fail, width),
2018                                                mode);
2019 
2020           case UNSIGNED_FIX:
2021             if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2022               return const0_rtx;
2023 
2024             /* Test against the unsigned upper bound.  */
2025             wmax = wi::max_value (width, UNSIGNED);
2026             real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2027             if (real_less (&t, x))
2028               return immed_wide_int_const (wmax, mode);
2029 
2030             return immed_wide_int_const (real_to_integer (x, &fail, width),
2031                                                mode);
2032 
2033           default:
2034             gcc_unreachable ();
2035           }
2036     }
2037 
2038   /* Handle polynomial integers.  */
2039   else if (CONST_POLY_INT_P (op))
2040     {
2041       poly_wide_int result;
2042       switch (code)
2043           {
2044           case NEG:
2045             result = -const_poly_int_value (op);
2046             break;
2047 
2048           case NOT:
2049             result = ~const_poly_int_value (op);
2050             break;
2051 
2052           default:
2053             return NULL_RTX;
2054           }
2055       return immed_wide_int_const (result, mode);
2056     }
2057 
2058   return NULL_RTX;
2059 }
2060 
2061 /* Subroutine of simplify_binary_operation to simplify a binary operation
2062    CODE that can commute with byte swapping, with result mode MODE and
2063    operating on OP0 and OP1.  CODE is currently one of AND, IOR or XOR.
2064    Return zero if no simplification or canonicalization is possible.  */
2065 
2066 static rtx
simplify_byte_swapping_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2067 simplify_byte_swapping_operation (enum rtx_code code, machine_mode mode,
2068                                           rtx op0, rtx op1)
2069 {
2070   rtx tem;
2071 
2072   /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped.  */
2073   if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2074     {
2075       tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2076                                          simplify_gen_unary (BSWAP, mode, op1, mode));
2077       return simplify_gen_unary (BSWAP, mode, tem, mode);
2078     }
2079 
2080   /* (op (bswap x) (bswap y)) -> (bswap (op x y)).  */
2081   if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2082     {
2083       tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2084       return simplify_gen_unary (BSWAP, mode, tem, mode);
2085     }
2086 
2087   return NULL_RTX;
2088 }
2089 
2090 /* Subroutine of simplify_binary_operation to simplify a commutative,
2091    associative binary operation CODE with result mode MODE, operating
2092    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2093    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
2094    canonicalization is possible.  */
2095 
2096 static rtx
simplify_associative_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2097 simplify_associative_operation (enum rtx_code code, machine_mode mode,
2098                                         rtx op0, rtx op1)
2099 {
2100   rtx tem;
2101 
2102   /* Linearize the operator to the left.  */
2103   if (GET_CODE (op1) == code)
2104     {
2105       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
2106       if (GET_CODE (op0) == code)
2107           {
2108             tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2109             return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2110           }
2111 
2112       /* "a op (b op c)" becomes "(b op c) op a".  */
2113       if (! swap_commutative_operands_p (op1, op0))
2114           return simplify_gen_binary (code, mode, op1, op0);
2115 
2116       std::swap (op0, op1);
2117     }
2118 
2119   if (GET_CODE (op0) == code)
2120     {
2121       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
2122       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2123           {
2124             tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2125             return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2126           }
2127 
2128       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
2129       tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2130       if (tem != 0)
2131         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2132 
2133       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
2134       tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2135       if (tem != 0)
2136         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2137     }
2138 
2139   return 0;
2140 }
2141 
2142 
2143 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2144    and OP1.  Return 0 if no simplification is possible.
2145 
2146    Don't use this for relational operations such as EQ or LT.
2147    Use simplify_relational_operation instead.  */
2148 rtx
simplify_binary_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2149 simplify_binary_operation (enum rtx_code code, machine_mode mode,
2150                                  rtx op0, rtx op1)
2151 {
2152   rtx trueop0, trueop1;
2153   rtx tem;
2154 
2155   /* Relational operations don't work here.  We must know the mode
2156      of the operands in order to do the comparison correctly.
2157      Assuming a full word can give incorrect results.
2158      Consider comparing 128 with -128 in QImode.  */
2159   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2160   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2161 
2162   /* Make sure the constant is second.  */
2163   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2164       && swap_commutative_operands_p (op0, op1))
2165     std::swap (op0, op1);
2166 
2167   trueop0 = avoid_constant_pool_reference (op0);
2168   trueop1 = avoid_constant_pool_reference (op1);
2169 
2170   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2171   if (tem)
2172     return tem;
2173   tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2174 
2175   if (tem)
2176     return tem;
2177 
2178   /* If the above steps did not result in a simplification and op0 or op1
2179      were constant pool references, use the referenced constants directly.  */
2180   if (trueop0 != op0 || trueop1 != op1)
2181     return simplify_gen_binary (code, mode, trueop0, trueop1);
2182 
2183   return NULL_RTX;
2184 }
2185 
2186 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2187    which OP0 and OP1 are both vector series or vector duplicates
2188    (which are really just series with a step of 0).  If so, try to
2189    form a new series by applying CODE to the bases and to the steps.
2190    Return null if no simplification is possible.
2191 
2192    MODE is the mode of the operation and is known to be a vector
2193    integer mode.  */
2194 
2195 static rtx
simplify_binary_operation_series(rtx_code code,machine_mode mode,rtx op0,rtx op1)2196 simplify_binary_operation_series (rtx_code code, machine_mode mode,
2197                                           rtx op0, rtx op1)
2198 {
2199   rtx base0, step0;
2200   if (vec_duplicate_p (op0, &base0))
2201     step0 = const0_rtx;
2202   else if (!vec_series_p (op0, &base0, &step0))
2203     return NULL_RTX;
2204 
2205   rtx base1, step1;
2206   if (vec_duplicate_p (op1, &base1))
2207     step1 = const0_rtx;
2208   else if (!vec_series_p (op1, &base1, &step1))
2209     return NULL_RTX;
2210 
2211   /* Only create a new series if we can simplify both parts.  In other
2212      cases this isn't really a simplification, and it's not necessarily
2213      a win to replace a vector operation with a scalar operation.  */
2214   scalar_mode inner_mode = GET_MODE_INNER (mode);
2215   rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2216   if (!new_base)
2217     return NULL_RTX;
2218 
2219   rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2220   if (!new_step)
2221     return NULL_RTX;
2222 
2223   return gen_vec_series (mode, new_base, new_step);
2224 }
2225 
2226 /* Subroutine of simplify_binary_operation.  Simplify a binary operation
2227    CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
2228    OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2229    actual constants.  */
2230 
2231 static rtx
simplify_binary_operation_1(enum rtx_code code,machine_mode mode,rtx op0,rtx op1,rtx trueop0,rtx trueop1)2232 simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
2233                                    rtx op0, rtx op1, rtx trueop0, rtx trueop1)
2234 {
2235   rtx tem, reversed, opleft, opright, elt0, elt1;
2236   HOST_WIDE_INT val;
2237   scalar_int_mode int_mode, inner_mode;
2238   poly_int64 offset;
2239 
2240   /* Even if we can't compute a constant result,
2241      there are some cases worth simplifying.  */
2242 
2243   switch (code)
2244     {
2245     case PLUS:
2246       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
2247            when x is NaN, infinite, or finite and nonzero.  They aren't
2248            when x is -0 and the rounding mode is not towards -infinity,
2249            since (-0) + 0 is then 0.  */
2250       if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2251           return op0;
2252 
2253       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
2254            transformations are safe even for IEEE.  */
2255       if (GET_CODE (op0) == NEG)
2256           return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2257       else if (GET_CODE (op1) == NEG)
2258           return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2259 
2260       /* (~a) + 1 -> -a */
2261       if (INTEGRAL_MODE_P (mode)
2262             && GET_CODE (op0) == NOT
2263             && trueop1 == const1_rtx)
2264           return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2265 
2266       /* Handle both-operands-constant cases.  We can only add
2267            CONST_INTs to constants since the sum of relocatable symbols
2268            can't be handled by most assemblers.  Don't add CONST_INT
2269            to CONST_INT since overflow won't be computed properly if wider
2270            than HOST_BITS_PER_WIDE_INT.  */
2271 
2272       if ((GET_CODE (op0) == CONST
2273              || GET_CODE (op0) == SYMBOL_REF
2274              || GET_CODE (op0) == LABEL_REF)
2275             && CONST_INT_P (op1))
2276           return plus_constant (mode, op0, INTVAL (op1));
2277       else if ((GET_CODE (op1) == CONST
2278                     || GET_CODE (op1) == SYMBOL_REF
2279                     || GET_CODE (op1) == LABEL_REF)
2280                  && CONST_INT_P (op0))
2281           return plus_constant (mode, op1, INTVAL (op0));
2282 
2283       /* See if this is something like X * C - X or vice versa or
2284            if the multiplication is written as a shift.  If so, we can
2285            distribute and make a new multiply, shift, or maybe just
2286            have X (if C is 2 in the example above).  But don't make
2287            something more expensive than we had before.  */
2288 
2289       if (is_a <scalar_int_mode> (mode, &int_mode))
2290           {
2291             rtx lhs = op0, rhs = op1;
2292 
2293             wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2294             wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2295 
2296             if (GET_CODE (lhs) == NEG)
2297               {
2298                 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2299                 lhs = XEXP (lhs, 0);
2300               }
2301             else if (GET_CODE (lhs) == MULT
2302                        && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2303               {
2304                 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2305                 lhs = XEXP (lhs, 0);
2306               }
2307             else if (GET_CODE (lhs) == ASHIFT
2308                        && CONST_INT_P (XEXP (lhs, 1))
2309                    && INTVAL (XEXP (lhs, 1)) >= 0
2310                        && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2311               {
2312                 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2313                                                       GET_MODE_PRECISION (int_mode));
2314                 lhs = XEXP (lhs, 0);
2315               }
2316 
2317             if (GET_CODE (rhs) == NEG)
2318               {
2319                 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2320                 rhs = XEXP (rhs, 0);
2321               }
2322             else if (GET_CODE (rhs) == MULT
2323                        && CONST_INT_P (XEXP (rhs, 1)))
2324               {
2325                 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2326                 rhs = XEXP (rhs, 0);
2327               }
2328             else if (GET_CODE (rhs) == ASHIFT
2329                        && CONST_INT_P (XEXP (rhs, 1))
2330                        && INTVAL (XEXP (rhs, 1)) >= 0
2331                        && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2332               {
2333                 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2334                                                       GET_MODE_PRECISION (int_mode));
2335                 rhs = XEXP (rhs, 0);
2336               }
2337 
2338             if (rtx_equal_p (lhs, rhs))
2339               {
2340                 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2341                 rtx coeff;
2342                 bool speed = optimize_function_for_speed_p (cfun);
2343 
2344                 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2345 
2346                 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2347                 return (set_src_cost (tem, int_mode, speed)
2348                           <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2349               }
2350           }
2351 
2352       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
2353       if (CONST_SCALAR_INT_P (op1)
2354             && GET_CODE (op0) == XOR
2355             && CONST_SCALAR_INT_P (XEXP (op0, 1))
2356             && mode_signbit_p (mode, op1))
2357           return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2358                                             simplify_gen_binary (XOR, mode, op1,
2359                                                                        XEXP (op0, 1)));
2360 
2361       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
2362       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2363             && GET_CODE (op0) == MULT
2364             && GET_CODE (XEXP (op0, 0)) == NEG)
2365           {
2366             rtx in1, in2;
2367 
2368             in1 = XEXP (XEXP (op0, 0), 0);
2369             in2 = XEXP (op0, 1);
2370             return simplify_gen_binary (MINUS, mode, op1,
2371                                               simplify_gen_binary (MULT, mode,
2372                                                                          in1, in2));
2373           }
2374 
2375       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2376            C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2377            is 1.  */
2378       if (COMPARISON_P (op0)
2379             && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2380                 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2381             && (reversed = reversed_comparison (op0, mode)))
2382           return
2383             simplify_gen_unary (NEG, mode, reversed, mode);
2384 
2385       /* If one of the operands is a PLUS or a MINUS, see if we can
2386            simplify this by the associative law.
2387            Don't use the associative law for floating point.
2388            The inaccuracy makes it nonassociative,
2389            and subtle programs can break if operations are associated.  */
2390 
2391       if (INTEGRAL_MODE_P (mode)
2392             && (plus_minus_operand_p (op0)
2393                 || plus_minus_operand_p (op1))
2394             && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2395           return tem;
2396 
2397       /* Reassociate floating point addition only when the user
2398            specifies associative math operations.  */
2399       if (FLOAT_MODE_P (mode)
2400             && flag_associative_math)
2401           {
2402             tem = simplify_associative_operation (code, mode, op0, op1);
2403             if (tem)
2404               return tem;
2405           }
2406 
2407       /* Handle vector series.  */
2408       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2409           {
2410             tem = simplify_binary_operation_series (code, mode, op0, op1);
2411             if (tem)
2412               return tem;
2413           }
2414       break;
2415 
2416     case COMPARE:
2417       /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags).  */
2418       if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
2419              || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
2420             && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
2421           {
2422             rtx xop00 = XEXP (op0, 0);
2423             rtx xop10 = XEXP (op1, 0);
2424 
2425             if (GET_CODE (xop00) == CC0 && GET_CODE (xop10) == CC0)
2426                 return xop00;
2427 
2428               if (REG_P (xop00) && REG_P (xop10)
2429                     && REGNO (xop00) == REGNO (xop10)
2430                     && GET_MODE (xop00) == mode
2431                     && GET_MODE (xop10) == mode
2432                     && GET_MODE_CLASS (mode) == MODE_CC)
2433                 return xop00;
2434           }
2435       break;
2436 
2437     case MINUS:
2438       /* We can't assume x-x is 0 even with non-IEEE floating point,
2439            but since it is zero except in very strange circumstances, we
2440            will treat it as zero with -ffinite-math-only.  */
2441       if (rtx_equal_p (trueop0, trueop1)
2442             && ! side_effects_p (op0)
2443             && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
2444           return CONST0_RTX (mode);
2445 
2446       /* Change subtraction from zero into negation.  (0 - x) is the
2447            same as -x when x is NaN, infinite, or finite and nonzero.
2448            But if the mode has signed zeros, and does not round towards
2449            -infinity, then 0 - 0 is 0, not -0.  */
2450       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
2451           return simplify_gen_unary (NEG, mode, op1, mode);
2452 
2453       /* (-1 - a) is ~a, unless the expression contains symbolic
2454            constants, in which case not retaining additions and
2455            subtractions could cause invalid assembly to be produced.  */
2456       if (trueop0 == constm1_rtx
2457             && !contains_symbolic_reference_p (op1))
2458           return simplify_gen_unary (NOT, mode, op1, mode);
2459 
2460       /* Subtracting 0 has no effect unless the mode has signed zeros
2461            and supports rounding towards -infinity.  In such a case,
2462            0 - 0 is -0.  */
2463       if (!(HONOR_SIGNED_ZEROS (mode)
2464               && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2465             && trueop1 == CONST0_RTX (mode))
2466           return op0;
2467 
2468       /* See if this is something like X * C - X or vice versa or
2469            if the multiplication is written as a shift.  If so, we can
2470            distribute and make a new multiply, shift, or maybe just
2471            have X (if C is 2 in the example above).  But don't make
2472            something more expensive than we had before.  */
2473 
2474       if (is_a <scalar_int_mode> (mode, &int_mode))
2475           {
2476             rtx lhs = op0, rhs = op1;
2477 
2478             wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2479             wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2480 
2481             if (GET_CODE (lhs) == NEG)
2482               {
2483                 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2484                 lhs = XEXP (lhs, 0);
2485               }
2486             else if (GET_CODE (lhs) == MULT
2487                        && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2488               {
2489                 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2490                 lhs = XEXP (lhs, 0);
2491               }
2492             else if (GET_CODE (lhs) == ASHIFT
2493                        && CONST_INT_P (XEXP (lhs, 1))
2494                        && INTVAL (XEXP (lhs, 1)) >= 0
2495                        && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2496               {
2497                 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2498                                                       GET_MODE_PRECISION (int_mode));
2499                 lhs = XEXP (lhs, 0);
2500               }
2501 
2502             if (GET_CODE (rhs) == NEG)
2503               {
2504                 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2505                 rhs = XEXP (rhs, 0);
2506               }
2507             else if (GET_CODE (rhs) == MULT
2508                        && CONST_INT_P (XEXP (rhs, 1)))
2509               {
2510                 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
2511                 rhs = XEXP (rhs, 0);
2512               }
2513             else if (GET_CODE (rhs) == ASHIFT
2514                        && CONST_INT_P (XEXP (rhs, 1))
2515                        && INTVAL (XEXP (rhs, 1)) >= 0
2516                        && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2517               {
2518                 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2519                                                          GET_MODE_PRECISION (int_mode));
2520                 negcoeff1 = -negcoeff1;
2521                 rhs = XEXP (rhs, 0);
2522               }
2523 
2524             if (rtx_equal_p (lhs, rhs))
2525               {
2526                 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
2527                 rtx coeff;
2528                 bool speed = optimize_function_for_speed_p (cfun);
2529 
2530                 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
2531 
2532                 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2533                 return (set_src_cost (tem, int_mode, speed)
2534                           <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2535               }
2536           }
2537 
2538       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
2539       if (GET_CODE (op1) == NEG)
2540           return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
2541 
2542       /* (-x - c) may be simplified as (-c - x).  */
2543       if (GET_CODE (op0) == NEG
2544             && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
2545           {
2546             tem = simplify_unary_operation (NEG, mode, op1, mode);
2547             if (tem)
2548               return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
2549           }
2550 
2551       if ((GET_CODE (op0) == CONST
2552              || GET_CODE (op0) == SYMBOL_REF
2553              || GET_CODE (op0) == LABEL_REF)
2554             && poly_int_rtx_p (op1, &offset))
2555           return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
2556 
2557       /* Don't let a relocatable value get a negative coeff.  */
2558       if (CONST_INT_P (op1) && GET_MODE (op0) != VOIDmode)
2559           return simplify_gen_binary (PLUS, mode,
2560                                             op0,
2561                                             neg_const_int (mode, op1));
2562 
2563       /* (x - (x & y)) -> (x & ~y) */
2564       if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
2565           {
2566             if (rtx_equal_p (op0, XEXP (op1, 0)))
2567               {
2568                 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
2569                                                   GET_MODE (XEXP (op1, 1)));
2570                 return simplify_gen_binary (AND, mode, op0, tem);
2571               }
2572             if (rtx_equal_p (op0, XEXP (op1, 1)))
2573               {
2574                 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
2575                                                   GET_MODE (XEXP (op1, 0)));
2576                 return simplify_gen_binary (AND, mode, op0, tem);
2577               }
2578           }
2579 
2580       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
2581            by reversing the comparison code if valid.  */
2582       if (STORE_FLAG_VALUE == 1
2583             && trueop0 == const1_rtx
2584             && COMPARISON_P (op1)
2585             && (reversed = reversed_comparison (op1, mode)))
2586           return reversed;
2587 
2588       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
2589       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2590             && GET_CODE (op1) == MULT
2591             && GET_CODE (XEXP (op1, 0)) == NEG)
2592           {
2593             rtx in1, in2;
2594 
2595             in1 = XEXP (XEXP (op1, 0), 0);
2596             in2 = XEXP (op1, 1);
2597             return simplify_gen_binary (PLUS, mode,
2598                                               simplify_gen_binary (MULT, mode,
2599                                                                          in1, in2),
2600                                               op0);
2601           }
2602 
2603       /* Canonicalize (minus (neg A) (mult B C)) to
2604            (minus (mult (neg B) C) A).  */
2605       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2606             && GET_CODE (op1) == MULT
2607             && GET_CODE (op0) == NEG)
2608           {
2609             rtx in1, in2;
2610 
2611             in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
2612             in2 = XEXP (op1, 1);
2613             return simplify_gen_binary (MINUS, mode,
2614                                               simplify_gen_binary (MULT, mode,
2615                                                                          in1, in2),
2616                                               XEXP (op0, 0));
2617           }
2618 
2619       /* If one of the operands is a PLUS or a MINUS, see if we can
2620            simplify this by the associative law.  This will, for example,
2621          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
2622            Don't use the associative law for floating point.
2623            The inaccuracy makes it nonassociative,
2624            and subtle programs can break if operations are associated.  */
2625 
2626       if (INTEGRAL_MODE_P (mode)
2627             && (plus_minus_operand_p (op0)
2628                 || plus_minus_operand_p (op1))
2629             && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2630           return tem;
2631 
2632       /* Handle vector series.  */
2633       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2634           {
2635             tem = simplify_binary_operation_series (code, mode, op0, op1);
2636             if (tem)
2637               return tem;
2638           }
2639       break;
2640 
2641     case MULT:
2642       if (trueop1 == constm1_rtx)
2643           return simplify_gen_unary (NEG, mode, op0, mode);
2644 
2645       if (GET_CODE (op0) == NEG)
2646           {
2647             rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
2648             /* If op1 is a MULT as well and simplify_unary_operation
2649                just moved the NEG to the second operand, simplify_gen_binary
2650                below could through simplify_associative_operation move
2651                the NEG around again and recurse endlessly.  */
2652             if (temp
2653                 && GET_CODE (op1) == MULT
2654                 && GET_CODE (temp) == MULT
2655                 && XEXP (op1, 0) == XEXP (temp, 0)
2656                 && GET_CODE (XEXP (temp, 1)) == NEG
2657                 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
2658               temp = NULL_RTX;
2659             if (temp)
2660               return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
2661           }
2662       if (GET_CODE (op1) == NEG)
2663           {
2664             rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
2665             /* If op0 is a MULT as well and simplify_unary_operation
2666                just moved the NEG to the second operand, simplify_gen_binary
2667                below could through simplify_associative_operation move
2668                the NEG around again and recurse endlessly.  */
2669             if (temp
2670                 && GET_CODE (op0) == MULT
2671                 && GET_CODE (temp) == MULT
2672                 && XEXP (op0, 0) == XEXP (temp, 0)
2673                 && GET_CODE (XEXP (temp, 1)) == NEG
2674                 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
2675               temp = NULL_RTX;
2676             if (temp)
2677               return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
2678           }
2679 
2680       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
2681            x is NaN, since x * 0 is then also NaN.  Nor is it valid
2682            when the mode has signed zeros, since multiplying a negative
2683            number by 0 will give -0, not 0.  */
2684       if (!HONOR_NANS (mode)
2685             && !HONOR_SIGNED_ZEROS (mode)
2686             && trueop1 == CONST0_RTX (mode)
2687             && ! side_effects_p (op0))
2688           return op1;
2689 
2690       /* In IEEE floating point, x*1 is not equivalent to x for
2691            signalling NaNs.  */
2692       if (!HONOR_SNANS (mode)
2693             && trueop1 == CONST1_RTX (mode))
2694           return op0;
2695 
2696       /* Convert multiply by constant power of two into shift.  */
2697       if (CONST_SCALAR_INT_P (trueop1))
2698           {
2699             val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
2700             if (val >= 0)
2701               return simplify_gen_binary (ASHIFT, mode, op0,
2702                                                   gen_int_shift_amount (mode, val));
2703           }
2704 
2705       /* x*2 is x+x and x*(-1) is -x */
2706       if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
2707             && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
2708             && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
2709             && GET_MODE (op0) == mode)
2710           {
2711             const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
2712 
2713             if (real_equal (d1, &dconst2))
2714               return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
2715 
2716             if (!HONOR_SNANS (mode)
2717                 && real_equal (d1, &dconstm1))
2718               return simplify_gen_unary (NEG, mode, op0, mode);
2719           }
2720 
2721       /* Optimize -x * -x as x * x.  */
2722       if (FLOAT_MODE_P (mode)
2723             && GET_CODE (op0) == NEG
2724             && GET_CODE (op1) == NEG
2725             && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2726             && !side_effects_p (XEXP (op0, 0)))
2727           return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2728 
2729       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
2730       if (SCALAR_FLOAT_MODE_P (mode)
2731             && GET_CODE (op0) == ABS
2732             && GET_CODE (op1) == ABS
2733             && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2734             && !side_effects_p (XEXP (op0, 0)))
2735           return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2736 
2737       /* Reassociate multiplication, but for floating point MULTs
2738            only when the user specifies unsafe math optimizations.  */
2739       if (! FLOAT_MODE_P (mode)
2740             || flag_unsafe_math_optimizations)
2741           {
2742             tem = simplify_associative_operation (code, mode, op0, op1);
2743             if (tem)
2744               return tem;
2745           }
2746       break;
2747 
2748     case IOR:
2749       if (trueop1 == CONST0_RTX (mode))
2750           return op0;
2751       if (INTEGRAL_MODE_P (mode)
2752             && trueop1 == CONSTM1_RTX (mode)
2753             && !side_effects_p (op0))
2754           return op1;
2755       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2756           return op0;
2757       /* A | (~A) -> -1 */
2758       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2759              || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2760             && ! side_effects_p (op0)
2761             && SCALAR_INT_MODE_P (mode))
2762           return constm1_rtx;
2763 
2764       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
2765       if (CONST_INT_P (op1)
2766             && HWI_COMPUTABLE_MODE_P (mode)
2767             && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
2768             && !side_effects_p (op0))
2769           return op1;
2770 
2771       /* Canonicalize (X & C1) | C2.  */
2772       if (GET_CODE (op0) == AND
2773             && CONST_INT_P (trueop1)
2774             && CONST_INT_P (XEXP (op0, 1)))
2775           {
2776             HOST_WIDE_INT mask = GET_MODE_MASK (mode);
2777             HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
2778             HOST_WIDE_INT c2 = INTVAL (trueop1);
2779 
2780             /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2.  */
2781             if ((c1 & c2) == c1
2782                 && !side_effects_p (XEXP (op0, 0)))
2783               return trueop1;
2784 
2785             /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
2786             if (((c1|c2) & mask) == mask)
2787               return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
2788           }
2789 
2790       /* Convert (A & B) | A to A.  */
2791       if (GET_CODE (op0) == AND
2792             && (rtx_equal_p (XEXP (op0, 0), op1)
2793                 || rtx_equal_p (XEXP (op0, 1), op1))
2794             && ! side_effects_p (XEXP (op0, 0))
2795             && ! side_effects_p (XEXP (op0, 1)))
2796           return op1;
2797 
2798       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
2799          mode size to (rotate A CX).  */
2800 
2801       if (GET_CODE (op1) == ASHIFT
2802           || GET_CODE (op1) == SUBREG)
2803         {
2804             opleft = op1;
2805             opright = op0;
2806           }
2807       else
2808         {
2809             opright = op1;
2810             opleft = op0;
2811           }
2812 
2813       if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
2814           && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
2815           && CONST_INT_P (XEXP (opleft, 1))
2816           && CONST_INT_P (XEXP (opright, 1))
2817           && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
2818                 == GET_MODE_UNIT_PRECISION (mode)))
2819         return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
2820 
2821       /* Same, but for ashift that has been "simplified" to a wider mode
2822         by simplify_shift_const.  */
2823 
2824       if (GET_CODE (opleft) == SUBREG
2825             && is_a <scalar_int_mode> (mode, &int_mode)
2826             && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
2827                                              &inner_mode)
2828           && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
2829           && GET_CODE (opright) == LSHIFTRT
2830           && GET_CODE (XEXP (opright, 0)) == SUBREG
2831             && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
2832             && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
2833           && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
2834                           SUBREG_REG (XEXP (opright, 0)))
2835           && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
2836           && CONST_INT_P (XEXP (opright, 1))
2837             && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
2838                 + INTVAL (XEXP (opright, 1))
2839                 == GET_MODE_PRECISION (int_mode)))
2840           return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
2841                                      XEXP (SUBREG_REG (opleft), 1));
2842 
2843       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
2844          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
2845            the PLUS does not affect any of the bits in OP1: then we can do
2846            the IOR as a PLUS and we can associate.  This is valid if OP1
2847          can be safely shifted left C bits.  */
2848       if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
2849           && GET_CODE (XEXP (op0, 0)) == PLUS
2850           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
2851           && CONST_INT_P (XEXP (op0, 1))
2852           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
2853         {
2854             int count = INTVAL (XEXP (op0, 1));
2855             HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
2856 
2857           if (mask >> count == INTVAL (trueop1)
2858                 && trunc_int_for_mode (mask, mode) == mask
2859               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
2860               return simplify_gen_binary (ASHIFTRT, mode,
2861                                                   plus_constant (mode, XEXP (op0, 0),
2862                                                                    mask),
2863                                                   XEXP (op0, 1));
2864         }
2865 
2866       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
2867       if (tem)
2868           return tem;
2869 
2870       tem = simplify_associative_operation (code, mode, op0, op1);
2871       if (tem)
2872           return tem;
2873       break;
2874 
2875     case XOR:
2876       if (trueop1 == CONST0_RTX (mode))
2877           return op0;
2878       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
2879           return simplify_gen_unary (NOT, mode, op0, mode);
2880       if (rtx_equal_p (trueop0, trueop1)
2881             && ! side_effects_p (op0)
2882             && GET_MODE_CLASS (mode) != MODE_CC)
2883            return CONST0_RTX (mode);
2884 
2885       /* Canonicalize XOR of the most significant bit to PLUS.  */
2886       if (CONST_SCALAR_INT_P (op1)
2887             && mode_signbit_p (mode, op1))
2888           return simplify_gen_binary (PLUS, mode, op0, op1);
2889       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
2890       if (CONST_SCALAR_INT_P (op1)
2891             && GET_CODE (op0) == PLUS
2892             && CONST_SCALAR_INT_P (XEXP (op0, 1))
2893             && mode_signbit_p (mode, XEXP (op0, 1)))
2894           return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2895                                             simplify_gen_binary (XOR, mode, op1,
2896                                                                        XEXP (op0, 1)));
2897 
2898       /* If we are XORing two things that have no bits in common,
2899            convert them into an IOR.  This helps to detect rotation encoded
2900            using those methods and possibly other simplifications.  */
2901 
2902       if (HWI_COMPUTABLE_MODE_P (mode)
2903             && (nonzero_bits (op0, mode)
2904                 & nonzero_bits (op1, mode)) == 0)
2905           return (simplify_gen_binary (IOR, mode, op0, op1));
2906 
2907       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
2908            Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
2909            (NOT y).  */
2910       {
2911           int num_negated = 0;
2912 
2913           if (GET_CODE (op0) == NOT)
2914             num_negated++, op0 = XEXP (op0, 0);
2915           if (GET_CODE (op1) == NOT)
2916             num_negated++, op1 = XEXP (op1, 0);
2917 
2918           if (num_negated == 2)
2919             return simplify_gen_binary (XOR, mode, op0, op1);
2920           else if (num_negated == 1)
2921             return simplify_gen_unary (NOT, mode,
2922                                              simplify_gen_binary (XOR, mode, op0, op1),
2923                                              mode);
2924       }
2925 
2926       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
2927            correspond to a machine insn or result in further simplifications
2928            if B is a constant.  */
2929 
2930       if (GET_CODE (op0) == AND
2931             && rtx_equal_p (XEXP (op0, 1), op1)
2932             && ! side_effects_p (op1))
2933           return simplify_gen_binary (AND, mode,
2934                                             simplify_gen_unary (NOT, mode,
2935                                                                       XEXP (op0, 0), mode),
2936                                             op1);
2937 
2938       else if (GET_CODE (op0) == AND
2939                  && rtx_equal_p (XEXP (op0, 0), op1)
2940                  && ! side_effects_p (op1))
2941           return simplify_gen_binary (AND, mode,
2942                                             simplify_gen_unary (NOT, mode,
2943                                                                       XEXP (op0, 1), mode),
2944                                             op1);
2945 
2946       /* Given (xor (ior (xor A B) C) D), where B, C and D are
2947            constants, simplify to (xor (ior A C) (B&~C)^D), canceling
2948            out bits inverted twice and not set by C.  Similarly, given
2949            (xor (and (xor A B) C) D), simplify without inverting C in
2950            the xor operand: (xor (and A C) (B&C)^D).
2951       */
2952       else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
2953                  && GET_CODE (XEXP (op0, 0)) == XOR
2954                  && CONST_INT_P (op1)
2955                  && CONST_INT_P (XEXP (op0, 1))
2956                  && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
2957           {
2958             enum rtx_code op = GET_CODE (op0);
2959             rtx a = XEXP (XEXP (op0, 0), 0);
2960             rtx b = XEXP (XEXP (op0, 0), 1);
2961             rtx c = XEXP (op0, 1);
2962             rtx d = op1;
2963             HOST_WIDE_INT bval = INTVAL (b);
2964             HOST_WIDE_INT cval = INTVAL (c);
2965             HOST_WIDE_INT dval = INTVAL (d);
2966             HOST_WIDE_INT xcval;
2967 
2968             if (op == IOR)
2969               xcval = ~cval;
2970             else
2971               xcval = cval;
2972 
2973             return simplify_gen_binary (XOR, mode,
2974                                               simplify_gen_binary (op, mode, a, c),
2975                                               gen_int_mode ((bval & xcval) ^ dval,
2976                                                                 mode));
2977           }
2978 
2979       /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
2980            we can transform like this:
2981             (A&B)^C == ~(A&B)&C | ~C&(A&B)
2982                     == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
2983                     == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
2984            Attempt a few simplifications when B and C are both constants.  */
2985       if (GET_CODE (op0) == AND
2986             && CONST_INT_P (op1)
2987             && CONST_INT_P (XEXP (op0, 1)))
2988           {
2989             rtx a = XEXP (op0, 0);
2990             rtx b = XEXP (op0, 1);
2991             rtx c = op1;
2992             HOST_WIDE_INT bval = INTVAL (b);
2993             HOST_WIDE_INT cval = INTVAL (c);
2994 
2995             /* Instead of computing ~A&C, we compute its negated value,
2996                ~(A|~C).  If it yields -1, ~A&C is zero, so we can
2997                optimize for sure.  If it does not simplify, we still try
2998                to compute ~A&C below, but since that always allocates
2999                RTL, we don't try that before committing to returning a
3000                simplified expression.  */
3001             rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3002                                                               GEN_INT (~cval));
3003 
3004             if ((~cval & bval) == 0)
3005               {
3006                 rtx na_c = NULL_RTX;
3007                 if (n_na_c)
3008                     na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3009                 else
3010                     {
3011                       /* If ~A does not simplify, don't bother: we don't
3012                          want to simplify 2 operations into 3, and if na_c
3013                          were to simplify with na, n_na_c would have
3014                          simplified as well.  */
3015                       rtx na = simplify_unary_operation (NOT, mode, a, mode);
3016                       if (na)
3017                         na_c = simplify_gen_binary (AND, mode, na, c);
3018                     }
3019 
3020                 /* Try to simplify ~A&C | ~B&C.  */
3021                 if (na_c != NULL_RTX)
3022                     return simplify_gen_binary (IOR, mode, na_c,
3023                                                       gen_int_mode (~bval & cval, mode));
3024               }
3025             else
3026               {
3027                 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
3028                 if (n_na_c == CONSTM1_RTX (mode))
3029                     {
3030                       rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3031                                                                 gen_int_mode (~cval & bval,
3032                                                                                   mode));
3033                       return simplify_gen_binary (IOR, mode, a_nc_b,
3034                                                         gen_int_mode (~bval & cval,
3035                                                                           mode));
3036                     }
3037               }
3038           }
3039 
3040       /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3041            do (ior (and A ~C) (and B C)) which is a machine instruction on some
3042            machines, and also has shorter instruction path length.  */
3043       if (GET_CODE (op0) == AND
3044             && GET_CODE (XEXP (op0, 0)) == XOR
3045             && CONST_INT_P (XEXP (op0, 1))
3046             && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3047           {
3048             rtx a = trueop1;
3049             rtx b = XEXP (XEXP (op0, 0), 1);
3050             rtx c = XEXP (op0, 1);
3051             rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3052             rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3053             rtx bc = simplify_gen_binary (AND, mode, b, c);
3054             return simplify_gen_binary (IOR, mode, a_nc, bc);
3055           }
3056       /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C))  */
3057       else if (GET_CODE (op0) == AND
3058             && GET_CODE (XEXP (op0, 0)) == XOR
3059             && CONST_INT_P (XEXP (op0, 1))
3060             && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3061           {
3062             rtx a = XEXP (XEXP (op0, 0), 0);
3063             rtx b = trueop1;
3064             rtx c = XEXP (op0, 1);
3065             rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3066             rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3067             rtx ac = simplify_gen_binary (AND, mode, a, c);
3068             return simplify_gen_binary (IOR, mode, ac, b_nc);
3069           }
3070 
3071       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3072            comparison if STORE_FLAG_VALUE is 1.  */
3073       if (STORE_FLAG_VALUE == 1
3074             && trueop1 == const1_rtx
3075             && COMPARISON_P (op0)
3076             && (reversed = reversed_comparison (op0, mode)))
3077           return reversed;
3078 
3079       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3080            is (lt foo (const_int 0)), so we can perform the above
3081            simplification if STORE_FLAG_VALUE is 1.  */
3082 
3083       if (is_a <scalar_int_mode> (mode, &int_mode)
3084             && STORE_FLAG_VALUE == 1
3085             && trueop1 == const1_rtx
3086             && GET_CODE (op0) == LSHIFTRT
3087             && CONST_INT_P (XEXP (op0, 1))
3088             && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3089           return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3090 
3091       /* (xor (comparison foo bar) (const_int sign-bit))
3092            when STORE_FLAG_VALUE is the sign bit.  */
3093       if (is_a <scalar_int_mode> (mode, &int_mode)
3094             && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3095             && trueop1 == const_true_rtx
3096             && COMPARISON_P (op0)
3097             && (reversed = reversed_comparison (op0, int_mode)))
3098           return reversed;
3099 
3100       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3101       if (tem)
3102           return tem;
3103 
3104       tem = simplify_associative_operation (code, mode, op0, op1);
3105       if (tem)
3106           return tem;
3107       break;
3108 
3109     case AND:
3110       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3111           return trueop1;
3112       if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3113           return op0;
3114       if (HWI_COMPUTABLE_MODE_P (mode))
3115           {
3116             HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
3117             HOST_WIDE_INT nzop1;
3118             if (CONST_INT_P (trueop1))
3119               {
3120                 HOST_WIDE_INT val1 = INTVAL (trueop1);
3121                 /* If we are turning off bits already known off in OP0, we need
3122                      not do an AND.  */
3123                 if ((nzop0 & ~val1) == 0)
3124                     return op0;
3125               }
3126             nzop1 = nonzero_bits (trueop1, mode);
3127             /* If we are clearing all the nonzero bits, the result is zero.  */
3128             if ((nzop1 & nzop0) == 0
3129                 && !side_effects_p (op0) && !side_effects_p (op1))
3130               return CONST0_RTX (mode);
3131           }
3132       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3133             && GET_MODE_CLASS (mode) != MODE_CC)
3134           return op0;
3135       /* A & (~A) -> 0 */
3136       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3137              || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3138             && ! side_effects_p (op0)
3139             && GET_MODE_CLASS (mode) != MODE_CC)
3140           return CONST0_RTX (mode);
3141 
3142       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3143            there are no nonzero bits of C outside of X's mode.  */
3144       if ((GET_CODE (op0) == SIGN_EXTEND
3145              || GET_CODE (op0) == ZERO_EXTEND)
3146             && CONST_INT_P (trueop1)
3147             && HWI_COMPUTABLE_MODE_P (mode)
3148             && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
3149                 & UINTVAL (trueop1)) == 0)
3150           {
3151             machine_mode imode = GET_MODE (XEXP (op0, 0));
3152             tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
3153                                              gen_int_mode (INTVAL (trueop1),
3154                                                                imode));
3155             return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3156           }
3157 
3158       /* Transform (and (truncate X) C) into (truncate (and X C)).  This way
3159            we might be able to further simplify the AND with X and potentially
3160            remove the truncation altogether.  */
3161       if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3162           {
3163             rtx x = XEXP (op0, 0);
3164             machine_mode xmode = GET_MODE (x);
3165             tem = simplify_gen_binary (AND, xmode, x,
3166                                              gen_int_mode (INTVAL (trueop1), xmode));
3167             return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3168           }
3169 
3170       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
3171       if (GET_CODE (op0) == IOR
3172             && CONST_INT_P (trueop1)
3173             && CONST_INT_P (XEXP (op0, 1)))
3174           {
3175             HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3176             return simplify_gen_binary (IOR, mode,
3177                                               simplify_gen_binary (AND, mode,
3178                                                                          XEXP (op0, 0), op1),
3179                                               gen_int_mode (tmp, mode));
3180           }
3181 
3182       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3183            insn (and may simplify more).  */
3184       if (GET_CODE (op0) == XOR
3185             && rtx_equal_p (XEXP (op0, 0), op1)
3186             && ! side_effects_p (op1))
3187           return simplify_gen_binary (AND, mode,
3188                                             simplify_gen_unary (NOT, mode,
3189                                                                       XEXP (op0, 1), mode),
3190                                             op1);
3191 
3192       if (GET_CODE (op0) == XOR
3193             && rtx_equal_p (XEXP (op0, 1), op1)
3194             && ! side_effects_p (op1))
3195           return simplify_gen_binary (AND, mode,
3196                                             simplify_gen_unary (NOT, mode,
3197                                                                       XEXP (op0, 0), mode),
3198                                             op1);
3199 
3200       /* Similarly for (~(A ^ B)) & A.  */
3201       if (GET_CODE (op0) == NOT
3202             && GET_CODE (XEXP (op0, 0)) == XOR
3203             && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3204             && ! side_effects_p (op1))
3205           return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3206 
3207       if (GET_CODE (op0) == NOT
3208             && GET_CODE (XEXP (op0, 0)) == XOR
3209             && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3210             && ! side_effects_p (op1))
3211           return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3212 
3213       /* Convert (A | B) & A to A.  */
3214       if (GET_CODE (op0) == IOR
3215             && (rtx_equal_p (XEXP (op0, 0), op1)
3216                 || rtx_equal_p (XEXP (op0, 1), op1))
3217             && ! side_effects_p (XEXP (op0, 0))
3218             && ! side_effects_p (XEXP (op0, 1)))
3219           return op1;
3220 
3221       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3222            ((A & N) + B) & M -> (A + B) & M
3223            Similarly if (N & M) == 0,
3224            ((A | N) + B) & M -> (A + B) & M
3225            and for - instead of + and/or ^ instead of |.
3226          Also, if (N & M) == 0, then
3227            (A +- N) & M -> A & M.  */
3228       if (CONST_INT_P (trueop1)
3229             && HWI_COMPUTABLE_MODE_P (mode)
3230             && ~UINTVAL (trueop1)
3231             && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3232             && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3233           {
3234             rtx pmop[2];
3235             int which;
3236 
3237             pmop[0] = XEXP (op0, 0);
3238             pmop[1] = XEXP (op0, 1);
3239 
3240             if (CONST_INT_P (pmop[1])
3241                 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3242               return simplify_gen_binary (AND, mode, pmop[0], op1);
3243 
3244             for (which = 0; which < 2; which++)
3245               {
3246                 tem = pmop[which];
3247                 switch (GET_CODE (tem))
3248                     {
3249                     case AND:
3250                       if (CONST_INT_P (XEXP (tem, 1))
3251                           && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3252                           == UINTVAL (trueop1))
3253                         pmop[which] = XEXP (tem, 0);
3254                       break;
3255                     case IOR:
3256                     case XOR:
3257                       if (CONST_INT_P (XEXP (tem, 1))
3258                           && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3259                         pmop[which] = XEXP (tem, 0);
3260                       break;
3261                     default:
3262                       break;
3263                     }
3264               }
3265 
3266             if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3267               {
3268                 tem = simplify_gen_binary (GET_CODE (op0), mode,
3269                                                    pmop[0], pmop[1]);
3270                 return simplify_gen_binary (code, mode, tem, op1);
3271               }
3272           }
3273 
3274       /* (and X (ior (not X) Y) -> (and X Y) */
3275       if (GET_CODE (op1) == IOR
3276             && GET_CODE (XEXP (op1, 0)) == NOT
3277             && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3278        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3279 
3280       /* (and (ior (not X) Y) X) -> (and X Y) */
3281       if (GET_CODE (op0) == IOR
3282             && GET_CODE (XEXP (op0, 0)) == NOT
3283             && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3284           return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3285 
3286       /* (and X (ior Y (not X)) -> (and X Y) */
3287       if (GET_CODE (op1) == IOR
3288             && GET_CODE (XEXP (op1, 1)) == NOT
3289             && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3290        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3291 
3292       /* (and (ior Y (not X)) X) -> (and X Y) */
3293       if (GET_CODE (op0) == IOR
3294             && GET_CODE (XEXP (op0, 1)) == NOT
3295             && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3296           return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3297 
3298       tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3299       if (tem)
3300           return tem;
3301 
3302       tem = simplify_associative_operation (code, mode, op0, op1);
3303       if (tem)
3304           return tem;
3305       break;
3306 
3307     case UDIV:
3308       /* 0/x is 0 (or x&0 if x has side-effects).  */
3309       if (trueop0 == CONST0_RTX (mode)
3310             && !cfun->can_throw_non_call_exceptions)
3311           {
3312             if (side_effects_p (op1))
3313               return simplify_gen_binary (AND, mode, op1, trueop0);
3314             return trueop0;
3315           }
3316       /* x/1 is x.  */
3317       if (trueop1 == CONST1_RTX (mode))
3318           {
3319             tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3320             if (tem)
3321               return tem;
3322           }
3323       /* Convert divide by power of two into shift.  */
3324       if (CONST_INT_P (trueop1)
3325             && (val = exact_log2 (UINTVAL (trueop1))) > 0)
3326           return simplify_gen_binary (LSHIFTRT, mode, op0,
3327                                             gen_int_shift_amount (mode, val));
3328       break;
3329 
3330     case DIV:
3331       /* Handle floating point and integers separately.  */
3332       if (SCALAR_FLOAT_MODE_P (mode))
3333           {
3334             /* Maybe change 0.0 / x to 0.0.  This transformation isn't
3335                safe for modes with NaNs, since 0.0 / 0.0 will then be
3336                NaN rather than 0.0.  Nor is it safe for modes with signed
3337                zeros, since dividing 0 by a negative number gives -0.0  */
3338             if (trueop0 == CONST0_RTX (mode)
3339                 && !HONOR_NANS (mode)
3340                 && !HONOR_SIGNED_ZEROS (mode)
3341                 && ! side_effects_p (op1))
3342               return op0;
3343             /* x/1.0 is x.  */
3344             if (trueop1 == CONST1_RTX (mode)
3345                 && !HONOR_SNANS (mode))
3346               return op0;
3347 
3348             if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3349                 && trueop1 != CONST0_RTX (mode))
3350               {
3351                 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3352 
3353                 /* x/-1.0 is -x.  */
3354                 if (real_equal (d1, &dconstm1)
3355                       && !HONOR_SNANS (mode))
3356                     return simplify_gen_unary (NEG, mode, op0, mode);
3357 
3358                 /* Change FP division by a constant into multiplication.
3359                      Only do this with -freciprocal-math.  */
3360                 if (flag_reciprocal_math
3361                       && !real_equal (d1, &dconst0))
3362                     {
3363                       REAL_VALUE_TYPE d;
3364                       real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
3365                       tem = const_double_from_real_value (d, mode);
3366                       return simplify_gen_binary (MULT, mode, op0, tem);
3367                     }
3368               }
3369           }
3370       else if (SCALAR_INT_MODE_P (mode))
3371           {
3372             /* 0/x is 0 (or x&0 if x has side-effects).  */
3373             if (trueop0 == CONST0_RTX (mode)
3374                 && !cfun->can_throw_non_call_exceptions)
3375               {
3376                 if (side_effects_p (op1))
3377                     return simplify_gen_binary (AND, mode, op1, trueop0);
3378                 return trueop0;
3379               }
3380             /* x/1 is x.  */
3381             if (trueop1 == CONST1_RTX (mode))
3382               {
3383                 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3384                 if (tem)
3385                     return tem;
3386               }
3387             /* x/-1 is -x.  */
3388             if (trueop1 == constm1_rtx)
3389               {
3390                 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3391                 if (x)
3392                     return simplify_gen_unary (NEG, mode, x, mode);
3393               }
3394           }
3395       break;
3396 
3397     case UMOD:
3398       /* 0%x is 0 (or x&0 if x has side-effects).  */
3399       if (trueop0 == CONST0_RTX (mode))
3400           {
3401             if (side_effects_p (op1))
3402               return simplify_gen_binary (AND, mode, op1, trueop0);
3403             return trueop0;
3404           }
3405       /* x%1 is 0 (of x&0 if x has side-effects).  */
3406       if (trueop1 == CONST1_RTX (mode))
3407           {
3408             if (side_effects_p (op0))
3409               return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3410             return CONST0_RTX (mode);
3411           }
3412       /* Implement modulus by power of two as AND.  */
3413       if (CONST_INT_P (trueop1)
3414             && exact_log2 (UINTVAL (trueop1)) > 0)
3415           return simplify_gen_binary (AND, mode, op0,
3416                                             gen_int_mode (UINTVAL (trueop1) - 1,
3417                                                               mode));
3418       break;
3419 
3420     case MOD:
3421       /* 0%x is 0 (or x&0 if x has side-effects).  */
3422       if (trueop0 == CONST0_RTX (mode))
3423           {
3424             if (side_effects_p (op1))
3425               return simplify_gen_binary (AND, mode, op1, trueop0);
3426             return trueop0;
3427           }
3428       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
3429       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
3430           {
3431             if (side_effects_p (op0))
3432               return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3433             return CONST0_RTX (mode);
3434           }
3435       break;
3436 
3437     case ROTATERT:
3438     case ROTATE:
3439       /* Canonicalize rotates by constant amount.  If op1 is bitsize / 2,
3440            prefer left rotation, if op1 is from bitsize / 2 + 1 to
3441            bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
3442            amount instead.  */
3443 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
3444       if (CONST_INT_P (trueop1)
3445             && IN_RANGE (INTVAL (trueop1),
3446                            GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
3447                            GET_MODE_UNIT_PRECISION (mode) - 1))
3448           {
3449             int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
3450             rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
3451             return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
3452                                               mode, op0, new_amount_rtx);
3453           }
3454 #endif
3455       /* FALLTHRU */
3456     case ASHIFTRT:
3457       if (trueop1 == CONST0_RTX (mode))
3458           return op0;
3459       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3460           return op0;
3461       /* Rotating ~0 always results in ~0.  */
3462       if (CONST_INT_P (trueop0)
3463             && HWI_COMPUTABLE_MODE_P (mode)
3464             && UINTVAL (trueop0) == GET_MODE_MASK (mode)
3465             && ! side_effects_p (op1))
3466           return op0;
3467 
3468     canonicalize_shift:
3469       /* Given:
3470            scalar modes M1, M2
3471            scalar constants c1, c2
3472            size (M2) > size (M1)
3473            c1 == size (M2) - size (M1)
3474            optimize:
3475            ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
3476                                          <low_part>)
3477                           (const_int <c2>))
3478            to:
3479            (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
3480                         <low_part>).  */
3481       if ((code == ASHIFTRT || code == LSHIFTRT)
3482             && is_a <scalar_int_mode> (mode, &int_mode)
3483             && SUBREG_P (op0)
3484             && CONST_INT_P (op1)
3485             && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
3486             && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
3487                                              &inner_mode)
3488             && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
3489             && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
3490             && (INTVAL (XEXP (SUBREG_REG (op0), 1))
3491                 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
3492             && subreg_lowpart_p (op0))
3493           {
3494             rtx tmp = gen_int_shift_amount
3495               (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
3496             tmp = simplify_gen_binary (code, inner_mode,
3497                                              XEXP (SUBREG_REG (op0), 0),
3498                                              tmp);
3499             return lowpart_subreg (int_mode, tmp, inner_mode);
3500           }
3501 
3502       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
3503           {
3504             val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
3505             if (val != INTVAL (op1))
3506               return simplify_gen_binary (code, mode, op0,
3507                                                   gen_int_shift_amount (mode, val));
3508           }
3509       break;
3510 
3511     case ASHIFT:
3512     case SS_ASHIFT:
3513     case US_ASHIFT:
3514       if (trueop1 == CONST0_RTX (mode))
3515           return op0;
3516       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3517           return op0;
3518       goto canonicalize_shift;
3519 
3520     case LSHIFTRT:
3521       if (trueop1 == CONST0_RTX (mode))
3522           return op0;
3523       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3524           return op0;
3525       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
3526       if (GET_CODE (op0) == CLZ
3527             && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
3528             && CONST_INT_P (trueop1)
3529             && STORE_FLAG_VALUE == 1
3530             && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
3531           {
3532             unsigned HOST_WIDE_INT zero_val = 0;
3533 
3534             if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
3535                 && zero_val == GET_MODE_PRECISION (inner_mode)
3536                 && INTVAL (trueop1) == exact_log2 (zero_val))
3537               return simplify_gen_relational (EQ, mode, inner_mode,
3538                                                       XEXP (op0, 0), const0_rtx);
3539           }
3540       goto canonicalize_shift;
3541 
3542     case SMIN:
3543       if (HWI_COMPUTABLE_MODE_P (mode)
3544             && mode_signbit_p (mode, trueop1)
3545             && ! side_effects_p (op0))
3546           return op1;
3547       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3548           return op0;
3549       tem = simplify_associative_operation (code, mode, op0, op1);
3550       if (tem)
3551           return tem;
3552       break;
3553 
3554     case SMAX:
3555       if (HWI_COMPUTABLE_MODE_P (mode)
3556             && CONST_INT_P (trueop1)
3557             && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
3558             && ! side_effects_p (op0))
3559           return op1;
3560       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3561           return op0;
3562       tem = simplify_associative_operation (code, mode, op0, op1);
3563       if (tem)
3564           return tem;
3565       break;
3566 
3567     case UMIN:
3568       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3569           return op1;
3570       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3571           return op0;
3572       tem = simplify_associative_operation (code, mode, op0, op1);
3573       if (tem)
3574           return tem;
3575       break;
3576 
3577     case UMAX:
3578       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
3579           return op1;
3580       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3581           return op0;
3582       tem = simplify_associative_operation (code, mode, op0, op1);
3583       if (tem)
3584           return tem;
3585       break;
3586 
3587     case SS_PLUS:
3588     case US_PLUS:
3589     case SS_MINUS:
3590     case US_MINUS:
3591     case SS_MULT:
3592     case US_MULT:
3593     case SS_DIV:
3594     case US_DIV:
3595       /* ??? There are simplifications that can be done.  */
3596       return 0;
3597 
3598     case VEC_SERIES:
3599       if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
3600           return gen_vec_duplicate (mode, op0);
3601       if (valid_for_const_vector_p (mode, op0)
3602             && valid_for_const_vector_p (mode, op1))
3603           return gen_const_vec_series (mode, op0, op1);
3604       return 0;
3605 
3606     case VEC_SELECT:
3607       if (!VECTOR_MODE_P (mode))
3608           {
3609             gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
3610             gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
3611             gcc_assert (GET_CODE (trueop1) == PARALLEL);
3612             gcc_assert (XVECLEN (trueop1, 0) == 1);
3613             gcc_assert (CONST_INT_P (XVECEXP (trueop1, 0, 0)));
3614 
3615             if (vec_duplicate_p (trueop0, &elt0))
3616               return elt0;
3617 
3618             if (GET_CODE (trueop0) == CONST_VECTOR)
3619               return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
3620                                                                   (trueop1, 0, 0)));
3621 
3622             /* Extract a scalar element from a nested VEC_SELECT expression
3623                (with optional nested VEC_CONCAT expression).  Some targets
3624                (i386) extract scalar element from a vector using chain of
3625                nested VEC_SELECT expressions.  When input operand is a memory
3626                operand, this operation can be simplified to a simple scalar
3627                load from an offseted memory address.  */
3628             int n_elts;
3629             if (GET_CODE (trueop0) == VEC_SELECT
3630                 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
3631                       .is_constant (&n_elts)))
3632               {
3633                 rtx op0 = XEXP (trueop0, 0);
3634                 rtx op1 = XEXP (trueop0, 1);
3635 
3636                 int i = INTVAL (XVECEXP (trueop1, 0, 0));
3637                 int elem;
3638 
3639                 rtvec vec;
3640                 rtx tmp_op, tmp;
3641 
3642                 gcc_assert (GET_CODE (op1) == PARALLEL);
3643                 gcc_assert (i < n_elts);
3644 
3645                 /* Select element, pointed by nested selector.  */
3646                 elem = INTVAL (XVECEXP (op1, 0, i));
3647 
3648                 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
3649                 if (GET_CODE (op0) == VEC_CONCAT)
3650                     {
3651                       rtx op00 = XEXP (op0, 0);
3652                       rtx op01 = XEXP (op0, 1);
3653 
3654                       machine_mode mode00, mode01;
3655                       int n_elts00, n_elts01;
3656 
3657                       mode00 = GET_MODE (op00);
3658                       mode01 = GET_MODE (op01);
3659 
3660                       /* Find out the number of elements of each operand.
3661                          Since the concatenated result has a constant number
3662                          of elements, the operands must too.  */
3663                       n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
3664                       n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
3665 
3666                       gcc_assert (n_elts == n_elts00 + n_elts01);
3667 
3668                       /* Select correct operand of VEC_CONCAT
3669                          and adjust selector. */
3670                       if (elem < n_elts01)
3671                         tmp_op = op00;
3672                       else
3673                         {
3674                           tmp_op = op01;
3675                           elem -= n_elts00;
3676                         }
3677                     }
3678                 else
3679                     tmp_op = op0;
3680 
3681                 vec = rtvec_alloc (1);
3682                 RTVEC_ELT (vec, 0) = GEN_INT (elem);
3683 
3684                 tmp = gen_rtx_fmt_ee (code, mode,
3685                                             tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
3686                 return tmp;
3687               }
3688           }
3689       else
3690           {
3691             gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
3692             gcc_assert (GET_MODE_INNER (mode)
3693                           == GET_MODE_INNER (GET_MODE (trueop0)));
3694             gcc_assert (GET_CODE (trueop1) == PARALLEL);
3695 
3696             if (vec_duplicate_p (trueop0, &elt0))
3697               /* It doesn't matter which elements are selected by trueop1,
3698                  because they are all the same.  */
3699               return gen_vec_duplicate (mode, elt0);
3700 
3701             if (GET_CODE (trueop0) == CONST_VECTOR)
3702               {
3703                 unsigned n_elts = XVECLEN (trueop1, 0);
3704                 rtvec v = rtvec_alloc (n_elts);
3705                 unsigned int i;
3706 
3707                 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
3708                 for (i = 0; i < n_elts; i++)
3709                     {
3710                       rtx x = XVECEXP (trueop1, 0, i);
3711 
3712                       gcc_assert (CONST_INT_P (x));
3713                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
3714                                                                    INTVAL (x));
3715                     }
3716 
3717                 return gen_rtx_CONST_VECTOR (mode, v);
3718               }
3719 
3720             /* Recognize the identity.  */
3721             if (GET_MODE (trueop0) == mode)
3722               {
3723                 bool maybe_ident = true;
3724                 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
3725                     {
3726                       rtx j = XVECEXP (trueop1, 0, i);
3727                       if (!CONST_INT_P (j) || INTVAL (j) != i)
3728                         {
3729                           maybe_ident = false;
3730                           break;
3731                         }
3732                     }
3733                 if (maybe_ident)
3734                     return trueop0;
3735               }
3736 
3737             /* If we build {a,b} then permute it, build the result directly.  */
3738             if (XVECLEN (trueop1, 0) == 2
3739                 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
3740                 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
3741                 && GET_CODE (trueop0) == VEC_CONCAT
3742                 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
3743                 && GET_MODE (XEXP (trueop0, 0)) == mode
3744                 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
3745                 && GET_MODE (XEXP (trueop0, 1)) == mode)
3746               {
3747                 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
3748                 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
3749                 rtx subop0, subop1;
3750 
3751                 gcc_assert (i0 < 4 && i1 < 4);
3752                 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
3753                 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
3754 
3755                 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
3756               }
3757 
3758             if (XVECLEN (trueop1, 0) == 2
3759                 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
3760                 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
3761                 && GET_CODE (trueop0) == VEC_CONCAT
3762                 && GET_MODE (trueop0) == mode)
3763               {
3764                 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
3765                 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
3766                 rtx subop0, subop1;
3767 
3768                 gcc_assert (i0 < 2 && i1 < 2);
3769                 subop0 = XEXP (trueop0, i0);
3770                 subop1 = XEXP (trueop0, i1);
3771 
3772                 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
3773               }
3774 
3775             /* If we select one half of a vec_concat, return that.  */
3776             int l0, l1;
3777             if (GET_CODE (trueop0) == VEC_CONCAT
3778                 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
3779                       .is_constant (&l0))
3780                 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
3781                       .is_constant (&l1))
3782                 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
3783               {
3784                 rtx subop0 = XEXP (trueop0, 0);
3785                 rtx subop1 = XEXP (trueop0, 1);
3786                 machine_mode mode0 = GET_MODE (subop0);
3787                 machine_mode mode1 = GET_MODE (subop1);
3788                 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
3789                 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
3790                     {
3791                       bool success = true;
3792                       for (int i = 1; i < l0; ++i)
3793                         {
3794                           rtx j = XVECEXP (trueop1, 0, i);
3795                           if (!CONST_INT_P (j) || INTVAL (j) != i)
3796                               {
3797                                 success = false;
3798                                 break;
3799                               }
3800                         }
3801                       if (success)
3802                         return subop0;
3803                     }
3804                 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
3805                     {
3806                       bool success = true;
3807                       for (int i = 1; i < l1; ++i)
3808                         {
3809                           rtx j = XVECEXP (trueop1, 0, i);
3810                           if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
3811                               {
3812                                 success = false;
3813                                 break;
3814                               }
3815                         }
3816                       if (success)
3817                         return subop1;
3818                     }
3819               }
3820           }
3821 
3822       if (XVECLEN (trueop1, 0) == 1
3823             && CONST_INT_P (XVECEXP (trueop1, 0, 0))
3824             && GET_CODE (trueop0) == VEC_CONCAT)
3825           {
3826             rtx vec = trueop0;
3827             offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
3828 
3829             /* Try to find the element in the VEC_CONCAT.  */
3830             while (GET_MODE (vec) != mode
3831                      && GET_CODE (vec) == VEC_CONCAT)
3832               {
3833                 poly_int64 vec_size;
3834 
3835                 if (CONST_INT_P (XEXP (vec, 0)))
3836                   {
3837                     /* vec_concat of two const_ints doesn't make sense with
3838                        respect to modes.  */
3839                     if (CONST_INT_P (XEXP (vec, 1)))
3840                       return 0;
3841 
3842                     vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
3843                                - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
3844                   }
3845                 else
3846                   vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
3847 
3848                 if (known_lt (offset, vec_size))
3849                     vec = XEXP (vec, 0);
3850                 else if (known_ge (offset, vec_size))
3851                     {
3852                       offset -= vec_size;
3853                       vec = XEXP (vec, 1);
3854                     }
3855                 else
3856                     break;
3857                 vec = avoid_constant_pool_reference (vec);
3858               }
3859 
3860             if (GET_MODE (vec) == mode)
3861               return vec;
3862           }
3863 
3864       /* If we select elements in a vec_merge that all come from the same
3865            operand, select from that operand directly.  */
3866       if (GET_CODE (op0) == VEC_MERGE)
3867           {
3868             rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
3869             if (CONST_INT_P (trueop02))
3870               {
3871                 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
3872                 bool all_operand0 = true;
3873                 bool all_operand1 = true;
3874                 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
3875                     {
3876                       rtx j = XVECEXP (trueop1, 0, i);
3877                       if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
3878                         all_operand1 = false;
3879                       else
3880                         all_operand0 = false;
3881                     }
3882                 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
3883                     return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
3884                 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
3885                     return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
3886               }
3887           }
3888 
3889       /* If we have two nested selects that are inverses of each
3890            other, replace them with the source operand.  */
3891       if (GET_CODE (trueop0) == VEC_SELECT
3892             && GET_MODE (XEXP (trueop0, 0)) == mode)
3893           {
3894             rtx op0_subop1 = XEXP (trueop0, 1);
3895             gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
3896             gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
3897 
3898             /* Apply the outer ordering vector to the inner one.  (The inner
3899                ordering vector is expressly permitted to be of a different
3900                length than the outer one.)  If the result is { 0, 1, ..., n-1 }
3901                then the two VEC_SELECTs cancel.  */
3902             for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
3903               {
3904                 rtx x = XVECEXP (trueop1, 0, i);
3905                 if (!CONST_INT_P (x))
3906                     return 0;
3907                 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
3908                 if (!CONST_INT_P (y) || i != INTVAL (y))
3909                     return 0;
3910               }
3911             return XEXP (trueop0, 0);
3912           }
3913 
3914       return 0;
3915     case VEC_CONCAT:
3916       {
3917           machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
3918                                               ? GET_MODE (trueop0)
3919                                               : GET_MODE_INNER (mode));
3920           machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
3921                                               ? GET_MODE (trueop1)
3922                                               : GET_MODE_INNER (mode));
3923 
3924           gcc_assert (VECTOR_MODE_P (mode));
3925           gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
3926                                     + GET_MODE_SIZE (op1_mode),
3927                                     GET_MODE_SIZE (mode)));
3928 
3929           if (VECTOR_MODE_P (op0_mode))
3930             gcc_assert (GET_MODE_INNER (mode)
3931                           == GET_MODE_INNER (op0_mode));
3932           else
3933             gcc_assert (GET_MODE_INNER (mode) == op0_mode);
3934 
3935           if (VECTOR_MODE_P (op1_mode))
3936             gcc_assert (GET_MODE_INNER (mode)
3937                           == GET_MODE_INNER (op1_mode));
3938           else
3939             gcc_assert (GET_MODE_INNER (mode) == op1_mode);
3940 
3941           unsigned int n_elts, in_n_elts;
3942           if ((GET_CODE (trueop0) == CONST_VECTOR
3943                || CONST_SCALAR_INT_P (trueop0)
3944                || CONST_DOUBLE_AS_FLOAT_P (trueop0))
3945               && (GET_CODE (trueop1) == CONST_VECTOR
3946                     || CONST_SCALAR_INT_P (trueop1)
3947                     || CONST_DOUBLE_AS_FLOAT_P (trueop1))
3948               && GET_MODE_NUNITS (mode).is_constant (&n_elts)
3949               && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
3950             {
3951               rtvec v = rtvec_alloc (n_elts);
3952               unsigned int i;
3953               for (i = 0; i < n_elts; i++)
3954                 {
3955                     if (i < in_n_elts)
3956                       {
3957                         if (!VECTOR_MODE_P (op0_mode))
3958                           RTVEC_ELT (v, i) = trueop0;
3959                         else
3960                           RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
3961                       }
3962                     else
3963                       {
3964                         if (!VECTOR_MODE_P (op1_mode))
3965                           RTVEC_ELT (v, i) = trueop1;
3966                         else
3967                           RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
3968                                                                          i - in_n_elts);
3969                       }
3970                 }
3971 
3972               return gen_rtx_CONST_VECTOR (mode, v);
3973             }
3974 
3975           /* Try to merge two VEC_SELECTs from the same vector into a single one.
3976              Restrict the transformation to avoid generating a VEC_SELECT with a
3977              mode unrelated to its operand.  */
3978           if (GET_CODE (trueop0) == VEC_SELECT
3979               && GET_CODE (trueop1) == VEC_SELECT
3980               && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
3981               && GET_MODE (XEXP (trueop0, 0)) == mode)
3982             {
3983               rtx par0 = XEXP (trueop0, 1);
3984               rtx par1 = XEXP (trueop1, 1);
3985               int len0 = XVECLEN (par0, 0);
3986               int len1 = XVECLEN (par1, 0);
3987               rtvec vec = rtvec_alloc (len0 + len1);
3988               for (int i = 0; i < len0; i++)
3989                 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
3990               for (int i = 0; i < len1; i++)
3991                 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
3992               return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
3993                                                   gen_rtx_PARALLEL (VOIDmode, vec));
3994             }
3995       }
3996       return 0;
3997 
3998     default:
3999       gcc_unreachable ();
4000     }
4001 
4002   if (mode == GET_MODE (op0)
4003       && mode == GET_MODE (op1)
4004       && vec_duplicate_p (op0, &elt0)
4005       && vec_duplicate_p (op1, &elt1))
4006     {
4007       /* Try applying the operator to ELT and see if that simplifies.
4008            We can duplicate the result if so.
4009 
4010            The reason we don't use simplify_gen_binary is that it isn't
4011            necessarily a win to convert things like:
4012 
4013              (plus:V (vec_duplicate:V (reg:S R1))
4014                        (vec_duplicate:V (reg:S R2)))
4015 
4016            to:
4017 
4018              (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4019 
4020            The first might be done entirely in vector registers while the
4021            second might need a move between register files.  */
4022       tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4023                                                elt0, elt1);
4024       if (tem)
4025           return gen_vec_duplicate (mode, tem);
4026     }
4027 
4028   return 0;
4029 }
4030 
4031 rtx
simplify_const_binary_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)4032 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4033                                          rtx op0, rtx op1)
4034 {
4035   if (VECTOR_MODE_P (mode)
4036       && code != VEC_CONCAT
4037       && GET_CODE (op0) == CONST_VECTOR
4038       && GET_CODE (op1) == CONST_VECTOR)
4039     {
4040       unsigned int n_elts;
4041       if (!CONST_VECTOR_NUNITS (op0).is_constant (&n_elts))
4042           return NULL_RTX;
4043 
4044       gcc_assert (known_eq (n_elts, CONST_VECTOR_NUNITS (op1)));
4045       gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4046       rtvec v = rtvec_alloc (n_elts);
4047       unsigned int i;
4048 
4049       for (i = 0; i < n_elts; i++)
4050           {
4051             rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4052                                                        CONST_VECTOR_ELT (op0, i),
4053                                                        CONST_VECTOR_ELT (op1, i));
4054             if (!x || !valid_for_const_vector_p (mode, x))
4055               return 0;
4056             RTVEC_ELT (v, i) = x;
4057           }
4058 
4059       return gen_rtx_CONST_VECTOR (mode, v);
4060     }
4061 
4062   if (VECTOR_MODE_P (mode)
4063       && code == VEC_CONCAT
4064       && (CONST_SCALAR_INT_P (op0)
4065             || CONST_FIXED_P (op0)
4066             || CONST_DOUBLE_AS_FLOAT_P (op0))
4067       && (CONST_SCALAR_INT_P (op1)
4068             || CONST_DOUBLE_AS_FLOAT_P (op1)
4069             || CONST_FIXED_P (op1)))
4070     {
4071       /* Both inputs have a constant number of elements, so the result
4072            must too.  */
4073       unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4074       rtvec v = rtvec_alloc (n_elts);
4075 
4076       gcc_assert (n_elts >= 2);
4077       if (n_elts == 2)
4078           {
4079             gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4080             gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4081 
4082             RTVEC_ELT (v, 0) = op0;
4083             RTVEC_ELT (v, 1) = op1;
4084           }
4085       else
4086           {
4087             unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4088             unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4089             unsigned i;
4090 
4091             gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4092             gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4093             gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4094 
4095             for (i = 0; i < op0_n_elts; ++i)
4096               RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4097             for (i = 0; i < op1_n_elts; ++i)
4098               RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4099           }
4100 
4101       return gen_rtx_CONST_VECTOR (mode, v);
4102     }
4103 
4104   if (SCALAR_FLOAT_MODE_P (mode)
4105       && CONST_DOUBLE_AS_FLOAT_P (op0)
4106       && CONST_DOUBLE_AS_FLOAT_P (op1)
4107       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4108     {
4109       if (code == AND
4110             || code == IOR
4111             || code == XOR)
4112           {
4113             long tmp0[4];
4114             long tmp1[4];
4115             REAL_VALUE_TYPE r;
4116             int i;
4117 
4118             real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4119                                 GET_MODE (op0));
4120             real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4121                                 GET_MODE (op1));
4122             for (i = 0; i < 4; i++)
4123               {
4124                 switch (code)
4125                 {
4126                 case AND:
4127                     tmp0[i] &= tmp1[i];
4128                     break;
4129                 case IOR:
4130                     tmp0[i] |= tmp1[i];
4131                     break;
4132                 case XOR:
4133                     tmp0[i] ^= tmp1[i];
4134                     break;
4135                 default:
4136                     gcc_unreachable ();
4137                 }
4138               }
4139              real_from_target (&r, tmp0, mode);
4140              return const_double_from_real_value (r, mode);
4141           }
4142       else
4143           {
4144             REAL_VALUE_TYPE f0, f1, value, result;
4145             const REAL_VALUE_TYPE *opr0, *opr1;
4146             bool inexact;
4147 
4148             opr0 = CONST_DOUBLE_REAL_VALUE (op0);
4149             opr1 = CONST_DOUBLE_REAL_VALUE (op1);
4150 
4151             if (HONOR_SNANS (mode)
4152                 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
4153                     || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
4154               return 0;
4155 
4156             real_convert (&f0, mode, opr0);
4157             real_convert (&f1, mode, opr1);
4158 
4159             if (code == DIV
4160                 && real_equal (&f1, &dconst0)
4161                 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
4162               return 0;
4163 
4164             if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4165                 && flag_trapping_math
4166                 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
4167               {
4168                 int s0 = REAL_VALUE_NEGATIVE (f0);
4169                 int s1 = REAL_VALUE_NEGATIVE (f1);
4170 
4171                 switch (code)
4172                     {
4173                     case PLUS:
4174                       /* Inf + -Inf = NaN plus exception.  */
4175                       if (s0 != s1)
4176                         return 0;
4177                       break;
4178                     case MINUS:
4179                       /* Inf - Inf = NaN plus exception.  */
4180                       if (s0 == s1)
4181                         return 0;
4182                       break;
4183                     case DIV:
4184                       /* Inf / Inf = NaN plus exception.  */
4185                       return 0;
4186                     default:
4187                       break;
4188                     }
4189               }
4190 
4191             if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4192                 && flag_trapping_math
4193                 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
4194                       || (REAL_VALUE_ISINF (f1)
4195                           && real_equal (&f0, &dconst0))))
4196               /* Inf * 0 = NaN plus exception.  */
4197               return 0;
4198 
4199             inexact = real_arithmetic (&value, rtx_to_tree_code (code),
4200                                              &f0, &f1);
4201             real_convert (&result, mode, &value);
4202 
4203             /* Don't constant fold this floating point operation if
4204                the result has overflowed and flag_trapping_math.  */
4205 
4206             if (flag_trapping_math
4207                 && MODE_HAS_INFINITIES (mode)
4208                 && REAL_VALUE_ISINF (result)
4209                 && !REAL_VALUE_ISINF (f0)
4210                 && !REAL_VALUE_ISINF (f1))
4211               /* Overflow plus exception.  */
4212               return 0;
4213 
4214             /* Don't constant fold this floating point operation if the
4215                result may dependent upon the run-time rounding mode and
4216                flag_rounding_math is set, or if GCC's software emulation
4217                is unable to accurately represent the result.  */
4218 
4219             if ((flag_rounding_math
4220                  || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
4221                 && (inexact || !real_identical (&result, &value)))
4222               return NULL_RTX;
4223 
4224             return const_double_from_real_value (result, mode);
4225           }
4226     }
4227 
4228   /* We can fold some multi-word operations.  */
4229   scalar_int_mode int_mode;
4230   if (is_a <scalar_int_mode> (mode, &int_mode)
4231       && CONST_SCALAR_INT_P (op0)
4232       && CONST_SCALAR_INT_P (op1))
4233     {
4234       wide_int result;
4235       bool overflow;
4236       rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
4237       rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
4238 
4239 #if TARGET_SUPPORTS_WIDE_INT == 0
4240       /* This assert keeps the simplification from producing a result
4241            that cannot be represented in a CONST_DOUBLE but a lot of
4242            upstream callers expect that this function never fails to
4243            simplify something and so you if you added this to the test
4244            above the code would die later anyway.  If this assert
4245            happens, you just need to make the port support wide int.  */
4246       gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
4247 #endif
4248       switch (code)
4249           {
4250           case MINUS:
4251             result = wi::sub (pop0, pop1);
4252             break;
4253 
4254           case PLUS:
4255             result = wi::add (pop0, pop1);
4256             break;
4257 
4258           case MULT:
4259             result = wi::mul (pop0, pop1);
4260             break;
4261 
4262           case DIV:
4263             result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
4264             if (overflow)
4265               return NULL_RTX;
4266             break;
4267 
4268           case MOD:
4269             result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
4270             if (overflow)
4271               return NULL_RTX;
4272             break;
4273 
4274           case UDIV:
4275             result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
4276             if (overflow)
4277               return NULL_RTX;
4278             break;
4279 
4280           case UMOD:
4281             result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
4282             if (overflow)
4283               return NULL_RTX;
4284             break;
4285 
4286           case AND:
4287             result = wi::bit_and (pop0, pop1);
4288             break;
4289 
4290           case IOR:
4291             result = wi::bit_or (pop0, pop1);
4292             break;
4293 
4294           case XOR:
4295             result = wi::bit_xor (pop0, pop1);
4296             break;
4297 
4298           case SMIN:
4299             result = wi::smin (pop0, pop1);
4300             break;
4301 
4302           case SMAX:
4303             result = wi::smax (pop0, pop1);
4304             break;
4305 
4306           case UMIN:
4307             result = wi::umin (pop0, pop1);
4308             break;
4309 
4310           case UMAX:
4311             result = wi::umax (pop0, pop1);
4312             break;
4313 
4314           case LSHIFTRT:
4315           case ASHIFTRT:
4316           case ASHIFT:
4317             {
4318               wide_int wop1 = pop1;
4319               if (SHIFT_COUNT_TRUNCATED)
4320                 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
4321               else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
4322                 return NULL_RTX;
4323 
4324               switch (code)
4325                 {
4326                 case LSHIFTRT:
4327                     result = wi::lrshift (pop0, wop1);
4328                     break;
4329 
4330                 case ASHIFTRT:
4331                     result = wi::arshift (pop0, wop1);
4332                     break;
4333 
4334                 case ASHIFT:
4335                     result = wi::lshift (pop0, wop1);
4336                     break;
4337 
4338                 default:
4339                     gcc_unreachable ();
4340                 }
4341               break;
4342             }
4343           case ROTATE:
4344           case ROTATERT:
4345             {
4346               if (wi::neg_p (pop1))
4347                 return NULL_RTX;
4348 
4349               switch (code)
4350                 {
4351                 case ROTATE:
4352                     result = wi::lrotate (pop0, pop1);
4353                     break;
4354 
4355                 case ROTATERT:
4356                     result = wi::rrotate (pop0, pop1);
4357                     break;
4358 
4359                 default:
4360                     gcc_unreachable ();
4361                 }
4362               break;
4363             }
4364           default:
4365             return NULL_RTX;
4366           }
4367       return immed_wide_int_const (result, int_mode);
4368     }
4369 
4370   /* Handle polynomial integers.  */
4371   if (NUM_POLY_INT_COEFFS > 1
4372       && is_a <scalar_int_mode> (mode, &int_mode)
4373       && poly_int_rtx_p (op0)
4374       && poly_int_rtx_p (op1))
4375     {
4376       poly_wide_int result;
4377       switch (code)
4378           {
4379           case PLUS:
4380             result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
4381             break;
4382 
4383           case MINUS:
4384             result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
4385             break;
4386 
4387           case MULT:
4388             if (CONST_SCALAR_INT_P (op1))
4389               result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
4390             else
4391               return NULL_RTX;
4392             break;
4393 
4394           case ASHIFT:
4395             if (CONST_SCALAR_INT_P (op1))
4396               {
4397                 wide_int shift = rtx_mode_t (op1, mode);
4398                 if (SHIFT_COUNT_TRUNCATED)
4399                     shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
4400                 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
4401                     return NULL_RTX;
4402                 result = wi::to_poly_wide (op0, mode) << shift;
4403               }
4404             else
4405               return NULL_RTX;
4406             break;
4407 
4408           case IOR:
4409             if (!CONST_SCALAR_INT_P (op1)
4410                 || !can_ior_p (wi::to_poly_wide (op0, mode),
4411                                    rtx_mode_t (op1, mode), &result))
4412               return NULL_RTX;
4413             break;
4414 
4415           default:
4416             return NULL_RTX;
4417           }
4418       return immed_wide_int_const (result, int_mode);
4419     }
4420 
4421   return NULL_RTX;
4422 }
4423 
4424 
4425 
4426 /* Return a positive integer if X should sort after Y.  The value
4427    returned is 1 if and only if X and Y are both regs.  */
4428 
4429 static int
simplify_plus_minus_op_data_cmp(rtx x,rtx y)4430 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
4431 {
4432   int result;
4433 
4434   result = (commutative_operand_precedence (y)
4435               - commutative_operand_precedence (x));
4436   if (result)
4437     return result + result;
4438 
4439   /* Group together equal REGs to do more simplification.  */
4440   if (REG_P (x) && REG_P (y))
4441     return REGNO (x) > REGNO (y);
4442 
4443   return 0;
4444 }
4445 
4446 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
4447    operands may be another PLUS or MINUS.
4448 
4449    Rather than test for specific case, we do this by a brute-force method
4450    and do all possible simplifications until no more changes occur.  Then
4451    we rebuild the operation.
4452 
4453    May return NULL_RTX when no changes were made.  */
4454 
4455 static rtx
simplify_plus_minus(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)4456 simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
4457                          rtx op1)
4458 {
4459   struct simplify_plus_minus_op_data
4460   {
4461     rtx op;
4462     short neg;
4463   } ops[16];
4464   rtx result, tem;
4465   int n_ops = 2;
4466   int changed, n_constants, canonicalized = 0;
4467   int i, j;
4468 
4469   memset (ops, 0, sizeof ops);
4470 
4471   /* Set up the two operands and then expand them until nothing has been
4472      changed.  If we run out of room in our array, give up; this should
4473      almost never happen.  */
4474 
4475   ops[0].op = op0;
4476   ops[0].neg = 0;
4477   ops[1].op = op1;
4478   ops[1].neg = (code == MINUS);
4479 
4480   do
4481     {
4482       changed = 0;
4483       n_constants = 0;
4484 
4485       for (i = 0; i < n_ops; i++)
4486           {
4487             rtx this_op = ops[i].op;
4488             int this_neg = ops[i].neg;
4489             enum rtx_code this_code = GET_CODE (this_op);
4490 
4491             switch (this_code)
4492               {
4493               case PLUS:
4494               case MINUS:
4495                 if (n_ops == ARRAY_SIZE (ops))
4496                     return NULL_RTX;
4497 
4498                 ops[n_ops].op = XEXP (this_op, 1);
4499                 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
4500                 n_ops++;
4501 
4502                 ops[i].op = XEXP (this_op, 0);
4503                 changed = 1;
4504                 /* If this operand was negated then we will potentially
4505                      canonicalize the expression.  Similarly if we don't
4506                      place the operands adjacent we're re-ordering the
4507                      expression and thus might be performing a
4508                      canonicalization.  Ignore register re-ordering.
4509                      ??? It might be better to shuffle the ops array here,
4510                      but then (plus (plus (A, B), plus (C, D))) wouldn't
4511                      be seen as non-canonical.  */
4512                 if (this_neg
4513                       || (i != n_ops - 2
4514                           && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
4515                     canonicalized = 1;
4516                 break;
4517 
4518               case NEG:
4519                 ops[i].op = XEXP (this_op, 0);
4520                 ops[i].neg = ! this_neg;
4521                 changed = 1;
4522                 canonicalized = 1;
4523                 break;
4524 
4525               case CONST:
4526                 if (n_ops != ARRAY_SIZE (ops)
4527                       && GET_CODE (XEXP (this_op, 0)) == PLUS
4528                       && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
4529                       && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
4530                     {
4531                       ops[i].op = XEXP (XEXP (this_op, 0), 0);
4532                       ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
4533                       ops[n_ops].neg = this_neg;
4534                       n_ops++;
4535                       changed = 1;
4536                       canonicalized = 1;
4537                     }
4538                 break;
4539 
4540               case NOT:
4541                 /* ~a -> (-a - 1) */
4542                 if (n_ops != ARRAY_SIZE (ops))
4543                     {
4544                       ops[n_ops].op = CONSTM1_RTX (mode);
4545                       ops[n_ops++].neg = this_neg;
4546                       ops[i].op = XEXP (this_op, 0);
4547                       ops[i].neg = !this_neg;
4548                       changed = 1;
4549                       canonicalized = 1;
4550                     }
4551                 break;
4552 
4553               case CONST_INT:
4554                 n_constants++;
4555                 if (this_neg)
4556                     {
4557                       ops[i].op = neg_const_int (mode, this_op);
4558                       ops[i].neg = 0;
4559                       changed = 1;
4560                       canonicalized = 1;
4561                     }
4562                 break;
4563 
4564               default:
4565                 break;
4566               }
4567           }
4568     }
4569   while (changed);
4570 
4571   if (n_constants > 1)
4572     canonicalized = 1;
4573 
4574   gcc_assert (n_ops >= 2);
4575 
4576   /* If we only have two operands, we can avoid the loops.  */
4577   if (n_ops == 2)
4578     {
4579       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
4580       rtx lhs, rhs;
4581 
4582       /* Get the two operands.  Be careful with the order, especially for
4583            the cases where code == MINUS.  */
4584       if (ops[0].neg && ops[1].neg)
4585           {
4586             lhs = gen_rtx_NEG (mode, ops[0].op);
4587             rhs = ops[1].op;
4588           }
4589       else if (ops[0].neg)
4590           {
4591             lhs = ops[1].op;
4592             rhs = ops[0].op;
4593           }
4594       else
4595           {
4596             lhs = ops[0].op;
4597             rhs = ops[1].op;
4598           }
4599 
4600       return simplify_const_binary_operation (code, mode, lhs, rhs);
4601     }
4602 
4603   /* Now simplify each pair of operands until nothing changes.  */
4604   while (1)
4605     {
4606       /* Insertion sort is good enough for a small array.  */
4607       for (i = 1; i < n_ops; i++)
4608           {
4609             struct simplify_plus_minus_op_data save;
4610             int cmp;
4611 
4612             j = i - 1;
4613             cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
4614             if (cmp <= 0)
4615               continue;
4616             /* Just swapping registers doesn't count as canonicalization.  */
4617             if (cmp != 1)
4618               canonicalized = 1;
4619 
4620             save = ops[i];
4621             do
4622               ops[j + 1] = ops[j];
4623             while (j--
4624                      && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
4625             ops[j + 1] = save;
4626           }
4627 
4628       changed = 0;
4629       for (i = n_ops - 1; i > 0; i--)
4630           for (j = i - 1; j >= 0; j--)
4631             {
4632               rtx lhs = ops[j].op, rhs = ops[i].op;
4633               int lneg = ops[j].neg, rneg = ops[i].neg;
4634 
4635               if (lhs != 0 && rhs != 0)
4636                 {
4637                     enum rtx_code ncode = PLUS;
4638 
4639                     if (lneg != rneg)
4640                       {
4641                         ncode = MINUS;
4642                         if (lneg)
4643                           std::swap (lhs, rhs);
4644                       }
4645                     else if (swap_commutative_operands_p (lhs, rhs))
4646                       std::swap (lhs, rhs);
4647 
4648                     if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
4649                         && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
4650                       {
4651                         rtx tem_lhs, tem_rhs;
4652 
4653                         tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
4654                         tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
4655                         tem = simplify_binary_operation (ncode, mode, tem_lhs,
4656                                                                  tem_rhs);
4657 
4658                         if (tem && !CONSTANT_P (tem))
4659                           tem = gen_rtx_CONST (GET_MODE (tem), tem);
4660                       }
4661                     else
4662                       tem = simplify_binary_operation (ncode, mode, lhs, rhs);
4663 
4664                     if (tem)
4665                       {
4666                         /* Reject "simplifications" that just wrap the two
4667                            arguments in a CONST.  Failure to do so can result
4668                            in infinite recursion with simplify_binary_operation
4669                            when it calls us to simplify CONST operations.
4670                            Also, if we find such a simplification, don't try
4671                            any more combinations with this rhs:  We must have
4672                            something like symbol+offset, ie. one of the
4673                            trivial CONST expressions we handle later.  */
4674                         if (GET_CODE (tem) == CONST
4675                               && GET_CODE (XEXP (tem, 0)) == ncode
4676                               && XEXP (XEXP (tem, 0), 0) == lhs
4677                               && XEXP (XEXP (tem, 0), 1) == rhs)
4678                           break;
4679                         lneg &= rneg;
4680                         if (GET_CODE (tem) == NEG)
4681                           tem = XEXP (tem, 0), lneg = !lneg;
4682                         if (CONST_INT_P (tem) && lneg)
4683                           tem = neg_const_int (mode, tem), lneg = 0;
4684 
4685                         ops[i].op = tem;
4686                         ops[i].neg = lneg;
4687                         ops[j].op = NULL_RTX;
4688                         changed = 1;
4689                         canonicalized = 1;
4690                       }
4691                 }
4692             }
4693 
4694       if (!changed)
4695           break;
4696 
4697       /* Pack all the operands to the lower-numbered entries.  */
4698       for (i = 0, j = 0; j < n_ops; j++)
4699           if (ops[j].op)
4700             {
4701               ops[i] = ops[j];
4702               i++;
4703             }
4704       n_ops = i;
4705     }
4706 
4707   /* If nothing changed, check that rematerialization of rtl instructions
4708      is still required.  */
4709   if (!canonicalized)
4710     {
4711       /* Perform rematerialization if only all operands are registers and
4712            all operations are PLUS.  */
4713       /* ??? Also disallow (non-global, non-frame) fixed registers to work
4714            around rs6000 and how it uses the CA register.  See PR67145.  */
4715       for (i = 0; i < n_ops; i++)
4716           if (ops[i].neg
4717               || !REG_P (ops[i].op)
4718               || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
4719                     && fixed_regs[REGNO (ops[i].op)]
4720                     && !global_regs[REGNO (ops[i].op)]
4721                     && ops[i].op != frame_pointer_rtx
4722                     && ops[i].op != arg_pointer_rtx
4723                     && ops[i].op != stack_pointer_rtx))
4724             return NULL_RTX;
4725       goto gen_result;
4726     }
4727 
4728   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
4729   if (n_ops == 2
4730       && CONST_INT_P (ops[1].op)
4731       && CONSTANT_P (ops[0].op)
4732       && ops[0].neg)
4733     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
4734 
4735   /* We suppressed creation of trivial CONST expressions in the
4736      combination loop to avoid recursion.  Create one manually now.
4737      The combination loop should have ensured that there is exactly
4738      one CONST_INT, and the sort will have ensured that it is last
4739      in the array and that any other constant will be next-to-last.  */
4740 
4741   if (n_ops > 1
4742       && CONST_INT_P (ops[n_ops - 1].op)
4743       && CONSTANT_P (ops[n_ops - 2].op))
4744     {
4745       rtx value = ops[n_ops - 1].op;
4746       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
4747           value = neg_const_int (mode, value);
4748       if (CONST_INT_P (value))
4749           {
4750             ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
4751                                                        INTVAL (value));
4752             n_ops--;
4753           }
4754     }
4755 
4756   /* Put a non-negated operand first, if possible.  */
4757 
4758   for (i = 0; i < n_ops && ops[i].neg; i++)
4759     continue;
4760   if (i == n_ops)
4761     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
4762   else if (i != 0)
4763     {
4764       tem = ops[0].op;
4765       ops[0] = ops[i];
4766       ops[i].op = tem;
4767       ops[i].neg = 1;
4768     }
4769 
4770   /* Now make the result by performing the requested operations.  */
4771  gen_result:
4772   result = ops[0].op;
4773   for (i = 1; i < n_ops; i++)
4774     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
4775                                    mode, result, ops[i].op);
4776 
4777   return result;
4778 }
4779 
4780 /* Check whether an operand is suitable for calling simplify_plus_minus.  */
4781 static bool
plus_minus_operand_p(const_rtx x)4782 plus_minus_operand_p (const_rtx x)
4783 {
4784   return GET_CODE (x) == PLUS
4785          || GET_CODE (x) == MINUS
4786            || (GET_CODE (x) == CONST
4787                && GET_CODE (XEXP (x, 0)) == PLUS
4788                && CONSTANT_P (XEXP (XEXP (x, 0), 0))
4789                && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
4790 }
4791 
4792 /* Like simplify_binary_operation except used for relational operators.
4793    MODE is the mode of the result. If MODE is VOIDmode, both operands must
4794    not also be VOIDmode.
4795 
4796    CMP_MODE specifies in which mode the comparison is done in, so it is
4797    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
4798    the operands or, if both are VOIDmode, the operands are compared in
4799    "infinite precision".  */
4800 rtx
simplify_relational_operation(enum rtx_code code,machine_mode mode,machine_mode cmp_mode,rtx op0,rtx op1)4801 simplify_relational_operation (enum rtx_code code, machine_mode mode,
4802                                      machine_mode cmp_mode, rtx op0, rtx op1)
4803 {
4804   rtx tem, trueop0, trueop1;
4805 
4806   if (cmp_mode == VOIDmode)
4807     cmp_mode = GET_MODE (op0);
4808   if (cmp_mode == VOIDmode)
4809     cmp_mode = GET_MODE (op1);
4810 
4811   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
4812   if (tem)
4813     {
4814       if (SCALAR_FLOAT_MODE_P (mode))
4815           {
4816           if (tem == const0_rtx)
4817             return CONST0_RTX (mode);
4818 #ifdef FLOAT_STORE_FLAG_VALUE
4819             {
4820               REAL_VALUE_TYPE val;
4821               val = FLOAT_STORE_FLAG_VALUE (mode);
4822               return const_double_from_real_value (val, mode);
4823             }
4824 #else
4825             return NULL_RTX;
4826 #endif
4827           }
4828       if (VECTOR_MODE_P (mode))
4829           {
4830             if (tem == const0_rtx)
4831               return CONST0_RTX (mode);
4832 #ifdef VECTOR_STORE_FLAG_VALUE
4833             {
4834               rtx val = VECTOR_STORE_FLAG_VALUE (mode);
4835               if (val == NULL_RTX)
4836                 return NULL_RTX;
4837               if (val == const1_rtx)
4838                 return CONST1_RTX (mode);
4839 
4840               return gen_const_vec_duplicate (mode, val);
4841             }
4842 #else
4843             return NULL_RTX;
4844 #endif
4845           }
4846 
4847       return tem;
4848     }
4849 
4850   /* For the following tests, ensure const0_rtx is op1.  */
4851   if (swap_commutative_operands_p (op0, op1)
4852       || (op0 == const0_rtx && op1 != const0_rtx))
4853     std::swap (op0, op1), code = swap_condition (code);
4854 
4855   /* If op0 is a compare, extract the comparison arguments from it.  */
4856   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
4857     return simplify_gen_relational (code, mode, VOIDmode,
4858                                             XEXP (op0, 0), XEXP (op0, 1));
4859 
4860   if (GET_MODE_CLASS (cmp_mode) == MODE_CC
4861       || CC0_P (op0))
4862     return NULL_RTX;
4863 
4864   trueop0 = avoid_constant_pool_reference (op0);
4865   trueop1 = avoid_constant_pool_reference (op1);
4866   return simplify_relational_operation_1 (code, mode, cmp_mode,
4867                                                     trueop0, trueop1);
4868 }
4869 
4870 /* This part of simplify_relational_operation is only used when CMP_MODE
4871    is not in class MODE_CC (i.e. it is a real comparison).
4872 
4873    MODE is the mode of the result, while CMP_MODE specifies in which
4874    mode the comparison is done in, so it is the mode of the operands.  */
4875 
4876 static rtx
simplify_relational_operation_1(enum rtx_code code,machine_mode mode,machine_mode cmp_mode,rtx op0,rtx op1)4877 simplify_relational_operation_1 (enum rtx_code code, machine_mode mode,
4878                                          machine_mode cmp_mode, rtx op0, rtx op1)
4879 {
4880   enum rtx_code op0code = GET_CODE (op0);
4881 
4882   if (op1 == const0_rtx && COMPARISON_P (op0))
4883     {
4884       /* If op0 is a comparison, extract the comparison arguments
4885          from it.  */
4886       if (code == NE)
4887           {
4888             if (GET_MODE (op0) == mode)
4889               return simplify_rtx (op0);
4890             else
4891               return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
4892                                                       XEXP (op0, 0), XEXP (op0, 1));
4893           }
4894       else if (code == EQ)
4895           {
4896             enum rtx_code new_code = reversed_comparison_code (op0, NULL);
4897             if (new_code != UNKNOWN)
4898               return simplify_gen_relational (new_code, mode, VOIDmode,
4899                                                       XEXP (op0, 0), XEXP (op0, 1));
4900           }
4901     }
4902 
4903   /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
4904      (GEU/LTU a -C).  Likewise for (LTU/GEU (PLUS a C) a).  */
4905   if ((code == LTU || code == GEU)
4906       && GET_CODE (op0) == PLUS
4907       && CONST_INT_P (XEXP (op0, 1))
4908       && (rtx_equal_p (op1, XEXP (op0, 0))
4909             || rtx_equal_p (op1, XEXP (op0, 1)))
4910       /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
4911       && XEXP (op0, 1) != const0_rtx)
4912     {
4913       rtx new_cmp
4914           = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
4915       return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
4916                                               cmp_mode, XEXP (op0, 0), new_cmp);
4917     }
4918 
4919   /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
4920      transformed into (LTU a -C).  */
4921   if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
4922       && CONST_INT_P (XEXP (op0, 1))
4923       && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
4924       && XEXP (op0, 1) != const0_rtx)
4925     {
4926       rtx new_cmp
4927           = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
4928       return simplify_gen_relational (LTU, mode, cmp_mode,
4929                                                XEXP (op0, 0), new_cmp);
4930     }
4931 
4932   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
4933   if ((code == LTU || code == GEU)
4934       && GET_CODE (op0) == PLUS
4935       && rtx_equal_p (op1, XEXP (op0, 1))
4936       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
4937       && !rtx_equal_p (op1, XEXP (op0, 0)))
4938     return simplify_gen_relational (code, mode, cmp_mode, op0,
4939                                             copy_rtx (XEXP (op0, 0)));
4940 
4941   if (op1 == const0_rtx)
4942     {
4943       /* Canonicalize (GTU x 0) as (NE x 0).  */
4944       if (code == GTU)
4945         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
4946       /* Canonicalize (LEU x 0) as (EQ x 0).  */
4947       if (code == LEU)
4948         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
4949     }
4950   else if (op1 == const1_rtx)
4951     {
4952       switch (code)
4953         {
4954         case GE:
4955             /* Canonicalize (GE x 1) as (GT x 0).  */
4956             return simplify_gen_relational (GT, mode, cmp_mode,
4957                                                     op0, const0_rtx);
4958           case GEU:
4959             /* Canonicalize (GEU x 1) as (NE x 0).  */
4960             return simplify_gen_relational (NE, mode, cmp_mode,
4961                                                     op0, const0_rtx);
4962           case LT:
4963             /* Canonicalize (LT x 1) as (LE x 0).  */
4964             return simplify_gen_relational (LE, mode, cmp_mode,
4965                                                     op0, const0_rtx);
4966           case LTU:
4967             /* Canonicalize (LTU x 1) as (EQ x 0).  */
4968             return simplify_gen_relational (EQ, mode, cmp_mode,
4969                                                     op0, const0_rtx);
4970           default:
4971             break;
4972           }
4973     }
4974   else if (op1 == constm1_rtx)
4975     {
4976       /* Canonicalize (LE x -1) as (LT x 0).  */
4977       if (code == LE)
4978         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
4979       /* Canonicalize (GT x -1) as (GE x 0).  */
4980       if (code == GT)
4981         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
4982     }
4983 
4984   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
4985   if ((code == EQ || code == NE)
4986       && (op0code == PLUS || op0code == MINUS)
4987       && CONSTANT_P (op1)
4988       && CONSTANT_P (XEXP (op0, 1))
4989       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
4990     {
4991       rtx x = XEXP (op0, 0);
4992       rtx c = XEXP (op0, 1);
4993       enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
4994       rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
4995 
4996       /* Detect an infinite recursive condition, where we oscillate at this
4997            simplification case between:
4998               A + B == C  <--->  C - B == A,
4999            where A, B, and C are all constants with non-simplifiable expressions,
5000            usually SYMBOL_REFs.  */
5001       if (GET_CODE (tem) == invcode
5002             && CONSTANT_P (x)
5003             && rtx_equal_p (c, XEXP (tem, 1)))
5004           return NULL_RTX;
5005 
5006       return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5007     }
5008 
5009   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5010      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
5011   scalar_int_mode int_mode, int_cmp_mode;
5012   if (code == NE
5013       && op1 == const0_rtx
5014       && is_int_mode (mode, &int_mode)
5015       && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5016       /* ??? Work-around BImode bugs in the ia64 backend.  */
5017       && int_mode != BImode
5018       && int_cmp_mode != BImode
5019       && nonzero_bits (op0, int_cmp_mode) == 1
5020       && STORE_FLAG_VALUE == 1)
5021     return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5022              ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5023              : lowpart_subreg (int_mode, op0, int_cmp_mode);
5024 
5025   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
5026   if ((code == EQ || code == NE)
5027       && op1 == const0_rtx
5028       && op0code == XOR)
5029     return simplify_gen_relational (code, mode, cmp_mode,
5030                                             XEXP (op0, 0), XEXP (op0, 1));
5031 
5032   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
5033   if ((code == EQ || code == NE)
5034       && op0code == XOR
5035       && rtx_equal_p (XEXP (op0, 0), op1)
5036       && !side_effects_p (XEXP (op0, 0)))
5037     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5038                                             CONST0_RTX (mode));
5039 
5040   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
5041   if ((code == EQ || code == NE)
5042       && op0code == XOR
5043       && rtx_equal_p (XEXP (op0, 1), op1)
5044       && !side_effects_p (XEXP (op0, 1)))
5045     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5046                                             CONST0_RTX (mode));
5047 
5048   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
5049   if ((code == EQ || code == NE)
5050       && op0code == XOR
5051       && CONST_SCALAR_INT_P (op1)
5052       && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5053     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5054                                             simplify_gen_binary (XOR, cmp_mode,
5055                                                                        XEXP (op0, 1), op1));
5056 
5057   /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5058      constant folding if x/y is a constant.  */
5059   if ((code == EQ || code == NE)
5060       && (op0code == AND || op0code == IOR)
5061       && !side_effects_p (op1)
5062       && op1 != CONST0_RTX (cmp_mode))
5063     {
5064       /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5065            (eq/ne (and (not y) x) 0).  */
5066       if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5067             || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5068           {
5069             rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5070                                                     cmp_mode);
5071             rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5072 
5073             return simplify_gen_relational (code, mode, cmp_mode, lhs,
5074                                                     CONST0_RTX (cmp_mode));
5075           }
5076 
5077       /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5078            (eq/ne (and (not x) y) 0).  */
5079       if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5080             || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5081           {
5082             rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5083                                                     cmp_mode);
5084             rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
5085 
5086             return simplify_gen_relational (code, mode, cmp_mode, lhs,
5087                                                     CONST0_RTX (cmp_mode));
5088           }
5089     }
5090 
5091   /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped.  */
5092   if ((code == EQ || code == NE)
5093       && GET_CODE (op0) == BSWAP
5094       && CONST_SCALAR_INT_P (op1))
5095     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5096                                             simplify_gen_unary (BSWAP, cmp_mode,
5097                                                                       op1, cmp_mode));
5098 
5099   /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y).  */
5100   if ((code == EQ || code == NE)
5101       && GET_CODE (op0) == BSWAP
5102       && GET_CODE (op1) == BSWAP)
5103     return simplify_gen_relational (code, mode, cmp_mode,
5104                                             XEXP (op0, 0), XEXP (op1, 0));
5105 
5106   if (op0code == POPCOUNT && op1 == const0_rtx)
5107     switch (code)
5108       {
5109       case EQ:
5110       case LE:
5111       case LEU:
5112           /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
5113           return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
5114                                                   XEXP (op0, 0), const0_rtx);
5115 
5116       case NE:
5117       case GT:
5118       case GTU:
5119           /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
5120           return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
5121                                                   XEXP (op0, 0), const0_rtx);
5122 
5123       default:
5124           break;
5125       }
5126 
5127   return NULL_RTX;
5128 }
5129 
5130 enum
5131 {
5132   CMP_EQ = 1,
5133   CMP_LT = 2,
5134   CMP_GT = 4,
5135   CMP_LTU = 8,
5136   CMP_GTU = 16
5137 };
5138 
5139 
5140 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
5141    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
5142    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
5143    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
5144    For floating-point comparisons, assume that the operands were ordered.  */
5145 
5146 static rtx
comparison_result(enum rtx_code code,int known_results)5147 comparison_result (enum rtx_code code, int known_results)
5148 {
5149   switch (code)
5150     {
5151     case EQ:
5152     case UNEQ:
5153       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
5154     case NE:
5155     case LTGT:
5156       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
5157 
5158     case LT:
5159     case UNLT:
5160       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
5161     case GE:
5162     case UNGE:
5163       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
5164 
5165     case GT:
5166     case UNGT:
5167       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
5168     case LE:
5169     case UNLE:
5170       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
5171 
5172     case LTU:
5173       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
5174     case GEU:
5175       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
5176 
5177     case GTU:
5178       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
5179     case LEU:
5180       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
5181 
5182     case ORDERED:
5183       return const_true_rtx;
5184     case UNORDERED:
5185       return const0_rtx;
5186     default:
5187       gcc_unreachable ();
5188     }
5189 }
5190 
5191 /* Check if the given comparison (done in the given MODE) is actually
5192    a tautology or a contradiction.  If the mode is VOID_mode, the
5193    comparison is done in "infinite precision".  If no simplification
5194    is possible, this function returns zero.  Otherwise, it returns
5195    either const_true_rtx or const0_rtx.  */
5196 
5197 rtx
simplify_const_relational_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)5198 simplify_const_relational_operation (enum rtx_code code,
5199                                              machine_mode mode,
5200                                              rtx op0, rtx op1)
5201 {
5202   rtx tem;
5203   rtx trueop0;
5204   rtx trueop1;
5205 
5206   gcc_assert (mode != VOIDmode
5207                 || (GET_MODE (op0) == VOIDmode
5208                       && GET_MODE (op1) == VOIDmode));
5209 
5210   /* If op0 is a compare, extract the comparison arguments from it.  */
5211   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5212     {
5213       op1 = XEXP (op0, 1);
5214       op0 = XEXP (op0, 0);
5215 
5216       if (GET_MODE (op0) != VOIDmode)
5217           mode = GET_MODE (op0);
5218       else if (GET_MODE (op1) != VOIDmode)
5219           mode = GET_MODE (op1);
5220       else
5221           return 0;
5222     }
5223 
5224   /* We can't simplify MODE_CC values since we don't know what the
5225      actual comparison is.  */
5226   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
5227     return 0;
5228 
5229   /* Make sure the constant is second.  */
5230   if (swap_commutative_operands_p (op0, op1))
5231     {
5232       std::swap (op0, op1);
5233       code = swap_condition (code);
5234     }
5235 
5236   trueop0 = avoid_constant_pool_reference (op0);
5237   trueop1 = avoid_constant_pool_reference (op1);
5238 
5239   /* For integer comparisons of A and B maybe we can simplify A - B and can
5240      then simplify a comparison of that with zero.  If A and B are both either
5241      a register or a CONST_INT, this can't help; testing for these cases will
5242      prevent infinite recursion here and speed things up.
5243 
5244      We can only do this for EQ and NE comparisons as otherwise we may
5245      lose or introduce overflow which we cannot disregard as undefined as
5246      we do not know the signedness of the operation on either the left or
5247      the right hand side of the comparison.  */
5248 
5249   if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
5250       && (code == EQ || code == NE)
5251       && ! ((REG_P (op0) || CONST_INT_P (trueop0))
5252               && (REG_P (op1) || CONST_INT_P (trueop1)))
5253       && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
5254       /* We cannot do this if tem is a nonzero address.  */
5255       && ! nonzero_address_p (tem))
5256     return simplify_const_relational_operation (signed_condition (code),
5257                                                             mode, tem, const0_rtx);
5258 
5259   if (! HONOR_NANS (mode) && code == ORDERED)
5260     return const_true_rtx;
5261 
5262   if (! HONOR_NANS (mode) && code == UNORDERED)
5263     return const0_rtx;
5264 
5265   /* For modes without NaNs, if the two operands are equal, we know the
5266      result except if they have side-effects.  Even with NaNs we know
5267      the result of unordered comparisons and, if signaling NaNs are
5268      irrelevant, also the result of LT/GT/LTGT.  */
5269   if ((! HONOR_NANS (trueop0)
5270        || code == UNEQ || code == UNLE || code == UNGE
5271        || ((code == LT || code == GT || code == LTGT)
5272              && ! HONOR_SNANS (trueop0)))
5273       && rtx_equal_p (trueop0, trueop1)
5274       && ! side_effects_p (trueop0))
5275     return comparison_result (code, CMP_EQ);
5276 
5277   /* If the operands are floating-point constants, see if we can fold
5278      the result.  */
5279   if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
5280       && CONST_DOUBLE_AS_FLOAT_P (trueop1)
5281       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
5282     {
5283       const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
5284       const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
5285 
5286       /* Comparisons are unordered iff at least one of the values is NaN.  */
5287       if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
5288           switch (code)
5289             {
5290             case UNEQ:
5291             case UNLT:
5292             case UNGT:
5293             case UNLE:
5294             case UNGE:
5295             case NE:
5296             case UNORDERED:
5297               return const_true_rtx;
5298             case EQ:
5299             case LT:
5300             case GT:
5301             case LE:
5302             case GE:
5303             case LTGT:
5304             case ORDERED:
5305               return const0_rtx;
5306             default:
5307               return 0;
5308             }
5309 
5310       return comparison_result (code,
5311                                         (real_equal (d0, d1) ? CMP_EQ :
5312                                          real_less (d0, d1) ? CMP_LT : CMP_GT));
5313     }
5314 
5315   /* Otherwise, see if the operands are both integers.  */
5316   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
5317       && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
5318     {
5319       /* It would be nice if we really had a mode here.  However, the
5320            largest int representable on the target is as good as
5321            infinite.  */
5322       machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
5323       rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
5324       rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
5325 
5326       if (wi::eq_p (ptrueop0, ptrueop1))
5327           return comparison_result (code, CMP_EQ);
5328       else
5329           {
5330             int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
5331             cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
5332             return comparison_result (code, cr);
5333           }
5334     }
5335 
5336   /* Optimize comparisons with upper and lower bounds.  */
5337   scalar_int_mode int_mode;
5338   if (CONST_INT_P (trueop1)
5339       && is_a <scalar_int_mode> (mode, &int_mode)
5340       && HWI_COMPUTABLE_MODE_P (int_mode)
5341       && !side_effects_p (trueop0))
5342     {
5343       int sign;
5344       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
5345       HOST_WIDE_INT val = INTVAL (trueop1);
5346       HOST_WIDE_INT mmin, mmax;
5347 
5348       if (code == GEU
5349             || code == LEU
5350             || code == GTU
5351             || code == LTU)
5352           sign = 0;
5353       else
5354           sign = 1;
5355 
5356       /* Get a reduced range if the sign bit is zero.  */
5357       if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
5358           {
5359             mmin = 0;
5360             mmax = nonzero;
5361           }
5362       else
5363           {
5364             rtx mmin_rtx, mmax_rtx;
5365             get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
5366 
5367             mmin = INTVAL (mmin_rtx);
5368             mmax = INTVAL (mmax_rtx);
5369             if (sign)
5370               {
5371                 unsigned int sign_copies
5372                     = num_sign_bit_copies (trueop0, int_mode);
5373 
5374                 mmin >>= (sign_copies - 1);
5375                 mmax >>= (sign_copies - 1);
5376               }
5377           }
5378 
5379       switch (code)
5380           {
5381           /* x >= y is always true for y <= mmin, always false for y > mmax.  */
5382           case GEU:
5383             if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
5384               return const_true_rtx;
5385             if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
5386               return const0_rtx;
5387             break;
5388           case GE:
5389             if (val <= mmin)
5390               return const_true_rtx;
5391             if (val > mmax)
5392               return const0_rtx;
5393             break;
5394 
5395           /* x <= y is always true for y >= mmax, always false for y < mmin.  */
5396           case LEU:
5397             if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
5398               return const_true_rtx;
5399             if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
5400               return const0_rtx;
5401             break;
5402           case LE:
5403             if (val >= mmax)
5404               return const_true_rtx;
5405             if (val < mmin)
5406               return const0_rtx;
5407             break;
5408 
5409           case EQ:
5410             /* x == y is always false for y out of range.  */
5411             if (val < mmin || val > mmax)
5412               return const0_rtx;
5413             break;
5414 
5415           /* x > y is always false for y >= mmax, always true for y < mmin.  */
5416           case GTU:
5417             if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
5418               return const0_rtx;
5419             if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
5420               return const_true_rtx;
5421             break;
5422           case GT:
5423             if (val >= mmax)
5424               return const0_rtx;
5425             if (val < mmin)
5426               return const_true_rtx;
5427             break;
5428 
5429           /* x < y is always false for y <= mmin, always true for y > mmax.  */
5430           case LTU:
5431             if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
5432               return const0_rtx;
5433             if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
5434               return const_true_rtx;
5435             break;
5436           case LT:
5437             if (val <= mmin)
5438               return const0_rtx;
5439             if (val > mmax)
5440               return const_true_rtx;
5441             break;
5442 
5443           case NE:
5444             /* x != y is always true for y out of range.  */
5445             if (val < mmin || val > mmax)
5446               return const_true_rtx;
5447             break;
5448 
5449           default:
5450             break;
5451           }
5452     }
5453 
5454   /* Optimize integer comparisons with zero.  */
5455   if (is_a <scalar_int_mode> (mode, &int_mode)
5456       && trueop1 == const0_rtx
5457       && !side_effects_p (trueop0))
5458     {
5459       /* Some addresses are known to be nonzero.  We don't know
5460            their sign, but equality comparisons are known.  */
5461       if (nonzero_address_p (trueop0))
5462           {
5463             if (code == EQ || code == LEU)
5464               return const0_rtx;
5465             if (code == NE || code == GTU)
5466               return const_true_rtx;
5467           }
5468 
5469       /* See if the first operand is an IOR with a constant.  If so, we
5470            may be able to determine the result of this comparison.  */
5471       if (GET_CODE (op0) == IOR)
5472           {
5473             rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
5474             if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
5475               {
5476                 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
5477                 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
5478                                     && (UINTVAL (inner_const)
5479                                           & (HOST_WIDE_INT_1U
5480                                              << sign_bitnum)));
5481 
5482                 switch (code)
5483                     {
5484                     case EQ:
5485                     case LEU:
5486                       return const0_rtx;
5487                     case NE:
5488                     case GTU:
5489                       return const_true_rtx;
5490                     case LT:
5491                     case LE:
5492                       if (has_sign)
5493                         return const_true_rtx;
5494                       break;
5495                     case GT:
5496                     case GE:
5497                       if (has_sign)
5498                         return const0_rtx;
5499                       break;
5500                     default:
5501                       break;
5502                     }
5503               }
5504           }
5505     }
5506 
5507   /* Optimize comparison of ABS with zero.  */
5508   if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
5509       && (GET_CODE (trueop0) == ABS
5510             || (GET_CODE (trueop0) == FLOAT_EXTEND
5511                 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
5512     {
5513       switch (code)
5514           {
5515           case LT:
5516             /* Optimize abs(x) < 0.0.  */
5517             if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
5518               return const0_rtx;
5519             break;
5520 
5521           case GE:
5522             /* Optimize abs(x) >= 0.0.  */
5523             if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
5524               return const_true_rtx;
5525             break;
5526 
5527           case UNGE:
5528             /* Optimize ! (abs(x) < 0.0).  */
5529             return const_true_rtx;
5530 
5531           default:
5532             break;
5533           }
5534     }
5535 
5536   return 0;
5537 }
5538 
5539 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
5540    where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
5541    or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
5542    can be simplified to that or NULL_RTX if not.
5543    Assume X is compared against zero with CMP_CODE and the true
5544    arm is TRUE_VAL and the false arm is FALSE_VAL.  */
5545 
5546 static rtx
simplify_cond_clz_ctz(rtx x,rtx_code cmp_code,rtx true_val,rtx false_val)5547 simplify_cond_clz_ctz (rtx x, rtx_code cmp_code, rtx true_val, rtx false_val)
5548 {
5549   if (cmp_code != EQ && cmp_code != NE)
5550     return NULL_RTX;
5551 
5552   /* Result on X == 0 and X !=0 respectively.  */
5553   rtx on_zero, on_nonzero;
5554   if (cmp_code == EQ)
5555     {
5556       on_zero = true_val;
5557       on_nonzero = false_val;
5558     }
5559   else
5560     {
5561       on_zero = false_val;
5562       on_nonzero = true_val;
5563     }
5564 
5565   rtx_code op_code = GET_CODE (on_nonzero);
5566   if ((op_code != CLZ && op_code != CTZ)
5567       || !rtx_equal_p (XEXP (on_nonzero, 0), x)
5568       || !CONST_INT_P (on_zero))
5569     return NULL_RTX;
5570 
5571   HOST_WIDE_INT op_val;
5572   scalar_int_mode mode ATTRIBUTE_UNUSED
5573     = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
5574   if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
5575        || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
5576       && op_val == INTVAL (on_zero))
5577     return on_nonzero;
5578 
5579   return NULL_RTX;
5580 }
5581 
5582 
5583 /* Simplify CODE, an operation with result mode MODE and three operands,
5584    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
5585    a constant.  Return 0 if no simplifications is possible.  */
5586 
5587 rtx
simplify_ternary_operation(enum rtx_code code,machine_mode mode,machine_mode op0_mode,rtx op0,rtx op1,rtx op2)5588 simplify_ternary_operation (enum rtx_code code, machine_mode mode,
5589                                   machine_mode op0_mode, rtx op0, rtx op1,
5590                                   rtx op2)
5591 {
5592   bool any_change = false;
5593   rtx tem, trueop2;
5594   scalar_int_mode int_mode, int_op0_mode;
5595   unsigned int n_elts;
5596 
5597   switch (code)
5598     {
5599     case FMA:
5600       /* Simplify negations around the multiplication.  */
5601       /* -a * -b + c  =>  a * b + c.  */
5602       if (GET_CODE (op0) == NEG)
5603           {
5604             tem = simplify_unary_operation (NEG, mode, op1, mode);
5605             if (tem)
5606               op1 = tem, op0 = XEXP (op0, 0), any_change = true;
5607           }
5608       else if (GET_CODE (op1) == NEG)
5609           {
5610             tem = simplify_unary_operation (NEG, mode, op0, mode);
5611             if (tem)
5612               op0 = tem, op1 = XEXP (op1, 0), any_change = true;
5613           }
5614 
5615       /* Canonicalize the two multiplication operands.  */
5616       /* a * -b + c  =>  -b * a + c.  */
5617       if (swap_commutative_operands_p (op0, op1))
5618           std::swap (op0, op1), any_change = true;
5619 
5620       if (any_change)
5621           return gen_rtx_FMA (mode, op0, op1, op2);
5622       return NULL_RTX;
5623 
5624     case SIGN_EXTRACT:
5625     case ZERO_EXTRACT:
5626       if (CONST_INT_P (op0)
5627             && CONST_INT_P (op1)
5628             && CONST_INT_P (op2)
5629             && is_a <scalar_int_mode> (mode, &int_mode)
5630             && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
5631             && HWI_COMPUTABLE_MODE_P (int_mode))
5632           {
5633             /* Extracting a bit-field from a constant */
5634             unsigned HOST_WIDE_INT val = UINTVAL (op0);
5635             HOST_WIDE_INT op1val = INTVAL (op1);
5636             HOST_WIDE_INT op2val = INTVAL (op2);
5637             if (!BITS_BIG_ENDIAN)
5638               val >>= op2val;
5639             else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
5640               val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
5641             else
5642               /* Not enough information to calculate the bit position.  */
5643               break;
5644 
5645             if (HOST_BITS_PER_WIDE_INT != op1val)
5646               {
5647                 /* First zero-extend.  */
5648                 val &= (HOST_WIDE_INT_1U << op1val) - 1;
5649                 /* If desired, propagate sign bit.  */
5650                 if (code == SIGN_EXTRACT
5651                       && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
5652                          != 0)
5653                     val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
5654               }
5655 
5656             return gen_int_mode (val, int_mode);
5657           }
5658       break;
5659 
5660     case IF_THEN_ELSE:
5661       if (CONST_INT_P (op0))
5662           return op0 != const0_rtx ? op1 : op2;
5663 
5664       /* Convert c ? a : a into "a".  */
5665       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
5666           return op1;
5667 
5668       /* Convert a != b ? a : b into "a".  */
5669       if (GET_CODE (op0) == NE
5670             && ! side_effects_p (op0)
5671             && ! HONOR_NANS (mode)
5672             && ! HONOR_SIGNED_ZEROS (mode)
5673             && ((rtx_equal_p (XEXP (op0, 0), op1)
5674                  && rtx_equal_p (XEXP (op0, 1), op2))
5675                 || (rtx_equal_p (XEXP (op0, 0), op2)
5676                       && rtx_equal_p (XEXP (op0, 1), op1))))
5677           return op1;
5678 
5679       /* Convert a == b ? a : b into "b".  */
5680       if (GET_CODE (op0) == EQ
5681             && ! side_effects_p (op0)
5682             && ! HONOR_NANS (mode)
5683             && ! HONOR_SIGNED_ZEROS (mode)
5684             && ((rtx_equal_p (XEXP (op0, 0), op1)
5685                  && rtx_equal_p (XEXP (op0, 1), op2))
5686                 || (rtx_equal_p (XEXP (op0, 0), op2)
5687                       && rtx_equal_p (XEXP (op0, 1), op1))))
5688           return op2;
5689 
5690       /* Convert (!c) != {0,...,0} ? a : b into
5691          c != {0,...,0} ? b : a for vector modes.  */
5692       if (VECTOR_MODE_P (GET_MODE (op1))
5693             && GET_CODE (op0) == NE
5694             && GET_CODE (XEXP (op0, 0)) == NOT
5695             && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
5696           {
5697             rtx cv = XEXP (op0, 1);
5698             int nunits;
5699             bool ok = true;
5700             if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
5701               ok = false;
5702             else
5703               for (int i = 0; i < nunits; ++i)
5704                 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
5705                     {
5706                       ok = false;
5707                       break;
5708                     }
5709             if (ok)
5710               {
5711                 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
5712                                                   XEXP (XEXP (op0, 0), 0),
5713                                                   XEXP (op0, 1));
5714                 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
5715                 return retval;
5716               }
5717           }
5718 
5719       /* Convert x == 0 ? N : clz (x) into clz (x) when
5720            CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
5721            Similarly for ctz (x).  */
5722       if (COMPARISON_P (op0) && !side_effects_p (op0)
5723             && XEXP (op0, 1) == const0_rtx)
5724           {
5725             rtx simplified
5726               = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
5727                                              op1, op2);
5728             if (simplified)
5729               return simplified;
5730           }
5731 
5732       if (COMPARISON_P (op0) && ! side_effects_p (op0))
5733           {
5734             machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
5735                                                   ? GET_MODE (XEXP (op0, 1))
5736                                                   : GET_MODE (XEXP (op0, 0)));
5737             rtx temp;
5738 
5739             /* Look for happy constants in op1 and op2.  */
5740             if (CONST_INT_P (op1) && CONST_INT_P (op2))
5741               {
5742                 HOST_WIDE_INT t = INTVAL (op1);
5743                 HOST_WIDE_INT f = INTVAL (op2);
5744 
5745                 if (t == STORE_FLAG_VALUE && f == 0)
5746                   code = GET_CODE (op0);
5747                 else if (t == 0 && f == STORE_FLAG_VALUE)
5748                     {
5749                       enum rtx_code tmp;
5750                       tmp = reversed_comparison_code (op0, NULL);
5751                       if (tmp == UNKNOWN)
5752                         break;
5753                       code = tmp;
5754                     }
5755                 else
5756                     break;
5757 
5758                 return simplify_gen_relational (code, mode, cmp_mode,
5759                                                         XEXP (op0, 0), XEXP (op0, 1));
5760               }
5761 
5762             temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
5763                                                             cmp_mode, XEXP (op0, 0),
5764                                                             XEXP (op0, 1));
5765 
5766             /* See if any simplifications were possible.  */
5767             if (temp)
5768               {
5769                 if (CONST_INT_P (temp))
5770                     return temp == const0_rtx ? op2 : op1;
5771                 else if (temp)
5772                   return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
5773               }
5774           }
5775       break;
5776 
5777     case VEC_MERGE:
5778       gcc_assert (GET_MODE (op0) == mode);
5779       gcc_assert (GET_MODE (op1) == mode);
5780       gcc_assert (VECTOR_MODE_P (mode));
5781       trueop2 = avoid_constant_pool_reference (op2);
5782       if (CONST_INT_P (trueop2)
5783             && GET_MODE_NUNITS (mode).is_constant (&n_elts))
5784           {
5785             unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
5786             unsigned HOST_WIDE_INT mask;
5787             if (n_elts == HOST_BITS_PER_WIDE_INT)
5788               mask = -1;
5789             else
5790               mask = (HOST_WIDE_INT_1U << n_elts) - 1;
5791 
5792             if (!(sel & mask) && !side_effects_p (op0))
5793               return op1;
5794             if ((sel & mask) == mask && !side_effects_p (op1))
5795               return op0;
5796 
5797             rtx trueop0 = avoid_constant_pool_reference (op0);
5798             rtx trueop1 = avoid_constant_pool_reference (op1);
5799             if (GET_CODE (trueop0) == CONST_VECTOR
5800                 && GET_CODE (trueop1) == CONST_VECTOR)
5801               {
5802                 rtvec v = rtvec_alloc (n_elts);
5803                 unsigned int i;
5804 
5805                 for (i = 0; i < n_elts; i++)
5806                     RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
5807                                             ? CONST_VECTOR_ELT (trueop0, i)
5808                                             : CONST_VECTOR_ELT (trueop1, i));
5809                 return gen_rtx_CONST_VECTOR (mode, v);
5810               }
5811 
5812             /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
5813                if no element from a appears in the result.  */
5814             if (GET_CODE (op0) == VEC_MERGE)
5815               {
5816                 tem = avoid_constant_pool_reference (XEXP (op0, 2));
5817                 if (CONST_INT_P (tem))
5818                     {
5819                       unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
5820                       if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
5821                         return simplify_gen_ternary (code, mode, mode,
5822                                                              XEXP (op0, 1), op1, op2);
5823                       if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
5824                         return simplify_gen_ternary (code, mode, mode,
5825                                                              XEXP (op0, 0), op1, op2);
5826                     }
5827               }
5828             if (GET_CODE (op1) == VEC_MERGE)
5829               {
5830                 tem = avoid_constant_pool_reference (XEXP (op1, 2));
5831                 if (CONST_INT_P (tem))
5832                     {
5833                       unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
5834                       if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
5835                         return simplify_gen_ternary (code, mode, mode,
5836                                                              op0, XEXP (op1, 1), op2);
5837                       if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
5838                         return simplify_gen_ternary (code, mode, mode,
5839                                                              op0, XEXP (op1, 0), op2);
5840                     }
5841               }
5842 
5843             /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
5844                with a.  */
5845             if (GET_CODE (op0) == VEC_DUPLICATE
5846                 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
5847                 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
5848                 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
5849               {
5850                 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
5851                 if (CONST_INT_P (tem) && CONST_INT_P (op2))
5852                     {
5853                       if (XEXP (XEXP (op0, 0), 0) == op1
5854                           && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
5855                         return op1;
5856                     }
5857               }
5858             /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
5859                (const_int N))
5860                with (vec_concat (X) (B)) if N == 1 or
5861                (vec_concat (A) (X)) if N == 2.  */
5862             if (GET_CODE (op0) == VEC_DUPLICATE
5863                 && GET_CODE (op1) == CONST_VECTOR
5864                 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
5865                 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
5866                 && IN_RANGE (sel, 1, 2))
5867               {
5868                 rtx newop0 = XEXP (op0, 0);
5869                 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
5870                 if (sel == 2)
5871                     std::swap (newop0, newop1);
5872                 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
5873               }
5874             /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
5875                with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
5876                Only applies for vectors of two elements.  */
5877             if (GET_CODE (op0) == VEC_DUPLICATE
5878                 && GET_CODE (op1) == VEC_CONCAT
5879                 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
5880                 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
5881                 && IN_RANGE (sel, 1, 2))
5882               {
5883                 rtx newop0 = XEXP (op0, 0);
5884                 rtx newop1 = XEXP (op1, 2 - sel);
5885                 rtx otherop = XEXP (op1, sel - 1);
5886                 if (sel == 2)
5887                     std::swap (newop0, newop1);
5888                 /* Don't want to throw away the other part of the vec_concat if
5889                      it has side-effects.  */
5890                 if (!side_effects_p (otherop))
5891                     return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
5892               }
5893 
5894             /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
5895                                          (const_int n))
5896                with (vec_concat x y) or (vec_concat y x) depending on value
5897                of N.  */
5898             if (GET_CODE (op0) == VEC_DUPLICATE
5899                 && GET_CODE (op1) == VEC_DUPLICATE
5900                 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
5901                 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
5902                 && IN_RANGE (sel, 1, 2))
5903               {
5904                 rtx newop0 = XEXP (op0, 0);
5905                 rtx newop1 = XEXP (op1, 0);
5906                 if (sel == 2)
5907                     std::swap (newop0, newop1);
5908 
5909                 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
5910               }
5911           }
5912 
5913       if (rtx_equal_p (op0, op1)
5914             && !side_effects_p (op2) && !side_effects_p (op1))
5915           return op0;
5916 
5917       break;
5918 
5919     default:
5920       gcc_unreachable ();
5921     }
5922 
5923   return 0;
5924 }
5925 
5926 /* Evaluate a SUBREG of a CONST_INT or CONST_WIDE_INT or CONST_DOUBLE
5927    or CONST_FIXED or CONST_VECTOR, returning another CONST_INT or
5928    CONST_WIDE_INT or CONST_DOUBLE or CONST_FIXED or CONST_VECTOR.
5929 
5930    Works by unpacking INNER_BYTES bytes of OP into a collection of 8-bit values
5931    represented as a little-endian array of 'unsigned char', selecting by BYTE,
5932    and then repacking them again for OUTERMODE.  If OP is a CONST_VECTOR,
5933    FIRST_ELEM is the number of the first element to extract, otherwise
5934    FIRST_ELEM is ignored.  */
5935 
5936 static rtx
simplify_immed_subreg(fixed_size_mode outermode,rtx op,machine_mode innermode,unsigned int byte,unsigned int first_elem,unsigned int inner_bytes)5937 simplify_immed_subreg (fixed_size_mode outermode, rtx op,
5938                            machine_mode innermode, unsigned int byte,
5939                            unsigned int first_elem, unsigned int inner_bytes)
5940 {
5941   enum {
5942     value_bit = 8,
5943     value_mask = (1 << value_bit) - 1
5944   };
5945   unsigned char value[MAX_BITSIZE_MODE_ANY_MODE / value_bit];
5946   int value_start;
5947   int i;
5948   int elem;
5949 
5950   int num_elem;
5951   rtx * elems;
5952   int elem_bitsize;
5953   rtx result_s = NULL;
5954   rtvec result_v = NULL;
5955   enum mode_class outer_class;
5956   scalar_mode outer_submode;
5957   int max_bitsize;
5958 
5959   /* Some ports misuse CCmode.  */
5960   if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (op))
5961     return op;
5962 
5963   /* We have no way to represent a complex constant at the rtl level.  */
5964   if (COMPLEX_MODE_P (outermode))
5965     return NULL_RTX;
5966 
5967   /* We support any size mode.  */
5968   max_bitsize = MAX (GET_MODE_BITSIZE (outermode),
5969                          inner_bytes * BITS_PER_UNIT);
5970 
5971   /* Unpack the value.  */
5972 
5973   if (GET_CODE (op) == CONST_VECTOR)
5974     {
5975       num_elem = CEIL (inner_bytes, GET_MODE_UNIT_SIZE (innermode));
5976       elem_bitsize = GET_MODE_UNIT_BITSIZE (innermode);
5977     }
5978   else
5979     {
5980       num_elem = 1;
5981       elem_bitsize = max_bitsize;
5982     }
5983   /* If this asserts, it is too complicated; reducing value_bit may help.  */
5984   gcc_assert (BITS_PER_UNIT % value_bit == 0);
5985   /* I don't know how to handle endianness of sub-units.  */
5986   gcc_assert (elem_bitsize % BITS_PER_UNIT == 0);
5987 
5988   for (elem = 0; elem < num_elem; elem++)
5989     {
5990       unsigned char * vp;
5991       rtx el = (GET_CODE (op) == CONST_VECTOR
5992                     ? CONST_VECTOR_ELT (op, first_elem + elem)
5993                     : op);
5994 
5995       /* Vectors are kept in target memory order.  (This is probably
5996            a mistake.)  */
5997       {
5998           unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
5999           unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
6000                                 / BITS_PER_UNIT);
6001           unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
6002           unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
6003           unsigned bytele = (subword_byte % UNITS_PER_WORD
6004                                + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
6005           vp = value + (bytele * BITS_PER_UNIT) / value_bit;
6006       }
6007 
6008       switch (GET_CODE (el))
6009           {
6010           case CONST_INT:
6011             for (i = 0;
6012                  i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
6013                  i += value_bit)
6014               *vp++ = INTVAL (el) >> i;
6015             /* CONST_INTs are always logically sign-extended.  */
6016             for (; i < elem_bitsize; i += value_bit)
6017               *vp++ = INTVAL (el) < 0 ? -1 : 0;
6018             break;
6019 
6020           case CONST_WIDE_INT:
6021             {
6022               rtx_mode_t val = rtx_mode_t (el, GET_MODE_INNER (innermode));
6023               unsigned char extend = wi::sign_mask (val);
6024               int prec = wi::get_precision (val);
6025 
6026               for (i = 0; i < prec && i < elem_bitsize; i += value_bit)
6027                 *vp++ = wi::extract_uhwi (val, i, value_bit);
6028               for (; i < elem_bitsize; i += value_bit)
6029                 *vp++ = extend;
6030             }
6031             break;
6032 
6033           case CONST_DOUBLE:
6034             if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (el) == VOIDmode)
6035               {
6036                 unsigned char extend = 0;
6037                 /* If this triggers, someone should have generated a
6038                      CONST_INT instead.  */
6039                 gcc_assert (elem_bitsize > HOST_BITS_PER_WIDE_INT);
6040 
6041                 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
6042                     *vp++ = CONST_DOUBLE_LOW (el) >> i;
6043                 while (i < HOST_BITS_PER_DOUBLE_INT && i < elem_bitsize)
6044                     {
6045                       *vp++
6046                         = CONST_DOUBLE_HIGH (el) >> (i - HOST_BITS_PER_WIDE_INT);
6047                       i += value_bit;
6048                     }
6049 
6050                 if (CONST_DOUBLE_HIGH (el) >> (HOST_BITS_PER_WIDE_INT - 1))
6051                     extend = -1;
6052                 for (; i < elem_bitsize; i += value_bit)
6053                     *vp++ = extend;
6054               }
6055             else
6056               {
6057                 /* This is big enough for anything on the platform.  */
6058                 long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32];
6059                 scalar_float_mode el_mode;
6060 
6061                 el_mode = as_a <scalar_float_mode> (GET_MODE (el));
6062                 int bitsize = GET_MODE_BITSIZE (el_mode);
6063 
6064                 gcc_assert (bitsize <= elem_bitsize);
6065                 gcc_assert (bitsize % value_bit == 0);
6066 
6067                 real_to_target (tmp, CONST_DOUBLE_REAL_VALUE (el),
6068                                     GET_MODE (el));
6069 
6070                 /* real_to_target produces its result in words affected by
6071                      FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
6072                      and use WORDS_BIG_ENDIAN instead; see the documentation
6073                    of SUBREG in rtl.texi.  */
6074                 for (i = 0; i < bitsize; i += value_bit)
6075                     {
6076                       int ibase;
6077                       if (WORDS_BIG_ENDIAN)
6078                         ibase = bitsize - 1 - i;
6079                       else
6080                         ibase = i;
6081                       *vp++ = tmp[ibase / 32] >> i % 32;
6082                     }
6083 
6084                 /* It shouldn't matter what's done here, so fill it with
6085                      zero.  */
6086                 for (; i < elem_bitsize; i += value_bit)
6087                     *vp++ = 0;
6088               }
6089             break;
6090 
6091         case CONST_FIXED:
6092             if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
6093               {
6094                 for (i = 0; i < elem_bitsize; i += value_bit)
6095                     *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
6096               }
6097             else
6098               {
6099                 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
6100                     *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
6101               for (; i < HOST_BITS_PER_DOUBLE_INT && i < elem_bitsize;
6102                        i += value_bit)
6103                     *vp++ = CONST_FIXED_VALUE_HIGH (el)
6104                               >> (i - HOST_BITS_PER_WIDE_INT);
6105                 for (; i < elem_bitsize; i += value_bit)
6106                     *vp++ = 0;
6107               }
6108           break;
6109 
6110           default:
6111             gcc_unreachable ();
6112           }
6113     }
6114 
6115   /* Now, pick the right byte to start with.  */
6116   /* Renumber BYTE so that the least-significant byte is byte 0.  A special
6117      case is paradoxical SUBREGs, which shouldn't be adjusted since they
6118      will already have offset 0.  */
6119   if (inner_bytes >= GET_MODE_SIZE (outermode))
6120     {
6121       unsigned ibyte = inner_bytes - GET_MODE_SIZE (outermode) - byte;
6122       unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
6123       unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
6124       byte = (subword_byte % UNITS_PER_WORD
6125                 + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
6126     }
6127 
6128   /* BYTE should still be inside OP.  (Note that BYTE is unsigned,
6129      so if it's become negative it will instead be very large.)  */
6130   gcc_assert (byte < inner_bytes);
6131 
6132   /* Convert from bytes to chunks of size value_bit.  */
6133   value_start = byte * (BITS_PER_UNIT / value_bit);
6134 
6135   /* Re-pack the value.  */
6136   num_elem = GET_MODE_NUNITS (outermode);
6137 
6138   if (VECTOR_MODE_P (outermode))
6139     {
6140       result_v = rtvec_alloc (num_elem);
6141       elems = &RTVEC_ELT (result_v, 0);
6142     }
6143   else
6144     elems = &result_s;
6145 
6146   outer_submode = GET_MODE_INNER (outermode);
6147   outer_class = GET_MODE_CLASS (outer_submode);
6148   elem_bitsize = GET_MODE_BITSIZE (outer_submode);
6149 
6150   gcc_assert (elem_bitsize % value_bit == 0);
6151   gcc_assert (elem_bitsize + value_start * value_bit <= max_bitsize);
6152 
6153   for (elem = 0; elem < num_elem; elem++)
6154     {
6155       unsigned char *vp;
6156 
6157       /* Vectors are stored in target memory order.  (This is probably
6158            a mistake.)  */
6159       {
6160           unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
6161           unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
6162                                 / BITS_PER_UNIT);
6163           unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
6164           unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
6165           unsigned bytele = (subword_byte % UNITS_PER_WORD
6166                                + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
6167           vp = value + value_start + (bytele * BITS_PER_UNIT) / value_bit;
6168       }
6169 
6170       switch (outer_class)
6171           {
6172           case MODE_INT:
6173           case MODE_PARTIAL_INT:
6174             {
6175               int u;
6176               int base = 0;
6177               int units
6178                 = (GET_MODE_BITSIZE (outer_submode) + HOST_BITS_PER_WIDE_INT - 1)
6179                 / HOST_BITS_PER_WIDE_INT;
6180               HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];
6181               wide_int r;
6182 
6183               if (GET_MODE_PRECISION (outer_submode) > MAX_BITSIZE_MODE_ANY_INT)
6184                 return NULL_RTX;
6185               for (u = 0; u < units; u++)
6186                 {
6187                     unsigned HOST_WIDE_INT buf = 0;
6188                     for (i = 0;
6189                          i < HOST_BITS_PER_WIDE_INT && base + i < elem_bitsize;
6190                          i += value_bit)
6191                       buf |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
6192 
6193                     tmp[u] = buf;
6194                     base += HOST_BITS_PER_WIDE_INT;
6195                 }
6196               r = wide_int::from_array (tmp, units,
6197                                               GET_MODE_PRECISION (outer_submode));
6198 #if TARGET_SUPPORTS_WIDE_INT == 0
6199               /* Make sure r will fit into CONST_INT or CONST_DOUBLE.  */
6200               if (wi::min_precision (r, SIGNED) > HOST_BITS_PER_DOUBLE_INT)
6201                 return NULL_RTX;
6202 #endif
6203               elems[elem] = immed_wide_int_const (r, outer_submode);
6204             }
6205             break;
6206 
6207           case MODE_FLOAT:
6208           case MODE_DECIMAL_FLOAT:
6209             {
6210               REAL_VALUE_TYPE r;
6211               long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32] = { 0 };
6212 
6213               /* real_from_target wants its input in words affected by
6214                  FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
6215                  and use WORDS_BIG_ENDIAN instead; see the documentation
6216                  of SUBREG in rtl.texi.  */
6217               for (i = 0; i < elem_bitsize; i += value_bit)
6218                 {
6219                     int ibase;
6220                     if (WORDS_BIG_ENDIAN)
6221                       ibase = elem_bitsize - 1 - i;
6222                     else
6223                       ibase = i;
6224                     tmp[ibase / 32] |= (*vp++ & value_mask) << i % 32;
6225                 }
6226 
6227               real_from_target (&r, tmp, outer_submode);
6228               elems[elem] = const_double_from_real_value (r, outer_submode);
6229             }
6230             break;
6231 
6232           case MODE_FRACT:
6233           case MODE_UFRACT:
6234           case MODE_ACCUM:
6235           case MODE_UACCUM:
6236             {
6237               FIXED_VALUE_TYPE f;
6238               f.data.low = 0;
6239               f.data.high = 0;
6240               f.mode = outer_submode;
6241 
6242               for (i = 0;
6243                      i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
6244                      i += value_bit)
6245                 f.data.low |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
6246               for (; i < elem_bitsize; i += value_bit)
6247                 f.data.high |= ((unsigned HOST_WIDE_INT)(*vp++ & value_mask)
6248                                    << (i - HOST_BITS_PER_WIDE_INT));
6249 
6250               elems[elem] = CONST_FIXED_FROM_FIXED_VALUE (f, outer_submode);
6251           }
6252           break;
6253 
6254           default:
6255             gcc_unreachable ();
6256           }
6257     }
6258   if (VECTOR_MODE_P (outermode))
6259     return gen_rtx_CONST_VECTOR (outermode, result_v);
6260   else
6261     return result_s;
6262 }
6263 
6264 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
6265    Return 0 if no simplifications are possible.  */
6266 rtx
simplify_subreg(machine_mode outermode,rtx op,machine_mode innermode,poly_uint64 byte)6267 simplify_subreg (machine_mode outermode, rtx op,
6268                      machine_mode innermode, poly_uint64 byte)
6269 {
6270   /* Little bit of sanity checking.  */
6271   gcc_assert (innermode != VOIDmode);
6272   gcc_assert (outermode != VOIDmode);
6273   gcc_assert (innermode != BLKmode);
6274   gcc_assert (outermode != BLKmode);
6275 
6276   gcc_assert (GET_MODE (op) == innermode
6277                 || GET_MODE (op) == VOIDmode);
6278 
6279   poly_uint64 outersize = GET_MODE_SIZE (outermode);
6280   if (!multiple_p (byte, outersize))
6281     return NULL_RTX;
6282 
6283   poly_uint64 innersize = GET_MODE_SIZE (innermode);
6284   if (maybe_ge (byte, innersize))
6285     return NULL_RTX;
6286 
6287   if (outermode == innermode && known_eq (byte, 0U))
6288     return op;
6289 
6290   if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
6291     {
6292       rtx elt;
6293 
6294       if (VECTOR_MODE_P (outermode)
6295             && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
6296             && vec_duplicate_p (op, &elt))
6297           return gen_vec_duplicate (outermode, elt);
6298 
6299       if (outermode == GET_MODE_INNER (innermode)
6300             && vec_duplicate_p (op, &elt))
6301           return elt;
6302     }
6303 
6304   if (CONST_SCALAR_INT_P (op)
6305       || CONST_DOUBLE_AS_FLOAT_P (op)
6306       || CONST_FIXED_P (op)
6307       || GET_CODE (op) == CONST_VECTOR)
6308     {
6309       /* simplify_immed_subreg deconstructs OP into bytes and constructs
6310            the result from bytes, so it only works if the sizes of the modes
6311            and the value of the offset are known at compile time.  Cases that
6312            that apply to general modes and offsets should be handled here
6313            before calling simplify_immed_subreg.  */
6314       fixed_size_mode fs_outermode, fs_innermode;
6315       unsigned HOST_WIDE_INT cbyte;
6316       if (is_a <fixed_size_mode> (outermode, &fs_outermode)
6317             && is_a <fixed_size_mode> (innermode, &fs_innermode)
6318             && byte.is_constant (&cbyte))
6319           return simplify_immed_subreg (fs_outermode, op, fs_innermode, cbyte,
6320                                               0, GET_MODE_SIZE (fs_innermode));
6321 
6322       /* Handle constant-sized outer modes and variable-sized inner modes.  */
6323       unsigned HOST_WIDE_INT first_elem;
6324       if (GET_CODE (op) == CONST_VECTOR
6325             && is_a <fixed_size_mode> (outermode, &fs_outermode)
6326             && constant_multiple_p (byte, GET_MODE_UNIT_SIZE (innermode),
6327                                           &first_elem))
6328           return simplify_immed_subreg (fs_outermode, op, innermode, 0,
6329                                               first_elem,
6330                                               GET_MODE_SIZE (fs_outermode));
6331 
6332       return NULL_RTX;
6333     }
6334 
6335   /* Changing mode twice with SUBREG => just change it once,
6336      or not at all if changing back op starting mode.  */
6337   if (GET_CODE (op) == SUBREG)
6338     {
6339       machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
6340       poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
6341       rtx newx;
6342 
6343       if (outermode == innermostmode
6344             && known_eq (byte, 0U)
6345             && known_eq (SUBREG_BYTE (op), 0))
6346           return SUBREG_REG (op);
6347 
6348       /* Work out the memory offset of the final OUTERMODE value relative
6349            to the inner value of OP.  */
6350       poly_int64 mem_offset = subreg_memory_offset (outermode,
6351                                                                 innermode, byte);
6352       poly_int64 op_mem_offset = subreg_memory_offset (op);
6353       poly_int64 final_offset = mem_offset + op_mem_offset;
6354 
6355       /* See whether resulting subreg will be paradoxical.  */
6356       if (!paradoxical_subreg_p (outermode, innermostmode))
6357           {
6358             /* Bail out in case resulting subreg would be incorrect.  */
6359             if (maybe_lt (final_offset, 0)
6360                 || maybe_ge (poly_uint64 (final_offset), innermostsize)
6361                 || !multiple_p (final_offset, outersize))
6362               return NULL_RTX;
6363           }
6364       else
6365           {
6366             poly_int64 required_offset = subreg_memory_offset (outermode,
6367                                                                            innermostmode, 0);
6368             if (maybe_ne (final_offset, required_offset))
6369               return NULL_RTX;
6370             /* Paradoxical subregs always have byte offset 0.  */
6371             final_offset = 0;
6372           }
6373 
6374       /* Recurse for further possible simplifications.  */
6375       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
6376                                     final_offset);
6377       if (newx)
6378           return newx;
6379       if (validate_subreg (outermode, innermostmode,
6380                                  SUBREG_REG (op), final_offset))
6381           {
6382             newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
6383             if (SUBREG_PROMOTED_VAR_P (op)
6384                 && SUBREG_PROMOTED_SIGN (op) >= 0
6385                 && GET_MODE_CLASS (outermode) == MODE_INT
6386                 && known_ge (outersize, innersize)
6387                 && known_le (outersize, innermostsize)
6388                 && subreg_lowpart_p (newx))
6389               {
6390                 SUBREG_PROMOTED_VAR_P (newx) = 1;
6391                 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
6392               }
6393             return newx;
6394           }
6395       return NULL_RTX;
6396     }
6397 
6398   /* SUBREG of a hard register => just change the register number
6399      and/or mode.  If the hard register is not valid in that mode,
6400      suppress this simplification.  If the hard register is the stack,
6401      frame, or argument pointer, leave this as a SUBREG.  */
6402 
6403   if (REG_P (op) && HARD_REGISTER_P (op))
6404     {
6405       unsigned int regno, final_regno;
6406 
6407       regno = REGNO (op);
6408       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
6409       if (HARD_REGISTER_NUM_P (final_regno))
6410           {
6411             rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
6412                                               subreg_memory_offset (outermode,
6413                                                                           innermode, byte));
6414 
6415             /* Propagate original regno.  We don't have any way to specify
6416                the offset inside original regno, so do so only for lowpart.
6417                The information is used only by alias analysis that can not
6418                grog partial register anyway.  */
6419 
6420             if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
6421               ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
6422             return x;
6423           }
6424     }
6425 
6426   /* If we have a SUBREG of a register that we are replacing and we are
6427      replacing it with a MEM, make a new MEM and try replacing the
6428      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
6429      or if we would be widening it.  */
6430 
6431   if (MEM_P (op)
6432       && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
6433       /* Allow splitting of volatile memory references in case we don't
6434          have instruction to move the whole thing.  */
6435       && (! MEM_VOLATILE_P (op)
6436             || ! have_insn_for (SET, innermode))
6437       && known_le (outersize, innersize))
6438     return adjust_address_nv (op, outermode, byte);
6439 
6440   /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
6441      of two parts.  */
6442   if (GET_CODE (op) == CONCAT
6443       || GET_CODE (op) == VEC_CONCAT)
6444     {
6445       poly_uint64 final_offset;
6446       rtx part, res;
6447 
6448       machine_mode part_mode = GET_MODE (XEXP (op, 0));
6449       if (part_mode == VOIDmode)
6450           part_mode = GET_MODE_INNER (GET_MODE (op));
6451       poly_uint64 part_size = GET_MODE_SIZE (part_mode);
6452       if (known_lt (byte, part_size))
6453           {
6454             part = XEXP (op, 0);
6455             final_offset = byte;
6456           }
6457       else if (known_ge (byte, part_size))
6458           {
6459             part = XEXP (op, 1);
6460             final_offset = byte - part_size;
6461           }
6462       else
6463           return NULL_RTX;
6464 
6465       if (maybe_gt (final_offset + outersize, part_size))
6466           return NULL_RTX;
6467 
6468       part_mode = GET_MODE (part);
6469       if (part_mode == VOIDmode)
6470           part_mode = GET_MODE_INNER (GET_MODE (op));
6471       res = simplify_subreg (outermode, part, part_mode, final_offset);
6472       if (res)
6473           return res;
6474       if (validate_subreg (outermode, part_mode, part, final_offset))
6475           return gen_rtx_SUBREG (outermode, part, final_offset);
6476       return NULL_RTX;
6477     }
6478 
6479   /* A SUBREG resulting from a zero extension may fold to zero if
6480      it extracts higher bits that the ZERO_EXTEND's source bits.  */
6481   if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
6482     {
6483       poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
6484       if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
6485           return CONST0_RTX (outermode);
6486     }
6487 
6488   scalar_int_mode int_outermode, int_innermode;
6489   if (is_a <scalar_int_mode> (outermode, &int_outermode)
6490       && is_a <scalar_int_mode> (innermode, &int_innermode)
6491       && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
6492     {
6493       /* Handle polynomial integers.  The upper bits of a paradoxical
6494            subreg are undefined, so this is safe regardless of whether
6495            we're truncating or extending.  */
6496       if (CONST_POLY_INT_P (op))
6497           {
6498             poly_wide_int val
6499               = poly_wide_int::from (const_poly_int_value (op),
6500                                            GET_MODE_PRECISION (int_outermode),
6501                                            SIGNED);
6502             return immed_wide_int_const (val, int_outermode);
6503           }
6504 
6505       if (GET_MODE_PRECISION (int_outermode)
6506             < GET_MODE_PRECISION (int_innermode))
6507           {
6508             rtx tem = simplify_truncation (int_outermode, op, int_innermode);
6509             if (tem)
6510               return tem;
6511           }
6512     }
6513 
6514   return NULL_RTX;
6515 }
6516 
6517 /* Make a SUBREG operation or equivalent if it folds.  */
6518 
6519 rtx
simplify_gen_subreg(machine_mode outermode,rtx op,machine_mode innermode,poly_uint64 byte)6520 simplify_gen_subreg (machine_mode outermode, rtx op,
6521                          machine_mode innermode, poly_uint64 byte)
6522 {
6523   rtx newx;
6524 
6525   newx = simplify_subreg (outermode, op, innermode, byte);
6526   if (newx)
6527     return newx;
6528 
6529   if (GET_CODE (op) == SUBREG
6530       || GET_CODE (op) == CONCAT
6531       || GET_MODE (op) == VOIDmode)
6532     return NULL_RTX;
6533 
6534   if (validate_subreg (outermode, innermode, op, byte))
6535     return gen_rtx_SUBREG (outermode, op, byte);
6536 
6537   return NULL_RTX;
6538 }
6539 
6540 /* Generates a subreg to get the least significant part of EXPR (in mode
6541    INNER_MODE) to OUTER_MODE.  */
6542 
6543 rtx
lowpart_subreg(machine_mode outer_mode,rtx expr,machine_mode inner_mode)6544 lowpart_subreg (machine_mode outer_mode, rtx expr,
6545                                    machine_mode inner_mode)
6546 {
6547   return simplify_gen_subreg (outer_mode, expr, inner_mode,
6548                                     subreg_lowpart_offset (outer_mode, inner_mode));
6549 }
6550 
6551 /* Simplify X, an rtx expression.
6552 
6553    Return the simplified expression or NULL if no simplifications
6554    were possible.
6555 
6556    This is the preferred entry point into the simplification routines;
6557    however, we still allow passes to call the more specific routines.
6558 
6559    Right now GCC has three (yes, three) major bodies of RTL simplification
6560    code that need to be unified.
6561 
6562           1. fold_rtx in cse.c.  This code uses various CSE specific
6563              information to aid in RTL simplification.
6564 
6565           2. simplify_rtx in combine.c.  Similar to fold_rtx, except that
6566              it uses combine specific information to aid in RTL
6567              simplification.
6568 
6569           3. The routines in this file.
6570 
6571 
6572    Long term we want to only have one body of simplification code; to
6573    get to that state I recommend the following steps:
6574 
6575           1. Pour over fold_rtx & simplify_rtx and move any simplifications
6576              which are not pass dependent state into these routines.
6577 
6578           2. As code is moved by #1, change fold_rtx & simplify_rtx to
6579              use this routine whenever possible.
6580 
6581           3. Allow for pass dependent state to be provided to these
6582              routines and add simplifications based on the pass dependent
6583              state.  Remove code from cse.c & combine.c that becomes
6584              redundant/dead.
6585 
6586     It will take time, but ultimately the compiler will be easier to
6587     maintain and improve.  It's totally silly that when we add a
6588     simplification that it needs to be added to 4 places (3 for RTL
6589     simplification and 1 for tree simplification.  */
6590 
6591 rtx
simplify_rtx(const_rtx x)6592 simplify_rtx (const_rtx x)
6593 {
6594   const enum rtx_code code = GET_CODE (x);
6595   const machine_mode mode = GET_MODE (x);
6596 
6597   switch (GET_RTX_CLASS (code))
6598     {
6599     case RTX_UNARY:
6600       return simplify_unary_operation (code, mode,
6601                                                XEXP (x, 0), GET_MODE (XEXP (x, 0)));
6602     case RTX_COMM_ARITH:
6603       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
6604           return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
6605 
6606       /* Fall through.  */
6607 
6608     case RTX_BIN_ARITH:
6609       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
6610 
6611     case RTX_TERNARY:
6612     case RTX_BITFIELD_OPS:
6613       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
6614                                                    XEXP (x, 0), XEXP (x, 1),
6615                                                    XEXP (x, 2));
6616 
6617     case RTX_COMPARE:
6618     case RTX_COMM_COMPARE:
6619       return simplify_relational_operation (code, mode,
6620                                             ((GET_MODE (XEXP (x, 0))
6621                                              != VOIDmode)
6622                                             ? GET_MODE (XEXP (x, 0))
6623                                             : GET_MODE (XEXP (x, 1))),
6624                                             XEXP (x, 0),
6625                                             XEXP (x, 1));
6626 
6627     case RTX_EXTRA:
6628       if (code == SUBREG)
6629           return simplify_subreg (mode, SUBREG_REG (x),
6630                                         GET_MODE (SUBREG_REG (x)),
6631                                         SUBREG_BYTE (x));
6632       break;
6633 
6634     case RTX_OBJ:
6635       if (code == LO_SUM)
6636           {
6637             /* Convert (lo_sum (high FOO) FOO) to FOO.  */
6638             if (GET_CODE (XEXP (x, 0)) == HIGH
6639                 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
6640             return XEXP (x, 1);
6641           }
6642       break;
6643 
6644     default:
6645       break;
6646     }
6647   return NULL;
6648 }
6649 
6650 #if CHECKING_P
6651 
6652 namespace selftest {
6653 
6654 /* Make a unique pseudo REG of mode MODE for use by selftests.  */
6655 
6656 static rtx
make_test_reg(machine_mode mode)6657 make_test_reg (machine_mode mode)
6658 {
6659   static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
6660 
6661   return gen_rtx_REG (mode, test_reg_num++);
6662 }
6663 
6664 /* Test vector simplifications involving VEC_DUPLICATE in which the
6665    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
6666    register that holds one element of MODE.  */
6667 
6668 static void
test_vector_ops_duplicate(machine_mode mode,rtx scalar_reg)6669 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
6670 {
6671   scalar_mode inner_mode = GET_MODE_INNER (mode);
6672   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
6673   poly_uint64 nunits = GET_MODE_NUNITS (mode);
6674   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
6675     {
6676       /* Test some simple unary cases with VEC_DUPLICATE arguments.  */
6677       rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
6678       rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
6679       ASSERT_RTX_EQ (duplicate,
6680                          simplify_unary_operation (NOT, mode,
6681                                                          duplicate_not, mode));
6682 
6683       rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
6684       rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
6685       ASSERT_RTX_EQ (duplicate,
6686                          simplify_unary_operation (NEG, mode,
6687                                                          duplicate_neg, mode));
6688 
6689       /* Test some simple binary cases with VEC_DUPLICATE arguments.  */
6690       ASSERT_RTX_EQ (duplicate,
6691                          simplify_binary_operation (PLUS, mode, duplicate,
6692                                                             CONST0_RTX (mode)));
6693 
6694       ASSERT_RTX_EQ (duplicate,
6695                          simplify_binary_operation (MINUS, mode, duplicate,
6696                                                             CONST0_RTX (mode)));
6697 
6698       ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
6699                                simplify_binary_operation (MINUS, mode, duplicate,
6700                                                                 duplicate));
6701     }
6702 
6703   /* Test a scalar VEC_SELECT of a VEC_DUPLICATE.  */
6704   rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
6705   ASSERT_RTX_PTR_EQ (scalar_reg,
6706                          simplify_binary_operation (VEC_SELECT, inner_mode,
6707                                                             duplicate, zero_par));
6708 
6709   /* And again with the final element.  */
6710   unsigned HOST_WIDE_INT const_nunits;
6711   if (nunits.is_constant (&const_nunits))
6712     {
6713       rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
6714       rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
6715       ASSERT_RTX_PTR_EQ (scalar_reg,
6716                                simplify_binary_operation (VEC_SELECT, inner_mode,
6717                                                                 duplicate, last_par));
6718     }
6719 
6720   /* Test a scalar subreg of a VEC_DUPLICATE.  */
6721   poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
6722   ASSERT_RTX_EQ (scalar_reg,
6723                      simplify_gen_subreg (inner_mode, duplicate,
6724                                               mode, offset));
6725 
6726   machine_mode narrower_mode;
6727   if (maybe_ne (nunits, 2U)
6728       && multiple_p (nunits, 2)
6729       && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
6730       && VECTOR_MODE_P (narrower_mode))
6731     {
6732       /* Test VEC_SELECT of a vector.  */
6733       rtx vec_par
6734           = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
6735       rtx narrower_duplicate
6736           = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
6737       ASSERT_RTX_EQ (narrower_duplicate,
6738                          simplify_binary_operation (VEC_SELECT, narrower_mode,
6739                                                             duplicate, vec_par));
6740 
6741       /* Test a vector subreg of a VEC_DUPLICATE.  */
6742       poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
6743       ASSERT_RTX_EQ (narrower_duplicate,
6744                          simplify_gen_subreg (narrower_mode, duplicate,
6745                                                     mode, offset));
6746     }
6747 }
6748 
6749 /* Test vector simplifications involving VEC_SERIES in which the
6750    operands and result have vector mode MODE.  SCALAR_REG is a pseudo
6751    register that holds one element of MODE.  */
6752 
6753 static void
test_vector_ops_series(machine_mode mode,rtx scalar_reg)6754 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
6755 {
6756   /* Test unary cases with VEC_SERIES arguments.  */
6757   scalar_mode inner_mode = GET_MODE_INNER (mode);
6758   rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
6759   rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
6760   rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
6761   rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
6762   rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
6763   rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
6764   rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
6765   rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
6766                                                    neg_scalar_reg);
6767   ASSERT_RTX_EQ (series_0_r,
6768                      simplify_unary_operation (NEG, mode, series_0_nr, mode));
6769   ASSERT_RTX_EQ (series_r_m1,
6770                      simplify_unary_operation (NEG, mode, series_nr_1, mode));
6771   ASSERT_RTX_EQ (series_r_r,
6772                      simplify_unary_operation (NEG, mode, series_nr_nr, mode));
6773 
6774   /* Test that a VEC_SERIES with a zero step is simplified away.  */
6775   ASSERT_RTX_EQ (duplicate,
6776                      simplify_binary_operation (VEC_SERIES, mode,
6777                                                       scalar_reg, const0_rtx));
6778 
6779   /* Test PLUS and MINUS with VEC_SERIES.  */
6780   rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
6781   rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
6782   rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
6783   ASSERT_RTX_EQ (series_r_r,
6784                      simplify_binary_operation (PLUS, mode, series_0_r,
6785                                                       duplicate));
6786   ASSERT_RTX_EQ (series_r_1,
6787                      simplify_binary_operation (PLUS, mode, duplicate,
6788                                                       series_0_1));
6789   ASSERT_RTX_EQ (series_r_m1,
6790                      simplify_binary_operation (PLUS, mode, duplicate,
6791                                                       series_0_m1));
6792   ASSERT_RTX_EQ (series_0_r,
6793                      simplify_binary_operation (MINUS, mode, series_r_r,
6794                                                       duplicate));
6795   ASSERT_RTX_EQ (series_r_m1,
6796                      simplify_binary_operation (MINUS, mode, duplicate,
6797                                                       series_0_1));
6798   ASSERT_RTX_EQ (series_r_1,
6799                      simplify_binary_operation (MINUS, mode, duplicate,
6800                                                       series_0_m1));
6801   ASSERT_RTX_EQ (series_0_m1,
6802                      simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
6803                                                       constm1_rtx));
6804 }
6805 
6806 /* Verify some simplifications involving vectors.  */
6807 
6808 static void
test_vector_ops()6809 test_vector_ops ()
6810 {
6811   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
6812     {
6813       machine_mode mode = (machine_mode) i;
6814       if (VECTOR_MODE_P (mode))
6815           {
6816             rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
6817             test_vector_ops_duplicate (mode, scalar_reg);
6818             if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
6819                 && maybe_gt (GET_MODE_NUNITS (mode), 2))
6820               test_vector_ops_series (mode, scalar_reg);
6821           }
6822     }
6823 }
6824 
6825 template<unsigned int N>
6826 struct simplify_const_poly_int_tests
6827 {
6828   static void run ();
6829 };
6830 
6831 template<>
6832 struct simplify_const_poly_int_tests<1>
6833 {
6834   static void run () {}
6835 };
6836 
6837 /* Test various CONST_POLY_INT properties.  */
6838 
6839 template<unsigned int N>
6840 void
6841 simplify_const_poly_int_tests<N>::run ()
6842 {
6843   rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
6844   rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
6845   rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
6846   rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
6847   rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
6848   rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
6849   rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
6850   rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
6851   rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
6852   rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
6853   rtx two = GEN_INT (2);
6854   rtx six = GEN_INT (6);
6855   poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
6856 
6857   /* These tests only try limited operation combinations.  Fuller arithmetic
6858      testing is done directly on poly_ints.  */
6859   ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
6860   ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
6861   ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
6862   ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
6863   ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
6864   ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
6865   ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
6866   ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
6867   ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
6868   ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
6869   ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
6870 }
6871 
6872 /* Run all of the selftests within this file.  */
6873 
6874 void
6875 simplify_rtx_c_tests ()
6876 {
6877   test_vector_ops ();
6878   simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
6879 }
6880 
6881 } // namespace selftest
6882 
6883 #endif /* CHECKING_P */
6884