1 /* RTL simplification functions for GNU compiler.
2 Copyright (C) 1987-2024 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
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
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/>. */
23 #include "coretypes.h"
33 #include "diagnostic-core.h"
37 #include "selftest-rtl.h"
38 #include "rtx-vector-builder.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
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. */
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. */
64 mode_signbit_p (machine_mode mode
, const_rtx x
)
66 unsigned HOST_WIDE_INT val
;
68 scalar_int_mode int_mode
;
70 if (!is_int_mode (mode
, &int_mode
))
73 width
= GET_MODE_PRECISION (int_mode
);
77 if (width
<= HOST_BITS_PER_WIDE_INT
80 #if TARGET_SUPPORTS_WIDE_INT
81 else if (CONST_WIDE_INT_P (x
))
84 unsigned int elts
= CONST_WIDE_INT_NUNITS (x
);
85 if (elts
!= (width
+ HOST_BITS_PER_WIDE_INT
- 1) / HOST_BITS_PER_WIDE_INT
)
87 for (i
= 0; i
< elts
- 1; i
++)
88 if (CONST_WIDE_INT_ELT (x
, i
) != 0)
90 val
= CONST_WIDE_INT_ELT (x
, elts
- 1);
91 width
%= HOST_BITS_PER_WIDE_INT
;
93 width
= HOST_BITS_PER_WIDE_INT
;
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
;
105 /* X is not an integer constant. */
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. */
118 val_signbit_p (machine_mode mode
, unsigned HOST_WIDE_INT val
)
121 scalar_int_mode int_mode
;
123 if (!is_int_mode (mode
, &int_mode
))
126 width
= GET_MODE_PRECISION (int_mode
);
127 if (width
== 0 || width
> HOST_BITS_PER_WIDE_INT
)
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. */
137 val_signbit_known_set_p (machine_mode mode
, unsigned HOST_WIDE_INT val
)
141 scalar_int_mode int_mode
;
142 if (!is_int_mode (mode
, &int_mode
))
145 width
= GET_MODE_PRECISION (int_mode
);
146 if (width
== 0 || width
> HOST_BITS_PER_WIDE_INT
)
149 val
&= HOST_WIDE_INT_1U
<< (width
- 1);
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. */
156 val_signbit_known_clear_p (machine_mode mode
, unsigned HOST_WIDE_INT val
)
160 scalar_int_mode int_mode
;
161 if (!is_int_mode (mode
, &int_mode
))
164 width
= GET_MODE_PRECISION (int_mode
);
165 if (width
== 0 || width
> HOST_BITS_PER_WIDE_INT
)
168 val
&= HOST_WIDE_INT_1U
<< (width
- 1);
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
,
181 /* If this simplifies, do it. */
182 tem
= simplify_binary_operation (code
, mode
, op0
, op1
);
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
)
201 poly_int64 offset
= 0;
203 switch (GET_CODE (x
))
209 /* Handle float extensions of constant pool references. */
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
),
221 if (GET_MODE (x
) == BLKmode
)
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
))
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
))
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. */
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
))
286 case ARRAY_RANGE_REF
:
291 case VIEW_CONVERT_EXPR
:
293 poly_int64 bitsize
, bitpos
, bytepos
, toffset_val
= 0;
295 int unsignedp
, reversep
, volatilep
= 0;
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
)))
305 offset
+= bytepos
+ toffset_val
;
311 && mode
== GET_MODE (x
)
313 && (TREE_STATIC (decl
)
314 || DECL_THREAD_LOCAL_P (decl
))
315 && DECL_RTL_SET_P (decl
)
316 && MEM_P (DECL_RTL (decl
)))
320 offset
+= MEM_OFFSET (x
);
322 newx
= DECL_RTL (decl
);
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))
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
)
359 /* If this simplifies, use it. */
360 if ((tem
= simplify_unary_operation (code
, mode
, op
, op_mode
)) != 0)
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
)
375 /* If this simplifies, use it. */
376 if ((tem
= simplify_ternary_operation (code
, mode
, op0_mode
,
377 op0
, op1
, op2
)) != 0)
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
,
393 if ((tem
= simplify_relational_operation (code
, mode
, cmp_mode
,
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
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
;
413 rtx op0
, op1
, op2
, newx
, op
;
417 if (UNLIKELY (fn
!= NULL
))
419 newx
= fn (x
, old_rtx
, data
);
423 else if (rtx_equal_p (x
, old_rtx
))
424 return copy_rtx ((rtx
) data
);
426 switch (GET_RTX_CLASS (code
))
430 op_mode
= GET_MODE (op0
);
431 op0
= simplify_replace_fn_rtx (op0
, old_rtx
, fn
, data
);
432 if (op0
== XEXP (x
, 0))
434 return simplify_gen_unary (code
, mode
, op0
, op_mode
);
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))
442 return simplify_gen_binary (code
, mode
, op0
, op1
);
445 case RTX_COMM_COMPARE
:
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))
453 return simplify_gen_relational (code
, mode
, op_mode
, op0
, op1
);
456 case RTX_BITFIELD_OPS
:
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))
464 if (op_mode
== VOIDmode
)
465 op_mode
= GET_MODE (op0
);
466 return simplify_gen_ternary (code
, mode
, op_mode
, op0
, op1
, op2
);
471 op0
= simplify_replace_fn_rtx (SUBREG_REG (x
), old_rtx
, fn
, data
);
472 if (op0
== SUBREG_REG (x
))
474 op0
= simplify_gen_subreg (GET_MODE (x
), op0
,
475 GET_MODE (SUBREG_REG (x
)),
477 return op0
? op0
: x
;
484 op0
= simplify_replace_fn_rtx (XEXP (x
, 0), old_rtx
, fn
, data
);
485 if (op0
== XEXP (x
, 0))
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
))
504 if (op0
== XEXP (x
, 0) && op1
== XEXP (x
, 1))
506 return gen_rtx_LO_SUM (mode
, op0
, op1
);
515 fmt
= GET_RTX_FORMAT (code
);
516 for (i
= 0; fmt
[i
]; 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
),
526 if (op
!= RTVEC_ELT (vec
, j
))
530 newvec
= shallow_copy_rtvec (vec
);
532 newx
= shallow_copy_rtx (x
);
533 XVEC (newx
, i
) = newvec
;
535 RTVEC_ELT (newvec
, j
) = op
;
543 op
= simplify_replace_fn_rtx (XEXP (x
, i
), old_rtx
, fn
, data
);
544 if (op
!= XEXP (x
, i
))
547 newx
= shallow_copy_rtx (x
);
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
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
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
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
632 machine_mode origmode
= GET_MODE (XEXP (op
, 0));
633 if (mode
== origmode
)
635 else if (precision
<= GET_MODE_UNIT_PRECISION (origmode
))
636 return simplify_gen_unary (TRUNCATE
, mode
,
637 XEXP (op
, 0), origmode
);
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))). */
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
);
655 rtx op1
= simplify_gen_unary (TRUNCATE
, mode
, XEXP (op
, 1), op_mode
);
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
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
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
));
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
));
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
,
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
,
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
,
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
),
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,
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)
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
)
887 trueop
= avoid_constant_pool_reference (op
);
889 tem
= simplify_const_unary_operation (code
, mode
, trueop
, op_mode
);
893 return simplify_unary_operation_1 (code
, mode
, op
);
896 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
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
)
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
);
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
927 simplify_context::simplify_unary_operation_1 (rtx_code code
, machine_mode mode
,
930 enum rtx_code reversed
;
931 rtx temp
, elt
, base
, step
;
932 scalar_int_mode inner
, int_mode
, op_mode
, op0_mode
;
937 /* (not (not X)) == X. */
938 if (GET_CODE (op
) == NOT
)
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),
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
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
));
1009 x
= gen_rtx_ROTATE (inner_mode
,
1010 simplify_gen_unary (NOT
, inner_mode
, const1_rtx
,
1012 XEXP (SUBREG_REG (op
), 1));
1013 temp
= rtl_hooks
.gen_lowpart_no_emit (mode
, x
);
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
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
)
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
,
1042 /* (not (bswap x)) -> (bswap (not x)). */
1043 if (GET_CODE (op
) == BSWAP
|| GET_CODE (op
) == BITREVERSE
)
1045 rtx x
= simplify_gen_unary (NOT
, mode
, XEXP (op
, 0), mode
);
1046 return simplify_gen_unary (GET_CODE (op
), mode
, x
, mode
);
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
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
);
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),
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
);
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
1131 if (GET_CODE (op
) == ASHIFT
)
1133 temp
= simplify_unary_operation (NEG
, mode
, XEXP (op
, 0), mode
);
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
,
1173 if (int_mode
== inner
)
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
,
1184 if (int_mode
== inner
)
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
);
1201 step
= simplify_unary_operation (NEG
, inner_mode
,
1204 return gen_vec_series (mode
, base
, step
);
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
)
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
);
1224 /* We can't handle truncation to a partial integer mode here
1225 because we don't know the real bitsize of the partial
1230 if (GET_MODE (op
) != VOIDmode
)
1232 temp
= simplify_truncation (mode
, op
, GET_MODE (op
));
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
);
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
);
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
);
1274 /* Check for useless truncation. */
1275 if (GET_MODE (op
) == mode
)
1279 case FLOAT_TRUNCATE
:
1280 /* Check for useless truncation. */
1281 if (GET_MODE (op
) == mode
)
1284 if (DECIMAL_FLOAT_MODE_P (mode
))
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
,
1308 XEXP (op
, 0), GET_MODE (XEXP (op
, 0)));
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
,
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
);
1336 /* Check for useless extension. */
1337 if (GET_MODE (op
) == mode
)
1340 if (DECIMAL_FLOAT_MODE_P (mode
))
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
,
1353 GET_MODE (XEXP (op
, 0)));
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),
1365 if (GET_MODE (op
) == VOIDmode
)
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
))))
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
))
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
))
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
);
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
,
1419 switch (GET_CODE (op
))
1423 /* (popcount (bswap <X>)) = (popcount <X>). */
1424 return simplify_gen_unary (POPCOUNT
, mode
, XEXP (op
, 0),
1425 GET_MODE (XEXP (op
, 0)));
1428 /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1429 temp
= simplify_gen_unary (POPCOUNT
, GET_MODE (XEXP (op
, 0)),
1430 XEXP (op
, 0), GET_MODE (XEXP (op
, 0)));
1431 return simplify_gen_unary (ZERO_EXTEND
, mode
, temp
,
1436 /* Rotations don't affect popcount. */
1437 if (!side_effects_p (XEXP (op
, 1)))
1438 return simplify_gen_unary (POPCOUNT
, mode
, XEXP (op
, 0),
1439 GET_MODE (XEXP (op
, 0)));
1448 switch (GET_CODE (op
))
1453 return simplify_gen_unary (PARITY
, mode
, XEXP (op
, 0),
1454 GET_MODE (XEXP (op
, 0)));
1458 temp
= simplify_gen_unary (PARITY
, GET_MODE (XEXP (op
, 0)),
1459 XEXP (op
, 0), GET_MODE (XEXP (op
, 0)));
1460 return simplify_gen_unary (GET_CODE (op
), mode
, temp
,
1465 /* Rotations don't affect parity. */
1466 if (!side_effects_p (XEXP (op
, 1)))
1467 return simplify_gen_unary (PARITY
, mode
, XEXP (op
, 0),
1468 GET_MODE (XEXP (op
, 0)));
1472 /* (parity (parity x)) -> parity (x). */
1481 /* (bswap (bswap x)) -> x. */
1482 if (GET_CODE (op
) == BSWAP
)
1483 return XEXP (op
, 0);
1487 /* (bitreverse (bitreverse x)) -> x. */
1488 if (GET_CODE (op
) == BITREVERSE
)
1489 return XEXP (op
, 0);
1493 /* (float (sign_extend <X>)) = (float <X>). */
1494 if (GET_CODE (op
) == SIGN_EXTEND
)
1495 return simplify_gen_unary (FLOAT
, mode
, XEXP (op
, 0),
1496 GET_MODE (XEXP (op
, 0)));
1500 /* Check for useless extension. */
1501 if (GET_MODE (op
) == mode
)
1504 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1505 becomes just the MINUS if its mode is MODE. This allows
1506 folding switch statements on machines using casesi (such as
1508 if (GET_CODE (op
) == TRUNCATE
1509 && GET_MODE (XEXP (op
, 0)) == mode
1510 && GET_CODE (XEXP (op
, 0)) == MINUS
1511 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == LABEL_REF
1512 && GET_CODE (XEXP (XEXP (op
, 0), 1)) == LABEL_REF
)
1513 return XEXP (op
, 0);
1515 /* Extending a widening multiplication should be canonicalized to
1516 a wider widening multiplication. */
1517 if (GET_CODE (op
) == MULT
)
1519 rtx lhs
= XEXP (op
, 0);
1520 rtx rhs
= XEXP (op
, 1);
1521 enum rtx_code lcode
= GET_CODE (lhs
);
1522 enum rtx_code rcode
= GET_CODE (rhs
);
1524 /* Widening multiplies usually extend both operands, but sometimes
1525 they use a shift to extract a portion of a register. */
1526 if ((lcode
== SIGN_EXTEND
1527 || (lcode
== ASHIFTRT
&& CONST_INT_P (XEXP (lhs
, 1))))
1528 && (rcode
== SIGN_EXTEND
1529 || (rcode
== ASHIFTRT
&& CONST_INT_P (XEXP (rhs
, 1)))))
1531 machine_mode lmode
= GET_MODE (lhs
);
1532 machine_mode rmode
= GET_MODE (rhs
);
1535 if (lcode
== ASHIFTRT
)
1536 /* Number of bits not shifted off the end. */
1537 bits
= (GET_MODE_UNIT_PRECISION (lmode
)
1538 - INTVAL (XEXP (lhs
, 1)));
1539 else /* lcode == SIGN_EXTEND */
1540 /* Size of inner mode. */
1541 bits
= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs
, 0)));
1543 if (rcode
== ASHIFTRT
)
1544 bits
+= (GET_MODE_UNIT_PRECISION (rmode
)
1545 - INTVAL (XEXP (rhs
, 1)));
1546 else /* rcode == SIGN_EXTEND */
1547 bits
+= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs
, 0)));
1549 /* We can only widen multiplies if the result is mathematiclly
1550 equivalent. I.e. if overflow was impossible. */
1551 if (bits
<= GET_MODE_UNIT_PRECISION (GET_MODE (op
)))
1552 return simplify_gen_binary
1554 simplify_gen_unary (SIGN_EXTEND
, mode
, lhs
, lmode
),
1555 simplify_gen_unary (SIGN_EXTEND
, mode
, rhs
, rmode
));
1559 /* Check for a sign extension of a subreg of a promoted
1560 variable, where the promotion is sign-extended, and the
1561 target mode is the same as the variable's promotion. */
1562 if (GET_CODE (op
) == SUBREG
1563 && SUBREG_PROMOTED_VAR_P (op
)
1564 && SUBREG_PROMOTED_SIGNED_P (op
))
1566 rtx subreg
= SUBREG_REG (op
);
1567 machine_mode subreg_mode
= GET_MODE (subreg
);
1568 if (!paradoxical_subreg_p (mode
, subreg_mode
))
1570 temp
= rtl_hooks
.gen_lowpart_no_emit (mode
, subreg
);
1573 /* Preserve SUBREG_PROMOTED_VAR_P. */
1574 if (partial_subreg_p (temp
))
1576 SUBREG_PROMOTED_VAR_P (temp
) = 1;
1577 SUBREG_PROMOTED_SET (temp
, SRP_SIGNED
);
1583 /* Sign-extending a sign-extended subreg. */
1584 return simplify_gen_unary (SIGN_EXTEND
, mode
,
1585 subreg
, subreg_mode
);
1588 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1589 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1590 if (GET_CODE (op
) == SIGN_EXTEND
|| GET_CODE (op
) == ZERO_EXTEND
)
1592 gcc_assert (GET_MODE_UNIT_PRECISION (mode
)
1593 > GET_MODE_UNIT_PRECISION (GET_MODE (op
)));
1594 return simplify_gen_unary (GET_CODE (op
), mode
, XEXP (op
, 0),
1595 GET_MODE (XEXP (op
, 0)));
1598 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1599 is (sign_extend:M (subreg:O <X>)) if there is mode with
1600 GET_MODE_BITSIZE (N) - I bits.
1601 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1602 is similarly (zero_extend:M (subreg:O <X>)). */
1603 if ((GET_CODE (op
) == ASHIFTRT
|| GET_CODE (op
) == LSHIFTRT
)
1604 && GET_CODE (XEXP (op
, 0)) == ASHIFT
1605 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
1606 && CONST_INT_P (XEXP (op
, 1))
1607 && XEXP (XEXP (op
, 0), 1) == XEXP (op
, 1)
1608 && (op_mode
= as_a
<scalar_int_mode
> (GET_MODE (op
)),
1609 GET_MODE_PRECISION (op_mode
) > INTVAL (XEXP (op
, 1))))
1611 scalar_int_mode tmode
;
1612 gcc_assert (GET_MODE_PRECISION (int_mode
)
1613 > GET_MODE_PRECISION (op_mode
));
1614 if (int_mode_for_size (GET_MODE_PRECISION (op_mode
)
1615 - INTVAL (XEXP (op
, 1)), 1).exists (&tmode
))
1618 rtl_hooks
.gen_lowpart_no_emit (tmode
, XEXP (XEXP (op
, 0), 0));
1620 return simplify_gen_unary (GET_CODE (op
) == ASHIFTRT
1621 ? SIGN_EXTEND
: ZERO_EXTEND
,
1622 int_mode
, inner
, tmode
);
1626 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1627 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1628 if (GET_CODE (op
) == LSHIFTRT
1629 && CONST_INT_P (XEXP (op
, 1))
1630 && XEXP (op
, 1) != const0_rtx
)
1631 return simplify_gen_unary (ZERO_EXTEND
, mode
, op
, GET_MODE (op
));
1633 /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1634 I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1635 (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1636 (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1637 O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1639 if (GET_CODE (op
) == TRUNCATE
1640 && GET_CODE (XEXP (op
, 0)) == LSHIFTRT
1641 && CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
1643 scalar_int_mode m_mode
, n_mode
, o_mode
;
1644 rtx old_shift
= XEXP (op
, 0);
1645 if (is_a
<scalar_int_mode
> (mode
, &m_mode
)
1646 && is_a
<scalar_int_mode
> (GET_MODE (op
), &n_mode
)
1647 && is_a
<scalar_int_mode
> (GET_MODE (old_shift
), &o_mode
)
1648 && GET_MODE_PRECISION (o_mode
) - GET_MODE_PRECISION (n_mode
)
1649 == INTVAL (XEXP (old_shift
, 1)))
1651 rtx new_shift
= simplify_gen_binary (ASHIFTRT
,
1652 GET_MODE (old_shift
),
1653 XEXP (old_shift
, 0),
1654 XEXP (old_shift
, 1));
1655 if (GET_MODE_PRECISION (m_mode
) > GET_MODE_PRECISION (o_mode
))
1656 return simplify_gen_unary (SIGN_EXTEND
, mode
, new_shift
,
1657 GET_MODE (new_shift
));
1658 if (mode
!= GET_MODE (new_shift
))
1659 return simplify_gen_unary (TRUNCATE
, mode
, new_shift
,
1660 GET_MODE (new_shift
));
1665 /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1666 we know the sign bit of OP must be clear. */
1667 if (val_signbit_known_clear_p (GET_MODE (op
),
1668 nonzero_bits (op
, GET_MODE (op
))))
1669 return simplify_gen_unary (ZERO_EXTEND
, mode
, op
, GET_MODE (op
));
1671 /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1672 if (GET_CODE (op
) == SUBREG
1673 && subreg_lowpart_p (op
)
1674 && GET_MODE (SUBREG_REG (op
)) == mode
1675 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
1676 && is_a
<scalar_int_mode
> (GET_MODE (op
), &op_mode
)
1677 && GET_MODE_PRECISION (int_mode
) <= HOST_BITS_PER_WIDE_INT
1678 && GET_MODE_PRECISION (op_mode
) < GET_MODE_PRECISION (int_mode
)
1679 && (nonzero_bits (SUBREG_REG (op
), mode
)
1680 & ~(GET_MODE_MASK (op_mode
) >> 1)) == 0)
1681 return SUBREG_REG (op
);
1683 #if defined(POINTERS_EXTEND_UNSIGNED)
1684 /* As we do not know which address space the pointer is referring to,
1685 we can do this only if the target does not support different pointer
1686 or address modes depending on the address space. */
1687 if (target_default_pointer_address_modes_p ()
1688 && ! POINTERS_EXTEND_UNSIGNED
1689 && mode
== Pmode
&& GET_MODE (op
) == ptr_mode
1691 || (GET_CODE (op
) == SUBREG
1692 && REG_P (SUBREG_REG (op
))
1693 && REG_POINTER (SUBREG_REG (op
))
1694 && GET_MODE (SUBREG_REG (op
)) == Pmode
))
1695 && !targetm
.have_ptr_extend ())
1698 = convert_memory_address_addr_space_1 (Pmode
, op
,
1699 ADDR_SPACE_GENERIC
, false,
1708 /* Check for useless extension. */
1709 if (GET_MODE (op
) == mode
)
1712 /* Check for a zero extension of a subreg of a promoted
1713 variable, where the promotion is zero-extended, and the
1714 target mode is the same as the variable's promotion. */
1715 if (GET_CODE (op
) == SUBREG
1716 && SUBREG_PROMOTED_VAR_P (op
)
1717 && SUBREG_PROMOTED_UNSIGNED_P (op
))
1719 rtx subreg
= SUBREG_REG (op
);
1720 machine_mode subreg_mode
= GET_MODE (subreg
);
1721 if (!paradoxical_subreg_p (mode
, subreg_mode
))
1723 temp
= rtl_hooks
.gen_lowpart_no_emit (mode
, subreg
);
1726 /* Preserve SUBREG_PROMOTED_VAR_P. */
1727 if (partial_subreg_p (temp
))
1729 SUBREG_PROMOTED_VAR_P (temp
) = 1;
1730 SUBREG_PROMOTED_SET (temp
, SRP_UNSIGNED
);
1736 /* Zero-extending a zero-extended subreg. */
1737 return simplify_gen_unary (ZERO_EXTEND
, mode
,
1738 subreg
, subreg_mode
);
1741 /* Extending a widening multiplication should be canonicalized to
1742 a wider widening multiplication. */
1743 if (GET_CODE (op
) == MULT
)
1745 rtx lhs
= XEXP (op
, 0);
1746 rtx rhs
= XEXP (op
, 1);
1747 enum rtx_code lcode
= GET_CODE (lhs
);
1748 enum rtx_code rcode
= GET_CODE (rhs
);
1750 /* Widening multiplies usually extend both operands, but sometimes
1751 they use a shift to extract a portion of a register. */
1752 if ((lcode
== ZERO_EXTEND
1753 || (lcode
== LSHIFTRT
&& CONST_INT_P (XEXP (lhs
, 1))))
1754 && (rcode
== ZERO_EXTEND
1755 || (rcode
== LSHIFTRT
&& CONST_INT_P (XEXP (rhs
, 1)))))
1757 machine_mode lmode
= GET_MODE (lhs
);
1758 machine_mode rmode
= GET_MODE (rhs
);
1761 if (lcode
== LSHIFTRT
)
1762 /* Number of bits not shifted off the end. */
1763 bits
= (GET_MODE_UNIT_PRECISION (lmode
)
1764 - INTVAL (XEXP (lhs
, 1)));
1765 else /* lcode == ZERO_EXTEND */
1766 /* Size of inner mode. */
1767 bits
= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs
, 0)));
1769 if (rcode
== LSHIFTRT
)
1770 bits
+= (GET_MODE_UNIT_PRECISION (rmode
)
1771 - INTVAL (XEXP (rhs
, 1)));
1772 else /* rcode == ZERO_EXTEND */
1773 bits
+= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs
, 0)));
1775 /* We can only widen multiplies if the result is mathematiclly
1776 equivalent. I.e. if overflow was impossible. */
1777 if (bits
<= GET_MODE_UNIT_PRECISION (GET_MODE (op
)))
1778 return simplify_gen_binary
1780 simplify_gen_unary (ZERO_EXTEND
, mode
, lhs
, lmode
),
1781 simplify_gen_unary (ZERO_EXTEND
, mode
, rhs
, rmode
));
1785 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1786 if (GET_CODE (op
) == ZERO_EXTEND
)
1787 return simplify_gen_unary (ZERO_EXTEND
, mode
, XEXP (op
, 0),
1788 GET_MODE (XEXP (op
, 0)));
1790 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1791 is (zero_extend:M (subreg:O <X>)) if there is mode with
1792 GET_MODE_PRECISION (N) - I bits. */
1793 if (GET_CODE (op
) == LSHIFTRT
1794 && GET_CODE (XEXP (op
, 0)) == ASHIFT
1795 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
1796 && CONST_INT_P (XEXP (op
, 1))
1797 && XEXP (XEXP (op
, 0), 1) == XEXP (op
, 1)
1798 && (op_mode
= as_a
<scalar_int_mode
> (GET_MODE (op
)),
1799 GET_MODE_PRECISION (op_mode
) > INTVAL (XEXP (op
, 1))))
1801 scalar_int_mode tmode
;
1802 if (int_mode_for_size (GET_MODE_PRECISION (op_mode
)
1803 - INTVAL (XEXP (op
, 1)), 1).exists (&tmode
))
1806 rtl_hooks
.gen_lowpart_no_emit (tmode
, XEXP (XEXP (op
, 0), 0));
1808 return simplify_gen_unary (ZERO_EXTEND
, int_mode
,
1813 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1814 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1816 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1817 (and:SI (reg:SI) (const_int 63)). */
1818 if (partial_subreg_p (op
)
1819 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
1820 && is_a
<scalar_int_mode
> (GET_MODE (SUBREG_REG (op
)), &op0_mode
)
1821 && GET_MODE_PRECISION (op0_mode
) <= HOST_BITS_PER_WIDE_INT
1822 && GET_MODE_PRECISION (int_mode
) >= GET_MODE_PRECISION (op0_mode
)
1823 && subreg_lowpart_p (op
)
1824 && (nonzero_bits (SUBREG_REG (op
), op0_mode
)
1825 & ~GET_MODE_MASK (GET_MODE (op
))) == 0)
1827 if (GET_MODE_PRECISION (int_mode
) == GET_MODE_PRECISION (op0_mode
))
1828 return SUBREG_REG (op
);
1829 return simplify_gen_unary (ZERO_EXTEND
, int_mode
, SUBREG_REG (op
),
1833 /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1834 if (GET_CODE (op
) == SUBREG
1835 && subreg_lowpart_p (op
)
1836 && GET_MODE (SUBREG_REG (op
)) == mode
1837 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
1838 && is_a
<scalar_int_mode
> (GET_MODE (op
), &op_mode
)
1839 && GET_MODE_PRECISION (int_mode
) <= HOST_BITS_PER_WIDE_INT
1840 && GET_MODE_PRECISION (op_mode
) < GET_MODE_PRECISION (int_mode
)
1841 && (nonzero_bits (SUBREG_REG (op
), mode
)
1842 & ~GET_MODE_MASK (op_mode
)) == 0)
1843 return SUBREG_REG (op
);
1845 #if defined(POINTERS_EXTEND_UNSIGNED)
1846 /* As we do not know which address space the pointer is referring to,
1847 we can do this only if the target does not support different pointer
1848 or address modes depending on the address space. */
1849 if (target_default_pointer_address_modes_p ()
1850 && POINTERS_EXTEND_UNSIGNED
> 0
1851 && mode
== Pmode
&& GET_MODE (op
) == ptr_mode
1853 || (GET_CODE (op
) == SUBREG
1854 && REG_P (SUBREG_REG (op
))
1855 && REG_POINTER (SUBREG_REG (op
))
1856 && GET_MODE (SUBREG_REG (op
)) == Pmode
))
1857 && !targetm
.have_ptr_extend ())
1860 = convert_memory_address_addr_space_1 (Pmode
, op
,
1861 ADDR_SPACE_GENERIC
, false,
1873 if (VECTOR_MODE_P (mode
)
1874 && vec_duplicate_p (op
, &elt
)
1875 && code
!= VEC_DUPLICATE
)
1877 if (code
== SIGN_EXTEND
|| code
== ZERO_EXTEND
)
1878 /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1879 operations by promoting VEC_DUPLICATE to the root of the expression
1880 (as far as possible). */
1881 temp
= simplify_gen_unary (code
, GET_MODE_INNER (mode
),
1882 elt
, GET_MODE_INNER (GET_MODE (op
)));
1884 /* Try applying the operator to ELT and see if that simplifies.
1885 We can duplicate the result if so.
1887 The reason we traditionally haven't used simplify_gen_unary
1888 for these codes is that it didn't necessarily seem to be a
1889 win to convert things like:
1891 (neg:V (vec_duplicate:V (reg:S R)))
1895 (vec_duplicate:V (neg:S (reg:S R)))
1897 The first might be done entirely in vector registers while the
1898 second might need a move between register files.
1900 However, there also cases where promoting the vec_duplicate is
1901 more efficient, and there is definite value in having a canonical
1902 form when matching instruction patterns. We should consider
1903 extending the simplify_gen_unary code above to more cases. */
1904 temp
= simplify_unary_operation (code
, GET_MODE_INNER (mode
),
1905 elt
, GET_MODE_INNER (GET_MODE (op
)));
1907 return gen_vec_duplicate (mode
, temp
);
1913 /* Try to compute the value of a unary operation CODE whose output mode is to
1914 be MODE with input operand OP whose mode was originally OP_MODE.
1915 Return zero if the value cannot be computed. */
1917 simplify_const_unary_operation (enum rtx_code code
, machine_mode mode
,
1918 rtx op
, machine_mode op_mode
)
1920 scalar_int_mode result_mode
;
1922 if (code
== VEC_DUPLICATE
)
1924 gcc_assert (VECTOR_MODE_P (mode
));
1925 if (GET_MODE (op
) != VOIDmode
)
1927 if (!VECTOR_MODE_P (GET_MODE (op
)))
1928 gcc_assert (GET_MODE_INNER (mode
) == GET_MODE (op
));
1930 gcc_assert (GET_MODE_INNER (mode
) == GET_MODE_INNER
1933 if (CONST_SCALAR_INT_P (op
) || CONST_DOUBLE_AS_FLOAT_P (op
))
1934 return gen_const_vec_duplicate (mode
, op
);
1935 if (GET_CODE (op
) == CONST_VECTOR
1936 && (CONST_VECTOR_DUPLICATE_P (op
)
1937 || CONST_VECTOR_NUNITS (op
).is_constant ()))
1939 unsigned int npatterns
= (CONST_VECTOR_DUPLICATE_P (op
)
1940 ? CONST_VECTOR_NPATTERNS (op
)
1941 : CONST_VECTOR_NUNITS (op
).to_constant ());
1942 gcc_assert (multiple_p (GET_MODE_NUNITS (mode
), npatterns
));
1943 rtx_vector_builder
builder (mode
, npatterns
, 1);
1944 for (unsigned i
= 0; i
< npatterns
; i
++)
1945 builder
.quick_push (CONST_VECTOR_ELT (op
, i
));
1946 return builder
.build ();
1950 if (VECTOR_MODE_P (mode
)
1951 && GET_CODE (op
) == CONST_VECTOR
1952 && known_eq (GET_MODE_NUNITS (mode
), CONST_VECTOR_NUNITS (op
)))
1954 gcc_assert (GET_MODE (op
) == op_mode
);
1956 rtx_vector_builder builder
;
1957 if (!builder
.new_unary_operation (mode
, op
, false))
1960 unsigned int count
= builder
.encoded_nelts ();
1961 for (unsigned int i
= 0; i
< count
; i
++)
1963 rtx x
= simplify_unary_operation (code
, GET_MODE_INNER (mode
),
1964 CONST_VECTOR_ELT (op
, i
),
1965 GET_MODE_INNER (op_mode
));
1966 if (!x
|| !valid_for_const_vector_p (mode
, x
))
1968 builder
.quick_push (x
);
1970 return builder
.build ();
1973 /* The order of these tests is critical so that, for example, we don't
1974 check the wrong mode (input vs. output) for a conversion operation,
1975 such as FIX. At some point, this should be simplified. */
1977 if (code
== FLOAT
&& CONST_SCALAR_INT_P (op
))
1981 if (op_mode
== VOIDmode
)
1983 /* CONST_INT have VOIDmode as the mode. We assume that all
1984 the bits of the constant are significant, though, this is
1985 a dangerous assumption as many times CONST_INTs are
1986 created and used with garbage in the bits outside of the
1987 precision of the implied mode of the const_int. */
1988 op_mode
= MAX_MODE_INT
;
1991 real_from_integer (&d
, mode
, rtx_mode_t (op
, op_mode
), SIGNED
);
1993 /* Avoid the folding if flag_signaling_nans is on and
1994 operand is a signaling NaN. */
1995 if (HONOR_SNANS (mode
) && REAL_VALUE_ISSIGNALING_NAN (d
))
1998 d
= real_value_truncate (mode
, d
);
2000 /* Avoid the folding if flag_rounding_math is on and the
2001 conversion is not exact. */
2002 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode
))
2005 wide_int w
= real_to_integer (&d
, &fail
,
2007 (as_a
<scalar_int_mode
> (op_mode
)));
2008 if (fail
|| wi::ne_p (w
, wide_int (rtx_mode_t (op
, op_mode
))))
2012 return const_double_from_real_value (d
, mode
);
2014 else if (code
== UNSIGNED_FLOAT
&& CONST_SCALAR_INT_P (op
))
2018 if (op_mode
== VOIDmode
)
2020 /* CONST_INT have VOIDmode as the mode. We assume that all
2021 the bits of the constant are significant, though, this is
2022 a dangerous assumption as many times CONST_INTs are
2023 created and used with garbage in the bits outside of the
2024 precision of the implied mode of the const_int. */
2025 op_mode
= MAX_MODE_INT
;
2028 real_from_integer (&d
, mode
, rtx_mode_t (op
, op_mode
), UNSIGNED
);
2030 /* Avoid the folding if flag_signaling_nans is on and
2031 operand is a signaling NaN. */
2032 if (HONOR_SNANS (mode
) && REAL_VALUE_ISSIGNALING_NAN (d
))
2035 d
= real_value_truncate (mode
, d
);
2037 /* Avoid the folding if flag_rounding_math is on and the
2038 conversion is not exact. */
2039 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode
))
2042 wide_int w
= real_to_integer (&d
, &fail
,
2044 (as_a
<scalar_int_mode
> (op_mode
)));
2045 if (fail
|| wi::ne_p (w
, wide_int (rtx_mode_t (op
, op_mode
))))
2049 return const_double_from_real_value (d
, mode
);
2052 if (CONST_SCALAR_INT_P (op
) && is_a
<scalar_int_mode
> (mode
, &result_mode
))
2054 unsigned int width
= GET_MODE_PRECISION (result_mode
);
2055 if (width
> MAX_BITSIZE_MODE_ANY_INT
)
2059 scalar_int_mode imode
= (op_mode
== VOIDmode
2061 : as_a
<scalar_int_mode
> (op_mode
));
2062 rtx_mode_t op0
= rtx_mode_t (op
, imode
);
2065 #if TARGET_SUPPORTS_WIDE_INT == 0
2066 /* This assert keeps the simplification from producing a result
2067 that cannot be represented in a CONST_DOUBLE but a lot of
2068 upstream callers expect that this function never fails to
2069 simplify something and so you if you added this to the test
2070 above the code would die later anyway. If this assert
2071 happens, you just need to make the port support wide int. */
2072 gcc_assert (width
<= HOST_BITS_PER_DOUBLE_INT
);
2078 result
= wi::bit_not (op0
);
2082 result
= wi::neg (op0
);
2086 result
= wi::abs (op0
);
2090 result
= wi::shwi (wi::ffs (op0
), result_mode
);
2094 if (wi::ne_p (op0
, 0))
2095 int_value
= wi::clz (op0
);
2096 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode
, int_value
))
2098 result
= wi::shwi (int_value
, result_mode
);
2102 result
= wi::shwi (wi::clrsb (op0
), result_mode
);
2106 if (wi::ne_p (op0
, 0))
2107 int_value
= wi::ctz (op0
);
2108 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode
, int_value
))
2110 result
= wi::shwi (int_value
, result_mode
);
2114 result
= wi::shwi (wi::popcount (op0
), result_mode
);
2118 result
= wi::shwi (wi::parity (op0
), result_mode
);
2122 result
= wi::bswap (op0
);
2126 result
= wi::bitreverse (op0
);
2131 result
= wide_int::from (op0
, width
, UNSIGNED
);
2137 signop sgn
= code
== US_TRUNCATE
? UNSIGNED
: SIGNED
;
2139 = wide_int::from (wi::max_value (width
, sgn
),
2140 GET_MODE_PRECISION (imode
), sgn
);
2142 = wide_int::from (wi::min_value (width
, sgn
),
2143 GET_MODE_PRECISION (imode
), sgn
);
2144 result
= wi::min (wi::max (op0
, nmin
, sgn
), nmax
, sgn
);
2145 result
= wide_int::from (result
, width
, sgn
);
2149 result
= wide_int::from (op0
, width
, SIGNED
);
2153 if (wi::only_sign_bit_p (op0
))
2154 result
= wi::max_value (GET_MODE_PRECISION (imode
), SIGNED
);
2156 result
= wi::neg (op0
);
2160 if (wi::only_sign_bit_p (op0
))
2161 result
= wi::max_value (GET_MODE_PRECISION (imode
), SIGNED
);
2163 result
= wi::abs (op0
);
2171 return immed_wide_int_const (result
, result_mode
);
2174 else if (CONST_DOUBLE_AS_FLOAT_P (op
)
2175 && SCALAR_FLOAT_MODE_P (mode
)
2176 && SCALAR_FLOAT_MODE_P (GET_MODE (op
)))
2178 REAL_VALUE_TYPE d
= *CONST_DOUBLE_REAL_VALUE (op
);
2184 d
= real_value_abs (&d
);
2187 d
= real_value_negate (&d
);
2189 case FLOAT_TRUNCATE
:
2190 /* Don't perform the operation if flag_signaling_nans is on
2191 and the operand is a signaling NaN. */
2192 if (HONOR_SNANS (mode
) && REAL_VALUE_ISSIGNALING_NAN (d
))
2194 /* Or if flag_rounding_math is on and the truncation is not
2196 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode
)
2197 && !exact_real_truncate (mode
, &d
))
2199 d
= real_value_truncate (mode
, d
);
2202 /* Don't perform the operation if flag_signaling_nans is on
2203 and the operand is a signaling NaN. */
2204 if (HONOR_SNANS (mode
) && REAL_VALUE_ISSIGNALING_NAN (d
))
2206 /* All this does is change the mode, unless changing
2208 if (GET_MODE_CLASS (mode
) != GET_MODE_CLASS (GET_MODE (op
)))
2209 real_convert (&d
, mode
, &d
);
2212 /* Don't perform the operation if flag_signaling_nans is on
2213 and the operand is a signaling NaN. */
2214 if (HONOR_SNANS (mode
) && REAL_VALUE_ISSIGNALING_NAN (d
))
2216 real_arithmetic (&d
, FIX_TRUNC_EXPR
, &d
, NULL
);
2223 real_to_target (tmp
, &d
, GET_MODE (op
));
2224 for (i
= 0; i
< 4; i
++)
2226 real_from_target (&d
, tmp
, mode
);
2232 return const_double_from_real_value (d
, mode
);
2234 else if (CONST_DOUBLE_AS_FLOAT_P (op
)
2235 && SCALAR_FLOAT_MODE_P (GET_MODE (op
))
2236 && is_int_mode (mode
, &result_mode
))
2238 unsigned int width
= GET_MODE_PRECISION (result_mode
);
2239 if (width
> MAX_BITSIZE_MODE_ANY_INT
)
2242 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2243 operators are intentionally left unspecified (to ease implementation
2244 by target backends), for consistency, this routine implements the
2245 same semantics for constant folding as used by the middle-end. */
2247 /* This was formerly used only for non-IEEE float.
2248 eggert@twinsun.com says it is safe for IEEE also. */
2250 const REAL_VALUE_TYPE
*x
= CONST_DOUBLE_REAL_VALUE (op
);
2251 wide_int wmax
, wmin
;
2252 /* This is part of the abi to real_to_integer, but we check
2253 things before making this call. */
2259 /* According to IEEE standard, for conversions from floating point to
2260 integer. When a NaN or infinite operand cannot be represented in
2261 the destination format and this cannot otherwise be indicated, the
2262 invalid operation exception shall be signaled. When a numeric
2263 operand would convert to an integer outside the range of the
2264 destination format, the invalid operation exception shall be
2265 signaled if this situation cannot otherwise be indicated. */
2266 if (REAL_VALUE_ISNAN (*x
))
2267 return flag_trapping_math
? NULL_RTX
: const0_rtx
;
2269 if (REAL_VALUE_ISINF (*x
) && flag_trapping_math
)
2272 /* Test against the signed upper bound. */
2273 wmax
= wi::max_value (width
, SIGNED
);
2274 real_from_integer (&t
, VOIDmode
, wmax
, SIGNED
);
2275 if (real_less (&t
, x
))
2276 return (flag_trapping_math
2277 ? NULL_RTX
: immed_wide_int_const (wmax
, mode
));
2279 /* Test against the signed lower bound. */
2280 wmin
= wi::min_value (width
, SIGNED
);
2281 real_from_integer (&t
, VOIDmode
, wmin
, SIGNED
);
2282 if (real_less (x
, &t
))
2283 return immed_wide_int_const (wmin
, mode
);
2285 return immed_wide_int_const (real_to_integer (x
, &fail
, width
),
2289 if (REAL_VALUE_ISNAN (*x
) || REAL_VALUE_NEGATIVE (*x
))
2290 return flag_trapping_math
? NULL_RTX
: const0_rtx
;
2292 if (REAL_VALUE_ISINF (*x
) && flag_trapping_math
)
2295 /* Test against the unsigned upper bound. */
2296 wmax
= wi::max_value (width
, UNSIGNED
);
2297 real_from_integer (&t
, VOIDmode
, wmax
, UNSIGNED
);
2298 if (real_less (&t
, x
))
2299 return (flag_trapping_math
2300 ? NULL_RTX
: immed_wide_int_const (wmax
, mode
));
2302 return immed_wide_int_const (real_to_integer (x
, &fail
, width
),
2310 /* Handle polynomial integers. */
2311 else if (CONST_POLY_INT_P (op
))
2313 poly_wide_int result
;
2317 result
= -const_poly_int_value (op
);
2321 result
= ~const_poly_int_value (op
);
2327 return immed_wide_int_const (result
, mode
);
2333 /* Subroutine of simplify_binary_operation to simplify a binary operation
2334 CODE that can commute with byte swapping, with result mode MODE and
2335 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2336 Return zero if no simplification or canonicalization is possible. */
2339 simplify_context::simplify_byte_swapping_operation (rtx_code code
,
2345 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2346 if (GET_CODE (op0
) == BSWAP
&& CONST_SCALAR_INT_P (op1
))
2348 tem
= simplify_gen_binary (code
, mode
, XEXP (op0
, 0),
2349 simplify_gen_unary (BSWAP
, mode
, op1
, mode
));
2350 return simplify_gen_unary (BSWAP
, mode
, tem
, mode
);
2353 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2354 if (GET_CODE (op0
) == BSWAP
&& GET_CODE (op1
) == BSWAP
)
2356 tem
= simplify_gen_binary (code
, mode
, XEXP (op0
, 0), XEXP (op1
, 0));
2357 return simplify_gen_unary (BSWAP
, mode
, tem
, mode
);
2363 /* Subroutine of simplify_binary_operation to simplify a commutative,
2364 associative binary operation CODE with result mode MODE, operating
2365 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2366 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2367 canonicalization is possible. */
2370 simplify_context::simplify_associative_operation (rtx_code code
,
2376 /* Normally expressions simplified by simplify-rtx.cc are combined
2377 at most from a few machine instructions and therefore the
2378 expressions should be fairly small. During var-tracking
2379 we can see arbitrarily large expressions though and reassociating
2380 those can be quadratic, so punt after encountering max_assoc_count
2381 simplify_associative_operation calls during outermost simplify_*
2383 if (++assoc_count
>= max_assoc_count
)
2386 /* Linearize the operator to the left. */
2387 if (GET_CODE (op1
) == code
)
2389 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2390 if (GET_CODE (op0
) == code
)
2392 tem
= simplify_gen_binary (code
, mode
, op0
, XEXP (op1
, 0));
2393 return simplify_gen_binary (code
, mode
, tem
, XEXP (op1
, 1));
2396 /* "a op (b op c)" becomes "(b op c) op a". */
2397 if (! swap_commutative_operands_p (op1
, op0
))
2398 return simplify_gen_binary (code
, mode
, op1
, op0
);
2400 std::swap (op0
, op1
);
2403 if (GET_CODE (op0
) == code
)
2405 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2406 if (swap_commutative_operands_p (XEXP (op0
, 1), op1
))
2408 tem
= simplify_gen_binary (code
, mode
, XEXP (op0
, 0), op1
);
2409 return simplify_gen_binary (code
, mode
, tem
, XEXP (op0
, 1));
2412 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2413 tem
= simplify_binary_operation (code
, mode
, XEXP (op0
, 1), op1
);
2415 return simplify_gen_binary (code
, mode
, XEXP (op0
, 0), tem
);
2417 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2418 tem
= simplify_binary_operation (code
, mode
, XEXP (op0
, 0), op1
);
2420 return simplify_gen_binary (code
, mode
, tem
, XEXP (op0
, 1));
2426 /* Return a mask describing the COMPARISON. */
2428 comparison_to_mask (enum rtx_code comparison
)
2468 /* Return a comparison corresponding to the MASK. */
2469 static enum rtx_code
2470 mask_to_comparison (int mask
)
2510 /* Return true if CODE is valid for comparisons of mode MODE, false
2513 It is always safe to return false, even if the code was valid for the
2514 given mode as that will merely suppress optimizations. */
2517 comparison_code_valid_for_mode (enum rtx_code code
, enum machine_mode mode
)
2521 /* These are valid for integral, floating and vector modes. */
2528 return (INTEGRAL_MODE_P (mode
)
2529 || FLOAT_MODE_P (mode
)
2530 || VECTOR_MODE_P (mode
));
2532 /* These are valid for floating point modes. */
2541 return FLOAT_MODE_P (mode
);
2543 /* These are filtered out in simplify_logical_operation, but
2544 we check for them too as a matter of safety. They are valid
2545 for integral and vector modes. */
2550 return INTEGRAL_MODE_P (mode
) || VECTOR_MODE_P (mode
);
2557 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2558 false/true value of comparison with MODE where comparison operands
2562 relational_result (machine_mode mode
, machine_mode cmp_mode
, rtx res
)
2564 if (SCALAR_FLOAT_MODE_P (mode
))
2566 if (res
== const0_rtx
)
2567 return CONST0_RTX (mode
);
2568 #ifdef FLOAT_STORE_FLAG_VALUE
2569 REAL_VALUE_TYPE val
= FLOAT_STORE_FLAG_VALUE (mode
);
2570 return const_double_from_real_value (val
, mode
);
2575 if (VECTOR_MODE_P (mode
))
2577 if (res
== const0_rtx
)
2578 return CONST0_RTX (mode
);
2579 #ifdef VECTOR_STORE_FLAG_VALUE
2580 rtx val
= VECTOR_STORE_FLAG_VALUE (mode
);
2581 if (val
== NULL_RTX
)
2583 if (val
== const1_rtx
)
2584 return CONST1_RTX (mode
);
2586 return gen_const_vec_duplicate (mode
, val
);
2591 /* For vector comparison with scalar int result, it is unknown
2592 if the target means here a comparison into an integral bitmask,
2593 or comparison where all comparisons true mean const_true_rtx
2594 whole result, or where any comparisons true mean const_true_rtx
2595 whole result. For const0_rtx all the cases are the same. */
2596 if (VECTOR_MODE_P (cmp_mode
)
2597 && SCALAR_INT_MODE_P (mode
)
2598 && res
== const_true_rtx
)
2604 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2605 and OP1, which should be both relational operations. Return 0 if no such
2606 simplification is possible. */
2608 simplify_context::simplify_logical_relational_operation (rtx_code code
,
2612 /* We only handle IOR of two relational operations. */
2616 if (!(COMPARISON_P (op0
) && COMPARISON_P (op1
)))
2619 if (!(rtx_equal_p (XEXP (op0
, 0), XEXP (op1
, 0))
2620 && rtx_equal_p (XEXP (op0
, 1), XEXP (op1
, 1))))
2623 enum rtx_code code0
= GET_CODE (op0
);
2624 enum rtx_code code1
= GET_CODE (op1
);
2626 /* We don't handle unsigned comparisons currently. */
2627 if (code0
== LTU
|| code0
== GTU
|| code0
== LEU
|| code0
== GEU
)
2629 if (code1
== LTU
|| code1
== GTU
|| code1
== LEU
|| code1
== GEU
)
2632 int mask0
= comparison_to_mask (code0
);
2633 int mask1
= comparison_to_mask (code1
);
2635 int mask
= mask0
| mask1
;
2638 return relational_result (mode
, GET_MODE (op0
), const_true_rtx
);
2640 code
= mask_to_comparison (mask
);
2642 /* Many comparison codes are only valid for certain mode classes. */
2643 if (!comparison_code_valid_for_mode (code
, mode
))
2646 op0
= XEXP (op1
, 0);
2647 op1
= XEXP (op1
, 1);
2649 return simplify_gen_relational (code
, mode
, VOIDmode
, op0
, op1
);
2652 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2653 and OP1. Return 0 if no simplification is possible.
2655 Don't use this for relational operations such as EQ or LT.
2656 Use simplify_relational_operation instead. */
2658 simplify_context::simplify_binary_operation (rtx_code code
, machine_mode mode
,
2661 rtx trueop0
, trueop1
;
2664 /* Relational operations don't work here. We must know the mode
2665 of the operands in order to do the comparison correctly.
2666 Assuming a full word can give incorrect results.
2667 Consider comparing 128 with -128 in QImode. */
2668 gcc_assert (GET_RTX_CLASS (code
) != RTX_COMPARE
);
2669 gcc_assert (GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
);
2671 /* Make sure the constant is second. */
2672 if (GET_RTX_CLASS (code
) == RTX_COMM_ARITH
2673 && swap_commutative_operands_p (op0
, op1
))
2674 std::swap (op0
, op1
);
2676 trueop0
= avoid_constant_pool_reference (op0
);
2677 trueop1
= avoid_constant_pool_reference (op1
);
2679 tem
= simplify_const_binary_operation (code
, mode
, trueop0
, trueop1
);
2682 tem
= simplify_binary_operation_1 (code
, mode
, op0
, op1
, trueop0
, trueop1
);
2687 /* If the above steps did not result in a simplification and op0 or op1
2688 were constant pool references, use the referenced constants directly. */
2689 if (trueop0
!= op0
|| trueop1
!= op1
)
2690 return simplify_gen_binary (code
, mode
, trueop0
, trueop1
);
2695 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2696 which OP0 and OP1 are both vector series or vector duplicates
2697 (which are really just series with a step of 0). If so, try to
2698 form a new series by applying CODE to the bases and to the steps.
2699 Return null if no simplification is possible.
2701 MODE is the mode of the operation and is known to be a vector
2705 simplify_context::simplify_binary_operation_series (rtx_code code
,
2710 if (vec_duplicate_p (op0
, &base0
))
2712 else if (!vec_series_p (op0
, &base0
, &step0
))
2716 if (vec_duplicate_p (op1
, &base1
))
2718 else if (!vec_series_p (op1
, &base1
, &step1
))
2721 /* Only create a new series if we can simplify both parts. In other
2722 cases this isn't really a simplification, and it's not necessarily
2723 a win to replace a vector operation with a scalar operation. */
2724 scalar_mode inner_mode
= GET_MODE_INNER (mode
);
2725 rtx new_base
= simplify_binary_operation (code
, inner_mode
, base0
, base1
);
2729 rtx new_step
= simplify_binary_operation (code
, inner_mode
, step0
, step1
);
2733 return gen_vec_series (mode
, new_base
, new_step
);
2736 /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2737 operation CODE with result mode MODE, operating on OP0 and OP1.
2738 e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2739 Returns NULL_RTX if no simplification is possible. */
2742 simplify_context::simplify_distributive_operation (rtx_code code
,
2746 enum rtx_code op
= GET_CODE (op0
);
2747 gcc_assert (GET_CODE (op1
) == op
);
2749 if (rtx_equal_p (XEXP (op0
, 1), XEXP (op1
, 1))
2750 && ! side_effects_p (XEXP (op0
, 1)))
2751 return simplify_gen_binary (op
, mode
,
2752 simplify_gen_binary (code
, mode
,
2757 if (GET_RTX_CLASS (op
) == RTX_COMM_ARITH
)
2759 if (rtx_equal_p (XEXP (op0
, 0), XEXP (op1
, 0))
2760 && ! side_effects_p (XEXP (op0
, 0)))
2761 return simplify_gen_binary (op
, mode
,
2762 simplify_gen_binary (code
, mode
,
2766 if (rtx_equal_p (XEXP (op0
, 0), XEXP (op1
, 1))
2767 && ! side_effects_p (XEXP (op0
, 0)))
2768 return simplify_gen_binary (op
, mode
,
2769 simplify_gen_binary (code
, mode
,
2773 if (rtx_equal_p (XEXP (op0
, 1), XEXP (op1
, 0))
2774 && ! side_effects_p (XEXP (op0
, 1)))
2775 return simplify_gen_binary (op
, mode
,
2776 simplify_gen_binary (code
, mode
,
2785 /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2788 If the rotate should not be reversed, return FALSE.
2790 LEFT indicates if this is a rotate left or a rotate right. */
2793 reverse_rotate_by_imm_p (machine_mode mode
, unsigned int left
, rtx op1
)
2795 if (!CONST_INT_P (op1
))
2798 /* Some targets may only be able to rotate by a constant
2799 in one direction. So we need to query the optab interface
2800 to see what is possible. */
2801 optab binoptab
= left
? rotl_optab
: rotr_optab
;
2802 optab re_binoptab
= left
? rotr_optab
: rotl_optab
;
2803 enum insn_code icode
= optab_handler (binoptab
, mode
);
2804 enum insn_code re_icode
= optab_handler (re_binoptab
, mode
);
2806 /* If the target can not support the reversed optab, then there
2807 is nothing to do. */
2808 if (re_icode
== CODE_FOR_nothing
)
2811 /* If the target does not support the requested rotate-by-immediate,
2812 then we want to try reversing the rotate. We also want to try
2813 reversing to minimize the count. */
2814 if ((icode
== CODE_FOR_nothing
)
2815 || (!insn_operand_matches (icode
, 2, op1
))
2816 || (IN_RANGE (INTVAL (op1
),
2817 GET_MODE_UNIT_PRECISION (mode
) / 2 + left
,
2818 GET_MODE_UNIT_PRECISION (mode
) - 1)))
2819 return (insn_operand_matches (re_icode
, 2, op1
));
2823 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2824 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2825 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2826 actual constants. */
2829 simplify_context::simplify_binary_operation_1 (rtx_code code
,
2832 rtx trueop0
, rtx trueop1
)
2834 rtx tem
, reversed
, opleft
, opright
, elt0
, elt1
;
2836 scalar_int_mode int_mode
, inner_mode
;
2839 /* Even if we can't compute a constant result,
2840 there are some cases worth simplifying. */
2845 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2846 when x is NaN, infinite, or finite and nonzero. They aren't
2847 when x is -0 and the rounding mode is not towards -infinity,
2848 since (-0) + 0 is then 0. */
2849 if (!HONOR_SIGNED_ZEROS (mode
) && !HONOR_SNANS (mode
)
2850 && trueop1
== CONST0_RTX (mode
))
2853 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2854 transformations are safe even for IEEE. */
2855 if (GET_CODE (op0
) == NEG
)
2856 return simplify_gen_binary (MINUS
, mode
, op1
, XEXP (op0
, 0));
2857 else if (GET_CODE (op1
) == NEG
)
2858 return simplify_gen_binary (MINUS
, mode
, op0
, XEXP (op1
, 0));
2860 /* (~a) + 1 -> -a */
2861 if (INTEGRAL_MODE_P (mode
)
2862 && GET_CODE (op0
) == NOT
2863 && trueop1
== const1_rtx
)
2864 return simplify_gen_unary (NEG
, mode
, XEXP (op0
, 0), mode
);
2866 /* Handle both-operands-constant cases. We can only add
2867 CONST_INTs to constants since the sum of relocatable symbols
2868 can't be handled by most assemblers. Don't add CONST_INT
2869 to CONST_INT since overflow won't be computed properly if wider
2870 than HOST_BITS_PER_WIDE_INT. */
2872 if ((GET_CODE (op0
) == CONST
2873 || GET_CODE (op0
) == SYMBOL_REF
2874 || GET_CODE (op0
) == LABEL_REF
)
2875 && poly_int_rtx_p (op1
, &offset
))
2876 return plus_constant (mode
, op0
, offset
);
2877 else if ((GET_CODE (op1
) == CONST
2878 || GET_CODE (op1
) == SYMBOL_REF
2879 || GET_CODE (op1
) == LABEL_REF
)
2880 && poly_int_rtx_p (op0
, &offset
))
2881 return plus_constant (mode
, op1
, offset
);
2883 /* See if this is something like X * C - X or vice versa or
2884 if the multiplication is written as a shift. If so, we can
2885 distribute and make a new multiply, shift, or maybe just
2886 have X (if C is 2 in the example above). But don't make
2887 something more expensive than we had before. */
2889 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
2891 rtx lhs
= op0
, rhs
= op1
;
2893 wide_int coeff0
= wi::one (GET_MODE_PRECISION (int_mode
));
2894 wide_int coeff1
= wi::one (GET_MODE_PRECISION (int_mode
));
2896 if (GET_CODE (lhs
) == NEG
)
2898 coeff0
= wi::minus_one (GET_MODE_PRECISION (int_mode
));
2899 lhs
= XEXP (lhs
, 0);
2901 else if (GET_CODE (lhs
) == MULT
2902 && CONST_SCALAR_INT_P (XEXP (lhs
, 1)))
2904 coeff0
= rtx_mode_t (XEXP (lhs
, 1), int_mode
);
2905 lhs
= XEXP (lhs
, 0);
2907 else if (GET_CODE (lhs
) == ASHIFT
2908 && CONST_INT_P (XEXP (lhs
, 1))
2909 && INTVAL (XEXP (lhs
, 1)) >= 0
2910 && INTVAL (XEXP (lhs
, 1)) < GET_MODE_PRECISION (int_mode
))
2912 coeff0
= wi::set_bit_in_zero (INTVAL (XEXP (lhs
, 1)),
2913 GET_MODE_PRECISION (int_mode
));
2914 lhs
= XEXP (lhs
, 0);
2917 if (GET_CODE (rhs
) == NEG
)
2919 coeff1
= wi::minus_one (GET_MODE_PRECISION (int_mode
));
2920 rhs
= XEXP (rhs
, 0);
2922 else if (GET_CODE (rhs
) == MULT
2923 && CONST_INT_P (XEXP (rhs
, 1)))
2925 coeff1
= rtx_mode_t (XEXP (rhs
, 1), int_mode
);
2926 rhs
= XEXP (rhs
, 0);
2928 else if (GET_CODE (rhs
) == ASHIFT
2929 && CONST_INT_P (XEXP (rhs
, 1))
2930 && INTVAL (XEXP (rhs
, 1)) >= 0
2931 && INTVAL (XEXP (rhs
, 1)) < GET_MODE_PRECISION (int_mode
))
2933 coeff1
= wi::set_bit_in_zero (INTVAL (XEXP (rhs
, 1)),
2934 GET_MODE_PRECISION (int_mode
));
2935 rhs
= XEXP (rhs
, 0);
2938 if (rtx_equal_p (lhs
, rhs
))
2940 rtx orig
= gen_rtx_PLUS (int_mode
, op0
, op1
);
2942 bool speed
= optimize_function_for_speed_p (cfun
);
2944 coeff
= immed_wide_int_const (coeff0
+ coeff1
, int_mode
);
2946 tem
= simplify_gen_binary (MULT
, int_mode
, lhs
, coeff
);
2947 return (set_src_cost (tem
, int_mode
, speed
)
2948 <= set_src_cost (orig
, int_mode
, speed
) ? tem
: 0);
2951 /* Optimize (X - 1) * Y + Y to X * Y. */
2954 if (GET_CODE (op0
) == MULT
)
2956 if (((GET_CODE (XEXP (op0
, 0)) == PLUS
2957 && XEXP (XEXP (op0
, 0), 1) == constm1_rtx
)
2958 || (GET_CODE (XEXP (op0
, 0)) == MINUS
2959 && XEXP (XEXP (op0
, 0), 1) == const1_rtx
))
2960 && rtx_equal_p (XEXP (op0
, 1), op1
))
2961 lhs
= XEXP (XEXP (op0
, 0), 0);
2962 else if (((GET_CODE (XEXP (op0
, 1)) == PLUS
2963 && XEXP (XEXP (op0
, 1), 1) == constm1_rtx
)
2964 || (GET_CODE (XEXP (op0
, 1)) == MINUS
2965 && XEXP (XEXP (op0
, 1), 1) == const1_rtx
))
2966 && rtx_equal_p (XEXP (op0
, 0), op1
))
2967 lhs
= XEXP (XEXP (op0
, 1), 0);
2969 else if (GET_CODE (op1
) == MULT
)
2971 if (((GET_CODE (XEXP (op1
, 0)) == PLUS
2972 && XEXP (XEXP (op1
, 0), 1) == constm1_rtx
)
2973 || (GET_CODE (XEXP (op1
, 0)) == MINUS
2974 && XEXP (XEXP (op1
, 0), 1) == const1_rtx
))
2975 && rtx_equal_p (XEXP (op1
, 1), op0
))
2976 rhs
= XEXP (XEXP (op1
, 0), 0);
2977 else if (((GET_CODE (XEXP (op1
, 1)) == PLUS
2978 && XEXP (XEXP (op1
, 1), 1) == constm1_rtx
)
2979 || (GET_CODE (XEXP (op1
, 1)) == MINUS
2980 && XEXP (XEXP (op1
, 1), 1) == const1_rtx
))
2981 && rtx_equal_p (XEXP (op1
, 0), op0
))
2982 rhs
= XEXP (XEXP (op1
, 1), 0);
2984 if (lhs
!= op0
|| rhs
!= op1
)
2985 return simplify_gen_binary (MULT
, int_mode
, lhs
, rhs
);
2988 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2989 if (CONST_SCALAR_INT_P (op1
)
2990 && GET_CODE (op0
) == XOR
2991 && CONST_SCALAR_INT_P (XEXP (op0
, 1))
2992 && mode_signbit_p (mode
, op1
))
2993 return simplify_gen_binary (XOR
, mode
, XEXP (op0
, 0),
2994 simplify_gen_binary (XOR
, mode
, op1
,
2997 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2998 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode
)
2999 && GET_CODE (op0
) == MULT
3000 && GET_CODE (XEXP (op0
, 0)) == NEG
)
3004 in1
= XEXP (XEXP (op0
, 0), 0);
3005 in2
= XEXP (op0
, 1);
3006 return simplify_gen_binary (MINUS
, mode
, op1
,
3007 simplify_gen_binary (MULT
, mode
,
3011 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3012 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3014 if (COMPARISON_P (op0
)
3015 && ((STORE_FLAG_VALUE
== -1 && trueop1
== const1_rtx
)
3016 || (STORE_FLAG_VALUE
== 1 && trueop1
== constm1_rtx
))
3017 && (reversed
= reversed_comparison (op0
, mode
)))
3019 simplify_gen_unary (NEG
, mode
, reversed
, mode
);
3021 /* If one of the operands is a PLUS or a MINUS, see if we can
3022 simplify this by the associative law.
3023 Don't use the associative law for floating point.
3024 The inaccuracy makes it nonassociative,
3025 and subtle programs can break if operations are associated. */
3027 if (INTEGRAL_MODE_P (mode
)
3028 && (plus_minus_operand_p (op0
)
3029 || plus_minus_operand_p (op1
))
3030 && (tem
= simplify_plus_minus (code
, mode
, op0
, op1
)) != 0)
3033 /* Reassociate floating point addition only when the user
3034 specifies associative math operations. */
3035 if (FLOAT_MODE_P (mode
)
3036 && flag_associative_math
)
3038 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
3043 /* Handle vector series. */
3044 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
3046 tem
= simplify_binary_operation_series (code
, mode
, op0
, op1
);
3053 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
3054 if (((GET_CODE (op0
) == GT
&& GET_CODE (op1
) == LT
)
3055 || (GET_CODE (op0
) == GTU
&& GET_CODE (op1
) == LTU
))
3056 && XEXP (op0
, 1) == const0_rtx
&& XEXP (op1
, 1) == const0_rtx
)
3058 rtx xop00
= XEXP (op0
, 0);
3059 rtx xop10
= XEXP (op1
, 0);
3061 if (REG_P (xop00
) && REG_P (xop10
)
3062 && REGNO (xop00
) == REGNO (xop10
)
3063 && GET_MODE (xop00
) == mode
3064 && GET_MODE (xop10
) == mode
3065 && GET_MODE_CLASS (mode
) == MODE_CC
)
3071 /* We can't assume x-x is 0 even with non-IEEE floating point,
3072 but since it is zero except in very strange circumstances, we
3073 will treat it as zero with -ffinite-math-only. */
3074 if (rtx_equal_p (trueop0
, trueop1
)
3075 && ! side_effects_p (op0
)
3076 && (!FLOAT_MODE_P (mode
) || !HONOR_NANS (mode
)))
3077 return CONST0_RTX (mode
);
3079 /* Change subtraction from zero into negation. (0 - x) is the
3080 same as -x when x is NaN, infinite, or finite and nonzero.
3081 But if the mode has signed zeros, and does not round towards
3082 -infinity, then 0 - 0 is 0, not -0. */
3083 if (!HONOR_SIGNED_ZEROS (mode
) && trueop0
== CONST0_RTX (mode
))
3084 return simplify_gen_unary (NEG
, mode
, op1
, mode
);
3086 /* (-1 - a) is ~a, unless the expression contains symbolic
3087 constants, in which case not retaining additions and
3088 subtractions could cause invalid assembly to be produced. */
3089 if (trueop0
== CONSTM1_RTX (mode
)
3090 && !contains_symbolic_reference_p (op1
))
3091 return simplify_gen_unary (NOT
, mode
, op1
, mode
);
3093 /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3094 or has signed zeros and supports rounding towards -infinity.
3095 In such a case, 0 - 0 is -0. */
3096 if (!(HONOR_SIGNED_ZEROS (mode
)
3097 && HONOR_SIGN_DEPENDENT_ROUNDING (mode
))
3098 && !HONOR_SNANS (mode
)
3099 && trueop1
== CONST0_RTX (mode
))
3102 /* See if this is something like X * C - X or vice versa or
3103 if the multiplication is written as a shift. If so, we can
3104 distribute and make a new multiply, shift, or maybe just
3105 have X (if C is 2 in the example above). But don't make
3106 something more expensive than we had before. */
3108 if (is_a
<scalar_int_mode
> (mode
, &int_mode
))
3110 rtx lhs
= op0
, rhs
= op1
;
3112 wide_int coeff0
= wi::one (GET_MODE_PRECISION (int_mode
));
3113 wide_int negcoeff1
= wi::minus_one (GET_MODE_PRECISION (int_mode
));
3115 if (GET_CODE (lhs
) == NEG
)
3117 coeff0
= wi::minus_one (GET_MODE_PRECISION (int_mode
));
3118 lhs
= XEXP (lhs
, 0);
3120 else if (GET_CODE (lhs
) == MULT
3121 && CONST_SCALAR_INT_P (XEXP (lhs
, 1)))
3123 coeff0
= rtx_mode_t (XEXP (lhs
, 1), int_mode
);
3124 lhs
= XEXP (lhs
, 0);
3126 else if (GET_CODE (lhs
) == ASHIFT
3127 && CONST_INT_P (XEXP (lhs
, 1))
3128 && INTVAL (XEXP (lhs
, 1)) >= 0
3129 && INTVAL (XEXP (lhs
, 1)) < GET_MODE_PRECISION (int_mode
))
3131 coeff0
= wi::set_bit_in_zero (INTVAL (XEXP (lhs
, 1)),
3132 GET_MODE_PRECISION (int_mode
));
3133 lhs
= XEXP (lhs
, 0);
3136 if (GET_CODE (rhs
) == NEG
)
3138 negcoeff1
= wi::one (GET_MODE_PRECISION (int_mode
));
3139 rhs
= XEXP (rhs
, 0);
3141 else if (GET_CODE (rhs
) == MULT
3142 && CONST_INT_P (XEXP (rhs
, 1)))
3144 negcoeff1
= wi::neg (rtx_mode_t (XEXP (rhs
, 1), int_mode
));
3145 rhs
= XEXP (rhs
, 0);
3147 else if (GET_CODE (rhs
) == ASHIFT
3148 && CONST_INT_P (XEXP (rhs
, 1))
3149 && INTVAL (XEXP (rhs
, 1)) >= 0
3150 && INTVAL (XEXP (rhs
, 1)) < GET_MODE_PRECISION (int_mode
))
3152 negcoeff1
= wi::set_bit_in_zero (INTVAL (XEXP (rhs
, 1)),
3153 GET_MODE_PRECISION (int_mode
));
3154 negcoeff1
= -negcoeff1
;
3155 rhs
= XEXP (rhs
, 0);
3158 if (rtx_equal_p (lhs
, rhs
))
3160 rtx orig
= gen_rtx_MINUS (int_mode
, op0
, op1
);
3162 bool speed
= optimize_function_for_speed_p (cfun
);
3164 coeff
= immed_wide_int_const (coeff0
+ negcoeff1
, int_mode
);
3166 tem
= simplify_gen_binary (MULT
, int_mode
, lhs
, coeff
);
3167 return (set_src_cost (tem
, int_mode
, speed
)
3168 <= set_src_cost (orig
, int_mode
, speed
) ? tem
: 0);
3171 /* Optimize (X + 1) * Y - Y to X * Y. */
3173 if (GET_CODE (op0
) == MULT
)
3175 if (((GET_CODE (XEXP (op0
, 0)) == PLUS
3176 && XEXP (XEXP (op0
, 0), 1) == const1_rtx
)
3177 || (GET_CODE (XEXP (op0
, 0)) == MINUS
3178 && XEXP (XEXP (op0
, 0), 1) == constm1_rtx
))
3179 && rtx_equal_p (XEXP (op0
, 1), op1
))
3180 lhs
= XEXP (XEXP (op0
, 0), 0);
3181 else if (((GET_CODE (XEXP (op0
, 1)) == PLUS
3182 && XEXP (XEXP (op0
, 1), 1) == const1_rtx
)
3183 || (GET_CODE (XEXP (op0
, 1)) == MINUS
3184 && XEXP (XEXP (op0
, 1), 1) == constm1_rtx
))
3185 && rtx_equal_p (XEXP (op0
, 0), op1
))
3186 lhs
= XEXP (XEXP (op0
, 1), 0);
3189 return simplify_gen_binary (MULT
, int_mode
, lhs
, op1
);
3192 /* (a - (-b)) -> (a + b). True even for IEEE. */
3193 if (GET_CODE (op1
) == NEG
)
3194 return simplify_gen_binary (PLUS
, mode
, op0
, XEXP (op1
, 0));
3196 /* (-x - c) may be simplified as (-c - x). */
3197 if (GET_CODE (op0
) == NEG
3198 && (CONST_SCALAR_INT_P (op1
) || CONST_DOUBLE_AS_FLOAT_P (op1
)))
3200 tem
= simplify_unary_operation (NEG
, mode
, op1
, mode
);
3202 return simplify_gen_binary (MINUS
, mode
, tem
, XEXP (op0
, 0));
3205 if ((GET_CODE (op0
) == CONST
3206 || GET_CODE (op0
) == SYMBOL_REF
3207 || GET_CODE (op0
) == LABEL_REF
)
3208 && poly_int_rtx_p (op1
, &offset
))
3209 return plus_constant (mode
, op0
, trunc_int_for_mode (-offset
, mode
));
3211 /* Don't let a relocatable value get a negative coeff. */
3212 if (poly_int_rtx_p (op1
) && GET_MODE (op0
) != VOIDmode
)
3213 return simplify_gen_binary (PLUS
, mode
,
3215 neg_poly_int_rtx (mode
, op1
));
3217 /* (x - (x & y)) -> (x & ~y) */
3218 if (INTEGRAL_MODE_P (mode
) && GET_CODE (op1
) == AND
)
3220 if (rtx_equal_p (op0
, XEXP (op1
, 0)))
3222 tem
= simplify_gen_unary (NOT
, mode
, XEXP (op1
, 1),
3223 GET_MODE (XEXP (op1
, 1)));
3224 return simplify_gen_binary (AND
, mode
, op0
, tem
);
3226 if (rtx_equal_p (op0
, XEXP (op1
, 1)))
3228 tem
= simplify_gen_unary (NOT
, mode
, XEXP (op1
, 0),
3229 GET_MODE (XEXP (op1
, 0)));
3230 return simplify_gen_binary (AND
, mode
, op0
, tem
);
3234 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3235 by reversing the comparison code if valid. */
3236 if (STORE_FLAG_VALUE
== 1
3237 && trueop0
== const1_rtx
3238 && COMPARISON_P (op1
)
3239 && (reversed
= reversed_comparison (op1
, mode
)))
3242 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3243 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode
)
3244 && GET_CODE (op1
) == MULT
3245 && GET_CODE (XEXP (op1
, 0)) == NEG
)
3249 in1
= XEXP (XEXP (op1
, 0), 0);
3250 in2
= XEXP (op1
, 1);
3251 return simplify_gen_binary (PLUS
, mode
,
3252 simplify_gen_binary (MULT
, mode
,
3257 /* Canonicalize (minus (neg A) (mult B C)) to
3258 (minus (mult (neg B) C) A). */
3259 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode
)
3260 && GET_CODE (op1
) == MULT
3261 && GET_CODE (op0
) == NEG
)
3265 in1
= simplify_gen_unary (NEG
, mode
, XEXP (op1
, 0), mode
);
3266 in2
= XEXP (op1
, 1);
3267 return simplify_gen_binary (MINUS
, mode
,
3268 simplify_gen_binary (MULT
, mode
,
3273 /* If one of the operands is a PLUS or a MINUS, see if we can
3274 simplify this by the associative law. This will, for example,
3275 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3276 Don't use the associative law for floating point.
3277 The inaccuracy makes it nonassociative,
3278 and subtle programs can break if operations are associated. */
3280 if (INTEGRAL_MODE_P (mode
)
3281 && (plus_minus_operand_p (op0
)
3282 || plus_minus_operand_p (op1
))
3283 && (tem
= simplify_plus_minus (code
, mode
, op0
, op1
)) != 0)
3286 /* Handle vector series. */
3287 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
3289 tem
= simplify_binary_operation_series (code
, mode
, op0
, op1
);
3296 if (trueop1
== constm1_rtx
)
3297 return simplify_gen_unary (NEG
, mode
, op0
, mode
);
3299 if (GET_CODE (op0
) == NEG
)
3301 rtx temp
= simplify_unary_operation (NEG
, mode
, op1
, mode
);
3302 /* If op1 is a MULT as well and simplify_unary_operation
3303 just moved the NEG to the second operand, simplify_gen_binary
3304 below could through simplify_associative_operation move
3305 the NEG around again and recurse endlessly. */
3307 && GET_CODE (op1
) == MULT
3308 && GET_CODE (temp
) == MULT
3309 && XEXP (op1
, 0) == XEXP (temp
, 0)
3310 && GET_CODE (XEXP (temp
, 1)) == NEG
3311 && XEXP (op1
, 1) == XEXP (XEXP (temp
, 1), 0))
3314 return simplify_gen_binary (MULT
, mode
, XEXP (op0
, 0), temp
);
3316 if (GET_CODE (op1
) == NEG
)
3318 rtx temp
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
3319 /* If op0 is a MULT as well and simplify_unary_operation
3320 just moved the NEG to the second operand, simplify_gen_binary
3321 below could through simplify_associative_operation move
3322 the NEG around again and recurse endlessly. */
3324 && GET_CODE (op0
) == MULT
3325 && GET_CODE (temp
) == MULT
3326 && XEXP (op0
, 0) == XEXP (temp
, 0)
3327 && GET_CODE (XEXP (temp
, 1)) == NEG
3328 && XEXP (op0
, 1) == XEXP (XEXP (temp
, 1), 0))
3331 return simplify_gen_binary (MULT
, mode
, temp
, XEXP (op1
, 0));
3334 /* Maybe simplify x * 0 to 0. The reduction is not valid if
3335 x is NaN, since x * 0 is then also NaN. Nor is it valid
3336 when the mode has signed zeros, since multiplying a negative
3337 number by 0 will give -0, not 0. */
3338 if (!HONOR_NANS (mode
)
3339 && !HONOR_SIGNED_ZEROS (mode
)
3340 && trueop1
== CONST0_RTX (mode
)
3341 && ! side_effects_p (op0
))
3344 /* In IEEE floating point, x*1 is not equivalent to x for
3346 if (!HONOR_SNANS (mode
)
3347 && trueop1
== CONST1_RTX (mode
))
3350 /* Convert multiply by constant power of two into shift. */
3351 if (mem_depth
== 0 && CONST_SCALAR_INT_P (trueop1
))
3353 val
= wi::exact_log2 (rtx_mode_t (trueop1
, mode
));
3355 return simplify_gen_binary (ASHIFT
, mode
, op0
,
3356 gen_int_shift_amount (mode
, val
));
3359 /* x*2 is x+x and x*(-1) is -x */
3360 if (CONST_DOUBLE_AS_FLOAT_P (trueop1
)
3361 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1
))
3362 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1
))
3363 && GET_MODE (op0
) == mode
)
3365 const REAL_VALUE_TYPE
*d1
= CONST_DOUBLE_REAL_VALUE (trueop1
);
3367 if (real_equal (d1
, &dconst2
))
3368 return simplify_gen_binary (PLUS
, mode
, op0
, copy_rtx (op0
));
3370 if (!HONOR_SNANS (mode
)
3371 && real_equal (d1
, &dconstm1
))
3372 return simplify_gen_unary (NEG
, mode
, op0
, mode
);
3375 /* Optimize -x * -x as x * x. */
3376 if (FLOAT_MODE_P (mode
)
3377 && GET_CODE (op0
) == NEG
3378 && GET_CODE (op1
) == NEG
3379 && rtx_equal_p (XEXP (op0
, 0), XEXP (op1
, 0))
3380 && !side_effects_p (XEXP (op0
, 0)))
3381 return simplify_gen_binary (MULT
, mode
, XEXP (op0
, 0), XEXP (op1
, 0));
3383 /* Likewise, optimize abs(x) * abs(x) as x * x. */
3384 if (SCALAR_FLOAT_MODE_P (mode
)
3385 && GET_CODE (op0
) == ABS
3386 && GET_CODE (op1
) == ABS
3387 && rtx_equal_p (XEXP (op0
, 0), XEXP (op1
, 0))
3388 && !side_effects_p (XEXP (op0
, 0)))
3389 return simplify_gen_binary (MULT
, mode
, XEXP (op0
, 0), XEXP (op1
, 0));
3391 /* Reassociate multiplication, but for floating point MULTs
3392 only when the user specifies unsafe math optimizations. */
3393 if (! FLOAT_MODE_P (mode
)
3394 || flag_unsafe_math_optimizations
)
3396 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
3403 if (trueop1
== CONST0_RTX (mode
))
3405 if (INTEGRAL_MODE_P (mode
)
3406 && trueop1
== CONSTM1_RTX (mode
)
3407 && !side_effects_p (op0
))
3409 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
))
3411 /* A | (~A) -> -1 */
3412 if (((GET_CODE (op0
) == NOT
&& rtx_equal_p (XEXP (op0
, 0), op1
))
3413 || (GET_CODE (op1
) == NOT
&& rtx_equal_p (XEXP (op1
, 0), op0
)))
3414 && ! side_effects_p (op0
)
3415 && GET_MODE_CLASS (mode
) != MODE_CC
)
3416 return CONSTM1_RTX (mode
);
3418 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3419 if (CONST_INT_P (op1
)
3420 && HWI_COMPUTABLE_MODE_P (mode
)
3421 && (nonzero_bits (op0
, mode
) & ~UINTVAL (op1
)) == 0
3422 && !side_effects_p (op0
))
3425 /* Canonicalize (X & C1) | C2. */
3426 if (GET_CODE (op0
) == AND
3427 && CONST_INT_P (trueop1
)
3428 && CONST_INT_P (XEXP (op0
, 1)))
3430 HOST_WIDE_INT mask
= GET_MODE_MASK (mode
);
3431 HOST_WIDE_INT c1
= INTVAL (XEXP (op0
, 1));
3432 HOST_WIDE_INT c2
= INTVAL (trueop1
);
3434 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3436 && !side_effects_p (XEXP (op0
, 0)))
3439 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3440 if (((c1
|c2
) & mask
) == mask
)
3441 return simplify_gen_binary (IOR
, mode
, XEXP (op0
, 0), op1
);
3444 /* Convert (A & B) | A to A. */
3445 if (GET_CODE (op0
) == AND
3446 && (rtx_equal_p (XEXP (op0
, 0), op1
)
3447 || rtx_equal_p (XEXP (op0
, 1), op1
))
3448 && ! side_effects_p (XEXP (op0
, 0))
3449 && ! side_effects_p (XEXP (op0
, 1)))
3452 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3453 mode size to (rotate A CX). */
3455 if (GET_CODE (op1
) == ASHIFT
3456 || GET_CODE (op1
) == SUBREG
)
3467 if (GET_CODE (opleft
) == ASHIFT
&& GET_CODE (opright
) == LSHIFTRT
3468 && rtx_equal_p (XEXP (opleft
, 0), XEXP (opright
, 0))
3469 && CONST_INT_P (XEXP (opleft
, 1))
3470 && CONST_INT_P (XEXP (opright
, 1))
3471 && (INTVAL (XEXP (opleft
, 1)) + INTVAL (XEXP (opright
, 1))
3472 == GET_MODE_UNIT_PRECISION (mode
)))
3473 return gen_rtx_ROTATE (mode
, XEXP (opright
, 0), XEXP (opleft
, 1));
3475 /* Same, but for ashift that has been "simplified" to a wider mode
3476 by simplify_shift_const. */
3478 if (GET_CODE (opleft
) == SUBREG
3479 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
3480 && is_a
<scalar_int_mode
> (GET_MODE (SUBREG_REG (opleft
)),
3482 && GET_CODE (SUBREG_REG (opleft
)) == ASHIFT
3483 && GET_CODE (opright
) == LSHIFTRT
3484 && GET_CODE (XEXP (opright
, 0)) == SUBREG
3485 && known_eq (SUBREG_BYTE (opleft
), SUBREG_BYTE (XEXP (opright
, 0)))
3486 && GET_MODE_SIZE (int_mode
) < GET_MODE_SIZE (inner_mode
)
3487 && rtx_equal_p (XEXP (SUBREG_REG (opleft
), 0),
3488 SUBREG_REG (XEXP (opright
, 0)))
3489 && CONST_INT_P (XEXP (SUBREG_REG (opleft
), 1))
3490 && CONST_INT_P (XEXP (opright
, 1))
3491 && (INTVAL (XEXP (SUBREG_REG (opleft
), 1))
3492 + INTVAL (XEXP (opright
, 1))
3493 == GET_MODE_PRECISION (int_mode
)))
3494 return gen_rtx_ROTATE (int_mode
, XEXP (opright
, 0),
3495 XEXP (SUBREG_REG (opleft
), 1));
3497 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3498 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3499 the PLUS does not affect any of the bits in OP1: then we can do
3500 the IOR as a PLUS and we can associate. This is valid if OP1
3501 can be safely shifted left C bits. */
3502 if (CONST_INT_P (trueop1
) && GET_CODE (op0
) == ASHIFTRT
3503 && GET_CODE (XEXP (op0
, 0)) == PLUS
3504 && CONST_INT_P (XEXP (XEXP (op0
, 0), 1))
3505 && CONST_INT_P (XEXP (op0
, 1))
3506 && INTVAL (XEXP (op0
, 1)) < HOST_BITS_PER_WIDE_INT
)
3508 int count
= INTVAL (XEXP (op0
, 1));
3509 HOST_WIDE_INT mask
= UINTVAL (trueop1
) << count
;
3511 if (mask
>> count
== INTVAL (trueop1
)
3512 && trunc_int_for_mode (mask
, mode
) == mask
3513 && (mask
& nonzero_bits (XEXP (op0
, 0), mode
)) == 0)
3514 return simplify_gen_binary (ASHIFTRT
, mode
,
3515 plus_constant (mode
, XEXP (op0
, 0),
3520 /* The following happens with bitfield merging.
3521 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3522 if (GET_CODE (op0
) == AND
3523 && GET_CODE (op1
) == AND
3524 && CONST_INT_P (XEXP (op0
, 1))
3525 && CONST_INT_P (XEXP (op1
, 1))
3526 && (INTVAL (XEXP (op0
, 1))
3527 == ~INTVAL (XEXP (op1
, 1))))
3529 /* The IOR may be on both sides. */
3530 rtx top0
= NULL_RTX
, top1
= NULL_RTX
;
3531 if (GET_CODE (XEXP (op1
, 0)) == IOR
)
3532 top0
= op0
, top1
= op1
;
3533 else if (GET_CODE (XEXP (op0
, 0)) == IOR
)
3534 top0
= op1
, top1
= op0
;
3537 /* X may be on either side of the inner IOR. */
3539 if (rtx_equal_p (XEXP (top0
, 0),
3540 XEXP (XEXP (top1
, 0), 0)))
3541 tem
= XEXP (XEXP (top1
, 0), 1);
3542 else if (rtx_equal_p (XEXP (top0
, 0),
3543 XEXP (XEXP (top1
, 0), 1)))
3544 tem
= XEXP (XEXP (top1
, 0), 0);
3546 return simplify_gen_binary (IOR
, mode
, XEXP (top0
, 0),
3548 (AND
, mode
, tem
, XEXP (top1
, 1)));
3552 /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3553 if (GET_CODE (op0
) == GET_CODE (op1
)
3554 && (GET_CODE (op0
) == AND
3555 || GET_CODE (op0
) == IOR
3556 || GET_CODE (op0
) == LSHIFTRT
3557 || GET_CODE (op0
) == ASHIFTRT
3558 || GET_CODE (op0
) == ASHIFT
3559 || GET_CODE (op0
) == ROTATE
3560 || GET_CODE (op0
) == ROTATERT
))
3562 tem
= simplify_distributive_operation (code
, mode
, op0
, op1
);
3567 /* Convert (ior (and (not A) B) A) into A | B. */
3568 if (GET_CODE (op0
) == AND
3569 && GET_CODE (XEXP (op0
, 0)) == NOT
3570 && rtx_equal_p (XEXP (XEXP (op0
, 0), 0), op1
))
3571 return simplify_gen_binary (IOR
, mode
, XEXP (op0
, 1), op1
);
3573 tem
= simplify_byte_swapping_operation (code
, mode
, op0
, op1
);
3577 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
3581 tem
= simplify_logical_relational_operation (code
, mode
, op0
, op1
);
3587 if (trueop1
== CONST0_RTX (mode
))
3589 if (INTEGRAL_MODE_P (mode
) && trueop1
== CONSTM1_RTX (mode
))
3590 return simplify_gen_unary (NOT
, mode
, op0
, mode
);
3591 if (rtx_equal_p (trueop0
, trueop1
)
3592 && ! side_effects_p (op0
)
3593 && GET_MODE_CLASS (mode
) != MODE_CC
)
3594 return CONST0_RTX (mode
);
3596 /* Canonicalize XOR of the most significant bit to PLUS. */
3597 if (CONST_SCALAR_INT_P (op1
)
3598 && mode_signbit_p (mode
, op1
))
3599 return simplify_gen_binary (PLUS
, mode
, op0
, op1
);
3600 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3601 if (CONST_SCALAR_INT_P (op1
)
3602 && GET_CODE (op0
) == PLUS
3603 && CONST_SCALAR_INT_P (XEXP (op0
, 1))
3604 && mode_signbit_p (mode
, XEXP (op0
, 1)))
3605 return simplify_gen_binary (XOR
, mode
, XEXP (op0
, 0),
3606 simplify_gen_binary (XOR
, mode
, op1
,
3609 /* If we are XORing two things that have no bits in common,
3610 convert them into an IOR. This helps to detect rotation encoded
3611 using those methods and possibly other simplifications. */
3613 if (HWI_COMPUTABLE_MODE_P (mode
)
3614 && (nonzero_bits (op0
, mode
)
3615 & nonzero_bits (op1
, mode
)) == 0)
3616 return (simplify_gen_binary (IOR
, mode
, op0
, op1
));
3618 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3619 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3622 int num_negated
= 0;
3624 if (GET_CODE (op0
) == NOT
)
3625 num_negated
++, op0
= XEXP (op0
, 0);
3626 if (GET_CODE (op1
) == NOT
)
3627 num_negated
++, op1
= XEXP (op1
, 0);
3629 if (num_negated
== 2)
3630 return simplify_gen_binary (XOR
, mode
, op0
, op1
);
3631 else if (num_negated
== 1)
3632 return simplify_gen_unary (NOT
, mode
,
3633 simplify_gen_binary (XOR
, mode
, op0
, op1
),
3637 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3638 correspond to a machine insn or result in further simplifications
3639 if B is a constant. */
3641 if (GET_CODE (op0
) == AND
3642 && rtx_equal_p (XEXP (op0
, 1), op1
)
3643 && ! side_effects_p (op1
))
3644 return simplify_gen_binary (AND
, mode
,
3645 simplify_gen_unary (NOT
, mode
,
3646 XEXP (op0
, 0), mode
),
3649 else if (GET_CODE (op0
) == AND
3650 && rtx_equal_p (XEXP (op0
, 0), op1
)
3651 && ! side_effects_p (op1
))
3652 return simplify_gen_binary (AND
, mode
,
3653 simplify_gen_unary (NOT
, mode
,
3654 XEXP (op0
, 1), mode
),
3657 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3658 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3659 out bits inverted twice and not set by C. Similarly, given
3660 (xor (and (xor A B) C) D), simplify without inverting C in
3661 the xor operand: (xor (and A C) (B&C)^D).
3663 else if ((GET_CODE (op0
) == IOR
|| GET_CODE (op0
) == AND
)
3664 && GET_CODE (XEXP (op0
, 0)) == XOR
3665 && CONST_INT_P (op1
)
3666 && CONST_INT_P (XEXP (op0
, 1))
3667 && CONST_INT_P (XEXP (XEXP (op0
, 0), 1)))
3669 enum rtx_code op
= GET_CODE (op0
);
3670 rtx a
= XEXP (XEXP (op0
, 0), 0);
3671 rtx b
= XEXP (XEXP (op0
, 0), 1);
3672 rtx c
= XEXP (op0
, 1);
3674 HOST_WIDE_INT bval
= INTVAL (b
);
3675 HOST_WIDE_INT cval
= INTVAL (c
);
3676 HOST_WIDE_INT dval
= INTVAL (d
);
3677 HOST_WIDE_INT xcval
;
3684 return simplify_gen_binary (XOR
, mode
,
3685 simplify_gen_binary (op
, mode
, a
, c
),
3686 gen_int_mode ((bval
& xcval
) ^ dval
,
3690 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3691 we can transform like this:
3692 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3693 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3694 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3695 Attempt a few simplifications when B and C are both constants. */
3696 if (GET_CODE (op0
) == AND
3697 && CONST_INT_P (op1
)
3698 && CONST_INT_P (XEXP (op0
, 1)))
3700 rtx a
= XEXP (op0
, 0);
3701 rtx b
= XEXP (op0
, 1);
3703 HOST_WIDE_INT bval
= INTVAL (b
);
3704 HOST_WIDE_INT cval
= INTVAL (c
);
3706 /* Instead of computing ~A&C, we compute its negated value,
3707 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3708 optimize for sure. If it does not simplify, we still try
3709 to compute ~A&C below, but since that always allocates
3710 RTL, we don't try that before committing to returning a
3711 simplified expression. */
3712 rtx n_na_c
= simplify_binary_operation (IOR
, mode
, a
,
3715 if ((~cval
& bval
) == 0)
3717 rtx na_c
= NULL_RTX
;
3719 na_c
= simplify_gen_unary (NOT
, mode
, n_na_c
, mode
);
3722 /* If ~A does not simplify, don't bother: we don't
3723 want to simplify 2 operations into 3, and if na_c
3724 were to simplify with na, n_na_c would have
3725 simplified as well. */
3726 rtx na
= simplify_unary_operation (NOT
, mode
, a
, mode
);
3728 na_c
= simplify_gen_binary (AND
, mode
, na
, c
);
3731 /* Try to simplify ~A&C | ~B&C. */
3732 if (na_c
!= NULL_RTX
)
3733 return simplify_gen_binary (IOR
, mode
, na_c
,
3734 gen_int_mode (~bval
& cval
, mode
));
3738 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3739 if (n_na_c
== CONSTM1_RTX (mode
))
3741 rtx a_nc_b
= simplify_gen_binary (AND
, mode
, a
,
3742 gen_int_mode (~cval
& bval
,
3744 return simplify_gen_binary (IOR
, mode
, a_nc_b
,
3745 gen_int_mode (~bval
& cval
,
3751 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3752 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3753 machines, and also has shorter instruction path length. */
3754 if (GET_CODE (op0
) == AND
3755 && GET_CODE (XEXP (op0
, 0)) == XOR
3756 && CONST_INT_P (XEXP (op0
, 1))
3757 && rtx_equal_p (XEXP (XEXP (op0
, 0), 0), trueop1
))
3760 rtx b
= XEXP (XEXP (op0
, 0), 1);
3761 rtx c
= XEXP (op0
, 1);
3762 rtx nc
= simplify_gen_unary (NOT
, mode
, c
, mode
);
3763 rtx a_nc
= simplify_gen_binary (AND
, mode
, a
, nc
);
3764 rtx bc
= simplify_gen_binary (AND
, mode
, b
, c
);
3765 return simplify_gen_binary (IOR
, mode
, a_nc
, bc
);
3767 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3768 else if (GET_CODE (op0
) == AND
3769 && GET_CODE (XEXP (op0
, 0)) == XOR
3770 && CONST_INT_P (XEXP (op0
, 1))
3771 && rtx_equal_p (XEXP (XEXP (op0
, 0), 1), trueop1
))
3773 rtx a
= XEXP (XEXP (op0
, 0), 0);
3775 rtx c
= XEXP (op0
, 1);
3776 rtx nc
= simplify_gen_unary (NOT
, mode
, c
, mode
);
3777 rtx b_nc
= simplify_gen_binary (AND
, mode
, b
, nc
);
3778 rtx ac
= simplify_gen_binary (AND
, mode
, a
, c
);
3779 return simplify_gen_binary (IOR
, mode
, ac
, b_nc
);
3782 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3783 comparison if STORE_FLAG_VALUE is 1. */
3784 if (STORE_FLAG_VALUE
== 1
3785 && trueop1
== const1_rtx
3786 && COMPARISON_P (op0
)
3787 && (reversed
= reversed_comparison (op0
, mode
)))
3790 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3791 is (lt foo (const_int 0)), so we can perform the above
3792 simplification if STORE_FLAG_VALUE is 1. */
3794 if (is_a
<scalar_int_mode
> (mode
, &int_mode
)
3795 && STORE_FLAG_VALUE
== 1
3796 && trueop1
== const1_rtx
3797 && GET_CODE (op0
) == LSHIFTRT
3798 && CONST_INT_P (XEXP (op0
, 1))
3799 && INTVAL (XEXP (op0
, 1)) == GET_MODE_PRECISION (int_mode
) - 1)
3800 return gen_rtx_GE (int_mode
, XEXP (op0
, 0), const0_rtx
);
3802 /* (xor (comparison foo bar) (const_int sign-bit))
3803 when STORE_FLAG_VALUE is the sign bit. */
3804 if (is_a
<scalar_int_mode
> (mode
, &int_mode
)
3805 && val_signbit_p (int_mode
, STORE_FLAG_VALUE
)
3806 && trueop1
== const_true_rtx
3807 && COMPARISON_P (op0
)
3808 && (reversed
= reversed_comparison (op0
, int_mode
)))
3811 /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3812 if (GET_CODE (op0
) == GET_CODE (op1
)
3813 && (GET_CODE (op0
) == AND
3814 || GET_CODE (op0
) == LSHIFTRT
3815 || GET_CODE (op0
) == ASHIFTRT
3816 || GET_CODE (op0
) == ASHIFT
3817 || GET_CODE (op0
) == ROTATE
3818 || GET_CODE (op0
) == ROTATERT
))
3820 tem
= simplify_distributive_operation (code
, mode
, op0
, op1
);
3825 /* Convert (xor (and (not A) B) A) into A | B. */
3826 if (GET_CODE (op0
) == AND
3827 && GET_CODE (XEXP (op0
, 0)) == NOT
3828 && rtx_equal_p (XEXP (XEXP (op0
, 0), 0), op1
))
3829 return simplify_gen_binary (IOR
, mode
, XEXP (op0
, 1), op1
);
3831 tem
= simplify_byte_swapping_operation (code
, mode
, op0
, op1
);
3835 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
3841 if (trueop1
== CONST0_RTX (mode
) && ! side_effects_p (op0
))
3843 if (INTEGRAL_MODE_P (mode
) && trueop1
== CONSTM1_RTX (mode
))
3845 if (HWI_COMPUTABLE_MODE_P (mode
))
3847 /* When WORD_REGISTER_OPERATIONS is true, we need to know the
3848 nonzero bits in WORD_MODE rather than MODE. */
3849 scalar_int_mode tmode
= as_a
<scalar_int_mode
> (mode
);
3850 if (WORD_REGISTER_OPERATIONS
3851 && GET_MODE_BITSIZE (tmode
) < BITS_PER_WORD
)
3853 HOST_WIDE_INT nzop0
= nonzero_bits (trueop0
, tmode
);
3854 HOST_WIDE_INT nzop1
;
3855 if (CONST_INT_P (trueop1
))
3857 HOST_WIDE_INT val1
= INTVAL (trueop1
);
3858 /* If we are turning off bits already known off in OP0, we need
3860 if ((nzop0
& ~val1
) == 0)
3863 nzop1
= nonzero_bits (trueop1
, mode
);
3864 /* If we are clearing all the nonzero bits, the result is zero. */
3865 if ((nzop1
& nzop0
) == 0
3866 && !side_effects_p (op0
) && !side_effects_p (op1
))
3867 return CONST0_RTX (mode
);
3869 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
)
3870 && GET_MODE_CLASS (mode
) != MODE_CC
)
3873 if (((GET_CODE (op0
) == NOT
&& rtx_equal_p (XEXP (op0
, 0), op1
))
3874 || (GET_CODE (op1
) == NOT
&& rtx_equal_p (XEXP (op1
, 0), op0
)))
3875 && ! side_effects_p (op0
)
3876 && GET_MODE_CLASS (mode
) != MODE_CC
)
3877 return CONST0_RTX (mode
);
3879 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3880 there are no nonzero bits of C outside of X's mode. */
3881 if ((GET_CODE (op0
) == SIGN_EXTEND
3882 || GET_CODE (op0
) == ZERO_EXTEND
)
3883 && CONST_SCALAR_INT_P (trueop1
)
3884 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
3885 && is_a
<scalar_int_mode
> (GET_MODE (XEXP (op0
, 0)), &inner_mode
)
3886 && (wi::mask (GET_MODE_PRECISION (inner_mode
), true,
3887 GET_MODE_PRECISION (int_mode
))
3888 & rtx_mode_t (trueop1
, mode
)) == 0)
3890 machine_mode imode
= GET_MODE (XEXP (op0
, 0));
3891 tem
= immed_wide_int_const (rtx_mode_t (trueop1
, mode
), imode
);
3892 tem
= simplify_gen_binary (AND
, imode
, XEXP (op0
, 0), tem
);
3893 return simplify_gen_unary (ZERO_EXTEND
, mode
, tem
, imode
);
3896 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3897 we might be able to further simplify the AND with X and potentially
3898 remove the truncation altogether. */
3899 if (GET_CODE (op0
) == TRUNCATE
&& CONST_INT_P (trueop1
))
3901 rtx x
= XEXP (op0
, 0);
3902 machine_mode xmode
= GET_MODE (x
);
3903 tem
= simplify_gen_binary (AND
, xmode
, x
,
3904 gen_int_mode (INTVAL (trueop1
), xmode
));
3905 return simplify_gen_unary (TRUNCATE
, mode
, tem
, xmode
);
3908 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3909 if (GET_CODE (op0
) == IOR
3910 && CONST_INT_P (trueop1
)
3911 && CONST_INT_P (XEXP (op0
, 1)))
3913 HOST_WIDE_INT tmp
= INTVAL (trueop1
) & INTVAL (XEXP (op0
, 1));
3914 return simplify_gen_binary (IOR
, mode
,
3915 simplify_gen_binary (AND
, mode
,
3916 XEXP (op0
, 0), op1
),
3917 gen_int_mode (tmp
, mode
));
3920 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3921 insn (and may simplify more). */
3922 if (GET_CODE (op0
) == XOR
3923 && rtx_equal_p (XEXP (op0
, 0), op1
)
3924 && ! side_effects_p (op1
))
3925 return simplify_gen_binary (AND
, mode
,
3926 simplify_gen_unary (NOT
, mode
,
3927 XEXP (op0
, 1), mode
),
3930 if (GET_CODE (op0
) == XOR
3931 && rtx_equal_p (XEXP (op0
, 1), op1
)
3932 && ! side_effects_p (op1
))
3933 return simplify_gen_binary (AND
, mode
,
3934 simplify_gen_unary (NOT
, mode
,
3935 XEXP (op0
, 0), mode
),
3938 /* Similarly for (~(A ^ B)) & A. */
3939 if (GET_CODE (op0
) == NOT
3940 && GET_CODE (XEXP (op0
, 0)) == XOR
3941 && rtx_equal_p (XEXP (XEXP (op0
, 0), 0), op1
)
3942 && ! side_effects_p (op1
))
3943 return simplify_gen_binary (AND
, mode
, XEXP (XEXP (op0
, 0), 1), op1
);
3945 if (GET_CODE (op0
) == NOT
3946 && GET_CODE (XEXP (op0
, 0)) == XOR
3947 && rtx_equal_p (XEXP (XEXP (op0
, 0), 1), op1
)
3948 && ! side_effects_p (op1
))
3949 return simplify_gen_binary (AND
, mode
, XEXP (XEXP (op0
, 0), 0), op1
);
3951 /* Convert (A | B) & A to A. */
3952 if (GET_CODE (op0
) == IOR
3953 && (rtx_equal_p (XEXP (op0
, 0), op1
)
3954 || rtx_equal_p (XEXP (op0
, 1), op1
))
3955 && ! side_effects_p (XEXP (op0
, 0))
3956 && ! side_effects_p (XEXP (op0
, 1)))
3959 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3960 ((A & N) + B) & M -> (A + B) & M
3961 Similarly if (N & M) == 0,
3962 ((A | N) + B) & M -> (A + B) & M
3963 and for - instead of + and/or ^ instead of |.
3964 Also, if (N & M) == 0, then
3965 (A +- N) & M -> A & M. */
3966 if (CONST_INT_P (trueop1
)
3967 && HWI_COMPUTABLE_MODE_P (mode
)
3968 && ~UINTVAL (trueop1
)
3969 && (UINTVAL (trueop1
) & (UINTVAL (trueop1
) + 1)) == 0
3970 && (GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
))
3975 pmop
[0] = XEXP (op0
, 0);
3976 pmop
[1] = XEXP (op0
, 1);
3978 if (CONST_INT_P (pmop
[1])
3979 && (UINTVAL (pmop
[1]) & UINTVAL (trueop1
)) == 0)
3980 return simplify_gen_binary (AND
, mode
, pmop
[0], op1
);
3982 for (which
= 0; which
< 2; which
++)
3985 switch (GET_CODE (tem
))
3988 if (CONST_INT_P (XEXP (tem
, 1))
3989 && (UINTVAL (XEXP (tem
, 1)) & UINTVAL (trueop1
))
3990 == UINTVAL (trueop1
))
3991 pmop
[which
] = XEXP (tem
, 0);
3995 if (CONST_INT_P (XEXP (tem
, 1))
3996 && (UINTVAL (XEXP (tem
, 1)) & UINTVAL (trueop1
)) == 0)
3997 pmop
[which
] = XEXP (tem
, 0);
4004 if (pmop
[0] != XEXP (op0
, 0) || pmop
[1] != XEXP (op0
, 1))
4006 tem
= simplify_gen_binary (GET_CODE (op0
), mode
,
4008 return simplify_gen_binary (code
, mode
, tem
, op1
);
4012 /* (and X (ior (not X) Y) -> (and X Y) */
4013 if (GET_CODE (op1
) == IOR
4014 && GET_CODE (XEXP (op1
, 0)) == NOT
4015 && rtx_equal_p (op0
, XEXP (XEXP (op1
, 0), 0)))
4016 return simplify_gen_binary (AND
, mode
, op0
, XEXP (op1
, 1));
4018 /* (and (ior (not X) Y) X) -> (and X Y) */
4019 if (GET_CODE (op0
) == IOR
4020 && GET_CODE (XEXP (op0
, 0)) == NOT
4021 && rtx_equal_p (op1
, XEXP (XEXP (op0
, 0), 0)))
4022 return simplify_gen_binary (AND
, mode
, op1
, XEXP (op0
, 1));
4024 /* (and X (ior Y (not X)) -> (and X Y) */
4025 if (GET_CODE (op1
) == IOR
4026 && GET_CODE (XEXP (op1
, 1)) == NOT
4027 && rtx_equal_p (op0
, XEXP (XEXP (op1
, 1), 0)))
4028 return simplify_gen_binary (AND
, mode
, op0
, XEXP (op1
, 0));
4030 /* (and (ior Y (not X)) X) -> (and X Y) */
4031 if (GET_CODE (op0
) == IOR
4032 && GET_CODE (XEXP (op0
, 1)) == NOT
4033 && rtx_equal_p (op1
, XEXP (XEXP (op0
, 1), 0)))
4034 return simplify_gen_binary (AND
, mode
, op1
, XEXP (op0
, 0));
4036 /* (and (ior/xor (X Y) (not Y)) -> X & ~Y */
4037 if ((GET_CODE (op0
) == IOR
|| GET_CODE (op0
) == XOR
)
4038 && GET_CODE (op1
) == NOT
4039 && rtx_equal_p (XEXP (op1
, 0), XEXP (op0
, 1)))
4040 return simplify_gen_binary (AND
, mode
, XEXP (op0
, 0),
4041 simplify_gen_unary (NOT
, mode
,
4044 /* (and (ior/xor (Y X) (not Y)) -> X & ~Y */
4045 if ((GET_CODE (op0
) == IOR
|| GET_CODE (op0
) == XOR
)
4046 && GET_CODE (op1
) == NOT
4047 && rtx_equal_p (XEXP (op1
, 0), XEXP (op0
, 0)))
4048 return simplify_gen_binary (AND
, mode
, XEXP (op0
, 1),
4049 simplify_gen_unary (NOT
, mode
,
4053 /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4054 if (GET_CODE (op0
) == GET_CODE (op1
)
4055 && (GET_CODE (op0
) == AND
4056 || GET_CODE (op0
) == IOR
4057 || GET_CODE (op0
) == LSHIFTRT
4058 || GET_CODE (op0
) == ASHIFTRT
4059 || GET_CODE (op0
) == ASHIFT
4060 || GET_CODE (op0
) == ROTATE
4061 || GET_CODE (op0
) == ROTATERT
))
4063 tem
= simplify_distributive_operation (code
, mode
, op0
, op1
);
4069 (ashiftrt:v4si A 16)
4070 (const_vector: 0xffff x4))
4071 is just (lshiftrt:v4si A 16). */
4072 if (VECTOR_MODE_P (mode
) && GET_CODE (op0
) == ASHIFTRT
4073 && (CONST_INT_P (XEXP (op0
, 1))
4074 || (GET_CODE (XEXP (op0
, 1)) == CONST_VECTOR
4075 && CONST_VECTOR_DUPLICATE_P (XEXP (op0
, 1))
4076 && CONST_INT_P (XVECEXP (XEXP (op0
, 1), 0, 0))))
4077 && GET_CODE (op1
) == CONST_VECTOR
4078 && CONST_VECTOR_DUPLICATE_P (op1
)
4079 && CONST_INT_P (XVECEXP (op1
, 0, 0)))
4081 unsigned HOST_WIDE_INT shift_count
4082 = (CONST_INT_P (XEXP (op0
, 1))
4083 ? UINTVAL (XEXP (op0
, 1))
4084 : UINTVAL (XVECEXP (XEXP (op0
, 1), 0, 0)));
4085 unsigned HOST_WIDE_INT inner_prec
4086 = GET_MODE_PRECISION (GET_MODE_INNER (mode
));
4088 /* Avoid UD shift count. */
4089 if (shift_count
< inner_prec
4090 && (UINTVAL (XVECEXP (op1
, 0, 0))
4091 == (HOST_WIDE_INT_1U
<< (inner_prec
- shift_count
)) - 1))
4092 return simplify_gen_binary (LSHIFTRT
, mode
, XEXP (op0
, 0), XEXP (op0
, 1));
4095 tem
= simplify_byte_swapping_operation (code
, mode
, op0
, op1
);
4099 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
4105 /* 0/x is 0 (or x&0 if x has side-effects). */
4106 if (trueop0
== CONST0_RTX (mode
)
4107 && !cfun
->can_throw_non_call_exceptions
)
4109 if (side_effects_p (op1
))
4110 return simplify_gen_binary (AND
, mode
, op1
, trueop0
);
4114 if (trueop1
== CONST1_RTX (mode
))
4116 tem
= rtl_hooks
.gen_lowpart_no_emit (mode
, op0
);
4120 /* Convert divide by power of two into shift. */
4121 if (CONST_INT_P (trueop1
)
4122 && (val
= exact_log2 (UINTVAL (trueop1
))) > 0)
4123 return simplify_gen_binary (LSHIFTRT
, mode
, op0
,
4124 gen_int_shift_amount (mode
, val
));
4128 /* Handle floating point and integers separately. */
4129 if (SCALAR_FLOAT_MODE_P (mode
))
4131 /* Maybe change 0.0 / x to 0.0. This transformation isn't
4132 safe for modes with NaNs, since 0.0 / 0.0 will then be
4133 NaN rather than 0.0. Nor is it safe for modes with signed
4134 zeros, since dividing 0 by a negative number gives -0.0 */
4135 if (trueop0
== CONST0_RTX (mode
)
4136 && !HONOR_NANS (mode
)
4137 && !HONOR_SIGNED_ZEROS (mode
)
4138 && ! side_effects_p (op1
))
4141 if (trueop1
== CONST1_RTX (mode
)
4142 && !HONOR_SNANS (mode
))
4145 if (CONST_DOUBLE_AS_FLOAT_P (trueop1
)
4146 && trueop1
!= CONST0_RTX (mode
))
4148 const REAL_VALUE_TYPE
*d1
= CONST_DOUBLE_REAL_VALUE (trueop1
);
4151 if (real_equal (d1
, &dconstm1
)
4152 && !HONOR_SNANS (mode
))
4153 return simplify_gen_unary (NEG
, mode
, op0
, mode
);
4155 /* Change FP division by a constant into multiplication.
4156 Only do this with -freciprocal-math. */
4157 if (flag_reciprocal_math
4158 && !real_equal (d1
, &dconst0
))
4161 real_arithmetic (&d
, RDIV_EXPR
, &dconst1
, d1
);
4162 tem
= const_double_from_real_value (d
, mode
);
4163 return simplify_gen_binary (MULT
, mode
, op0
, tem
);
4167 else if (SCALAR_INT_MODE_P (mode
) || GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
4169 /* 0/x is 0 (or x&0 if x has side-effects). */
4170 if (trueop0
== CONST0_RTX (mode
)
4171 && !cfun
->can_throw_non_call_exceptions
)
4173 if (side_effects_p (op1
))
4174 return simplify_gen_binary (AND
, mode
, op1
, trueop0
);
4178 if (trueop1
== CONST1_RTX (mode
))
4180 tem
= rtl_hooks
.gen_lowpart_no_emit (mode
, op0
);
4185 if (trueop1
== CONSTM1_RTX (mode
))
4187 rtx x
= rtl_hooks
.gen_lowpart_no_emit (mode
, op0
);
4189 return simplify_gen_unary (NEG
, mode
, x
, mode
);
4195 /* 0%x is 0 (or x&0 if x has side-effects). */
4196 if (trueop0
== CONST0_RTX (mode
))
4198 if (side_effects_p (op1
))
4199 return simplify_gen_binary (AND
, mode
, op1
, trueop0
);
4202 /* x%1 is 0 (of x&0 if x has side-effects). */
4203 if (trueop1
== CONST1_RTX (mode
))
4205 if (side_effects_p (op0
))
4206 return simplify_gen_binary (AND
, mode
, op0
, CONST0_RTX (mode
));
4207 return CONST0_RTX (mode
);
4209 /* Implement modulus by power of two as AND. */
4210 if (CONST_INT_P (trueop1
)
4211 && exact_log2 (UINTVAL (trueop1
)) > 0)
4212 return simplify_gen_binary (AND
, mode
, op0
,
4213 gen_int_mode (UINTVAL (trueop1
) - 1,
4218 /* 0%x is 0 (or x&0 if x has side-effects). */
4219 if (trueop0
== CONST0_RTX (mode
))
4221 if (side_effects_p (op1
))
4222 return simplify_gen_binary (AND
, mode
, op1
, trueop0
);
4225 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4226 if (trueop1
== CONST1_RTX (mode
) || trueop1
== constm1_rtx
)
4228 if (side_effects_p (op0
))
4229 return simplify_gen_binary (AND
, mode
, op0
, CONST0_RTX (mode
));
4230 return CONST0_RTX (mode
);
4236 if (trueop1
== CONST0_RTX (mode
))
4238 /* Canonicalize rotates by constant amount. If the condition of
4239 reversing direction is met, then reverse the direction. */
4240 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4241 if (reverse_rotate_by_imm_p (mode
, (code
== ROTATE
), trueop1
))
4243 int new_amount
= GET_MODE_UNIT_PRECISION (mode
) - INTVAL (trueop1
);
4244 rtx new_amount_rtx
= gen_int_shift_amount (mode
, new_amount
);
4245 return simplify_gen_binary (code
== ROTATE
? ROTATERT
: ROTATE
,
4246 mode
, op0
, new_amount_rtx
);
4251 if (trueop1
== CONST0_RTX (mode
))
4253 if (trueop0
== CONST0_RTX (mode
) && ! side_effects_p (op1
))
4255 /* Rotating ~0 always results in ~0. */
4256 if (CONST_INT_P (trueop0
)
4257 && HWI_COMPUTABLE_MODE_P (mode
)
4258 && UINTVAL (trueop0
) == GET_MODE_MASK (mode
)
4259 && ! side_effects_p (op1
))
4265 scalar constants c1, c2
4266 size (M2) > size (M1)
4267 c1 == size (M2) - size (M1)
4269 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4273 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4275 if ((code
== ASHIFTRT
|| code
== LSHIFTRT
)
4276 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
4278 && CONST_INT_P (op1
)
4279 && GET_CODE (SUBREG_REG (op0
)) == LSHIFTRT
4280 && is_a
<scalar_int_mode
> (GET_MODE (SUBREG_REG (op0
)),
4282 && CONST_INT_P (XEXP (SUBREG_REG (op0
), 1))
4283 && GET_MODE_BITSIZE (inner_mode
) > GET_MODE_BITSIZE (int_mode
)
4284 && (INTVAL (XEXP (SUBREG_REG (op0
), 1))
4285 == GET_MODE_BITSIZE (inner_mode
) - GET_MODE_BITSIZE (int_mode
))
4286 && subreg_lowpart_p (op0
))
4288 rtx tmp
= gen_int_shift_amount
4289 (inner_mode
, INTVAL (XEXP (SUBREG_REG (op0
), 1)) + INTVAL (op1
));
4291 /* Combine would usually zero out the value when combining two
4292 local shifts and the range becomes larger or equal to the mode.
4293 However since we fold away one of the shifts here combine won't
4294 see it so we should immediately zero the result if it's out of
4296 if (code
== LSHIFTRT
4297 && INTVAL (tmp
) >= GET_MODE_BITSIZE (inner_mode
))
4300 tmp
= simplify_gen_binary (code
,
4302 XEXP (SUBREG_REG (op0
), 0),
4305 return lowpart_subreg (int_mode
, tmp
, inner_mode
);
4308 if (SHIFT_COUNT_TRUNCATED
&& CONST_INT_P (op1
))
4310 val
= INTVAL (op1
) & (GET_MODE_UNIT_PRECISION (mode
) - 1);
4311 if (val
!= INTVAL (op1
))
4312 return simplify_gen_binary (code
, mode
, op0
,
4313 gen_int_shift_amount (mode
, val
));
4318 if (CONST_INT_P (trueop0
)
4319 && HWI_COMPUTABLE_MODE_P (mode
)
4320 && (UINTVAL (trueop0
) == (GET_MODE_MASK (mode
) >> 1)
4321 || mode_signbit_p (mode
, trueop0
))
4322 && ! side_effects_p (op1
))
4324 goto simplify_ashift
;
4327 if (CONST_INT_P (trueop0
)
4328 && HWI_COMPUTABLE_MODE_P (mode
)
4329 && UINTVAL (trueop0
) == GET_MODE_MASK (mode
)
4330 && ! side_effects_p (op1
))
4336 if (trueop1
== CONST0_RTX (mode
))
4338 if (trueop0
== CONST0_RTX (mode
) && ! side_effects_p (op1
))
4342 && CONST_INT_P (trueop1
)
4343 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
4344 && IN_RANGE (UINTVAL (trueop1
),
4345 1, GET_MODE_PRECISION (int_mode
) - 1))
4347 auto c
= (wi::one (GET_MODE_PRECISION (int_mode
))
4348 << UINTVAL (trueop1
));
4349 rtx new_op1
= immed_wide_int_const (c
, int_mode
);
4350 return simplify_gen_binary (MULT
, int_mode
, op0
, new_op1
);
4352 goto canonicalize_shift
;
4355 if (trueop1
== CONST0_RTX (mode
))
4357 if (trueop0
== CONST0_RTX (mode
) && ! side_effects_p (op1
))
4359 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4360 if (GET_CODE (op0
) == CLZ
4361 && is_a
<scalar_int_mode
> (GET_MODE (XEXP (op0
, 0)), &inner_mode
)
4362 && CONST_INT_P (trueop1
)
4363 && STORE_FLAG_VALUE
== 1
4364 && INTVAL (trueop1
) < GET_MODE_UNIT_PRECISION (mode
))
4366 unsigned HOST_WIDE_INT zero_val
= 0;
4368 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode
, zero_val
)
4369 && zero_val
== GET_MODE_PRECISION (inner_mode
)
4370 && INTVAL (trueop1
) == exact_log2 (zero_val
))
4371 return simplify_gen_relational (EQ
, mode
, inner_mode
,
4372 XEXP (op0
, 0), const0_rtx
);
4374 goto canonicalize_shift
;
4377 if (HWI_COMPUTABLE_MODE_P (mode
)
4378 && mode_signbit_p (mode
, trueop1
)
4379 && ! side_effects_p (op0
))
4381 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
))
4383 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
4389 if (HWI_COMPUTABLE_MODE_P (mode
)
4390 && CONST_INT_P (trueop1
)
4391 && (UINTVAL (trueop1
) == GET_MODE_MASK (mode
) >> 1)
4392 && ! side_effects_p (op0
))
4394 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
))
4396 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
4402 if (trueop1
== CONST0_RTX (mode
) && ! side_effects_p (op0
))
4404 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
))
4406 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
4412 if (trueop1
== constm1_rtx
&& ! side_effects_p (op0
))
4414 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
))
4416 tem
= simplify_associative_operation (code
, mode
, op0
, op1
);
4425 /* Simplify x +/- 0 to x, if possible. */
4426 if (trueop1
== CONST0_RTX (mode
))
4432 /* Simplify x * 0 to 0, if possible. */
4433 if (trueop1
== CONST0_RTX (mode
)
4434 && !side_effects_p (op0
))
4437 /* Simplify x * 1 to x, if possible. */
4438 if (trueop1
== CONST1_RTX (mode
))
4444 /* Simplify x * 0 to 0, if possible. */
4445 if (trueop1
== CONST0_RTX (mode
)
4446 && !side_effects_p (op0
))
4452 /* Simplify x / 1 to x, if possible. */
4453 if (trueop1
== CONST1_RTX (mode
))
4458 if (rtx_equal_p (trueop0
, trueop1
) && ! side_effects_p (op0
))
4460 if (CONST_DOUBLE_AS_FLOAT_P (trueop1
))
4463 real_convert (&f1
, mode
, CONST_DOUBLE_REAL_VALUE (trueop1
));
4464 rtx tmp
= simplify_gen_unary (ABS
, mode
, op0
, mode
);
4465 if (REAL_VALUE_NEGATIVE (f1
))
4466 tmp
= simplify_unary_operation (NEG
, mode
, tmp
, mode
);
4469 if (GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
4470 return simplify_gen_binary (COPYSIGN
, mode
, XEXP (op0
, 0), op1
);
4471 if (GET_CODE (op1
) == ABS
4472 && ! side_effects_p (op1
))
4473 return simplify_gen_unary (ABS
, mode
, op0
, mode
);
4474 if (GET_CODE (op0
) == COPYSIGN
4475 && ! side_effects_p (XEXP (op0
, 1)))
4476 return simplify_gen_binary (COPYSIGN
, mode
, XEXP (op0
, 0), op1
);
4477 if (GET_CODE (op1
) == COPYSIGN
4478 && ! side_effects_p (XEXP (op1
, 0)))
4479 return simplify_gen_binary (COPYSIGN
, mode
, op0
, XEXP (op1
, 1));
4483 if (op1
== CONST0_RTX (GET_MODE_INNER (mode
)))
4484 return gen_vec_duplicate (mode
, op0
);
4485 if (valid_for_const_vector_p (mode
, op0
)
4486 && valid_for_const_vector_p (mode
, op1
))
4487 return gen_const_vec_series (mode
, op0
, op1
);
4491 if (!VECTOR_MODE_P (mode
))
4493 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0
)));
4494 gcc_assert (mode
== GET_MODE_INNER (GET_MODE (trueop0
)));
4495 gcc_assert (GET_CODE (trueop1
) == PARALLEL
);
4496 gcc_assert (XVECLEN (trueop1
, 0) == 1);
4498 /* We can't reason about selections made at runtime. */
4499 if (!CONST_INT_P (XVECEXP (trueop1
, 0, 0)))
4502 if (vec_duplicate_p (trueop0
, &elt0
))
4505 if (GET_CODE (trueop0
) == CONST_VECTOR
)
4506 return CONST_VECTOR_ELT (trueop0
, INTVAL (XVECEXP
4509 /* Extract a scalar element from a nested VEC_SELECT expression
4510 (with optional nested VEC_CONCAT expression). Some targets
4511 (i386) extract scalar element from a vector using chain of
4512 nested VEC_SELECT expressions. When input operand is a memory
4513 operand, this operation can be simplified to a simple scalar
4514 load from an offseted memory address. */
4516 if (GET_CODE (trueop0
) == VEC_SELECT
4517 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0
, 0)))
4518 .is_constant (&n_elts
)))
4520 rtx op0
= XEXP (trueop0
, 0);
4521 rtx op1
= XEXP (trueop0
, 1);
4523 int i
= INTVAL (XVECEXP (trueop1
, 0, 0));
4529 gcc_assert (GET_CODE (op1
) == PARALLEL
);
4530 gcc_assert (i
< n_elts
);
4532 /* Select element, pointed by nested selector. */
4533 elem
= INTVAL (XVECEXP (op1
, 0, i
));
4535 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4536 if (GET_CODE (op0
) == VEC_CONCAT
)
4538 rtx op00
= XEXP (op0
, 0);
4539 rtx op01
= XEXP (op0
, 1);
4541 machine_mode mode00
, mode01
;
4542 int n_elts00
, n_elts01
;
4544 mode00
= GET_MODE (op00
);
4545 mode01
= GET_MODE (op01
);
4547 /* Find out the number of elements of each operand.
4548 Since the concatenated result has a constant number
4549 of elements, the operands must too. */
4550 n_elts00
= GET_MODE_NUNITS (mode00
).to_constant ();
4551 n_elts01
= GET_MODE_NUNITS (mode01
).to_constant ();
4553 gcc_assert (n_elts
== n_elts00
+ n_elts01
);
4555 /* Select correct operand of VEC_CONCAT
4556 and adjust selector. */
4557 if (elem
< n_elts01
)
4568 vec
= rtvec_alloc (1);
4569 RTVEC_ELT (vec
, 0) = GEN_INT (elem
);
4571 tmp
= gen_rtx_fmt_ee (code
, mode
,
4572 tmp_op
, gen_rtx_PARALLEL (VOIDmode
, vec
));
4578 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0
)));
4579 gcc_assert (GET_MODE_INNER (mode
)
4580 == GET_MODE_INNER (GET_MODE (trueop0
)));
4581 gcc_assert (GET_CODE (trueop1
) == PARALLEL
);
4583 if (vec_duplicate_p (trueop0
, &elt0
))
4584 /* It doesn't matter which elements are selected by trueop1,
4585 because they are all the same. */
4586 return gen_vec_duplicate (mode
, elt0
);
4588 if (GET_CODE (trueop0
) == CONST_VECTOR
)
4590 unsigned n_elts
= XVECLEN (trueop1
, 0);
4591 rtvec v
= rtvec_alloc (n_elts
);
4594 gcc_assert (known_eq (n_elts
, GET_MODE_NUNITS (mode
)));
4595 for (i
= 0; i
< n_elts
; i
++)
4597 rtx x
= XVECEXP (trueop1
, 0, i
);
4599 if (!CONST_INT_P (x
))
4602 RTVEC_ELT (v
, i
) = CONST_VECTOR_ELT (trueop0
,
4606 return gen_rtx_CONST_VECTOR (mode
, v
);
4609 /* Recognize the identity. */
4610 if (GET_MODE (trueop0
) == mode
)
4612 bool maybe_ident
= true;
4613 for (int i
= 0; i
< XVECLEN (trueop1
, 0); i
++)
4615 rtx j
= XVECEXP (trueop1
, 0, i
);
4616 if (!CONST_INT_P (j
) || INTVAL (j
) != i
)
4618 maybe_ident
= false;
4626 /* If we select a low-part subreg, return that. */
4627 if (vec_series_lowpart_p (mode
, GET_MODE (trueop0
), trueop1
))
4629 rtx new_rtx
= lowpart_subreg (mode
, trueop0
,
4630 GET_MODE (trueop0
));
4631 if (new_rtx
!= NULL_RTX
)
4635 /* If we build {a,b} then permute it, build the result directly. */
4636 if (XVECLEN (trueop1
, 0) == 2
4637 && CONST_INT_P (XVECEXP (trueop1
, 0, 0))
4638 && CONST_INT_P (XVECEXP (trueop1
, 0, 1))
4639 && GET_CODE (trueop0
) == VEC_CONCAT
4640 && GET_CODE (XEXP (trueop0
, 0)) == VEC_CONCAT
4641 && GET_MODE (XEXP (trueop0
, 0)) == mode
4642 && GET_CODE (XEXP (trueop0
, 1)) == VEC_CONCAT
4643 && GET_MODE (XEXP (trueop0
, 1)) == mode
)
4645 unsigned int i0
= INTVAL (XVECEXP (trueop1
, 0, 0));
4646 unsigned int i1
= INTVAL (XVECEXP (trueop1
, 0, 1));
4649 gcc_assert (i0
< 4 && i1
< 4);
4650 subop0
= XEXP (XEXP (trueop0
, i0
/ 2), i0
% 2);
4651 subop1
= XEXP (XEXP (trueop0
, i1
/ 2), i1
% 2);
4653 return simplify_gen_binary (VEC_CONCAT
, mode
, subop0
, subop1
);
4656 if (XVECLEN (trueop1
, 0) == 2
4657 && CONST_INT_P (XVECEXP (trueop1
, 0, 0))
4658 && CONST_INT_P (XVECEXP (trueop1
, 0, 1))
4659 && GET_CODE (trueop0
) == VEC_CONCAT
4660 && GET_MODE (trueop0
) == mode
)
4662 unsigned int i0
= INTVAL (XVECEXP (trueop1
, 0, 0));
4663 unsigned int i1
= INTVAL (XVECEXP (trueop1
, 0, 1));
4666 gcc_assert (i0
< 2 && i1
< 2);
4667 subop0
= XEXP (trueop0
, i0
);
4668 subop1
= XEXP (trueop0
, i1
);
4670 return simplify_gen_binary (VEC_CONCAT
, mode
, subop0
, subop1
);
4673 /* If we select one half of a vec_concat, return that. */
4675 if (GET_CODE (trueop0
) == VEC_CONCAT
4676 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0
, 0)))
4678 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0
, 1)))
4680 && CONST_INT_P (XVECEXP (trueop1
, 0, 0)))
4682 rtx subop0
= XEXP (trueop0
, 0);
4683 rtx subop1
= XEXP (trueop0
, 1);
4684 machine_mode mode0
= GET_MODE (subop0
);
4685 machine_mode mode1
= GET_MODE (subop1
);
4686 int i0
= INTVAL (XVECEXP (trueop1
, 0, 0));
4687 if (i0
== 0 && !side_effects_p (op1
) && mode
== mode0
)
4689 bool success
= true;
4690 for (int i
= 1; i
< l0
; ++i
)
4692 rtx j
= XVECEXP (trueop1
, 0, i
);
4693 if (!CONST_INT_P (j
) || INTVAL (j
) != i
)
4702 if (i0
== l0
&& !side_effects_p (op0
) && mode
== mode1
)
4704 bool success
= true;
4705 for (int i
= 1; i
< l1
; ++i
)
4707 rtx j
= XVECEXP (trueop1
, 0, i
);
4708 if (!CONST_INT_P (j
) || INTVAL (j
) != i0
+ i
)
4719 /* Simplify vec_select of a subreg of X to just a vec_select of X
4720 when X has same component mode as vec_select. */
4721 unsigned HOST_WIDE_INT subreg_offset
= 0;
4722 if (GET_CODE (trueop0
) == SUBREG
4723 && GET_MODE_INNER (mode
)
4724 == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0
)))
4725 && GET_MODE_NUNITS (mode
).is_constant (&l1
)
4726 && constant_multiple_p (subreg_memory_offset (trueop0
),
4727 GET_MODE_UNIT_BITSIZE (mode
),
4731 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0
)));
4732 bool success
= true;
4733 for (int i
= 0; i
!= l1
; i
++)
4735 rtx idx
= XVECEXP (trueop1
, 0, i
);
4736 if (!CONST_INT_P (idx
)
4737 || maybe_ge (UINTVAL (idx
) + subreg_offset
, nunits
))
4749 rtvec vec
= rtvec_alloc (l1
);
4750 for (int i
= 0; i
< l1
; i
++)
4752 = GEN_INT (INTVAL (XVECEXP (trueop1
, 0, i
))
4754 par
= gen_rtx_PARALLEL (VOIDmode
, vec
);
4756 return gen_rtx_VEC_SELECT (mode
, SUBREG_REG (trueop0
), par
);
4761 if (XVECLEN (trueop1
, 0) == 1
4762 && CONST_INT_P (XVECEXP (trueop1
, 0, 0))
4763 && GET_CODE (trueop0
) == VEC_CONCAT
)
4766 offset
= INTVAL (XVECEXP (trueop1
, 0, 0)) * GET_MODE_SIZE (mode
);
4768 /* Try to find the element in the VEC_CONCAT. */
4769 while (GET_MODE (vec
) != mode
4770 && GET_CODE (vec
) == VEC_CONCAT
)
4772 poly_int64 vec_size
;
4774 if (CONST_INT_P (XEXP (vec
, 0)))
4776 /* vec_concat of two const_ints doesn't make sense with
4777 respect to modes. */
4778 if (CONST_INT_P (XEXP (vec
, 1)))
4781 vec_size
= GET_MODE_SIZE (GET_MODE (trueop0
))
4782 - GET_MODE_SIZE (GET_MODE (XEXP (vec
, 1)));
4785 vec_size
= GET_MODE_SIZE (GET_MODE (XEXP (vec
, 0)));
4787 if (known_lt (offset
, vec_size
))
4788 vec
= XEXP (vec
, 0);
4789 else if (known_ge (offset
, vec_size
))
4792 vec
= XEXP (vec
, 1);
4796 vec
= avoid_constant_pool_reference (vec
);
4799 if (GET_MODE (vec
) == mode
)
4803 /* If we select elements in a vec_merge that all come from the same
4804 operand, select from that operand directly. */
4805 if (GET_CODE (op0
) == VEC_MERGE
)
4807 rtx trueop02
= avoid_constant_pool_reference (XEXP (op0
, 2));
4808 if (CONST_INT_P (trueop02
))
4810 unsigned HOST_WIDE_INT sel
= UINTVAL (trueop02
);
4811 bool all_operand0
= true;
4812 bool all_operand1
= true;
4813 for (int i
= 0; i
< XVECLEN (trueop1
, 0); i
++)
4815 rtx j
= XVECEXP (trueop1
, 0, i
);
4816 if (sel
& (HOST_WIDE_INT_1U
<< UINTVAL (j
)))
4817 all_operand1
= false;
4819 all_operand0
= false;
4821 if (all_operand0
&& !side_effects_p (XEXP (op0
, 1)))
4822 return simplify_gen_binary (VEC_SELECT
, mode
, XEXP (op0
, 0), op1
);
4823 if (all_operand1
&& !side_effects_p (XEXP (op0
, 0)))
4824 return simplify_gen_binary (VEC_SELECT
, mode
, XEXP (op0
, 1), op1
);
4828 /* If we have two nested selects that are inverses of each
4829 other, replace them with the source operand. */
4830 if (GET_CODE (trueop0
) == VEC_SELECT
4831 && GET_MODE (XEXP (trueop0
, 0)) == mode
)
4833 rtx op0_subop1
= XEXP (trueop0
, 1);
4834 gcc_assert (GET_CODE (op0_subop1
) == PARALLEL
);
4835 gcc_assert (known_eq (XVECLEN (trueop1
, 0), GET_MODE_NUNITS (mode
)));
4837 /* Apply the outer ordering vector to the inner one. (The inner
4838 ordering vector is expressly permitted to be of a different
4839 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4840 then the two VEC_SELECTs cancel. */
4841 for (int i
= 0; i
< XVECLEN (trueop1
, 0); ++i
)
4843 rtx x
= XVECEXP (trueop1
, 0, i
);
4844 if (!CONST_INT_P (x
))
4846 rtx y
= XVECEXP (op0_subop1
, 0, INTVAL (x
));
4847 if (!CONST_INT_P (y
) || i
!= INTVAL (y
))
4850 return XEXP (trueop0
, 0);
4856 machine_mode op0_mode
= (GET_MODE (trueop0
) != VOIDmode
4857 ? GET_MODE (trueop0
)
4858 : GET_MODE_INNER (mode
));
4859 machine_mode op1_mode
= (GET_MODE (trueop1
) != VOIDmode
4860 ? GET_MODE (trueop1
)
4861 : GET_MODE_INNER (mode
));
4863 gcc_assert (VECTOR_MODE_P (mode
));
4864 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode
)
4865 + GET_MODE_SIZE (op1_mode
),
4866 GET_MODE_SIZE (mode
)));
4868 if (VECTOR_MODE_P (op0_mode
))
4869 gcc_assert (GET_MODE_INNER (mode
)
4870 == GET_MODE_INNER (op0_mode
));
4872 gcc_assert (GET_MODE_INNER (mode
) == op0_mode
);
4874 if (VECTOR_MODE_P (op1_mode
))
4875 gcc_assert (GET_MODE_INNER (mode
)
4876 == GET_MODE_INNER (op1_mode
));
4878 gcc_assert (GET_MODE_INNER (mode
) == op1_mode
);
4880 unsigned int n_elts
, in_n_elts
;
4881 if ((GET_CODE (trueop0
) == CONST_VECTOR
4882 || CONST_SCALAR_INT_P (trueop0
)
4883 || CONST_DOUBLE_AS_FLOAT_P (trueop0
))
4884 && (GET_CODE (trueop1
) == CONST_VECTOR
4885 || CONST_SCALAR_INT_P (trueop1
)
4886 || CONST_DOUBLE_AS_FLOAT_P (trueop1
))
4887 && GET_MODE_NUNITS (mode
).is_constant (&n_elts
)
4888 && GET_MODE_NUNITS (op0_mode
).is_constant (&in_n_elts
))
4890 rtvec v
= rtvec_alloc (n_elts
);
4892 for (i
= 0; i
< n_elts
; i
++)
4896 if (!VECTOR_MODE_P (op0_mode
))
4897 RTVEC_ELT (v
, i
) = trueop0
;
4899 RTVEC_ELT (v
, i
) = CONST_VECTOR_ELT (trueop0
, i
);
4903 if (!VECTOR_MODE_P (op1_mode
))
4904 RTVEC_ELT (v
, i
) = trueop1
;
4906 RTVEC_ELT (v
, i
) = CONST_VECTOR_ELT (trueop1
,
4911 return gen_rtx_CONST_VECTOR (mode
, v
);
4914 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4915 Restrict the transformation to avoid generating a VEC_SELECT with a
4916 mode unrelated to its operand. */
4917 if (GET_CODE (trueop0
) == VEC_SELECT
4918 && GET_CODE (trueop1
) == VEC_SELECT
4919 && rtx_equal_p (XEXP (trueop0
, 0), XEXP (trueop1
, 0))
4920 && GET_MODE_INNER (GET_MODE (XEXP (trueop0
, 0)))
4921 == GET_MODE_INNER(mode
))
4923 rtx par0
= XEXP (trueop0
, 1);
4924 rtx par1
= XEXP (trueop1
, 1);
4925 int len0
= XVECLEN (par0
, 0);
4926 int len1
= XVECLEN (par1
, 0);
4927 rtvec vec
= rtvec_alloc (len0
+ len1
);
4928 for (int i
= 0; i
< len0
; i
++)
4929 RTVEC_ELT (vec
, i
) = XVECEXP (par0
, 0, i
);
4930 for (int i
= 0; i
< len1
; i
++)
4931 RTVEC_ELT (vec
, len0
+ i
) = XVECEXP (par1
, 0, i
);
4932 return simplify_gen_binary (VEC_SELECT
, mode
, XEXP (trueop0
, 0),
4933 gen_rtx_PARALLEL (VOIDmode
, vec
));
4936 (subreg_lowpart:N OP)
4937 (vec_select:N OP P)) --> OP when P selects the high half
4939 if (GET_CODE (trueop0
) == SUBREG
4940 && subreg_lowpart_p (trueop0
)
4941 && GET_CODE (trueop1
) == VEC_SELECT
4942 && SUBREG_REG (trueop0
) == XEXP (trueop1
, 0)
4943 && !side_effects_p (XEXP (trueop1
, 0))
4944 && vec_series_highpart_p (op1_mode
, mode
, XEXP (trueop1
, 1)))
4945 return XEXP (trueop1
, 0);
4953 if (mode
== GET_MODE (op0
)
4954 && mode
== GET_MODE (op1
)
4955 && vec_duplicate_p (op0
, &elt0
)
4956 && vec_duplicate_p (op1
, &elt1
))
4958 /* Try applying the operator to ELT and see if that simplifies.
4959 We can duplicate the result if so.
4961 The reason we don't use simplify_gen_binary is that it isn't
4962 necessarily a win to convert things like:
4964 (plus:V (vec_duplicate:V (reg:S R1))
4965 (vec_duplicate:V (reg:S R2)))
4969 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4971 The first might be done entirely in vector registers while the
4972 second might need a move between register files. */
4973 tem
= simplify_binary_operation (code
, GET_MODE_INNER (mode
),
4976 return gen_vec_duplicate (mode
, tem
);
4982 /* Return true if binary operation OP distributes over addition in operand
4983 OPNO, with the other operand being held constant. OPNO counts from 1. */
4986 distributes_over_addition_p (rtx_code op
, int opno
)
5004 simplify_const_binary_operation (enum rtx_code code
, machine_mode mode
,
5007 if (VECTOR_MODE_P (mode
)
5008 && code
!= VEC_CONCAT
5009 && GET_CODE (op0
) == CONST_VECTOR
5010 && GET_CODE (op1
) == CONST_VECTOR
)
5013 if (CONST_VECTOR_STEPPED_P (op0
)
5014 && CONST_VECTOR_STEPPED_P (op1
))
5015 /* We can operate directly on the encoding if:
5017 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5019 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5021 Addition and subtraction are the supported operators
5022 for which this is true. */
5023 step_ok_p
= (code
== PLUS
|| code
== MINUS
);
5024 else if (CONST_VECTOR_STEPPED_P (op0
))
5025 /* We can operate directly on stepped encodings if:
5029 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5031 which is true if (x -> x op c) distributes over addition. */
5032 step_ok_p
= distributes_over_addition_p (code
, 1);
5034 /* Similarly in reverse. */
5035 step_ok_p
= distributes_over_addition_p (code
, 2);
5036 rtx_vector_builder builder
;
5037 if (!builder
.new_binary_operation (mode
, op0
, op1
, step_ok_p
))
5040 unsigned int count
= builder
.encoded_nelts ();
5041 for (unsigned int i
= 0; i
< count
; i
++)
5043 rtx x
= simplify_binary_operation (code
, GET_MODE_INNER (mode
),
5044 CONST_VECTOR_ELT (op0
, i
),
5045 CONST_VECTOR_ELT (op1
, i
));
5046 if (!x
|| !valid_for_const_vector_p (mode
, x
))
5048 builder
.quick_push (x
);
5050 return builder
.build ();
5053 if (VECTOR_MODE_P (mode
)
5054 && code
== VEC_CONCAT
5055 && (CONST_SCALAR_INT_P (op0
)
5056 || CONST_FIXED_P (op0
)
5057 || CONST_DOUBLE_AS_FLOAT_P (op0
))
5058 && (CONST_SCALAR_INT_P (op1
)
5059 || CONST_DOUBLE_AS_FLOAT_P (op1
)
5060 || CONST_FIXED_P (op1
)))
5062 /* Both inputs have a constant number of elements, so the result
5064 unsigned n_elts
= GET_MODE_NUNITS (mode
).to_constant ();
5065 rtvec v
= rtvec_alloc (n_elts
);
5067 gcc_assert (n_elts
>= 2);
5070 gcc_assert (GET_CODE (op0
) != CONST_VECTOR
);
5071 gcc_assert (GET_CODE (op1
) != CONST_VECTOR
);
5073 RTVEC_ELT (v
, 0) = op0
;
5074 RTVEC_ELT (v
, 1) = op1
;
5078 unsigned op0_n_elts
= GET_MODE_NUNITS (GET_MODE (op0
)).to_constant ();
5079 unsigned op1_n_elts
= GET_MODE_NUNITS (GET_MODE (op1
)).to_constant ();
5082 gcc_assert (GET_CODE (op0
) == CONST_VECTOR
);
5083 gcc_assert (GET_CODE (op1
) == CONST_VECTOR
);
5084 gcc_assert (op0_n_elts
+ op1_n_elts
== n_elts
);
5086 for (i
= 0; i
< op0_n_elts
; ++i
)
5087 RTVEC_ELT (v
, i
) = CONST_VECTOR_ELT (op0
, i
);
5088 for (i
= 0; i
< op1_n_elts
; ++i
)
5089 RTVEC_ELT (v
, op0_n_elts
+i
) = CONST_VECTOR_ELT (op1
, i
);
5092 return gen_rtx_CONST_VECTOR (mode
, v
);
5095 if (VECTOR_MODE_P (mode
)
5096 && GET_CODE (op0
) == CONST_VECTOR
5097 && (CONST_SCALAR_INT_P (op1
) || CONST_DOUBLE_AS_FLOAT_P (op1
))
5098 && (CONST_VECTOR_DUPLICATE_P (op0
)
5099 || CONST_VECTOR_NUNITS (op0
).is_constant ()))
5134 unsigned int npatterns
= (CONST_VECTOR_DUPLICATE_P (op0
)
5135 ? CONST_VECTOR_NPATTERNS (op0
)
5136 : CONST_VECTOR_NUNITS (op0
).to_constant ());
5137 rtx_vector_builder
builder (mode
, npatterns
, 1);
5138 for (unsigned i
= 0; i
< npatterns
; i
++)
5140 rtx x
= simplify_binary_operation (code
, GET_MODE_INNER (mode
),
5141 CONST_VECTOR_ELT (op0
, i
), op1
);
5142 if (!x
|| !valid_for_const_vector_p (mode
, x
))
5144 builder
.quick_push (x
);
5146 return builder
.build ();
5149 if (SCALAR_FLOAT_MODE_P (mode
)
5150 && CONST_DOUBLE_AS_FLOAT_P (op0
)
5151 && CONST_DOUBLE_AS_FLOAT_P (op1
)
5152 && mode
== GET_MODE (op0
) && mode
== GET_MODE (op1
))
5163 real_to_target (tmp0
, CONST_DOUBLE_REAL_VALUE (op0
),
5165 real_to_target (tmp1
, CONST_DOUBLE_REAL_VALUE (op1
),
5167 for (i
= 0; i
< 4; i
++)
5184 real_from_target (&r
, tmp0
, mode
);
5185 return const_double_from_real_value (r
, mode
);
5187 else if (code
== COPYSIGN
)
5189 REAL_VALUE_TYPE f0
, f1
;
5190 real_convert (&f0
, mode
, CONST_DOUBLE_REAL_VALUE (op0
));
5191 real_convert (&f1
, mode
, CONST_DOUBLE_REAL_VALUE (op1
));
5192 real_copysign (&f0
, &f1
);
5193 return const_double_from_real_value (f0
, mode
);
5197 REAL_VALUE_TYPE f0
, f1
, value
, result
;
5198 const REAL_VALUE_TYPE
*opr0
, *opr1
;
5201 opr0
= CONST_DOUBLE_REAL_VALUE (op0
);
5202 opr1
= CONST_DOUBLE_REAL_VALUE (op1
);
5204 if (HONOR_SNANS (mode
)
5205 && (REAL_VALUE_ISSIGNALING_NAN (*opr0
)
5206 || REAL_VALUE_ISSIGNALING_NAN (*opr1
)))
5209 real_convert (&f0
, mode
, opr0
);
5210 real_convert (&f1
, mode
, opr1
);
5213 && real_equal (&f1
, &dconst0
)
5214 && (flag_trapping_math
|| ! MODE_HAS_INFINITIES (mode
)))
5217 if (MODE_HAS_INFINITIES (mode
) && HONOR_NANS (mode
)
5218 && flag_trapping_math
5219 && REAL_VALUE_ISINF (f0
) && REAL_VALUE_ISINF (f1
))
5221 int s0
= REAL_VALUE_NEGATIVE (f0
);
5222 int s1
= REAL_VALUE_NEGATIVE (f1
);
5227 /* Inf + -Inf = NaN plus exception. */
5232 /* Inf - Inf = NaN plus exception. */
5237 /* Inf / Inf = NaN plus exception. */
5244 if (code
== MULT
&& MODE_HAS_INFINITIES (mode
) && HONOR_NANS (mode
)
5245 && flag_trapping_math
5246 && ((REAL_VALUE_ISINF (f0
) && real_equal (&f1
, &dconst0
))
5247 || (REAL_VALUE_ISINF (f1
)
5248 && real_equal (&f0
, &dconst0
))))
5249 /* Inf * 0 = NaN plus exception. */
5252 inexact
= real_arithmetic (&value
, rtx_to_tree_code (code
),
5254 real_convert (&result
, mode
, &value
);
5256 /* Don't constant fold this floating point operation if
5257 the result has overflowed and flag_trapping_math. */
5259 if (flag_trapping_math
5260 && MODE_HAS_INFINITIES (mode
)
5261 && REAL_VALUE_ISINF (result
)
5262 && !REAL_VALUE_ISINF (f0
)
5263 && !REAL_VALUE_ISINF (f1
))
5264 /* Overflow plus exception. */
5267 /* Don't constant fold this floating point operation if the
5268 result may dependent upon the run-time rounding mode and
5269 flag_rounding_math is set, or if GCC's software emulation
5270 is unable to accurately represent the result. */
5272 if ((flag_rounding_math
5273 || (MODE_COMPOSITE_P (mode
) && !flag_unsafe_math_optimizations
))
5274 && (inexact
|| !real_identical (&result
, &value
)))
5277 return const_double_from_real_value (result
, mode
);
5281 /* We can fold some multi-word operations. */
5282 scalar_int_mode int_mode
;
5283 if (is_a
<scalar_int_mode
> (mode
, &int_mode
)
5284 && CONST_SCALAR_INT_P (op0
)
5285 && CONST_SCALAR_INT_P (op1
)
5286 && GET_MODE_PRECISION (int_mode
) <= MAX_BITSIZE_MODE_ANY_INT
)
5289 wi::overflow_type overflow
;
5290 rtx_mode_t pop0
= rtx_mode_t (op0
, int_mode
);
5291 rtx_mode_t pop1
= rtx_mode_t (op1
, int_mode
);
5293 #if TARGET_SUPPORTS_WIDE_INT == 0
5294 /* This assert keeps the simplification from producing a result
5295 that cannot be represented in a CONST_DOUBLE but a lot of
5296 upstream callers expect that this function never fails to
5297 simplify something and so you if you added this to the test
5298 above the code would die later anyway. If this assert
5299 happens, you just need to make the port support wide int. */
5300 gcc_assert (GET_MODE_PRECISION (int_mode
) <= HOST_BITS_PER_DOUBLE_INT
);
5305 result
= wi::sub (pop0
, pop1
);
5309 result
= wi::add (pop0
, pop1
);
5313 result
= wi::mul (pop0
, pop1
);
5317 result
= wi::div_trunc (pop0
, pop1
, SIGNED
, &overflow
);
5323 result
= wi::mod_trunc (pop0
, pop1
, SIGNED
, &overflow
);
5329 result
= wi::div_trunc (pop0
, pop1
, UNSIGNED
, &overflow
);
5335 result
= wi::mod_trunc (pop0
, pop1
, UNSIGNED
, &overflow
);
5341 result
= wi::bit_and (pop0
, pop1
);
5345 result
= wi::bit_or (pop0
, pop1
);
5349 result
= wi::bit_xor (pop0
, pop1
);
5353 result
= wi::smin (pop0
, pop1
);
5357 result
= wi::smax (pop0
, pop1
);
5361 result
= wi::umin (pop0
, pop1
);
5365 result
= wi::umax (pop0
, pop1
);
5374 /* The shift count might be in SImode while int_mode might
5375 be narrower. On IA-64 it is even DImode. If the shift
5376 count is too large and doesn't fit into int_mode, we'd
5377 ICE. So, if int_mode is narrower than word, use
5378 word_mode for the shift count. */
5379 if (GET_MODE (op1
) == VOIDmode
5380 && GET_MODE_PRECISION (int_mode
) < BITS_PER_WORD
)
5381 pop1
= rtx_mode_t (op1
, word_mode
);
5383 wide_int wop1
= pop1
;
5384 if (SHIFT_COUNT_TRUNCATED
)
5385 wop1
= wi::umod_trunc (wop1
, GET_MODE_PRECISION (int_mode
));
5386 else if (wi::geu_p (wop1
, GET_MODE_PRECISION (int_mode
)))
5392 result
= wi::lrshift (pop0
, wop1
);
5396 result
= wi::arshift (pop0
, wop1
);
5400 result
= wi::lshift (pop0
, wop1
);
5404 if (wi::leu_p (wop1
, wi::clrsb (pop0
)))
5405 result
= wi::lshift (pop0
, wop1
);
5406 else if (wi::neg_p (pop0
))
5407 result
= wi::min_value (int_mode
, SIGNED
);
5409 result
= wi::max_value (int_mode
, SIGNED
);
5413 if (wi::eq_p (pop0
, 0))
5415 else if (wi::leu_p (wop1
, wi::clz (pop0
)))
5416 result
= wi::lshift (pop0
, wop1
);
5418 result
= wi::max_value (int_mode
, UNSIGNED
);
5429 /* The rotate count might be in SImode while int_mode might
5430 be narrower. On IA-64 it is even DImode. If the shift
5431 count is too large and doesn't fit into int_mode, we'd
5432 ICE. So, if int_mode is narrower than word, use
5433 word_mode for the shift count. */
5434 if (GET_MODE (op1
) == VOIDmode
5435 && GET_MODE_PRECISION (int_mode
) < BITS_PER_WORD
)
5436 pop1
= rtx_mode_t (op1
, word_mode
);
5438 if (wi::neg_p (pop1
))
5444 result
= wi::lrotate (pop0
, pop1
);
5448 result
= wi::rrotate (pop0
, pop1
);
5458 result
= wi::add (pop0
, pop1
, SIGNED
, &overflow
);
5459 clamp_signed_saturation
:
5460 if (overflow
== wi::OVF_OVERFLOW
)
5461 result
= wi::max_value (GET_MODE_PRECISION (int_mode
), SIGNED
);
5462 else if (overflow
== wi::OVF_UNDERFLOW
)
5463 result
= wi::min_value (GET_MODE_PRECISION (int_mode
), SIGNED
);
5464 else if (overflow
!= wi::OVF_NONE
)
5469 result
= wi::add (pop0
, pop1
, UNSIGNED
, &overflow
);
5470 clamp_unsigned_saturation
:
5471 if (overflow
!= wi::OVF_NONE
)
5472 result
= wi::max_value (GET_MODE_PRECISION (int_mode
), UNSIGNED
);
5476 result
= wi::sub (pop0
, pop1
, SIGNED
, &overflow
);
5477 goto clamp_signed_saturation
;
5480 result
= wi::sub (pop0
, pop1
, UNSIGNED
, &overflow
);
5481 if (overflow
!= wi::OVF_NONE
)
5482 result
= wi::min_value (GET_MODE_PRECISION (int_mode
), UNSIGNED
);
5486 result
= wi::mul (pop0
, pop1
, SIGNED
, &overflow
);
5487 goto clamp_signed_saturation
;
5490 result
= wi::mul (pop0
, pop1
, UNSIGNED
, &overflow
);
5491 goto clamp_unsigned_saturation
;
5494 result
= wi::mul_high (pop0
, pop1
, SIGNED
);
5498 result
= wi::mul_high (pop0
, pop1
, UNSIGNED
);
5504 return immed_wide_int_const (result
, int_mode
);
5507 /* Handle polynomial integers. */
5508 if (NUM_POLY_INT_COEFFS
> 1
5509 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
5510 && poly_int_rtx_p (op0
)
5511 && poly_int_rtx_p (op1
))
5513 poly_wide_int result
;
5517 result
= wi::to_poly_wide (op0
, mode
) + wi::to_poly_wide (op1
, mode
);
5521 result
= wi::to_poly_wide (op0
, mode
) - wi::to_poly_wide (op1
, mode
);
5525 if (CONST_SCALAR_INT_P (op1
))
5526 result
= wi::to_poly_wide (op0
, mode
) * rtx_mode_t (op1
, mode
);
5532 if (CONST_SCALAR_INT_P (op1
))
5536 GET_MODE (op1
) == VOIDmode
5537 && GET_MODE_PRECISION (int_mode
) < BITS_PER_WORD
5538 ? word_mode
: mode
);
5539 if (SHIFT_COUNT_TRUNCATED
)
5540 shift
= wi::umod_trunc (shift
, GET_MODE_PRECISION (int_mode
));
5541 else if (wi::geu_p (shift
, GET_MODE_PRECISION (int_mode
)))
5543 result
= wi::to_poly_wide (op0
, mode
) << shift
;
5550 if (!CONST_SCALAR_INT_P (op1
)
5551 || !can_ior_p (wi::to_poly_wide (op0
, mode
),
5552 rtx_mode_t (op1
, mode
), &result
))
5559 return immed_wide_int_const (result
, int_mode
);
5567 /* Return a positive integer if X should sort after Y. The value
5568 returned is 1 if and only if X and Y are both regs. */
5571 simplify_plus_minus_op_data_cmp (rtx x
, rtx y
)
5575 result
= (commutative_operand_precedence (y
)
5576 - commutative_operand_precedence (x
));
5578 return result
+ result
;
5580 /* Group together equal REGs to do more simplification. */
5581 if (REG_P (x
) && REG_P (y
))
5582 return REGNO (x
) > REGNO (y
);
5587 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5588 operands may be another PLUS or MINUS.
5590 Rather than test for specific case, we do this by a brute-force method
5591 and do all possible simplifications until no more changes occur. Then
5592 we rebuild the operation.
5594 May return NULL_RTX when no changes were made. */
5597 simplify_context::simplify_plus_minus (rtx_code code
, machine_mode mode
,
5600 struct simplify_plus_minus_op_data
5607 int changed
, n_constants
, canonicalized
= 0;
5610 memset (ops
, 0, sizeof ops
);
5612 /* Set up the two operands and then expand them until nothing has been
5613 changed. If we run out of room in our array, give up; this should
5614 almost never happen. */
5619 ops
[1].neg
= (code
== MINUS
);
5626 for (i
= 0; i
< n_ops
; i
++)
5628 rtx this_op
= ops
[i
].op
;
5629 int this_neg
= ops
[i
].neg
;
5630 enum rtx_code this_code
= GET_CODE (this_op
);
5636 if (n_ops
== ARRAY_SIZE (ops
))
5639 ops
[n_ops
].op
= XEXP (this_op
, 1);
5640 ops
[n_ops
].neg
= (this_code
== MINUS
) ^ this_neg
;
5643 ops
[i
].op
= XEXP (this_op
, 0);
5645 /* If this operand was negated then we will potentially
5646 canonicalize the expression. Similarly if we don't
5647 place the operands adjacent we're re-ordering the
5648 expression and thus might be performing a
5649 canonicalization. Ignore register re-ordering.
5650 ??? It might be better to shuffle the ops array here,
5651 but then (plus (plus (A, B), plus (C, D))) wouldn't
5652 be seen as non-canonical. */
5655 && !(REG_P (ops
[i
].op
) && REG_P (ops
[n_ops
- 1].op
))))
5660 ops
[i
].op
= XEXP (this_op
, 0);
5661 ops
[i
].neg
= ! this_neg
;
5667 if (n_ops
!= ARRAY_SIZE (ops
)
5668 && GET_CODE (XEXP (this_op
, 0)) == PLUS
5669 && CONSTANT_P (XEXP (XEXP (this_op
, 0), 0))
5670 && CONSTANT_P (XEXP (XEXP (this_op
, 0), 1)))
5672 ops
[i
].op
= XEXP (XEXP (this_op
, 0), 0);
5673 ops
[n_ops
].op
= XEXP (XEXP (this_op
, 0), 1);
5674 ops
[n_ops
].neg
= this_neg
;
5682 /* ~a -> (-a - 1) */
5683 if (n_ops
!= ARRAY_SIZE (ops
))
5685 ops
[n_ops
].op
= CONSTM1_RTX (mode
);
5686 ops
[n_ops
++].neg
= this_neg
;
5687 ops
[i
].op
= XEXP (this_op
, 0);
5688 ops
[i
].neg
= !this_neg
;
5694 CASE_CONST_SCALAR_INT
:
5695 case CONST_POLY_INT
:
5699 ops
[i
].op
= neg_poly_int_rtx (mode
, this_op
);
5713 if (n_constants
> 1)
5716 gcc_assert (n_ops
>= 2);
5718 /* If we only have two operands, we can avoid the loops. */
5721 enum rtx_code code
= ops
[0].neg
|| ops
[1].neg
? MINUS
: PLUS
;
5724 /* Get the two operands. Be careful with the order, especially for
5725 the cases where code == MINUS. */
5726 if (ops
[0].neg
&& ops
[1].neg
)
5728 lhs
= gen_rtx_NEG (mode
, ops
[0].op
);
5731 else if (ops
[0].neg
)
5742 return simplify_const_binary_operation (code
, mode
, lhs
, rhs
);
5745 /* Now simplify each pair of operands until nothing changes. */
5748 /* Insertion sort is good enough for a small array. */
5749 for (i
= 1; i
< n_ops
; i
++)
5751 struct simplify_plus_minus_op_data save
;
5755 cmp
= simplify_plus_minus_op_data_cmp (ops
[j
].op
, ops
[i
].op
);
5758 /* Just swapping registers doesn't count as canonicalization. */
5764 ops
[j
+ 1] = ops
[j
];
5766 && simplify_plus_minus_op_data_cmp (ops
[j
].op
, save
.op
) > 0);
5771 for (i
= n_ops
- 1; i
> 0; i
--)
5772 for (j
= i
- 1; j
>= 0; j
--)
5774 rtx lhs
= ops
[j
].op
, rhs
= ops
[i
].op
;
5775 int lneg
= ops
[j
].neg
, rneg
= ops
[i
].neg
;
5777 if (lhs
!= 0 && rhs
!= 0)
5779 enum rtx_code ncode
= PLUS
;
5785 std::swap (lhs
, rhs
);
5787 else if (swap_commutative_operands_p (lhs
, rhs
))
5788 std::swap (lhs
, rhs
);
5790 if ((GET_CODE (lhs
) == CONST
|| CONST_INT_P (lhs
))
5791 && (GET_CODE (rhs
) == CONST
|| CONST_INT_P (rhs
)))
5793 rtx tem_lhs
, tem_rhs
;
5795 tem_lhs
= GET_CODE (lhs
) == CONST
? XEXP (lhs
, 0) : lhs
;
5796 tem_rhs
= GET_CODE (rhs
) == CONST
? XEXP (rhs
, 0) : rhs
;
5797 tem
= simplify_binary_operation (ncode
, mode
, tem_lhs
,
5800 if (tem
&& !CONSTANT_P (tem
))
5801 tem
= gen_rtx_CONST (GET_MODE (tem
), tem
);
5804 tem
= simplify_binary_operation (ncode
, mode
, lhs
, rhs
);
5808 /* Reject "simplifications" that just wrap the two
5809 arguments in a CONST. Failure to do so can result
5810 in infinite recursion with simplify_binary_operation
5811 when it calls us to simplify CONST operations.
5812 Also, if we find such a simplification, don't try
5813 any more combinations with this rhs: We must have
5814 something like symbol+offset, ie. one of the
5815 trivial CONST expressions we handle later. */
5816 if (GET_CODE (tem
) == CONST
5817 && GET_CODE (XEXP (tem
, 0)) == ncode
5818 && XEXP (XEXP (tem
, 0), 0) == lhs
5819 && XEXP (XEXP (tem
, 0), 1) == rhs
)
5822 if (GET_CODE (tem
) == NEG
)
5823 tem
= XEXP (tem
, 0), lneg
= !lneg
;
5824 if (poly_int_rtx_p (tem
) && lneg
)
5825 tem
= neg_poly_int_rtx (mode
, tem
), lneg
= 0;
5829 ops
[j
].op
= NULL_RTX
;
5839 /* Pack all the operands to the lower-numbered entries. */
5840 for (i
= 0, j
= 0; j
< n_ops
; j
++)
5849 /* If nothing changed, check that rematerialization of rtl instructions
5850 is still required. */
5853 /* Perform rematerialization if only all operands are registers and
5854 all operations are PLUS. */
5855 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5856 around rs6000 and how it uses the CA register. See PR67145. */
5857 for (i
= 0; i
< n_ops
; i
++)
5859 || !REG_P (ops
[i
].op
)
5860 || (REGNO (ops
[i
].op
) < FIRST_PSEUDO_REGISTER
5861 && fixed_regs
[REGNO (ops
[i
].op
)]
5862 && !global_regs
[REGNO (ops
[i
].op
)]
5863 && ops
[i
].op
!= frame_pointer_rtx
5864 && ops
[i
].op
!= arg_pointer_rtx
5865 && ops
[i
].op
!= stack_pointer_rtx
))
5870 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5872 && CONST_INT_P (ops
[1].op
)
5873 && CONSTANT_P (ops
[0].op
)
5875 return gen_rtx_fmt_ee (MINUS
, mode
, ops
[1].op
, ops
[0].op
);
5877 /* We suppressed creation of trivial CONST expressions in the
5878 combination loop to avoid recursion. Create one manually now.
5879 The combination loop should have ensured that there is exactly
5880 one CONST_INT, and the sort will have ensured that it is last
5881 in the array and that any other constant will be next-to-last. */
5884 && poly_int_rtx_p (ops
[n_ops
- 1].op
)
5885 && CONSTANT_P (ops
[n_ops
- 2].op
))
5887 rtx value
= ops
[n_ops
- 1].op
;
5888 if (ops
[n_ops
- 1].neg
^ ops
[n_ops
- 2].neg
)
5889 value
= neg_poly_int_rtx (mode
, value
);
5890 if (CONST_INT_P (value
))
5892 ops
[n_ops
- 2].op
= plus_constant (mode
, ops
[n_ops
- 2].op
,
5898 /* Put a non-negated operand first, if possible. */
5900 for (i
= 0; i
< n_ops
&& ops
[i
].neg
; i
++)
5903 ops
[0].op
= gen_rtx_NEG (mode
, ops
[0].op
);
5912 /* Now make the result by performing the requested operations. */
5915 for (i
= 1; i
< n_ops
; i
++)
5916 result
= gen_rtx_fmt_ee (ops
[i
].neg
? MINUS
: PLUS
,
5917 mode
, result
, ops
[i
].op
);
5922 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5924 plus_minus_operand_p (const_rtx x
)
5926 return GET_CODE (x
) == PLUS
5927 || GET_CODE (x
) == MINUS
5928 || (GET_CODE (x
) == CONST
5929 && GET_CODE (XEXP (x
, 0)) == PLUS
5930 && CONSTANT_P (XEXP (XEXP (x
, 0), 0))
5931 && CONSTANT_P (XEXP (XEXP (x
, 0), 1)));
5934 /* Like simplify_binary_operation except used for relational operators.
5935 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5936 not also be VOIDmode.
5938 CMP_MODE specifies in which mode the comparison is done in, so it is
5939 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5940 the operands or, if both are VOIDmode, the operands are compared in
5941 "infinite precision". */
5943 simplify_context::simplify_relational_operation (rtx_code code
,
5945 machine_mode cmp_mode
,
5948 rtx tem
, trueop0
, trueop1
;
5950 if (cmp_mode
== VOIDmode
)
5951 cmp_mode
= GET_MODE (op0
);
5952 if (cmp_mode
== VOIDmode
)
5953 cmp_mode
= GET_MODE (op1
);
5955 tem
= simplify_const_relational_operation (code
, cmp_mode
, op0
, op1
);
5957 return relational_result (mode
, cmp_mode
, tem
);
5959 /* For the following tests, ensure const0_rtx is op1. */
5960 if (swap_commutative_operands_p (op0
, op1
)
5961 || (op0
== const0_rtx
&& op1
!= const0_rtx
))
5962 std::swap (op0
, op1
), code
= swap_condition (code
);
5964 /* If op0 is a compare, extract the comparison arguments from it. */
5965 if (GET_CODE (op0
) == COMPARE
&& op1
== const0_rtx
)
5966 return simplify_gen_relational (code
, mode
, VOIDmode
,
5967 XEXP (op0
, 0), XEXP (op0
, 1));
5969 if (GET_MODE_CLASS (cmp_mode
) == MODE_CC
)
5972 trueop0
= avoid_constant_pool_reference (op0
);
5973 trueop1
= avoid_constant_pool_reference (op1
);
5974 return simplify_relational_operation_1 (code
, mode
, cmp_mode
,
5978 /* This part of simplify_relational_operation is only used when CMP_MODE
5979 is not in class MODE_CC (i.e. it is a real comparison).
5981 MODE is the mode of the result, while CMP_MODE specifies in which
5982 mode the comparison is done in, so it is the mode of the operands. */
5985 simplify_context::simplify_relational_operation_1 (rtx_code code
,
5987 machine_mode cmp_mode
,
5990 enum rtx_code op0code
= GET_CODE (op0
);
5992 if (op1
== const0_rtx
&& COMPARISON_P (op0
))
5994 /* If op0 is a comparison, extract the comparison arguments
5998 if (GET_MODE (op0
) == mode
)
5999 return simplify_rtx (op0
);
6001 return simplify_gen_relational (GET_CODE (op0
), mode
, VOIDmode
,
6002 XEXP (op0
, 0), XEXP (op0
, 1));
6004 else if (code
== EQ
)
6006 enum rtx_code new_code
= reversed_comparison_code (op0
, NULL
);
6007 if (new_code
!= UNKNOWN
)
6008 return simplify_gen_relational (new_code
, mode
, VOIDmode
,
6009 XEXP (op0
, 0), XEXP (op0
, 1));
6013 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6014 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6015 if ((code
== LTU
|| code
== GEU
)
6016 && GET_CODE (op0
) == PLUS
6017 && CONST_INT_P (XEXP (op0
, 1))
6018 && (rtx_equal_p (op1
, XEXP (op0
, 0))
6019 || rtx_equal_p (op1
, XEXP (op0
, 1)))
6020 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6021 && XEXP (op0
, 1) != const0_rtx
)
6024 = simplify_gen_unary (NEG
, cmp_mode
, XEXP (op0
, 1), cmp_mode
);
6025 return simplify_gen_relational ((code
== LTU
? GEU
: LTU
), mode
,
6026 cmp_mode
, XEXP (op0
, 0), new_cmp
);
6029 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6030 transformed into (LTU a -C). */
6031 if (code
== GTU
&& GET_CODE (op0
) == PLUS
&& CONST_INT_P (op1
)
6032 && CONST_INT_P (XEXP (op0
, 1))
6033 && (UINTVAL (op1
) == UINTVAL (XEXP (op0
, 1)) - 1)
6034 && XEXP (op0
, 1) != const0_rtx
)
6037 = simplify_gen_unary (NEG
, cmp_mode
, XEXP (op0
, 1), cmp_mode
);
6038 return simplify_gen_relational (LTU
, mode
, cmp_mode
,
6039 XEXP (op0
, 0), new_cmp
);
6042 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6043 if ((code
== LTU
|| code
== GEU
)
6044 && GET_CODE (op0
) == PLUS
6045 && rtx_equal_p (op1
, XEXP (op0
, 1))
6046 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6047 && !rtx_equal_p (op1
, XEXP (op0
, 0)))
6048 return simplify_gen_relational (code
, mode
, cmp_mode
, op0
,
6049 copy_rtx (XEXP (op0
, 0)));
6051 if (op1
== const0_rtx
)
6053 /* Canonicalize (GTU x 0) as (NE x 0). */
6055 return simplify_gen_relational (NE
, mode
, cmp_mode
, op0
, op1
);
6056 /* Canonicalize (LEU x 0) as (EQ x 0). */
6058 return simplify_gen_relational (EQ
, mode
, cmp_mode
, op0
, op1
);
6060 else if (op1
== const1_rtx
)
6065 /* Canonicalize (GE x 1) as (GT x 0). */
6066 return simplify_gen_relational (GT
, mode
, cmp_mode
,
6069 /* Canonicalize (GEU x 1) as (NE x 0). */
6070 return simplify_gen_relational (NE
, mode
, cmp_mode
,
6073 /* Canonicalize (LT x 1) as (LE x 0). */
6074 return simplify_gen_relational (LE
, mode
, cmp_mode
,
6077 /* Canonicalize (LTU x 1) as (EQ x 0). */
6078 return simplify_gen_relational (EQ
, mode
, cmp_mode
,
6084 else if (op1
== constm1_rtx
)
6086 /* Canonicalize (LE x -1) as (LT x 0). */
6088 return simplify_gen_relational (LT
, mode
, cmp_mode
, op0
, const0_rtx
);
6089 /* Canonicalize (GT x -1) as (GE x 0). */
6091 return simplify_gen_relational (GE
, mode
, cmp_mode
, op0
, const0_rtx
);
6094 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6095 if ((code
== EQ
|| code
== NE
)
6096 && (op0code
== PLUS
|| op0code
== MINUS
)
6098 && CONSTANT_P (XEXP (op0
, 1))
6099 && (INTEGRAL_MODE_P (cmp_mode
) || flag_unsafe_math_optimizations
))
6101 rtx x
= XEXP (op0
, 0);
6102 rtx c
= XEXP (op0
, 1);
6103 enum rtx_code invcode
= op0code
== PLUS
? MINUS
: PLUS
;
6104 rtx tem
= simplify_gen_binary (invcode
, cmp_mode
, op1
, c
);
6106 /* Detect an infinite recursive condition, where we oscillate at this
6107 simplification case between:
6108 A + B == C <---> C - B == A,
6109 where A, B, and C are all constants with non-simplifiable expressions,
6110 usually SYMBOL_REFs. */
6111 if (GET_CODE (tem
) == invcode
6113 && rtx_equal_p (c
, XEXP (tem
, 1)))
6116 return simplify_gen_relational (code
, mode
, cmp_mode
, x
, tem
);
6119 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6120 the same as (zero_extract:SI FOO (const_int 1) BAR). */
6121 scalar_int_mode int_mode
, int_cmp_mode
;
6123 && op1
== const0_rtx
6124 && is_int_mode (mode
, &int_mode
)
6125 && is_a
<scalar_int_mode
> (cmp_mode
, &int_cmp_mode
)
6126 /* ??? Work-around BImode bugs in the ia64 backend. */
6127 && int_mode
!= BImode
6128 && int_cmp_mode
!= BImode
6129 && nonzero_bits (op0
, int_cmp_mode
) == 1
6130 && STORE_FLAG_VALUE
== 1)
6131 return GET_MODE_SIZE (int_mode
) > GET_MODE_SIZE (int_cmp_mode
)
6132 ? simplify_gen_unary (ZERO_EXTEND
, int_mode
, op0
, int_cmp_mode
)
6133 : lowpart_subreg (int_mode
, op0
, int_cmp_mode
);
6135 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6136 if ((code
== EQ
|| code
== NE
)
6137 && op1
== const0_rtx
6139 return simplify_gen_relational (code
, mode
, cmp_mode
,
6140 XEXP (op0
, 0), XEXP (op0
, 1));
6142 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6143 if ((code
== EQ
|| code
== NE
)
6145 && rtx_equal_p (XEXP (op0
, 0), op1
)
6146 && !side_effects_p (XEXP (op0
, 0)))
6147 return simplify_gen_relational (code
, mode
, cmp_mode
, XEXP (op0
, 1),
6150 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6151 if ((code
== EQ
|| code
== NE
)
6153 && rtx_equal_p (XEXP (op0
, 1), op1
)
6154 && !side_effects_p (XEXP (op0
, 1)))
6155 return simplify_gen_relational (code
, mode
, cmp_mode
, XEXP (op0
, 0),
6158 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6159 if ((code
== EQ
|| code
== NE
)
6161 && CONST_SCALAR_INT_P (op1
)
6162 && CONST_SCALAR_INT_P (XEXP (op0
, 1)))
6163 return simplify_gen_relational (code
, mode
, cmp_mode
, XEXP (op0
, 0),
6164 simplify_gen_binary (XOR
, cmp_mode
,
6165 XEXP (op0
, 1), op1
));
6167 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6168 constant folding if x/y is a constant. */
6169 if ((code
== EQ
|| code
== NE
)
6170 && (op0code
== AND
|| op0code
== IOR
)
6171 && !side_effects_p (op1
)
6172 && op1
!= CONST0_RTX (cmp_mode
))
6174 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6175 (eq/ne (and (not y) x) 0). */
6176 if ((op0code
== AND
&& rtx_equal_p (XEXP (op0
, 0), op1
))
6177 || (op0code
== IOR
&& rtx_equal_p (XEXP (op0
, 1), op1
)))
6179 rtx not_y
= simplify_gen_unary (NOT
, cmp_mode
, XEXP (op0
, 1),
6181 rtx lhs
= simplify_gen_binary (AND
, cmp_mode
, not_y
, XEXP (op0
, 0));
6183 return simplify_gen_relational (code
, mode
, cmp_mode
, lhs
,
6184 CONST0_RTX (cmp_mode
));
6187 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6188 (eq/ne (and (not x) y) 0). */
6189 if ((op0code
== AND
&& rtx_equal_p (XEXP (op0
, 1), op1
))
6190 || (op0code
== IOR
&& rtx_equal_p (XEXP (op0
, 0), op1
)))
6192 rtx not_x
= simplify_gen_unary (NOT
, cmp_mode
, XEXP (op0
, 0),
6194 rtx lhs
= simplify_gen_binary (AND
, cmp_mode
, not_x
, XEXP (op0
, 1));
6196 return simplify_gen_relational (code
, mode
, cmp_mode
, lhs
,
6197 CONST0_RTX (cmp_mode
));
6201 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6202 if ((code
== EQ
|| code
== NE
)
6203 && GET_CODE (op0
) == BSWAP
6204 && CONST_SCALAR_INT_P (op1
))
6205 return simplify_gen_relational (code
, mode
, cmp_mode
, XEXP (op0
, 0),
6206 simplify_gen_unary (BSWAP
, cmp_mode
,
6209 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6210 if ((code
== EQ
|| code
== NE
)
6211 && GET_CODE (op0
) == BSWAP
6212 && GET_CODE (op1
) == BSWAP
)
6213 return simplify_gen_relational (code
, mode
, cmp_mode
,
6214 XEXP (op0
, 0), XEXP (op1
, 0));
6216 if (op0code
== POPCOUNT
&& op1
== const0_rtx
)
6222 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6223 return simplify_gen_relational (EQ
, mode
, GET_MODE (XEXP (op0
, 0)),
6224 XEXP (op0
, 0), const0_rtx
);
6229 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6230 return simplify_gen_relational (NE
, mode
, GET_MODE (XEXP (op0
, 0)),
6231 XEXP (op0
, 0), const0_rtx
);
6237 /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6239 && op1
== const0_rtx
6240 && (op0code
== TRUNCATE
6241 || (partial_subreg_p (op0
)
6242 && subreg_lowpart_p (op0
)))
6243 && SCALAR_INT_MODE_P (mode
)
6244 && STORE_FLAG_VALUE
== 1)
6246 rtx tmp
= XEXP (op0
, 0);
6247 if (GET_CODE (tmp
) == ASHIFT
6248 && GET_MODE (tmp
) == mode
6249 && CONST_INT_P (XEXP (tmp
, 1))
6250 && is_int_mode (GET_MODE (op0
), &int_mode
)
6251 && INTVAL (XEXP (tmp
, 1)) == GET_MODE_PRECISION (int_mode
) - 1)
6252 return simplify_gen_binary (AND
, mode
, XEXP (tmp
, 0), const1_rtx
);
6267 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6268 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6269 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6270 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6271 For floating-point comparisons, assume that the operands were ordered. */
6274 comparison_result (enum rtx_code code
, int known_results
)
6280 return (known_results
& CMP_EQ
) ? const_true_rtx
: const0_rtx
;
6283 return (known_results
& CMP_EQ
) ? const0_rtx
: const_true_rtx
;
6287 return (known_results
& CMP_LT
) ? const_true_rtx
: const0_rtx
;
6290 return (known_results
& CMP_LT
) ? const0_rtx
: const_true_rtx
;
6294 return (known_results
& CMP_GT
) ? const_true_rtx
: const0_rtx
;
6297 return (known_results
& CMP_GT
) ? const0_rtx
: const_true_rtx
;
6300 return (known_results
& CMP_LTU
) ? const_true_rtx
: const0_rtx
;
6302 return (known_results
& CMP_LTU
) ? const0_rtx
: const_true_rtx
;
6305 return (known_results
& CMP_GTU
) ? const_true_rtx
: const0_rtx
;
6307 return (known_results
& CMP_GTU
) ? const0_rtx
: const_true_rtx
;
6310 return const_true_rtx
;
6318 /* Check if the given comparison (done in the given MODE) is actually
6319 a tautology or a contradiction. If the mode is VOIDmode, the
6320 comparison is done in "infinite precision". If no simplification
6321 is possible, this function returns zero. Otherwise, it returns
6322 either const_true_rtx or const0_rtx. */
6325 simplify_const_relational_operation (enum rtx_code code
,
6333 gcc_assert (mode
!= VOIDmode
6334 || (GET_MODE (op0
) == VOIDmode
6335 && GET_MODE (op1
) == VOIDmode
));
6337 /* We only handle MODE_CC comparisons that are COMPARE against zero. */
6338 if (GET_MODE_CLASS (mode
) == MODE_CC
6339 && (op1
!= const0_rtx
6340 || GET_CODE (op0
) != COMPARE
))
6343 /* If op0 is a compare, extract the comparison arguments from it. */
6344 if (GET_CODE (op0
) == COMPARE
&& op1
== const0_rtx
)
6346 op1
= XEXP (op0
, 1);
6347 op0
= XEXP (op0
, 0);
6349 if (GET_MODE (op0
) != VOIDmode
)
6350 mode
= GET_MODE (op0
);
6351 else if (GET_MODE (op1
) != VOIDmode
)
6352 mode
= GET_MODE (op1
);
6357 /* We can't simplify MODE_CC values since we don't know what the
6358 actual comparison is. */
6359 if (GET_MODE_CLASS (GET_MODE (op0
)) == MODE_CC
)
6362 /* Make sure the constant is second. */
6363 if (swap_commutative_operands_p (op0
, op1
))
6365 std::swap (op0
, op1
);
6366 code
= swap_condition (code
);
6369 trueop0
= avoid_constant_pool_reference (op0
);
6370 trueop1
= avoid_constant_pool_reference (op1
);
6372 /* For integer comparisons of A and B maybe we can simplify A - B and can
6373 then simplify a comparison of that with zero. If A and B are both either
6374 a register or a CONST_INT, this can't help; testing for these cases will
6375 prevent infinite recursion here and speed things up.
6377 We can only do this for EQ and NE comparisons as otherwise we may
6378 lose or introduce overflow which we cannot disregard as undefined as
6379 we do not know the signedness of the operation on either the left or
6380 the right hand side of the comparison. */
6382 if (INTEGRAL_MODE_P (mode
) && trueop1
!= const0_rtx
6383 && (code
== EQ
|| code
== NE
)
6384 && ! ((REG_P (op0
) || CONST_INT_P (trueop0
))
6385 && (REG_P (op1
) || CONST_INT_P (trueop1
)))
6386 && (tem
= simplify_binary_operation (MINUS
, mode
, op0
, op1
)) != 0
6387 /* We cannot do this if tem is a nonzero address. */
6388 && ! nonzero_address_p (tem
))
6389 return simplify_const_relational_operation (signed_condition (code
),
6390 mode
, tem
, const0_rtx
);
6392 if (! HONOR_NANS (mode
) && code
== ORDERED
)
6393 return const_true_rtx
;
6395 if (! HONOR_NANS (mode
) && code
== UNORDERED
)
6398 /* For modes without NaNs, if the two operands are equal, we know the
6399 result except if they have side-effects. Even with NaNs we know
6400 the result of unordered comparisons and, if signaling NaNs are
6401 irrelevant, also the result of LT/GT/LTGT. */
6402 if ((! HONOR_NANS (trueop0
)
6403 || code
== UNEQ
|| code
== UNLE
|| code
== UNGE
6404 || ((code
== LT
|| code
== GT
|| code
== LTGT
)
6405 && ! HONOR_SNANS (trueop0
)))
6406 && rtx_equal_p (trueop0
, trueop1
)
6407 && ! side_effects_p (trueop0
))
6408 return comparison_result (code
, CMP_EQ
);
6410 /* If the operands are floating-point constants, see if we can fold
6412 if (CONST_DOUBLE_AS_FLOAT_P (trueop0
)
6413 && CONST_DOUBLE_AS_FLOAT_P (trueop1
)
6414 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0
)))
6416 const REAL_VALUE_TYPE
*d0
= CONST_DOUBLE_REAL_VALUE (trueop0
);
6417 const REAL_VALUE_TYPE
*d1
= CONST_DOUBLE_REAL_VALUE (trueop1
);
6419 /* Comparisons are unordered iff at least one of the values is NaN. */
6420 if (REAL_VALUE_ISNAN (*d0
) || REAL_VALUE_ISNAN (*d1
))
6430 return const_true_rtx
;
6443 return comparison_result (code
,
6444 (real_equal (d0
, d1
) ? CMP_EQ
:
6445 real_less (d0
, d1
) ? CMP_LT
: CMP_GT
));
6448 /* Otherwise, see if the operands are both integers. */
6449 if ((GET_MODE_CLASS (mode
) == MODE_INT
|| mode
== VOIDmode
)
6450 && CONST_SCALAR_INT_P (trueop0
) && CONST_SCALAR_INT_P (trueop1
))
6452 /* It would be nice if we really had a mode here. However, the
6453 largest int representable on the target is as good as
6455 machine_mode cmode
= (mode
== VOIDmode
) ? MAX_MODE_INT
: mode
;
6456 rtx_mode_t ptrueop0
= rtx_mode_t (trueop0
, cmode
);
6457 rtx_mode_t ptrueop1
= rtx_mode_t (trueop1
, cmode
);
6459 if (wi::eq_p (ptrueop0
, ptrueop1
))
6460 return comparison_result (code
, CMP_EQ
);
6463 int cr
= wi::lts_p (ptrueop0
, ptrueop1
) ? CMP_LT
: CMP_GT
;
6464 cr
|= wi::ltu_p (ptrueop0
, ptrueop1
) ? CMP_LTU
: CMP_GTU
;
6465 return comparison_result (code
, cr
);
6469 /* Optimize comparisons with upper and lower bounds. */
6470 scalar_int_mode int_mode
;
6471 if (CONST_INT_P (trueop1
)
6472 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
6473 && HWI_COMPUTABLE_MODE_P (int_mode
)
6474 && !side_effects_p (trueop0
))
6477 unsigned HOST_WIDE_INT nonzero
= nonzero_bits (trueop0
, int_mode
);
6478 HOST_WIDE_INT val
= INTVAL (trueop1
);
6479 HOST_WIDE_INT mmin
, mmax
;
6489 /* Get a reduced range if the sign bit is zero. */
6490 if (nonzero
<= (GET_MODE_MASK (int_mode
) >> 1))
6497 rtx mmin_rtx
, mmax_rtx
;
6498 get_mode_bounds (int_mode
, sign
, int_mode
, &mmin_rtx
, &mmax_rtx
);
6500 mmin
= INTVAL (mmin_rtx
);
6501 mmax
= INTVAL (mmax_rtx
);
6504 unsigned int sign_copies
6505 = num_sign_bit_copies (trueop0
, int_mode
);
6507 mmin
>>= (sign_copies
- 1);
6508 mmax
>>= (sign_copies
- 1);
6514 /* x >= y is always true for y <= mmin, always false for y > mmax. */
6516 if ((unsigned HOST_WIDE_INT
) val
<= (unsigned HOST_WIDE_INT
) mmin
)
6517 return const_true_rtx
;
6518 if ((unsigned HOST_WIDE_INT
) val
> (unsigned HOST_WIDE_INT
) mmax
)
6523 return const_true_rtx
;
6528 /* x <= y is always true for y >= mmax, always false for y < mmin. */
6530 if ((unsigned HOST_WIDE_INT
) val
>= (unsigned HOST_WIDE_INT
) mmax
)
6531 return const_true_rtx
;
6532 if ((unsigned HOST_WIDE_INT
) val
< (unsigned HOST_WIDE_INT
) mmin
)
6537 return const_true_rtx
;
6543 /* x == y is always false for y out of range. */
6544 if (val
< mmin
|| val
> mmax
)
6548 /* x > y is always false for y >= mmax, always true for y < mmin. */
6550 if ((unsigned HOST_WIDE_INT
) val
>= (unsigned HOST_WIDE_INT
) mmax
)
6552 if ((unsigned HOST_WIDE_INT
) val
< (unsigned HOST_WIDE_INT
) mmin
)
6553 return const_true_rtx
;
6559 return const_true_rtx
;
6562 /* x < y is always false for y <= mmin, always true for y > mmax. */
6564 if ((unsigned HOST_WIDE_INT
) val
<= (unsigned HOST_WIDE_INT
) mmin
)
6566 if ((unsigned HOST_WIDE_INT
) val
> (unsigned HOST_WIDE_INT
) mmax
)
6567 return const_true_rtx
;
6573 return const_true_rtx
;
6577 /* x != y is always true for y out of range. */
6578 if (val
< mmin
|| val
> mmax
)
6579 return const_true_rtx
;
6587 /* Optimize integer comparisons with zero. */
6588 if (is_a
<scalar_int_mode
> (mode
, &int_mode
)
6589 && trueop1
== const0_rtx
6590 && !side_effects_p (trueop0
))
6592 /* Some addresses are known to be nonzero. We don't know
6593 their sign, but equality comparisons are known. */
6594 if (nonzero_address_p (trueop0
))
6596 if (code
== EQ
|| code
== LEU
)
6598 if (code
== NE
|| code
== GTU
)
6599 return const_true_rtx
;
6602 /* See if the first operand is an IOR with a constant. If so, we
6603 may be able to determine the result of this comparison. */
6604 if (GET_CODE (op0
) == IOR
)
6606 rtx inner_const
= avoid_constant_pool_reference (XEXP (op0
, 1));
6607 if (CONST_INT_P (inner_const
) && inner_const
!= const0_rtx
)
6609 int sign_bitnum
= GET_MODE_PRECISION (int_mode
) - 1;
6610 int has_sign
= (HOST_BITS_PER_WIDE_INT
>= sign_bitnum
6611 && (UINTVAL (inner_const
)
6622 return const_true_rtx
;
6626 return const_true_rtx
;
6640 /* Optimize comparison of ABS with zero. */
6641 if (trueop1
== CONST0_RTX (mode
) && !side_effects_p (trueop0
)
6642 && (GET_CODE (trueop0
) == ABS
6643 || (GET_CODE (trueop0
) == FLOAT_EXTEND
6644 && GET_CODE (XEXP (trueop0
, 0)) == ABS
)))
6649 /* Optimize abs(x) < 0.0. */
6650 if (!INTEGRAL_MODE_P (mode
) && !HONOR_SNANS (mode
))
6655 /* Optimize abs(x) >= 0.0. */
6656 if (!INTEGRAL_MODE_P (mode
) && !HONOR_NANS (mode
))
6657 return const_true_rtx
;
6661 /* Optimize ! (abs(x) < 0.0). */
6662 return const_true_rtx
;
6672 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6673 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6674 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6675 can be simplified to that or NULL_RTX if not.
6676 Assume X is compared against zero with CMP_CODE and the true
6677 arm is TRUE_VAL and the false arm is FALSE_VAL. */
6680 simplify_context::simplify_cond_clz_ctz (rtx x
, rtx_code cmp_code
,
6681 rtx true_val
, rtx false_val
)
6683 if (cmp_code
!= EQ
&& cmp_code
!= NE
)
6686 /* Result on X == 0 and X !=0 respectively. */
6687 rtx on_zero
, on_nonzero
;
6691 on_nonzero
= false_val
;
6695 on_zero
= false_val
;
6696 on_nonzero
= true_val
;
6699 rtx_code op_code
= GET_CODE (on_nonzero
);
6700 if ((op_code
!= CLZ
&& op_code
!= CTZ
)
6701 || !rtx_equal_p (XEXP (on_nonzero
, 0), x
)
6702 || !CONST_INT_P (on_zero
))
6705 HOST_WIDE_INT op_val
;
6706 scalar_int_mode mode ATTRIBUTE_UNUSED
6707 = as_a
<scalar_int_mode
> (GET_MODE (XEXP (on_nonzero
, 0)));
6708 if (((op_code
== CLZ
&& CLZ_DEFINED_VALUE_AT_ZERO (mode
, op_val
))
6709 || (op_code
== CTZ
&& CTZ_DEFINED_VALUE_AT_ZERO (mode
, op_val
)))
6710 && op_val
== INTVAL (on_zero
))
6716 /* Try to simplify X given that it appears within operand OP of a
6717 VEC_MERGE operation whose mask is MASK. X need not use the same
6718 vector mode as the VEC_MERGE, but it must have the same number of
6721 Return the simplified X on success, otherwise return NULL_RTX. */
6724 simplify_context::simplify_merge_mask (rtx x
, rtx mask
, int op
)
6726 gcc_assert (VECTOR_MODE_P (GET_MODE (x
)));
6727 poly_uint64 nunits
= GET_MODE_NUNITS (GET_MODE (x
));
6728 if (GET_CODE (x
) == VEC_MERGE
&& rtx_equal_p (XEXP (x
, 2), mask
))
6730 if (side_effects_p (XEXP (x
, 1 - op
)))
6733 return XEXP (x
, op
);
6736 && VECTOR_MODE_P (GET_MODE (XEXP (x
, 0)))
6737 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x
, 0))), nunits
))
6739 rtx top0
= simplify_merge_mask (XEXP (x
, 0), mask
, op
);
6741 return simplify_gen_unary (GET_CODE (x
), GET_MODE (x
), top0
,
6742 GET_MODE (XEXP (x
, 0)));
6745 && VECTOR_MODE_P (GET_MODE (XEXP (x
, 0)))
6746 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x
, 0))), nunits
)
6747 && VECTOR_MODE_P (GET_MODE (XEXP (x
, 1)))
6748 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x
, 1))), nunits
))
6750 rtx top0
= simplify_merge_mask (XEXP (x
, 0), mask
, op
);
6751 rtx top1
= simplify_merge_mask (XEXP (x
, 1), mask
, op
);
6754 if (COMPARISON_P (x
))
6755 return simplify_gen_relational (GET_CODE (x
), GET_MODE (x
),
6756 GET_MODE (XEXP (x
, 0)) != VOIDmode
6757 ? GET_MODE (XEXP (x
, 0))
6758 : GET_MODE (XEXP (x
, 1)),
6759 top0
? top0
: XEXP (x
, 0),
6760 top1
? top1
: XEXP (x
, 1));
6762 return simplify_gen_binary (GET_CODE (x
), GET_MODE (x
),
6763 top0
? top0
: XEXP (x
, 0),
6764 top1
? top1
: XEXP (x
, 1));
6767 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
6768 && VECTOR_MODE_P (GET_MODE (XEXP (x
, 0)))
6769 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x
, 0))), nunits
)
6770 && VECTOR_MODE_P (GET_MODE (XEXP (x
, 1)))
6771 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x
, 1))), nunits
)
6772 && VECTOR_MODE_P (GET_MODE (XEXP (x
, 2)))
6773 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x
, 2))), nunits
))
6775 rtx top0
= simplify_merge_mask (XEXP (x
, 0), mask
, op
);
6776 rtx top1
= simplify_merge_mask (XEXP (x
, 1), mask
, op
);
6777 rtx top2
= simplify_merge_mask (XEXP (x
, 2), mask
, op
);
6778 if (top0
|| top1
|| top2
)
6779 return simplify_gen_ternary (GET_CODE (x
), GET_MODE (x
),
6780 GET_MODE (XEXP (x
, 0)),
6781 top0
? top0
: XEXP (x
, 0),
6782 top1
? top1
: XEXP (x
, 1),
6783 top2
? top2
: XEXP (x
, 2));
6789 /* Simplify CODE, an operation with result mode MODE and three operands,
6790 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6791 a constant. Return 0 if no simplifications is possible. */
6794 simplify_context::simplify_ternary_operation (rtx_code code
, machine_mode mode
,
6795 machine_mode op0_mode
,
6796 rtx op0
, rtx op1
, rtx op2
)
6798 bool any_change
= false;
6800 scalar_int_mode int_mode
, int_op0_mode
;
6801 unsigned int n_elts
;
6806 /* Simplify negations around the multiplication. */
6807 /* -a * -b + c => a * b + c. */
6808 if (GET_CODE (op0
) == NEG
)
6810 tem
= simplify_unary_operation (NEG
, mode
, op1
, mode
);
6812 op1
= tem
, op0
= XEXP (op0
, 0), any_change
= true;
6814 else if (GET_CODE (op1
) == NEG
)
6816 tem
= simplify_unary_operation (NEG
, mode
, op0
, mode
);
6818 op0
= tem
, op1
= XEXP (op1
, 0), any_change
= true;
6821 /* Canonicalize the two multiplication operands. */
6822 /* a * -b + c => -b * a + c. */
6823 if (swap_commutative_operands_p (op0
, op1
))
6824 std::swap (op0
, op1
), any_change
= true;
6827 return gen_rtx_FMA (mode
, op0
, op1
, op2
);
6832 if (CONST_INT_P (op0
)
6833 && CONST_INT_P (op1
)
6834 && CONST_INT_P (op2
)
6835 && is_a
<scalar_int_mode
> (mode
, &int_mode
)
6836 && INTVAL (op1
) + INTVAL (op2
) <= GET_MODE_PRECISION (int_mode
)
6837 && HWI_COMPUTABLE_MODE_P (int_mode
))
6839 /* Extracting a bit-field from a constant */
6840 unsigned HOST_WIDE_INT val
= UINTVAL (op0
);
6841 HOST_WIDE_INT op1val
= INTVAL (op1
);
6842 HOST_WIDE_INT op2val
= INTVAL (op2
);
6843 if (!BITS_BIG_ENDIAN
)
6845 else if (is_a
<scalar_int_mode
> (op0_mode
, &int_op0_mode
))
6846 val
>>= GET_MODE_PRECISION (int_op0_mode
) - op2val
- op1val
;
6848 /* Not enough information to calculate the bit position. */
6851 if (HOST_BITS_PER_WIDE_INT
!= op1val
)
6853 /* First zero-extend. */
6854 val
&= (HOST_WIDE_INT_1U
<< op1val
) - 1;
6855 /* If desired, propagate sign bit. */
6856 if (code
== SIGN_EXTRACT
6857 && (val
& (HOST_WIDE_INT_1U
<< (op1val
- 1)))
6859 val
|= ~ ((HOST_WIDE_INT_1U
<< op1val
) - 1);
6862 return gen_int_mode (val
, int_mode
);
6867 if (CONST_INT_P (op0
))
6868 return op0
!= const0_rtx
? op1
: op2
;
6870 /* Convert c ? a : a into "a". */
6871 if (rtx_equal_p (op1
, op2
) && ! side_effects_p (op0
))
6874 /* Convert a != b ? a : b into "a". */
6875 if (GET_CODE (op0
) == NE
6876 && ! side_effects_p (op0
)
6877 && ! HONOR_NANS (mode
)
6878 && ! HONOR_SIGNED_ZEROS (mode
)
6879 && ((rtx_equal_p (XEXP (op0
, 0), op1
)
6880 && rtx_equal_p (XEXP (op0
, 1), op2
))
6881 || (rtx_equal_p (XEXP (op0
, 0), op2
)
6882 && rtx_equal_p (XEXP (op0
, 1), op1
))))
6885 /* Convert a == b ? a : b into "b". */
6886 if (GET_CODE (op0
) == EQ
6887 && ! side_effects_p (op0
)
6888 && ! HONOR_NANS (mode
)
6889 && ! HONOR_SIGNED_ZEROS (mode
)
6890 && ((rtx_equal_p (XEXP (op0
, 0), op1
)
6891 && rtx_equal_p (XEXP (op0
, 1), op2
))
6892 || (rtx_equal_p (XEXP (op0
, 0), op2
)
6893 && rtx_equal_p (XEXP (op0
, 1), op1
))))
6896 /* Convert (!c) != {0,...,0} ? a : b into
6897 c != {0,...,0} ? b : a for vector modes. */
6898 if (VECTOR_MODE_P (GET_MODE (op1
))
6899 && GET_CODE (op0
) == NE
6900 && GET_CODE (XEXP (op0
, 0)) == NOT
6901 && GET_CODE (XEXP (op0
, 1)) == CONST_VECTOR
)
6903 rtx cv
= XEXP (op0
, 1);
6906 if (!CONST_VECTOR_NUNITS (cv
).is_constant (&nunits
))
6909 for (int i
= 0; i
< nunits
; ++i
)
6910 if (CONST_VECTOR_ELT (cv
, i
) != const0_rtx
)
6917 rtx new_op0
= gen_rtx_NE (GET_MODE (op0
),
6918 XEXP (XEXP (op0
, 0), 0),
6920 rtx retval
= gen_rtx_IF_THEN_ELSE (mode
, new_op0
, op2
, op1
);
6925 /* Convert x == 0 ? N : clz (x) into clz (x) when
6926 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6927 Similarly for ctz (x). */
6928 if (COMPARISON_P (op0
) && !side_effects_p (op0
)
6929 && XEXP (op0
, 1) == const0_rtx
)
6932 = simplify_cond_clz_ctz (XEXP (op0
, 0), GET_CODE (op0
),
6938 if (COMPARISON_P (op0
) && ! side_effects_p (op0
))
6940 machine_mode cmp_mode
= (GET_MODE (XEXP (op0
, 0)) == VOIDmode
6941 ? GET_MODE (XEXP (op0
, 1))
6942 : GET_MODE (XEXP (op0
, 0)));
6945 /* Look for happy constants in op1 and op2. */
6946 if (CONST_INT_P (op1
) && CONST_INT_P (op2
))
6948 HOST_WIDE_INT t
= INTVAL (op1
);
6949 HOST_WIDE_INT f
= INTVAL (op2
);
6951 if (t
== STORE_FLAG_VALUE
&& f
== 0)
6952 code
= GET_CODE (op0
);
6953 else if (t
== 0 && f
== STORE_FLAG_VALUE
)
6956 tmp
= reversed_comparison_code (op0
, NULL
);
6964 return simplify_gen_relational (code
, mode
, cmp_mode
,
6965 XEXP (op0
, 0), XEXP (op0
, 1));
6968 temp
= simplify_relational_operation (GET_CODE (op0
), op0_mode
,
6969 cmp_mode
, XEXP (op0
, 0),
6972 /* See if any simplifications were possible. */
6975 if (CONST_INT_P (temp
))
6976 return temp
== const0_rtx
? op2
: op1
;
6978 return gen_rtx_IF_THEN_ELSE (mode
, temp
, op1
, op2
);
6984 gcc_assert (GET_MODE (op0
) == mode
);
6985 gcc_assert (GET_MODE (op1
) == mode
);
6986 gcc_assert (VECTOR_MODE_P (mode
));
6987 trueop2
= avoid_constant_pool_reference (op2
);
6988 if (CONST_INT_P (trueop2
)
6989 && GET_MODE_NUNITS (mode
).is_constant (&n_elts
))
6991 unsigned HOST_WIDE_INT sel
= UINTVAL (trueop2
);
6992 unsigned HOST_WIDE_INT mask
;
6993 if (n_elts
== HOST_BITS_PER_WIDE_INT
)
6996 mask
= (HOST_WIDE_INT_1U
<< n_elts
) - 1;
6998 if (!(sel
& mask
) && !side_effects_p (op0
))
7000 if ((sel
& mask
) == mask
&& !side_effects_p (op1
))
7003 rtx trueop0
= avoid_constant_pool_reference (op0
);
7004 rtx trueop1
= avoid_constant_pool_reference (op1
);
7005 if (GET_CODE (trueop0
) == CONST_VECTOR
7006 && GET_CODE (trueop1
) == CONST_VECTOR
)
7008 rtvec v
= rtvec_alloc (n_elts
);
7011 for (i
= 0; i
< n_elts
; i
++)
7012 RTVEC_ELT (v
, i
) = ((sel
& (HOST_WIDE_INT_1U
<< i
))
7013 ? CONST_VECTOR_ELT (trueop0
, i
)
7014 : CONST_VECTOR_ELT (trueop1
, i
));
7015 return gen_rtx_CONST_VECTOR (mode
, v
);
7018 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7019 if no element from a appears in the result. */
7020 if (GET_CODE (op0
) == VEC_MERGE
)
7022 tem
= avoid_constant_pool_reference (XEXP (op0
, 2));
7023 if (CONST_INT_P (tem
))
7025 unsigned HOST_WIDE_INT sel0
= UINTVAL (tem
);
7026 if (!(sel
& sel0
& mask
) && !side_effects_p (XEXP (op0
, 0)))
7027 return simplify_gen_ternary (code
, mode
, mode
,
7028 XEXP (op0
, 1), op1
, op2
);
7029 if (!(sel
& ~sel0
& mask
) && !side_effects_p (XEXP (op0
, 1)))
7030 return simplify_gen_ternary (code
, mode
, mode
,
7031 XEXP (op0
, 0), op1
, op2
);
7034 if (GET_CODE (op1
) == VEC_MERGE
)
7036 tem
= avoid_constant_pool_reference (XEXP (op1
, 2));
7037 if (CONST_INT_P (tem
))
7039 unsigned HOST_WIDE_INT sel1
= UINTVAL (tem
);
7040 if (!(~sel
& sel1
& mask
) && !side_effects_p (XEXP (op1
, 0)))
7041 return simplify_gen_ternary (code
, mode
, mode
,
7042 op0
, XEXP (op1
, 1), op2
);
7043 if (!(~sel
& ~sel1
& mask
) && !side_effects_p (XEXP (op1
, 1)))
7044 return simplify_gen_ternary (code
, mode
, mode
,
7045 op0
, XEXP (op1
, 0), op2
);
7049 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7051 if (GET_CODE (op0
) == VEC_DUPLICATE
7052 && GET_CODE (XEXP (op0
, 0)) == VEC_SELECT
7053 && GET_CODE (XEXP (XEXP (op0
, 0), 1)) == PARALLEL
7054 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0
, 0))), 1))
7056 tem
= XVECEXP ((XEXP (XEXP (op0
, 0), 1)), 0, 0);
7057 if (CONST_INT_P (tem
) && CONST_INT_P (op2
))
7059 if (XEXP (XEXP (op0
, 0), 0) == op1
7060 && UINTVAL (op2
) == HOST_WIDE_INT_1U
<< UINTVAL (tem
))
7064 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7066 with (vec_concat (X) (B)) if N == 1 or
7067 (vec_concat (A) (X)) if N == 2. */
7068 if (GET_CODE (op0
) == VEC_DUPLICATE
7069 && GET_CODE (op1
) == CONST_VECTOR
7070 && known_eq (CONST_VECTOR_NUNITS (op1
), 2)
7071 && known_eq (GET_MODE_NUNITS (GET_MODE (op0
)), 2)
7072 && IN_RANGE (sel
, 1, 2))
7074 rtx newop0
= XEXP (op0
, 0);
7075 rtx newop1
= CONST_VECTOR_ELT (op1
, 2 - sel
);
7077 std::swap (newop0
, newop1
);
7078 return simplify_gen_binary (VEC_CONCAT
, mode
, newop0
, newop1
);
7080 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7081 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7082 Only applies for vectors of two elements. */
7083 if (GET_CODE (op0
) == VEC_DUPLICATE
7084 && GET_CODE (op1
) == VEC_CONCAT
7085 && known_eq (GET_MODE_NUNITS (GET_MODE (op0
)), 2)
7086 && known_eq (GET_MODE_NUNITS (GET_MODE (op1
)), 2)
7087 && IN_RANGE (sel
, 1, 2))
7089 rtx newop0
= XEXP (op0
, 0);
7090 rtx newop1
= XEXP (op1
, 2 - sel
);
7091 rtx otherop
= XEXP (op1
, sel
- 1);
7093 std::swap (newop0
, newop1
);
7094 /* Don't want to throw away the other part of the vec_concat if
7095 it has side-effects. */
7096 if (!side_effects_p (otherop
))
7097 return simplify_gen_binary (VEC_CONCAT
, mode
, newop0
, newop1
);
7102 (vec_merge:outer (vec_duplicate:outer x:inner)
7103 (subreg:outer y:inner 0)
7106 with (vec_concat:outer x:inner y:inner) if N == 1,
7107 or (vec_concat:outer y:inner x:inner) if N == 2.
7109 Implicitly, this means we have a paradoxical subreg, but such
7110 a check is cheap, so make it anyway.
7112 Only applies for vectors of two elements. */
7113 if (GET_CODE (op0
) == VEC_DUPLICATE
7114 && GET_CODE (op1
) == SUBREG
7115 && GET_MODE (op1
) == GET_MODE (op0
)
7116 && GET_MODE (SUBREG_REG (op1
)) == GET_MODE (XEXP (op0
, 0))
7117 && paradoxical_subreg_p (op1
)
7118 && subreg_lowpart_p (op1
)
7119 && known_eq (GET_MODE_NUNITS (GET_MODE (op0
)), 2)
7120 && known_eq (GET_MODE_NUNITS (GET_MODE (op1
)), 2)
7121 && IN_RANGE (sel
, 1, 2))
7123 rtx newop0
= XEXP (op0
, 0);
7124 rtx newop1
= SUBREG_REG (op1
);
7126 std::swap (newop0
, newop1
);
7127 return simplify_gen_binary (VEC_CONCAT
, mode
, newop0
, newop1
);
7130 /* Same as above but with switched operands:
7131 Replace (vec_merge:outer (subreg:outer x:inner 0)
7132 (vec_duplicate:outer y:inner)
7135 with (vec_concat:outer x:inner y:inner) if N == 1,
7136 or (vec_concat:outer y:inner x:inner) if N == 2. */
7137 if (GET_CODE (op1
) == VEC_DUPLICATE
7138 && GET_CODE (op0
) == SUBREG
7139 && GET_MODE (op0
) == GET_MODE (op1
)
7140 && GET_MODE (SUBREG_REG (op0
)) == GET_MODE (XEXP (op1
, 0))
7141 && paradoxical_subreg_p (op0
)
7142 && subreg_lowpart_p (op0
)
7143 && known_eq (GET_MODE_NUNITS (GET_MODE (op1
)), 2)
7144 && known_eq (GET_MODE_NUNITS (GET_MODE (op0
)), 2)
7145 && IN_RANGE (sel
, 1, 2))
7147 rtx newop0
= SUBREG_REG (op0
);
7148 rtx newop1
= XEXP (op1
, 0);
7150 std::swap (newop0
, newop1
);
7151 return simplify_gen_binary (VEC_CONCAT
, mode
, newop0
, newop1
);
7154 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7156 with (vec_concat x y) or (vec_concat y x) depending on value
7158 if (GET_CODE (op0
) == VEC_DUPLICATE
7159 && GET_CODE (op1
) == VEC_DUPLICATE
7160 && known_eq (GET_MODE_NUNITS (GET_MODE (op0
)), 2)
7161 && known_eq (GET_MODE_NUNITS (GET_MODE (op1
)), 2)
7162 && IN_RANGE (sel
, 1, 2))
7164 rtx newop0
= XEXP (op0
, 0);
7165 rtx newop1
= XEXP (op1
, 0);
7167 std::swap (newop0
, newop1
);
7169 return simplify_gen_binary (VEC_CONCAT
, mode
, newop0
, newop1
);
7173 if (rtx_equal_p (op0
, op1
)
7174 && !side_effects_p (op2
) && !side_effects_p (op1
))
7177 if (!side_effects_p (op2
))
7180 = may_trap_p (op0
) ? NULL_RTX
: simplify_merge_mask (op0
, op2
, 0);
7182 = may_trap_p (op1
) ? NULL_RTX
: simplify_merge_mask (op1
, op2
, 1);
7184 return simplify_gen_ternary (code
, mode
, mode
,
7186 top1
? top1
: op1
, op2
);
7198 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
7199 starting at byte FIRST_BYTE. Return true on success and add the
7200 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
7201 that the bytes follow target memory order. Leave BYTES unmodified
7204 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
7205 BYTES before calling this function. */
7208 native_encode_rtx (machine_mode mode
, rtx x
, vec
<target_unit
> &bytes
,
7209 unsigned int first_byte
, unsigned int num_bytes
)
7211 /* Check the mode is sensible. */
7212 gcc_assert (GET_MODE (x
) == VOIDmode
7213 ? is_a
<scalar_int_mode
> (mode
)
7214 : mode
== GET_MODE (x
));
7216 if (GET_CODE (x
) == CONST_VECTOR
)
7218 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7219 is necessary. The only complication is that MODE_VECTOR_BOOL
7220 vectors can have several elements per byte. */
7221 unsigned int elt_bits
= vector_element_size (GET_MODE_PRECISION (mode
),
7222 GET_MODE_NUNITS (mode
));
7223 unsigned int elt
= first_byte
* BITS_PER_UNIT
/ elt_bits
;
7224 if (elt_bits
< BITS_PER_UNIT
)
7226 /* This is the only case in which elements can be smaller than
7228 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
);
7229 auto mask
= GET_MODE_MASK (GET_MODE_INNER (mode
));
7230 for (unsigned int i
= 0; i
< num_bytes
; ++i
)
7232 target_unit value
= 0;
7233 for (unsigned int j
= 0; j
< BITS_PER_UNIT
; j
+= elt_bits
)
7235 if (INTVAL (CONST_VECTOR_ELT (x
, elt
)))
7239 bytes
.quick_push (value
);
7244 unsigned int start
= bytes
.length ();
7245 unsigned int elt_bytes
= GET_MODE_UNIT_SIZE (mode
);
7246 /* Make FIRST_BYTE relative to ELT. */
7247 first_byte
%= elt_bytes
;
7248 while (num_bytes
> 0)
7250 /* Work out how many bytes we want from element ELT. */
7251 unsigned int chunk_bytes
= MIN (num_bytes
, elt_bytes
- first_byte
);
7252 if (!native_encode_rtx (GET_MODE_INNER (mode
),
7253 CONST_VECTOR_ELT (x
, elt
), bytes
,
7254 first_byte
, chunk_bytes
))
7256 bytes
.truncate (start
);
7261 num_bytes
-= chunk_bytes
;
7266 /* All subsequent cases are limited to scalars. */
7268 if (!is_a
<scalar_mode
> (mode
, &smode
))
7271 /* Make sure that the region is in range. */
7272 unsigned int end_byte
= first_byte
+ num_bytes
;
7273 unsigned int mode_bytes
= GET_MODE_SIZE (smode
);
7274 gcc_assert (end_byte
<= mode_bytes
);
7276 if (CONST_SCALAR_INT_P (x
))
7278 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7279 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7280 position of each byte. */
7281 rtx_mode_t
value (x
, smode
);
7282 wide_int_ref
value_wi (value
);
7283 for (unsigned int byte
= first_byte
; byte
< end_byte
; ++byte
)
7285 /* Always constant because the inputs are. */
7287 = subreg_size_lsb (1, mode_bytes
, byte
).to_constant ();
7288 /* Operate directly on the encoding rather than using
7289 wi::extract_uhwi, so that we preserve the sign or zero
7290 extension for modes that are not a whole number of bits in
7291 size. (Zero extension is only used for the combination of
7292 innermode == BImode && STORE_FLAG_VALUE == 1). */
7293 unsigned int elt
= lsb
/ HOST_BITS_PER_WIDE_INT
;
7294 unsigned int shift
= lsb
% HOST_BITS_PER_WIDE_INT
;
7295 unsigned HOST_WIDE_INT uhwi
= value_wi
.elt (elt
);
7296 bytes
.quick_push (uhwi
>> shift
);
7301 if (CONST_DOUBLE_P (x
))
7303 /* real_to_target produces an array of integers in target memory order.
7304 All integers before the last one have 32 bits; the last one may
7305 have 32 bits or fewer, depending on whether the mode bitsize
7306 is divisible by 32. Each of these integers is then laid out
7307 in target memory as any other integer would be. */
7308 long el32
[MAX_BITSIZE_MODE_ANY_MODE
/ 32];
7309 real_to_target (el32
, CONST_DOUBLE_REAL_VALUE (x
), smode
);
7311 /* The (maximum) number of target bytes per element of el32. */
7312 unsigned int bytes_per_el32
= 32 / BITS_PER_UNIT
;
7313 gcc_assert (bytes_per_el32
!= 0);
7315 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7317 for (unsigned int byte
= first_byte
; byte
< end_byte
; ++byte
)
7319 unsigned int index
= byte
/ bytes_per_el32
;
7320 unsigned int subbyte
= byte
% bytes_per_el32
;
7321 unsigned int int_bytes
= MIN (bytes_per_el32
,
7322 mode_bytes
- index
* bytes_per_el32
);
7323 /* Always constant because the inputs are. */
7325 = subreg_size_lsb (1, int_bytes
, subbyte
).to_constant ();
7326 bytes
.quick_push ((unsigned long) el32
[index
] >> lsb
);
7331 if (GET_CODE (x
) == CONST_FIXED
)
7333 for (unsigned int byte
= first_byte
; byte
< end_byte
; ++byte
)
7335 /* Always constant because the inputs are. */
7337 = subreg_size_lsb (1, mode_bytes
, byte
).to_constant ();
7338 unsigned HOST_WIDE_INT piece
= CONST_FIXED_VALUE_LOW (x
);
7339 if (lsb
>= HOST_BITS_PER_WIDE_INT
)
7341 lsb
-= HOST_BITS_PER_WIDE_INT
;
7342 piece
= CONST_FIXED_VALUE_HIGH (x
);
7344 bytes
.quick_push (piece
>> lsb
);
7352 /* Read a vector of mode MODE from the target memory image given by BYTES,
7353 starting at byte FIRST_BYTE. The vector is known to be encodable using
7354 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
7355 and BYTES is known to have enough bytes to supply NPATTERNS *
7356 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
7357 BITS_PER_UNIT bits and the bytes are in target memory order.
7359 Return the vector on success, otherwise return NULL_RTX. */
7362 native_decode_vector_rtx (machine_mode mode
, const vec
<target_unit
> &bytes
,
7363 unsigned int first_byte
, unsigned int npatterns
,
7364 unsigned int nelts_per_pattern
)
7366 rtx_vector_builder
builder (mode
, npatterns
, nelts_per_pattern
);
7368 unsigned int elt_bits
= vector_element_size (GET_MODE_PRECISION (mode
),
7369 GET_MODE_NUNITS (mode
));
7370 if (elt_bits
< BITS_PER_UNIT
)
7372 /* This is the only case in which elements can be smaller than a byte.
7373 Element 0 is always in the lsb of the containing byte. */
7374 gcc_assert (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
);
7375 for (unsigned int i
= 0; i
< builder
.encoded_nelts (); ++i
)
7377 unsigned int bit_index
= first_byte
* BITS_PER_UNIT
+ i
* elt_bits
;
7378 unsigned int byte_index
= bit_index
/ BITS_PER_UNIT
;
7379 unsigned int lsb
= bit_index
% BITS_PER_UNIT
;
7380 unsigned int value
= bytes
[byte_index
] >> lsb
;
7381 builder
.quick_push (gen_int_mode (value
, GET_MODE_INNER (mode
)));
7386 for (unsigned int i
= 0; i
< builder
.encoded_nelts (); ++i
)
7388 rtx x
= native_decode_rtx (GET_MODE_INNER (mode
), bytes
, first_byte
);
7391 builder
.quick_push (x
);
7392 first_byte
+= elt_bits
/ BITS_PER_UNIT
;
7395 return builder
.build ();
7398 /* Read an rtx of mode MODE from the target memory image given by BYTES,
7399 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
7400 bits and the bytes are in target memory order. The image has enough
7401 values to specify all bytes of MODE.
7403 Return the rtx on success, otherwise return NULL_RTX. */
7406 native_decode_rtx (machine_mode mode
, const vec
<target_unit
> &bytes
,
7407 unsigned int first_byte
)
7409 if (VECTOR_MODE_P (mode
))
7411 /* If we know at compile time how many elements there are,
7412 pull each element directly from BYTES. */
7414 if (GET_MODE_NUNITS (mode
).is_constant (&nelts
))
7415 return native_decode_vector_rtx (mode
, bytes
, first_byte
, nelts
, 1);
7419 scalar_int_mode imode
;
7420 if (is_a
<scalar_int_mode
> (mode
, &imode
)
7421 && GET_MODE_PRECISION (imode
) <= MAX_BITSIZE_MODE_ANY_INT
)
7423 /* Pull the bytes msb first, so that we can use simple
7424 shift-and-insert wide_int operations. */
7425 unsigned int size
= GET_MODE_SIZE (imode
);
7426 wide_int
result (wi::zero (GET_MODE_PRECISION (imode
)));
7427 for (unsigned int i
= 0; i
< size
; ++i
)
7429 unsigned int lsb
= (size
- i
- 1) * BITS_PER_UNIT
;
7430 /* Always constant because the inputs are. */
7431 unsigned int subbyte
7432 = subreg_size_offset_from_lsb (1, size
, lsb
).to_constant ();
7433 result
<<= BITS_PER_UNIT
;
7434 result
|= bytes
[first_byte
+ subbyte
];
7436 return immed_wide_int_const (result
, imode
);
7439 scalar_float_mode fmode
;
7440 if (is_a
<scalar_float_mode
> (mode
, &fmode
))
7442 /* We need to build an array of integers in target memory order.
7443 All integers before the last one have 32 bits; the last one may
7444 have 32 bits or fewer, depending on whether the mode bitsize
7445 is divisible by 32. */
7446 long el32
[MAX_BITSIZE_MODE_ANY_MODE
/ 32];
7447 unsigned int num_el32
= CEIL (GET_MODE_BITSIZE (fmode
), 32);
7448 memset (el32
, 0, num_el32
* sizeof (long));
7450 /* The (maximum) number of target bytes per element of el32. */
7451 unsigned int bytes_per_el32
= 32 / BITS_PER_UNIT
;
7452 gcc_assert (bytes_per_el32
!= 0);
7454 unsigned int mode_bytes
= GET_MODE_SIZE (fmode
);
7455 for (unsigned int byte
= 0; byte
< mode_bytes
; ++byte
)
7457 unsigned int index
= byte
/ bytes_per_el32
;
7458 unsigned int subbyte
= byte
% bytes_per_el32
;
7459 unsigned int int_bytes
= MIN (bytes_per_el32
,
7460 mode_bytes
- index
* bytes_per_el32
);
7461 /* Always constant because the inputs are. */
7463 = subreg_size_lsb (1, int_bytes
, subbyte
).to_constant ();
7464 el32
[index
] |= (unsigned long) bytes
[first_byte
+ byte
] << lsb
;
7467 real_from_target (&r
, el32
, fmode
);
7468 return const_double_from_real_value (r
, fmode
);
7471 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode
))
7473 scalar_mode smode
= as_a
<scalar_mode
> (mode
);
7479 unsigned int mode_bytes
= GET_MODE_SIZE (smode
);
7480 for (unsigned int byte
= 0; byte
< mode_bytes
; ++byte
)
7482 /* Always constant because the inputs are. */
7484 = subreg_size_lsb (1, mode_bytes
, byte
).to_constant ();
7485 unsigned HOST_WIDE_INT unit
= bytes
[first_byte
+ byte
];
7486 if (lsb
>= HOST_BITS_PER_WIDE_INT
)
7487 f
.data
.high
|= unit
<< (lsb
- HOST_BITS_PER_WIDE_INT
);
7489 f
.data
.low
|= unit
<< lsb
;
7491 return CONST_FIXED_FROM_FIXED_VALUE (f
, mode
);
7497 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
7498 is to convert a runtime BYTE value into a constant one. */
7501 simplify_const_vector_byte_offset (rtx x
, poly_uint64 byte
)
7503 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7504 machine_mode mode
= GET_MODE (x
);
7505 unsigned int elt_bits
= vector_element_size (GET_MODE_PRECISION (mode
),
7506 GET_MODE_NUNITS (mode
));
7507 /* The number of bits needed to encode one element from each pattern. */
7508 unsigned int sequence_bits
= CONST_VECTOR_NPATTERNS (x
) * elt_bits
;
7510 /* Identify the start point in terms of a sequence number and a byte offset
7511 within that sequence. */
7512 poly_uint64 first_sequence
;
7513 unsigned HOST_WIDE_INT subbit
;
7514 if (can_div_trunc_p (byte
* BITS_PER_UNIT
, sequence_bits
,
7515 &first_sequence
, &subbit
))
7517 unsigned int nelts_per_pattern
= CONST_VECTOR_NELTS_PER_PATTERN (x
);
7518 if (nelts_per_pattern
== 1)
7519 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
7521 byte
= subbit
/ BITS_PER_UNIT
;
7522 else if (nelts_per_pattern
== 2 && known_gt (first_sequence
, 0U))
7524 /* The subreg drops the first element from each pattern and
7525 only uses the second element. Find the first sequence
7526 that starts on a byte boundary. */
7527 subbit
+= least_common_multiple (sequence_bits
, BITS_PER_UNIT
);
7528 byte
= subbit
/ BITS_PER_UNIT
;
7534 /* Subroutine of simplify_subreg in which:
7536 - X is known to be a CONST_VECTOR
7537 - OUTERMODE is known to be a vector mode
7539 Try to handle the subreg by operating on the CONST_VECTOR encoding
7540 rather than on each individual element of the CONST_VECTOR.
7542 Return the simplified subreg on success, otherwise return NULL_RTX. */
7545 simplify_const_vector_subreg (machine_mode outermode
, rtx x
,
7546 machine_mode innermode
, unsigned int first_byte
)
7548 /* Paradoxical subregs of vectors have dubious semantics. */
7549 if (paradoxical_subreg_p (outermode
, innermode
))
7552 /* We can only preserve the semantics of a stepped pattern if the new
7553 vector element is the same as the original one. */
7554 if (CONST_VECTOR_STEPPED_P (x
)
7555 && GET_MODE_INNER (outermode
) != GET_MODE_INNER (innermode
))
7558 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7559 unsigned int x_elt_bits
7560 = vector_element_size (GET_MODE_PRECISION (innermode
),
7561 GET_MODE_NUNITS (innermode
));
7562 unsigned int out_elt_bits
7563 = vector_element_size (GET_MODE_PRECISION (outermode
),
7564 GET_MODE_NUNITS (outermode
));
7566 /* The number of bits needed to encode one element from every pattern
7567 of the original vector. */
7568 unsigned int x_sequence_bits
= CONST_VECTOR_NPATTERNS (x
) * x_elt_bits
;
7570 /* The number of bits needed to encode one element from every pattern
7572 unsigned int out_sequence_bits
7573 = least_common_multiple (x_sequence_bits
, out_elt_bits
);
7575 /* Work out the number of interleaved patterns in the output vector
7576 and the number of encoded elements per pattern. */
7577 unsigned int out_npatterns
= out_sequence_bits
/ out_elt_bits
;
7578 unsigned int nelts_per_pattern
= CONST_VECTOR_NELTS_PER_PATTERN (x
);
7580 /* The encoding scheme requires the number of elements to be a multiple
7581 of the number of patterns, so that each pattern appears at least once
7582 and so that the same number of elements appear from each pattern. */
7583 bool ok_p
= multiple_p (GET_MODE_NUNITS (outermode
), out_npatterns
);
7584 unsigned int const_nunits
;
7585 if (GET_MODE_NUNITS (outermode
).is_constant (&const_nunits
)
7586 && (!ok_p
|| out_npatterns
* nelts_per_pattern
> const_nunits
))
7588 /* Either the encoding is invalid, or applying it would give us
7589 more elements than we need. Just encode each element directly. */
7590 out_npatterns
= const_nunits
;
7591 nelts_per_pattern
= 1;
7596 /* Get enough bytes of X to form the new encoding. */
7597 unsigned int buffer_bits
= out_npatterns
* nelts_per_pattern
* out_elt_bits
;
7598 unsigned int buffer_bytes
= CEIL (buffer_bits
, BITS_PER_UNIT
);
7599 auto_vec
<target_unit
, 128> buffer (buffer_bytes
);
7600 if (!native_encode_rtx (innermode
, x
, buffer
, first_byte
, buffer_bytes
))
7603 /* Reencode the bytes as OUTERMODE. */
7604 return native_decode_vector_rtx (outermode
, buffer
, 0, out_npatterns
,
7608 /* Try to simplify a subreg of a constant by encoding the subreg region
7609 as a sequence of target bytes and reading them back in the new mode.
7610 Return the new value on success, otherwise return null.
7612 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7613 and byte offset FIRST_BYTE. */
7616 simplify_immed_subreg (fixed_size_mode outermode
, rtx x
,
7617 machine_mode innermode
, unsigned int first_byte
)
7619 unsigned int buffer_bytes
= GET_MODE_SIZE (outermode
);
7620 auto_vec
<target_unit
, 128> buffer (buffer_bytes
);
7622 /* Some ports misuse CCmode. */
7623 if (GET_MODE_CLASS (outermode
) == MODE_CC
&& CONST_INT_P (x
))
7626 /* Paradoxical subregs read undefined values for bytes outside of the
7627 inner value. However, we have traditionally always sign-extended
7628 integer constants and zero-extended others. */
7629 unsigned int inner_bytes
= buffer_bytes
;
7630 if (paradoxical_subreg_p (outermode
, innermode
))
7632 if (!GET_MODE_SIZE (innermode
).is_constant (&inner_bytes
))
7635 target_unit filler
= 0;
7636 if (CONST_SCALAR_INT_P (x
) && wi::neg_p (rtx_mode_t (x
, innermode
)))
7639 /* Add any leading bytes due to big-endian layout. The number of
7640 bytes must be constant because both modes have constant size. */
7641 unsigned int leading_bytes
7642 = -byte_lowpart_offset (outermode
, innermode
).to_constant ();
7643 for (unsigned int i
= 0; i
< leading_bytes
; ++i
)
7644 buffer
.quick_push (filler
);
7646 if (!native_encode_rtx (innermode
, x
, buffer
, first_byte
, inner_bytes
))
7649 /* Add any trailing bytes due to little-endian layout. */
7650 while (buffer
.length () < buffer_bytes
)
7651 buffer
.quick_push (filler
);
7653 else if (!native_encode_rtx (innermode
, x
, buffer
, first_byte
, inner_bytes
))
7655 rtx ret
= native_decode_rtx (outermode
, buffer
, 0);
7656 if (ret
&& FLOAT_MODE_P (outermode
))
7658 auto_vec
<target_unit
, 128> buffer2 (buffer_bytes
);
7659 if (!native_encode_rtx (outermode
, ret
, buffer2
, 0, buffer_bytes
))
7661 for (unsigned int i
= 0; i
< buffer_bytes
; ++i
)
7662 if (buffer
[i
] != buffer2
[i
])
7668 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7669 Return 0 if no simplifications are possible. */
7671 simplify_context::simplify_subreg (machine_mode outermode
, rtx op
,
7672 machine_mode innermode
, poly_uint64 byte
)
7674 /* Little bit of sanity checking. */
7675 gcc_assert (innermode
!= VOIDmode
);
7676 gcc_assert (outermode
!= VOIDmode
);
7677 gcc_assert (innermode
!= BLKmode
);
7678 gcc_assert (outermode
!= BLKmode
);
7680 gcc_assert (GET_MODE (op
) == innermode
7681 || GET_MODE (op
) == VOIDmode
);
7683 poly_uint64 outersize
= GET_MODE_SIZE (outermode
);
7684 if (!multiple_p (byte
, outersize
))
7687 poly_uint64 innersize
= GET_MODE_SIZE (innermode
);
7688 if (maybe_ge (byte
, innersize
))
7691 if (outermode
== innermode
&& known_eq (byte
, 0U))
7694 if (GET_CODE (op
) == CONST_VECTOR
)
7695 byte
= simplify_const_vector_byte_offset (op
, byte
);
7697 if (multiple_p (byte
, GET_MODE_UNIT_SIZE (innermode
)))
7701 if (VECTOR_MODE_P (outermode
)
7702 && GET_MODE_INNER (outermode
) == GET_MODE_INNER (innermode
)
7703 && vec_duplicate_p (op
, &elt
))
7704 return gen_vec_duplicate (outermode
, elt
);
7706 if (outermode
== GET_MODE_INNER (innermode
)
7707 && vec_duplicate_p (op
, &elt
))
7711 if (CONST_SCALAR_INT_P (op
)
7712 || CONST_DOUBLE_AS_FLOAT_P (op
)
7713 || CONST_FIXED_P (op
)
7714 || GET_CODE (op
) == CONST_VECTOR
)
7716 unsigned HOST_WIDE_INT cbyte
;
7717 if (byte
.is_constant (&cbyte
))
7719 if (GET_CODE (op
) == CONST_VECTOR
&& VECTOR_MODE_P (outermode
))
7721 rtx tmp
= simplify_const_vector_subreg (outermode
, op
,
7727 fixed_size_mode fs_outermode
;
7728 if (is_a
<fixed_size_mode
> (outermode
, &fs_outermode
))
7729 return simplify_immed_subreg (fs_outermode
, op
, innermode
, cbyte
);
7733 /* Changing mode twice with SUBREG => just change it once,
7734 or not at all if changing back op starting mode. */
7735 if (GET_CODE (op
) == SUBREG
)
7737 machine_mode innermostmode
= GET_MODE (SUBREG_REG (op
));
7738 poly_uint64 innermostsize
= GET_MODE_SIZE (innermostmode
);
7741 /* Make sure that the relationship between the two subregs is
7742 known at compile time. */
7743 if (!ordered_p (outersize
, innermostsize
))
7746 if (outermode
== innermostmode
7747 && known_eq (byte
, subreg_lowpart_offset (outermode
, innermode
))
7748 && known_eq (SUBREG_BYTE (op
),
7749 subreg_lowpart_offset (innermode
, innermostmode
)))
7750 return SUBREG_REG (op
);
7752 /* Work out the memory offset of the final OUTERMODE value relative
7753 to the inner value of OP. */
7754 poly_int64 mem_offset
= subreg_memory_offset (outermode
,
7756 poly_int64 op_mem_offset
= subreg_memory_offset (op
);
7757 poly_int64 final_offset
= mem_offset
+ op_mem_offset
;
7759 /* See whether resulting subreg will be paradoxical. */
7760 if (!paradoxical_subreg_p (outermode
, innermostmode
))
7762 /* Bail out in case resulting subreg would be incorrect. */
7763 if (maybe_lt (final_offset
, 0)
7764 || maybe_ge (poly_uint64 (final_offset
), innermostsize
)
7765 || !multiple_p (final_offset
, outersize
))
7770 poly_int64 required_offset
= subreg_memory_offset (outermode
,
7772 if (maybe_ne (final_offset
, required_offset
))
7774 /* Paradoxical subregs always have byte offset 0. */
7778 /* Recurse for further possible simplifications. */
7779 newx
= simplify_subreg (outermode
, SUBREG_REG (op
), innermostmode
,
7783 if (validate_subreg (outermode
, innermostmode
,
7784 SUBREG_REG (op
), final_offset
))
7786 newx
= gen_rtx_SUBREG (outermode
, SUBREG_REG (op
), final_offset
);
7787 if (SUBREG_PROMOTED_VAR_P (op
)
7788 && SUBREG_PROMOTED_SIGN (op
) >= 0
7789 && GET_MODE_CLASS (outermode
) == MODE_INT
7790 && known_ge (outersize
, innersize
)
7791 && known_le (outersize
, innermostsize
)
7792 && subreg_lowpart_p (newx
))
7794 SUBREG_PROMOTED_VAR_P (newx
) = 1;
7795 SUBREG_PROMOTED_SET (newx
, SUBREG_PROMOTED_GET (op
));
7802 /* SUBREG of a hard register => just change the register number
7803 and/or mode. If the hard register is not valid in that mode,
7804 suppress this simplification. If the hard register is the stack,
7805 frame, or argument pointer, leave this as a SUBREG. */
7807 if (REG_P (op
) && HARD_REGISTER_P (op
))
7809 unsigned int regno
, final_regno
;
7812 final_regno
= simplify_subreg_regno (regno
, innermode
, byte
, outermode
);
7813 if (HARD_REGISTER_NUM_P (final_regno
))
7815 rtx x
= gen_rtx_REG_offset (op
, outermode
, final_regno
,
7816 subreg_memory_offset (outermode
,
7819 /* Propagate original regno. We don't have any way to specify
7820 the offset inside original regno, so do so only for lowpart.
7821 The information is used only by alias analysis that cannot
7822 grog partial register anyway. */
7824 if (known_eq (subreg_lowpart_offset (outermode
, innermode
), byte
))
7825 ORIGINAL_REGNO (x
) = ORIGINAL_REGNO (op
);
7830 /* If we have a SUBREG of a register that we are replacing and we are
7831 replacing it with a MEM, make a new MEM and try replacing the
7832 SUBREG with it. Don't do this if the MEM has a mode-dependent address
7833 or if we would be widening it. */
7836 && ! mode_dependent_address_p (XEXP (op
, 0), MEM_ADDR_SPACE (op
))
7837 /* Allow splitting of volatile memory references in case we don't
7838 have instruction to move the whole thing. */
7839 && (! MEM_VOLATILE_P (op
)
7840 || ! have_insn_for (SET
, innermode
))
7841 && !(STRICT_ALIGNMENT
&& MEM_ALIGN (op
) < GET_MODE_ALIGNMENT (outermode
))
7842 && known_le (outersize
, innersize
))
7843 return adjust_address_nv (op
, outermode
, byte
);
7845 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7847 if (GET_CODE (op
) == CONCAT
7848 || GET_CODE (op
) == VEC_CONCAT
)
7850 poly_uint64 final_offset
;
7853 machine_mode part_mode
= GET_MODE (XEXP (op
, 0));
7854 if (part_mode
== VOIDmode
)
7855 part_mode
= GET_MODE_INNER (GET_MODE (op
));
7856 poly_uint64 part_size
= GET_MODE_SIZE (part_mode
);
7857 if (known_lt (byte
, part_size
))
7859 part
= XEXP (op
, 0);
7860 final_offset
= byte
;
7862 else if (known_ge (byte
, part_size
))
7864 part
= XEXP (op
, 1);
7865 final_offset
= byte
- part_size
;
7870 if (maybe_gt (final_offset
+ outersize
, part_size
))
7873 part_mode
= GET_MODE (part
);
7874 if (part_mode
== VOIDmode
)
7875 part_mode
= GET_MODE_INNER (GET_MODE (op
));
7876 res
= simplify_subreg (outermode
, part
, part_mode
, final_offset
);
7879 if (validate_subreg (outermode
, part_mode
, part
, final_offset
))
7880 return gen_rtx_SUBREG (outermode
, part
, final_offset
);
7885 (subreg (vec_merge (X)
7887 (const_int ((1 << N) | M)))
7888 (N * sizeof (outermode)))
7890 (subreg (X) (N * sizeof (outermode)))
7893 if (constant_multiple_p (byte
, GET_MODE_SIZE (outermode
), &idx
)
7894 && idx
< HOST_BITS_PER_WIDE_INT
7895 && GET_CODE (op
) == VEC_MERGE
7896 && GET_MODE_INNER (innermode
) == outermode
7897 && CONST_INT_P (XEXP (op
, 2))
7898 && (UINTVAL (XEXP (op
, 2)) & (HOST_WIDE_INT_1U
<< idx
)) != 0)
7899 return simplify_gen_subreg (outermode
, XEXP (op
, 0), innermode
, byte
);
7901 /* A SUBREG resulting from a zero extension may fold to zero if
7902 it extracts higher bits that the ZERO_EXTEND's source bits. */
7903 if (GET_CODE (op
) == ZERO_EXTEND
&& SCALAR_INT_MODE_P (innermode
))
7905 poly_uint64 bitpos
= subreg_lsb_1 (outermode
, innermode
, byte
);
7906 if (known_ge (bitpos
, GET_MODE_PRECISION (GET_MODE (XEXP (op
, 0)))))
7907 return CONST0_RTX (outermode
);
7910 /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
7911 if (GET_CODE (op
) == ASHIFT
7912 && SCALAR_INT_MODE_P (innermode
)
7913 && CONST_INT_P (XEXP (op
, 1))
7914 && INTVAL (XEXP (op
, 1)) > 0
7915 && known_gt (GET_MODE_BITSIZE (innermode
), INTVAL (XEXP (op
, 1))))
7917 HOST_WIDE_INT val
= INTVAL (XEXP (op
, 1));
7918 /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
7919 if (known_eq (subreg_lowpart_offset (outermode
, innermode
), byte
)
7920 && known_le (GET_MODE_BITSIZE (outermode
), val
))
7921 return CONST0_RTX (outermode
);
7922 /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
7923 if (GET_CODE (XEXP (op
, 0)) == ZERO_EXTEND
7924 && GET_MODE (XEXP (XEXP (op
, 0), 0)) == outermode
7925 && known_eq (GET_MODE_BITSIZE (outermode
), val
)
7926 && known_eq (GET_MODE_BITSIZE (innermode
), 2 * val
)
7927 && known_eq (subreg_highpart_offset (outermode
, innermode
), byte
))
7928 return XEXP (XEXP (op
, 0), 0);
7931 /* Attempt to simplify WORD_MODE SUBREGs of bitwise expressions. */
7932 if (outermode
== word_mode
7933 && (GET_CODE (op
) == IOR
|| GET_CODE (op
) == XOR
|| GET_CODE (op
) == AND
)
7934 && SCALAR_INT_MODE_P (innermode
))
7936 rtx op0
= simplify_subreg (outermode
, XEXP (op
, 0), innermode
, byte
);
7937 rtx op1
= simplify_subreg (outermode
, XEXP (op
, 1), innermode
, byte
);
7939 return simplify_gen_binary (GET_CODE (op
), outermode
, op0
, op1
);
7942 scalar_int_mode int_outermode
, int_innermode
;
7943 if (is_a
<scalar_int_mode
> (outermode
, &int_outermode
)
7944 && is_a
<scalar_int_mode
> (innermode
, &int_innermode
)
7945 && known_eq (byte
, subreg_lowpart_offset (int_outermode
, int_innermode
)))
7947 /* Handle polynomial integers. The upper bits of a paradoxical
7948 subreg are undefined, so this is safe regardless of whether
7949 we're truncating or extending. */
7950 if (CONST_POLY_INT_P (op
))
7953 = poly_wide_int::from (const_poly_int_value (op
),
7954 GET_MODE_PRECISION (int_outermode
),
7956 return immed_wide_int_const (val
, int_outermode
);
7959 if (GET_MODE_PRECISION (int_outermode
)
7960 < GET_MODE_PRECISION (int_innermode
))
7962 rtx tem
= simplify_truncation (int_outermode
, op
, int_innermode
);
7968 /* If the outer mode is not integral, try taking a subreg with the equivalent
7969 integer outer mode and then bitcasting the result.
7970 Other simplifications rely on integer to integer subregs and we'd
7971 potentially miss out on optimizations otherwise. */
7972 if (known_gt (GET_MODE_SIZE (innermode
),
7973 GET_MODE_SIZE (outermode
))
7974 && SCALAR_INT_MODE_P (innermode
)
7975 && !SCALAR_INT_MODE_P (outermode
)
7976 && int_mode_for_size (GET_MODE_BITSIZE (outermode
),
7977 0).exists (&int_outermode
))
7979 rtx tem
= simplify_subreg (int_outermode
, op
, innermode
, byte
);
7981 return lowpart_subreg (outermode
, tem
, int_outermode
);
7984 /* If OP is a vector comparison and the subreg is not changing the
7985 number of elements or the size of the elements, change the result
7986 of the comparison to the new mode. */
7987 if (COMPARISON_P (op
)
7988 && VECTOR_MODE_P (outermode
)
7989 && VECTOR_MODE_P (innermode
)
7990 && known_eq (GET_MODE_NUNITS (outermode
), GET_MODE_NUNITS (innermode
))
7991 && known_eq (GET_MODE_UNIT_SIZE (outermode
),
7992 GET_MODE_UNIT_SIZE (innermode
)))
7993 return simplify_gen_relational (GET_CODE (op
), outermode
, innermode
,
7994 XEXP (op
, 0), XEXP (op
, 1));
7998 /* Make a SUBREG operation or equivalent if it folds. */
8001 simplify_context::simplify_gen_subreg (machine_mode outermode
, rtx op
,
8002 machine_mode innermode
,
8007 newx
= simplify_subreg (outermode
, op
, innermode
, byte
);
8011 if (GET_CODE (op
) == SUBREG
8012 || GET_CODE (op
) == CONCAT
8013 || GET_MODE (op
) == VOIDmode
)
8016 if (MODE_COMPOSITE_P (outermode
)
8017 && (CONST_SCALAR_INT_P (op
)
8018 || CONST_DOUBLE_AS_FLOAT_P (op
)
8019 || CONST_FIXED_P (op
)
8020 || GET_CODE (op
) == CONST_VECTOR
))
8023 if (validate_subreg (outermode
, innermode
, op
, byte
))
8024 return gen_rtx_SUBREG (outermode
, op
, byte
);
8029 /* Generates a subreg to get the least significant part of EXPR (in mode
8030 INNER_MODE) to OUTER_MODE. */
8033 simplify_context::lowpart_subreg (machine_mode outer_mode
, rtx expr
,
8034 machine_mode inner_mode
)
8036 return simplify_gen_subreg (outer_mode
, expr
, inner_mode
,
8037 subreg_lowpart_offset (outer_mode
, inner_mode
));
8040 /* Generate RTX to select element at INDEX out of vector OP. */
8043 simplify_context::simplify_gen_vec_select (rtx op
, unsigned int index
)
8045 gcc_assert (VECTOR_MODE_P (GET_MODE (op
)));
8047 scalar_mode imode
= GET_MODE_INNER (GET_MODE (op
));
8049 if (known_eq (index
* GET_MODE_SIZE (imode
),
8050 subreg_lowpart_offset (imode
, GET_MODE (op
))))
8052 rtx res
= lowpart_subreg (imode
, op
, GET_MODE (op
));
8057 rtx tmp
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, GEN_INT (index
)));
8058 return gen_rtx_VEC_SELECT (imode
, op
, tmp
);
8062 /* Simplify X, an rtx expression.
8064 Return the simplified expression or NULL if no simplifications
8067 This is the preferred entry point into the simplification routines;
8068 however, we still allow passes to call the more specific routines.
8070 Right now GCC has three (yes, three) major bodies of RTL simplification
8071 code that need to be unified.
8073 1. fold_rtx in cse.cc. This code uses various CSE specific
8074 information to aid in RTL simplification.
8076 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
8077 it uses combine specific information to aid in RTL
8080 3. The routines in this file.
8083 Long term we want to only have one body of simplification code; to
8084 get to that state I recommend the following steps:
8086 1. Pour over fold_rtx & simplify_rtx and move any simplifications
8087 which are not pass dependent state into these routines.
8089 2. As code is moved by #1, change fold_rtx & simplify_rtx to
8090 use this routine whenever possible.
8092 3. Allow for pass dependent state to be provided to these
8093 routines and add simplifications based on the pass dependent
8094 state. Remove code from cse.cc & combine.cc that becomes
8097 It will take time, but ultimately the compiler will be easier to
8098 maintain and improve. It's totally silly that when we add a
8099 simplification that it needs to be added to 4 places (3 for RTL
8100 simplification and 1 for tree simplification. */
8103 simplify_rtx (const_rtx x
)
8105 const enum rtx_code code
= GET_CODE (x
);
8106 const machine_mode mode
= GET_MODE (x
);
8108 switch (GET_RTX_CLASS (code
))
8111 return simplify_unary_operation (code
, mode
,
8112 XEXP (x
, 0), GET_MODE (XEXP (x
, 0)));
8113 case RTX_COMM_ARITH
:
8114 if (swap_commutative_operands_p (XEXP (x
, 0), XEXP (x
, 1)))
8115 return simplify_gen_binary (code
, mode
, XEXP (x
, 1), XEXP (x
, 0));
8120 return simplify_binary_operation (code
, mode
, XEXP (x
, 0), XEXP (x
, 1));
8123 case RTX_BITFIELD_OPS
:
8124 return simplify_ternary_operation (code
, mode
, GET_MODE (XEXP (x
, 0)),
8125 XEXP (x
, 0), XEXP (x
, 1),
8129 case RTX_COMM_COMPARE
:
8130 return simplify_relational_operation (code
, mode
,
8131 ((GET_MODE (XEXP (x
, 0))
8133 ? GET_MODE (XEXP (x
, 0))
8134 : GET_MODE (XEXP (x
, 1))),
8140 return simplify_subreg (mode
, SUBREG_REG (x
),
8141 GET_MODE (SUBREG_REG (x
)),
8148 /* Convert (lo_sum (high FOO) FOO) to FOO. */
8149 if (GET_CODE (XEXP (x
, 0)) == HIGH
8150 && rtx_equal_p (XEXP (XEXP (x
, 0), 0), XEXP (x
, 1)))
8163 namespace selftest
{
8165 /* Make a unique pseudo REG of mode MODE for use by selftests. */
8168 make_test_reg (machine_mode mode
)
8170 static int test_reg_num
= LAST_VIRTUAL_REGISTER
+ 1;
8172 return gen_rtx_REG (mode
, test_reg_num
++);
8176 test_scalar_int_ops (machine_mode mode
)
8178 rtx op0
= make_test_reg (mode
);
8179 rtx op1
= make_test_reg (mode
);
8180 rtx six
= GEN_INT (6);
8182 rtx neg_op0
= simplify_gen_unary (NEG
, mode
, op0
, mode
);
8183 rtx not_op0
= simplify_gen_unary (NOT
, mode
, op0
, mode
);
8184 rtx bswap_op0
= simplify_gen_unary (BSWAP
, mode
, op0
, mode
);
8186 rtx and_op0_op1
= simplify_gen_binary (AND
, mode
, op0
, op1
);
8187 rtx ior_op0_op1
= simplify_gen_binary (IOR
, mode
, op0
, op1
);
8188 rtx xor_op0_op1
= simplify_gen_binary (XOR
, mode
, op0
, op1
);
8190 rtx and_op0_6
= simplify_gen_binary (AND
, mode
, op0
, six
);
8191 rtx and_op1_6
= simplify_gen_binary (AND
, mode
, op1
, six
);
8193 /* Test some binary identities. */
8194 ASSERT_RTX_EQ (op0
, simplify_gen_binary (PLUS
, mode
, op0
, const0_rtx
));
8195 ASSERT_RTX_EQ (op0
, simplify_gen_binary (PLUS
, mode
, const0_rtx
, op0
));
8196 ASSERT_RTX_EQ (op0
, simplify_gen_binary (MINUS
, mode
, op0
, const0_rtx
));
8197 ASSERT_RTX_EQ (op0
, simplify_gen_binary (MULT
, mode
, op0
, const1_rtx
));
8198 ASSERT_RTX_EQ (op0
, simplify_gen_binary (MULT
, mode
, const1_rtx
, op0
));
8199 ASSERT_RTX_EQ (op0
, simplify_gen_binary (DIV
, mode
, op0
, const1_rtx
));
8200 ASSERT_RTX_EQ (op0
, simplify_gen_binary (AND
, mode
, op0
, constm1_rtx
));
8201 ASSERT_RTX_EQ (op0
, simplify_gen_binary (AND
, mode
, constm1_rtx
, op0
));
8202 ASSERT_RTX_EQ (op0
, simplify_gen_binary (IOR
, mode
, op0
, const0_rtx
));
8203 ASSERT_RTX_EQ (op0
, simplify_gen_binary (IOR
, mode
, const0_rtx
, op0
));
8204 ASSERT_RTX_EQ (op0
, simplify_gen_binary (XOR
, mode
, op0
, const0_rtx
));
8205 ASSERT_RTX_EQ (op0
, simplify_gen_binary (XOR
, mode
, const0_rtx
, op0
));
8206 ASSERT_RTX_EQ (op0
, simplify_gen_binary (ASHIFT
, mode
, op0
, const0_rtx
));
8207 ASSERT_RTX_EQ (op0
, simplify_gen_binary (ROTATE
, mode
, op0
, const0_rtx
));
8208 ASSERT_RTX_EQ (op0
, simplify_gen_binary (ASHIFTRT
, mode
, op0
, const0_rtx
));
8209 ASSERT_RTX_EQ (op0
, simplify_gen_binary (LSHIFTRT
, mode
, op0
, const0_rtx
));
8210 ASSERT_RTX_EQ (op0
, simplify_gen_binary (ROTATERT
, mode
, op0
, const0_rtx
));
8212 /* Test some self-inverse operations. */
8213 ASSERT_RTX_EQ (op0
, simplify_gen_unary (NEG
, mode
, neg_op0
, mode
));
8214 ASSERT_RTX_EQ (op0
, simplify_gen_unary (NOT
, mode
, not_op0
, mode
));
8215 ASSERT_RTX_EQ (op0
, simplify_gen_unary (BSWAP
, mode
, bswap_op0
, mode
));
8217 /* Test some reflexive operations. */
8218 ASSERT_RTX_EQ (op0
, simplify_gen_binary (AND
, mode
, op0
, op0
));
8219 ASSERT_RTX_EQ (op0
, simplify_gen_binary (IOR
, mode
, op0
, op0
));
8220 ASSERT_RTX_EQ (op0
, simplify_gen_binary (SMIN
, mode
, op0
, op0
));
8221 ASSERT_RTX_EQ (op0
, simplify_gen_binary (SMAX
, mode
, op0
, op0
));
8222 ASSERT_RTX_EQ (op0
, simplify_gen_binary (UMIN
, mode
, op0
, op0
));
8223 ASSERT_RTX_EQ (op0
, simplify_gen_binary (UMAX
, mode
, op0
, op0
));
8225 ASSERT_RTX_EQ (const0_rtx
, simplify_gen_binary (MINUS
, mode
, op0
, op0
));
8226 ASSERT_RTX_EQ (const0_rtx
, simplify_gen_binary (XOR
, mode
, op0
, op0
));
8228 /* Test simplify_distributive_operation. */
8229 ASSERT_RTX_EQ (simplify_gen_binary (AND
, mode
, xor_op0_op1
, six
),
8230 simplify_gen_binary (XOR
, mode
, and_op0_6
, and_op1_6
));
8231 ASSERT_RTX_EQ (simplify_gen_binary (AND
, mode
, ior_op0_op1
, six
),
8232 simplify_gen_binary (IOR
, mode
, and_op0_6
, and_op1_6
));
8233 ASSERT_RTX_EQ (simplify_gen_binary (AND
, mode
, and_op0_op1
, six
),
8234 simplify_gen_binary (AND
, mode
, and_op0_6
, and_op1_6
));
8236 /* Test useless extensions are eliminated. */
8237 ASSERT_RTX_EQ (op0
, simplify_gen_unary (TRUNCATE
, mode
, op0
, mode
));
8238 ASSERT_RTX_EQ (op0
, simplify_gen_unary (ZERO_EXTEND
, mode
, op0
, mode
));
8239 ASSERT_RTX_EQ (op0
, simplify_gen_unary (SIGN_EXTEND
, mode
, op0
, mode
));
8240 ASSERT_RTX_EQ (op0
, lowpart_subreg (mode
, op0
, mode
));
8243 /* Verify some simplifications of integer extension/truncation.
8244 Machine mode BMODE is the guaranteed wider than SMODE. */
8247 test_scalar_int_ext_ops (machine_mode bmode
, machine_mode smode
)
8249 rtx sreg
= make_test_reg (smode
);
8251 /* Check truncation of extension. */
8252 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8253 simplify_gen_unary (ZERO_EXTEND
, bmode
,
8257 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8258 simplify_gen_unary (SIGN_EXTEND
, bmode
,
8262 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8263 lowpart_subreg (bmode
, sreg
, smode
),
8268 /* Verify more simplifications of integer extension/truncation.
8269 BMODE is wider than MMODE which is wider than SMODE. */
8272 test_scalar_int_ext_ops2 (machine_mode bmode
, machine_mode mmode
,
8275 rtx breg
= make_test_reg (bmode
);
8276 rtx mreg
= make_test_reg (mmode
);
8277 rtx sreg
= make_test_reg (smode
);
8279 /* Check truncate of truncate. */
8280 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8281 simplify_gen_unary (TRUNCATE
, mmode
,
8284 simplify_gen_unary (TRUNCATE
, smode
, breg
, bmode
));
8286 /* Check extension of extension. */
8287 ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND
, bmode
,
8288 simplify_gen_unary (ZERO_EXTEND
, mmode
,
8291 simplify_gen_unary (ZERO_EXTEND
, bmode
, sreg
, smode
));
8292 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND
, bmode
,
8293 simplify_gen_unary (SIGN_EXTEND
, mmode
,
8296 simplify_gen_unary (SIGN_EXTEND
, bmode
, sreg
, smode
));
8297 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND
, bmode
,
8298 simplify_gen_unary (ZERO_EXTEND
, mmode
,
8301 simplify_gen_unary (ZERO_EXTEND
, bmode
, sreg
, smode
));
8303 /* Check truncation of extension. */
8304 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8305 simplify_gen_unary (ZERO_EXTEND
, bmode
,
8308 simplify_gen_unary (TRUNCATE
, smode
, mreg
, mmode
));
8309 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8310 simplify_gen_unary (SIGN_EXTEND
, bmode
,
8313 simplify_gen_unary (TRUNCATE
, smode
, mreg
, mmode
));
8314 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE
, smode
,
8315 lowpart_subreg (bmode
, mreg
, mmode
),
8317 simplify_gen_unary (TRUNCATE
, smode
, mreg
, mmode
));
8321 /* Verify some simplifications involving scalar expressions. */
8326 for (unsigned int i
= 0; i
< NUM_MACHINE_MODES
; ++i
)
8328 machine_mode mode
= (machine_mode
) i
;
8329 if (SCALAR_INT_MODE_P (mode
) && mode
!= BImode
)
8330 test_scalar_int_ops (mode
);
8333 test_scalar_int_ext_ops (HImode
, QImode
);
8334 test_scalar_int_ext_ops (SImode
, QImode
);
8335 test_scalar_int_ext_ops (SImode
, HImode
);
8336 test_scalar_int_ext_ops (DImode
, QImode
);
8337 test_scalar_int_ext_ops (DImode
, HImode
);
8338 test_scalar_int_ext_ops (DImode
, SImode
);
8340 test_scalar_int_ext_ops2 (SImode
, HImode
, QImode
);
8341 test_scalar_int_ext_ops2 (DImode
, HImode
, QImode
);
8342 test_scalar_int_ext_ops2 (DImode
, SImode
, QImode
);
8343 test_scalar_int_ext_ops2 (DImode
, SImode
, HImode
);
8346 /* Test vector simplifications involving VEC_DUPLICATE in which the
8347 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8348 register that holds one element of MODE. */
8351 test_vector_ops_duplicate (machine_mode mode
, rtx scalar_reg
)
8353 scalar_mode inner_mode
= GET_MODE_INNER (mode
);
8354 rtx duplicate
= gen_rtx_VEC_DUPLICATE (mode
, scalar_reg
);
8355 poly_uint64 nunits
= GET_MODE_NUNITS (mode
);
8356 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
8358 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
8359 rtx not_scalar_reg
= gen_rtx_NOT (inner_mode
, scalar_reg
);
8360 rtx duplicate_not
= gen_rtx_VEC_DUPLICATE (mode
, not_scalar_reg
);
8361 ASSERT_RTX_EQ (duplicate
,
8362 simplify_unary_operation (NOT
, mode
,
8363 duplicate_not
, mode
));
8365 rtx neg_scalar_reg
= gen_rtx_NEG (inner_mode
, scalar_reg
);
8366 rtx duplicate_neg
= gen_rtx_VEC_DUPLICATE (mode
, neg_scalar_reg
);
8367 ASSERT_RTX_EQ (duplicate
,
8368 simplify_unary_operation (NEG
, mode
,
8369 duplicate_neg
, mode
));
8371 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
8372 ASSERT_RTX_EQ (duplicate
,
8373 simplify_binary_operation (PLUS
, mode
, duplicate
,
8374 CONST0_RTX (mode
)));
8376 ASSERT_RTX_EQ (duplicate
,
8377 simplify_binary_operation (MINUS
, mode
, duplicate
,
8378 CONST0_RTX (mode
)));
8380 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode
),
8381 simplify_binary_operation (MINUS
, mode
, duplicate
,
8385 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
8386 rtx zero_par
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, const0_rtx
));
8387 ASSERT_RTX_PTR_EQ (scalar_reg
,
8388 simplify_binary_operation (VEC_SELECT
, inner_mode
,
8389 duplicate
, zero_par
));
8391 unsigned HOST_WIDE_INT const_nunits
;
8392 if (nunits
.is_constant (&const_nunits
))
8394 /* And again with the final element. */
8395 rtx last_index
= gen_int_mode (const_nunits
- 1, word_mode
);
8396 rtx last_par
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, last_index
));
8397 ASSERT_RTX_PTR_EQ (scalar_reg
,
8398 simplify_binary_operation (VEC_SELECT
, inner_mode
,
8399 duplicate
, last_par
));
8401 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
8402 /* Skip this test for vectors of booleans, because offset is in bytes,
8403 while vec_merge indices are in elements (usually bits). */
8404 if (GET_MODE_CLASS (mode
) != MODE_VECTOR_BOOL
)
8406 rtx vector_reg
= make_test_reg (mode
);
8407 for (unsigned HOST_WIDE_INT i
= 0; i
< const_nunits
; i
++)
8409 if (i
>= HOST_BITS_PER_WIDE_INT
)
8411 rtx mask
= GEN_INT ((HOST_WIDE_INT_1U
<< i
) | (i
+ 1));
8412 rtx vm
= gen_rtx_VEC_MERGE (mode
, duplicate
, vector_reg
, mask
);
8413 poly_uint64 offset
= i
* GET_MODE_SIZE (inner_mode
);
8415 ASSERT_RTX_EQ (scalar_reg
,
8416 simplify_gen_subreg (inner_mode
, vm
,
8422 /* Test a scalar subreg of a VEC_DUPLICATE. */
8423 poly_uint64 offset
= subreg_lowpart_offset (inner_mode
, mode
);
8424 ASSERT_RTX_EQ (scalar_reg
,
8425 simplify_gen_subreg (inner_mode
, duplicate
,
8428 machine_mode narrower_mode
;
8429 if (maybe_ne (nunits
, 2U)
8430 && multiple_p (nunits
, 2)
8431 && mode_for_vector (inner_mode
, 2).exists (&narrower_mode
)
8432 && VECTOR_MODE_P (narrower_mode
))
8434 /* Test VEC_DUPLICATE of a vector. */
8435 rtx_vector_builder
nbuilder (narrower_mode
, 2, 1);
8436 nbuilder
.quick_push (const0_rtx
);
8437 nbuilder
.quick_push (const1_rtx
);
8438 rtx_vector_builder
builder (mode
, 2, 1);
8439 builder
.quick_push (const0_rtx
);
8440 builder
.quick_push (const1_rtx
);
8441 ASSERT_RTX_EQ (builder
.build (),
8442 simplify_unary_operation (VEC_DUPLICATE
, mode
,
8446 /* Test VEC_SELECT of a vector. */
8448 = gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, const1_rtx
, const0_rtx
));
8449 rtx narrower_duplicate
8450 = gen_rtx_VEC_DUPLICATE (narrower_mode
, scalar_reg
);
8451 ASSERT_RTX_EQ (narrower_duplicate
,
8452 simplify_binary_operation (VEC_SELECT
, narrower_mode
,
8453 duplicate
, vec_par
));
8455 /* Test a vector subreg of a VEC_DUPLICATE. */
8456 poly_uint64 offset
= subreg_lowpart_offset (narrower_mode
, mode
);
8457 ASSERT_RTX_EQ (narrower_duplicate
,
8458 simplify_gen_subreg (narrower_mode
, duplicate
,
8463 /* Test vector simplifications involving VEC_SERIES in which the
8464 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8465 register that holds one element of MODE. */
8468 test_vector_ops_series (machine_mode mode
, rtx scalar_reg
)
8470 /* Test unary cases with VEC_SERIES arguments. */
8471 scalar_mode inner_mode
= GET_MODE_INNER (mode
);
8472 rtx duplicate
= gen_rtx_VEC_DUPLICATE (mode
, scalar_reg
);
8473 rtx neg_scalar_reg
= gen_rtx_NEG (inner_mode
, scalar_reg
);
8474 rtx series_0_r
= gen_rtx_VEC_SERIES (mode
, const0_rtx
, scalar_reg
);
8475 rtx series_0_nr
= gen_rtx_VEC_SERIES (mode
, const0_rtx
, neg_scalar_reg
);
8476 rtx series_nr_1
= gen_rtx_VEC_SERIES (mode
, neg_scalar_reg
, const1_rtx
);
8477 rtx series_r_m1
= gen_rtx_VEC_SERIES (mode
, scalar_reg
, constm1_rtx
);
8478 rtx series_r_r
= gen_rtx_VEC_SERIES (mode
, scalar_reg
, scalar_reg
);
8479 rtx series_nr_nr
= gen_rtx_VEC_SERIES (mode
, neg_scalar_reg
,
8481 ASSERT_RTX_EQ (series_0_r
,
8482 simplify_unary_operation (NEG
, mode
, series_0_nr
, mode
));
8483 ASSERT_RTX_EQ (series_r_m1
,
8484 simplify_unary_operation (NEG
, mode
, series_nr_1
, mode
));
8485 ASSERT_RTX_EQ (series_r_r
,
8486 simplify_unary_operation (NEG
, mode
, series_nr_nr
, mode
));
8488 /* Test that a VEC_SERIES with a zero step is simplified away. */
8489 ASSERT_RTX_EQ (duplicate
,
8490 simplify_binary_operation (VEC_SERIES
, mode
,
8491 scalar_reg
, const0_rtx
));
8493 /* Test PLUS and MINUS with VEC_SERIES. */
8494 rtx series_0_1
= gen_const_vec_series (mode
, const0_rtx
, const1_rtx
);
8495 rtx series_0_m1
= gen_const_vec_series (mode
, const0_rtx
, constm1_rtx
);
8496 rtx series_r_1
= gen_rtx_VEC_SERIES (mode
, scalar_reg
, const1_rtx
);
8497 ASSERT_RTX_EQ (series_r_r
,
8498 simplify_binary_operation (PLUS
, mode
, series_0_r
,
8500 ASSERT_RTX_EQ (series_r_1
,
8501 simplify_binary_operation (PLUS
, mode
, duplicate
,
8503 ASSERT_RTX_EQ (series_r_m1
,
8504 simplify_binary_operation (PLUS
, mode
, duplicate
,
8506 ASSERT_RTX_EQ (series_0_r
,
8507 simplify_binary_operation (MINUS
, mode
, series_r_r
,
8509 ASSERT_RTX_EQ (series_r_m1
,
8510 simplify_binary_operation (MINUS
, mode
, duplicate
,
8512 ASSERT_RTX_EQ (series_r_1
,
8513 simplify_binary_operation (MINUS
, mode
, duplicate
,
8515 ASSERT_RTX_EQ (series_0_m1
,
8516 simplify_binary_operation (VEC_SERIES
, mode
, const0_rtx
,
8519 /* Test NEG on constant vector series. */
8520 ASSERT_RTX_EQ (series_0_m1
,
8521 simplify_unary_operation (NEG
, mode
, series_0_1
, mode
));
8522 ASSERT_RTX_EQ (series_0_1
,
8523 simplify_unary_operation (NEG
, mode
, series_0_m1
, mode
));
8525 /* Test PLUS and MINUS on constant vector series. */
8526 rtx scalar2
= gen_int_mode (2, inner_mode
);
8527 rtx scalar3
= gen_int_mode (3, inner_mode
);
8528 rtx series_1_1
= gen_const_vec_series (mode
, const1_rtx
, const1_rtx
);
8529 rtx series_0_2
= gen_const_vec_series (mode
, const0_rtx
, scalar2
);
8530 rtx series_1_3
= gen_const_vec_series (mode
, const1_rtx
, scalar3
);
8531 ASSERT_RTX_EQ (series_1_1
,
8532 simplify_binary_operation (PLUS
, mode
, series_0_1
,
8533 CONST1_RTX (mode
)));
8534 ASSERT_RTX_EQ (series_0_m1
,
8535 simplify_binary_operation (PLUS
, mode
, CONST0_RTX (mode
),
8537 ASSERT_RTX_EQ (series_1_3
,
8538 simplify_binary_operation (PLUS
, mode
, series_1_1
,
8540 ASSERT_RTX_EQ (series_0_1
,
8541 simplify_binary_operation (MINUS
, mode
, series_1_1
,
8542 CONST1_RTX (mode
)));
8543 ASSERT_RTX_EQ (series_1_1
,
8544 simplify_binary_operation (MINUS
, mode
, CONST1_RTX (mode
),
8546 ASSERT_RTX_EQ (series_1_1
,
8547 simplify_binary_operation (MINUS
, mode
, series_1_3
,
8550 /* Test MULT between constant vectors. */
8551 rtx vec2
= gen_const_vec_duplicate (mode
, scalar2
);
8552 rtx vec3
= gen_const_vec_duplicate (mode
, scalar3
);
8553 rtx scalar9
= gen_int_mode (9, inner_mode
);
8554 rtx series_3_9
= gen_const_vec_series (mode
, scalar3
, scalar9
);
8555 ASSERT_RTX_EQ (series_0_2
,
8556 simplify_binary_operation (MULT
, mode
, series_0_1
, vec2
));
8557 ASSERT_RTX_EQ (series_3_9
,
8558 simplify_binary_operation (MULT
, mode
, vec3
, series_1_3
));
8559 if (!GET_MODE_NUNITS (mode
).is_constant ())
8560 ASSERT_FALSE (simplify_binary_operation (MULT
, mode
, series_0_1
,
8563 /* Test ASHIFT between constant vectors. */
8564 ASSERT_RTX_EQ (series_0_2
,
8565 simplify_binary_operation (ASHIFT
, mode
, series_0_1
,
8566 CONST1_RTX (mode
)));
8567 if (!GET_MODE_NUNITS (mode
).is_constant ())
8568 ASSERT_FALSE (simplify_binary_operation (ASHIFT
, mode
, CONST1_RTX (mode
),
8573 simplify_merge_mask (rtx x
, rtx mask
, int op
)
8575 return simplify_context ().simplify_merge_mask (x
, mask
, op
);
8578 /* Verify simplify_merge_mask works correctly. */
8581 test_vec_merge (machine_mode mode
)
8583 rtx op0
= make_test_reg (mode
);
8584 rtx op1
= make_test_reg (mode
);
8585 rtx op2
= make_test_reg (mode
);
8586 rtx op3
= make_test_reg (mode
);
8587 rtx op4
= make_test_reg (mode
);
8588 rtx op5
= make_test_reg (mode
);
8589 rtx mask1
= make_test_reg (SImode
);
8590 rtx mask2
= make_test_reg (SImode
);
8591 rtx vm1
= gen_rtx_VEC_MERGE (mode
, op0
, op1
, mask1
);
8592 rtx vm2
= gen_rtx_VEC_MERGE (mode
, op2
, op3
, mask1
);
8593 rtx vm3
= gen_rtx_VEC_MERGE (mode
, op4
, op5
, mask1
);
8595 /* Simple vec_merge. */
8596 ASSERT_EQ (op0
, simplify_merge_mask (vm1
, mask1
, 0));
8597 ASSERT_EQ (op1
, simplify_merge_mask (vm1
, mask1
, 1));
8598 ASSERT_EQ (NULL_RTX
, simplify_merge_mask (vm1
, mask2
, 0));
8599 ASSERT_EQ (NULL_RTX
, simplify_merge_mask (vm1
, mask2
, 1));
8601 /* Nested vec_merge.
8602 It's tempting to make this simplify right down to opN, but we don't
8603 because all the simplify_* functions assume that the operands have
8604 already been simplified. */
8605 rtx nvm
= gen_rtx_VEC_MERGE (mode
, vm1
, vm2
, mask1
);
8606 ASSERT_EQ (vm1
, simplify_merge_mask (nvm
, mask1
, 0));
8607 ASSERT_EQ (vm2
, simplify_merge_mask (nvm
, mask1
, 1));
8609 /* Intermediate unary op. */
8610 rtx unop
= gen_rtx_NOT (mode
, vm1
);
8611 ASSERT_RTX_EQ (gen_rtx_NOT (mode
, op0
),
8612 simplify_merge_mask (unop
, mask1
, 0));
8613 ASSERT_RTX_EQ (gen_rtx_NOT (mode
, op1
),
8614 simplify_merge_mask (unop
, mask1
, 1));
8616 /* Intermediate binary op. */
8617 rtx binop
= gen_rtx_PLUS (mode
, vm1
, vm2
);
8618 ASSERT_RTX_EQ (gen_rtx_PLUS (mode
, op0
, op2
),
8619 simplify_merge_mask (binop
, mask1
, 0));
8620 ASSERT_RTX_EQ (gen_rtx_PLUS (mode
, op1
, op3
),
8621 simplify_merge_mask (binop
, mask1
, 1));
8623 /* Intermediate ternary op. */
8624 rtx tenop
= gen_rtx_FMA (mode
, vm1
, vm2
, vm3
);
8625 ASSERT_RTX_EQ (gen_rtx_FMA (mode
, op0
, op2
, op4
),
8626 simplify_merge_mask (tenop
, mask1
, 0));
8627 ASSERT_RTX_EQ (gen_rtx_FMA (mode
, op1
, op3
, op5
),
8628 simplify_merge_mask (tenop
, mask1
, 1));
8631 rtx badop0
= gen_rtx_PRE_INC (mode
, op0
);
8632 rtx badvm
= gen_rtx_VEC_MERGE (mode
, badop0
, op1
, mask1
);
8633 ASSERT_EQ (badop0
, simplify_merge_mask (badvm
, mask1
, 0));
8634 ASSERT_EQ (NULL_RTX
, simplify_merge_mask (badvm
, mask1
, 1));
8636 /* Called indirectly. */
8637 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode
, op0
, op3
, mask1
),
8638 simplify_rtx (nvm
));
8641 /* Test subregs of integer vector constant X, trying elements in
8642 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
8643 where NELTS is the number of elements in X. Subregs involving
8644 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
8647 test_vector_subregs_modes (rtx x
, poly_uint64 elt_bias
= 0,
8648 unsigned int first_valid
= 0)
8650 machine_mode inner_mode
= GET_MODE (x
);
8651 scalar_mode int_mode
= GET_MODE_INNER (inner_mode
);
8653 for (unsigned int modei
= 0; modei
< NUM_MACHINE_MODES
; ++modei
)
8655 machine_mode outer_mode
= (machine_mode
) modei
;
8656 if (!VECTOR_MODE_P (outer_mode
))
8659 unsigned int outer_nunits
;
8660 if (GET_MODE_INNER (outer_mode
) == int_mode
8661 && GET_MODE_NUNITS (outer_mode
).is_constant (&outer_nunits
)
8662 && multiple_p (GET_MODE_NUNITS (inner_mode
), outer_nunits
))
8664 /* Test subregs in which the outer mode is a smaller,
8665 constant-sized vector of the same element type. */
8667 = constant_lower_bound (GET_MODE_NUNITS (inner_mode
));
8668 for (unsigned int elt
= 0; elt
< limit
; elt
+= outer_nunits
)
8670 rtx expected
= NULL_RTX
;
8671 if (elt
>= first_valid
)
8673 rtx_vector_builder
builder (outer_mode
, outer_nunits
, 1);
8674 for (unsigned int i
= 0; i
< outer_nunits
; ++i
)
8675 builder
.quick_push (CONST_VECTOR_ELT (x
, elt
+ i
));
8676 expected
= builder
.build ();
8678 poly_uint64 byte
= (elt_bias
+ elt
) * GET_MODE_SIZE (int_mode
);
8679 ASSERT_RTX_EQ (expected
,
8680 simplify_subreg (outer_mode
, x
,
8684 else if (known_eq (GET_MODE_SIZE (outer_mode
),
8685 GET_MODE_SIZE (inner_mode
))
8686 && known_eq (elt_bias
, 0U)
8687 && (GET_MODE_CLASS (outer_mode
) != MODE_VECTOR_BOOL
8688 || known_eq (GET_MODE_BITSIZE (outer_mode
),
8689 GET_MODE_NUNITS (outer_mode
)))
8690 && (!FLOAT_MODE_P (outer_mode
)
8691 || (FLOAT_MODE_FORMAT (outer_mode
)->ieee_bits
8692 == GET_MODE_UNIT_PRECISION (outer_mode
)))
8693 && (GET_MODE_SIZE (inner_mode
).is_constant ()
8694 || !CONST_VECTOR_STEPPED_P (x
)))
8696 /* Try converting to OUTER_MODE and back. */
8697 rtx outer_x
= simplify_subreg (outer_mode
, x
, inner_mode
, 0);
8698 ASSERT_TRUE (outer_x
!= NULL_RTX
);
8699 ASSERT_RTX_EQ (x
, simplify_subreg (inner_mode
, outer_x
,
8704 if (BYTES_BIG_ENDIAN
== WORDS_BIG_ENDIAN
)
8706 /* Test each byte in the element range. */
8708 = constant_lower_bound (GET_MODE_SIZE (inner_mode
));
8709 for (unsigned int i
= 0; i
< limit
; ++i
)
8711 unsigned int elt
= i
/ GET_MODE_SIZE (int_mode
);
8712 rtx expected
= NULL_RTX
;
8713 if (elt
>= first_valid
)
8715 unsigned int byte_shift
= i
% GET_MODE_SIZE (int_mode
);
8716 if (BYTES_BIG_ENDIAN
)
8717 byte_shift
= GET_MODE_SIZE (int_mode
) - byte_shift
- 1;
8718 rtx_mode_t
vec_elt (CONST_VECTOR_ELT (x
, elt
), int_mode
);
8719 wide_int shifted_elt
8720 = wi::lrshift (vec_elt
, byte_shift
* BITS_PER_UNIT
);
8721 expected
= immed_wide_int_const (shifted_elt
, QImode
);
8723 poly_uint64 byte
= elt_bias
* GET_MODE_SIZE (int_mode
) + i
;
8724 ASSERT_RTX_EQ (expected
,
8725 simplify_subreg (QImode
, x
, inner_mode
, byte
));
8730 /* Test constant subregs of integer vector mode INNER_MODE, using 1
8731 element per pattern. */
8734 test_vector_subregs_repeating (machine_mode inner_mode
)
8736 poly_uint64 nunits
= GET_MODE_NUNITS (inner_mode
);
8737 unsigned int min_nunits
= constant_lower_bound (nunits
);
8738 scalar_mode int_mode
= GET_MODE_INNER (inner_mode
);
8739 unsigned int count
= gcd (min_nunits
, 8);
8741 rtx_vector_builder
builder (inner_mode
, count
, 1);
8742 for (unsigned int i
= 0; i
< count
; ++i
)
8743 builder
.quick_push (gen_int_mode (8 - i
, int_mode
));
8744 rtx x
= builder
.build ();
8746 test_vector_subregs_modes (x
);
8747 if (!nunits
.is_constant ())
8748 test_vector_subregs_modes (x
, nunits
- min_nunits
);
8751 /* Test constant subregs of integer vector mode INNER_MODE, using 2
8752 elements per pattern. */
8755 test_vector_subregs_fore_back (machine_mode inner_mode
)
8757 poly_uint64 nunits
= GET_MODE_NUNITS (inner_mode
);
8758 unsigned int min_nunits
= constant_lower_bound (nunits
);
8759 scalar_mode int_mode
= GET_MODE_INNER (inner_mode
);
8760 unsigned int count
= gcd (min_nunits
, 4);
8762 rtx_vector_builder
builder (inner_mode
, count
, 2);
8763 for (unsigned int i
= 0; i
< count
; ++i
)
8764 builder
.quick_push (gen_int_mode (i
, int_mode
));
8765 for (unsigned int i
= 0; i
< count
; ++i
)
8766 builder
.quick_push (gen_int_mode (-1 - (int) i
, int_mode
));
8767 rtx x
= builder
.build ();
8769 test_vector_subregs_modes (x
);
8770 if (!nunits
.is_constant ())
8771 test_vector_subregs_modes (x
, nunits
- min_nunits
, count
);
8774 /* Test constant subregs of integer vector mode INNER_MODE, using 3
8775 elements per pattern. */
8778 test_vector_subregs_stepped (machine_mode inner_mode
)
8780 /* Build { 0, 1, 2, 3, ... }. */
8781 scalar_mode int_mode
= GET_MODE_INNER (inner_mode
);
8782 rtx_vector_builder
builder (inner_mode
, 1, 3);
8783 for (unsigned int i
= 0; i
< 3; ++i
)
8784 builder
.quick_push (gen_int_mode (i
, int_mode
));
8785 rtx x
= builder
.build ();
8787 test_vector_subregs_modes (x
);
8790 /* Test constant subregs of integer vector mode INNER_MODE. */
8793 test_vector_subregs (machine_mode inner_mode
)
8795 test_vector_subregs_repeating (inner_mode
);
8796 test_vector_subregs_fore_back (inner_mode
);
8797 test_vector_subregs_stepped (inner_mode
);
8800 /* Verify some simplifications involving vectors. */
8805 for (unsigned int i
= 0; i
< NUM_MACHINE_MODES
; ++i
)
8807 machine_mode mode
= (machine_mode
) i
;
8808 if (VECTOR_MODE_P (mode
))
8810 rtx scalar_reg
= make_test_reg (GET_MODE_INNER (mode
));
8811 test_vector_ops_duplicate (mode
, scalar_reg
);
8812 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
8813 && maybe_gt (GET_MODE_NUNITS (mode
), 2))
8815 test_vector_ops_series (mode
, scalar_reg
);
8816 test_vector_subregs (mode
);
8818 test_vec_merge (mode
);
8823 template<unsigned int N
>
8824 struct simplify_const_poly_int_tests
8830 struct simplify_const_poly_int_tests
<1>
8832 static void run () {}
8835 /* Test various CONST_POLY_INT properties. */
8837 template<unsigned int N
>
8839 simplify_const_poly_int_tests
<N
>::run ()
8841 using poly_int64
= poly_int
<N
, HOST_WIDE_INT
>;
8842 rtx x1
= gen_int_mode (poly_int64 (1, 1), QImode
);
8843 rtx x2
= gen_int_mode (poly_int64 (-80, 127), QImode
);
8844 rtx x3
= gen_int_mode (poly_int64 (-79, -128), QImode
);
8845 rtx x4
= gen_int_mode (poly_int64 (5, 4), QImode
);
8846 rtx x5
= gen_int_mode (poly_int64 (30, 24), QImode
);
8847 rtx x6
= gen_int_mode (poly_int64 (20, 16), QImode
);
8848 rtx x7
= gen_int_mode (poly_int64 (7, 4), QImode
);
8849 rtx x8
= gen_int_mode (poly_int64 (30, 24), HImode
);
8850 rtx x9
= gen_int_mode (poly_int64 (-30, -24), HImode
);
8851 rtx x10
= gen_int_mode (poly_int64 (-31, -24), HImode
);
8852 rtx two
= GEN_INT (2);
8853 rtx six
= GEN_INT (6);
8854 poly_uint64 offset
= subreg_lowpart_offset (QImode
, HImode
);
8856 /* These tests only try limited operation combinations. Fuller arithmetic
8857 testing is done directly on poly_ints. */
8858 ASSERT_EQ (simplify_unary_operation (NEG
, HImode
, x8
, HImode
), x9
);
8859 ASSERT_EQ (simplify_unary_operation (NOT
, HImode
, x8
, HImode
), x10
);
8860 ASSERT_EQ (simplify_unary_operation (TRUNCATE
, QImode
, x8
, HImode
), x5
);
8861 ASSERT_EQ (simplify_binary_operation (PLUS
, QImode
, x1
, x2
), x3
);
8862 ASSERT_EQ (simplify_binary_operation (MINUS
, QImode
, x3
, x1
), x2
);
8863 ASSERT_EQ (simplify_binary_operation (MULT
, QImode
, x4
, six
), x5
);
8864 ASSERT_EQ (simplify_binary_operation (MULT
, QImode
, six
, x4
), x5
);
8865 ASSERT_EQ (simplify_binary_operation (ASHIFT
, QImode
, x4
, two
), x6
);
8866 ASSERT_EQ (simplify_binary_operation (IOR
, QImode
, x4
, two
), x7
);
8867 ASSERT_EQ (simplify_subreg (HImode
, x5
, QImode
, 0), x8
);
8868 ASSERT_EQ (simplify_subreg (QImode
, x8
, HImode
, offset
), x5
);
8871 /* Run all of the selftests within this file. */
8874 simplify_rtx_cc_tests ()
8878 simplify_const_poly_int_tests
<NUM_POLY_INT_COEFFS
>::run ();
8881 } // namespace selftest
8883 #endif /* CHECKING_P */