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