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