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