Add assember CFI directives to millicode division and remainder routines.
[official-gcc.git] / gcc / simplify-rtx.cc
blob3b33afa24617f3185872ddc43284e4c9cd073510
1 /* RTL simplification functions for GNU compiler.
2 Copyright (C) 1987-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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 #include "rtlanal.h"
41 /* Simplification and canonicalization of RTL. */
43 /* Much code operates on (low, high) pairs; the low value is an
44 unsigned wide int, the high value a signed wide int. We
45 occasionally need to sign extend from low to high as if low were a
46 signed wide int. */
47 #define HWI_SIGN_EXTEND(low) \
48 ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
50 static bool plus_minus_operand_p (const_rtx);
52 /* Negate I, which satisfies poly_int_rtx_p. MODE is the mode of I. */
54 static rtx
55 neg_poly_int_rtx (machine_mode mode, const_rtx i)
57 return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
60 /* Test whether expression, X, is an immediate constant that represents
61 the most significant bit of machine mode MODE. */
63 bool
64 mode_signbit_p (machine_mode mode, const_rtx x)
66 unsigned HOST_WIDE_INT val;
67 unsigned int width;
68 scalar_int_mode int_mode;
70 if (!is_int_mode (mode, &int_mode))
71 return false;
73 width = GET_MODE_PRECISION (int_mode);
74 if (width == 0)
75 return false;
77 if (width <= HOST_BITS_PER_WIDE_INT
78 && CONST_INT_P (x))
79 val = INTVAL (x);
80 #if TARGET_SUPPORTS_WIDE_INT
81 else if (CONST_WIDE_INT_P (x))
83 unsigned int i;
84 unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 return false;
87 for (i = 0; i < elts - 1; i++)
88 if (CONST_WIDE_INT_ELT (x, i) != 0)
89 return false;
90 val = CONST_WIDE_INT_ELT (x, elts - 1);
91 width %= HOST_BITS_PER_WIDE_INT;
92 if (width == 0)
93 width = HOST_BITS_PER_WIDE_INT;
95 #else
96 else if (width <= HOST_BITS_PER_DOUBLE_INT
97 && CONST_DOUBLE_AS_INT_P (x)
98 && CONST_DOUBLE_LOW (x) == 0)
100 val = CONST_DOUBLE_HIGH (x);
101 width -= HOST_BITS_PER_WIDE_INT;
103 #endif
104 else
105 /* X is not an integer constant. */
106 return false;
108 if (width < HOST_BITS_PER_WIDE_INT)
109 val &= (HOST_WIDE_INT_1U << width) - 1;
110 return val == (HOST_WIDE_INT_1U << (width - 1));
113 /* Test whether VAL is equal to the most significant bit of mode MODE
114 (after masking with the mode mask of MODE). Returns false if the
115 precision of MODE is too large to handle. */
117 bool
118 val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
120 unsigned int width;
121 scalar_int_mode int_mode;
123 if (!is_int_mode (mode, &int_mode))
124 return false;
126 width = GET_MODE_PRECISION (int_mode);
127 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 return false;
130 val &= GET_MODE_MASK (int_mode);
131 return val == (HOST_WIDE_INT_1U << (width - 1));
134 /* Test whether the most significant bit of mode MODE is set in VAL.
135 Returns false if the precision of MODE is too large to handle. */
136 bool
137 val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
139 unsigned int width;
141 scalar_int_mode int_mode;
142 if (!is_int_mode (mode, &int_mode))
143 return false;
145 width = GET_MODE_PRECISION (int_mode);
146 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 return false;
149 val &= HOST_WIDE_INT_1U << (width - 1);
150 return val != 0;
153 /* Test whether the most significant bit of mode MODE is clear in VAL.
154 Returns false if the precision of MODE is too large to handle. */
155 bool
156 val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
158 unsigned int width;
160 scalar_int_mode int_mode;
161 if (!is_int_mode (mode, &int_mode))
162 return false;
164 width = GET_MODE_PRECISION (int_mode);
165 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 return false;
168 val &= HOST_WIDE_INT_1U << (width - 1);
169 return val == 0;
172 /* Make a binary operation by properly ordering the operands and
173 seeing if the expression folds. */
176 simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 rtx op0, rtx op1)
179 rtx tem;
181 /* If this simplifies, do it. */
182 tem = simplify_binary_operation (code, mode, op0, op1);
183 if (tem)
184 return tem;
186 /* Put complex operands first and constants second if commutative. */
187 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 && swap_commutative_operands_p (op0, op1))
189 std::swap (op0, op1);
191 return gen_rtx_fmt_ee (code, mode, op0, op1);
194 /* If X is a MEM referencing the constant pool, return the real value.
195 Otherwise return X. */
197 avoid_constant_pool_reference (rtx x)
199 rtx c, tmp, addr;
200 machine_mode cmode;
201 poly_int64 offset = 0;
203 switch (GET_CODE (x))
205 case MEM:
206 break;
208 case FLOAT_EXTEND:
209 /* Handle float extensions of constant pool references. */
210 tmp = XEXP (x, 0);
211 c = avoid_constant_pool_reference (tmp);
212 if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 GET_MODE (x));
215 return x;
217 default:
218 return x;
221 if (GET_MODE (x) == BLKmode)
222 return x;
224 addr = XEXP (x, 0);
226 /* Call target hook to avoid the effects of -fpic etc.... */
227 addr = targetm.delegitimize_address (addr);
229 /* Split the address into a base and integer offset. */
230 addr = strip_offset (addr, &offset);
232 if (GET_CODE (addr) == LO_SUM)
233 addr = XEXP (addr, 1);
235 /* If this is a constant pool reference, we can turn it into its
236 constant and hope that simplifications happen. */
237 if (GET_CODE (addr) == SYMBOL_REF
238 && CONSTANT_POOL_ADDRESS_P (addr))
240 c = get_pool_constant (addr);
241 cmode = get_pool_mode (addr);
243 /* If we're accessing the constant in a different mode than it was
244 originally stored, attempt to fix that up via subreg simplifications.
245 If that fails we have no choice but to return the original memory. */
246 if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 return c;
248 else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
250 rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 if (tem && CONSTANT_P (tem))
252 return tem;
256 return x;
259 /* Simplify a MEM based on its attributes. This is the default
260 delegitimize_address target hook, and it's recommended that every
261 overrider call it. */
264 delegitimize_mem_from_attrs (rtx x)
266 /* MEMs without MEM_OFFSETs may have been offset, so we can't just
267 use their base addresses as equivalent. */
268 if (MEM_P (x)
269 && MEM_EXPR (x)
270 && MEM_OFFSET_KNOWN_P (x))
272 tree decl = MEM_EXPR (x);
273 machine_mode mode = GET_MODE (x);
274 poly_int64 offset = 0;
276 switch (TREE_CODE (decl))
278 default:
279 decl = NULL;
280 break;
282 case VAR_DECL:
283 break;
285 case ARRAY_REF:
286 case ARRAY_RANGE_REF:
287 case COMPONENT_REF:
288 case BIT_FIELD_REF:
289 case REALPART_EXPR:
290 case IMAGPART_EXPR:
291 case VIEW_CONVERT_EXPR:
293 poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 tree toffset;
295 int unsignedp, reversep, volatilep = 0;
297 decl
298 = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 &unsignedp, &reversep, &volatilep);
300 if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 decl = NULL;
304 else
305 offset += bytepos + toffset_val;
306 break;
310 if (decl
311 && mode == GET_MODE (x)
312 && VAR_P (decl)
313 && (TREE_STATIC (decl)
314 || DECL_THREAD_LOCAL_P (decl))
315 && DECL_RTL_SET_P (decl)
316 && MEM_P (DECL_RTL (decl)))
318 rtx newx;
320 offset += MEM_OFFSET (x);
322 newx = DECL_RTL (decl);
324 if (MEM_P (newx))
326 rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 poly_int64 n_offset, o_offset;
329 /* Avoid creating a new MEM needlessly if we already had
330 the same address. We do if there's no OFFSET and the
331 old address X is identical to NEWX, or if X is of the
332 form (plus NEWX OFFSET), or the NEWX is of the form
333 (plus Y (const_int Z)) and X is that with the offset
334 added: (plus Y (const_int Z+OFFSET)). */
335 n = strip_offset (n, &n_offset);
336 o = strip_offset (o, &o_offset);
337 if (!(known_eq (o_offset, n_offset + offset)
338 && rtx_equal_p (o, n)))
339 x = adjust_address_nv (newx, mode, offset);
341 else if (GET_MODE (x) == GET_MODE (newx)
342 && known_eq (offset, 0))
343 x = newx;
347 return x;
350 /* Make a unary operation by first seeing if it folds and otherwise making
351 the specified operation. */
354 simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 machine_mode op_mode)
357 rtx tem;
359 /* If this simplifies, use it. */
360 if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 return tem;
363 return gen_rtx_fmt_e (code, mode, op);
366 /* Likewise for ternary operations. */
369 simplify_context::simplify_gen_ternary (rtx_code code, machine_mode mode,
370 machine_mode op0_mode,
371 rtx op0, rtx op1, rtx op2)
373 rtx tem;
375 /* If this simplifies, use it. */
376 if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 op0, op1, op2)) != 0)
378 return tem;
380 return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
383 /* Likewise, for relational operations.
384 CMP_MODE specifies mode comparison is done in. */
387 simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 machine_mode cmp_mode,
389 rtx op0, rtx op1)
391 rtx tem;
393 if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 op0, op1)) != 0)
395 return tem;
397 return gen_rtx_fmt_ee (code, mode, op0, op1);
400 /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
401 and simplify the result. If FN is non-NULL, call this callback on each
402 X, if it returns non-NULL, replace X with its return value and simplify the
403 result. */
406 simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 rtx (*fn) (rtx, const_rtx, void *), void *data)
409 enum rtx_code code = GET_CODE (x);
410 machine_mode mode = GET_MODE (x);
411 machine_mode op_mode;
412 const char *fmt;
413 rtx op0, op1, op2, newx, op;
414 rtvec vec, newvec;
415 int i, j;
417 if (UNLIKELY (fn != NULL))
419 newx = fn (x, old_rtx, data);
420 if (newx)
421 return newx;
423 else if (rtx_equal_p (x, old_rtx))
424 return copy_rtx ((rtx) data);
426 switch (GET_RTX_CLASS (code))
428 case RTX_UNARY:
429 op0 = XEXP (x, 0);
430 op_mode = GET_MODE (op0);
431 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 if (op0 == XEXP (x, 0))
433 return x;
434 return simplify_gen_unary (code, mode, op0, op_mode);
436 case RTX_BIN_ARITH:
437 case RTX_COMM_ARITH:
438 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 return x;
442 return simplify_gen_binary (code, mode, op0, op1);
444 case RTX_COMPARE:
445 case RTX_COMM_COMPARE:
446 op0 = XEXP (x, 0);
447 op1 = XEXP (x, 1);
448 op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 return x;
453 return simplify_gen_relational (code, mode, op_mode, op0, op1);
455 case RTX_TERNARY:
456 case RTX_BITFIELD_OPS:
457 op0 = XEXP (x, 0);
458 op_mode = GET_MODE (op0);
459 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 return x;
464 if (op_mode == VOIDmode)
465 op_mode = GET_MODE (op0);
466 return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
468 case RTX_EXTRA:
469 if (code == SUBREG)
471 op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 if (op0 == SUBREG_REG (x))
473 return x;
474 op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 GET_MODE (SUBREG_REG (x)),
476 SUBREG_BYTE (x));
477 return op0 ? op0 : x;
479 break;
481 case RTX_OBJ:
482 if (code == MEM)
484 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 if (op0 == XEXP (x, 0))
486 return x;
487 return replace_equiv_address_nv (x, op0);
489 else if (code == LO_SUM)
491 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
492 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
494 /* (lo_sum (high x) y) -> y where x and y have the same base. */
495 if (GET_CODE (op0) == HIGH)
497 rtx base0, base1, offset0, offset1;
498 split_const (XEXP (op0, 0), &base0, &offset0);
499 split_const (op1, &base1, &offset1);
500 if (rtx_equal_p (base0, base1))
501 return op1;
504 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
505 return x;
506 return gen_rtx_LO_SUM (mode, op0, op1);
508 break;
510 default:
511 break;
514 newx = x;
515 fmt = GET_RTX_FORMAT (code);
516 for (i = 0; fmt[i]; i++)
517 switch (fmt[i])
519 case 'E':
520 vec = XVEC (x, i);
521 newvec = XVEC (newx, i);
522 for (j = 0; j < GET_NUM_ELEM (vec); j++)
524 op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 old_rtx, fn, data);
526 if (op != RTVEC_ELT (vec, j))
528 if (newvec == vec)
530 newvec = shallow_copy_rtvec (vec);
531 if (x == newx)
532 newx = shallow_copy_rtx (x);
533 XVEC (newx, i) = newvec;
535 RTVEC_ELT (newvec, j) = op;
538 break;
540 case 'e':
541 if (XEXP (x, i))
543 op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 if (op != XEXP (x, i))
546 if (x == newx)
547 newx = shallow_copy_rtx (x);
548 XEXP (newx, i) = op;
551 break;
553 return newx;
556 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
557 resulting RTX. Return a new RTX which is as simplified as possible. */
560 simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
562 return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
565 /* Try to simplify a MODE truncation of OP, which has OP_MODE.
566 Only handle cases where the truncated value is inherently an rvalue.
568 RTL provides two ways of truncating a value:
570 1. a lowpart subreg. This form is only a truncation when both
571 the outer and inner modes (here MODE and OP_MODE respectively)
572 are scalar integers, and only then when the subreg is used as
573 an rvalue.
575 It is only valid to form such truncating subregs if the
576 truncation requires no action by the target. The onus for
577 proving this is on the creator of the subreg -- e.g. the
578 caller to simplify_subreg or simplify_gen_subreg -- and typically
579 involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
581 2. a TRUNCATE. This form handles both scalar and compound integers.
583 The first form is preferred where valid. However, the TRUNCATE
584 handling in simplify_unary_operation turns the second form into the
585 first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
586 so it is generally safe to form rvalue truncations using:
588 simplify_gen_unary (TRUNCATE, ...)
590 and leave simplify_unary_operation to work out which representation
591 should be used.
593 Because of the proof requirements on (1), simplify_truncation must
594 also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
595 regardless of whether the outer truncation came from a SUBREG or a
596 TRUNCATE. For example, if the caller has proven that an SImode
597 truncation of:
599 (and:DI X Y)
601 is a no-op and can be represented as a subreg, it does not follow
602 that SImode truncations of X and Y are also no-ops. On a target
603 like 64-bit MIPS that requires SImode values to be stored in
604 sign-extended form, an SImode truncation of:
606 (and:DI (reg:DI X) (const_int 63))
608 is trivially a no-op because only the lower 6 bits can be set.
609 However, X is still an arbitrary 64-bit number and so we cannot
610 assume that truncating it too is a no-op. */
613 simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 machine_mode op_mode)
616 unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 scalar_int_mode int_mode, int_op_mode, subreg_mode;
620 gcc_assert (precision <= op_precision);
622 /* Optimize truncations of zero and sign extended values. */
623 if (GET_CODE (op) == ZERO_EXTEND
624 || GET_CODE (op) == SIGN_EXTEND)
626 /* There are three possibilities. If MODE is the same as the
627 origmode, we can omit both the extension and the subreg.
628 If MODE is not larger than the origmode, we can apply the
629 truncation without the extension. Finally, if the outermode
630 is larger than the origmode, we can just extend to the appropriate
631 mode. */
632 machine_mode origmode = GET_MODE (XEXP (op, 0));
633 if (mode == origmode)
634 return XEXP (op, 0);
635 else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 return simplify_gen_unary (TRUNCATE, mode,
637 XEXP (op, 0), origmode);
638 else
639 return simplify_gen_unary (GET_CODE (op), mode,
640 XEXP (op, 0), origmode);
643 /* If the machine can perform operations in the truncated mode, distribute
644 the truncation, i.e. simplify (truncate:QI (op:SI (x:SI) (y:SI))) into
645 (op:QI (truncate:QI (x:SI)) (truncate:QI (y:SI))). */
646 if (1
647 && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 && (GET_CODE (op) == PLUS
649 || GET_CODE (op) == MINUS
650 || GET_CODE (op) == MULT))
652 rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 if (op0)
655 rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 if (op1)
657 return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
661 /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
662 to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
663 the outer subreg is effectively a truncation to the original mode. */
664 if ((GET_CODE (op) == LSHIFTRT
665 || GET_CODE (op) == ASHIFTRT)
666 /* Ensure that OP_MODE is at least twice as wide as MODE
667 to avoid the possibility that an outer LSHIFTRT shifts by more
668 than the sign extension's sign_bit_copies and introduces zeros
669 into the high bits of the result. */
670 && 2 * precision <= op_precision
671 && CONST_INT_P (XEXP (op, 1))
672 && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
673 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
674 && UINTVAL (XEXP (op, 1)) < precision)
675 return simplify_gen_binary (ASHIFTRT, mode,
676 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
678 /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
679 to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
680 the outer subreg is effectively a truncation to the original mode. */
681 if ((GET_CODE (op) == LSHIFTRT
682 || GET_CODE (op) == ASHIFTRT)
683 && CONST_INT_P (XEXP (op, 1))
684 && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 && UINTVAL (XEXP (op, 1)) < precision)
687 return simplify_gen_binary (LSHIFTRT, mode,
688 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
690 /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
691 to (ashift:QI (x:QI) C), where C is a suitable small constant and
692 the outer subreg is effectively a truncation to the original mode. */
693 if (GET_CODE (op) == ASHIFT
694 && CONST_INT_P (XEXP (op, 1))
695 && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 && UINTVAL (XEXP (op, 1)) < precision)
699 return simplify_gen_binary (ASHIFT, mode,
700 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
702 /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into
703 (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C
704 and C2. */
705 if (GET_CODE (op) == AND
706 && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 && CONST_INT_P (XEXP (op, 1)))
711 rtx op0 = (XEXP (XEXP (op, 0), 0));
712 rtx shift_op = XEXP (XEXP (op, 0), 1);
713 rtx mask_op = XEXP (op, 1);
714 unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
717 if (shift < precision
718 /* If doing this transform works for an X with all bits set,
719 it works for any X. */
720 && ((GET_MODE_MASK (mode) >> shift) & mask)
721 == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
725 mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 return simplify_gen_binary (AND, mode, op0, mask_op);
730 /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
731 (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
732 changing len. */
733 if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 && REG_P (XEXP (op, 0))
735 && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 && CONST_INT_P (XEXP (op, 1))
737 && CONST_INT_P (XEXP (op, 2)))
739 rtx op0 = XEXP (op, 0);
740 unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
744 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 if (op0)
747 pos -= op_precision - precision;
748 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 XEXP (op, 1), GEN_INT (pos));
752 else if (!BITS_BIG_ENDIAN && precision >= len + pos)
754 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 if (op0)
756 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 XEXP (op, 1), XEXP (op, 2));
761 /* Recognize a word extraction from a multi-word subreg. */
762 if ((GET_CODE (op) == LSHIFTRT
763 || GET_CODE (op) == ASHIFTRT)
764 && SCALAR_INT_MODE_P (mode)
765 && SCALAR_INT_MODE_P (op_mode)
766 && precision >= BITS_PER_WORD
767 && 2 * precision <= op_precision
768 && CONST_INT_P (XEXP (op, 1))
769 && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 && UINTVAL (XEXP (op, 1)) < op_precision)
772 poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 (WORDS_BIG_ENDIAN
776 ? byte - shifted_bytes
777 : byte + shifted_bytes));
780 /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
781 and try replacing the TRUNCATE and shift with it. Don't do this
782 if the MEM has a mode-dependent address. */
783 if ((GET_CODE (op) == LSHIFTRT
784 || GET_CODE (op) == ASHIFTRT)
785 && is_a <scalar_int_mode> (mode, &int_mode)
786 && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 && MEM_P (XEXP (op, 0))
788 && CONST_INT_P (XEXP (op, 1))
789 && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 && INTVAL (XEXP (op, 1)) > 0
791 && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 MEM_ADDR_SPACE (XEXP (op, 0)))
794 && ! MEM_VOLATILE_P (XEXP (op, 0))
795 && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
798 poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 return adjust_address_nv (XEXP (op, 0), int_mode,
801 (WORDS_BIG_ENDIAN
802 ? byte - shifted_bytes
803 : byte + shifted_bytes));
806 /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
807 (OP:SI foo:SI) if OP is NEG or ABS. */
808 if ((GET_CODE (op) == ABS
809 || GET_CODE (op) == NEG)
810 && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 return simplify_gen_unary (GET_CODE (op), mode,
814 XEXP (XEXP (op, 0), 0), mode);
816 /* Simplifications of (truncate:A (subreg:B X 0)). */
817 if (GET_CODE (op) == SUBREG
818 && is_a <scalar_int_mode> (mode, &int_mode)
819 && SCALAR_INT_MODE_P (op_mode)
820 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 && subreg_lowpart_p (op))
823 /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 if (GET_CODE (SUBREG_REG (op)) == TRUNCATE)
826 rtx inner = XEXP (SUBREG_REG (op), 0);
827 if (GET_MODE_PRECISION (int_mode)
828 <= GET_MODE_PRECISION (subreg_mode))
829 return simplify_gen_unary (TRUNCATE, int_mode, inner,
830 GET_MODE (inner));
831 else
832 /* If subreg above is paradoxical and C is narrower
833 than A, return (subreg:A (truncate:C X) 0). */
834 return simplify_gen_subreg (int_mode, SUBREG_REG (op),
835 subreg_mode, 0);
838 /* Simplifications of (truncate:A (subreg:B X:C 0)) with
839 paradoxical subregs (B is wider than C). */
840 if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
842 unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 if (int_op_prec > subreg_prec)
846 if (int_mode == subreg_mode)
847 return SUBREG_REG (op);
848 if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 return simplify_gen_unary (TRUNCATE, int_mode,
850 SUBREG_REG (op), subreg_mode);
852 /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 A is narrower than B and B is narrower than C. */
854 else if (int_op_prec < subreg_prec
855 && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 return simplify_gen_unary (TRUNCATE, int_mode,
857 SUBREG_REG (op), subreg_mode);
861 /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 if (GET_CODE (op) == TRUNCATE)
863 return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
864 GET_MODE (XEXP (op, 0)));
866 /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
867 in mode A. */
868 if (GET_CODE (op) == IOR
869 && SCALAR_INT_MODE_P (mode)
870 && SCALAR_INT_MODE_P (op_mode)
871 && CONST_INT_P (XEXP (op, 1))
872 && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
873 return constm1_rtx;
875 return NULL_RTX;
878 /* Try to simplify a unary operation CODE whose output mode is to be
879 MODE with input operand OP whose mode was originally OP_MODE.
880 Return zero if no simplification can be made. */
882 simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 rtx op, machine_mode op_mode)
885 rtx trueop, tem;
887 trueop = avoid_constant_pool_reference (op);
889 tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 if (tem)
891 return tem;
893 return simplify_unary_operation_1 (code, mode, op);
896 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
897 to be exact. */
899 static bool
900 exact_int_to_float_conversion_p (const_rtx op)
902 machine_mode op0_mode = GET_MODE (XEXP (op, 0));
903 /* Constants can reach here with -frounding-math, if they do then
904 the conversion isn't exact. */
905 if (op0_mode == VOIDmode)
906 return false;
907 int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 int in_bits = in_prec;
910 if (HWI_COMPUTABLE_MODE_P (op0_mode))
912 unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 if (GET_CODE (op) == FLOAT)
914 in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 else
918 gcc_unreachable ();
919 in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
921 return in_bits <= out_bits;
924 /* Perform some simplifications we can do even if the operands
925 aren't constant. */
927 simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 rtx op)
930 enum rtx_code reversed;
931 rtx temp, elt, base, step;
932 scalar_int_mode inner, int_mode, op_mode, op0_mode;
934 switch (code)
936 case NOT:
937 /* (not (not X)) == X. */
938 if (GET_CODE (op) == NOT)
939 return XEXP (op, 0);
941 /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
942 comparison is all ones. */
943 if (COMPARISON_P (op)
944 && (mode == BImode || STORE_FLAG_VALUE == -1)
945 && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
946 return simplify_gen_relational (reversed, mode, VOIDmode,
947 XEXP (op, 0), XEXP (op, 1));
949 /* (not (plus X -1)) can become (neg X). */
950 if (GET_CODE (op) == PLUS
951 && XEXP (op, 1) == constm1_rtx)
952 return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
954 /* Similarly, (not (neg X)) is (plus X -1). Only do this for
955 modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
956 and MODE_VECTOR_INT. */
957 if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 CONSTM1_RTX (mode));
961 /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 if (GET_CODE (op) == XOR
963 && CONST_INT_P (XEXP (op, 1))
964 && (temp = simplify_unary_operation (NOT, mode,
965 XEXP (op, 1), mode)) != 0)
966 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
968 /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
969 if (GET_CODE (op) == PLUS
970 && CONST_INT_P (XEXP (op, 1))
971 && mode_signbit_p (mode, XEXP (op, 1))
972 && (temp = simplify_unary_operation (NOT, mode,
973 XEXP (op, 1), mode)) != 0)
974 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
977 /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
978 operands other than 1, but that is not valid. We could do a
979 similar simplification for (not (lshiftrt C X)) where C is
980 just the sign bit, but this doesn't seem common enough to
981 bother with. */
982 if (GET_CODE (op) == ASHIFT
983 && XEXP (op, 0) == const1_rtx)
985 temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
989 /* (not (ashiftrt foo C)) where C is the number of bits in FOO
990 minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
991 so we can perform the above simplification. */
992 if (STORE_FLAG_VALUE == -1
993 && is_a <scalar_int_mode> (mode, &int_mode)
994 && GET_CODE (op) == ASHIFTRT
995 && CONST_INT_P (XEXP (op, 1))
996 && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
997 return simplify_gen_relational (GE, int_mode, VOIDmode,
998 XEXP (op, 0), const0_rtx);
1001 if (partial_subreg_p (op)
1002 && subreg_lowpart_p (op)
1003 && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1006 machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1007 rtx x;
1009 x = gen_rtx_ROTATE (inner_mode,
1010 simplify_gen_unary (NOT, inner_mode, const1_rtx,
1011 inner_mode),
1012 XEXP (SUBREG_REG (op), 1));
1013 temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1014 if (temp)
1015 return temp;
1018 /* Apply De Morgan's laws to reduce number of patterns for machines
1019 with negating logical insns (and-not, nand, etc.). If result has
1020 only one NOT, put it first, since that is how the patterns are
1021 coded. */
1022 if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1024 rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 machine_mode op_mode;
1027 op_mode = GET_MODE (in1);
1028 in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1030 op_mode = GET_MODE (in2);
1031 if (op_mode == VOIDmode)
1032 op_mode = mode;
1033 in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1035 if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 std::swap (in1, in2);
1038 return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1039 mode, in1, in2);
1042 /* (not (bswap x)) -> (bswap (not x)). */
1043 if (GET_CODE (op) == BSWAP)
1045 rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1046 return simplify_gen_unary (BSWAP, mode, x, mode);
1048 break;
1050 case NEG:
1051 /* (neg (neg X)) == X. */
1052 if (GET_CODE (op) == NEG)
1053 return XEXP (op, 0);
1055 /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1056 If comparison is not reversible use
1057 x ? y : (neg y). */
1058 if (GET_CODE (op) == IF_THEN_ELSE)
1060 rtx cond = XEXP (op, 0);
1061 rtx true_rtx = XEXP (op, 1);
1062 rtx false_rtx = XEXP (op, 2);
1064 if ((GET_CODE (true_rtx) == NEG
1065 && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 || (GET_CODE (false_rtx) == NEG
1067 && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1069 if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1070 temp = reversed_comparison (cond, mode);
1071 else
1073 temp = cond;
1074 std::swap (true_rtx, false_rtx);
1076 return simplify_gen_ternary (IF_THEN_ELSE, mode,
1077 mode, temp, true_rtx, false_rtx);
1081 /* (neg (plus X 1)) can become (not X). */
1082 if (GET_CODE (op) == PLUS
1083 && XEXP (op, 1) == const1_rtx)
1084 return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1086 /* Similarly, (neg (not X)) is (plus X 1). */
1087 if (GET_CODE (op) == NOT)
1088 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 CONST1_RTX (mode));
1091 /* (neg (minus X Y)) can become (minus Y X). This transformation
1092 isn't safe for modes with signed zeros, since if X and Y are
1093 both +0, (minus Y X) is the same as (minus X Y). If the
1094 rounding mode is towards +infinity (or -infinity) then the two
1095 expressions will be rounded differently. */
1096 if (GET_CODE (op) == MINUS
1097 && !HONOR_SIGNED_ZEROS (mode)
1098 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1101 if (GET_CODE (op) == PLUS
1102 && !HONOR_SIGNED_ZEROS (mode)
1103 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1105 /* (neg (plus A C)) is simplified to (minus -C A). */
1106 if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1109 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 if (temp)
1111 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1114 /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1115 temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1119 /* (neg (mult A B)) becomes (mult A (neg B)).
1120 This works even for floating-point values. */
1121 if (GET_CODE (op) == MULT
1122 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1124 temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1128 /* NEG commutes with ASHIFT since it is multiplication. Only do
1129 this if we can then eliminate the NEG (e.g., if the operand
1130 is a constant). */
1131 if (GET_CODE (op) == ASHIFT)
1133 temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 if (temp)
1135 return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1138 /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1139 C is equal to the width of MODE minus 1. */
1140 if (GET_CODE (op) == ASHIFTRT
1141 && CONST_INT_P (XEXP (op, 1))
1142 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1143 return simplify_gen_binary (LSHIFTRT, mode,
1144 XEXP (op, 0), XEXP (op, 1));
1146 /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1147 C is equal to the width of MODE minus 1. */
1148 if (GET_CODE (op) == LSHIFTRT
1149 && CONST_INT_P (XEXP (op, 1))
1150 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 return simplify_gen_binary (ASHIFTRT, mode,
1152 XEXP (op, 0), XEXP (op, 1));
1154 /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1155 if (GET_CODE (op) == XOR
1156 && XEXP (op, 1) == const1_rtx
1157 && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 return plus_constant (mode, XEXP (op, 0), -1);
1160 /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1161 /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1162 if (GET_CODE (op) == LT
1163 && XEXP (op, 1) == const0_rtx
1164 && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1166 int_mode = as_a <scalar_int_mode> (mode);
1167 int isize = GET_MODE_PRECISION (inner);
1168 if (STORE_FLAG_VALUE == 1)
1170 temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1171 gen_int_shift_amount (inner,
1172 isize - 1));
1173 if (int_mode == inner)
1174 return temp;
1175 if (GET_MODE_PRECISION (int_mode) > isize)
1176 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1177 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1179 else if (STORE_FLAG_VALUE == -1)
1181 temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1182 gen_int_shift_amount (inner,
1183 isize - 1));
1184 if (int_mode == inner)
1185 return temp;
1186 if (GET_MODE_PRECISION (int_mode) > isize)
1187 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1188 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1192 if (vec_series_p (op, &base, &step))
1194 /* Only create a new series if we can simplify both parts. In other
1195 cases this isn't really a simplification, and it's not necessarily
1196 a win to replace a vector operation with a scalar operation. */
1197 scalar_mode inner_mode = GET_MODE_INNER (mode);
1198 base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1199 if (base)
1201 step = simplify_unary_operation (NEG, inner_mode,
1202 step, inner_mode);
1203 if (step)
1204 return gen_vec_series (mode, base, step);
1207 break;
1209 case TRUNCATE:
1210 /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 with the umulXi3_highpart patterns. */
1212 if (GET_CODE (op) == LSHIFTRT
1213 && GET_CODE (XEXP (op, 0)) == MULT)
1214 break;
1216 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1218 if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1220 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1221 if (temp)
1222 return temp;
1224 /* We can't handle truncation to a partial integer mode here
1225 because we don't know the real bitsize of the partial
1226 integer mode. */
1227 break;
1230 if (GET_MODE (op) != VOIDmode)
1232 temp = simplify_truncation (mode, op, GET_MODE (op));
1233 if (temp)
1234 return temp;
1237 /* If we know that the value is already truncated, we can
1238 replace the TRUNCATE with a SUBREG. */
1239 if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 || truncated_to_mode (mode, op)))
1243 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 if (temp)
1245 return temp;
1248 /* A truncate of a comparison can be replaced with a subreg if
1249 STORE_FLAG_VALUE permits. This is like the previous test,
1250 but it works even if the comparison is done in a mode larger
1251 than HOST_BITS_PER_WIDE_INT. */
1252 if (HWI_COMPUTABLE_MODE_P (mode)
1253 && COMPARISON_P (op)
1254 && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1257 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1258 if (temp)
1259 return temp;
1262 /* A truncate of a memory is just loading the low part of the memory
1263 if we are not changing the meaning of the address. */
1264 if (GET_CODE (op) == MEM
1265 && !VECTOR_MODE_P (mode)
1266 && !MEM_VOLATILE_P (op)
1267 && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1269 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 if (temp)
1271 return temp;
1274 /* Check for useless truncation. */
1275 if (GET_MODE (op) == mode)
1276 return op;
1277 break;
1279 case FLOAT_TRUNCATE:
1280 /* Check for useless truncation. */
1281 if (GET_MODE (op) == mode)
1282 return op;
1284 if (DECIMAL_FLOAT_MODE_P (mode))
1285 break;
1287 /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 if (GET_CODE (op) == FLOAT_EXTEND
1289 && GET_MODE (XEXP (op, 0)) == mode)
1290 return XEXP (op, 0);
1292 /* (float_truncate:SF (float_truncate:DF foo:XF))
1293 = (float_truncate:SF foo:XF).
1294 This may eliminate double rounding, so it is unsafe.
1296 (float_truncate:SF (float_extend:XF foo:DF))
1297 = (float_truncate:SF foo:DF).
1299 (float_truncate:DF (float_extend:XF foo:SF))
1300 = (float_extend:DF foo:SF). */
1301 if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 && flag_unsafe_math_optimizations)
1303 || GET_CODE (op) == FLOAT_EXTEND)
1304 return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1305 > GET_MODE_UNIT_SIZE (mode)
1306 ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1307 mode,
1308 XEXP (op, 0), mode);
1310 /* (float_truncate (float x)) is (float x) */
1311 if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 && (flag_unsafe_math_optimizations
1313 || exact_int_to_float_conversion_p (op)))
1314 return simplify_gen_unary (GET_CODE (op), mode,
1315 XEXP (op, 0),
1316 GET_MODE (XEXP (op, 0)));
1318 /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1319 (OP:SF foo:SF) if OP is NEG or ABS. */
1320 if ((GET_CODE (op) == ABS
1321 || GET_CODE (op) == NEG)
1322 && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1323 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1324 return simplify_gen_unary (GET_CODE (op), mode,
1325 XEXP (XEXP (op, 0), 0), mode);
1327 /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1328 is (float_truncate:SF x). */
1329 if (GET_CODE (op) == SUBREG
1330 && subreg_lowpart_p (op)
1331 && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 return SUBREG_REG (op);
1333 break;
1335 case FLOAT_EXTEND:
1336 /* Check for useless extension. */
1337 if (GET_MODE (op) == mode)
1338 return op;
1340 if (DECIMAL_FLOAT_MODE_P (mode))
1341 break;
1343 /* (float_extend (float_extend x)) is (float_extend x)
1345 (float_extend (float x)) is (float x) assuming that double
1346 rounding can't happen.
1348 if (GET_CODE (op) == FLOAT_EXTEND
1349 || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 && exact_int_to_float_conversion_p (op)))
1351 return simplify_gen_unary (GET_CODE (op), mode,
1352 XEXP (op, 0),
1353 GET_MODE (XEXP (op, 0)));
1355 break;
1357 case ABS:
1358 /* (abs (neg <foo>)) -> (abs <foo>) */
1359 if (GET_CODE (op) == NEG)
1360 return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1361 GET_MODE (XEXP (op, 0)));
1363 /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1364 do nothing. */
1365 if (GET_MODE (op) == VOIDmode)
1366 break;
1368 /* If operand is something known to be positive, ignore the ABS. */
1369 if (val_signbit_known_clear_p (GET_MODE (op),
1370 nonzero_bits (op, GET_MODE (op))))
1371 return op;
1373 /* Using nonzero_bits doesn't (currently) work for modes wider than
1374 HOST_WIDE_INT, so the following transformations help simplify
1375 ABS for TImode and wider. */
1376 switch (GET_CODE (op))
1378 case ABS:
1379 case CLRSB:
1380 case FFS:
1381 case PARITY:
1382 case POPCOUNT:
1383 case SS_ABS:
1384 return op;
1386 case LSHIFTRT:
1387 if (CONST_INT_P (XEXP (op, 1))
1388 && INTVAL (XEXP (op, 1)) > 0
1389 && is_a <scalar_int_mode> (mode, &int_mode)
1390 && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1391 return op;
1392 break;
1394 default:
1395 break;
1398 /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1399 if (is_a <scalar_int_mode> (mode, &int_mode)
1400 && (num_sign_bit_copies (op, int_mode)
1401 == GET_MODE_PRECISION (int_mode)))
1402 return gen_rtx_NEG (int_mode, op);
1404 break;
1406 case FFS:
1407 /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1408 if (GET_CODE (op) == SIGN_EXTEND
1409 || GET_CODE (op) == ZERO_EXTEND)
1411 temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1412 XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1413 return simplify_gen_unary (GET_CODE (op), mode, temp,
1414 GET_MODE (temp));
1416 break;
1418 case POPCOUNT:
1419 switch (GET_CODE (op))
1421 case BSWAP:
1422 /* (popcount (bswap <X>)) = (popcount <X>). */
1423 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1424 GET_MODE (XEXP (op, 0)));
1426 case ZERO_EXTEND:
1427 /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1428 temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1429 XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1430 return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1431 GET_MODE (temp));
1433 case ROTATE:
1434 case ROTATERT:
1435 /* Rotations don't affect popcount. */
1436 if (!side_effects_p (XEXP (op, 1)))
1437 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1438 GET_MODE (XEXP (op, 0)));
1439 break;
1441 default:
1442 break;
1444 break;
1446 case PARITY:
1447 switch (GET_CODE (op))
1449 case NOT:
1450 case BSWAP:
1451 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1452 GET_MODE (XEXP (op, 0)));
1454 case ZERO_EXTEND:
1455 case SIGN_EXTEND:
1456 temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1457 XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1458 return simplify_gen_unary (GET_CODE (op), mode, temp,
1459 GET_MODE (temp));
1461 case ROTATE:
1462 case ROTATERT:
1463 /* Rotations don't affect parity. */
1464 if (!side_effects_p (XEXP (op, 1)))
1465 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1466 GET_MODE (XEXP (op, 0)));
1467 break;
1469 case PARITY:
1470 /* (parity (parity x)) -> parity (x). */
1471 return op;
1473 default:
1474 break;
1476 break;
1478 case BSWAP:
1479 /* (bswap (bswap x)) -> x. */
1480 if (GET_CODE (op) == BSWAP)
1481 return XEXP (op, 0);
1482 break;
1484 case FLOAT:
1485 /* (float (sign_extend <X>)) = (float <X>). */
1486 if (GET_CODE (op) == SIGN_EXTEND)
1487 return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1488 GET_MODE (XEXP (op, 0)));
1489 break;
1491 case SIGN_EXTEND:
1492 /* Check for useless extension. */
1493 if (GET_MODE (op) == mode)
1494 return op;
1496 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1497 becomes just the MINUS if its mode is MODE. This allows
1498 folding switch statements on machines using casesi (such as
1499 the VAX). */
1500 if (GET_CODE (op) == TRUNCATE
1501 && GET_MODE (XEXP (op, 0)) == mode
1502 && GET_CODE (XEXP (op, 0)) == MINUS
1503 && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1504 && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1505 return XEXP (op, 0);
1507 /* Extending a widening multiplication should be canonicalized to
1508 a wider widening multiplication. */
1509 if (GET_CODE (op) == MULT)
1511 rtx lhs = XEXP (op, 0);
1512 rtx rhs = XEXP (op, 1);
1513 enum rtx_code lcode = GET_CODE (lhs);
1514 enum rtx_code rcode = GET_CODE (rhs);
1516 /* Widening multiplies usually extend both operands, but sometimes
1517 they use a shift to extract a portion of a register. */
1518 if ((lcode == SIGN_EXTEND
1519 || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1520 && (rcode == SIGN_EXTEND
1521 || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1523 machine_mode lmode = GET_MODE (lhs);
1524 machine_mode rmode = GET_MODE (rhs);
1525 int bits;
1527 if (lcode == ASHIFTRT)
1528 /* Number of bits not shifted off the end. */
1529 bits = (GET_MODE_UNIT_PRECISION (lmode)
1530 - INTVAL (XEXP (lhs, 1)));
1531 else /* lcode == SIGN_EXTEND */
1532 /* Size of inner mode. */
1533 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1535 if (rcode == ASHIFTRT)
1536 bits += (GET_MODE_UNIT_PRECISION (rmode)
1537 - INTVAL (XEXP (rhs, 1)));
1538 else /* rcode == SIGN_EXTEND */
1539 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1541 /* We can only widen multiplies if the result is mathematiclly
1542 equivalent. I.e. if overflow was impossible. */
1543 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1544 return simplify_gen_binary
1545 (MULT, mode,
1546 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1547 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1551 /* Check for a sign extension of a subreg of a promoted
1552 variable, where the promotion is sign-extended, and the
1553 target mode is the same as the variable's promotion. */
1554 if (GET_CODE (op) == SUBREG
1555 && SUBREG_PROMOTED_VAR_P (op)
1556 && SUBREG_PROMOTED_SIGNED_P (op))
1558 rtx subreg = SUBREG_REG (op);
1559 machine_mode subreg_mode = GET_MODE (subreg);
1560 if (!paradoxical_subreg_p (mode, subreg_mode))
1562 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1563 if (temp)
1565 /* Preserve SUBREG_PROMOTED_VAR_P. */
1566 if (partial_subreg_p (temp))
1568 SUBREG_PROMOTED_VAR_P (temp) = 1;
1569 SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1571 return temp;
1574 else
1575 /* Sign-extending a sign-extended subreg. */
1576 return simplify_gen_unary (SIGN_EXTEND, mode,
1577 subreg, subreg_mode);
1580 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1581 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1582 if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1584 gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1585 > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1586 return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1587 GET_MODE (XEXP (op, 0)));
1590 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1591 is (sign_extend:M (subreg:O <X>)) if there is mode with
1592 GET_MODE_BITSIZE (N) - I bits.
1593 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1594 is similarly (zero_extend:M (subreg:O <X>)). */
1595 if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1596 && GET_CODE (XEXP (op, 0)) == ASHIFT
1597 && is_a <scalar_int_mode> (mode, &int_mode)
1598 && CONST_INT_P (XEXP (op, 1))
1599 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1600 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1601 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1603 scalar_int_mode tmode;
1604 gcc_assert (GET_MODE_PRECISION (int_mode)
1605 > GET_MODE_PRECISION (op_mode));
1606 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1607 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1609 rtx inner =
1610 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1611 if (inner)
1612 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1613 ? SIGN_EXTEND : ZERO_EXTEND,
1614 int_mode, inner, tmode);
1618 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1619 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1620 if (GET_CODE (op) == LSHIFTRT
1621 && CONST_INT_P (XEXP (op, 1))
1622 && XEXP (op, 1) != const0_rtx)
1623 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1625 /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1626 I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1627 (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1628 (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1629 O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1630 wider than O. */
1631 if (GET_CODE (op) == TRUNCATE
1632 && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1633 && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1635 scalar_int_mode m_mode, n_mode, o_mode;
1636 rtx old_shift = XEXP (op, 0);
1637 if (is_a <scalar_int_mode> (mode, &m_mode)
1638 && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1639 && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1640 && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1641 == INTVAL (XEXP (old_shift, 1)))
1643 rtx new_shift = simplify_gen_binary (ASHIFTRT,
1644 GET_MODE (old_shift),
1645 XEXP (old_shift, 0),
1646 XEXP (old_shift, 1));
1647 if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1648 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1649 GET_MODE (new_shift));
1650 if (mode != GET_MODE (new_shift))
1651 return simplify_gen_unary (TRUNCATE, mode, new_shift,
1652 GET_MODE (new_shift));
1653 return new_shift;
1657 /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1658 we know the sign bit of OP must be clear. */
1659 if (val_signbit_known_clear_p (GET_MODE (op),
1660 nonzero_bits (op, GET_MODE (op))))
1661 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1663 /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1664 if (GET_CODE (op) == SUBREG
1665 && subreg_lowpart_p (op)
1666 && GET_MODE (SUBREG_REG (op)) == mode
1667 && is_a <scalar_int_mode> (mode, &int_mode)
1668 && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1669 && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1670 && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1671 && (nonzero_bits (SUBREG_REG (op), mode)
1672 & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1673 return SUBREG_REG (op);
1675 #if defined(POINTERS_EXTEND_UNSIGNED)
1676 /* As we do not know which address space the pointer is referring to,
1677 we can do this only if the target does not support different pointer
1678 or address modes depending on the address space. */
1679 if (target_default_pointer_address_modes_p ()
1680 && ! POINTERS_EXTEND_UNSIGNED
1681 && mode == Pmode && GET_MODE (op) == ptr_mode
1682 && (CONSTANT_P (op)
1683 || (GET_CODE (op) == SUBREG
1684 && REG_P (SUBREG_REG (op))
1685 && REG_POINTER (SUBREG_REG (op))
1686 && GET_MODE (SUBREG_REG (op)) == Pmode))
1687 && !targetm.have_ptr_extend ())
1689 temp
1690 = convert_memory_address_addr_space_1 (Pmode, op,
1691 ADDR_SPACE_GENERIC, false,
1692 true);
1693 if (temp)
1694 return temp;
1696 #endif
1697 break;
1699 case ZERO_EXTEND:
1700 /* Check for useless extension. */
1701 if (GET_MODE (op) == mode)
1702 return op;
1704 /* Check for a zero extension of a subreg of a promoted
1705 variable, where the promotion is zero-extended, and the
1706 target mode is the same as the variable's promotion. */
1707 if (GET_CODE (op) == SUBREG
1708 && SUBREG_PROMOTED_VAR_P (op)
1709 && SUBREG_PROMOTED_UNSIGNED_P (op))
1711 rtx subreg = SUBREG_REG (op);
1712 machine_mode subreg_mode = GET_MODE (subreg);
1713 if (!paradoxical_subreg_p (mode, subreg_mode))
1715 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1716 if (temp)
1718 /* Preserve SUBREG_PROMOTED_VAR_P. */
1719 if (partial_subreg_p (temp))
1721 SUBREG_PROMOTED_VAR_P (temp) = 1;
1722 SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1724 return temp;
1727 else
1728 /* Zero-extending a zero-extended subreg. */
1729 return simplify_gen_unary (ZERO_EXTEND, mode,
1730 subreg, subreg_mode);
1733 /* Extending a widening multiplication should be canonicalized to
1734 a wider widening multiplication. */
1735 if (GET_CODE (op) == MULT)
1737 rtx lhs = XEXP (op, 0);
1738 rtx rhs = XEXP (op, 1);
1739 enum rtx_code lcode = GET_CODE (lhs);
1740 enum rtx_code rcode = GET_CODE (rhs);
1742 /* Widening multiplies usually extend both operands, but sometimes
1743 they use a shift to extract a portion of a register. */
1744 if ((lcode == ZERO_EXTEND
1745 || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1746 && (rcode == ZERO_EXTEND
1747 || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1749 machine_mode lmode = GET_MODE (lhs);
1750 machine_mode rmode = GET_MODE (rhs);
1751 int bits;
1753 if (lcode == LSHIFTRT)
1754 /* Number of bits not shifted off the end. */
1755 bits = (GET_MODE_UNIT_PRECISION (lmode)
1756 - INTVAL (XEXP (lhs, 1)));
1757 else /* lcode == ZERO_EXTEND */
1758 /* Size of inner mode. */
1759 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1761 if (rcode == LSHIFTRT)
1762 bits += (GET_MODE_UNIT_PRECISION (rmode)
1763 - INTVAL (XEXP (rhs, 1)));
1764 else /* rcode == ZERO_EXTEND */
1765 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1767 /* We can only widen multiplies if the result is mathematiclly
1768 equivalent. I.e. if overflow was impossible. */
1769 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1770 return simplify_gen_binary
1771 (MULT, mode,
1772 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1773 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1777 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1778 if (GET_CODE (op) == ZERO_EXTEND)
1779 return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1780 GET_MODE (XEXP (op, 0)));
1782 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1783 is (zero_extend:M (subreg:O <X>)) if there is mode with
1784 GET_MODE_PRECISION (N) - I bits. */
1785 if (GET_CODE (op) == LSHIFTRT
1786 && GET_CODE (XEXP (op, 0)) == ASHIFT
1787 && is_a <scalar_int_mode> (mode, &int_mode)
1788 && CONST_INT_P (XEXP (op, 1))
1789 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1790 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1791 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1793 scalar_int_mode tmode;
1794 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1795 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1797 rtx inner =
1798 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1799 if (inner)
1800 return simplify_gen_unary (ZERO_EXTEND, int_mode,
1801 inner, tmode);
1805 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1806 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1807 of mode N. E.g.
1808 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1809 (and:SI (reg:SI) (const_int 63)). */
1810 if (partial_subreg_p (op)
1811 && is_a <scalar_int_mode> (mode, &int_mode)
1812 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1813 && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1814 && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1815 && subreg_lowpart_p (op)
1816 && (nonzero_bits (SUBREG_REG (op), op0_mode)
1817 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1819 if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1820 return SUBREG_REG (op);
1821 return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1822 op0_mode);
1825 /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1826 if (GET_CODE (op) == SUBREG
1827 && subreg_lowpart_p (op)
1828 && GET_MODE (SUBREG_REG (op)) == mode
1829 && is_a <scalar_int_mode> (mode, &int_mode)
1830 && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1831 && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1832 && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1833 && (nonzero_bits (SUBREG_REG (op), mode)
1834 & ~GET_MODE_MASK (op_mode)) == 0)
1835 return SUBREG_REG (op);
1837 #if defined(POINTERS_EXTEND_UNSIGNED)
1838 /* As we do not know which address space the pointer is referring to,
1839 we can do this only if the target does not support different pointer
1840 or address modes depending on the address space. */
1841 if (target_default_pointer_address_modes_p ()
1842 && POINTERS_EXTEND_UNSIGNED > 0
1843 && mode == Pmode && GET_MODE (op) == ptr_mode
1844 && (CONSTANT_P (op)
1845 || (GET_CODE (op) == SUBREG
1846 && REG_P (SUBREG_REG (op))
1847 && REG_POINTER (SUBREG_REG (op))
1848 && GET_MODE (SUBREG_REG (op)) == Pmode))
1849 && !targetm.have_ptr_extend ())
1851 temp
1852 = convert_memory_address_addr_space_1 (Pmode, op,
1853 ADDR_SPACE_GENERIC, false,
1854 true);
1855 if (temp)
1856 return temp;
1858 #endif
1859 break;
1861 default:
1862 break;
1865 if (VECTOR_MODE_P (mode)
1866 && vec_duplicate_p (op, &elt)
1867 && code != VEC_DUPLICATE)
1869 if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1870 /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1871 operations by promoting VEC_DUPLICATE to the root of the expression
1872 (as far as possible). */
1873 temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1874 elt, GET_MODE_INNER (GET_MODE (op)));
1875 else
1876 /* Try applying the operator to ELT and see if that simplifies.
1877 We can duplicate the result if so.
1879 The reason we traditionally haven't used simplify_gen_unary
1880 for these codes is that it didn't necessarily seem to be a
1881 win to convert things like:
1883 (neg:V (vec_duplicate:V (reg:S R)))
1887 (vec_duplicate:V (neg:S (reg:S R)))
1889 The first might be done entirely in vector registers while the
1890 second might need a move between register files.
1892 However, there also cases where promoting the vec_duplicate is
1893 more efficient, and there is definite value in having a canonical
1894 form when matching instruction patterns. We should consider
1895 extending the simplify_gen_unary code above to more cases. */
1896 temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1897 elt, GET_MODE_INNER (GET_MODE (op)));
1898 if (temp)
1899 return gen_vec_duplicate (mode, temp);
1902 return 0;
1905 /* Try to compute the value of a unary operation CODE whose output mode is to
1906 be MODE with input operand OP whose mode was originally OP_MODE.
1907 Return zero if the value cannot be computed. */
1909 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1910 rtx op, machine_mode op_mode)
1912 scalar_int_mode result_mode;
1914 if (code == VEC_DUPLICATE)
1916 gcc_assert (VECTOR_MODE_P (mode));
1917 if (GET_MODE (op) != VOIDmode)
1919 if (!VECTOR_MODE_P (GET_MODE (op)))
1920 gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1921 else
1922 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1923 (GET_MODE (op)));
1925 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1926 return gen_const_vec_duplicate (mode, op);
1927 if (GET_CODE (op) == CONST_VECTOR
1928 && (CONST_VECTOR_DUPLICATE_P (op)
1929 || CONST_VECTOR_NUNITS (op).is_constant ()))
1931 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1932 ? CONST_VECTOR_NPATTERNS (op)
1933 : CONST_VECTOR_NUNITS (op).to_constant ());
1934 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1935 rtx_vector_builder builder (mode, npatterns, 1);
1936 for (unsigned i = 0; i < npatterns; i++)
1937 builder.quick_push (CONST_VECTOR_ELT (op, i));
1938 return builder.build ();
1942 if (VECTOR_MODE_P (mode)
1943 && GET_CODE (op) == CONST_VECTOR
1944 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1946 gcc_assert (GET_MODE (op) == op_mode);
1948 rtx_vector_builder builder;
1949 if (!builder.new_unary_operation (mode, op, false))
1950 return 0;
1952 unsigned int count = builder.encoded_nelts ();
1953 for (unsigned int i = 0; i < count; i++)
1955 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1956 CONST_VECTOR_ELT (op, i),
1957 GET_MODE_INNER (op_mode));
1958 if (!x || !valid_for_const_vector_p (mode, x))
1959 return 0;
1960 builder.quick_push (x);
1962 return builder.build ();
1965 /* The order of these tests is critical so that, for example, we don't
1966 check the wrong mode (input vs. output) for a conversion operation,
1967 such as FIX. At some point, this should be simplified. */
1969 if (code == FLOAT && CONST_SCALAR_INT_P (op))
1971 REAL_VALUE_TYPE d;
1973 if (op_mode == VOIDmode)
1975 /* CONST_INT have VOIDmode as the mode. We assume that all
1976 the bits of the constant are significant, though, this is
1977 a dangerous assumption as many times CONST_INTs are
1978 created and used with garbage in the bits outside of the
1979 precision of the implied mode of the const_int. */
1980 op_mode = MAX_MODE_INT;
1983 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1985 /* Avoid the folding if flag_signaling_nans is on and
1986 operand is a signaling NaN. */
1987 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1988 return 0;
1990 d = real_value_truncate (mode, d);
1992 /* Avoid the folding if flag_rounding_math is on and the
1993 conversion is not exact. */
1994 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1996 bool fail = false;
1997 wide_int w = real_to_integer (&d, &fail,
1998 GET_MODE_PRECISION
1999 (as_a <scalar_int_mode> (op_mode)));
2000 if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2001 return 0;
2004 return const_double_from_real_value (d, mode);
2006 else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2008 REAL_VALUE_TYPE d;
2010 if (op_mode == VOIDmode)
2012 /* CONST_INT have VOIDmode as the mode. We assume that all
2013 the bits of the constant are significant, though, this is
2014 a dangerous assumption as many times CONST_INTs are
2015 created and used with garbage in the bits outside of the
2016 precision of the implied mode of the const_int. */
2017 op_mode = MAX_MODE_INT;
2020 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2022 /* Avoid the folding if flag_signaling_nans is on and
2023 operand is a signaling NaN. */
2024 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2025 return 0;
2027 d = real_value_truncate (mode, d);
2029 /* Avoid the folding if flag_rounding_math is on and the
2030 conversion is not exact. */
2031 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2033 bool fail = false;
2034 wide_int w = real_to_integer (&d, &fail,
2035 GET_MODE_PRECISION
2036 (as_a <scalar_int_mode> (op_mode)));
2037 if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2038 return 0;
2041 return const_double_from_real_value (d, mode);
2044 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2046 unsigned int width = GET_MODE_PRECISION (result_mode);
2047 if (width > MAX_BITSIZE_MODE_ANY_INT)
2048 return 0;
2050 wide_int result;
2051 scalar_int_mode imode = (op_mode == VOIDmode
2052 ? result_mode
2053 : as_a <scalar_int_mode> (op_mode));
2054 rtx_mode_t op0 = rtx_mode_t (op, imode);
2055 int int_value;
2057 #if TARGET_SUPPORTS_WIDE_INT == 0
2058 /* This assert keeps the simplification from producing a result
2059 that cannot be represented in a CONST_DOUBLE but a lot of
2060 upstream callers expect that this function never fails to
2061 simplify something and so you if you added this to the test
2062 above the code would die later anyway. If this assert
2063 happens, you just need to make the port support wide int. */
2064 gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2065 #endif
2067 switch (code)
2069 case NOT:
2070 result = wi::bit_not (op0);
2071 break;
2073 case NEG:
2074 result = wi::neg (op0);
2075 break;
2077 case ABS:
2078 result = wi::abs (op0);
2079 break;
2081 case FFS:
2082 result = wi::shwi (wi::ffs (op0), result_mode);
2083 break;
2085 case CLZ:
2086 if (wi::ne_p (op0, 0))
2087 int_value = wi::clz (op0);
2088 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2089 return NULL_RTX;
2090 result = wi::shwi (int_value, result_mode);
2091 break;
2093 case CLRSB:
2094 result = wi::shwi (wi::clrsb (op0), result_mode);
2095 break;
2097 case CTZ:
2098 if (wi::ne_p (op0, 0))
2099 int_value = wi::ctz (op0);
2100 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2101 return NULL_RTX;
2102 result = wi::shwi (int_value, result_mode);
2103 break;
2105 case POPCOUNT:
2106 result = wi::shwi (wi::popcount (op0), result_mode);
2107 break;
2109 case PARITY:
2110 result = wi::shwi (wi::parity (op0), result_mode);
2111 break;
2113 case BSWAP:
2114 result = wide_int (op0).bswap ();
2115 break;
2117 case TRUNCATE:
2118 case ZERO_EXTEND:
2119 result = wide_int::from (op0, width, UNSIGNED);
2120 break;
2122 case SIGN_EXTEND:
2123 result = wide_int::from (op0, width, SIGNED);
2124 break;
2126 case SS_NEG:
2127 if (wi::only_sign_bit_p (op0))
2128 result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2129 else
2130 result = wi::neg (op0);
2131 break;
2133 case SS_ABS:
2134 if (wi::only_sign_bit_p (op0))
2135 result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2136 else
2137 result = wi::abs (op0);
2138 break;
2140 case SQRT:
2141 default:
2142 return 0;
2145 return immed_wide_int_const (result, result_mode);
2148 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2149 && SCALAR_FLOAT_MODE_P (mode)
2150 && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2152 REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2153 switch (code)
2155 case SQRT:
2156 return 0;
2157 case ABS:
2158 d = real_value_abs (&d);
2159 break;
2160 case NEG:
2161 d = real_value_negate (&d);
2162 break;
2163 case FLOAT_TRUNCATE:
2164 /* Don't perform the operation if flag_signaling_nans is on
2165 and the operand is a signaling NaN. */
2166 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2167 return NULL_RTX;
2168 /* Or if flag_rounding_math is on and the truncation is not
2169 exact. */
2170 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2171 && !exact_real_truncate (mode, &d))
2172 return NULL_RTX;
2173 d = real_value_truncate (mode, d);
2174 break;
2175 case FLOAT_EXTEND:
2176 /* Don't perform the operation if flag_signaling_nans is on
2177 and the operand is a signaling NaN. */
2178 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2179 return NULL_RTX;
2180 /* All this does is change the mode, unless changing
2181 mode class. */
2182 if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2183 real_convert (&d, mode, &d);
2184 break;
2185 case FIX:
2186 /* Don't perform the operation if flag_signaling_nans is on
2187 and the operand is a signaling NaN. */
2188 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2189 return NULL_RTX;
2190 real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2191 break;
2192 case NOT:
2194 long tmp[4];
2195 int i;
2197 real_to_target (tmp, &d, GET_MODE (op));
2198 for (i = 0; i < 4; i++)
2199 tmp[i] = ~tmp[i];
2200 real_from_target (&d, tmp, mode);
2201 break;
2203 default:
2204 gcc_unreachable ();
2206 return const_double_from_real_value (d, mode);
2208 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2209 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2210 && is_int_mode (mode, &result_mode))
2212 unsigned int width = GET_MODE_PRECISION (result_mode);
2213 if (width > MAX_BITSIZE_MODE_ANY_INT)
2214 return 0;
2216 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2217 operators are intentionally left unspecified (to ease implementation
2218 by target backends), for consistency, this routine implements the
2219 same semantics for constant folding as used by the middle-end. */
2221 /* This was formerly used only for non-IEEE float.
2222 eggert@twinsun.com says it is safe for IEEE also. */
2223 REAL_VALUE_TYPE t;
2224 const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2225 wide_int wmax, wmin;
2226 /* This is part of the abi to real_to_integer, but we check
2227 things before making this call. */
2228 bool fail;
2230 switch (code)
2232 case FIX:
2233 if (REAL_VALUE_ISNAN (*x))
2234 return const0_rtx;
2236 /* Test against the signed upper bound. */
2237 wmax = wi::max_value (width, SIGNED);
2238 real_from_integer (&t, VOIDmode, wmax, SIGNED);
2239 if (real_less (&t, x))
2240 return immed_wide_int_const (wmax, mode);
2242 /* Test against the signed lower bound. */
2243 wmin = wi::min_value (width, SIGNED);
2244 real_from_integer (&t, VOIDmode, wmin, SIGNED);
2245 if (real_less (x, &t))
2246 return immed_wide_int_const (wmin, mode);
2248 return immed_wide_int_const (real_to_integer (x, &fail, width),
2249 mode);
2251 case UNSIGNED_FIX:
2252 if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2253 return const0_rtx;
2255 /* Test against the unsigned upper bound. */
2256 wmax = wi::max_value (width, UNSIGNED);
2257 real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2258 if (real_less (&t, x))
2259 return immed_wide_int_const (wmax, mode);
2261 return immed_wide_int_const (real_to_integer (x, &fail, width),
2262 mode);
2264 default:
2265 gcc_unreachable ();
2269 /* Handle polynomial integers. */
2270 else if (CONST_POLY_INT_P (op))
2272 poly_wide_int result;
2273 switch (code)
2275 case NEG:
2276 result = -const_poly_int_value (op);
2277 break;
2279 case NOT:
2280 result = ~const_poly_int_value (op);
2281 break;
2283 default:
2284 return NULL_RTX;
2286 return immed_wide_int_const (result, mode);
2289 return NULL_RTX;
2292 /* Subroutine of simplify_binary_operation to simplify a binary operation
2293 CODE that can commute with byte swapping, with result mode MODE and
2294 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2295 Return zero if no simplification or canonicalization is possible. */
2298 simplify_context::simplify_byte_swapping_operation (rtx_code code,
2299 machine_mode mode,
2300 rtx op0, rtx op1)
2302 rtx tem;
2304 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2305 if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2307 tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2308 simplify_gen_unary (BSWAP, mode, op1, mode));
2309 return simplify_gen_unary (BSWAP, mode, tem, mode);
2312 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2313 if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2315 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2316 return simplify_gen_unary (BSWAP, mode, tem, mode);
2319 return NULL_RTX;
2322 /* Subroutine of simplify_binary_operation to simplify a commutative,
2323 associative binary operation CODE with result mode MODE, operating
2324 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2325 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2326 canonicalization is possible. */
2329 simplify_context::simplify_associative_operation (rtx_code code,
2330 machine_mode mode,
2331 rtx op0, rtx op1)
2333 rtx tem;
2335 /* Normally expressions simplified by simplify-rtx.cc are combined
2336 at most from a few machine instructions and therefore the
2337 expressions should be fairly small. During var-tracking
2338 we can see arbitrarily large expressions though and reassociating
2339 those can be quadratic, so punt after encountering max_assoc_count
2340 simplify_associative_operation calls during outermost simplify_*
2341 call. */
2342 if (++assoc_count >= max_assoc_count)
2343 return NULL_RTX;
2345 /* Linearize the operator to the left. */
2346 if (GET_CODE (op1) == code)
2348 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2349 if (GET_CODE (op0) == code)
2351 tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2352 return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2355 /* "a op (b op c)" becomes "(b op c) op a". */
2356 if (! swap_commutative_operands_p (op1, op0))
2357 return simplify_gen_binary (code, mode, op1, op0);
2359 std::swap (op0, op1);
2362 if (GET_CODE (op0) == code)
2364 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2365 if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2367 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2368 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2371 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2372 tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2373 if (tem != 0)
2374 return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2376 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2377 tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2378 if (tem != 0)
2379 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2382 return 0;
2385 /* Return a mask describing the COMPARISON. */
2386 static int
2387 comparison_to_mask (enum rtx_code comparison)
2389 switch (comparison)
2391 case LT:
2392 return 8;
2393 case GT:
2394 return 4;
2395 case EQ:
2396 return 2;
2397 case UNORDERED:
2398 return 1;
2400 case LTGT:
2401 return 12;
2402 case LE:
2403 return 10;
2404 case GE:
2405 return 6;
2406 case UNLT:
2407 return 9;
2408 case UNGT:
2409 return 5;
2410 case UNEQ:
2411 return 3;
2413 case ORDERED:
2414 return 14;
2415 case NE:
2416 return 13;
2417 case UNLE:
2418 return 11;
2419 case UNGE:
2420 return 7;
2422 default:
2423 gcc_unreachable ();
2427 /* Return a comparison corresponding to the MASK. */
2428 static enum rtx_code
2429 mask_to_comparison (int mask)
2431 switch (mask)
2433 case 8:
2434 return LT;
2435 case 4:
2436 return GT;
2437 case 2:
2438 return EQ;
2439 case 1:
2440 return UNORDERED;
2442 case 12:
2443 return LTGT;
2444 case 10:
2445 return LE;
2446 case 6:
2447 return GE;
2448 case 9:
2449 return UNLT;
2450 case 5:
2451 return UNGT;
2452 case 3:
2453 return UNEQ;
2455 case 14:
2456 return ORDERED;
2457 case 13:
2458 return NE;
2459 case 11:
2460 return UNLE;
2461 case 7:
2462 return UNGE;
2464 default:
2465 gcc_unreachable ();
2469 /* Return true if CODE is valid for comparisons of mode MODE, false
2470 otherwise.
2472 It is always safe to return false, even if the code was valid for the
2473 given mode as that will merely suppress optimizations. */
2475 static bool
2476 comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2478 switch (code)
2480 /* These are valid for integral, floating and vector modes. */
2481 case NE:
2482 case EQ:
2483 case GE:
2484 case GT:
2485 case LE:
2486 case LT:
2487 return (INTEGRAL_MODE_P (mode)
2488 || FLOAT_MODE_P (mode)
2489 || VECTOR_MODE_P (mode));
2491 /* These are valid for floating point modes. */
2492 case LTGT:
2493 case UNORDERED:
2494 case ORDERED:
2495 case UNEQ:
2496 case UNGE:
2497 case UNGT:
2498 case UNLE:
2499 case UNLT:
2500 return FLOAT_MODE_P (mode);
2502 /* These are filtered out in simplify_logical_operation, but
2503 we check for them too as a matter of safety. They are valid
2504 for integral and vector modes. */
2505 case GEU:
2506 case GTU:
2507 case LEU:
2508 case LTU:
2509 return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2511 default:
2512 gcc_unreachable ();
2516 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2517 false/true value of comparison with MODE where comparison operands
2518 have CMP_MODE. */
2520 static rtx
2521 relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2523 if (SCALAR_FLOAT_MODE_P (mode))
2525 if (res == const0_rtx)
2526 return CONST0_RTX (mode);
2527 #ifdef FLOAT_STORE_FLAG_VALUE
2528 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2529 return const_double_from_real_value (val, mode);
2530 #else
2531 return NULL_RTX;
2532 #endif
2534 if (VECTOR_MODE_P (mode))
2536 if (res == const0_rtx)
2537 return CONST0_RTX (mode);
2538 #ifdef VECTOR_STORE_FLAG_VALUE
2539 rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2540 if (val == NULL_RTX)
2541 return NULL_RTX;
2542 if (val == const1_rtx)
2543 return CONST1_RTX (mode);
2545 return gen_const_vec_duplicate (mode, val);
2546 #else
2547 return NULL_RTX;
2548 #endif
2550 /* For vector comparison with scalar int result, it is unknown
2551 if the target means here a comparison into an integral bitmask,
2552 or comparison where all comparisons true mean const_true_rtx
2553 whole result, or where any comparisons true mean const_true_rtx
2554 whole result. For const0_rtx all the cases are the same. */
2555 if (VECTOR_MODE_P (cmp_mode)
2556 && SCALAR_INT_MODE_P (mode)
2557 && res == const_true_rtx)
2558 return NULL_RTX;
2560 return res;
2563 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2564 and OP1, which should be both relational operations. Return 0 if no such
2565 simplification is possible. */
2567 simplify_context::simplify_logical_relational_operation (rtx_code code,
2568 machine_mode mode,
2569 rtx op0, rtx op1)
2571 /* We only handle IOR of two relational operations. */
2572 if (code != IOR)
2573 return 0;
2575 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2576 return 0;
2578 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2579 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2580 return 0;
2582 enum rtx_code code0 = GET_CODE (op0);
2583 enum rtx_code code1 = GET_CODE (op1);
2585 /* We don't handle unsigned comparisons currently. */
2586 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2587 return 0;
2588 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2589 return 0;
2591 int mask0 = comparison_to_mask (code0);
2592 int mask1 = comparison_to_mask (code1);
2594 int mask = mask0 | mask1;
2596 if (mask == 15)
2597 return relational_result (mode, GET_MODE (op0), const_true_rtx);
2599 code = mask_to_comparison (mask);
2601 /* Many comparison codes are only valid for certain mode classes. */
2602 if (!comparison_code_valid_for_mode (code, mode))
2603 return 0;
2605 op0 = XEXP (op1, 0);
2606 op1 = XEXP (op1, 1);
2608 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2611 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2612 and OP1. Return 0 if no simplification is possible.
2614 Don't use this for relational operations such as EQ or LT.
2615 Use simplify_relational_operation instead. */
2617 simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2618 rtx op0, rtx op1)
2620 rtx trueop0, trueop1;
2621 rtx tem;
2623 /* Relational operations don't work here. We must know the mode
2624 of the operands in order to do the comparison correctly.
2625 Assuming a full word can give incorrect results.
2626 Consider comparing 128 with -128 in QImode. */
2627 gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2628 gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2630 /* Make sure the constant is second. */
2631 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2632 && swap_commutative_operands_p (op0, op1))
2633 std::swap (op0, op1);
2635 trueop0 = avoid_constant_pool_reference (op0);
2636 trueop1 = avoid_constant_pool_reference (op1);
2638 tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2639 if (tem)
2640 return tem;
2641 tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2643 if (tem)
2644 return tem;
2646 /* If the above steps did not result in a simplification and op0 or op1
2647 were constant pool references, use the referenced constants directly. */
2648 if (trueop0 != op0 || trueop1 != op1)
2649 return simplify_gen_binary (code, mode, trueop0, trueop1);
2651 return NULL_RTX;
2654 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2655 which OP0 and OP1 are both vector series or vector duplicates
2656 (which are really just series with a step of 0). If so, try to
2657 form a new series by applying CODE to the bases and to the steps.
2658 Return null if no simplification is possible.
2660 MODE is the mode of the operation and is known to be a vector
2661 integer mode. */
2664 simplify_context::simplify_binary_operation_series (rtx_code code,
2665 machine_mode mode,
2666 rtx op0, rtx op1)
2668 rtx base0, step0;
2669 if (vec_duplicate_p (op0, &base0))
2670 step0 = const0_rtx;
2671 else if (!vec_series_p (op0, &base0, &step0))
2672 return NULL_RTX;
2674 rtx base1, step1;
2675 if (vec_duplicate_p (op1, &base1))
2676 step1 = const0_rtx;
2677 else if (!vec_series_p (op1, &base1, &step1))
2678 return NULL_RTX;
2680 /* Only create a new series if we can simplify both parts. In other
2681 cases this isn't really a simplification, and it's not necessarily
2682 a win to replace a vector operation with a scalar operation. */
2683 scalar_mode inner_mode = GET_MODE_INNER (mode);
2684 rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2685 if (!new_base)
2686 return NULL_RTX;
2688 rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2689 if (!new_step)
2690 return NULL_RTX;
2692 return gen_vec_series (mode, new_base, new_step);
2695 /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2696 operation CODE with result mode MODE, operating on OP0 and OP1.
2697 e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2698 Returns NULL_RTX if no simplification is possible. */
2701 simplify_context::simplify_distributive_operation (rtx_code code,
2702 machine_mode mode,
2703 rtx op0, rtx op1)
2705 enum rtx_code op = GET_CODE (op0);
2706 gcc_assert (GET_CODE (op1) == op);
2708 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2709 && ! side_effects_p (XEXP (op0, 1)))
2710 return simplify_gen_binary (op, mode,
2711 simplify_gen_binary (code, mode,
2712 XEXP (op0, 0),
2713 XEXP (op1, 0)),
2714 XEXP (op0, 1));
2716 if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2718 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2719 && ! side_effects_p (XEXP (op0, 0)))
2720 return simplify_gen_binary (op, mode,
2721 simplify_gen_binary (code, mode,
2722 XEXP (op0, 1),
2723 XEXP (op1, 1)),
2724 XEXP (op0, 0));
2725 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2726 && ! side_effects_p (XEXP (op0, 0)))
2727 return simplify_gen_binary (op, mode,
2728 simplify_gen_binary (code, mode,
2729 XEXP (op0, 1),
2730 XEXP (op1, 0)),
2731 XEXP (op0, 0));
2732 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2733 && ! side_effects_p (XEXP (op0, 1)))
2734 return simplify_gen_binary (op, mode,
2735 simplify_gen_binary (code, mode,
2736 XEXP (op0, 0),
2737 XEXP (op1, 1)),
2738 XEXP (op0, 1));
2741 return NULL_RTX;
2744 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2745 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2746 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2747 actual constants. */
2750 simplify_context::simplify_binary_operation_1 (rtx_code code,
2751 machine_mode mode,
2752 rtx op0, rtx op1,
2753 rtx trueop0, rtx trueop1)
2755 rtx tem, reversed, opleft, opright, elt0, elt1;
2756 HOST_WIDE_INT val;
2757 scalar_int_mode int_mode, inner_mode;
2758 poly_int64 offset;
2760 /* Even if we can't compute a constant result,
2761 there are some cases worth simplifying. */
2763 switch (code)
2765 case PLUS:
2766 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2767 when x is NaN, infinite, or finite and nonzero. They aren't
2768 when x is -0 and the rounding mode is not towards -infinity,
2769 since (-0) + 0 is then 0. */
2770 if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2771 return op0;
2773 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2774 transformations are safe even for IEEE. */
2775 if (GET_CODE (op0) == NEG)
2776 return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2777 else if (GET_CODE (op1) == NEG)
2778 return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2780 /* (~a) + 1 -> -a */
2781 if (INTEGRAL_MODE_P (mode)
2782 && GET_CODE (op0) == NOT
2783 && trueop1 == const1_rtx)
2784 return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2786 /* Handle both-operands-constant cases. We can only add
2787 CONST_INTs to constants since the sum of relocatable symbols
2788 can't be handled by most assemblers. Don't add CONST_INT
2789 to CONST_INT since overflow won't be computed properly if wider
2790 than HOST_BITS_PER_WIDE_INT. */
2792 if ((GET_CODE (op0) == CONST
2793 || GET_CODE (op0) == SYMBOL_REF
2794 || GET_CODE (op0) == LABEL_REF)
2795 && poly_int_rtx_p (op1, &offset))
2796 return plus_constant (mode, op0, offset);
2797 else if ((GET_CODE (op1) == CONST
2798 || GET_CODE (op1) == SYMBOL_REF
2799 || GET_CODE (op1) == LABEL_REF)
2800 && poly_int_rtx_p (op0, &offset))
2801 return plus_constant (mode, op1, offset);
2803 /* See if this is something like X * C - X or vice versa or
2804 if the multiplication is written as a shift. If so, we can
2805 distribute and make a new multiply, shift, or maybe just
2806 have X (if C is 2 in the example above). But don't make
2807 something more expensive than we had before. */
2809 if (is_a <scalar_int_mode> (mode, &int_mode))
2811 rtx lhs = op0, rhs = op1;
2813 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2814 wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2816 if (GET_CODE (lhs) == NEG)
2818 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2819 lhs = XEXP (lhs, 0);
2821 else if (GET_CODE (lhs) == MULT
2822 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2824 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2825 lhs = XEXP (lhs, 0);
2827 else if (GET_CODE (lhs) == ASHIFT
2828 && CONST_INT_P (XEXP (lhs, 1))
2829 && INTVAL (XEXP (lhs, 1)) >= 0
2830 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2832 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2833 GET_MODE_PRECISION (int_mode));
2834 lhs = XEXP (lhs, 0);
2837 if (GET_CODE (rhs) == NEG)
2839 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2840 rhs = XEXP (rhs, 0);
2842 else if (GET_CODE (rhs) == MULT
2843 && CONST_INT_P (XEXP (rhs, 1)))
2845 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2846 rhs = XEXP (rhs, 0);
2848 else if (GET_CODE (rhs) == ASHIFT
2849 && CONST_INT_P (XEXP (rhs, 1))
2850 && INTVAL (XEXP (rhs, 1)) >= 0
2851 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2853 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2854 GET_MODE_PRECISION (int_mode));
2855 rhs = XEXP (rhs, 0);
2858 if (rtx_equal_p (lhs, rhs))
2860 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2861 rtx coeff;
2862 bool speed = optimize_function_for_speed_p (cfun);
2864 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2866 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2867 return (set_src_cost (tem, int_mode, speed)
2868 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2871 /* Optimize (X - 1) * Y + Y to X * Y. */
2872 lhs = op0;
2873 rhs = op1;
2874 if (GET_CODE (op0) == MULT)
2876 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2877 && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
2878 || (GET_CODE (XEXP (op0, 0)) == MINUS
2879 && XEXP (XEXP (op0, 0), 1) == const1_rtx))
2880 && rtx_equal_p (XEXP (op0, 1), op1))
2881 lhs = XEXP (XEXP (op0, 0), 0);
2882 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2883 && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
2884 || (GET_CODE (XEXP (op0, 1)) == MINUS
2885 && XEXP (XEXP (op0, 1), 1) == const1_rtx))
2886 && rtx_equal_p (XEXP (op0, 0), op1))
2887 lhs = XEXP (XEXP (op0, 1), 0);
2889 else if (GET_CODE (op1) == MULT)
2891 if (((GET_CODE (XEXP (op1, 0)) == PLUS
2892 && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
2893 || (GET_CODE (XEXP (op1, 0)) == MINUS
2894 && XEXP (XEXP (op1, 0), 1) == const1_rtx))
2895 && rtx_equal_p (XEXP (op1, 1), op0))
2896 rhs = XEXP (XEXP (op1, 0), 0);
2897 else if (((GET_CODE (XEXP (op1, 1)) == PLUS
2898 && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
2899 || (GET_CODE (XEXP (op1, 1)) == MINUS
2900 && XEXP (XEXP (op1, 1), 1) == const1_rtx))
2901 && rtx_equal_p (XEXP (op1, 0), op0))
2902 rhs = XEXP (XEXP (op1, 1), 0);
2904 if (lhs != op0 || rhs != op1)
2905 return simplify_gen_binary (MULT, int_mode, lhs, rhs);
2908 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2909 if (CONST_SCALAR_INT_P (op1)
2910 && GET_CODE (op0) == XOR
2911 && CONST_SCALAR_INT_P (XEXP (op0, 1))
2912 && mode_signbit_p (mode, op1))
2913 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2914 simplify_gen_binary (XOR, mode, op1,
2915 XEXP (op0, 1)));
2917 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2918 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2919 && GET_CODE (op0) == MULT
2920 && GET_CODE (XEXP (op0, 0)) == NEG)
2922 rtx in1, in2;
2924 in1 = XEXP (XEXP (op0, 0), 0);
2925 in2 = XEXP (op0, 1);
2926 return simplify_gen_binary (MINUS, mode, op1,
2927 simplify_gen_binary (MULT, mode,
2928 in1, in2));
2931 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2932 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2933 is 1. */
2934 if (COMPARISON_P (op0)
2935 && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2936 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2937 && (reversed = reversed_comparison (op0, mode)))
2938 return
2939 simplify_gen_unary (NEG, mode, reversed, mode);
2941 /* If one of the operands is a PLUS or a MINUS, see if we can
2942 simplify this by the associative law.
2943 Don't use the associative law for floating point.
2944 The inaccuracy makes it nonassociative,
2945 and subtle programs can break if operations are associated. */
2947 if (INTEGRAL_MODE_P (mode)
2948 && (plus_minus_operand_p (op0)
2949 || plus_minus_operand_p (op1))
2950 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2951 return tem;
2953 /* Reassociate floating point addition only when the user
2954 specifies associative math operations. */
2955 if (FLOAT_MODE_P (mode)
2956 && flag_associative_math)
2958 tem = simplify_associative_operation (code, mode, op0, op1);
2959 if (tem)
2960 return tem;
2963 /* Handle vector series. */
2964 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2966 tem = simplify_binary_operation_series (code, mode, op0, op1);
2967 if (tem)
2968 return tem;
2970 break;
2972 case COMPARE:
2973 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
2974 if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
2975 || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
2976 && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
2978 rtx xop00 = XEXP (op0, 0);
2979 rtx xop10 = XEXP (op1, 0);
2981 if (REG_P (xop00) && REG_P (xop10)
2982 && REGNO (xop00) == REGNO (xop10)
2983 && GET_MODE (xop00) == mode
2984 && GET_MODE (xop10) == mode
2985 && GET_MODE_CLASS (mode) == MODE_CC)
2986 return xop00;
2988 break;
2990 case MINUS:
2991 /* We can't assume x-x is 0 even with non-IEEE floating point,
2992 but since it is zero except in very strange circumstances, we
2993 will treat it as zero with -ffinite-math-only. */
2994 if (rtx_equal_p (trueop0, trueop1)
2995 && ! side_effects_p (op0)
2996 && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
2997 return CONST0_RTX (mode);
2999 /* Change subtraction from zero into negation. (0 - x) is the
3000 same as -x when x is NaN, infinite, or finite and nonzero.
3001 But if the mode has signed zeros, and does not round towards
3002 -infinity, then 0 - 0 is 0, not -0. */
3003 if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3004 return simplify_gen_unary (NEG, mode, op1, mode);
3006 /* (-1 - a) is ~a, unless the expression contains symbolic
3007 constants, in which case not retaining additions and
3008 subtractions could cause invalid assembly to be produced. */
3009 if (trueop0 == constm1_rtx
3010 && !contains_symbolic_reference_p (op1))
3011 return simplify_gen_unary (NOT, mode, op1, mode);
3013 /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3014 or has signed zeros and supports rounding towards -infinity.
3015 In such a case, 0 - 0 is -0. */
3016 if (!(HONOR_SIGNED_ZEROS (mode)
3017 && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3018 && !HONOR_SNANS (mode)
3019 && trueop1 == CONST0_RTX (mode))
3020 return op0;
3022 /* See if this is something like X * C - X or vice versa or
3023 if the multiplication is written as a shift. If so, we can
3024 distribute and make a new multiply, shift, or maybe just
3025 have X (if C is 2 in the example above). But don't make
3026 something more expensive than we had before. */
3028 if (is_a <scalar_int_mode> (mode, &int_mode))
3030 rtx lhs = op0, rhs = op1;
3032 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3033 wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3035 if (GET_CODE (lhs) == NEG)
3037 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3038 lhs = XEXP (lhs, 0);
3040 else if (GET_CODE (lhs) == MULT
3041 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3043 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3044 lhs = XEXP (lhs, 0);
3046 else if (GET_CODE (lhs) == ASHIFT
3047 && CONST_INT_P (XEXP (lhs, 1))
3048 && INTVAL (XEXP (lhs, 1)) >= 0
3049 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3051 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3052 GET_MODE_PRECISION (int_mode));
3053 lhs = XEXP (lhs, 0);
3056 if (GET_CODE (rhs) == NEG)
3058 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3059 rhs = XEXP (rhs, 0);
3061 else if (GET_CODE (rhs) == MULT
3062 && CONST_INT_P (XEXP (rhs, 1)))
3064 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3065 rhs = XEXP (rhs, 0);
3067 else if (GET_CODE (rhs) == ASHIFT
3068 && CONST_INT_P (XEXP (rhs, 1))
3069 && INTVAL (XEXP (rhs, 1)) >= 0
3070 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3072 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3073 GET_MODE_PRECISION (int_mode));
3074 negcoeff1 = -negcoeff1;
3075 rhs = XEXP (rhs, 0);
3078 if (rtx_equal_p (lhs, rhs))
3080 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3081 rtx coeff;
3082 bool speed = optimize_function_for_speed_p (cfun);
3084 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3086 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3087 return (set_src_cost (tem, int_mode, speed)
3088 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3091 /* Optimize (X + 1) * Y - Y to X * Y. */
3092 lhs = op0;
3093 if (GET_CODE (op0) == MULT)
3095 if (((GET_CODE (XEXP (op0, 0)) == PLUS
3096 && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3097 || (GET_CODE (XEXP (op0, 0)) == MINUS
3098 && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3099 && rtx_equal_p (XEXP (op0, 1), op1))
3100 lhs = XEXP (XEXP (op0, 0), 0);
3101 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3102 && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3103 || (GET_CODE (XEXP (op0, 1)) == MINUS
3104 && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3105 && rtx_equal_p (XEXP (op0, 0), op1))
3106 lhs = XEXP (XEXP (op0, 1), 0);
3108 if (lhs != op0)
3109 return simplify_gen_binary (MULT, int_mode, lhs, op1);
3112 /* (a - (-b)) -> (a + b). True even for IEEE. */
3113 if (GET_CODE (op1) == NEG)
3114 return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3116 /* (-x - c) may be simplified as (-c - x). */
3117 if (GET_CODE (op0) == NEG
3118 && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3120 tem = simplify_unary_operation (NEG, mode, op1, mode);
3121 if (tem)
3122 return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3125 if ((GET_CODE (op0) == CONST
3126 || GET_CODE (op0) == SYMBOL_REF
3127 || GET_CODE (op0) == LABEL_REF)
3128 && poly_int_rtx_p (op1, &offset))
3129 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3131 /* Don't let a relocatable value get a negative coeff. */
3132 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
3133 return simplify_gen_binary (PLUS, mode,
3134 op0,
3135 neg_poly_int_rtx (mode, op1));
3137 /* (x - (x & y)) -> (x & ~y) */
3138 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3140 if (rtx_equal_p (op0, XEXP (op1, 0)))
3142 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3143 GET_MODE (XEXP (op1, 1)));
3144 return simplify_gen_binary (AND, mode, op0, tem);
3146 if (rtx_equal_p (op0, XEXP (op1, 1)))
3148 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3149 GET_MODE (XEXP (op1, 0)));
3150 return simplify_gen_binary (AND, mode, op0, tem);
3154 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3155 by reversing the comparison code if valid. */
3156 if (STORE_FLAG_VALUE == 1
3157 && trueop0 == const1_rtx
3158 && COMPARISON_P (op1)
3159 && (reversed = reversed_comparison (op1, mode)))
3160 return reversed;
3162 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3163 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3164 && GET_CODE (op1) == MULT
3165 && GET_CODE (XEXP (op1, 0)) == NEG)
3167 rtx in1, in2;
3169 in1 = XEXP (XEXP (op1, 0), 0);
3170 in2 = XEXP (op1, 1);
3171 return simplify_gen_binary (PLUS, mode,
3172 simplify_gen_binary (MULT, mode,
3173 in1, in2),
3174 op0);
3177 /* Canonicalize (minus (neg A) (mult B C)) to
3178 (minus (mult (neg B) C) A). */
3179 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3180 && GET_CODE (op1) == MULT
3181 && GET_CODE (op0) == NEG)
3183 rtx in1, in2;
3185 in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3186 in2 = XEXP (op1, 1);
3187 return simplify_gen_binary (MINUS, mode,
3188 simplify_gen_binary (MULT, mode,
3189 in1, in2),
3190 XEXP (op0, 0));
3193 /* If one of the operands is a PLUS or a MINUS, see if we can
3194 simplify this by the associative law. This will, for example,
3195 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3196 Don't use the associative law for floating point.
3197 The inaccuracy makes it nonassociative,
3198 and subtle programs can break if operations are associated. */
3200 if (INTEGRAL_MODE_P (mode)
3201 && (plus_minus_operand_p (op0)
3202 || plus_minus_operand_p (op1))
3203 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3204 return tem;
3206 /* Handle vector series. */
3207 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3209 tem = simplify_binary_operation_series (code, mode, op0, op1);
3210 if (tem)
3211 return tem;
3213 break;
3215 case MULT:
3216 if (trueop1 == constm1_rtx)
3217 return simplify_gen_unary (NEG, mode, op0, mode);
3219 if (GET_CODE (op0) == NEG)
3221 rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3222 /* If op1 is a MULT as well and simplify_unary_operation
3223 just moved the NEG to the second operand, simplify_gen_binary
3224 below could through simplify_associative_operation move
3225 the NEG around again and recurse endlessly. */
3226 if (temp
3227 && GET_CODE (op1) == MULT
3228 && GET_CODE (temp) == MULT
3229 && XEXP (op1, 0) == XEXP (temp, 0)
3230 && GET_CODE (XEXP (temp, 1)) == NEG
3231 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3232 temp = NULL_RTX;
3233 if (temp)
3234 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3236 if (GET_CODE (op1) == NEG)
3238 rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3239 /* If op0 is a MULT as well and simplify_unary_operation
3240 just moved the NEG to the second operand, simplify_gen_binary
3241 below could through simplify_associative_operation move
3242 the NEG around again and recurse endlessly. */
3243 if (temp
3244 && GET_CODE (op0) == MULT
3245 && GET_CODE (temp) == MULT
3246 && XEXP (op0, 0) == XEXP (temp, 0)
3247 && GET_CODE (XEXP (temp, 1)) == NEG
3248 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3249 temp = NULL_RTX;
3250 if (temp)
3251 return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3254 /* Maybe simplify x * 0 to 0. The reduction is not valid if
3255 x is NaN, since x * 0 is then also NaN. Nor is it valid
3256 when the mode has signed zeros, since multiplying a negative
3257 number by 0 will give -0, not 0. */
3258 if (!HONOR_NANS (mode)
3259 && !HONOR_SIGNED_ZEROS (mode)
3260 && trueop1 == CONST0_RTX (mode)
3261 && ! side_effects_p (op0))
3262 return op1;
3264 /* In IEEE floating point, x*1 is not equivalent to x for
3265 signalling NaNs. */
3266 if (!HONOR_SNANS (mode)
3267 && trueop1 == CONST1_RTX (mode))
3268 return op0;
3270 /* Convert multiply by constant power of two into shift. */
3271 if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3273 val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3274 if (val >= 0)
3275 return simplify_gen_binary (ASHIFT, mode, op0,
3276 gen_int_shift_amount (mode, val));
3279 /* x*2 is x+x and x*(-1) is -x */
3280 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3281 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3282 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3283 && GET_MODE (op0) == mode)
3285 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3287 if (real_equal (d1, &dconst2))
3288 return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3290 if (!HONOR_SNANS (mode)
3291 && real_equal (d1, &dconstm1))
3292 return simplify_gen_unary (NEG, mode, op0, mode);
3295 /* Optimize -x * -x as x * x. */
3296 if (FLOAT_MODE_P (mode)
3297 && GET_CODE (op0) == NEG
3298 && GET_CODE (op1) == NEG
3299 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3300 && !side_effects_p (XEXP (op0, 0)))
3301 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3303 /* Likewise, optimize abs(x) * abs(x) as x * x. */
3304 if (SCALAR_FLOAT_MODE_P (mode)
3305 && GET_CODE (op0) == ABS
3306 && GET_CODE (op1) == ABS
3307 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3308 && !side_effects_p (XEXP (op0, 0)))
3309 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3311 /* Reassociate multiplication, but for floating point MULTs
3312 only when the user specifies unsafe math optimizations. */
3313 if (! FLOAT_MODE_P (mode)
3314 || flag_unsafe_math_optimizations)
3316 tem = simplify_associative_operation (code, mode, op0, op1);
3317 if (tem)
3318 return tem;
3320 break;
3322 case IOR:
3323 if (trueop1 == CONST0_RTX (mode))
3324 return op0;
3325 if (INTEGRAL_MODE_P (mode)
3326 && trueop1 == CONSTM1_RTX (mode)
3327 && !side_effects_p (op0))
3328 return op1;
3329 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3330 return op0;
3331 /* A | (~A) -> -1 */
3332 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3333 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3334 && ! side_effects_p (op0)
3335 && SCALAR_INT_MODE_P (mode))
3336 return constm1_rtx;
3338 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3339 if (CONST_INT_P (op1)
3340 && HWI_COMPUTABLE_MODE_P (mode)
3341 && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3342 && !side_effects_p (op0))
3343 return op1;
3345 /* Canonicalize (X & C1) | C2. */
3346 if (GET_CODE (op0) == AND
3347 && CONST_INT_P (trueop1)
3348 && CONST_INT_P (XEXP (op0, 1)))
3350 HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3351 HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3352 HOST_WIDE_INT c2 = INTVAL (trueop1);
3354 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3355 if ((c1 & c2) == c1
3356 && !side_effects_p (XEXP (op0, 0)))
3357 return trueop1;
3359 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3360 if (((c1|c2) & mask) == mask)
3361 return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3364 /* Convert (A & B) | A to A. */
3365 if (GET_CODE (op0) == AND
3366 && (rtx_equal_p (XEXP (op0, 0), op1)
3367 || rtx_equal_p (XEXP (op0, 1), op1))
3368 && ! side_effects_p (XEXP (op0, 0))
3369 && ! side_effects_p (XEXP (op0, 1)))
3370 return op1;
3372 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3373 mode size to (rotate A CX). */
3375 if (GET_CODE (op1) == ASHIFT
3376 || GET_CODE (op1) == SUBREG)
3378 opleft = op1;
3379 opright = op0;
3381 else
3383 opright = op1;
3384 opleft = op0;
3387 if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3388 && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3389 && CONST_INT_P (XEXP (opleft, 1))
3390 && CONST_INT_P (XEXP (opright, 1))
3391 && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3392 == GET_MODE_UNIT_PRECISION (mode)))
3393 return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3395 /* Same, but for ashift that has been "simplified" to a wider mode
3396 by simplify_shift_const. */
3398 if (GET_CODE (opleft) == SUBREG
3399 && is_a <scalar_int_mode> (mode, &int_mode)
3400 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3401 &inner_mode)
3402 && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3403 && GET_CODE (opright) == LSHIFTRT
3404 && GET_CODE (XEXP (opright, 0)) == SUBREG
3405 && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3406 && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3407 && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3408 SUBREG_REG (XEXP (opright, 0)))
3409 && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3410 && CONST_INT_P (XEXP (opright, 1))
3411 && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3412 + INTVAL (XEXP (opright, 1))
3413 == GET_MODE_PRECISION (int_mode)))
3414 return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3415 XEXP (SUBREG_REG (opleft), 1));
3417 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3418 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3419 the PLUS does not affect any of the bits in OP1: then we can do
3420 the IOR as a PLUS and we can associate. This is valid if OP1
3421 can be safely shifted left C bits. */
3422 if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3423 && GET_CODE (XEXP (op0, 0)) == PLUS
3424 && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3425 && CONST_INT_P (XEXP (op0, 1))
3426 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3428 int count = INTVAL (XEXP (op0, 1));
3429 HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3431 if (mask >> count == INTVAL (trueop1)
3432 && trunc_int_for_mode (mask, mode) == mask
3433 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3434 return simplify_gen_binary (ASHIFTRT, mode,
3435 plus_constant (mode, XEXP (op0, 0),
3436 mask),
3437 XEXP (op0, 1));
3440 /* The following happens with bitfield merging.
3441 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3442 if (GET_CODE (op0) == AND
3443 && GET_CODE (op1) == AND
3444 && CONST_INT_P (XEXP (op0, 1))
3445 && CONST_INT_P (XEXP (op1, 1))
3446 && (INTVAL (XEXP (op0, 1))
3447 == ~INTVAL (XEXP (op1, 1))))
3449 /* The IOR may be on both sides. */
3450 rtx top0 = NULL_RTX, top1 = NULL_RTX;
3451 if (GET_CODE (XEXP (op1, 0)) == IOR)
3452 top0 = op0, top1 = op1;
3453 else if (GET_CODE (XEXP (op0, 0)) == IOR)
3454 top0 = op1, top1 = op0;
3455 if (top0 && top1)
3457 /* X may be on either side of the inner IOR. */
3458 rtx tem = NULL_RTX;
3459 if (rtx_equal_p (XEXP (top0, 0),
3460 XEXP (XEXP (top1, 0), 0)))
3461 tem = XEXP (XEXP (top1, 0), 1);
3462 else if (rtx_equal_p (XEXP (top0, 0),
3463 XEXP (XEXP (top1, 0), 1)))
3464 tem = XEXP (XEXP (top1, 0), 0);
3465 if (tem)
3466 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3467 simplify_gen_binary
3468 (AND, mode, tem, XEXP (top1, 1)));
3472 /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3473 if (GET_CODE (op0) == GET_CODE (op1)
3474 && (GET_CODE (op0) == AND
3475 || GET_CODE (op0) == IOR
3476 || GET_CODE (op0) == LSHIFTRT
3477 || GET_CODE (op0) == ASHIFTRT
3478 || GET_CODE (op0) == ASHIFT
3479 || GET_CODE (op0) == ROTATE
3480 || GET_CODE (op0) == ROTATERT))
3482 tem = simplify_distributive_operation (code, mode, op0, op1);
3483 if (tem)
3484 return tem;
3487 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3488 if (tem)
3489 return tem;
3491 tem = simplify_associative_operation (code, mode, op0, op1);
3492 if (tem)
3493 return tem;
3495 tem = simplify_logical_relational_operation (code, mode, op0, op1);
3496 if (tem)
3497 return tem;
3498 break;
3500 case XOR:
3501 if (trueop1 == CONST0_RTX (mode))
3502 return op0;
3503 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3504 return simplify_gen_unary (NOT, mode, op0, mode);
3505 if (rtx_equal_p (trueop0, trueop1)
3506 && ! side_effects_p (op0)
3507 && GET_MODE_CLASS (mode) != MODE_CC)
3508 return CONST0_RTX (mode);
3510 /* Canonicalize XOR of the most significant bit to PLUS. */
3511 if (CONST_SCALAR_INT_P (op1)
3512 && mode_signbit_p (mode, op1))
3513 return simplify_gen_binary (PLUS, mode, op0, op1);
3514 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3515 if (CONST_SCALAR_INT_P (op1)
3516 && GET_CODE (op0) == PLUS
3517 && CONST_SCALAR_INT_P (XEXP (op0, 1))
3518 && mode_signbit_p (mode, XEXP (op0, 1)))
3519 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3520 simplify_gen_binary (XOR, mode, op1,
3521 XEXP (op0, 1)));
3523 /* If we are XORing two things that have no bits in common,
3524 convert them into an IOR. This helps to detect rotation encoded
3525 using those methods and possibly other simplifications. */
3527 if (HWI_COMPUTABLE_MODE_P (mode)
3528 && (nonzero_bits (op0, mode)
3529 & nonzero_bits (op1, mode)) == 0)
3530 return (simplify_gen_binary (IOR, mode, op0, op1));
3532 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3533 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3534 (NOT y). */
3536 int num_negated = 0;
3538 if (GET_CODE (op0) == NOT)
3539 num_negated++, op0 = XEXP (op0, 0);
3540 if (GET_CODE (op1) == NOT)
3541 num_negated++, op1 = XEXP (op1, 0);
3543 if (num_negated == 2)
3544 return simplify_gen_binary (XOR, mode, op0, op1);
3545 else if (num_negated == 1)
3546 return simplify_gen_unary (NOT, mode,
3547 simplify_gen_binary (XOR, mode, op0, op1),
3548 mode);
3551 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3552 correspond to a machine insn or result in further simplifications
3553 if B is a constant. */
3555 if (GET_CODE (op0) == AND
3556 && rtx_equal_p (XEXP (op0, 1), op1)
3557 && ! side_effects_p (op1))
3558 return simplify_gen_binary (AND, mode,
3559 simplify_gen_unary (NOT, mode,
3560 XEXP (op0, 0), mode),
3561 op1);
3563 else if (GET_CODE (op0) == AND
3564 && rtx_equal_p (XEXP (op0, 0), op1)
3565 && ! side_effects_p (op1))
3566 return simplify_gen_binary (AND, mode,
3567 simplify_gen_unary (NOT, mode,
3568 XEXP (op0, 1), mode),
3569 op1);
3571 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3572 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3573 out bits inverted twice and not set by C. Similarly, given
3574 (xor (and (xor A B) C) D), simplify without inverting C in
3575 the xor operand: (xor (and A C) (B&C)^D).
3577 else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3578 && GET_CODE (XEXP (op0, 0)) == XOR
3579 && CONST_INT_P (op1)
3580 && CONST_INT_P (XEXP (op0, 1))
3581 && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3583 enum rtx_code op = GET_CODE (op0);
3584 rtx a = XEXP (XEXP (op0, 0), 0);
3585 rtx b = XEXP (XEXP (op0, 0), 1);
3586 rtx c = XEXP (op0, 1);
3587 rtx d = op1;
3588 HOST_WIDE_INT bval = INTVAL (b);
3589 HOST_WIDE_INT cval = INTVAL (c);
3590 HOST_WIDE_INT dval = INTVAL (d);
3591 HOST_WIDE_INT xcval;
3593 if (op == IOR)
3594 xcval = ~cval;
3595 else
3596 xcval = cval;
3598 return simplify_gen_binary (XOR, mode,
3599 simplify_gen_binary (op, mode, a, c),
3600 gen_int_mode ((bval & xcval) ^ dval,
3601 mode));
3604 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3605 we can transform like this:
3606 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3607 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3608 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3609 Attempt a few simplifications when B and C are both constants. */
3610 if (GET_CODE (op0) == AND
3611 && CONST_INT_P (op1)
3612 && CONST_INT_P (XEXP (op0, 1)))
3614 rtx a = XEXP (op0, 0);
3615 rtx b = XEXP (op0, 1);
3616 rtx c = op1;
3617 HOST_WIDE_INT bval = INTVAL (b);
3618 HOST_WIDE_INT cval = INTVAL (c);
3620 /* Instead of computing ~A&C, we compute its negated value,
3621 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3622 optimize for sure. If it does not simplify, we still try
3623 to compute ~A&C below, but since that always allocates
3624 RTL, we don't try that before committing to returning a
3625 simplified expression. */
3626 rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3627 GEN_INT (~cval));
3629 if ((~cval & bval) == 0)
3631 rtx na_c = NULL_RTX;
3632 if (n_na_c)
3633 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3634 else
3636 /* If ~A does not simplify, don't bother: we don't
3637 want to simplify 2 operations into 3, and if na_c
3638 were to simplify with na, n_na_c would have
3639 simplified as well. */
3640 rtx na = simplify_unary_operation (NOT, mode, a, mode);
3641 if (na)
3642 na_c = simplify_gen_binary (AND, mode, na, c);
3645 /* Try to simplify ~A&C | ~B&C. */
3646 if (na_c != NULL_RTX)
3647 return simplify_gen_binary (IOR, mode, na_c,
3648 gen_int_mode (~bval & cval, mode));
3650 else
3652 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3653 if (n_na_c == CONSTM1_RTX (mode))
3655 rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3656 gen_int_mode (~cval & bval,
3657 mode));
3658 return simplify_gen_binary (IOR, mode, a_nc_b,
3659 gen_int_mode (~bval & cval,
3660 mode));
3665 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3666 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3667 machines, and also has shorter instruction path length. */
3668 if (GET_CODE (op0) == AND
3669 && GET_CODE (XEXP (op0, 0)) == XOR
3670 && CONST_INT_P (XEXP (op0, 1))
3671 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3673 rtx a = trueop1;
3674 rtx b = XEXP (XEXP (op0, 0), 1);
3675 rtx c = XEXP (op0, 1);
3676 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3677 rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3678 rtx bc = simplify_gen_binary (AND, mode, b, c);
3679 return simplify_gen_binary (IOR, mode, a_nc, bc);
3681 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3682 else if (GET_CODE (op0) == AND
3683 && GET_CODE (XEXP (op0, 0)) == XOR
3684 && CONST_INT_P (XEXP (op0, 1))
3685 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3687 rtx a = XEXP (XEXP (op0, 0), 0);
3688 rtx b = trueop1;
3689 rtx c = XEXP (op0, 1);
3690 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3691 rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3692 rtx ac = simplify_gen_binary (AND, mode, a, c);
3693 return simplify_gen_binary (IOR, mode, ac, b_nc);
3696 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3697 comparison if STORE_FLAG_VALUE is 1. */
3698 if (STORE_FLAG_VALUE == 1
3699 && trueop1 == const1_rtx
3700 && COMPARISON_P (op0)
3701 && (reversed = reversed_comparison (op0, mode)))
3702 return reversed;
3704 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3705 is (lt foo (const_int 0)), so we can perform the above
3706 simplification if STORE_FLAG_VALUE is 1. */
3708 if (is_a <scalar_int_mode> (mode, &int_mode)
3709 && STORE_FLAG_VALUE == 1
3710 && trueop1 == const1_rtx
3711 && GET_CODE (op0) == LSHIFTRT
3712 && CONST_INT_P (XEXP (op0, 1))
3713 && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3714 return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3716 /* (xor (comparison foo bar) (const_int sign-bit))
3717 when STORE_FLAG_VALUE is the sign bit. */
3718 if (is_a <scalar_int_mode> (mode, &int_mode)
3719 && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3720 && trueop1 == const_true_rtx
3721 && COMPARISON_P (op0)
3722 && (reversed = reversed_comparison (op0, int_mode)))
3723 return reversed;
3725 /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3726 if (GET_CODE (op0) == GET_CODE (op1)
3727 && (GET_CODE (op0) == AND
3728 || GET_CODE (op0) == LSHIFTRT
3729 || GET_CODE (op0) == ASHIFTRT
3730 || GET_CODE (op0) == ASHIFT
3731 || GET_CODE (op0) == ROTATE
3732 || GET_CODE (op0) == ROTATERT))
3734 tem = simplify_distributive_operation (code, mode, op0, op1);
3735 if (tem)
3736 return tem;
3739 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3740 if (tem)
3741 return tem;
3743 tem = simplify_associative_operation (code, mode, op0, op1);
3744 if (tem)
3745 return tem;
3746 break;
3748 case AND:
3749 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3750 return trueop1;
3751 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3752 return op0;
3753 if (HWI_COMPUTABLE_MODE_P (mode))
3755 HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
3756 HOST_WIDE_INT nzop1;
3757 if (CONST_INT_P (trueop1))
3759 HOST_WIDE_INT val1 = INTVAL (trueop1);
3760 /* If we are turning off bits already known off in OP0, we need
3761 not do an AND. */
3762 if ((nzop0 & ~val1) == 0)
3763 return op0;
3765 nzop1 = nonzero_bits (trueop1, mode);
3766 /* If we are clearing all the nonzero bits, the result is zero. */
3767 if ((nzop1 & nzop0) == 0
3768 && !side_effects_p (op0) && !side_effects_p (op1))
3769 return CONST0_RTX (mode);
3771 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3772 && GET_MODE_CLASS (mode) != MODE_CC)
3773 return op0;
3774 /* A & (~A) -> 0 */
3775 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3776 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3777 && ! side_effects_p (op0)
3778 && GET_MODE_CLASS (mode) != MODE_CC)
3779 return CONST0_RTX (mode);
3781 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3782 there are no nonzero bits of C outside of X's mode. */
3783 if ((GET_CODE (op0) == SIGN_EXTEND
3784 || GET_CODE (op0) == ZERO_EXTEND)
3785 && CONST_INT_P (trueop1)
3786 && HWI_COMPUTABLE_MODE_P (mode)
3787 && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
3788 & UINTVAL (trueop1)) == 0)
3790 machine_mode imode = GET_MODE (XEXP (op0, 0));
3791 tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
3792 gen_int_mode (INTVAL (trueop1),
3793 imode));
3794 return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3797 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3798 we might be able to further simplify the AND with X and potentially
3799 remove the truncation altogether. */
3800 if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3802 rtx x = XEXP (op0, 0);
3803 machine_mode xmode = GET_MODE (x);
3804 tem = simplify_gen_binary (AND, xmode, x,
3805 gen_int_mode (INTVAL (trueop1), xmode));
3806 return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3809 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3810 if (GET_CODE (op0) == IOR
3811 && CONST_INT_P (trueop1)
3812 && CONST_INT_P (XEXP (op0, 1)))
3814 HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3815 return simplify_gen_binary (IOR, mode,
3816 simplify_gen_binary (AND, mode,
3817 XEXP (op0, 0), op1),
3818 gen_int_mode (tmp, mode));
3821 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3822 insn (and may simplify more). */
3823 if (GET_CODE (op0) == XOR
3824 && rtx_equal_p (XEXP (op0, 0), op1)
3825 && ! side_effects_p (op1))
3826 return simplify_gen_binary (AND, mode,
3827 simplify_gen_unary (NOT, mode,
3828 XEXP (op0, 1), mode),
3829 op1);
3831 if (GET_CODE (op0) == XOR
3832 && rtx_equal_p (XEXP (op0, 1), op1)
3833 && ! side_effects_p (op1))
3834 return simplify_gen_binary (AND, mode,
3835 simplify_gen_unary (NOT, mode,
3836 XEXP (op0, 0), mode),
3837 op1);
3839 /* Similarly for (~(A ^ B)) & A. */
3840 if (GET_CODE (op0) == NOT
3841 && GET_CODE (XEXP (op0, 0)) == XOR
3842 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3843 && ! side_effects_p (op1))
3844 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3846 if (GET_CODE (op0) == NOT
3847 && GET_CODE (XEXP (op0, 0)) == XOR
3848 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3849 && ! side_effects_p (op1))
3850 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3852 /* Convert (A | B) & A to A. */
3853 if (GET_CODE (op0) == IOR
3854 && (rtx_equal_p (XEXP (op0, 0), op1)
3855 || rtx_equal_p (XEXP (op0, 1), op1))
3856 && ! side_effects_p (XEXP (op0, 0))
3857 && ! side_effects_p (XEXP (op0, 1)))
3858 return op1;
3860 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3861 ((A & N) + B) & M -> (A + B) & M
3862 Similarly if (N & M) == 0,
3863 ((A | N) + B) & M -> (A + B) & M
3864 and for - instead of + and/or ^ instead of |.
3865 Also, if (N & M) == 0, then
3866 (A +- N) & M -> A & M. */
3867 if (CONST_INT_P (trueop1)
3868 && HWI_COMPUTABLE_MODE_P (mode)
3869 && ~UINTVAL (trueop1)
3870 && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3871 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3873 rtx pmop[2];
3874 int which;
3876 pmop[0] = XEXP (op0, 0);
3877 pmop[1] = XEXP (op0, 1);
3879 if (CONST_INT_P (pmop[1])
3880 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3881 return simplify_gen_binary (AND, mode, pmop[0], op1);
3883 for (which = 0; which < 2; which++)
3885 tem = pmop[which];
3886 switch (GET_CODE (tem))
3888 case AND:
3889 if (CONST_INT_P (XEXP (tem, 1))
3890 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3891 == UINTVAL (trueop1))
3892 pmop[which] = XEXP (tem, 0);
3893 break;
3894 case IOR:
3895 case XOR:
3896 if (CONST_INT_P (XEXP (tem, 1))
3897 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3898 pmop[which] = XEXP (tem, 0);
3899 break;
3900 default:
3901 break;
3905 if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3907 tem = simplify_gen_binary (GET_CODE (op0), mode,
3908 pmop[0], pmop[1]);
3909 return simplify_gen_binary (code, mode, tem, op1);
3913 /* (and X (ior (not X) Y) -> (and X Y) */
3914 if (GET_CODE (op1) == IOR
3915 && GET_CODE (XEXP (op1, 0)) == NOT
3916 && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3917 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3919 /* (and (ior (not X) Y) X) -> (and X Y) */
3920 if (GET_CODE (op0) == IOR
3921 && GET_CODE (XEXP (op0, 0)) == NOT
3922 && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3923 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3925 /* (and X (ior Y (not X)) -> (and X Y) */
3926 if (GET_CODE (op1) == IOR
3927 && GET_CODE (XEXP (op1, 1)) == NOT
3928 && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3929 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3931 /* (and (ior Y (not X)) X) -> (and X Y) */
3932 if (GET_CODE (op0) == IOR
3933 && GET_CODE (XEXP (op0, 1)) == NOT
3934 && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3935 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3937 /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
3938 if (GET_CODE (op0) == GET_CODE (op1)
3939 && (GET_CODE (op0) == AND
3940 || GET_CODE (op0) == IOR
3941 || GET_CODE (op0) == LSHIFTRT
3942 || GET_CODE (op0) == ASHIFTRT
3943 || GET_CODE (op0) == ASHIFT
3944 || GET_CODE (op0) == ROTATE
3945 || GET_CODE (op0) == ROTATERT))
3947 tem = simplify_distributive_operation (code, mode, op0, op1);
3948 if (tem)
3949 return tem;
3952 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3953 if (tem)
3954 return tem;
3956 tem = simplify_associative_operation (code, mode, op0, op1);
3957 if (tem)
3958 return tem;
3959 break;
3961 case UDIV:
3962 /* 0/x is 0 (or x&0 if x has side-effects). */
3963 if (trueop0 == CONST0_RTX (mode)
3964 && !cfun->can_throw_non_call_exceptions)
3966 if (side_effects_p (op1))
3967 return simplify_gen_binary (AND, mode, op1, trueop0);
3968 return trueop0;
3970 /* x/1 is x. */
3971 if (trueop1 == CONST1_RTX (mode))
3973 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3974 if (tem)
3975 return tem;
3977 /* Convert divide by power of two into shift. */
3978 if (CONST_INT_P (trueop1)
3979 && (val = exact_log2 (UINTVAL (trueop1))) > 0)
3980 return simplify_gen_binary (LSHIFTRT, mode, op0,
3981 gen_int_shift_amount (mode, val));
3982 break;
3984 case DIV:
3985 /* Handle floating point and integers separately. */
3986 if (SCALAR_FLOAT_MODE_P (mode))
3988 /* Maybe change 0.0 / x to 0.0. This transformation isn't
3989 safe for modes with NaNs, since 0.0 / 0.0 will then be
3990 NaN rather than 0.0. Nor is it safe for modes with signed
3991 zeros, since dividing 0 by a negative number gives -0.0 */
3992 if (trueop0 == CONST0_RTX (mode)
3993 && !HONOR_NANS (mode)
3994 && !HONOR_SIGNED_ZEROS (mode)
3995 && ! side_effects_p (op1))
3996 return op0;
3997 /* x/1.0 is x. */
3998 if (trueop1 == CONST1_RTX (mode)
3999 && !HONOR_SNANS (mode))
4000 return op0;
4002 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4003 && trueop1 != CONST0_RTX (mode))
4005 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4007 /* x/-1.0 is -x. */
4008 if (real_equal (d1, &dconstm1)
4009 && !HONOR_SNANS (mode))
4010 return simplify_gen_unary (NEG, mode, op0, mode);
4012 /* Change FP division by a constant into multiplication.
4013 Only do this with -freciprocal-math. */
4014 if (flag_reciprocal_math
4015 && !real_equal (d1, &dconst0))
4017 REAL_VALUE_TYPE d;
4018 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4019 tem = const_double_from_real_value (d, mode);
4020 return simplify_gen_binary (MULT, mode, op0, tem);
4024 else if (SCALAR_INT_MODE_P (mode))
4026 /* 0/x is 0 (or x&0 if x has side-effects). */
4027 if (trueop0 == CONST0_RTX (mode)
4028 && !cfun->can_throw_non_call_exceptions)
4030 if (side_effects_p (op1))
4031 return simplify_gen_binary (AND, mode, op1, trueop0);
4032 return trueop0;
4034 /* x/1 is x. */
4035 if (trueop1 == CONST1_RTX (mode))
4037 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4038 if (tem)
4039 return tem;
4041 /* x/-1 is -x. */
4042 if (trueop1 == constm1_rtx)
4044 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4045 if (x)
4046 return simplify_gen_unary (NEG, mode, x, mode);
4049 break;
4051 case UMOD:
4052 /* 0%x is 0 (or x&0 if x has side-effects). */
4053 if (trueop0 == CONST0_RTX (mode))
4055 if (side_effects_p (op1))
4056 return simplify_gen_binary (AND, mode, op1, trueop0);
4057 return trueop0;
4059 /* x%1 is 0 (of x&0 if x has side-effects). */
4060 if (trueop1 == CONST1_RTX (mode))
4062 if (side_effects_p (op0))
4063 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4064 return CONST0_RTX (mode);
4066 /* Implement modulus by power of two as AND. */
4067 if (CONST_INT_P (trueop1)
4068 && exact_log2 (UINTVAL (trueop1)) > 0)
4069 return simplify_gen_binary (AND, mode, op0,
4070 gen_int_mode (UINTVAL (trueop1) - 1,
4071 mode));
4072 break;
4074 case MOD:
4075 /* 0%x is 0 (or x&0 if x has side-effects). */
4076 if (trueop0 == CONST0_RTX (mode))
4078 if (side_effects_p (op1))
4079 return simplify_gen_binary (AND, mode, op1, trueop0);
4080 return trueop0;
4082 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4083 if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4085 if (side_effects_p (op0))
4086 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4087 return CONST0_RTX (mode);
4089 break;
4091 case ROTATERT:
4092 case ROTATE:
4093 if (trueop1 == CONST0_RTX (mode))
4094 return op0;
4095 /* Canonicalize rotates by constant amount. If op1 is bitsize / 2,
4096 prefer left rotation, if op1 is from bitsize / 2 + 1 to
4097 bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
4098 amount instead. */
4099 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4100 if (CONST_INT_P (trueop1)
4101 && IN_RANGE (INTVAL (trueop1),
4102 GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
4103 GET_MODE_UNIT_PRECISION (mode) - 1))
4105 int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4106 rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4107 return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4108 mode, op0, new_amount_rtx);
4110 #endif
4111 /* FALLTHRU */
4112 case ASHIFTRT:
4113 if (trueop1 == CONST0_RTX (mode))
4114 return op0;
4115 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4116 return op0;
4117 /* Rotating ~0 always results in ~0. */
4118 if (CONST_INT_P (trueop0)
4119 && HWI_COMPUTABLE_MODE_P (mode)
4120 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4121 && ! side_effects_p (op1))
4122 return op0;
4124 canonicalize_shift:
4125 /* Given:
4126 scalar modes M1, M2
4127 scalar constants c1, c2
4128 size (M2) > size (M1)
4129 c1 == size (M2) - size (M1)
4130 optimize:
4131 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4132 <low_part>)
4133 (const_int <c2>))
4135 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4136 <low_part>). */
4137 if ((code == ASHIFTRT || code == LSHIFTRT)
4138 && is_a <scalar_int_mode> (mode, &int_mode)
4139 && SUBREG_P (op0)
4140 && CONST_INT_P (op1)
4141 && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4142 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4143 &inner_mode)
4144 && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4145 && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4146 && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4147 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4148 && subreg_lowpart_p (op0))
4150 rtx tmp = gen_int_shift_amount
4151 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4153 /* Combine would usually zero out the value when combining two
4154 local shifts and the range becomes larger or equal to the mode.
4155 However since we fold away one of the shifts here combine won't
4156 see it so we should immediately zero the result if it's out of
4157 range. */
4158 if (code == LSHIFTRT
4159 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4160 tmp = const0_rtx;
4161 else
4162 tmp = simplify_gen_binary (code,
4163 inner_mode,
4164 XEXP (SUBREG_REG (op0), 0),
4165 tmp);
4167 return lowpart_subreg (int_mode, tmp, inner_mode);
4170 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4172 val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4173 if (val != INTVAL (op1))
4174 return simplify_gen_binary (code, mode, op0,
4175 gen_int_shift_amount (mode, val));
4177 break;
4179 case SS_ASHIFT:
4180 if (CONST_INT_P (trueop0)
4181 && HWI_COMPUTABLE_MODE_P (mode)
4182 && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4183 || mode_signbit_p (mode, trueop0))
4184 && ! side_effects_p (op1))
4185 return op0;
4186 goto simplify_ashift;
4188 case US_ASHIFT:
4189 if (CONST_INT_P (trueop0)
4190 && HWI_COMPUTABLE_MODE_P (mode)
4191 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4192 && ! side_effects_p (op1))
4193 return op0;
4194 /* FALLTHRU */
4196 case ASHIFT:
4197 simplify_ashift:
4198 if (trueop1 == CONST0_RTX (mode))
4199 return op0;
4200 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4201 return op0;
4202 if (mem_depth
4203 && code == ASHIFT
4204 && CONST_INT_P (trueop1)
4205 && is_a <scalar_int_mode> (mode, &int_mode)
4206 && IN_RANGE (UINTVAL (trueop1),
4207 1, GET_MODE_PRECISION (int_mode) - 1))
4209 auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4210 << UINTVAL (trueop1));
4211 rtx new_op1 = immed_wide_int_const (c, int_mode);
4212 return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4214 goto canonicalize_shift;
4216 case LSHIFTRT:
4217 if (trueop1 == CONST0_RTX (mode))
4218 return op0;
4219 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4220 return op0;
4221 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4222 if (GET_CODE (op0) == CLZ
4223 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4224 && CONST_INT_P (trueop1)
4225 && STORE_FLAG_VALUE == 1
4226 && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4228 unsigned HOST_WIDE_INT zero_val = 0;
4230 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4231 && zero_val == GET_MODE_PRECISION (inner_mode)
4232 && INTVAL (trueop1) == exact_log2 (zero_val))
4233 return simplify_gen_relational (EQ, mode, inner_mode,
4234 XEXP (op0, 0), const0_rtx);
4236 goto canonicalize_shift;
4238 case SMIN:
4239 if (HWI_COMPUTABLE_MODE_P (mode)
4240 && mode_signbit_p (mode, trueop1)
4241 && ! side_effects_p (op0))
4242 return op1;
4243 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4244 return op0;
4245 tem = simplify_associative_operation (code, mode, op0, op1);
4246 if (tem)
4247 return tem;
4248 break;
4250 case SMAX:
4251 if (HWI_COMPUTABLE_MODE_P (mode)
4252 && CONST_INT_P (trueop1)
4253 && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4254 && ! side_effects_p (op0))
4255 return op1;
4256 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4257 return op0;
4258 tem = simplify_associative_operation (code, mode, op0, op1);
4259 if (tem)
4260 return tem;
4261 break;
4263 case UMIN:
4264 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4265 return op1;
4266 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4267 return op0;
4268 tem = simplify_associative_operation (code, mode, op0, op1);
4269 if (tem)
4270 return tem;
4271 break;
4273 case UMAX:
4274 if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4275 return op1;
4276 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4277 return op0;
4278 tem = simplify_associative_operation (code, mode, op0, op1);
4279 if (tem)
4280 return tem;
4281 break;
4283 case SS_PLUS:
4284 case US_PLUS:
4285 case SS_MINUS:
4286 case US_MINUS:
4287 /* Simplify x +/- 0 to x, if possible. */
4288 if (trueop1 == CONST0_RTX (mode))
4289 return op0;
4290 return 0;
4292 case SS_MULT:
4293 case US_MULT:
4294 /* Simplify x * 0 to 0, if possible. */
4295 if (trueop1 == CONST0_RTX (mode)
4296 && !side_effects_p (op0))
4297 return op1;
4299 /* Simplify x * 1 to x, if possible. */
4300 if (trueop1 == CONST1_RTX (mode))
4301 return op0;
4302 return 0;
4304 case SMUL_HIGHPART:
4305 case UMUL_HIGHPART:
4306 /* Simplify x * 0 to 0, if possible. */
4307 if (trueop1 == CONST0_RTX (mode)
4308 && !side_effects_p (op0))
4309 return op1;
4310 return 0;
4312 case SS_DIV:
4313 case US_DIV:
4314 /* Simplify x / 1 to x, if possible. */
4315 if (trueop1 == CONST1_RTX (mode))
4316 return op0;
4317 return 0;
4319 case VEC_SERIES:
4320 if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4321 return gen_vec_duplicate (mode, op0);
4322 if (valid_for_const_vector_p (mode, op0)
4323 && valid_for_const_vector_p (mode, op1))
4324 return gen_const_vec_series (mode, op0, op1);
4325 return 0;
4327 case VEC_SELECT:
4328 if (!VECTOR_MODE_P (mode))
4330 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4331 gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4332 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4333 gcc_assert (XVECLEN (trueop1, 0) == 1);
4335 /* We can't reason about selections made at runtime. */
4336 if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4337 return 0;
4339 if (vec_duplicate_p (trueop0, &elt0))
4340 return elt0;
4342 if (GET_CODE (trueop0) == CONST_VECTOR)
4343 return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4344 (trueop1, 0, 0)));
4346 /* Extract a scalar element from a nested VEC_SELECT expression
4347 (with optional nested VEC_CONCAT expression). Some targets
4348 (i386) extract scalar element from a vector using chain of
4349 nested VEC_SELECT expressions. When input operand is a memory
4350 operand, this operation can be simplified to a simple scalar
4351 load from an offseted memory address. */
4352 int n_elts;
4353 if (GET_CODE (trueop0) == VEC_SELECT
4354 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4355 .is_constant (&n_elts)))
4357 rtx op0 = XEXP (trueop0, 0);
4358 rtx op1 = XEXP (trueop0, 1);
4360 int i = INTVAL (XVECEXP (trueop1, 0, 0));
4361 int elem;
4363 rtvec vec;
4364 rtx tmp_op, tmp;
4366 gcc_assert (GET_CODE (op1) == PARALLEL);
4367 gcc_assert (i < n_elts);
4369 /* Select element, pointed by nested selector. */
4370 elem = INTVAL (XVECEXP (op1, 0, i));
4372 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4373 if (GET_CODE (op0) == VEC_CONCAT)
4375 rtx op00 = XEXP (op0, 0);
4376 rtx op01 = XEXP (op0, 1);
4378 machine_mode mode00, mode01;
4379 int n_elts00, n_elts01;
4381 mode00 = GET_MODE (op00);
4382 mode01 = GET_MODE (op01);
4384 /* Find out the number of elements of each operand.
4385 Since the concatenated result has a constant number
4386 of elements, the operands must too. */
4387 n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4388 n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4390 gcc_assert (n_elts == n_elts00 + n_elts01);
4392 /* Select correct operand of VEC_CONCAT
4393 and adjust selector. */
4394 if (elem < n_elts01)
4395 tmp_op = op00;
4396 else
4398 tmp_op = op01;
4399 elem -= n_elts00;
4402 else
4403 tmp_op = op0;
4405 vec = rtvec_alloc (1);
4406 RTVEC_ELT (vec, 0) = GEN_INT (elem);
4408 tmp = gen_rtx_fmt_ee (code, mode,
4409 tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
4410 return tmp;
4413 else
4415 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4416 gcc_assert (GET_MODE_INNER (mode)
4417 == GET_MODE_INNER (GET_MODE (trueop0)));
4418 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4420 if (vec_duplicate_p (trueop0, &elt0))
4421 /* It doesn't matter which elements are selected by trueop1,
4422 because they are all the same. */
4423 return gen_vec_duplicate (mode, elt0);
4425 if (GET_CODE (trueop0) == CONST_VECTOR)
4427 unsigned n_elts = XVECLEN (trueop1, 0);
4428 rtvec v = rtvec_alloc (n_elts);
4429 unsigned int i;
4431 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4432 for (i = 0; i < n_elts; i++)
4434 rtx x = XVECEXP (trueop1, 0, i);
4436 if (!CONST_INT_P (x))
4437 return 0;
4439 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
4440 INTVAL (x));
4443 return gen_rtx_CONST_VECTOR (mode, v);
4446 /* Recognize the identity. */
4447 if (GET_MODE (trueop0) == mode)
4449 bool maybe_ident = true;
4450 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4452 rtx j = XVECEXP (trueop1, 0, i);
4453 if (!CONST_INT_P (j) || INTVAL (j) != i)
4455 maybe_ident = false;
4456 break;
4459 if (maybe_ident)
4460 return trueop0;
4463 /* If we select a low-part subreg, return that. */
4464 if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
4466 rtx new_rtx = lowpart_subreg (mode, trueop0,
4467 GET_MODE (trueop0));
4468 if (new_rtx != NULL_RTX)
4469 return new_rtx;
4472 /* If we build {a,b} then permute it, build the result directly. */
4473 if (XVECLEN (trueop1, 0) == 2
4474 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4475 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4476 && GET_CODE (trueop0) == VEC_CONCAT
4477 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4478 && GET_MODE (XEXP (trueop0, 0)) == mode
4479 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4480 && GET_MODE (XEXP (trueop0, 1)) == mode)
4482 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4483 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4484 rtx subop0, subop1;
4486 gcc_assert (i0 < 4 && i1 < 4);
4487 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4488 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4490 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4493 if (XVECLEN (trueop1, 0) == 2
4494 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4495 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4496 && GET_CODE (trueop0) == VEC_CONCAT
4497 && GET_MODE (trueop0) == mode)
4499 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4500 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4501 rtx subop0, subop1;
4503 gcc_assert (i0 < 2 && i1 < 2);
4504 subop0 = XEXP (trueop0, i0);
4505 subop1 = XEXP (trueop0, i1);
4507 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4510 /* If we select one half of a vec_concat, return that. */
4511 int l0, l1;
4512 if (GET_CODE (trueop0) == VEC_CONCAT
4513 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4514 .is_constant (&l0))
4515 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4516 .is_constant (&l1))
4517 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4519 rtx subop0 = XEXP (trueop0, 0);
4520 rtx subop1 = XEXP (trueop0, 1);
4521 machine_mode mode0 = GET_MODE (subop0);
4522 machine_mode mode1 = GET_MODE (subop1);
4523 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4524 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4526 bool success = true;
4527 for (int i = 1; i < l0; ++i)
4529 rtx j = XVECEXP (trueop1, 0, i);
4530 if (!CONST_INT_P (j) || INTVAL (j) != i)
4532 success = false;
4533 break;
4536 if (success)
4537 return subop0;
4539 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4541 bool success = true;
4542 for (int i = 1; i < l1; ++i)
4544 rtx j = XVECEXP (trueop1, 0, i);
4545 if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4547 success = false;
4548 break;
4551 if (success)
4552 return subop1;
4556 /* Simplify vec_select of a subreg of X to just a vec_select of X
4557 when X has same component mode as vec_select. */
4558 unsigned HOST_WIDE_INT subreg_offset = 0;
4559 if (GET_CODE (trueop0) == SUBREG
4560 && GET_MODE_INNER (mode)
4561 == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
4562 && GET_MODE_NUNITS (mode).is_constant (&l1)
4563 && constant_multiple_p (subreg_memory_offset (trueop0),
4564 GET_MODE_UNIT_BITSIZE (mode),
4565 &subreg_offset))
4567 poly_uint64 nunits
4568 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
4569 bool success = true;
4570 for (int i = 0; i != l1; i++)
4572 rtx idx = XVECEXP (trueop1, 0, i);
4573 if (!CONST_INT_P (idx)
4574 || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
4576 success = false;
4577 break;
4581 if (success)
4583 rtx par = trueop1;
4584 if (subreg_offset)
4586 rtvec vec = rtvec_alloc (l1);
4587 for (int i = 0; i < l1; i++)
4588 RTVEC_ELT (vec, i)
4589 = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
4590 + subreg_offset);
4591 par = gen_rtx_PARALLEL (VOIDmode, vec);
4593 return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
4598 if (XVECLEN (trueop1, 0) == 1
4599 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4600 && GET_CODE (trueop0) == VEC_CONCAT)
4602 rtx vec = trueop0;
4603 offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4605 /* Try to find the element in the VEC_CONCAT. */
4606 while (GET_MODE (vec) != mode
4607 && GET_CODE (vec) == VEC_CONCAT)
4609 poly_int64 vec_size;
4611 if (CONST_INT_P (XEXP (vec, 0)))
4613 /* vec_concat of two const_ints doesn't make sense with
4614 respect to modes. */
4615 if (CONST_INT_P (XEXP (vec, 1)))
4616 return 0;
4618 vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4619 - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4621 else
4622 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4624 if (known_lt (offset, vec_size))
4625 vec = XEXP (vec, 0);
4626 else if (known_ge (offset, vec_size))
4628 offset -= vec_size;
4629 vec = XEXP (vec, 1);
4631 else
4632 break;
4633 vec = avoid_constant_pool_reference (vec);
4636 if (GET_MODE (vec) == mode)
4637 return vec;
4640 /* If we select elements in a vec_merge that all come from the same
4641 operand, select from that operand directly. */
4642 if (GET_CODE (op0) == VEC_MERGE)
4644 rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4645 if (CONST_INT_P (trueop02))
4647 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4648 bool all_operand0 = true;
4649 bool all_operand1 = true;
4650 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4652 rtx j = XVECEXP (trueop1, 0, i);
4653 if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4654 all_operand1 = false;
4655 else
4656 all_operand0 = false;
4658 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4659 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4660 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4661 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4665 /* If we have two nested selects that are inverses of each
4666 other, replace them with the source operand. */
4667 if (GET_CODE (trueop0) == VEC_SELECT
4668 && GET_MODE (XEXP (trueop0, 0)) == mode)
4670 rtx op0_subop1 = XEXP (trueop0, 1);
4671 gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4672 gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4674 /* Apply the outer ordering vector to the inner one. (The inner
4675 ordering vector is expressly permitted to be of a different
4676 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4677 then the two VEC_SELECTs cancel. */
4678 for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4680 rtx x = XVECEXP (trueop1, 0, i);
4681 if (!CONST_INT_P (x))
4682 return 0;
4683 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4684 if (!CONST_INT_P (y) || i != INTVAL (y))
4685 return 0;
4687 return XEXP (trueop0, 0);
4690 return 0;
4691 case VEC_CONCAT:
4693 machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4694 ? GET_MODE (trueop0)
4695 : GET_MODE_INNER (mode));
4696 machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4697 ? GET_MODE (trueop1)
4698 : GET_MODE_INNER (mode));
4700 gcc_assert (VECTOR_MODE_P (mode));
4701 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4702 + GET_MODE_SIZE (op1_mode),
4703 GET_MODE_SIZE (mode)));
4705 if (VECTOR_MODE_P (op0_mode))
4706 gcc_assert (GET_MODE_INNER (mode)
4707 == GET_MODE_INNER (op0_mode));
4708 else
4709 gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4711 if (VECTOR_MODE_P (op1_mode))
4712 gcc_assert (GET_MODE_INNER (mode)
4713 == GET_MODE_INNER (op1_mode));
4714 else
4715 gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4717 unsigned int n_elts, in_n_elts;
4718 if ((GET_CODE (trueop0) == CONST_VECTOR
4719 || CONST_SCALAR_INT_P (trueop0)
4720 || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4721 && (GET_CODE (trueop1) == CONST_VECTOR
4722 || CONST_SCALAR_INT_P (trueop1)
4723 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4724 && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4725 && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4727 rtvec v = rtvec_alloc (n_elts);
4728 unsigned int i;
4729 for (i = 0; i < n_elts; i++)
4731 if (i < in_n_elts)
4733 if (!VECTOR_MODE_P (op0_mode))
4734 RTVEC_ELT (v, i) = trueop0;
4735 else
4736 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4738 else
4740 if (!VECTOR_MODE_P (op1_mode))
4741 RTVEC_ELT (v, i) = trueop1;
4742 else
4743 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4744 i - in_n_elts);
4748 return gen_rtx_CONST_VECTOR (mode, v);
4751 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4752 Restrict the transformation to avoid generating a VEC_SELECT with a
4753 mode unrelated to its operand. */
4754 if (GET_CODE (trueop0) == VEC_SELECT
4755 && GET_CODE (trueop1) == VEC_SELECT
4756 && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4757 && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
4758 == GET_MODE_INNER(mode))
4760 rtx par0 = XEXP (trueop0, 1);
4761 rtx par1 = XEXP (trueop1, 1);
4762 int len0 = XVECLEN (par0, 0);
4763 int len1 = XVECLEN (par1, 0);
4764 rtvec vec = rtvec_alloc (len0 + len1);
4765 for (int i = 0; i < len0; i++)
4766 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4767 for (int i = 0; i < len1; i++)
4768 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4769 return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4770 gen_rtx_PARALLEL (VOIDmode, vec));
4773 return 0;
4775 default:
4776 gcc_unreachable ();
4779 if (mode == GET_MODE (op0)
4780 && mode == GET_MODE (op1)
4781 && vec_duplicate_p (op0, &elt0)
4782 && vec_duplicate_p (op1, &elt1))
4784 /* Try applying the operator to ELT and see if that simplifies.
4785 We can duplicate the result if so.
4787 The reason we don't use simplify_gen_binary is that it isn't
4788 necessarily a win to convert things like:
4790 (plus:V (vec_duplicate:V (reg:S R1))
4791 (vec_duplicate:V (reg:S R2)))
4795 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4797 The first might be done entirely in vector registers while the
4798 second might need a move between register files. */
4799 tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4800 elt0, elt1);
4801 if (tem)
4802 return gen_vec_duplicate (mode, tem);
4805 return 0;
4808 /* Return true if binary operation OP distributes over addition in operand
4809 OPNO, with the other operand being held constant. OPNO counts from 1. */
4811 static bool
4812 distributes_over_addition_p (rtx_code op, int opno)
4814 switch (op)
4816 case PLUS:
4817 case MINUS:
4818 case MULT:
4819 return true;
4821 case ASHIFT:
4822 return opno == 1;
4824 default:
4825 return false;
4830 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4831 rtx op0, rtx op1)
4833 if (VECTOR_MODE_P (mode)
4834 && code != VEC_CONCAT
4835 && GET_CODE (op0) == CONST_VECTOR
4836 && GET_CODE (op1) == CONST_VECTOR)
4838 bool step_ok_p;
4839 if (CONST_VECTOR_STEPPED_P (op0)
4840 && CONST_VECTOR_STEPPED_P (op1))
4841 /* We can operate directly on the encoding if:
4843 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4844 implies
4845 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4847 Addition and subtraction are the supported operators
4848 for which this is true. */
4849 step_ok_p = (code == PLUS || code == MINUS);
4850 else if (CONST_VECTOR_STEPPED_P (op0))
4851 /* We can operate directly on stepped encodings if:
4853 a3 - a2 == a2 - a1
4854 implies:
4855 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4857 which is true if (x -> x op c) distributes over addition. */
4858 step_ok_p = distributes_over_addition_p (code, 1);
4859 else
4860 /* Similarly in reverse. */
4861 step_ok_p = distributes_over_addition_p (code, 2);
4862 rtx_vector_builder builder;
4863 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4864 return 0;
4866 unsigned int count = builder.encoded_nelts ();
4867 for (unsigned int i = 0; i < count; i++)
4869 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4870 CONST_VECTOR_ELT (op0, i),
4871 CONST_VECTOR_ELT (op1, i));
4872 if (!x || !valid_for_const_vector_p (mode, x))
4873 return 0;
4874 builder.quick_push (x);
4876 return builder.build ();
4879 if (VECTOR_MODE_P (mode)
4880 && code == VEC_CONCAT
4881 && (CONST_SCALAR_INT_P (op0)
4882 || CONST_FIXED_P (op0)
4883 || CONST_DOUBLE_AS_FLOAT_P (op0))
4884 && (CONST_SCALAR_INT_P (op1)
4885 || CONST_DOUBLE_AS_FLOAT_P (op1)
4886 || CONST_FIXED_P (op1)))
4888 /* Both inputs have a constant number of elements, so the result
4889 must too. */
4890 unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4891 rtvec v = rtvec_alloc (n_elts);
4893 gcc_assert (n_elts >= 2);
4894 if (n_elts == 2)
4896 gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4897 gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4899 RTVEC_ELT (v, 0) = op0;
4900 RTVEC_ELT (v, 1) = op1;
4902 else
4904 unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4905 unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4906 unsigned i;
4908 gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4909 gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4910 gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4912 for (i = 0; i < op0_n_elts; ++i)
4913 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4914 for (i = 0; i < op1_n_elts; ++i)
4915 RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4918 return gen_rtx_CONST_VECTOR (mode, v);
4921 if (SCALAR_FLOAT_MODE_P (mode)
4922 && CONST_DOUBLE_AS_FLOAT_P (op0)
4923 && CONST_DOUBLE_AS_FLOAT_P (op1)
4924 && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4926 if (code == AND
4927 || code == IOR
4928 || code == XOR)
4930 long tmp0[4];
4931 long tmp1[4];
4932 REAL_VALUE_TYPE r;
4933 int i;
4935 real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4936 GET_MODE (op0));
4937 real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4938 GET_MODE (op1));
4939 for (i = 0; i < 4; i++)
4941 switch (code)
4943 case AND:
4944 tmp0[i] &= tmp1[i];
4945 break;
4946 case IOR:
4947 tmp0[i] |= tmp1[i];
4948 break;
4949 case XOR:
4950 tmp0[i] ^= tmp1[i];
4951 break;
4952 default:
4953 gcc_unreachable ();
4956 real_from_target (&r, tmp0, mode);
4957 return const_double_from_real_value (r, mode);
4959 else
4961 REAL_VALUE_TYPE f0, f1, value, result;
4962 const REAL_VALUE_TYPE *opr0, *opr1;
4963 bool inexact;
4965 opr0 = CONST_DOUBLE_REAL_VALUE (op0);
4966 opr1 = CONST_DOUBLE_REAL_VALUE (op1);
4968 if (HONOR_SNANS (mode)
4969 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
4970 || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
4971 return 0;
4973 real_convert (&f0, mode, opr0);
4974 real_convert (&f1, mode, opr1);
4976 if (code == DIV
4977 && real_equal (&f1, &dconst0)
4978 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
4979 return 0;
4981 if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4982 && flag_trapping_math
4983 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
4985 int s0 = REAL_VALUE_NEGATIVE (f0);
4986 int s1 = REAL_VALUE_NEGATIVE (f1);
4988 switch (code)
4990 case PLUS:
4991 /* Inf + -Inf = NaN plus exception. */
4992 if (s0 != s1)
4993 return 0;
4994 break;
4995 case MINUS:
4996 /* Inf - Inf = NaN plus exception. */
4997 if (s0 == s1)
4998 return 0;
4999 break;
5000 case DIV:
5001 /* Inf / Inf = NaN plus exception. */
5002 return 0;
5003 default:
5004 break;
5008 if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5009 && flag_trapping_math
5010 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5011 || (REAL_VALUE_ISINF (f1)
5012 && real_equal (&f0, &dconst0))))
5013 /* Inf * 0 = NaN plus exception. */
5014 return 0;
5016 inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5017 &f0, &f1);
5018 real_convert (&result, mode, &value);
5020 /* Don't constant fold this floating point operation if
5021 the result has overflowed and flag_trapping_math. */
5023 if (flag_trapping_math
5024 && MODE_HAS_INFINITIES (mode)
5025 && REAL_VALUE_ISINF (result)
5026 && !REAL_VALUE_ISINF (f0)
5027 && !REAL_VALUE_ISINF (f1))
5028 /* Overflow plus exception. */
5029 return 0;
5031 /* Don't constant fold this floating point operation if the
5032 result may dependent upon the run-time rounding mode and
5033 flag_rounding_math is set, or if GCC's software emulation
5034 is unable to accurately represent the result. */
5036 if ((flag_rounding_math
5037 || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5038 && (inexact || !real_identical (&result, &value)))
5039 return NULL_RTX;
5041 return const_double_from_real_value (result, mode);
5045 /* We can fold some multi-word operations. */
5046 scalar_int_mode int_mode;
5047 if (is_a <scalar_int_mode> (mode, &int_mode)
5048 && CONST_SCALAR_INT_P (op0)
5049 && CONST_SCALAR_INT_P (op1)
5050 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5052 wide_int result;
5053 wi::overflow_type overflow;
5054 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5055 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5057 #if TARGET_SUPPORTS_WIDE_INT == 0
5058 /* This assert keeps the simplification from producing a result
5059 that cannot be represented in a CONST_DOUBLE but a lot of
5060 upstream callers expect that this function never fails to
5061 simplify something and so you if you added this to the test
5062 above the code would die later anyway. If this assert
5063 happens, you just need to make the port support wide int. */
5064 gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5065 #endif
5066 switch (code)
5068 case MINUS:
5069 result = wi::sub (pop0, pop1);
5070 break;
5072 case PLUS:
5073 result = wi::add (pop0, pop1);
5074 break;
5076 case MULT:
5077 result = wi::mul (pop0, pop1);
5078 break;
5080 case DIV:
5081 result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5082 if (overflow)
5083 return NULL_RTX;
5084 break;
5086 case MOD:
5087 result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5088 if (overflow)
5089 return NULL_RTX;
5090 break;
5092 case UDIV:
5093 result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5094 if (overflow)
5095 return NULL_RTX;
5096 break;
5098 case UMOD:
5099 result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5100 if (overflow)
5101 return NULL_RTX;
5102 break;
5104 case AND:
5105 result = wi::bit_and (pop0, pop1);
5106 break;
5108 case IOR:
5109 result = wi::bit_or (pop0, pop1);
5110 break;
5112 case XOR:
5113 result = wi::bit_xor (pop0, pop1);
5114 break;
5116 case SMIN:
5117 result = wi::smin (pop0, pop1);
5118 break;
5120 case SMAX:
5121 result = wi::smax (pop0, pop1);
5122 break;
5124 case UMIN:
5125 result = wi::umin (pop0, pop1);
5126 break;
5128 case UMAX:
5129 result = wi::umax (pop0, pop1);
5130 break;
5132 case LSHIFTRT:
5133 case ASHIFTRT:
5134 case ASHIFT:
5135 case SS_ASHIFT:
5136 case US_ASHIFT:
5138 /* The shift count might be in SImode while int_mode might
5139 be narrower. On IA-64 it is even DImode. If the shift
5140 count is too large and doesn't fit into int_mode, we'd
5141 ICE. So, if int_mode is narrower than word, use
5142 word_mode for the shift count. */
5143 if (GET_MODE (op1) == VOIDmode
5144 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5145 pop1 = rtx_mode_t (op1, word_mode);
5147 wide_int wop1 = pop1;
5148 if (SHIFT_COUNT_TRUNCATED)
5149 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
5150 else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
5151 return NULL_RTX;
5153 switch (code)
5155 case LSHIFTRT:
5156 result = wi::lrshift (pop0, wop1);
5157 break;
5159 case ASHIFTRT:
5160 result = wi::arshift (pop0, wop1);
5161 break;
5163 case ASHIFT:
5164 result = wi::lshift (pop0, wop1);
5165 break;
5167 case SS_ASHIFT:
5168 if (wi::leu_p (wop1, wi::clrsb (pop0)))
5169 result = wi::lshift (pop0, wop1);
5170 else if (wi::neg_p (pop0))
5171 result = wi::min_value (int_mode, SIGNED);
5172 else
5173 result = wi::max_value (int_mode, SIGNED);
5174 break;
5176 case US_ASHIFT:
5177 if (wi::eq_p (pop0, 0))
5178 result = pop0;
5179 else if (wi::leu_p (wop1, wi::clz (pop0)))
5180 result = wi::lshift (pop0, wop1);
5181 else
5182 result = wi::max_value (int_mode, UNSIGNED);
5183 break;
5185 default:
5186 gcc_unreachable ();
5188 break;
5190 case ROTATE:
5191 case ROTATERT:
5193 /* The rotate count might be in SImode while int_mode might
5194 be narrower. On IA-64 it is even DImode. If the shift
5195 count is too large and doesn't fit into int_mode, we'd
5196 ICE. So, if int_mode is narrower than word, use
5197 word_mode for the shift count. */
5198 if (GET_MODE (op1) == VOIDmode
5199 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5200 pop1 = rtx_mode_t (op1, word_mode);
5202 if (wi::neg_p (pop1))
5203 return NULL_RTX;
5205 switch (code)
5207 case ROTATE:
5208 result = wi::lrotate (pop0, pop1);
5209 break;
5211 case ROTATERT:
5212 result = wi::rrotate (pop0, pop1);
5213 break;
5215 default:
5216 gcc_unreachable ();
5218 break;
5221 case SS_PLUS:
5222 result = wi::add (pop0, pop1, SIGNED, &overflow);
5223 clamp_signed_saturation:
5224 if (overflow == wi::OVF_OVERFLOW)
5225 result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
5226 else if (overflow == wi::OVF_UNDERFLOW)
5227 result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
5228 else if (overflow != wi::OVF_NONE)
5229 return NULL_RTX;
5230 break;
5232 case US_PLUS:
5233 result = wi::add (pop0, pop1, UNSIGNED, &overflow);
5234 clamp_unsigned_saturation:
5235 if (overflow != wi::OVF_NONE)
5236 result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5237 break;
5239 case SS_MINUS:
5240 result = wi::sub (pop0, pop1, SIGNED, &overflow);
5241 goto clamp_signed_saturation;
5243 case US_MINUS:
5244 result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
5245 if (overflow != wi::OVF_NONE)
5246 result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5247 break;
5249 case SS_MULT:
5250 result = wi::mul (pop0, pop1, SIGNED, &overflow);
5251 goto clamp_signed_saturation;
5253 case US_MULT:
5254 result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
5255 goto clamp_unsigned_saturation;
5257 case SMUL_HIGHPART:
5258 result = wi::mul_high (pop0, pop1, SIGNED);
5259 break;
5261 case UMUL_HIGHPART:
5262 result = wi::mul_high (pop0, pop1, UNSIGNED);
5263 break;
5265 default:
5266 return NULL_RTX;
5268 return immed_wide_int_const (result, int_mode);
5271 /* Handle polynomial integers. */
5272 if (NUM_POLY_INT_COEFFS > 1
5273 && is_a <scalar_int_mode> (mode, &int_mode)
5274 && poly_int_rtx_p (op0)
5275 && poly_int_rtx_p (op1))
5277 poly_wide_int result;
5278 switch (code)
5280 case PLUS:
5281 result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
5282 break;
5284 case MINUS:
5285 result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
5286 break;
5288 case MULT:
5289 if (CONST_SCALAR_INT_P (op1))
5290 result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
5291 else
5292 return NULL_RTX;
5293 break;
5295 case ASHIFT:
5296 if (CONST_SCALAR_INT_P (op1))
5298 wide_int shift
5299 = rtx_mode_t (op1,
5300 GET_MODE (op1) == VOIDmode
5301 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
5302 ? word_mode : mode);
5303 if (SHIFT_COUNT_TRUNCATED)
5304 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
5305 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
5306 return NULL_RTX;
5307 result = wi::to_poly_wide (op0, mode) << shift;
5309 else
5310 return NULL_RTX;
5311 break;
5313 case IOR:
5314 if (!CONST_SCALAR_INT_P (op1)
5315 || !can_ior_p (wi::to_poly_wide (op0, mode),
5316 rtx_mode_t (op1, mode), &result))
5317 return NULL_RTX;
5318 break;
5320 default:
5321 return NULL_RTX;
5323 return immed_wide_int_const (result, int_mode);
5326 return NULL_RTX;
5331 /* Return a positive integer if X should sort after Y. The value
5332 returned is 1 if and only if X and Y are both regs. */
5334 static int
5335 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
5337 int result;
5339 result = (commutative_operand_precedence (y)
5340 - commutative_operand_precedence (x));
5341 if (result)
5342 return result + result;
5344 /* Group together equal REGs to do more simplification. */
5345 if (REG_P (x) && REG_P (y))
5346 return REGNO (x) > REGNO (y);
5348 return 0;
5351 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5352 operands may be another PLUS or MINUS.
5354 Rather than test for specific case, we do this by a brute-force method
5355 and do all possible simplifications until no more changes occur. Then
5356 we rebuild the operation.
5358 May return NULL_RTX when no changes were made. */
5361 simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
5362 rtx op0, rtx op1)
5364 struct simplify_plus_minus_op_data
5366 rtx op;
5367 short neg;
5368 } ops[16];
5369 rtx result, tem;
5370 int n_ops = 2;
5371 int changed, n_constants, canonicalized = 0;
5372 int i, j;
5374 memset (ops, 0, sizeof ops);
5376 /* Set up the two operands and then expand them until nothing has been
5377 changed. If we run out of room in our array, give up; this should
5378 almost never happen. */
5380 ops[0].op = op0;
5381 ops[0].neg = 0;
5382 ops[1].op = op1;
5383 ops[1].neg = (code == MINUS);
5387 changed = 0;
5388 n_constants = 0;
5390 for (i = 0; i < n_ops; i++)
5392 rtx this_op = ops[i].op;
5393 int this_neg = ops[i].neg;
5394 enum rtx_code this_code = GET_CODE (this_op);
5396 switch (this_code)
5398 case PLUS:
5399 case MINUS:
5400 if (n_ops == ARRAY_SIZE (ops))
5401 return NULL_RTX;
5403 ops[n_ops].op = XEXP (this_op, 1);
5404 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
5405 n_ops++;
5407 ops[i].op = XEXP (this_op, 0);
5408 changed = 1;
5409 /* If this operand was negated then we will potentially
5410 canonicalize the expression. Similarly if we don't
5411 place the operands adjacent we're re-ordering the
5412 expression and thus might be performing a
5413 canonicalization. Ignore register re-ordering.
5414 ??? It might be better to shuffle the ops array here,
5415 but then (plus (plus (A, B), plus (C, D))) wouldn't
5416 be seen as non-canonical. */
5417 if (this_neg
5418 || (i != n_ops - 2
5419 && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
5420 canonicalized = 1;
5421 break;
5423 case NEG:
5424 ops[i].op = XEXP (this_op, 0);
5425 ops[i].neg = ! this_neg;
5426 changed = 1;
5427 canonicalized = 1;
5428 break;
5430 case CONST:
5431 if (n_ops != ARRAY_SIZE (ops)
5432 && GET_CODE (XEXP (this_op, 0)) == PLUS
5433 && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
5434 && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
5436 ops[i].op = XEXP (XEXP (this_op, 0), 0);
5437 ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
5438 ops[n_ops].neg = this_neg;
5439 n_ops++;
5440 changed = 1;
5441 canonicalized = 1;
5443 break;
5445 case NOT:
5446 /* ~a -> (-a - 1) */
5447 if (n_ops != ARRAY_SIZE (ops))
5449 ops[n_ops].op = CONSTM1_RTX (mode);
5450 ops[n_ops++].neg = this_neg;
5451 ops[i].op = XEXP (this_op, 0);
5452 ops[i].neg = !this_neg;
5453 changed = 1;
5454 canonicalized = 1;
5456 break;
5458 CASE_CONST_SCALAR_INT:
5459 case CONST_POLY_INT:
5460 n_constants++;
5461 if (this_neg)
5463 ops[i].op = neg_poly_int_rtx (mode, this_op);
5464 ops[i].neg = 0;
5465 changed = 1;
5466 canonicalized = 1;
5468 break;
5470 default:
5471 break;
5475 while (changed);
5477 if (n_constants > 1)
5478 canonicalized = 1;
5480 gcc_assert (n_ops >= 2);
5482 /* If we only have two operands, we can avoid the loops. */
5483 if (n_ops == 2)
5485 enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
5486 rtx lhs, rhs;
5488 /* Get the two operands. Be careful with the order, especially for
5489 the cases where code == MINUS. */
5490 if (ops[0].neg && ops[1].neg)
5492 lhs = gen_rtx_NEG (mode, ops[0].op);
5493 rhs = ops[1].op;
5495 else if (ops[0].neg)
5497 lhs = ops[1].op;
5498 rhs = ops[0].op;
5500 else
5502 lhs = ops[0].op;
5503 rhs = ops[1].op;
5506 return simplify_const_binary_operation (code, mode, lhs, rhs);
5509 /* Now simplify each pair of operands until nothing changes. */
5510 while (1)
5512 /* Insertion sort is good enough for a small array. */
5513 for (i = 1; i < n_ops; i++)
5515 struct simplify_plus_minus_op_data save;
5516 int cmp;
5518 j = i - 1;
5519 cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
5520 if (cmp <= 0)
5521 continue;
5522 /* Just swapping registers doesn't count as canonicalization. */
5523 if (cmp != 1)
5524 canonicalized = 1;
5526 save = ops[i];
5528 ops[j + 1] = ops[j];
5529 while (j--
5530 && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
5531 ops[j + 1] = save;
5534 changed = 0;
5535 for (i = n_ops - 1; i > 0; i--)
5536 for (j = i - 1; j >= 0; j--)
5538 rtx lhs = ops[j].op, rhs = ops[i].op;
5539 int lneg = ops[j].neg, rneg = ops[i].neg;
5541 if (lhs != 0 && rhs != 0)
5543 enum rtx_code ncode = PLUS;
5545 if (lneg != rneg)
5547 ncode = MINUS;
5548 if (lneg)
5549 std::swap (lhs, rhs);
5551 else if (swap_commutative_operands_p (lhs, rhs))
5552 std::swap (lhs, rhs);
5554 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
5555 && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
5557 rtx tem_lhs, tem_rhs;
5559 tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
5560 tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
5561 tem = simplify_binary_operation (ncode, mode, tem_lhs,
5562 tem_rhs);
5564 if (tem && !CONSTANT_P (tem))
5565 tem = gen_rtx_CONST (GET_MODE (tem), tem);
5567 else
5568 tem = simplify_binary_operation (ncode, mode, lhs, rhs);
5570 if (tem)
5572 /* Reject "simplifications" that just wrap the two
5573 arguments in a CONST. Failure to do so can result
5574 in infinite recursion with simplify_binary_operation
5575 when it calls us to simplify CONST operations.
5576 Also, if we find such a simplification, don't try
5577 any more combinations with this rhs: We must have
5578 something like symbol+offset, ie. one of the
5579 trivial CONST expressions we handle later. */
5580 if (GET_CODE (tem) == CONST
5581 && GET_CODE (XEXP (tem, 0)) == ncode
5582 && XEXP (XEXP (tem, 0), 0) == lhs
5583 && XEXP (XEXP (tem, 0), 1) == rhs)
5584 break;
5585 lneg &= rneg;
5586 if (GET_CODE (tem) == NEG)
5587 tem = XEXP (tem, 0), lneg = !lneg;
5588 if (poly_int_rtx_p (tem) && lneg)
5589 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
5591 ops[i].op = tem;
5592 ops[i].neg = lneg;
5593 ops[j].op = NULL_RTX;
5594 changed = 1;
5595 canonicalized = 1;
5600 if (!changed)
5601 break;
5603 /* Pack all the operands to the lower-numbered entries. */
5604 for (i = 0, j = 0; j < n_ops; j++)
5605 if (ops[j].op)
5607 ops[i] = ops[j];
5608 i++;
5610 n_ops = i;
5613 /* If nothing changed, check that rematerialization of rtl instructions
5614 is still required. */
5615 if (!canonicalized)
5617 /* Perform rematerialization if only all operands are registers and
5618 all operations are PLUS. */
5619 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5620 around rs6000 and how it uses the CA register. See PR67145. */
5621 for (i = 0; i < n_ops; i++)
5622 if (ops[i].neg
5623 || !REG_P (ops[i].op)
5624 || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5625 && fixed_regs[REGNO (ops[i].op)]
5626 && !global_regs[REGNO (ops[i].op)]
5627 && ops[i].op != frame_pointer_rtx
5628 && ops[i].op != arg_pointer_rtx
5629 && ops[i].op != stack_pointer_rtx))
5630 return NULL_RTX;
5631 goto gen_result;
5634 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5635 if (n_ops == 2
5636 && CONST_INT_P (ops[1].op)
5637 && CONSTANT_P (ops[0].op)
5638 && ops[0].neg)
5639 return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5641 /* We suppressed creation of trivial CONST expressions in the
5642 combination loop to avoid recursion. Create one manually now.
5643 The combination loop should have ensured that there is exactly
5644 one CONST_INT, and the sort will have ensured that it is last
5645 in the array and that any other constant will be next-to-last. */
5647 if (n_ops > 1
5648 && poly_int_rtx_p (ops[n_ops - 1].op)
5649 && CONSTANT_P (ops[n_ops - 2].op))
5651 rtx value = ops[n_ops - 1].op;
5652 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5653 value = neg_poly_int_rtx (mode, value);
5654 if (CONST_INT_P (value))
5656 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5657 INTVAL (value));
5658 n_ops--;
5662 /* Put a non-negated operand first, if possible. */
5664 for (i = 0; i < n_ops && ops[i].neg; i++)
5665 continue;
5666 if (i == n_ops)
5667 ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5668 else if (i != 0)
5670 tem = ops[0].op;
5671 ops[0] = ops[i];
5672 ops[i].op = tem;
5673 ops[i].neg = 1;
5676 /* Now make the result by performing the requested operations. */
5677 gen_result:
5678 result = ops[0].op;
5679 for (i = 1; i < n_ops; i++)
5680 result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5681 mode, result, ops[i].op);
5683 return result;
5686 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5687 static bool
5688 plus_minus_operand_p (const_rtx x)
5690 return GET_CODE (x) == PLUS
5691 || GET_CODE (x) == MINUS
5692 || (GET_CODE (x) == CONST
5693 && GET_CODE (XEXP (x, 0)) == PLUS
5694 && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5695 && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5698 /* Like simplify_binary_operation except used for relational operators.
5699 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5700 not also be VOIDmode.
5702 CMP_MODE specifies in which mode the comparison is done in, so it is
5703 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5704 the operands or, if both are VOIDmode, the operands are compared in
5705 "infinite precision". */
5707 simplify_context::simplify_relational_operation (rtx_code code,
5708 machine_mode mode,
5709 machine_mode cmp_mode,
5710 rtx op0, rtx op1)
5712 rtx tem, trueop0, trueop1;
5714 if (cmp_mode == VOIDmode)
5715 cmp_mode = GET_MODE (op0);
5716 if (cmp_mode == VOIDmode)
5717 cmp_mode = GET_MODE (op1);
5719 tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5720 if (tem)
5721 return relational_result (mode, cmp_mode, tem);
5723 /* For the following tests, ensure const0_rtx is op1. */
5724 if (swap_commutative_operands_p (op0, op1)
5725 || (op0 == const0_rtx && op1 != const0_rtx))
5726 std::swap (op0, op1), code = swap_condition (code);
5728 /* If op0 is a compare, extract the comparison arguments from it. */
5729 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5730 return simplify_gen_relational (code, mode, VOIDmode,
5731 XEXP (op0, 0), XEXP (op0, 1));
5733 if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
5734 return NULL_RTX;
5736 trueop0 = avoid_constant_pool_reference (op0);
5737 trueop1 = avoid_constant_pool_reference (op1);
5738 return simplify_relational_operation_1 (code, mode, cmp_mode,
5739 trueop0, trueop1);
5742 /* This part of simplify_relational_operation is only used when CMP_MODE
5743 is not in class MODE_CC (i.e. it is a real comparison).
5745 MODE is the mode of the result, while CMP_MODE specifies in which
5746 mode the comparison is done in, so it is the mode of the operands. */
5749 simplify_context::simplify_relational_operation_1 (rtx_code code,
5750 machine_mode mode,
5751 machine_mode cmp_mode,
5752 rtx op0, rtx op1)
5754 enum rtx_code op0code = GET_CODE (op0);
5756 if (op1 == const0_rtx && COMPARISON_P (op0))
5758 /* If op0 is a comparison, extract the comparison arguments
5759 from it. */
5760 if (code == NE)
5762 if (GET_MODE (op0) == mode)
5763 return simplify_rtx (op0);
5764 else
5765 return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5766 XEXP (op0, 0), XEXP (op0, 1));
5768 else if (code == EQ)
5770 enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5771 if (new_code != UNKNOWN)
5772 return simplify_gen_relational (new_code, mode, VOIDmode,
5773 XEXP (op0, 0), XEXP (op0, 1));
5777 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5778 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5779 if ((code == LTU || code == GEU)
5780 && GET_CODE (op0) == PLUS
5781 && CONST_INT_P (XEXP (op0, 1))
5782 && (rtx_equal_p (op1, XEXP (op0, 0))
5783 || rtx_equal_p (op1, XEXP (op0, 1)))
5784 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5785 && XEXP (op0, 1) != const0_rtx)
5787 rtx new_cmp
5788 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5789 return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5790 cmp_mode, XEXP (op0, 0), new_cmp);
5793 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5794 transformed into (LTU a -C). */
5795 if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5796 && CONST_INT_P (XEXP (op0, 1))
5797 && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5798 && XEXP (op0, 1) != const0_rtx)
5800 rtx new_cmp
5801 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5802 return simplify_gen_relational (LTU, mode, cmp_mode,
5803 XEXP (op0, 0), new_cmp);
5806 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5807 if ((code == LTU || code == GEU)
5808 && GET_CODE (op0) == PLUS
5809 && rtx_equal_p (op1, XEXP (op0, 1))
5810 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5811 && !rtx_equal_p (op1, XEXP (op0, 0)))
5812 return simplify_gen_relational (code, mode, cmp_mode, op0,
5813 copy_rtx (XEXP (op0, 0)));
5815 if (op1 == const0_rtx)
5817 /* Canonicalize (GTU x 0) as (NE x 0). */
5818 if (code == GTU)
5819 return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5820 /* Canonicalize (LEU x 0) as (EQ x 0). */
5821 if (code == LEU)
5822 return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5824 else if (op1 == const1_rtx)
5826 switch (code)
5828 case GE:
5829 /* Canonicalize (GE x 1) as (GT x 0). */
5830 return simplify_gen_relational (GT, mode, cmp_mode,
5831 op0, const0_rtx);
5832 case GEU:
5833 /* Canonicalize (GEU x 1) as (NE x 0). */
5834 return simplify_gen_relational (NE, mode, cmp_mode,
5835 op0, const0_rtx);
5836 case LT:
5837 /* Canonicalize (LT x 1) as (LE x 0). */
5838 return simplify_gen_relational (LE, mode, cmp_mode,
5839 op0, const0_rtx);
5840 case LTU:
5841 /* Canonicalize (LTU x 1) as (EQ x 0). */
5842 return simplify_gen_relational (EQ, mode, cmp_mode,
5843 op0, const0_rtx);
5844 default:
5845 break;
5848 else if (op1 == constm1_rtx)
5850 /* Canonicalize (LE x -1) as (LT x 0). */
5851 if (code == LE)
5852 return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5853 /* Canonicalize (GT x -1) as (GE x 0). */
5854 if (code == GT)
5855 return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5858 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5859 if ((code == EQ || code == NE)
5860 && (op0code == PLUS || op0code == MINUS)
5861 && CONSTANT_P (op1)
5862 && CONSTANT_P (XEXP (op0, 1))
5863 && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5865 rtx x = XEXP (op0, 0);
5866 rtx c = XEXP (op0, 1);
5867 enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5868 rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5870 /* Detect an infinite recursive condition, where we oscillate at this
5871 simplification case between:
5872 A + B == C <---> C - B == A,
5873 where A, B, and C are all constants with non-simplifiable expressions,
5874 usually SYMBOL_REFs. */
5875 if (GET_CODE (tem) == invcode
5876 && CONSTANT_P (x)
5877 && rtx_equal_p (c, XEXP (tem, 1)))
5878 return NULL_RTX;
5880 return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5883 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5884 the same as (zero_extract:SI FOO (const_int 1) BAR). */
5885 scalar_int_mode int_mode, int_cmp_mode;
5886 if (code == NE
5887 && op1 == const0_rtx
5888 && is_int_mode (mode, &int_mode)
5889 && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5890 /* ??? Work-around BImode bugs in the ia64 backend. */
5891 && int_mode != BImode
5892 && int_cmp_mode != BImode
5893 && nonzero_bits (op0, int_cmp_mode) == 1
5894 && STORE_FLAG_VALUE == 1)
5895 return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5896 ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5897 : lowpart_subreg (int_mode, op0, int_cmp_mode);
5899 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
5900 if ((code == EQ || code == NE)
5901 && op1 == const0_rtx
5902 && op0code == XOR)
5903 return simplify_gen_relational (code, mode, cmp_mode,
5904 XEXP (op0, 0), XEXP (op0, 1));
5906 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
5907 if ((code == EQ || code == NE)
5908 && op0code == XOR
5909 && rtx_equal_p (XEXP (op0, 0), op1)
5910 && !side_effects_p (XEXP (op0, 0)))
5911 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5912 CONST0_RTX (mode));
5914 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
5915 if ((code == EQ || code == NE)
5916 && op0code == XOR
5917 && rtx_equal_p (XEXP (op0, 1), op1)
5918 && !side_effects_p (XEXP (op0, 1)))
5919 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5920 CONST0_RTX (mode));
5922 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
5923 if ((code == EQ || code == NE)
5924 && op0code == XOR
5925 && CONST_SCALAR_INT_P (op1)
5926 && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5927 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5928 simplify_gen_binary (XOR, cmp_mode,
5929 XEXP (op0, 1), op1));
5931 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5932 constant folding if x/y is a constant. */
5933 if ((code == EQ || code == NE)
5934 && (op0code == AND || op0code == IOR)
5935 && !side_effects_p (op1)
5936 && op1 != CONST0_RTX (cmp_mode))
5938 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5939 (eq/ne (and (not y) x) 0). */
5940 if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5941 || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5943 rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5944 cmp_mode);
5945 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5947 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5948 CONST0_RTX (cmp_mode));
5951 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5952 (eq/ne (and (not x) y) 0). */
5953 if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5954 || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5956 rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5957 cmp_mode);
5958 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
5960 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5961 CONST0_RTX (cmp_mode));
5965 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
5966 if ((code == EQ || code == NE)
5967 && GET_CODE (op0) == BSWAP
5968 && CONST_SCALAR_INT_P (op1))
5969 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5970 simplify_gen_unary (BSWAP, cmp_mode,
5971 op1, cmp_mode));
5973 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
5974 if ((code == EQ || code == NE)
5975 && GET_CODE (op0) == BSWAP
5976 && GET_CODE (op1) == BSWAP)
5977 return simplify_gen_relational (code, mode, cmp_mode,
5978 XEXP (op0, 0), XEXP (op1, 0));
5980 if (op0code == POPCOUNT && op1 == const0_rtx)
5981 switch (code)
5983 case EQ:
5984 case LE:
5985 case LEU:
5986 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
5987 return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
5988 XEXP (op0, 0), const0_rtx);
5990 case NE:
5991 case GT:
5992 case GTU:
5993 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
5994 return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
5995 XEXP (op0, 0), const0_rtx);
5997 default:
5998 break;
6001 return NULL_RTX;
6004 enum
6006 CMP_EQ = 1,
6007 CMP_LT = 2,
6008 CMP_GT = 4,
6009 CMP_LTU = 8,
6010 CMP_GTU = 16
6014 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6015 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6016 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6017 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6018 For floating-point comparisons, assume that the operands were ordered. */
6020 static rtx
6021 comparison_result (enum rtx_code code, int known_results)
6023 switch (code)
6025 case EQ:
6026 case UNEQ:
6027 return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
6028 case NE:
6029 case LTGT:
6030 return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
6032 case LT:
6033 case UNLT:
6034 return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
6035 case GE:
6036 case UNGE:
6037 return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
6039 case GT:
6040 case UNGT:
6041 return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
6042 case LE:
6043 case UNLE:
6044 return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
6046 case LTU:
6047 return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
6048 case GEU:
6049 return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
6051 case GTU:
6052 return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
6053 case LEU:
6054 return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
6056 case ORDERED:
6057 return const_true_rtx;
6058 case UNORDERED:
6059 return const0_rtx;
6060 default:
6061 gcc_unreachable ();
6065 /* Check if the given comparison (done in the given MODE) is actually
6066 a tautology or a contradiction. If the mode is VOIDmode, the
6067 comparison is done in "infinite precision". If no simplification
6068 is possible, this function returns zero. Otherwise, it returns
6069 either const_true_rtx or const0_rtx. */
6072 simplify_const_relational_operation (enum rtx_code code,
6073 machine_mode mode,
6074 rtx op0, rtx op1)
6076 rtx tem;
6077 rtx trueop0;
6078 rtx trueop1;
6080 gcc_assert (mode != VOIDmode
6081 || (GET_MODE (op0) == VOIDmode
6082 && GET_MODE (op1) == VOIDmode));
6084 /* If op0 is a compare, extract the comparison arguments from it. */
6085 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6087 op1 = XEXP (op0, 1);
6088 op0 = XEXP (op0, 0);
6090 if (GET_MODE (op0) != VOIDmode)
6091 mode = GET_MODE (op0);
6092 else if (GET_MODE (op1) != VOIDmode)
6093 mode = GET_MODE (op1);
6094 else
6095 return 0;
6098 /* We can't simplify MODE_CC values since we don't know what the
6099 actual comparison is. */
6100 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
6101 return 0;
6103 /* Make sure the constant is second. */
6104 if (swap_commutative_operands_p (op0, op1))
6106 std::swap (op0, op1);
6107 code = swap_condition (code);
6110 trueop0 = avoid_constant_pool_reference (op0);
6111 trueop1 = avoid_constant_pool_reference (op1);
6113 /* For integer comparisons of A and B maybe we can simplify A - B and can
6114 then simplify a comparison of that with zero. If A and B are both either
6115 a register or a CONST_INT, this can't help; testing for these cases will
6116 prevent infinite recursion here and speed things up.
6118 We can only do this for EQ and NE comparisons as otherwise we may
6119 lose or introduce overflow which we cannot disregard as undefined as
6120 we do not know the signedness of the operation on either the left or
6121 the right hand side of the comparison. */
6123 if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
6124 && (code == EQ || code == NE)
6125 && ! ((REG_P (op0) || CONST_INT_P (trueop0))
6126 && (REG_P (op1) || CONST_INT_P (trueop1)))
6127 && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
6128 /* We cannot do this if tem is a nonzero address. */
6129 && ! nonzero_address_p (tem))
6130 return simplify_const_relational_operation (signed_condition (code),
6131 mode, tem, const0_rtx);
6133 if (! HONOR_NANS (mode) && code == ORDERED)
6134 return const_true_rtx;
6136 if (! HONOR_NANS (mode) && code == UNORDERED)
6137 return const0_rtx;
6139 /* For modes without NaNs, if the two operands are equal, we know the
6140 result except if they have side-effects. Even with NaNs we know
6141 the result of unordered comparisons and, if signaling NaNs are
6142 irrelevant, also the result of LT/GT/LTGT. */
6143 if ((! HONOR_NANS (trueop0)
6144 || code == UNEQ || code == UNLE || code == UNGE
6145 || ((code == LT || code == GT || code == LTGT)
6146 && ! HONOR_SNANS (trueop0)))
6147 && rtx_equal_p (trueop0, trueop1)
6148 && ! side_effects_p (trueop0))
6149 return comparison_result (code, CMP_EQ);
6151 /* If the operands are floating-point constants, see if we can fold
6152 the result. */
6153 if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
6154 && CONST_DOUBLE_AS_FLOAT_P (trueop1)
6155 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
6157 const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
6158 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
6160 /* Comparisons are unordered iff at least one of the values is NaN. */
6161 if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
6162 switch (code)
6164 case UNEQ:
6165 case UNLT:
6166 case UNGT:
6167 case UNLE:
6168 case UNGE:
6169 case NE:
6170 case UNORDERED:
6171 return const_true_rtx;
6172 case EQ:
6173 case LT:
6174 case GT:
6175 case LE:
6176 case GE:
6177 case LTGT:
6178 case ORDERED:
6179 return const0_rtx;
6180 default:
6181 return 0;
6184 return comparison_result (code,
6185 (real_equal (d0, d1) ? CMP_EQ :
6186 real_less (d0, d1) ? CMP_LT : CMP_GT));
6189 /* Otherwise, see if the operands are both integers. */
6190 if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
6191 && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
6193 /* It would be nice if we really had a mode here. However, the
6194 largest int representable on the target is as good as
6195 infinite. */
6196 machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
6197 rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
6198 rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
6200 if (wi::eq_p (ptrueop0, ptrueop1))
6201 return comparison_result (code, CMP_EQ);
6202 else
6204 int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
6205 cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
6206 return comparison_result (code, cr);
6210 /* Optimize comparisons with upper and lower bounds. */
6211 scalar_int_mode int_mode;
6212 if (CONST_INT_P (trueop1)
6213 && is_a <scalar_int_mode> (mode, &int_mode)
6214 && HWI_COMPUTABLE_MODE_P (int_mode)
6215 && !side_effects_p (trueop0))
6217 int sign;
6218 unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
6219 HOST_WIDE_INT val = INTVAL (trueop1);
6220 HOST_WIDE_INT mmin, mmax;
6222 if (code == GEU
6223 || code == LEU
6224 || code == GTU
6225 || code == LTU)
6226 sign = 0;
6227 else
6228 sign = 1;
6230 /* Get a reduced range if the sign bit is zero. */
6231 if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
6233 mmin = 0;
6234 mmax = nonzero;
6236 else
6238 rtx mmin_rtx, mmax_rtx;
6239 get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
6241 mmin = INTVAL (mmin_rtx);
6242 mmax = INTVAL (mmax_rtx);
6243 if (sign)
6245 unsigned int sign_copies
6246 = num_sign_bit_copies (trueop0, int_mode);
6248 mmin >>= (sign_copies - 1);
6249 mmax >>= (sign_copies - 1);
6253 switch (code)
6255 /* x >= y is always true for y <= mmin, always false for y > mmax. */
6256 case GEU:
6257 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6258 return const_true_rtx;
6259 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6260 return const0_rtx;
6261 break;
6262 case GE:
6263 if (val <= mmin)
6264 return const_true_rtx;
6265 if (val > mmax)
6266 return const0_rtx;
6267 break;
6269 /* x <= y is always true for y >= mmax, always false for y < mmin. */
6270 case LEU:
6271 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6272 return const_true_rtx;
6273 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6274 return const0_rtx;
6275 break;
6276 case LE:
6277 if (val >= mmax)
6278 return const_true_rtx;
6279 if (val < mmin)
6280 return const0_rtx;
6281 break;
6283 case EQ:
6284 /* x == y is always false for y out of range. */
6285 if (val < mmin || val > mmax)
6286 return const0_rtx;
6287 break;
6289 /* x > y is always false for y >= mmax, always true for y < mmin. */
6290 case GTU:
6291 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6292 return const0_rtx;
6293 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6294 return const_true_rtx;
6295 break;
6296 case GT:
6297 if (val >= mmax)
6298 return const0_rtx;
6299 if (val < mmin)
6300 return const_true_rtx;
6301 break;
6303 /* x < y is always false for y <= mmin, always true for y > mmax. */
6304 case LTU:
6305 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6306 return const0_rtx;
6307 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6308 return const_true_rtx;
6309 break;
6310 case LT:
6311 if (val <= mmin)
6312 return const0_rtx;
6313 if (val > mmax)
6314 return const_true_rtx;
6315 break;
6317 case NE:
6318 /* x != y is always true for y out of range. */
6319 if (val < mmin || val > mmax)
6320 return const_true_rtx;
6321 break;
6323 default:
6324 break;
6328 /* Optimize integer comparisons with zero. */
6329 if (is_a <scalar_int_mode> (mode, &int_mode)
6330 && trueop1 == const0_rtx
6331 && !side_effects_p (trueop0))
6333 /* Some addresses are known to be nonzero. We don't know
6334 their sign, but equality comparisons are known. */
6335 if (nonzero_address_p (trueop0))
6337 if (code == EQ || code == LEU)
6338 return const0_rtx;
6339 if (code == NE || code == GTU)
6340 return const_true_rtx;
6343 /* See if the first operand is an IOR with a constant. If so, we
6344 may be able to determine the result of this comparison. */
6345 if (GET_CODE (op0) == IOR)
6347 rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
6348 if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
6350 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
6351 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
6352 && (UINTVAL (inner_const)
6353 & (HOST_WIDE_INT_1U
6354 << sign_bitnum)));
6356 switch (code)
6358 case EQ:
6359 case LEU:
6360 return const0_rtx;
6361 case NE:
6362 case GTU:
6363 return const_true_rtx;
6364 case LT:
6365 case LE:
6366 if (has_sign)
6367 return const_true_rtx;
6368 break;
6369 case GT:
6370 case GE:
6371 if (has_sign)
6372 return const0_rtx;
6373 break;
6374 default:
6375 break;
6381 /* Optimize comparison of ABS with zero. */
6382 if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
6383 && (GET_CODE (trueop0) == ABS
6384 || (GET_CODE (trueop0) == FLOAT_EXTEND
6385 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
6387 switch (code)
6389 case LT:
6390 /* Optimize abs(x) < 0.0. */
6391 if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
6392 return const0_rtx;
6393 break;
6395 case GE:
6396 /* Optimize abs(x) >= 0.0. */
6397 if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
6398 return const_true_rtx;
6399 break;
6401 case UNGE:
6402 /* Optimize ! (abs(x) < 0.0). */
6403 return const_true_rtx;
6405 default:
6406 break;
6410 return 0;
6413 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6414 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6415 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6416 can be simplified to that or NULL_RTX if not.
6417 Assume X is compared against zero with CMP_CODE and the true
6418 arm is TRUE_VAL and the false arm is FALSE_VAL. */
6421 simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
6422 rtx true_val, rtx false_val)
6424 if (cmp_code != EQ && cmp_code != NE)
6425 return NULL_RTX;
6427 /* Result on X == 0 and X !=0 respectively. */
6428 rtx on_zero, on_nonzero;
6429 if (cmp_code == EQ)
6431 on_zero = true_val;
6432 on_nonzero = false_val;
6434 else
6436 on_zero = false_val;
6437 on_nonzero = true_val;
6440 rtx_code op_code = GET_CODE (on_nonzero);
6441 if ((op_code != CLZ && op_code != CTZ)
6442 || !rtx_equal_p (XEXP (on_nonzero, 0), x)
6443 || !CONST_INT_P (on_zero))
6444 return NULL_RTX;
6446 HOST_WIDE_INT op_val;
6447 scalar_int_mode mode ATTRIBUTE_UNUSED
6448 = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
6449 if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
6450 || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
6451 && op_val == INTVAL (on_zero))
6452 return on_nonzero;
6454 return NULL_RTX;
6457 /* Try to simplify X given that it appears within operand OP of a
6458 VEC_MERGE operation whose mask is MASK. X need not use the same
6459 vector mode as the VEC_MERGE, but it must have the same number of
6460 elements.
6462 Return the simplified X on success, otherwise return NULL_RTX. */
6465 simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
6467 gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
6468 poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
6469 if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
6471 if (side_effects_p (XEXP (x, 1 - op)))
6472 return NULL_RTX;
6474 return XEXP (x, op);
6476 if (UNARY_P (x)
6477 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6478 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
6480 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6481 if (top0)
6482 return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
6483 GET_MODE (XEXP (x, 0)));
6485 if (BINARY_P (x)
6486 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6487 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6488 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6489 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
6491 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6492 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6493 if (top0 || top1)
6495 if (COMPARISON_P (x))
6496 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6497 GET_MODE (XEXP (x, 0)) != VOIDmode
6498 ? GET_MODE (XEXP (x, 0))
6499 : GET_MODE (XEXP (x, 1)),
6500 top0 ? top0 : XEXP (x, 0),
6501 top1 ? top1 : XEXP (x, 1));
6502 else
6503 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
6504 top0 ? top0 : XEXP (x, 0),
6505 top1 ? top1 : XEXP (x, 1));
6508 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
6509 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6510 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6511 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6512 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
6513 && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
6514 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
6516 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6517 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6518 rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
6519 if (top0 || top1 || top2)
6520 return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6521 GET_MODE (XEXP (x, 0)),
6522 top0 ? top0 : XEXP (x, 0),
6523 top1 ? top1 : XEXP (x, 1),
6524 top2 ? top2 : XEXP (x, 2));
6526 return NULL_RTX;
6530 /* Simplify CODE, an operation with result mode MODE and three operands,
6531 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6532 a constant. Return 0 if no simplifications is possible. */
6535 simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
6536 machine_mode op0_mode,
6537 rtx op0, rtx op1, rtx op2)
6539 bool any_change = false;
6540 rtx tem, trueop2;
6541 scalar_int_mode int_mode, int_op0_mode;
6542 unsigned int n_elts;
6544 switch (code)
6546 case FMA:
6547 /* Simplify negations around the multiplication. */
6548 /* -a * -b + c => a * b + c. */
6549 if (GET_CODE (op0) == NEG)
6551 tem = simplify_unary_operation (NEG, mode, op1, mode);
6552 if (tem)
6553 op1 = tem, op0 = XEXP (op0, 0), any_change = true;
6555 else if (GET_CODE (op1) == NEG)
6557 tem = simplify_unary_operation (NEG, mode, op0, mode);
6558 if (tem)
6559 op0 = tem, op1 = XEXP (op1, 0), any_change = true;
6562 /* Canonicalize the two multiplication operands. */
6563 /* a * -b + c => -b * a + c. */
6564 if (swap_commutative_operands_p (op0, op1))
6565 std::swap (op0, op1), any_change = true;
6567 if (any_change)
6568 return gen_rtx_FMA (mode, op0, op1, op2);
6569 return NULL_RTX;
6571 case SIGN_EXTRACT:
6572 case ZERO_EXTRACT:
6573 if (CONST_INT_P (op0)
6574 && CONST_INT_P (op1)
6575 && CONST_INT_P (op2)
6576 && is_a <scalar_int_mode> (mode, &int_mode)
6577 && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
6578 && HWI_COMPUTABLE_MODE_P (int_mode))
6580 /* Extracting a bit-field from a constant */
6581 unsigned HOST_WIDE_INT val = UINTVAL (op0);
6582 HOST_WIDE_INT op1val = INTVAL (op1);
6583 HOST_WIDE_INT op2val = INTVAL (op2);
6584 if (!BITS_BIG_ENDIAN)
6585 val >>= op2val;
6586 else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
6587 val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
6588 else
6589 /* Not enough information to calculate the bit position. */
6590 break;
6592 if (HOST_BITS_PER_WIDE_INT != op1val)
6594 /* First zero-extend. */
6595 val &= (HOST_WIDE_INT_1U << op1val) - 1;
6596 /* If desired, propagate sign bit. */
6597 if (code == SIGN_EXTRACT
6598 && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6599 != 0)
6600 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6603 return gen_int_mode (val, int_mode);
6605 break;
6607 case IF_THEN_ELSE:
6608 if (CONST_INT_P (op0))
6609 return op0 != const0_rtx ? op1 : op2;
6611 /* Convert c ? a : a into "a". */
6612 if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6613 return op1;
6615 /* Convert a != b ? a : b into "a". */
6616 if (GET_CODE (op0) == NE
6617 && ! side_effects_p (op0)
6618 && ! HONOR_NANS (mode)
6619 && ! HONOR_SIGNED_ZEROS (mode)
6620 && ((rtx_equal_p (XEXP (op0, 0), op1)
6621 && rtx_equal_p (XEXP (op0, 1), op2))
6622 || (rtx_equal_p (XEXP (op0, 0), op2)
6623 && rtx_equal_p (XEXP (op0, 1), op1))))
6624 return op1;
6626 /* Convert a == b ? a : b into "b". */
6627 if (GET_CODE (op0) == EQ
6628 && ! side_effects_p (op0)
6629 && ! HONOR_NANS (mode)
6630 && ! HONOR_SIGNED_ZEROS (mode)
6631 && ((rtx_equal_p (XEXP (op0, 0), op1)
6632 && rtx_equal_p (XEXP (op0, 1), op2))
6633 || (rtx_equal_p (XEXP (op0, 0), op2)
6634 && rtx_equal_p (XEXP (op0, 1), op1))))
6635 return op2;
6637 /* Convert (!c) != {0,...,0} ? a : b into
6638 c != {0,...,0} ? b : a for vector modes. */
6639 if (VECTOR_MODE_P (GET_MODE (op1))
6640 && GET_CODE (op0) == NE
6641 && GET_CODE (XEXP (op0, 0)) == NOT
6642 && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6644 rtx cv = XEXP (op0, 1);
6645 int nunits;
6646 bool ok = true;
6647 if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6648 ok = false;
6649 else
6650 for (int i = 0; i < nunits; ++i)
6651 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6653 ok = false;
6654 break;
6656 if (ok)
6658 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6659 XEXP (XEXP (op0, 0), 0),
6660 XEXP (op0, 1));
6661 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6662 return retval;
6666 /* Convert x == 0 ? N : clz (x) into clz (x) when
6667 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6668 Similarly for ctz (x). */
6669 if (COMPARISON_P (op0) && !side_effects_p (op0)
6670 && XEXP (op0, 1) == const0_rtx)
6672 rtx simplified
6673 = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6674 op1, op2);
6675 if (simplified)
6676 return simplified;
6679 if (COMPARISON_P (op0) && ! side_effects_p (op0))
6681 machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6682 ? GET_MODE (XEXP (op0, 1))
6683 : GET_MODE (XEXP (op0, 0)));
6684 rtx temp;
6686 /* Look for happy constants in op1 and op2. */
6687 if (CONST_INT_P (op1) && CONST_INT_P (op2))
6689 HOST_WIDE_INT t = INTVAL (op1);
6690 HOST_WIDE_INT f = INTVAL (op2);
6692 if (t == STORE_FLAG_VALUE && f == 0)
6693 code = GET_CODE (op0);
6694 else if (t == 0 && f == STORE_FLAG_VALUE)
6696 enum rtx_code tmp;
6697 tmp = reversed_comparison_code (op0, NULL);
6698 if (tmp == UNKNOWN)
6699 break;
6700 code = tmp;
6702 else
6703 break;
6705 return simplify_gen_relational (code, mode, cmp_mode,
6706 XEXP (op0, 0), XEXP (op0, 1));
6709 temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6710 cmp_mode, XEXP (op0, 0),
6711 XEXP (op0, 1));
6713 /* See if any simplifications were possible. */
6714 if (temp)
6716 if (CONST_INT_P (temp))
6717 return temp == const0_rtx ? op2 : op1;
6718 else if (temp)
6719 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6722 break;
6724 case VEC_MERGE:
6725 gcc_assert (GET_MODE (op0) == mode);
6726 gcc_assert (GET_MODE (op1) == mode);
6727 gcc_assert (VECTOR_MODE_P (mode));
6728 trueop2 = avoid_constant_pool_reference (op2);
6729 if (CONST_INT_P (trueop2)
6730 && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6732 unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6733 unsigned HOST_WIDE_INT mask;
6734 if (n_elts == HOST_BITS_PER_WIDE_INT)
6735 mask = -1;
6736 else
6737 mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6739 if (!(sel & mask) && !side_effects_p (op0))
6740 return op1;
6741 if ((sel & mask) == mask && !side_effects_p (op1))
6742 return op0;
6744 rtx trueop0 = avoid_constant_pool_reference (op0);
6745 rtx trueop1 = avoid_constant_pool_reference (op1);
6746 if (GET_CODE (trueop0) == CONST_VECTOR
6747 && GET_CODE (trueop1) == CONST_VECTOR)
6749 rtvec v = rtvec_alloc (n_elts);
6750 unsigned int i;
6752 for (i = 0; i < n_elts; i++)
6753 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6754 ? CONST_VECTOR_ELT (trueop0, i)
6755 : CONST_VECTOR_ELT (trueop1, i));
6756 return gen_rtx_CONST_VECTOR (mode, v);
6759 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6760 if no element from a appears in the result. */
6761 if (GET_CODE (op0) == VEC_MERGE)
6763 tem = avoid_constant_pool_reference (XEXP (op0, 2));
6764 if (CONST_INT_P (tem))
6766 unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6767 if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6768 return simplify_gen_ternary (code, mode, mode,
6769 XEXP (op0, 1), op1, op2);
6770 if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6771 return simplify_gen_ternary (code, mode, mode,
6772 XEXP (op0, 0), op1, op2);
6775 if (GET_CODE (op1) == VEC_MERGE)
6777 tem = avoid_constant_pool_reference (XEXP (op1, 2));
6778 if (CONST_INT_P (tem))
6780 unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6781 if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6782 return simplify_gen_ternary (code, mode, mode,
6783 op0, XEXP (op1, 1), op2);
6784 if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6785 return simplify_gen_ternary (code, mode, mode,
6786 op0, XEXP (op1, 0), op2);
6790 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6791 with a. */
6792 if (GET_CODE (op0) == VEC_DUPLICATE
6793 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6794 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6795 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6797 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6798 if (CONST_INT_P (tem) && CONST_INT_P (op2))
6800 if (XEXP (XEXP (op0, 0), 0) == op1
6801 && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6802 return op1;
6805 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6806 (const_int N))
6807 with (vec_concat (X) (B)) if N == 1 or
6808 (vec_concat (A) (X)) if N == 2. */
6809 if (GET_CODE (op0) == VEC_DUPLICATE
6810 && GET_CODE (op1) == CONST_VECTOR
6811 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6812 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6813 && IN_RANGE (sel, 1, 2))
6815 rtx newop0 = XEXP (op0, 0);
6816 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6817 if (sel == 2)
6818 std::swap (newop0, newop1);
6819 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6821 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6822 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6823 Only applies for vectors of two elements. */
6824 if (GET_CODE (op0) == VEC_DUPLICATE
6825 && GET_CODE (op1) == VEC_CONCAT
6826 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6827 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6828 && IN_RANGE (sel, 1, 2))
6830 rtx newop0 = XEXP (op0, 0);
6831 rtx newop1 = XEXP (op1, 2 - sel);
6832 rtx otherop = XEXP (op1, sel - 1);
6833 if (sel == 2)
6834 std::swap (newop0, newop1);
6835 /* Don't want to throw away the other part of the vec_concat if
6836 it has side-effects. */
6837 if (!side_effects_p (otherop))
6838 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6841 /* Replace:
6843 (vec_merge:outer (vec_duplicate:outer x:inner)
6844 (subreg:outer y:inner 0)
6845 (const_int N))
6847 with (vec_concat:outer x:inner y:inner) if N == 1,
6848 or (vec_concat:outer y:inner x:inner) if N == 2.
6850 Implicitly, this means we have a paradoxical subreg, but such
6851 a check is cheap, so make it anyway.
6853 Only applies for vectors of two elements. */
6854 if (GET_CODE (op0) == VEC_DUPLICATE
6855 && GET_CODE (op1) == SUBREG
6856 && GET_MODE (op1) == GET_MODE (op0)
6857 && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6858 && paradoxical_subreg_p (op1)
6859 && subreg_lowpart_p (op1)
6860 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6861 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6862 && IN_RANGE (sel, 1, 2))
6864 rtx newop0 = XEXP (op0, 0);
6865 rtx newop1 = SUBREG_REG (op1);
6866 if (sel == 2)
6867 std::swap (newop0, newop1);
6868 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6871 /* Same as above but with switched operands:
6872 Replace (vec_merge:outer (subreg:outer x:inner 0)
6873 (vec_duplicate:outer y:inner)
6874 (const_int N))
6876 with (vec_concat:outer x:inner y:inner) if N == 1,
6877 or (vec_concat:outer y:inner x:inner) if N == 2. */
6878 if (GET_CODE (op1) == VEC_DUPLICATE
6879 && GET_CODE (op0) == SUBREG
6880 && GET_MODE (op0) == GET_MODE (op1)
6881 && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
6882 && paradoxical_subreg_p (op0)
6883 && subreg_lowpart_p (op0)
6884 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6885 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6886 && IN_RANGE (sel, 1, 2))
6888 rtx newop0 = SUBREG_REG (op0);
6889 rtx newop1 = XEXP (op1, 0);
6890 if (sel == 2)
6891 std::swap (newop0, newop1);
6892 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6895 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
6896 (const_int n))
6897 with (vec_concat x y) or (vec_concat y x) depending on value
6898 of N. */
6899 if (GET_CODE (op0) == VEC_DUPLICATE
6900 && GET_CODE (op1) == VEC_DUPLICATE
6901 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6902 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6903 && IN_RANGE (sel, 1, 2))
6905 rtx newop0 = XEXP (op0, 0);
6906 rtx newop1 = XEXP (op1, 0);
6907 if (sel == 2)
6908 std::swap (newop0, newop1);
6910 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6914 if (rtx_equal_p (op0, op1)
6915 && !side_effects_p (op2) && !side_effects_p (op1))
6916 return op0;
6918 if (!side_effects_p (op2))
6920 rtx top0
6921 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6922 rtx top1
6923 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6924 if (top0 || top1)
6925 return simplify_gen_ternary (code, mode, mode,
6926 top0 ? top0 : op0,
6927 top1 ? top1 : op1, op2);
6930 break;
6932 default:
6933 gcc_unreachable ();
6936 return 0;
6939 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6940 starting at byte FIRST_BYTE. Return true on success and add the
6941 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6942 that the bytes follow target memory order. Leave BYTES unmodified
6943 on failure.
6945 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6946 BYTES before calling this function. */
6948 bool
6949 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6950 unsigned int first_byte, unsigned int num_bytes)
6952 /* Check the mode is sensible. */
6953 gcc_assert (GET_MODE (x) == VOIDmode
6954 ? is_a <scalar_int_mode> (mode)
6955 : mode == GET_MODE (x));
6957 if (GET_CODE (x) == CONST_VECTOR)
6959 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
6960 is necessary. The only complication is that MODE_VECTOR_BOOL
6961 vectors can have several elements per byte. */
6962 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6963 GET_MODE_NUNITS (mode));
6964 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
6965 if (elt_bits < BITS_PER_UNIT)
6967 /* This is the only case in which elements can be smaller than
6968 a byte. */
6969 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6970 auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
6971 for (unsigned int i = 0; i < num_bytes; ++i)
6973 target_unit value = 0;
6974 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
6976 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & mask) << j;
6977 elt += 1;
6979 bytes.quick_push (value);
6981 return true;
6984 unsigned int start = bytes.length ();
6985 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
6986 /* Make FIRST_BYTE relative to ELT. */
6987 first_byte %= elt_bytes;
6988 while (num_bytes > 0)
6990 /* Work out how many bytes we want from element ELT. */
6991 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
6992 if (!native_encode_rtx (GET_MODE_INNER (mode),
6993 CONST_VECTOR_ELT (x, elt), bytes,
6994 first_byte, chunk_bytes))
6996 bytes.truncate (start);
6997 return false;
6999 elt += 1;
7000 first_byte = 0;
7001 num_bytes -= chunk_bytes;
7003 return true;
7006 /* All subsequent cases are limited to scalars. */
7007 scalar_mode smode;
7008 if (!is_a <scalar_mode> (mode, &smode))
7009 return false;
7011 /* Make sure that the region is in range. */
7012 unsigned int end_byte = first_byte + num_bytes;
7013 unsigned int mode_bytes = GET_MODE_SIZE (smode);
7014 gcc_assert (end_byte <= mode_bytes);
7016 if (CONST_SCALAR_INT_P (x))
7018 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7019 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7020 position of each byte. */
7021 rtx_mode_t value (x, smode);
7022 wide_int_ref value_wi (value);
7023 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7025 /* Always constant because the inputs are. */
7026 unsigned int lsb
7027 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7028 /* Operate directly on the encoding rather than using
7029 wi::extract_uhwi, so that we preserve the sign or zero
7030 extension for modes that are not a whole number of bits in
7031 size. (Zero extension is only used for the combination of
7032 innermode == BImode && STORE_FLAG_VALUE == 1). */
7033 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
7034 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
7035 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
7036 bytes.quick_push (uhwi >> shift);
7038 return true;
7041 if (CONST_DOUBLE_P (x))
7043 /* real_to_target produces an array of integers in target memory order.
7044 All integers before the last one have 32 bits; the last one may
7045 have 32 bits or fewer, depending on whether the mode bitsize
7046 is divisible by 32. Each of these integers is then laid out
7047 in target memory as any other integer would be. */
7048 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7049 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
7051 /* The (maximum) number of target bytes per element of el32. */
7052 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7053 gcc_assert (bytes_per_el32 != 0);
7055 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7056 handling above. */
7057 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7059 unsigned int index = byte / bytes_per_el32;
7060 unsigned int subbyte = byte % bytes_per_el32;
7061 unsigned int int_bytes = MIN (bytes_per_el32,
7062 mode_bytes - index * bytes_per_el32);
7063 /* Always constant because the inputs are. */
7064 unsigned int lsb
7065 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7066 bytes.quick_push ((unsigned long) el32[index] >> lsb);
7068 return true;
7071 if (GET_CODE (x) == CONST_FIXED)
7073 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7075 /* Always constant because the inputs are. */
7076 unsigned int lsb
7077 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7078 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
7079 if (lsb >= HOST_BITS_PER_WIDE_INT)
7081 lsb -= HOST_BITS_PER_WIDE_INT;
7082 piece = CONST_FIXED_VALUE_HIGH (x);
7084 bytes.quick_push (piece >> lsb);
7086 return true;
7089 return false;
7092 /* Read a vector of mode MODE from the target memory image given by BYTES,
7093 starting at byte FIRST_BYTE. The vector is known to be encodable using
7094 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
7095 and BYTES is known to have enough bytes to supply NPATTERNS *
7096 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
7097 BITS_PER_UNIT bits and the bytes are in target memory order.
7099 Return the vector on success, otherwise return NULL_RTX. */
7102 native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
7103 unsigned int first_byte, unsigned int npatterns,
7104 unsigned int nelts_per_pattern)
7106 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
7108 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7109 GET_MODE_NUNITS (mode));
7110 if (elt_bits < BITS_PER_UNIT)
7112 /* This is the only case in which elements can be smaller than a byte.
7113 Element 0 is always in the lsb of the containing byte. */
7114 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7115 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7117 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
7118 unsigned int byte_index = bit_index / BITS_PER_UNIT;
7119 unsigned int lsb = bit_index % BITS_PER_UNIT;
7120 unsigned int value = bytes[byte_index] >> lsb;
7121 builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
7124 else
7126 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7128 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
7129 if (!x)
7130 return NULL_RTX;
7131 builder.quick_push (x);
7132 first_byte += elt_bits / BITS_PER_UNIT;
7135 return builder.build ();
7138 /* Read an rtx of mode MODE from the target memory image given by BYTES,
7139 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
7140 bits and the bytes are in target memory order. The image has enough
7141 values to specify all bytes of MODE.
7143 Return the rtx on success, otherwise return NULL_RTX. */
7146 native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
7147 unsigned int first_byte)
7149 if (VECTOR_MODE_P (mode))
7151 /* If we know at compile time how many elements there are,
7152 pull each element directly from BYTES. */
7153 unsigned int nelts;
7154 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
7155 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
7156 return NULL_RTX;
7159 scalar_int_mode imode;
7160 if (is_a <scalar_int_mode> (mode, &imode)
7161 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
7163 /* Pull the bytes msb first, so that we can use simple
7164 shift-and-insert wide_int operations. */
7165 unsigned int size = GET_MODE_SIZE (imode);
7166 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
7167 for (unsigned int i = 0; i < size; ++i)
7169 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
7170 /* Always constant because the inputs are. */
7171 unsigned int subbyte
7172 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
7173 result <<= BITS_PER_UNIT;
7174 result |= bytes[first_byte + subbyte];
7176 return immed_wide_int_const (result, imode);
7179 scalar_float_mode fmode;
7180 if (is_a <scalar_float_mode> (mode, &fmode))
7182 /* We need to build an array of integers in target memory order.
7183 All integers before the last one have 32 bits; the last one may
7184 have 32 bits or fewer, depending on whether the mode bitsize
7185 is divisible by 32. */
7186 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7187 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
7188 memset (el32, 0, num_el32 * sizeof (long));
7190 /* The (maximum) number of target bytes per element of el32. */
7191 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7192 gcc_assert (bytes_per_el32 != 0);
7194 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
7195 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7197 unsigned int index = byte / bytes_per_el32;
7198 unsigned int subbyte = byte % bytes_per_el32;
7199 unsigned int int_bytes = MIN (bytes_per_el32,
7200 mode_bytes - index * bytes_per_el32);
7201 /* Always constant because the inputs are. */
7202 unsigned int lsb
7203 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7204 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
7206 REAL_VALUE_TYPE r;
7207 real_from_target (&r, el32, fmode);
7208 return const_double_from_real_value (r, fmode);
7211 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7213 scalar_mode smode = as_a <scalar_mode> (mode);
7214 FIXED_VALUE_TYPE f;
7215 f.data.low = 0;
7216 f.data.high = 0;
7217 f.mode = smode;
7219 unsigned int mode_bytes = GET_MODE_SIZE (smode);
7220 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7222 /* Always constant because the inputs are. */
7223 unsigned int lsb
7224 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7225 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
7226 if (lsb >= HOST_BITS_PER_WIDE_INT)
7227 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
7228 else
7229 f.data.low |= unit << lsb;
7231 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
7234 return NULL_RTX;
7237 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
7238 is to convert a runtime BYTE value into a constant one. */
7240 static poly_uint64
7241 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
7243 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7244 machine_mode mode = GET_MODE (x);
7245 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7246 GET_MODE_NUNITS (mode));
7247 /* The number of bits needed to encode one element from each pattern. */
7248 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
7250 /* Identify the start point in terms of a sequence number and a byte offset
7251 within that sequence. */
7252 poly_uint64 first_sequence;
7253 unsigned HOST_WIDE_INT subbit;
7254 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
7255 &first_sequence, &subbit))
7257 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7258 if (nelts_per_pattern == 1)
7259 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
7260 doesn't matter. */
7261 byte = subbit / BITS_PER_UNIT;
7262 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
7264 /* The subreg drops the first element from each pattern and
7265 only uses the second element. Find the first sequence
7266 that starts on a byte boundary. */
7267 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
7268 byte = subbit / BITS_PER_UNIT;
7271 return byte;
7274 /* Subroutine of simplify_subreg in which:
7276 - X is known to be a CONST_VECTOR
7277 - OUTERMODE is known to be a vector mode
7279 Try to handle the subreg by operating on the CONST_VECTOR encoding
7280 rather than on each individual element of the CONST_VECTOR.
7282 Return the simplified subreg on success, otherwise return NULL_RTX. */
7284 static rtx
7285 simplify_const_vector_subreg (machine_mode outermode, rtx x,
7286 machine_mode innermode, unsigned int first_byte)
7288 /* Paradoxical subregs of vectors have dubious semantics. */
7289 if (paradoxical_subreg_p (outermode, innermode))
7290 return NULL_RTX;
7292 /* We can only preserve the semantics of a stepped pattern if the new
7293 vector element is the same as the original one. */
7294 if (CONST_VECTOR_STEPPED_P (x)
7295 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
7296 return NULL_RTX;
7298 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7299 unsigned int x_elt_bits
7300 = vector_element_size (GET_MODE_BITSIZE (innermode),
7301 GET_MODE_NUNITS (innermode));
7302 unsigned int out_elt_bits
7303 = vector_element_size (GET_MODE_BITSIZE (outermode),
7304 GET_MODE_NUNITS (outermode));
7306 /* The number of bits needed to encode one element from every pattern
7307 of the original vector. */
7308 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
7310 /* The number of bits needed to encode one element from every pattern
7311 of the result. */
7312 unsigned int out_sequence_bits
7313 = least_common_multiple (x_sequence_bits, out_elt_bits);
7315 /* Work out the number of interleaved patterns in the output vector
7316 and the number of encoded elements per pattern. */
7317 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
7318 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7320 /* The encoding scheme requires the number of elements to be a multiple
7321 of the number of patterns, so that each pattern appears at least once
7322 and so that the same number of elements appear from each pattern. */
7323 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
7324 unsigned int const_nunits;
7325 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
7326 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
7328 /* Either the encoding is invalid, or applying it would give us
7329 more elements than we need. Just encode each element directly. */
7330 out_npatterns = const_nunits;
7331 nelts_per_pattern = 1;
7333 else if (!ok_p)
7334 return NULL_RTX;
7336 /* Get enough bytes of X to form the new encoding. */
7337 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
7338 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
7339 auto_vec<target_unit, 128> buffer (buffer_bytes);
7340 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
7341 return NULL_RTX;
7343 /* Reencode the bytes as OUTERMODE. */
7344 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
7345 nelts_per_pattern);
7348 /* Try to simplify a subreg of a constant by encoding the subreg region
7349 as a sequence of target bytes and reading them back in the new mode.
7350 Return the new value on success, otherwise return null.
7352 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7353 and byte offset FIRST_BYTE. */
7355 static rtx
7356 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
7357 machine_mode innermode, unsigned int first_byte)
7359 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
7360 auto_vec<target_unit, 128> buffer (buffer_bytes);
7362 /* Some ports misuse CCmode. */
7363 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
7364 return x;
7366 /* Paradoxical subregs read undefined values for bytes outside of the
7367 inner value. However, we have traditionally always sign-extended
7368 integer constants and zero-extended others. */
7369 unsigned int inner_bytes = buffer_bytes;
7370 if (paradoxical_subreg_p (outermode, innermode))
7372 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
7373 return NULL_RTX;
7375 target_unit filler = 0;
7376 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
7377 filler = -1;
7379 /* Add any leading bytes due to big-endian layout. The number of
7380 bytes must be constant because both modes have constant size. */
7381 unsigned int leading_bytes
7382 = -byte_lowpart_offset (outermode, innermode).to_constant ();
7383 for (unsigned int i = 0; i < leading_bytes; ++i)
7384 buffer.quick_push (filler);
7386 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7387 return NULL_RTX;
7389 /* Add any trailing bytes due to little-endian layout. */
7390 while (buffer.length () < buffer_bytes)
7391 buffer.quick_push (filler);
7393 else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7394 return NULL_RTX;
7395 rtx ret = native_decode_rtx (outermode, buffer, 0);
7396 if (ret && FLOAT_MODE_P (outermode))
7398 auto_vec<target_unit, 128> buffer2 (buffer_bytes);
7399 if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
7400 return NULL_RTX;
7401 for (unsigned int i = 0; i < buffer_bytes; ++i)
7402 if (buffer[i] != buffer2[i])
7403 return NULL_RTX;
7405 return ret;
7408 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7409 Return 0 if no simplifications are possible. */
7411 simplify_context::simplify_subreg (machine_mode outermode, rtx op,
7412 machine_mode innermode, poly_uint64 byte)
7414 /* Little bit of sanity checking. */
7415 gcc_assert (innermode != VOIDmode);
7416 gcc_assert (outermode != VOIDmode);
7417 gcc_assert (innermode != BLKmode);
7418 gcc_assert (outermode != BLKmode);
7420 gcc_assert (GET_MODE (op) == innermode
7421 || GET_MODE (op) == VOIDmode);
7423 poly_uint64 outersize = GET_MODE_SIZE (outermode);
7424 if (!multiple_p (byte, outersize))
7425 return NULL_RTX;
7427 poly_uint64 innersize = GET_MODE_SIZE (innermode);
7428 if (maybe_ge (byte, innersize))
7429 return NULL_RTX;
7431 if (outermode == innermode && known_eq (byte, 0U))
7432 return op;
7434 if (GET_CODE (op) == CONST_VECTOR)
7435 byte = simplify_const_vector_byte_offset (op, byte);
7437 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
7439 rtx elt;
7441 if (VECTOR_MODE_P (outermode)
7442 && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
7443 && vec_duplicate_p (op, &elt))
7444 return gen_vec_duplicate (outermode, elt);
7446 if (outermode == GET_MODE_INNER (innermode)
7447 && vec_duplicate_p (op, &elt))
7448 return elt;
7451 if (CONST_SCALAR_INT_P (op)
7452 || CONST_DOUBLE_AS_FLOAT_P (op)
7453 || CONST_FIXED_P (op)
7454 || GET_CODE (op) == CONST_VECTOR)
7456 unsigned HOST_WIDE_INT cbyte;
7457 if (byte.is_constant (&cbyte))
7459 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
7461 rtx tmp = simplify_const_vector_subreg (outermode, op,
7462 innermode, cbyte);
7463 if (tmp)
7464 return tmp;
7467 fixed_size_mode fs_outermode;
7468 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
7469 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
7473 /* Changing mode twice with SUBREG => just change it once,
7474 or not at all if changing back op starting mode. */
7475 if (GET_CODE (op) == SUBREG)
7477 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
7478 poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
7479 rtx newx;
7481 if (outermode == innermostmode
7482 && known_eq (byte, 0U)
7483 && known_eq (SUBREG_BYTE (op), 0))
7484 return SUBREG_REG (op);
7486 /* Work out the memory offset of the final OUTERMODE value relative
7487 to the inner value of OP. */
7488 poly_int64 mem_offset = subreg_memory_offset (outermode,
7489 innermode, byte);
7490 poly_int64 op_mem_offset = subreg_memory_offset (op);
7491 poly_int64 final_offset = mem_offset + op_mem_offset;
7493 /* See whether resulting subreg will be paradoxical. */
7494 if (!paradoxical_subreg_p (outermode, innermostmode))
7496 /* Bail out in case resulting subreg would be incorrect. */
7497 if (maybe_lt (final_offset, 0)
7498 || maybe_ge (poly_uint64 (final_offset), innermostsize)
7499 || !multiple_p (final_offset, outersize))
7500 return NULL_RTX;
7502 else
7504 poly_int64 required_offset = subreg_memory_offset (outermode,
7505 innermostmode, 0);
7506 if (maybe_ne (final_offset, required_offset))
7507 return NULL_RTX;
7508 /* Paradoxical subregs always have byte offset 0. */
7509 final_offset = 0;
7512 /* Recurse for further possible simplifications. */
7513 newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
7514 final_offset);
7515 if (newx)
7516 return newx;
7517 if (validate_subreg (outermode, innermostmode,
7518 SUBREG_REG (op), final_offset))
7520 newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
7521 if (SUBREG_PROMOTED_VAR_P (op)
7522 && SUBREG_PROMOTED_SIGN (op) >= 0
7523 && GET_MODE_CLASS (outermode) == MODE_INT
7524 && known_ge (outersize, innersize)
7525 && known_le (outersize, innermostsize)
7526 && subreg_lowpart_p (newx))
7528 SUBREG_PROMOTED_VAR_P (newx) = 1;
7529 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
7531 return newx;
7533 return NULL_RTX;
7536 /* SUBREG of a hard register => just change the register number
7537 and/or mode. If the hard register is not valid in that mode,
7538 suppress this simplification. If the hard register is the stack,
7539 frame, or argument pointer, leave this as a SUBREG. */
7541 if (REG_P (op) && HARD_REGISTER_P (op))
7543 unsigned int regno, final_regno;
7545 regno = REGNO (op);
7546 final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
7547 if (HARD_REGISTER_NUM_P (final_regno))
7549 rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
7550 subreg_memory_offset (outermode,
7551 innermode, byte));
7553 /* Propagate original regno. We don't have any way to specify
7554 the offset inside original regno, so do so only for lowpart.
7555 The information is used only by alias analysis that cannot
7556 grog partial register anyway. */
7558 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
7559 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
7560 return x;
7564 /* If we have a SUBREG of a register that we are replacing and we are
7565 replacing it with a MEM, make a new MEM and try replacing the
7566 SUBREG with it. Don't do this if the MEM has a mode-dependent address
7567 or if we would be widening it. */
7569 if (MEM_P (op)
7570 && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
7571 /* Allow splitting of volatile memory references in case we don't
7572 have instruction to move the whole thing. */
7573 && (! MEM_VOLATILE_P (op)
7574 || ! have_insn_for (SET, innermode))
7575 && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
7576 && known_le (outersize, innersize))
7577 return adjust_address_nv (op, outermode, byte);
7579 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7580 of two parts. */
7581 if (GET_CODE (op) == CONCAT
7582 || GET_CODE (op) == VEC_CONCAT)
7584 poly_uint64 final_offset;
7585 rtx part, res;
7587 machine_mode part_mode = GET_MODE (XEXP (op, 0));
7588 if (part_mode == VOIDmode)
7589 part_mode = GET_MODE_INNER (GET_MODE (op));
7590 poly_uint64 part_size = GET_MODE_SIZE (part_mode);
7591 if (known_lt (byte, part_size))
7593 part = XEXP (op, 0);
7594 final_offset = byte;
7596 else if (known_ge (byte, part_size))
7598 part = XEXP (op, 1);
7599 final_offset = byte - part_size;
7601 else
7602 return NULL_RTX;
7604 if (maybe_gt (final_offset + outersize, part_size))
7605 return NULL_RTX;
7607 part_mode = GET_MODE (part);
7608 if (part_mode == VOIDmode)
7609 part_mode = GET_MODE_INNER (GET_MODE (op));
7610 res = simplify_subreg (outermode, part, part_mode, final_offset);
7611 if (res)
7612 return res;
7613 if (validate_subreg (outermode, part_mode, part, final_offset))
7614 return gen_rtx_SUBREG (outermode, part, final_offset);
7615 return NULL_RTX;
7618 /* Simplify
7619 (subreg (vec_merge (X)
7620 (vector)
7621 (const_int ((1 << N) | M)))
7622 (N * sizeof (outermode)))
7624 (subreg (X) (N * sizeof (outermode)))
7626 unsigned int idx;
7627 if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7628 && idx < HOST_BITS_PER_WIDE_INT
7629 && GET_CODE (op) == VEC_MERGE
7630 && GET_MODE_INNER (innermode) == outermode
7631 && CONST_INT_P (XEXP (op, 2))
7632 && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7633 return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7635 /* A SUBREG resulting from a zero extension may fold to zero if
7636 it extracts higher bits that the ZERO_EXTEND's source bits. */
7637 if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7639 poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7640 if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7641 return CONST0_RTX (outermode);
7644 scalar_int_mode int_outermode, int_innermode;
7645 if (is_a <scalar_int_mode> (outermode, &int_outermode)
7646 && is_a <scalar_int_mode> (innermode, &int_innermode)
7647 && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7649 /* Handle polynomial integers. The upper bits of a paradoxical
7650 subreg are undefined, so this is safe regardless of whether
7651 we're truncating or extending. */
7652 if (CONST_POLY_INT_P (op))
7654 poly_wide_int val
7655 = poly_wide_int::from (const_poly_int_value (op),
7656 GET_MODE_PRECISION (int_outermode),
7657 SIGNED);
7658 return immed_wide_int_const (val, int_outermode);
7661 if (GET_MODE_PRECISION (int_outermode)
7662 < GET_MODE_PRECISION (int_innermode))
7664 rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7665 if (tem)
7666 return tem;
7670 /* If the outer mode is not integral, try taking a subreg with the equivalent
7671 integer outer mode and then bitcasting the result.
7672 Other simplifications rely on integer to integer subregs and we'd
7673 potentially miss out on optimizations otherwise. */
7674 if (known_gt (GET_MODE_SIZE (innermode),
7675 GET_MODE_SIZE (outermode))
7676 && SCALAR_INT_MODE_P (innermode)
7677 && !SCALAR_INT_MODE_P (outermode)
7678 && int_mode_for_size (GET_MODE_BITSIZE (outermode),
7679 0).exists (&int_outermode))
7681 rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
7682 if (tem)
7683 return simplify_gen_subreg (outermode, tem, int_outermode, byte);
7686 /* If OP is a vector comparison and the subreg is not changing the
7687 number of elements or the size of the elements, change the result
7688 of the comparison to the new mode. */
7689 if (COMPARISON_P (op)
7690 && VECTOR_MODE_P (outermode)
7691 && VECTOR_MODE_P (innermode)
7692 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7693 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7694 GET_MODE_UNIT_SIZE (innermode)))
7695 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7696 XEXP (op, 0), XEXP (op, 1));
7697 return NULL_RTX;
7700 /* Make a SUBREG operation or equivalent if it folds. */
7703 simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
7704 machine_mode innermode,
7705 poly_uint64 byte)
7707 rtx newx;
7709 newx = simplify_subreg (outermode, op, innermode, byte);
7710 if (newx)
7711 return newx;
7713 if (GET_CODE (op) == SUBREG
7714 || GET_CODE (op) == CONCAT
7715 || GET_MODE (op) == VOIDmode)
7716 return NULL_RTX;
7718 if (MODE_COMPOSITE_P (outermode)
7719 && (CONST_SCALAR_INT_P (op)
7720 || CONST_DOUBLE_AS_FLOAT_P (op)
7721 || CONST_FIXED_P (op)
7722 || GET_CODE (op) == CONST_VECTOR))
7723 return NULL_RTX;
7725 if (validate_subreg (outermode, innermode, op, byte))
7726 return gen_rtx_SUBREG (outermode, op, byte);
7728 return NULL_RTX;
7731 /* Generates a subreg to get the least significant part of EXPR (in mode
7732 INNER_MODE) to OUTER_MODE. */
7735 simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
7736 machine_mode inner_mode)
7738 return simplify_gen_subreg (outer_mode, expr, inner_mode,
7739 subreg_lowpart_offset (outer_mode, inner_mode));
7742 /* Generate RTX to select element at INDEX out of vector OP. */
7745 simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
7747 gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
7749 scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
7751 if (known_eq (index * GET_MODE_SIZE (imode),
7752 subreg_lowpart_offset (imode, GET_MODE (op))))
7754 rtx res = lowpart_subreg (imode, op, GET_MODE (op));
7755 if (res)
7756 return res;
7759 rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
7760 return gen_rtx_VEC_SELECT (imode, op, tmp);
7764 /* Simplify X, an rtx expression.
7766 Return the simplified expression or NULL if no simplifications
7767 were possible.
7769 This is the preferred entry point into the simplification routines;
7770 however, we still allow passes to call the more specific routines.
7772 Right now GCC has three (yes, three) major bodies of RTL simplification
7773 code that need to be unified.
7775 1. fold_rtx in cse.cc. This code uses various CSE specific
7776 information to aid in RTL simplification.
7778 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
7779 it uses combine specific information to aid in RTL
7780 simplification.
7782 3. The routines in this file.
7785 Long term we want to only have one body of simplification code; to
7786 get to that state I recommend the following steps:
7788 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7789 which are not pass dependent state into these routines.
7791 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7792 use this routine whenever possible.
7794 3. Allow for pass dependent state to be provided to these
7795 routines and add simplifications based on the pass dependent
7796 state. Remove code from cse.cc & combine.cc that becomes
7797 redundant/dead.
7799 It will take time, but ultimately the compiler will be easier to
7800 maintain and improve. It's totally silly that when we add a
7801 simplification that it needs to be added to 4 places (3 for RTL
7802 simplification and 1 for tree simplification. */
7805 simplify_rtx (const_rtx x)
7807 const enum rtx_code code = GET_CODE (x);
7808 const machine_mode mode = GET_MODE (x);
7810 switch (GET_RTX_CLASS (code))
7812 case RTX_UNARY:
7813 return simplify_unary_operation (code, mode,
7814 XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7815 case RTX_COMM_ARITH:
7816 if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7817 return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7819 /* Fall through. */
7821 case RTX_BIN_ARITH:
7822 return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7824 case RTX_TERNARY:
7825 case RTX_BITFIELD_OPS:
7826 return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7827 XEXP (x, 0), XEXP (x, 1),
7828 XEXP (x, 2));
7830 case RTX_COMPARE:
7831 case RTX_COMM_COMPARE:
7832 return simplify_relational_operation (code, mode,
7833 ((GET_MODE (XEXP (x, 0))
7834 != VOIDmode)
7835 ? GET_MODE (XEXP (x, 0))
7836 : GET_MODE (XEXP (x, 1))),
7837 XEXP (x, 0),
7838 XEXP (x, 1));
7840 case RTX_EXTRA:
7841 if (code == SUBREG)
7842 return simplify_subreg (mode, SUBREG_REG (x),
7843 GET_MODE (SUBREG_REG (x)),
7844 SUBREG_BYTE (x));
7845 break;
7847 case RTX_OBJ:
7848 if (code == LO_SUM)
7850 /* Convert (lo_sum (high FOO) FOO) to FOO. */
7851 if (GET_CODE (XEXP (x, 0)) == HIGH
7852 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
7853 return XEXP (x, 1);
7855 break;
7857 default:
7858 break;
7860 return NULL;
7863 #if CHECKING_P
7865 namespace selftest {
7867 /* Make a unique pseudo REG of mode MODE for use by selftests. */
7869 static rtx
7870 make_test_reg (machine_mode mode)
7872 static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
7874 return gen_rtx_REG (mode, test_reg_num++);
7877 static void
7878 test_scalar_int_ops (machine_mode mode)
7880 rtx op0 = make_test_reg (mode);
7881 rtx op1 = make_test_reg (mode);
7882 rtx six = GEN_INT (6);
7884 rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
7885 rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
7886 rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
7888 rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
7889 rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
7890 rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
7892 rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
7893 rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
7895 /* Test some binary identities. */
7896 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
7897 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
7898 ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
7899 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
7900 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
7901 ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
7902 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
7903 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
7904 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
7905 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
7906 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
7907 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
7908 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
7909 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
7910 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
7911 ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
7912 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
7914 /* Test some self-inverse operations. */
7915 ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
7916 ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
7917 ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
7919 /* Test some reflexive operations. */
7920 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
7921 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
7922 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
7923 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
7924 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
7925 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
7927 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
7928 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
7930 /* Test simplify_distributive_operation. */
7931 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
7932 simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
7933 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
7934 simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
7935 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
7936 simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
7938 /* Test useless extensions are eliminated. */
7939 ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
7940 ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
7941 ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
7942 ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
7945 /* Verify some simplifications of integer extension/truncation.
7946 Machine mode BMODE is the guaranteed wider than SMODE. */
7948 static void
7949 test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
7951 rtx sreg = make_test_reg (smode);
7953 /* Check truncation of extension. */
7954 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7955 simplify_gen_unary (ZERO_EXTEND, bmode,
7956 sreg, smode),
7957 bmode),
7958 sreg);
7959 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7960 simplify_gen_unary (SIGN_EXTEND, bmode,
7961 sreg, smode),
7962 bmode),
7963 sreg);
7964 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7965 lowpart_subreg (bmode, sreg, smode),
7966 bmode),
7967 sreg);
7970 /* Verify more simplifications of integer extension/truncation.
7971 BMODE is wider than MMODE which is wider than SMODE. */
7973 static void
7974 test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
7975 machine_mode smode)
7977 rtx breg = make_test_reg (bmode);
7978 rtx mreg = make_test_reg (mmode);
7979 rtx sreg = make_test_reg (smode);
7981 /* Check truncate of truncate. */
7982 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7983 simplify_gen_unary (TRUNCATE, mmode,
7984 breg, bmode),
7985 mmode),
7986 simplify_gen_unary (TRUNCATE, smode, breg, bmode));
7988 /* Check extension of extension. */
7989 ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
7990 simplify_gen_unary (ZERO_EXTEND, mmode,
7991 sreg, smode),
7992 mmode),
7993 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
7994 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
7995 simplify_gen_unary (SIGN_EXTEND, mmode,
7996 sreg, smode),
7997 mmode),
7998 simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
7999 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8000 simplify_gen_unary (ZERO_EXTEND, mmode,
8001 sreg, smode),
8002 mmode),
8003 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8005 /* Check truncation of extension. */
8006 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8007 simplify_gen_unary (ZERO_EXTEND, bmode,
8008 mreg, mmode),
8009 bmode),
8010 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8011 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8012 simplify_gen_unary (SIGN_EXTEND, bmode,
8013 mreg, mmode),
8014 bmode),
8015 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8016 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8017 lowpart_subreg (bmode, mreg, mmode),
8018 bmode),
8019 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8023 /* Verify some simplifications involving scalar expressions. */
8025 static void
8026 test_scalar_ops ()
8028 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8030 machine_mode mode = (machine_mode) i;
8031 if (SCALAR_INT_MODE_P (mode) && mode != BImode)
8032 test_scalar_int_ops (mode);
8035 test_scalar_int_ext_ops (HImode, QImode);
8036 test_scalar_int_ext_ops (SImode, QImode);
8037 test_scalar_int_ext_ops (SImode, HImode);
8038 test_scalar_int_ext_ops (DImode, QImode);
8039 test_scalar_int_ext_ops (DImode, HImode);
8040 test_scalar_int_ext_ops (DImode, SImode);
8042 test_scalar_int_ext_ops2 (SImode, HImode, QImode);
8043 test_scalar_int_ext_ops2 (DImode, HImode, QImode);
8044 test_scalar_int_ext_ops2 (DImode, SImode, QImode);
8045 test_scalar_int_ext_ops2 (DImode, SImode, HImode);
8048 /* Test vector simplifications involving VEC_DUPLICATE in which the
8049 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8050 register that holds one element of MODE. */
8052 static void
8053 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
8055 scalar_mode inner_mode = GET_MODE_INNER (mode);
8056 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8057 poly_uint64 nunits = GET_MODE_NUNITS (mode);
8058 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
8060 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
8061 rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
8062 rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
8063 ASSERT_RTX_EQ (duplicate,
8064 simplify_unary_operation (NOT, mode,
8065 duplicate_not, mode));
8067 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8068 rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
8069 ASSERT_RTX_EQ (duplicate,
8070 simplify_unary_operation (NEG, mode,
8071 duplicate_neg, mode));
8073 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
8074 ASSERT_RTX_EQ (duplicate,
8075 simplify_binary_operation (PLUS, mode, duplicate,
8076 CONST0_RTX (mode)));
8078 ASSERT_RTX_EQ (duplicate,
8079 simplify_binary_operation (MINUS, mode, duplicate,
8080 CONST0_RTX (mode)));
8082 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
8083 simplify_binary_operation (MINUS, mode, duplicate,
8084 duplicate));
8087 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
8088 rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
8089 ASSERT_RTX_PTR_EQ (scalar_reg,
8090 simplify_binary_operation (VEC_SELECT, inner_mode,
8091 duplicate, zero_par));
8093 unsigned HOST_WIDE_INT const_nunits;
8094 if (nunits.is_constant (&const_nunits))
8096 /* And again with the final element. */
8097 rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
8098 rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
8099 ASSERT_RTX_PTR_EQ (scalar_reg,
8100 simplify_binary_operation (VEC_SELECT, inner_mode,
8101 duplicate, last_par));
8103 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
8104 /* Skip this test for vectors of booleans, because offset is in bytes,
8105 while vec_merge indices are in elements (usually bits). */
8106 if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
8108 rtx vector_reg = make_test_reg (mode);
8109 for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
8111 if (i >= HOST_BITS_PER_WIDE_INT)
8112 break;
8113 rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
8114 rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
8115 poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
8117 ASSERT_RTX_EQ (scalar_reg,
8118 simplify_gen_subreg (inner_mode, vm,
8119 mode, offset));
8124 /* Test a scalar subreg of a VEC_DUPLICATE. */
8125 poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
8126 ASSERT_RTX_EQ (scalar_reg,
8127 simplify_gen_subreg (inner_mode, duplicate,
8128 mode, offset));
8130 machine_mode narrower_mode;
8131 if (maybe_ne (nunits, 2U)
8132 && multiple_p (nunits, 2)
8133 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
8134 && VECTOR_MODE_P (narrower_mode))
8136 /* Test VEC_DUPLICATE of a vector. */
8137 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
8138 nbuilder.quick_push (const0_rtx);
8139 nbuilder.quick_push (const1_rtx);
8140 rtx_vector_builder builder (mode, 2, 1);
8141 builder.quick_push (const0_rtx);
8142 builder.quick_push (const1_rtx);
8143 ASSERT_RTX_EQ (builder.build (),
8144 simplify_unary_operation (VEC_DUPLICATE, mode,
8145 nbuilder.build (),
8146 narrower_mode));
8148 /* Test VEC_SELECT of a vector. */
8149 rtx vec_par
8150 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
8151 rtx narrower_duplicate
8152 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
8153 ASSERT_RTX_EQ (narrower_duplicate,
8154 simplify_binary_operation (VEC_SELECT, narrower_mode,
8155 duplicate, vec_par));
8157 /* Test a vector subreg of a VEC_DUPLICATE. */
8158 poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
8159 ASSERT_RTX_EQ (narrower_duplicate,
8160 simplify_gen_subreg (narrower_mode, duplicate,
8161 mode, offset));
8165 /* Test vector simplifications involving VEC_SERIES in which the
8166 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8167 register that holds one element of MODE. */
8169 static void
8170 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
8172 /* Test unary cases with VEC_SERIES arguments. */
8173 scalar_mode inner_mode = GET_MODE_INNER (mode);
8174 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8175 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8176 rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
8177 rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
8178 rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
8179 rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
8180 rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
8181 rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
8182 neg_scalar_reg);
8183 ASSERT_RTX_EQ (series_0_r,
8184 simplify_unary_operation (NEG, mode, series_0_nr, mode));
8185 ASSERT_RTX_EQ (series_r_m1,
8186 simplify_unary_operation (NEG, mode, series_nr_1, mode));
8187 ASSERT_RTX_EQ (series_r_r,
8188 simplify_unary_operation (NEG, mode, series_nr_nr, mode));
8190 /* Test that a VEC_SERIES with a zero step is simplified away. */
8191 ASSERT_RTX_EQ (duplicate,
8192 simplify_binary_operation (VEC_SERIES, mode,
8193 scalar_reg, const0_rtx));
8195 /* Test PLUS and MINUS with VEC_SERIES. */
8196 rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
8197 rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
8198 rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
8199 ASSERT_RTX_EQ (series_r_r,
8200 simplify_binary_operation (PLUS, mode, series_0_r,
8201 duplicate));
8202 ASSERT_RTX_EQ (series_r_1,
8203 simplify_binary_operation (PLUS, mode, duplicate,
8204 series_0_1));
8205 ASSERT_RTX_EQ (series_r_m1,
8206 simplify_binary_operation (PLUS, mode, duplicate,
8207 series_0_m1));
8208 ASSERT_RTX_EQ (series_0_r,
8209 simplify_binary_operation (MINUS, mode, series_r_r,
8210 duplicate));
8211 ASSERT_RTX_EQ (series_r_m1,
8212 simplify_binary_operation (MINUS, mode, duplicate,
8213 series_0_1));
8214 ASSERT_RTX_EQ (series_r_1,
8215 simplify_binary_operation (MINUS, mode, duplicate,
8216 series_0_m1));
8217 ASSERT_RTX_EQ (series_0_m1,
8218 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
8219 constm1_rtx));
8221 /* Test NEG on constant vector series. */
8222 ASSERT_RTX_EQ (series_0_m1,
8223 simplify_unary_operation (NEG, mode, series_0_1, mode));
8224 ASSERT_RTX_EQ (series_0_1,
8225 simplify_unary_operation (NEG, mode, series_0_m1, mode));
8227 /* Test PLUS and MINUS on constant vector series. */
8228 rtx scalar2 = gen_int_mode (2, inner_mode);
8229 rtx scalar3 = gen_int_mode (3, inner_mode);
8230 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
8231 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
8232 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
8233 ASSERT_RTX_EQ (series_1_1,
8234 simplify_binary_operation (PLUS, mode, series_0_1,
8235 CONST1_RTX (mode)));
8236 ASSERT_RTX_EQ (series_0_m1,
8237 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
8238 series_0_m1));
8239 ASSERT_RTX_EQ (series_1_3,
8240 simplify_binary_operation (PLUS, mode, series_1_1,
8241 series_0_2));
8242 ASSERT_RTX_EQ (series_0_1,
8243 simplify_binary_operation (MINUS, mode, series_1_1,
8244 CONST1_RTX (mode)));
8245 ASSERT_RTX_EQ (series_1_1,
8246 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
8247 series_0_m1));
8248 ASSERT_RTX_EQ (series_1_1,
8249 simplify_binary_operation (MINUS, mode, series_1_3,
8250 series_0_2));
8252 /* Test MULT between constant vectors. */
8253 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
8254 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
8255 rtx scalar9 = gen_int_mode (9, inner_mode);
8256 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
8257 ASSERT_RTX_EQ (series_0_2,
8258 simplify_binary_operation (MULT, mode, series_0_1, vec2));
8259 ASSERT_RTX_EQ (series_3_9,
8260 simplify_binary_operation (MULT, mode, vec3, series_1_3));
8261 if (!GET_MODE_NUNITS (mode).is_constant ())
8262 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
8263 series_0_1));
8265 /* Test ASHIFT between constant vectors. */
8266 ASSERT_RTX_EQ (series_0_2,
8267 simplify_binary_operation (ASHIFT, mode, series_0_1,
8268 CONST1_RTX (mode)));
8269 if (!GET_MODE_NUNITS (mode).is_constant ())
8270 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
8271 series_0_1));
8274 static rtx
8275 simplify_merge_mask (rtx x, rtx mask, int op)
8277 return simplify_context ().simplify_merge_mask (x, mask, op);
8280 /* Verify simplify_merge_mask works correctly. */
8282 static void
8283 test_vec_merge (machine_mode mode)
8285 rtx op0 = make_test_reg (mode);
8286 rtx op1 = make_test_reg (mode);
8287 rtx op2 = make_test_reg (mode);
8288 rtx op3 = make_test_reg (mode);
8289 rtx op4 = make_test_reg (mode);
8290 rtx op5 = make_test_reg (mode);
8291 rtx mask1 = make_test_reg (SImode);
8292 rtx mask2 = make_test_reg (SImode);
8293 rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
8294 rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
8295 rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
8297 /* Simple vec_merge. */
8298 ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
8299 ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
8300 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
8301 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
8303 /* Nested vec_merge.
8304 It's tempting to make this simplify right down to opN, but we don't
8305 because all the simplify_* functions assume that the operands have
8306 already been simplified. */
8307 rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
8308 ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
8309 ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
8311 /* Intermediate unary op. */
8312 rtx unop = gen_rtx_NOT (mode, vm1);
8313 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
8314 simplify_merge_mask (unop, mask1, 0));
8315 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
8316 simplify_merge_mask (unop, mask1, 1));
8318 /* Intermediate binary op. */
8319 rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
8320 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
8321 simplify_merge_mask (binop, mask1, 0));
8322 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
8323 simplify_merge_mask (binop, mask1, 1));
8325 /* Intermediate ternary op. */
8326 rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
8327 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
8328 simplify_merge_mask (tenop, mask1, 0));
8329 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
8330 simplify_merge_mask (tenop, mask1, 1));
8332 /* Side effects. */
8333 rtx badop0 = gen_rtx_PRE_INC (mode, op0);
8334 rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
8335 ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
8336 ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
8338 /* Called indirectly. */
8339 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
8340 simplify_rtx (nvm));
8343 /* Test subregs of integer vector constant X, trying elements in
8344 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
8345 where NELTS is the number of elements in X. Subregs involving
8346 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
8348 static void
8349 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
8350 unsigned int first_valid = 0)
8352 machine_mode inner_mode = GET_MODE (x);
8353 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8355 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
8357 machine_mode outer_mode = (machine_mode) modei;
8358 if (!VECTOR_MODE_P (outer_mode))
8359 continue;
8361 unsigned int outer_nunits;
8362 if (GET_MODE_INNER (outer_mode) == int_mode
8363 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
8364 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
8366 /* Test subregs in which the outer mode is a smaller,
8367 constant-sized vector of the same element type. */
8368 unsigned int limit
8369 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
8370 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
8372 rtx expected = NULL_RTX;
8373 if (elt >= first_valid)
8375 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
8376 for (unsigned int i = 0; i < outer_nunits; ++i)
8377 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
8378 expected = builder.build ();
8380 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
8381 ASSERT_RTX_EQ (expected,
8382 simplify_subreg (outer_mode, x,
8383 inner_mode, byte));
8386 else if (known_eq (GET_MODE_SIZE (outer_mode),
8387 GET_MODE_SIZE (inner_mode))
8388 && known_eq (elt_bias, 0U)
8389 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
8390 || known_eq (GET_MODE_BITSIZE (outer_mode),
8391 GET_MODE_NUNITS (outer_mode)))
8392 && (!FLOAT_MODE_P (outer_mode)
8393 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
8394 == GET_MODE_UNIT_PRECISION (outer_mode)))
8395 && (GET_MODE_SIZE (inner_mode).is_constant ()
8396 || !CONST_VECTOR_STEPPED_P (x)))
8398 /* Try converting to OUTER_MODE and back. */
8399 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
8400 ASSERT_TRUE (outer_x != NULL_RTX);
8401 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
8402 outer_mode, 0));
8406 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
8408 /* Test each byte in the element range. */
8409 unsigned int limit
8410 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
8411 for (unsigned int i = 0; i < limit; ++i)
8413 unsigned int elt = i / GET_MODE_SIZE (int_mode);
8414 rtx expected = NULL_RTX;
8415 if (elt >= first_valid)
8417 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
8418 if (BYTES_BIG_ENDIAN)
8419 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
8420 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
8421 wide_int shifted_elt
8422 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
8423 expected = immed_wide_int_const (shifted_elt, QImode);
8425 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
8426 ASSERT_RTX_EQ (expected,
8427 simplify_subreg (QImode, x, inner_mode, byte));
8432 /* Test constant subregs of integer vector mode INNER_MODE, using 1
8433 element per pattern. */
8435 static void
8436 test_vector_subregs_repeating (machine_mode inner_mode)
8438 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8439 unsigned int min_nunits = constant_lower_bound (nunits);
8440 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8441 unsigned int count = gcd (min_nunits, 8);
8443 rtx_vector_builder builder (inner_mode, count, 1);
8444 for (unsigned int i = 0; i < count; ++i)
8445 builder.quick_push (gen_int_mode (8 - i, int_mode));
8446 rtx x = builder.build ();
8448 test_vector_subregs_modes (x);
8449 if (!nunits.is_constant ())
8450 test_vector_subregs_modes (x, nunits - min_nunits);
8453 /* Test constant subregs of integer vector mode INNER_MODE, using 2
8454 elements per pattern. */
8456 static void
8457 test_vector_subregs_fore_back (machine_mode inner_mode)
8459 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8460 unsigned int min_nunits = constant_lower_bound (nunits);
8461 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8462 unsigned int count = gcd (min_nunits, 4);
8464 rtx_vector_builder builder (inner_mode, count, 2);
8465 for (unsigned int i = 0; i < count; ++i)
8466 builder.quick_push (gen_int_mode (i, int_mode));
8467 for (unsigned int i = 0; i < count; ++i)
8468 builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
8469 rtx x = builder.build ();
8471 test_vector_subregs_modes (x);
8472 if (!nunits.is_constant ())
8473 test_vector_subregs_modes (x, nunits - min_nunits, count);
8476 /* Test constant subregs of integer vector mode INNER_MODE, using 3
8477 elements per pattern. */
8479 static void
8480 test_vector_subregs_stepped (machine_mode inner_mode)
8482 /* Build { 0, 1, 2, 3, ... }. */
8483 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8484 rtx_vector_builder builder (inner_mode, 1, 3);
8485 for (unsigned int i = 0; i < 3; ++i)
8486 builder.quick_push (gen_int_mode (i, int_mode));
8487 rtx x = builder.build ();
8489 test_vector_subregs_modes (x);
8492 /* Test constant subregs of integer vector mode INNER_MODE. */
8494 static void
8495 test_vector_subregs (machine_mode inner_mode)
8497 test_vector_subregs_repeating (inner_mode);
8498 test_vector_subregs_fore_back (inner_mode);
8499 test_vector_subregs_stepped (inner_mode);
8502 /* Verify some simplifications involving vectors. */
8504 static void
8505 test_vector_ops ()
8507 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8509 machine_mode mode = (machine_mode) i;
8510 if (VECTOR_MODE_P (mode))
8512 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
8513 test_vector_ops_duplicate (mode, scalar_reg);
8514 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
8515 && maybe_gt (GET_MODE_NUNITS (mode), 2))
8517 test_vector_ops_series (mode, scalar_reg);
8518 test_vector_subregs (mode);
8520 test_vec_merge (mode);
8525 template<unsigned int N>
8526 struct simplify_const_poly_int_tests
8528 static void run ();
8531 template<>
8532 struct simplify_const_poly_int_tests<1>
8534 static void run () {}
8537 /* Test various CONST_POLY_INT properties. */
8539 template<unsigned int N>
8540 void
8541 simplify_const_poly_int_tests<N>::run ()
8543 rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
8544 rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
8545 rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
8546 rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
8547 rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
8548 rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
8549 rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
8550 rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
8551 rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
8552 rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
8553 rtx two = GEN_INT (2);
8554 rtx six = GEN_INT (6);
8555 poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
8557 /* These tests only try limited operation combinations. Fuller arithmetic
8558 testing is done directly on poly_ints. */
8559 ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
8560 ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
8561 ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
8562 ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
8563 ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
8564 ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
8565 ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
8566 ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
8567 ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
8568 ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
8569 ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
8572 /* Run all of the selftests within this file. */
8574 void
8575 simplify_rtx_cc_tests ()
8577 test_scalar_ops ();
8578 test_vector_ops ();
8579 simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
8582 } // namespace selftest
8584 #endif /* CHECKING_P */