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