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