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