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