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

source code of gcc/simplify-rtx.cc