Default to dwarf version 4 on hppa64-hpux
[official-gcc.git] / gcc / simplify-rtx.c
blob16286befd79e4c75ee51a9440c9ea623a5dfa62c
1 /* RTL simplification functions for GNU compiler.
2 Copyright (C) 1987-2021 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "predict.h"
29 #include "memmodel.h"
30 #include "optabs.h"
31 #include "emit-rtl.h"
32 #include "recog.h"
33 #include "diagnostic-core.h"
34 #include "varasm.h"
35 #include "flags.h"
36 #include "selftest.h"
37 #include "selftest-rtl.h"
38 #include "rtx-vector-builder.h"
39 #include "rtlanal.h"
41 /* Simplification and canonicalization of RTL. */
43 /* Much code operates on (low, high) pairs; the low value is an
44 unsigned wide int, the high value a signed wide int. We
45 occasionally need to sign extend from low to high as if low were a
46 signed wide int. */
47 #define HWI_SIGN_EXTEND(low) \
48 ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
50 static bool plus_minus_operand_p (const_rtx);
52 /* Negate I, which satisfies poly_int_rtx_p. MODE is the mode of I. */
54 static rtx
55 neg_poly_int_rtx (machine_mode mode, const_rtx i)
57 return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
60 /* Test whether expression, X, is an immediate constant that represents
61 the most significant bit of machine mode MODE. */
63 bool
64 mode_signbit_p (machine_mode mode, const_rtx x)
66 unsigned HOST_WIDE_INT val;
67 unsigned int width;
68 scalar_int_mode int_mode;
70 if (!is_int_mode (mode, &int_mode))
71 return false;
73 width = GET_MODE_PRECISION (int_mode);
74 if (width == 0)
75 return false;
77 if (width <= HOST_BITS_PER_WIDE_INT
78 && CONST_INT_P (x))
79 val = INTVAL (x);
80 #if TARGET_SUPPORTS_WIDE_INT
81 else if (CONST_WIDE_INT_P (x))
83 unsigned int i;
84 unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 return false;
87 for (i = 0; i < elts - 1; i++)
88 if (CONST_WIDE_INT_ELT (x, i) != 0)
89 return false;
90 val = CONST_WIDE_INT_ELT (x, elts - 1);
91 width %= HOST_BITS_PER_WIDE_INT;
92 if (width == 0)
93 width = HOST_BITS_PER_WIDE_INT;
95 #else
96 else if (width <= HOST_BITS_PER_DOUBLE_INT
97 && CONST_DOUBLE_AS_INT_P (x)
98 && CONST_DOUBLE_LOW (x) == 0)
100 val = CONST_DOUBLE_HIGH (x);
101 width -= HOST_BITS_PER_WIDE_INT;
103 #endif
104 else
105 /* X is not an integer constant. */
106 return false;
108 if (width < HOST_BITS_PER_WIDE_INT)
109 val &= (HOST_WIDE_INT_1U << width) - 1;
110 return val == (HOST_WIDE_INT_1U << (width - 1));
113 /* Test whether VAL is equal to the most significant bit of mode MODE
114 (after masking with the mode mask of MODE). Returns false if the
115 precision of MODE is too large to handle. */
117 bool
118 val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
120 unsigned int width;
121 scalar_int_mode int_mode;
123 if (!is_int_mode (mode, &int_mode))
124 return false;
126 width = GET_MODE_PRECISION (int_mode);
127 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 return false;
130 val &= GET_MODE_MASK (int_mode);
131 return val == (HOST_WIDE_INT_1U << (width - 1));
134 /* Test whether the most significant bit of mode MODE is set in VAL.
135 Returns false if the precision of MODE is too large to handle. */
136 bool
137 val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
139 unsigned int width;
141 scalar_int_mode int_mode;
142 if (!is_int_mode (mode, &int_mode))
143 return false;
145 width = GET_MODE_PRECISION (int_mode);
146 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 return false;
149 val &= HOST_WIDE_INT_1U << (width - 1);
150 return val != 0;
153 /* Test whether the most significant bit of mode MODE is clear in VAL.
154 Returns false if the precision of MODE is too large to handle. */
155 bool
156 val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
158 unsigned int width;
160 scalar_int_mode int_mode;
161 if (!is_int_mode (mode, &int_mode))
162 return false;
164 width = GET_MODE_PRECISION (int_mode);
165 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 return false;
168 val &= HOST_WIDE_INT_1U << (width - 1);
169 return val == 0;
172 /* Make a binary operation by properly ordering the operands and
173 seeing if the expression folds. */
176 simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 rtx op0, rtx op1)
179 rtx tem;
181 /* If this simplifies, do it. */
182 tem = simplify_binary_operation (code, mode, op0, op1);
183 if (tem)
184 return tem;
186 /* Put complex operands first and constants second if commutative. */
187 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 && swap_commutative_operands_p (op0, op1))
189 std::swap (op0, op1);
191 return gen_rtx_fmt_ee (code, mode, op0, op1);
194 /* If X is a MEM referencing the constant pool, return the real value.
195 Otherwise return X. */
197 avoid_constant_pool_reference (rtx x)
199 rtx c, tmp, addr;
200 machine_mode cmode;
201 poly_int64 offset = 0;
203 switch (GET_CODE (x))
205 case MEM:
206 break;
208 case FLOAT_EXTEND:
209 /* Handle float extensions of constant pool references. */
210 tmp = XEXP (x, 0);
211 c = avoid_constant_pool_reference (tmp);
212 if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 GET_MODE (x));
215 return x;
217 default:
218 return x;
221 if (GET_MODE (x) == BLKmode)
222 return x;
224 addr = XEXP (x, 0);
226 /* Call target hook to avoid the effects of -fpic etc.... */
227 addr = targetm.delegitimize_address (addr);
229 /* Split the address into a base and integer offset. */
230 addr = strip_offset (addr, &offset);
232 if (GET_CODE (addr) == LO_SUM)
233 addr = XEXP (addr, 1);
235 /* If this is a constant pool reference, we can turn it into its
236 constant and hope that simplifications happen. */
237 if (GET_CODE (addr) == SYMBOL_REF
238 && CONSTANT_POOL_ADDRESS_P (addr))
240 c = get_pool_constant (addr);
241 cmode = get_pool_mode (addr);
243 /* If we're accessing the constant in a different mode than it was
244 originally stored, attempt to fix that up via subreg simplifications.
245 If that fails we have no choice but to return the original memory. */
246 if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 return c;
248 else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
250 rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 if (tem && CONSTANT_P (tem))
252 return tem;
256 return x;
259 /* Simplify a MEM based on its attributes. This is the default
260 delegitimize_address target hook, and it's recommended that every
261 overrider call it. */
264 delegitimize_mem_from_attrs (rtx x)
266 /* MEMs without MEM_OFFSETs may have been offset, so we can't just
267 use their base addresses as equivalent. */
268 if (MEM_P (x)
269 && MEM_EXPR (x)
270 && MEM_OFFSET_KNOWN_P (x))
272 tree decl = MEM_EXPR (x);
273 machine_mode mode = GET_MODE (x);
274 poly_int64 offset = 0;
276 switch (TREE_CODE (decl))
278 default:
279 decl = NULL;
280 break;
282 case VAR_DECL:
283 break;
285 case ARRAY_REF:
286 case ARRAY_RANGE_REF:
287 case COMPONENT_REF:
288 case BIT_FIELD_REF:
289 case REALPART_EXPR:
290 case IMAGPART_EXPR:
291 case VIEW_CONVERT_EXPR:
293 poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 tree toffset;
295 int unsignedp, reversep, volatilep = 0;
297 decl
298 = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 &unsignedp, &reversep, &volatilep);
300 if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 decl = NULL;
304 else
305 offset += bytepos + toffset_val;
306 break;
310 if (decl
311 && mode == GET_MODE (x)
312 && VAR_P (decl)
313 && (TREE_STATIC (decl)
314 || DECL_THREAD_LOCAL_P (decl))
315 && DECL_RTL_SET_P (decl)
316 && MEM_P (DECL_RTL (decl)))
318 rtx newx;
320 offset += MEM_OFFSET (x);
322 newx = DECL_RTL (decl);
324 if (MEM_P (newx))
326 rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 poly_int64 n_offset, o_offset;
329 /* Avoid creating a new MEM needlessly if we already had
330 the same address. We do if there's no OFFSET and the
331 old address X is identical to NEWX, or if X is of the
332 form (plus NEWX OFFSET), or the NEWX is of the form
333 (plus Y (const_int Z)) and X is that with the offset
334 added: (plus Y (const_int Z+OFFSET)). */
335 n = strip_offset (n, &n_offset);
336 o = strip_offset (o, &o_offset);
337 if (!(known_eq (o_offset, n_offset + offset)
338 && rtx_equal_p (o, n)))
339 x = adjust_address_nv (newx, mode, offset);
341 else if (GET_MODE (x) == GET_MODE (newx)
342 && known_eq (offset, 0))
343 x = newx;
347 return x;
350 /* Make a unary operation by first seeing if it folds and otherwise making
351 the specified operation. */
354 simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 machine_mode op_mode)
357 rtx tem;
359 /* If this simplifies, use it. */
360 if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 return tem;
363 return gen_rtx_fmt_e (code, mode, op);
366 /* Likewise for ternary operations. */
369 simplify_context::simplify_gen_ternary (rtx_code code, machine_mode mode,
370 machine_mode op0_mode,
371 rtx op0, rtx op1, rtx op2)
373 rtx tem;
375 /* If this simplifies, use it. */
376 if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 op0, op1, op2)) != 0)
378 return tem;
380 return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
383 /* Likewise, for relational operations.
384 CMP_MODE specifies mode comparison is done in. */
387 simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 machine_mode cmp_mode,
389 rtx op0, rtx op1)
391 rtx tem;
393 if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 op0, op1)) != 0)
395 return tem;
397 return gen_rtx_fmt_ee (code, mode, op0, op1);
400 /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
401 and simplify the result. If FN is non-NULL, call this callback on each
402 X, if it returns non-NULL, replace X with its return value and simplify the
403 result. */
406 simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 rtx (*fn) (rtx, const_rtx, void *), void *data)
409 enum rtx_code code = GET_CODE (x);
410 machine_mode mode = GET_MODE (x);
411 machine_mode op_mode;
412 const char *fmt;
413 rtx op0, op1, op2, newx, op;
414 rtvec vec, newvec;
415 int i, j;
417 if (__builtin_expect (fn != NULL, 0))
419 newx = fn (x, old_rtx, data);
420 if (newx)
421 return newx;
423 else if (rtx_equal_p (x, old_rtx))
424 return copy_rtx ((rtx) data);
426 switch (GET_RTX_CLASS (code))
428 case RTX_UNARY:
429 op0 = XEXP (x, 0);
430 op_mode = GET_MODE (op0);
431 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 if (op0 == XEXP (x, 0))
433 return x;
434 return simplify_gen_unary (code, mode, op0, op_mode);
436 case RTX_BIN_ARITH:
437 case RTX_COMM_ARITH:
438 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 return x;
442 return simplify_gen_binary (code, mode, op0, op1);
444 case RTX_COMPARE:
445 case RTX_COMM_COMPARE:
446 op0 = XEXP (x, 0);
447 op1 = XEXP (x, 1);
448 op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 return x;
453 return simplify_gen_relational (code, mode, op_mode, op0, op1);
455 case RTX_TERNARY:
456 case RTX_BITFIELD_OPS:
457 op0 = XEXP (x, 0);
458 op_mode = GET_MODE (op0);
459 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 return x;
464 if (op_mode == VOIDmode)
465 op_mode = GET_MODE (op0);
466 return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
468 case RTX_EXTRA:
469 if (code == SUBREG)
471 op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 if (op0 == SUBREG_REG (x))
473 return x;
474 op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 GET_MODE (SUBREG_REG (x)),
476 SUBREG_BYTE (x));
477 return op0 ? op0 : x;
479 break;
481 case RTX_OBJ:
482 if (code == MEM)
484 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 if (op0 == XEXP (x, 0))
486 return x;
487 return replace_equiv_address_nv (x, op0);
489 else if (code == LO_SUM)
491 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
492 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
494 /* (lo_sum (high x) y) -> y where x and y have the same base. */
495 if (GET_CODE (op0) == HIGH)
497 rtx base0, base1, offset0, offset1;
498 split_const (XEXP (op0, 0), &base0, &offset0);
499 split_const (op1, &base1, &offset1);
500 if (rtx_equal_p (base0, base1))
501 return op1;
504 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
505 return x;
506 return gen_rtx_LO_SUM (mode, op0, op1);
508 break;
510 default:
511 break;
514 newx = x;
515 fmt = GET_RTX_FORMAT (code);
516 for (i = 0; fmt[i]; i++)
517 switch (fmt[i])
519 case 'E':
520 vec = XVEC (x, i);
521 newvec = XVEC (newx, i);
522 for (j = 0; j < GET_NUM_ELEM (vec); j++)
524 op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 old_rtx, fn, data);
526 if (op != RTVEC_ELT (vec, j))
528 if (newvec == vec)
530 newvec = shallow_copy_rtvec (vec);
531 if (x == newx)
532 newx = shallow_copy_rtx (x);
533 XVEC (newx, i) = newvec;
535 RTVEC_ELT (newvec, j) = op;
538 break;
540 case 'e':
541 if (XEXP (x, i))
543 op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 if (op != XEXP (x, i))
546 if (x == newx)
547 newx = shallow_copy_rtx (x);
548 XEXP (newx, i) = op;
551 break;
553 return newx;
556 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
557 resulting RTX. Return a new RTX which is as simplified as possible. */
560 simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
562 return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
565 /* Try to simplify a MODE truncation of OP, which has OP_MODE.
566 Only handle cases where the truncated value is inherently an rvalue.
568 RTL provides two ways of truncating a value:
570 1. a lowpart subreg. This form is only a truncation when both
571 the outer and inner modes (here MODE and OP_MODE respectively)
572 are scalar integers, and only then when the subreg is used as
573 an rvalue.
575 It is only valid to form such truncating subregs if the
576 truncation requires no action by the target. The onus for
577 proving this is on the creator of the subreg -- e.g. the
578 caller to simplify_subreg or simplify_gen_subreg -- and typically
579 involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
581 2. a TRUNCATE. This form handles both scalar and compound integers.
583 The first form is preferred where valid. However, the TRUNCATE
584 handling in simplify_unary_operation turns the second form into the
585 first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
586 so it is generally safe to form rvalue truncations using:
588 simplify_gen_unary (TRUNCATE, ...)
590 and leave simplify_unary_operation to work out which representation
591 should be used.
593 Because of the proof requirements on (1), simplify_truncation must
594 also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
595 regardless of whether the outer truncation came from a SUBREG or a
596 TRUNCATE. For example, if the caller has proven that an SImode
597 truncation of:
599 (and:DI X Y)
601 is a no-op and can be represented as a subreg, it does not follow
602 that SImode truncations of X and Y are also no-ops. On a target
603 like 64-bit MIPS that requires SImode values to be stored in
604 sign-extended form, an SImode truncation of:
606 (and:DI (reg:DI X) (const_int 63))
608 is trivially a no-op because only the lower 6 bits can be set.
609 However, X is still an arbitrary 64-bit number and so we cannot
610 assume that truncating it too is a no-op. */
613 simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 machine_mode op_mode)
616 unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 scalar_int_mode int_mode, int_op_mode, subreg_mode;
620 gcc_assert (precision <= op_precision);
622 /* Optimize truncations of zero and sign extended values. */
623 if (GET_CODE (op) == ZERO_EXTEND
624 || GET_CODE (op) == SIGN_EXTEND)
626 /* There are three possibilities. If MODE is the same as the
627 origmode, we can omit both the extension and the subreg.
628 If MODE is not larger than the origmode, we can apply the
629 truncation without the extension. Finally, if the outermode
630 is larger than the origmode, we can just extend to the appropriate
631 mode. */
632 machine_mode origmode = GET_MODE (XEXP (op, 0));
633 if (mode == origmode)
634 return XEXP (op, 0);
635 else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 return simplify_gen_unary (TRUNCATE, mode,
637 XEXP (op, 0), origmode);
638 else
639 return simplify_gen_unary (GET_CODE (op), mode,
640 XEXP (op, 0), origmode);
643 /* If the machine can perform operations in the truncated mode, distribute
644 the truncation, i.e. simplify (truncate:QI (op:SI (x:SI) (y:SI))) into
645 (op:QI (truncate:QI (x:SI)) (truncate:QI (y:SI))). */
646 if (1
647 && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 && (GET_CODE (op) == PLUS
649 || GET_CODE (op) == MINUS
650 || GET_CODE (op) == MULT))
652 rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 if (op0)
655 rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 if (op1)
657 return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
661 /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
662 to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
663 the outer subreg is effectively a truncation to the original mode. */
664 if ((GET_CODE (op) == LSHIFTRT
665 || GET_CODE (op) == ASHIFTRT)
666 /* Ensure that OP_MODE is at least twice as wide as MODE
667 to avoid the possibility that an outer LSHIFTRT shifts by more
668 than the sign extension's sign_bit_copies and introduces zeros
669 into the high bits of the result. */
670 && 2 * precision <= op_precision
671 && CONST_INT_P (XEXP (op, 1))
672 && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
673 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
674 && UINTVAL (XEXP (op, 1)) < precision)
675 return simplify_gen_binary (ASHIFTRT, mode,
676 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
678 /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
679 to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
680 the outer subreg is effectively a truncation to the original mode. */
681 if ((GET_CODE (op) == LSHIFTRT
682 || GET_CODE (op) == ASHIFTRT)
683 && CONST_INT_P (XEXP (op, 1))
684 && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 && UINTVAL (XEXP (op, 1)) < precision)
687 return simplify_gen_binary (LSHIFTRT, mode,
688 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
690 /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
691 to (ashift:QI (x:QI) C), where C is a suitable small constant and
692 the outer subreg is effectively a truncation to the original mode. */
693 if (GET_CODE (op) == ASHIFT
694 && CONST_INT_P (XEXP (op, 1))
695 && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 && UINTVAL (XEXP (op, 1)) < precision)
699 return simplify_gen_binary (ASHIFT, mode,
700 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
702 /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into
703 (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C
704 and C2. */
705 if (GET_CODE (op) == AND
706 && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 && CONST_INT_P (XEXP (op, 1)))
711 rtx op0 = (XEXP (XEXP (op, 0), 0));
712 rtx shift_op = XEXP (XEXP (op, 0), 1);
713 rtx mask_op = XEXP (op, 1);
714 unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
717 if (shift < precision
718 /* If doing this transform works for an X with all bits set,
719 it works for any X. */
720 && ((GET_MODE_MASK (mode) >> shift) & mask)
721 == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
725 mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 return simplify_gen_binary (AND, mode, op0, mask_op);
730 /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
731 (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
732 changing len. */
733 if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 && REG_P (XEXP (op, 0))
735 && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 && CONST_INT_P (XEXP (op, 1))
737 && CONST_INT_P (XEXP (op, 2)))
739 rtx op0 = XEXP (op, 0);
740 unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
744 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 if (op0)
747 pos -= op_precision - precision;
748 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 XEXP (op, 1), GEN_INT (pos));
752 else if (!BITS_BIG_ENDIAN && precision >= len + pos)
754 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 if (op0)
756 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 XEXP (op, 1), XEXP (op, 2));
761 /* Recognize a word extraction from a multi-word subreg. */
762 if ((GET_CODE (op) == LSHIFTRT
763 || GET_CODE (op) == ASHIFTRT)
764 && SCALAR_INT_MODE_P (mode)
765 && SCALAR_INT_MODE_P (op_mode)
766 && precision >= BITS_PER_WORD
767 && 2 * precision <= op_precision
768 && CONST_INT_P (XEXP (op, 1))
769 && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 && UINTVAL (XEXP (op, 1)) < op_precision)
772 poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 (WORDS_BIG_ENDIAN
776 ? byte - shifted_bytes
777 : byte + shifted_bytes));
780 /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
781 and try replacing the TRUNCATE and shift with it. Don't do this
782 if the MEM has a mode-dependent address. */
783 if ((GET_CODE (op) == LSHIFTRT
784 || GET_CODE (op) == ASHIFTRT)
785 && is_a <scalar_int_mode> (mode, &int_mode)
786 && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 && MEM_P (XEXP (op, 0))
788 && CONST_INT_P (XEXP (op, 1))
789 && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 && INTVAL (XEXP (op, 1)) > 0
791 && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 MEM_ADDR_SPACE (XEXP (op, 0)))
794 && ! MEM_VOLATILE_P (XEXP (op, 0))
795 && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
798 poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 return adjust_address_nv (XEXP (op, 0), int_mode,
801 (WORDS_BIG_ENDIAN
802 ? byte - shifted_bytes
803 : byte + shifted_bytes));
806 /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
807 (OP:SI foo:SI) if OP is NEG or ABS. */
808 if ((GET_CODE (op) == ABS
809 || GET_CODE (op) == NEG)
810 && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 return simplify_gen_unary (GET_CODE (op), mode,
814 XEXP (XEXP (op, 0), 0), mode);
816 /* Simplifications of (truncate:A (subreg:B X 0)). */
817 if (GET_CODE (op) == SUBREG
818 && is_a <scalar_int_mode> (mode, &int_mode)
819 && SCALAR_INT_MODE_P (op_mode)
820 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 && subreg_lowpart_p (op))
823 /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 if (GET_CODE (SUBREG_REG (op)) == TRUNCATE)
826 rtx inner = XEXP (SUBREG_REG (op), 0);
827 if (GET_MODE_PRECISION (int_mode)
828 <= GET_MODE_PRECISION (subreg_mode))
829 return simplify_gen_unary (TRUNCATE, int_mode, inner,
830 GET_MODE (inner));
831 else
832 /* If subreg above is paradoxical and C is narrower
833 than A, return (subreg:A (truncate:C X) 0). */
834 return simplify_gen_subreg (int_mode, SUBREG_REG (op),
835 subreg_mode, 0);
838 /* Simplifications of (truncate:A (subreg:B X:C 0)) with
839 paradoxical subregs (B is wider than C). */
840 if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
842 unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 if (int_op_prec > subreg_prec)
846 if (int_mode == subreg_mode)
847 return SUBREG_REG (op);
848 if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 return simplify_gen_unary (TRUNCATE, int_mode,
850 SUBREG_REG (op), subreg_mode);
852 /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 A is narrower than B and B is narrower than C. */
854 else if (int_op_prec < subreg_prec
855 && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 return simplify_gen_unary (TRUNCATE, int_mode,
857 SUBREG_REG (op), subreg_mode);
861 /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 if (GET_CODE (op) == TRUNCATE)
863 return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
864 GET_MODE (XEXP (op, 0)));
866 /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
867 in mode A. */
868 if (GET_CODE (op) == IOR
869 && SCALAR_INT_MODE_P (mode)
870 && SCALAR_INT_MODE_P (op_mode)
871 && CONST_INT_P (XEXP (op, 1))
872 && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
873 return constm1_rtx;
875 return NULL_RTX;
878 /* Try to simplify a unary operation CODE whose output mode is to be
879 MODE with input operand OP whose mode was originally OP_MODE.
880 Return zero if no simplification can be made. */
882 simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 rtx op, machine_mode op_mode)
885 rtx trueop, tem;
887 trueop = avoid_constant_pool_reference (op);
889 tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 if (tem)
891 return tem;
893 return simplify_unary_operation_1 (code, mode, op);
896 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
897 to be exact. */
899 static bool
900 exact_int_to_float_conversion_p (const_rtx op)
902 int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
903 machine_mode op0_mode = GET_MODE (XEXP (op, 0));
904 /* Constants shouldn't reach here. */
905 gcc_assert (op0_mode != VOIDmode);
906 int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
907 int in_bits = in_prec;
908 if (HWI_COMPUTABLE_MODE_P (op0_mode))
910 unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
911 if (GET_CODE (op) == FLOAT)
912 in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
913 else if (GET_CODE (op) == UNSIGNED_FLOAT)
914 in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
915 else
916 gcc_unreachable ();
917 in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
919 return in_bits <= out_bits;
922 /* Perform some simplifications we can do even if the operands
923 aren't constant. */
925 simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
926 rtx op)
928 enum rtx_code reversed;
929 rtx temp, elt, base, step;
930 scalar_int_mode inner, int_mode, op_mode, op0_mode;
932 switch (code)
934 case NOT:
935 /* (not (not X)) == X. */
936 if (GET_CODE (op) == NOT)
937 return XEXP (op, 0);
939 /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
940 comparison is all ones. */
941 if (COMPARISON_P (op)
942 && (mode == BImode || STORE_FLAG_VALUE == -1)
943 && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
944 return simplify_gen_relational (reversed, mode, VOIDmode,
945 XEXP (op, 0), XEXP (op, 1));
947 /* (not (plus X -1)) can become (neg X). */
948 if (GET_CODE (op) == PLUS
949 && XEXP (op, 1) == constm1_rtx)
950 return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
952 /* Similarly, (not (neg X)) is (plus X -1). Only do this for
953 modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
954 and MODE_VECTOR_INT. */
955 if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
956 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
957 CONSTM1_RTX (mode));
959 /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
960 if (GET_CODE (op) == XOR
961 && CONST_INT_P (XEXP (op, 1))
962 && (temp = simplify_unary_operation (NOT, mode,
963 XEXP (op, 1), mode)) != 0)
964 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
966 /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
967 if (GET_CODE (op) == PLUS
968 && CONST_INT_P (XEXP (op, 1))
969 && mode_signbit_p (mode, XEXP (op, 1))
970 && (temp = simplify_unary_operation (NOT, mode,
971 XEXP (op, 1), mode)) != 0)
972 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
975 /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
976 operands other than 1, but that is not valid. We could do a
977 similar simplification for (not (lshiftrt C X)) where C is
978 just the sign bit, but this doesn't seem common enough to
979 bother with. */
980 if (GET_CODE (op) == ASHIFT
981 && XEXP (op, 0) == const1_rtx)
983 temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
984 return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
987 /* (not (ashiftrt foo C)) where C is the number of bits in FOO
988 minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
989 so we can perform the above simplification. */
990 if (STORE_FLAG_VALUE == -1
991 && is_a <scalar_int_mode> (mode, &int_mode)
992 && GET_CODE (op) == ASHIFTRT
993 && CONST_INT_P (XEXP (op, 1))
994 && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
995 return simplify_gen_relational (GE, int_mode, VOIDmode,
996 XEXP (op, 0), const0_rtx);
999 if (partial_subreg_p (op)
1000 && subreg_lowpart_p (op)
1001 && GET_CODE (SUBREG_REG (op)) == ASHIFT
1002 && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1004 machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1005 rtx x;
1007 x = gen_rtx_ROTATE (inner_mode,
1008 simplify_gen_unary (NOT, inner_mode, const1_rtx,
1009 inner_mode),
1010 XEXP (SUBREG_REG (op), 1));
1011 temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1012 if (temp)
1013 return temp;
1016 /* Apply De Morgan's laws to reduce number of patterns for machines
1017 with negating logical insns (and-not, nand, etc.). If result has
1018 only one NOT, put it first, since that is how the patterns are
1019 coded. */
1020 if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1022 rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1023 machine_mode op_mode;
1025 op_mode = GET_MODE (in1);
1026 in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1028 op_mode = GET_MODE (in2);
1029 if (op_mode == VOIDmode)
1030 op_mode = mode;
1031 in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1033 if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1034 std::swap (in1, in2);
1036 return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1037 mode, in1, in2);
1040 /* (not (bswap x)) -> (bswap (not x)). */
1041 if (GET_CODE (op) == BSWAP)
1043 rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1044 return simplify_gen_unary (BSWAP, mode, x, mode);
1046 break;
1048 case NEG:
1049 /* (neg (neg X)) == X. */
1050 if (GET_CODE (op) == NEG)
1051 return XEXP (op, 0);
1053 /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1054 If comparison is not reversible use
1055 x ? y : (neg y). */
1056 if (GET_CODE (op) == IF_THEN_ELSE)
1058 rtx cond = XEXP (op, 0);
1059 rtx true_rtx = XEXP (op, 1);
1060 rtx false_rtx = XEXP (op, 2);
1062 if ((GET_CODE (true_rtx) == NEG
1063 && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1064 || (GET_CODE (false_rtx) == NEG
1065 && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1067 if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1068 temp = reversed_comparison (cond, mode);
1069 else
1071 temp = cond;
1072 std::swap (true_rtx, false_rtx);
1074 return simplify_gen_ternary (IF_THEN_ELSE, mode,
1075 mode, temp, true_rtx, false_rtx);
1079 /* (neg (plus X 1)) can become (not X). */
1080 if (GET_CODE (op) == PLUS
1081 && XEXP (op, 1) == const1_rtx)
1082 return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1084 /* Similarly, (neg (not X)) is (plus X 1). */
1085 if (GET_CODE (op) == NOT)
1086 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1087 CONST1_RTX (mode));
1089 /* (neg (minus X Y)) can become (minus Y X). This transformation
1090 isn't safe for modes with signed zeros, since if X and Y are
1091 both +0, (minus Y X) is the same as (minus X Y). If the
1092 rounding mode is towards +infinity (or -infinity) then the two
1093 expressions will be rounded differently. */
1094 if (GET_CODE (op) == MINUS
1095 && !HONOR_SIGNED_ZEROS (mode)
1096 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1097 return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1099 if (GET_CODE (op) == PLUS
1100 && !HONOR_SIGNED_ZEROS (mode)
1101 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1103 /* (neg (plus A C)) is simplified to (minus -C A). */
1104 if (CONST_SCALAR_INT_P (XEXP (op, 1))
1105 || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1107 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1108 if (temp)
1109 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1112 /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1113 temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1114 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1117 /* (neg (mult A B)) becomes (mult A (neg B)).
1118 This works even for floating-point values. */
1119 if (GET_CODE (op) == MULT
1120 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1122 temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1123 return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1126 /* NEG commutes with ASHIFT since it is multiplication. Only do
1127 this if we can then eliminate the NEG (e.g., if the operand
1128 is a constant). */
1129 if (GET_CODE (op) == ASHIFT)
1131 temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1132 if (temp)
1133 return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1136 /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1137 C is equal to the width of MODE minus 1. */
1138 if (GET_CODE (op) == ASHIFTRT
1139 && CONST_INT_P (XEXP (op, 1))
1140 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1141 return simplify_gen_binary (LSHIFTRT, mode,
1142 XEXP (op, 0), XEXP (op, 1));
1144 /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1145 C is equal to the width of MODE minus 1. */
1146 if (GET_CODE (op) == LSHIFTRT
1147 && CONST_INT_P (XEXP (op, 1))
1148 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1149 return simplify_gen_binary (ASHIFTRT, mode,
1150 XEXP (op, 0), XEXP (op, 1));
1152 /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1153 if (GET_CODE (op) == XOR
1154 && XEXP (op, 1) == const1_rtx
1155 && nonzero_bits (XEXP (op, 0), mode) == 1)
1156 return plus_constant (mode, XEXP (op, 0), -1);
1158 /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1159 /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1160 if (GET_CODE (op) == LT
1161 && XEXP (op, 1) == const0_rtx
1162 && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1164 int_mode = as_a <scalar_int_mode> (mode);
1165 int isize = GET_MODE_PRECISION (inner);
1166 if (STORE_FLAG_VALUE == 1)
1168 temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1169 gen_int_shift_amount (inner,
1170 isize - 1));
1171 if (int_mode == inner)
1172 return temp;
1173 if (GET_MODE_PRECISION (int_mode) > isize)
1174 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1175 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1177 else if (STORE_FLAG_VALUE == -1)
1179 temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1180 gen_int_shift_amount (inner,
1181 isize - 1));
1182 if (int_mode == inner)
1183 return temp;
1184 if (GET_MODE_PRECISION (int_mode) > isize)
1185 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1186 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1190 if (vec_series_p (op, &base, &step))
1192 /* Only create a new series if we can simplify both parts. In other
1193 cases this isn't really a simplification, and it's not necessarily
1194 a win to replace a vector operation with a scalar operation. */
1195 scalar_mode inner_mode = GET_MODE_INNER (mode);
1196 base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1197 if (base)
1199 step = simplify_unary_operation (NEG, inner_mode,
1200 step, inner_mode);
1201 if (step)
1202 return gen_vec_series (mode, base, step);
1205 break;
1207 case TRUNCATE:
1208 /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1209 with the umulXi3_highpart patterns. */
1210 if (GET_CODE (op) == LSHIFTRT
1211 && GET_CODE (XEXP (op, 0)) == MULT)
1212 break;
1214 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1216 if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1218 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1219 if (temp)
1220 return temp;
1222 /* We can't handle truncation to a partial integer mode here
1223 because we don't know the real bitsize of the partial
1224 integer mode. */
1225 break;
1228 if (GET_MODE (op) != VOIDmode)
1230 temp = simplify_truncation (mode, op, GET_MODE (op));
1231 if (temp)
1232 return temp;
1235 /* If we know that the value is already truncated, we can
1236 replace the TRUNCATE with a SUBREG. */
1237 if (known_eq (GET_MODE_NUNITS (mode), 1)
1238 && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1239 || truncated_to_mode (mode, op)))
1241 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1242 if (temp)
1243 return temp;
1246 /* A truncate of a comparison can be replaced with a subreg if
1247 STORE_FLAG_VALUE permits. This is like the previous test,
1248 but it works even if the comparison is done in a mode larger
1249 than HOST_BITS_PER_WIDE_INT. */
1250 if (HWI_COMPUTABLE_MODE_P (mode)
1251 && COMPARISON_P (op)
1252 && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1253 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1255 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1256 if (temp)
1257 return temp;
1260 /* A truncate of a memory is just loading the low part of the memory
1261 if we are not changing the meaning of the address. */
1262 if (GET_CODE (op) == MEM
1263 && !VECTOR_MODE_P (mode)
1264 && !MEM_VOLATILE_P (op)
1265 && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1267 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1268 if (temp)
1269 return temp;
1272 /* Check for useless truncation. */
1273 if (GET_MODE (op) == mode)
1274 return op;
1275 break;
1277 case FLOAT_TRUNCATE:
1278 /* Check for useless truncation. */
1279 if (GET_MODE (op) == mode)
1280 return op;
1282 if (DECIMAL_FLOAT_MODE_P (mode))
1283 break;
1285 /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1286 if (GET_CODE (op) == FLOAT_EXTEND
1287 && GET_MODE (XEXP (op, 0)) == mode)
1288 return XEXP (op, 0);
1290 /* (float_truncate:SF (float_truncate:DF foo:XF))
1291 = (float_truncate:SF foo:XF).
1292 This may eliminate double rounding, so it is unsafe.
1294 (float_truncate:SF (float_extend:XF foo:DF))
1295 = (float_truncate:SF foo:DF).
1297 (float_truncate:DF (float_extend:XF foo:SF))
1298 = (float_extend:DF foo:SF). */
1299 if ((GET_CODE (op) == FLOAT_TRUNCATE
1300 && flag_unsafe_math_optimizations)
1301 || GET_CODE (op) == FLOAT_EXTEND)
1302 return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1303 > GET_MODE_UNIT_SIZE (mode)
1304 ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1305 mode,
1306 XEXP (op, 0), mode);
1308 /* (float_truncate (float x)) is (float x) */
1309 if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1310 && (flag_unsafe_math_optimizations
1311 || exact_int_to_float_conversion_p (op)))
1312 return simplify_gen_unary (GET_CODE (op), mode,
1313 XEXP (op, 0),
1314 GET_MODE (XEXP (op, 0)));
1316 /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1317 (OP:SF foo:SF) if OP is NEG or ABS. */
1318 if ((GET_CODE (op) == ABS
1319 || GET_CODE (op) == NEG)
1320 && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1321 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1322 return simplify_gen_unary (GET_CODE (op), mode,
1323 XEXP (XEXP (op, 0), 0), mode);
1325 /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1326 is (float_truncate:SF x). */
1327 if (GET_CODE (op) == SUBREG
1328 && subreg_lowpart_p (op)
1329 && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1330 return SUBREG_REG (op);
1331 break;
1333 case FLOAT_EXTEND:
1334 /* Check for useless extension. */
1335 if (GET_MODE (op) == mode)
1336 return op;
1338 if (DECIMAL_FLOAT_MODE_P (mode))
1339 break;
1341 /* (float_extend (float_extend x)) is (float_extend x)
1343 (float_extend (float x)) is (float x) assuming that double
1344 rounding can't happen.
1346 if (GET_CODE (op) == FLOAT_EXTEND
1347 || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1348 && exact_int_to_float_conversion_p (op)))
1349 return simplify_gen_unary (GET_CODE (op), mode,
1350 XEXP (op, 0),
1351 GET_MODE (XEXP (op, 0)));
1353 break;
1355 case ABS:
1356 /* (abs (neg <foo>)) -> (abs <foo>) */
1357 if (GET_CODE (op) == NEG)
1358 return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1359 GET_MODE (XEXP (op, 0)));
1361 /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1362 do nothing. */
1363 if (GET_MODE (op) == VOIDmode)
1364 break;
1366 /* If operand is something known to be positive, ignore the ABS. */
1367 if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
1368 || val_signbit_known_clear_p (GET_MODE (op),
1369 nonzero_bits (op, GET_MODE (op))))
1370 return op;
1372 /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1373 if (is_a <scalar_int_mode> (mode, &int_mode)
1374 && (num_sign_bit_copies (op, int_mode)
1375 == GET_MODE_PRECISION (int_mode)))
1376 return gen_rtx_NEG (int_mode, op);
1378 break;
1380 case FFS:
1381 /* (ffs (*_extend <X>)) = (ffs <X>) */
1382 if (GET_CODE (op) == SIGN_EXTEND
1383 || GET_CODE (op) == ZERO_EXTEND)
1384 return simplify_gen_unary (FFS, mode, XEXP (op, 0),
1385 GET_MODE (XEXP (op, 0)));
1386 break;
1388 case POPCOUNT:
1389 switch (GET_CODE (op))
1391 case BSWAP:
1392 case ZERO_EXTEND:
1393 /* (popcount (zero_extend <X>)) = (popcount <X>) */
1394 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1395 GET_MODE (XEXP (op, 0)));
1397 case ROTATE:
1398 case ROTATERT:
1399 /* Rotations don't affect popcount. */
1400 if (!side_effects_p (XEXP (op, 1)))
1401 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1402 GET_MODE (XEXP (op, 0)));
1403 break;
1405 default:
1406 break;
1408 break;
1410 case PARITY:
1411 switch (GET_CODE (op))
1413 case NOT:
1414 case BSWAP:
1415 case ZERO_EXTEND:
1416 case SIGN_EXTEND:
1417 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1418 GET_MODE (XEXP (op, 0)));
1420 case ROTATE:
1421 case ROTATERT:
1422 /* Rotations don't affect parity. */
1423 if (!side_effects_p (XEXP (op, 1)))
1424 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1425 GET_MODE (XEXP (op, 0)));
1426 break;
1428 case PARITY:
1429 /* (parity (parity x)) -> parity (x). */
1430 return op;
1432 default:
1433 break;
1435 break;
1437 case BSWAP:
1438 /* (bswap (bswap x)) -> x. */
1439 if (GET_CODE (op) == BSWAP)
1440 return XEXP (op, 0);
1441 break;
1443 case FLOAT:
1444 /* (float (sign_extend <X>)) = (float <X>). */
1445 if (GET_CODE (op) == SIGN_EXTEND)
1446 return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1447 GET_MODE (XEXP (op, 0)));
1448 break;
1450 case SIGN_EXTEND:
1451 /* Check for useless extension. */
1452 if (GET_MODE (op) == mode)
1453 return op;
1455 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1456 becomes just the MINUS if its mode is MODE. This allows
1457 folding switch statements on machines using casesi (such as
1458 the VAX). */
1459 if (GET_CODE (op) == TRUNCATE
1460 && GET_MODE (XEXP (op, 0)) == mode
1461 && GET_CODE (XEXP (op, 0)) == MINUS
1462 && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1463 && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1464 return XEXP (op, 0);
1466 /* Extending a widening multiplication should be canonicalized to
1467 a wider widening multiplication. */
1468 if (GET_CODE (op) == MULT)
1470 rtx lhs = XEXP (op, 0);
1471 rtx rhs = XEXP (op, 1);
1472 enum rtx_code lcode = GET_CODE (lhs);
1473 enum rtx_code rcode = GET_CODE (rhs);
1475 /* Widening multiplies usually extend both operands, but sometimes
1476 they use a shift to extract a portion of a register. */
1477 if ((lcode == SIGN_EXTEND
1478 || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1479 && (rcode == SIGN_EXTEND
1480 || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1482 machine_mode lmode = GET_MODE (lhs);
1483 machine_mode rmode = GET_MODE (rhs);
1484 int bits;
1486 if (lcode == ASHIFTRT)
1487 /* Number of bits not shifted off the end. */
1488 bits = (GET_MODE_UNIT_PRECISION (lmode)
1489 - INTVAL (XEXP (lhs, 1)));
1490 else /* lcode == SIGN_EXTEND */
1491 /* Size of inner mode. */
1492 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1494 if (rcode == ASHIFTRT)
1495 bits += (GET_MODE_UNIT_PRECISION (rmode)
1496 - INTVAL (XEXP (rhs, 1)));
1497 else /* rcode == SIGN_EXTEND */
1498 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1500 /* We can only widen multiplies if the result is mathematiclly
1501 equivalent. I.e. if overflow was impossible. */
1502 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1503 return simplify_gen_binary
1504 (MULT, mode,
1505 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1506 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1510 /* Check for a sign extension of a subreg of a promoted
1511 variable, where the promotion is sign-extended, and the
1512 target mode is the same as the variable's promotion. */
1513 if (GET_CODE (op) == SUBREG
1514 && SUBREG_PROMOTED_VAR_P (op)
1515 && SUBREG_PROMOTED_SIGNED_P (op))
1517 rtx subreg = SUBREG_REG (op);
1518 machine_mode subreg_mode = GET_MODE (subreg);
1519 if (!paradoxical_subreg_p (mode, subreg_mode))
1521 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1522 if (temp)
1524 /* Preserve SUBREG_PROMOTED_VAR_P. */
1525 if (partial_subreg_p (temp))
1527 SUBREG_PROMOTED_VAR_P (temp) = 1;
1528 SUBREG_PROMOTED_SET (temp, 1);
1530 return temp;
1533 else
1534 /* Sign-extending a sign-extended subreg. */
1535 return simplify_gen_unary (SIGN_EXTEND, mode,
1536 subreg, subreg_mode);
1539 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1540 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1541 if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1543 gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1544 > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1545 return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1546 GET_MODE (XEXP (op, 0)));
1549 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1550 is (sign_extend:M (subreg:O <X>)) if there is mode with
1551 GET_MODE_BITSIZE (N) - I bits.
1552 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1553 is similarly (zero_extend:M (subreg:O <X>)). */
1554 if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1555 && GET_CODE (XEXP (op, 0)) == ASHIFT
1556 && is_a <scalar_int_mode> (mode, &int_mode)
1557 && CONST_INT_P (XEXP (op, 1))
1558 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1559 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1560 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1562 scalar_int_mode tmode;
1563 gcc_assert (GET_MODE_PRECISION (int_mode)
1564 > GET_MODE_PRECISION (op_mode));
1565 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1566 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1568 rtx inner =
1569 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1570 if (inner)
1571 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1572 ? SIGN_EXTEND : ZERO_EXTEND,
1573 int_mode, inner, tmode);
1577 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1578 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1579 if (GET_CODE (op) == LSHIFTRT
1580 && CONST_INT_P (XEXP (op, 1))
1581 && XEXP (op, 1) != const0_rtx)
1582 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1584 /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1585 I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1586 (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1587 (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1588 O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1589 wider than O. */
1590 if (GET_CODE (op) == TRUNCATE
1591 && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1592 && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1594 scalar_int_mode m_mode, n_mode, o_mode;
1595 rtx old_shift = XEXP (op, 0);
1596 if (is_a <scalar_int_mode> (mode, &m_mode)
1597 && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1598 && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1599 && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1600 == INTVAL (XEXP (old_shift, 1)))
1602 rtx new_shift = simplify_gen_binary (ASHIFTRT,
1603 GET_MODE (old_shift),
1604 XEXP (old_shift, 0),
1605 XEXP (old_shift, 1));
1606 if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1607 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1608 GET_MODE (new_shift));
1609 if (mode != GET_MODE (new_shift))
1610 return simplify_gen_unary (TRUNCATE, mode, new_shift,
1611 GET_MODE (new_shift));
1612 return new_shift;
1616 #if defined(POINTERS_EXTEND_UNSIGNED)
1617 /* As we do not know which address space the pointer is referring to,
1618 we can do this only if the target does not support different pointer
1619 or address modes depending on the address space. */
1620 if (target_default_pointer_address_modes_p ()
1621 && ! POINTERS_EXTEND_UNSIGNED
1622 && mode == Pmode && GET_MODE (op) == ptr_mode
1623 && (CONSTANT_P (op)
1624 || (GET_CODE (op) == SUBREG
1625 && REG_P (SUBREG_REG (op))
1626 && REG_POINTER (SUBREG_REG (op))
1627 && GET_MODE (SUBREG_REG (op)) == Pmode))
1628 && !targetm.have_ptr_extend ())
1630 temp
1631 = convert_memory_address_addr_space_1 (Pmode, op,
1632 ADDR_SPACE_GENERIC, false,
1633 true);
1634 if (temp)
1635 return temp;
1637 #endif
1638 break;
1640 case ZERO_EXTEND:
1641 /* Check for useless extension. */
1642 if (GET_MODE (op) == mode)
1643 return op;
1645 /* Check for a zero extension of a subreg of a promoted
1646 variable, where the promotion is zero-extended, and the
1647 target mode is the same as the variable's promotion. */
1648 if (GET_CODE (op) == SUBREG
1649 && SUBREG_PROMOTED_VAR_P (op)
1650 && SUBREG_PROMOTED_UNSIGNED_P (op))
1652 rtx subreg = SUBREG_REG (op);
1653 machine_mode subreg_mode = GET_MODE (subreg);
1654 if (!paradoxical_subreg_p (mode, subreg_mode))
1656 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1657 if (temp)
1659 /* Preserve SUBREG_PROMOTED_VAR_P. */
1660 if (partial_subreg_p (temp))
1662 SUBREG_PROMOTED_VAR_P (temp) = 1;
1663 SUBREG_PROMOTED_SET (temp, 0);
1665 return temp;
1668 else
1669 /* Zero-extending a zero-extended subreg. */
1670 return simplify_gen_unary (ZERO_EXTEND, mode,
1671 subreg, subreg_mode);
1674 /* Extending a widening multiplication should be canonicalized to
1675 a wider widening multiplication. */
1676 if (GET_CODE (op) == MULT)
1678 rtx lhs = XEXP (op, 0);
1679 rtx rhs = XEXP (op, 1);
1680 enum rtx_code lcode = GET_CODE (lhs);
1681 enum rtx_code rcode = GET_CODE (rhs);
1683 /* Widening multiplies usually extend both operands, but sometimes
1684 they use a shift to extract a portion of a register. */
1685 if ((lcode == ZERO_EXTEND
1686 || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1687 && (rcode == ZERO_EXTEND
1688 || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1690 machine_mode lmode = GET_MODE (lhs);
1691 machine_mode rmode = GET_MODE (rhs);
1692 int bits;
1694 if (lcode == LSHIFTRT)
1695 /* Number of bits not shifted off the end. */
1696 bits = (GET_MODE_UNIT_PRECISION (lmode)
1697 - INTVAL (XEXP (lhs, 1)));
1698 else /* lcode == ZERO_EXTEND */
1699 /* Size of inner mode. */
1700 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1702 if (rcode == LSHIFTRT)
1703 bits += (GET_MODE_UNIT_PRECISION (rmode)
1704 - INTVAL (XEXP (rhs, 1)));
1705 else /* rcode == ZERO_EXTEND */
1706 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1708 /* We can only widen multiplies if the result is mathematiclly
1709 equivalent. I.e. if overflow was impossible. */
1710 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1711 return simplify_gen_binary
1712 (MULT, mode,
1713 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1714 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1718 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1719 if (GET_CODE (op) == ZERO_EXTEND)
1720 return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1721 GET_MODE (XEXP (op, 0)));
1723 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1724 is (zero_extend:M (subreg:O <X>)) if there is mode with
1725 GET_MODE_PRECISION (N) - I bits. */
1726 if (GET_CODE (op) == LSHIFTRT
1727 && GET_CODE (XEXP (op, 0)) == ASHIFT
1728 && is_a <scalar_int_mode> (mode, &int_mode)
1729 && CONST_INT_P (XEXP (op, 1))
1730 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1731 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1732 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1734 scalar_int_mode tmode;
1735 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1736 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1738 rtx inner =
1739 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1740 if (inner)
1741 return simplify_gen_unary (ZERO_EXTEND, int_mode,
1742 inner, tmode);
1746 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1747 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1748 of mode N. E.g.
1749 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1750 (and:SI (reg:SI) (const_int 63)). */
1751 if (partial_subreg_p (op)
1752 && is_a <scalar_int_mode> (mode, &int_mode)
1753 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1754 && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1755 && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1756 && subreg_lowpart_p (op)
1757 && (nonzero_bits (SUBREG_REG (op), op0_mode)
1758 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1760 if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1761 return SUBREG_REG (op);
1762 return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1763 op0_mode);
1766 #if defined(POINTERS_EXTEND_UNSIGNED)
1767 /* As we do not know which address space the pointer is referring to,
1768 we can do this only if the target does not support different pointer
1769 or address modes depending on the address space. */
1770 if (target_default_pointer_address_modes_p ()
1771 && POINTERS_EXTEND_UNSIGNED > 0
1772 && mode == Pmode && GET_MODE (op) == ptr_mode
1773 && (CONSTANT_P (op)
1774 || (GET_CODE (op) == SUBREG
1775 && REG_P (SUBREG_REG (op))
1776 && REG_POINTER (SUBREG_REG (op))
1777 && GET_MODE (SUBREG_REG (op)) == Pmode))
1778 && !targetm.have_ptr_extend ())
1780 temp
1781 = convert_memory_address_addr_space_1 (Pmode, op,
1782 ADDR_SPACE_GENERIC, false,
1783 true);
1784 if (temp)
1785 return temp;
1787 #endif
1788 break;
1790 default:
1791 break;
1794 if (VECTOR_MODE_P (mode)
1795 && vec_duplicate_p (op, &elt)
1796 && code != VEC_DUPLICATE)
1798 if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1799 /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1800 operations by promoting VEC_DUPLICATE to the root of the expression
1801 (as far as possible). */
1802 temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1803 elt, GET_MODE_INNER (GET_MODE (op)));
1804 else
1805 /* Try applying the operator to ELT and see if that simplifies.
1806 We can duplicate the result if so.
1808 The reason we traditionally haven't used simplify_gen_unary
1809 for these codes is that it didn't necessarily seem to be a
1810 win to convert things like:
1812 (neg:V (vec_duplicate:V (reg:S R)))
1816 (vec_duplicate:V (neg:S (reg:S R)))
1818 The first might be done entirely in vector registers while the
1819 second might need a move between register files.
1821 However, there also cases where promoting the vec_duplicate is
1822 more efficient, and there is definite value in having a canonical
1823 form when matching instruction patterns. We should consider
1824 extending the simplify_gen_unary code above to more cases. */
1825 temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1826 elt, GET_MODE_INNER (GET_MODE (op)));
1827 if (temp)
1828 return gen_vec_duplicate (mode, temp);
1831 return 0;
1834 /* Try to compute the value of a unary operation CODE whose output mode is to
1835 be MODE with input operand OP whose mode was originally OP_MODE.
1836 Return zero if the value cannot be computed. */
1838 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1839 rtx op, machine_mode op_mode)
1841 scalar_int_mode result_mode;
1843 if (code == VEC_DUPLICATE)
1845 gcc_assert (VECTOR_MODE_P (mode));
1846 if (GET_MODE (op) != VOIDmode)
1848 if (!VECTOR_MODE_P (GET_MODE (op)))
1849 gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1850 else
1851 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1852 (GET_MODE (op)));
1854 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1855 return gen_const_vec_duplicate (mode, op);
1856 if (GET_CODE (op) == CONST_VECTOR
1857 && (CONST_VECTOR_DUPLICATE_P (op)
1858 || CONST_VECTOR_NUNITS (op).is_constant ()))
1860 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1861 ? CONST_VECTOR_NPATTERNS (op)
1862 : CONST_VECTOR_NUNITS (op).to_constant ());
1863 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1864 rtx_vector_builder builder (mode, npatterns, 1);
1865 for (unsigned i = 0; i < npatterns; i++)
1866 builder.quick_push (CONST_VECTOR_ELT (op, i));
1867 return builder.build ();
1871 if (VECTOR_MODE_P (mode)
1872 && GET_CODE (op) == CONST_VECTOR
1873 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1875 gcc_assert (GET_MODE (op) == op_mode);
1877 rtx_vector_builder builder;
1878 if (!builder.new_unary_operation (mode, op, false))
1879 return 0;
1881 unsigned int count = builder.encoded_nelts ();
1882 for (unsigned int i = 0; i < count; i++)
1884 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1885 CONST_VECTOR_ELT (op, i),
1886 GET_MODE_INNER (op_mode));
1887 if (!x || !valid_for_const_vector_p (mode, x))
1888 return 0;
1889 builder.quick_push (x);
1891 return builder.build ();
1894 /* The order of these tests is critical so that, for example, we don't
1895 check the wrong mode (input vs. output) for a conversion operation,
1896 such as FIX. At some point, this should be simplified. */
1898 if (code == FLOAT && CONST_SCALAR_INT_P (op))
1900 REAL_VALUE_TYPE d;
1902 if (op_mode == VOIDmode)
1904 /* CONST_INT have VOIDmode as the mode. We assume that all
1905 the bits of the constant are significant, though, this is
1906 a dangerous assumption as many times CONST_INTs are
1907 created and used with garbage in the bits outside of the
1908 precision of the implied mode of the const_int. */
1909 op_mode = MAX_MODE_INT;
1912 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1914 /* Avoid the folding if flag_signaling_nans is on and
1915 operand is a signaling NaN. */
1916 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1917 return 0;
1919 d = real_value_truncate (mode, d);
1920 return const_double_from_real_value (d, mode);
1922 else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
1924 REAL_VALUE_TYPE d;
1926 if (op_mode == VOIDmode)
1928 /* CONST_INT have VOIDmode as the mode. We assume that all
1929 the bits of the constant are significant, though, this is
1930 a dangerous assumption as many times CONST_INTs are
1931 created and used with garbage in the bits outside of the
1932 precision of the implied mode of the const_int. */
1933 op_mode = MAX_MODE_INT;
1936 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
1938 /* Avoid the folding if flag_signaling_nans is on and
1939 operand is a signaling NaN. */
1940 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1941 return 0;
1943 d = real_value_truncate (mode, d);
1944 return const_double_from_real_value (d, mode);
1947 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
1949 unsigned int width = GET_MODE_PRECISION (result_mode);
1950 if (width > MAX_BITSIZE_MODE_ANY_INT)
1951 return 0;
1953 wide_int result;
1954 scalar_int_mode imode = (op_mode == VOIDmode
1955 ? result_mode
1956 : as_a <scalar_int_mode> (op_mode));
1957 rtx_mode_t op0 = rtx_mode_t (op, imode);
1958 int int_value;
1960 #if TARGET_SUPPORTS_WIDE_INT == 0
1961 /* This assert keeps the simplification from producing a result
1962 that cannot be represented in a CONST_DOUBLE but a lot of
1963 upstream callers expect that this function never fails to
1964 simplify something and so you if you added this to the test
1965 above the code would die later anyway. If this assert
1966 happens, you just need to make the port support wide int. */
1967 gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
1968 #endif
1970 switch (code)
1972 case NOT:
1973 result = wi::bit_not (op0);
1974 break;
1976 case NEG:
1977 result = wi::neg (op0);
1978 break;
1980 case ABS:
1981 result = wi::abs (op0);
1982 break;
1984 case FFS:
1985 result = wi::shwi (wi::ffs (op0), result_mode);
1986 break;
1988 case CLZ:
1989 if (wi::ne_p (op0, 0))
1990 int_value = wi::clz (op0);
1991 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1992 return NULL_RTX;
1993 result = wi::shwi (int_value, result_mode);
1994 break;
1996 case CLRSB:
1997 result = wi::shwi (wi::clrsb (op0), result_mode);
1998 break;
2000 case CTZ:
2001 if (wi::ne_p (op0, 0))
2002 int_value = wi::ctz (op0);
2003 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2004 return NULL_RTX;
2005 result = wi::shwi (int_value, result_mode);
2006 break;
2008 case POPCOUNT:
2009 result = wi::shwi (wi::popcount (op0), result_mode);
2010 break;
2012 case PARITY:
2013 result = wi::shwi (wi::parity (op0), result_mode);
2014 break;
2016 case BSWAP:
2017 result = wide_int (op0).bswap ();
2018 break;
2020 case TRUNCATE:
2021 case ZERO_EXTEND:
2022 result = wide_int::from (op0, width, UNSIGNED);
2023 break;
2025 case SIGN_EXTEND:
2026 result = wide_int::from (op0, width, SIGNED);
2027 break;
2029 case SQRT:
2030 default:
2031 return 0;
2034 return immed_wide_int_const (result, result_mode);
2037 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2038 && SCALAR_FLOAT_MODE_P (mode)
2039 && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2041 REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2042 switch (code)
2044 case SQRT:
2045 return 0;
2046 case ABS:
2047 d = real_value_abs (&d);
2048 break;
2049 case NEG:
2050 d = real_value_negate (&d);
2051 break;
2052 case FLOAT_TRUNCATE:
2053 /* Don't perform the operation if flag_signaling_nans is on
2054 and the operand is a signaling NaN. */
2055 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2056 return NULL_RTX;
2057 d = real_value_truncate (mode, d);
2058 break;
2059 case FLOAT_EXTEND:
2060 /* Don't perform the operation if flag_signaling_nans is on
2061 and the operand is a signaling NaN. */
2062 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2063 return NULL_RTX;
2064 /* All this does is change the mode, unless changing
2065 mode class. */
2066 if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2067 real_convert (&d, mode, &d);
2068 break;
2069 case FIX:
2070 /* Don't perform the operation if flag_signaling_nans is on
2071 and the operand is a signaling NaN. */
2072 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2073 return NULL_RTX;
2074 real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2075 break;
2076 case NOT:
2078 long tmp[4];
2079 int i;
2081 real_to_target (tmp, &d, GET_MODE (op));
2082 for (i = 0; i < 4; i++)
2083 tmp[i] = ~tmp[i];
2084 real_from_target (&d, tmp, mode);
2085 break;
2087 default:
2088 gcc_unreachable ();
2090 return const_double_from_real_value (d, mode);
2092 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2093 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2094 && is_int_mode (mode, &result_mode))
2096 unsigned int width = GET_MODE_PRECISION (result_mode);
2097 if (width > MAX_BITSIZE_MODE_ANY_INT)
2098 return 0;
2100 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2101 operators are intentionally left unspecified (to ease implementation
2102 by target backends), for consistency, this routine implements the
2103 same semantics for constant folding as used by the middle-end. */
2105 /* This was formerly used only for non-IEEE float.
2106 eggert@twinsun.com says it is safe for IEEE also. */
2107 REAL_VALUE_TYPE t;
2108 const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2109 wide_int wmax, wmin;
2110 /* This is part of the abi to real_to_integer, but we check
2111 things before making this call. */
2112 bool fail;
2114 switch (code)
2116 case FIX:
2117 if (REAL_VALUE_ISNAN (*x))
2118 return const0_rtx;
2120 /* Test against the signed upper bound. */
2121 wmax = wi::max_value (width, SIGNED);
2122 real_from_integer (&t, VOIDmode, wmax, SIGNED);
2123 if (real_less (&t, x))
2124 return immed_wide_int_const (wmax, mode);
2126 /* Test against the signed lower bound. */
2127 wmin = wi::min_value (width, SIGNED);
2128 real_from_integer (&t, VOIDmode, wmin, SIGNED);
2129 if (real_less (x, &t))
2130 return immed_wide_int_const (wmin, mode);
2132 return immed_wide_int_const (real_to_integer (x, &fail, width),
2133 mode);
2135 case UNSIGNED_FIX:
2136 if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2137 return const0_rtx;
2139 /* Test against the unsigned upper bound. */
2140 wmax = wi::max_value (width, UNSIGNED);
2141 real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2142 if (real_less (&t, x))
2143 return immed_wide_int_const (wmax, mode);
2145 return immed_wide_int_const (real_to_integer (x, &fail, width),
2146 mode);
2148 default:
2149 gcc_unreachable ();
2153 /* Handle polynomial integers. */
2154 else if (CONST_POLY_INT_P (op))
2156 poly_wide_int result;
2157 switch (code)
2159 case NEG:
2160 result = -const_poly_int_value (op);
2161 break;
2163 case NOT:
2164 result = ~const_poly_int_value (op);
2165 break;
2167 default:
2168 return NULL_RTX;
2170 return immed_wide_int_const (result, mode);
2173 return NULL_RTX;
2176 /* Subroutine of simplify_binary_operation to simplify a binary operation
2177 CODE that can commute with byte swapping, with result mode MODE and
2178 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2179 Return zero if no simplification or canonicalization is possible. */
2182 simplify_context::simplify_byte_swapping_operation (rtx_code code,
2183 machine_mode mode,
2184 rtx op0, rtx op1)
2186 rtx tem;
2188 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2189 if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2191 tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2192 simplify_gen_unary (BSWAP, mode, op1, mode));
2193 return simplify_gen_unary (BSWAP, mode, tem, mode);
2196 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2197 if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2199 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2200 return simplify_gen_unary (BSWAP, mode, tem, mode);
2203 return NULL_RTX;
2206 /* Subroutine of simplify_binary_operation to simplify a commutative,
2207 associative binary operation CODE with result mode MODE, operating
2208 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2209 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2210 canonicalization is possible. */
2213 simplify_context::simplify_associative_operation (rtx_code code,
2214 machine_mode mode,
2215 rtx op0, rtx op1)
2217 rtx tem;
2219 /* Linearize the operator to the left. */
2220 if (GET_CODE (op1) == code)
2222 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2223 if (GET_CODE (op0) == code)
2225 tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2226 return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2229 /* "a op (b op c)" becomes "(b op c) op a". */
2230 if (! swap_commutative_operands_p (op1, op0))
2231 return simplify_gen_binary (code, mode, op1, op0);
2233 std::swap (op0, op1);
2236 if (GET_CODE (op0) == code)
2238 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2239 if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2241 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2242 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2245 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2246 tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2247 if (tem != 0)
2248 return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2250 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2251 tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2252 if (tem != 0)
2253 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2256 return 0;
2259 /* Return a mask describing the COMPARISON. */
2260 static int
2261 comparison_to_mask (enum rtx_code comparison)
2263 switch (comparison)
2265 case LT:
2266 return 8;
2267 case GT:
2268 return 4;
2269 case EQ:
2270 return 2;
2271 case UNORDERED:
2272 return 1;
2274 case LTGT:
2275 return 12;
2276 case LE:
2277 return 10;
2278 case GE:
2279 return 6;
2280 case UNLT:
2281 return 9;
2282 case UNGT:
2283 return 5;
2284 case UNEQ:
2285 return 3;
2287 case ORDERED:
2288 return 14;
2289 case NE:
2290 return 13;
2291 case UNLE:
2292 return 11;
2293 case UNGE:
2294 return 7;
2296 default:
2297 gcc_unreachable ();
2301 /* Return a comparison corresponding to the MASK. */
2302 static enum rtx_code
2303 mask_to_comparison (int mask)
2305 switch (mask)
2307 case 8:
2308 return LT;
2309 case 4:
2310 return GT;
2311 case 2:
2312 return EQ;
2313 case 1:
2314 return UNORDERED;
2316 case 12:
2317 return LTGT;
2318 case 10:
2319 return LE;
2320 case 6:
2321 return GE;
2322 case 9:
2323 return UNLT;
2324 case 5:
2325 return UNGT;
2326 case 3:
2327 return UNEQ;
2329 case 14:
2330 return ORDERED;
2331 case 13:
2332 return NE;
2333 case 11:
2334 return UNLE;
2335 case 7:
2336 return UNGE;
2338 default:
2339 gcc_unreachable ();
2343 /* Return true if CODE is valid for comparisons of mode MODE, false
2344 otherwise.
2346 It is always safe to return false, even if the code was valid for the
2347 given mode as that will merely suppress optimizations. */
2349 static bool
2350 comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2352 switch (code)
2354 /* These are valid for integral, floating and vector modes. */
2355 case NE:
2356 case EQ:
2357 case GE:
2358 case GT:
2359 case LE:
2360 case LT:
2361 return (INTEGRAL_MODE_P (mode)
2362 || FLOAT_MODE_P (mode)
2363 || VECTOR_MODE_P (mode));
2365 /* These are valid for floating point modes. */
2366 case LTGT:
2367 case UNORDERED:
2368 case ORDERED:
2369 case UNEQ:
2370 case UNGE:
2371 case UNGT:
2372 case UNLE:
2373 case UNLT:
2374 return FLOAT_MODE_P (mode);
2376 /* These are filtered out in simplify_logical_operation, but
2377 we check for them too as a matter of safety. They are valid
2378 for integral and vector modes. */
2379 case GEU:
2380 case GTU:
2381 case LEU:
2382 case LTU:
2383 return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2385 default:
2386 gcc_unreachable ();
2390 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2391 false/true value of comparison with MODE where comparison operands
2392 have CMP_MODE. */
2394 static rtx
2395 relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2397 if (SCALAR_FLOAT_MODE_P (mode))
2399 if (res == const0_rtx)
2400 return CONST0_RTX (mode);
2401 #ifdef FLOAT_STORE_FLAG_VALUE
2402 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2403 return const_double_from_real_value (val, mode);
2404 #else
2405 return NULL_RTX;
2406 #endif
2408 if (VECTOR_MODE_P (mode))
2410 if (res == const0_rtx)
2411 return CONST0_RTX (mode);
2412 #ifdef VECTOR_STORE_FLAG_VALUE
2413 rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2414 if (val == NULL_RTX)
2415 return NULL_RTX;
2416 if (val == const1_rtx)
2417 return CONST1_RTX (mode);
2419 return gen_const_vec_duplicate (mode, val);
2420 #else
2421 return NULL_RTX;
2422 #endif
2424 /* For vector comparison with scalar int result, it is unknown
2425 if the target means here a comparison into an integral bitmask,
2426 or comparison where all comparisons true mean const_true_rtx
2427 whole result, or where any comparisons true mean const_true_rtx
2428 whole result. For const0_rtx all the cases are the same. */
2429 if (VECTOR_MODE_P (cmp_mode)
2430 && SCALAR_INT_MODE_P (mode)
2431 && res == const_true_rtx)
2432 return NULL_RTX;
2434 return res;
2437 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2438 and OP1, which should be both relational operations. Return 0 if no such
2439 simplification is possible. */
2441 simplify_context::simplify_logical_relational_operation (rtx_code code,
2442 machine_mode mode,
2443 rtx op0, rtx op1)
2445 /* We only handle IOR of two relational operations. */
2446 if (code != IOR)
2447 return 0;
2449 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2450 return 0;
2452 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2453 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2454 return 0;
2456 enum rtx_code code0 = GET_CODE (op0);
2457 enum rtx_code code1 = GET_CODE (op1);
2459 /* We don't handle unsigned comparisons currently. */
2460 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2461 return 0;
2462 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2463 return 0;
2465 int mask0 = comparison_to_mask (code0);
2466 int mask1 = comparison_to_mask (code1);
2468 int mask = mask0 | mask1;
2470 if (mask == 15)
2471 return relational_result (mode, GET_MODE (op0), const_true_rtx);
2473 code = mask_to_comparison (mask);
2475 /* Many comparison codes are only valid for certain mode classes. */
2476 if (!comparison_code_valid_for_mode (code, mode))
2477 return 0;
2479 op0 = XEXP (op1, 0);
2480 op1 = XEXP (op1, 1);
2482 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2485 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2486 and OP1. Return 0 if no simplification is possible.
2488 Don't use this for relational operations such as EQ or LT.
2489 Use simplify_relational_operation instead. */
2491 simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2492 rtx op0, rtx op1)
2494 rtx trueop0, trueop1;
2495 rtx tem;
2497 /* Relational operations don't work here. We must know the mode
2498 of the operands in order to do the comparison correctly.
2499 Assuming a full word can give incorrect results.
2500 Consider comparing 128 with -128 in QImode. */
2501 gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2502 gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2504 /* Make sure the constant is second. */
2505 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2506 && swap_commutative_operands_p (op0, op1))
2507 std::swap (op0, op1);
2509 trueop0 = avoid_constant_pool_reference (op0);
2510 trueop1 = avoid_constant_pool_reference (op1);
2512 tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2513 if (tem)
2514 return tem;
2515 tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2517 if (tem)
2518 return tem;
2520 /* If the above steps did not result in a simplification and op0 or op1
2521 were constant pool references, use the referenced constants directly. */
2522 if (trueop0 != op0 || trueop1 != op1)
2523 return simplify_gen_binary (code, mode, trueop0, trueop1);
2525 return NULL_RTX;
2528 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2529 which OP0 and OP1 are both vector series or vector duplicates
2530 (which are really just series with a step of 0). If so, try to
2531 form a new series by applying CODE to the bases and to the steps.
2532 Return null if no simplification is possible.
2534 MODE is the mode of the operation and is known to be a vector
2535 integer mode. */
2538 simplify_context::simplify_binary_operation_series (rtx_code code,
2539 machine_mode mode,
2540 rtx op0, rtx op1)
2542 rtx base0, step0;
2543 if (vec_duplicate_p (op0, &base0))
2544 step0 = const0_rtx;
2545 else if (!vec_series_p (op0, &base0, &step0))
2546 return NULL_RTX;
2548 rtx base1, step1;
2549 if (vec_duplicate_p (op1, &base1))
2550 step1 = const0_rtx;
2551 else if (!vec_series_p (op1, &base1, &step1))
2552 return NULL_RTX;
2554 /* Only create a new series if we can simplify both parts. In other
2555 cases this isn't really a simplification, and it's not necessarily
2556 a win to replace a vector operation with a scalar operation. */
2557 scalar_mode inner_mode = GET_MODE_INNER (mode);
2558 rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2559 if (!new_base)
2560 return NULL_RTX;
2562 rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2563 if (!new_step)
2564 return NULL_RTX;
2566 return gen_vec_series (mode, new_base, new_step);
2569 /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2570 operation CODE with result mode MODE, operating on OP0 and OP1.
2571 e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2572 Returns NULL_RTX if no simplification is possible. */
2575 simplify_context::simplify_distributive_operation (rtx_code code,
2576 machine_mode mode,
2577 rtx op0, rtx op1)
2579 enum rtx_code op = GET_CODE (op0);
2580 gcc_assert (GET_CODE (op1) == op);
2582 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2583 && ! side_effects_p (XEXP (op0, 1)))
2584 return simplify_gen_binary (op, mode,
2585 simplify_gen_binary (code, mode,
2586 XEXP (op0, 0),
2587 XEXP (op1, 0)),
2588 XEXP (op0, 1));
2590 if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2592 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2593 && ! side_effects_p (XEXP (op0, 0)))
2594 return simplify_gen_binary (op, mode,
2595 simplify_gen_binary (code, mode,
2596 XEXP (op0, 1),
2597 XEXP (op1, 1)),
2598 XEXP (op0, 0));
2599 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2600 && ! side_effects_p (XEXP (op0, 0)))
2601 return simplify_gen_binary (op, mode,
2602 simplify_gen_binary (code, mode,
2603 XEXP (op0, 1),
2604 XEXP (op1, 0)),
2605 XEXP (op0, 0));
2606 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2607 && ! side_effects_p (XEXP (op0, 1)))
2608 return simplify_gen_binary (op, mode,
2609 simplify_gen_binary (code, mode,
2610 XEXP (op0, 0),
2611 XEXP (op1, 1)),
2612 XEXP (op0, 1));
2615 return NULL_RTX;
2618 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2619 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2620 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2621 actual constants. */
2624 simplify_context::simplify_binary_operation_1 (rtx_code code,
2625 machine_mode mode,
2626 rtx op0, rtx op1,
2627 rtx trueop0, rtx trueop1)
2629 rtx tem, reversed, opleft, opright, elt0, elt1;
2630 HOST_WIDE_INT val;
2631 scalar_int_mode int_mode, inner_mode;
2632 poly_int64 offset;
2634 /* Even if we can't compute a constant result,
2635 there are some cases worth simplifying. */
2637 switch (code)
2639 case PLUS:
2640 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2641 when x is NaN, infinite, or finite and nonzero. They aren't
2642 when x is -0 and the rounding mode is not towards -infinity,
2643 since (-0) + 0 is then 0. */
2644 if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2645 return op0;
2647 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2648 transformations are safe even for IEEE. */
2649 if (GET_CODE (op0) == NEG)
2650 return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2651 else if (GET_CODE (op1) == NEG)
2652 return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2654 /* (~a) + 1 -> -a */
2655 if (INTEGRAL_MODE_P (mode)
2656 && GET_CODE (op0) == NOT
2657 && trueop1 == const1_rtx)
2658 return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2660 /* Handle both-operands-constant cases. We can only add
2661 CONST_INTs to constants since the sum of relocatable symbols
2662 can't be handled by most assemblers. Don't add CONST_INT
2663 to CONST_INT since overflow won't be computed properly if wider
2664 than HOST_BITS_PER_WIDE_INT. */
2666 if ((GET_CODE (op0) == CONST
2667 || GET_CODE (op0) == SYMBOL_REF
2668 || GET_CODE (op0) == LABEL_REF)
2669 && poly_int_rtx_p (op1, &offset))
2670 return plus_constant (mode, op0, offset);
2671 else if ((GET_CODE (op1) == CONST
2672 || GET_CODE (op1) == SYMBOL_REF
2673 || GET_CODE (op1) == LABEL_REF)
2674 && poly_int_rtx_p (op0, &offset))
2675 return plus_constant (mode, op1, offset);
2677 /* See if this is something like X * C - X or vice versa or
2678 if the multiplication is written as a shift. If so, we can
2679 distribute and make a new multiply, shift, or maybe just
2680 have X (if C is 2 in the example above). But don't make
2681 something more expensive than we had before. */
2683 if (is_a <scalar_int_mode> (mode, &int_mode))
2685 rtx lhs = op0, rhs = op1;
2687 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2688 wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2690 if (GET_CODE (lhs) == NEG)
2692 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2693 lhs = XEXP (lhs, 0);
2695 else if (GET_CODE (lhs) == MULT
2696 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2698 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2699 lhs = XEXP (lhs, 0);
2701 else if (GET_CODE (lhs) == ASHIFT
2702 && CONST_INT_P (XEXP (lhs, 1))
2703 && INTVAL (XEXP (lhs, 1)) >= 0
2704 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2706 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2707 GET_MODE_PRECISION (int_mode));
2708 lhs = XEXP (lhs, 0);
2711 if (GET_CODE (rhs) == NEG)
2713 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2714 rhs = XEXP (rhs, 0);
2716 else if (GET_CODE (rhs) == MULT
2717 && CONST_INT_P (XEXP (rhs, 1)))
2719 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2720 rhs = XEXP (rhs, 0);
2722 else if (GET_CODE (rhs) == ASHIFT
2723 && CONST_INT_P (XEXP (rhs, 1))
2724 && INTVAL (XEXP (rhs, 1)) >= 0
2725 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2727 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2728 GET_MODE_PRECISION (int_mode));
2729 rhs = XEXP (rhs, 0);
2732 if (rtx_equal_p (lhs, rhs))
2734 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2735 rtx coeff;
2736 bool speed = optimize_function_for_speed_p (cfun);
2738 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2740 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2741 return (set_src_cost (tem, int_mode, speed)
2742 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2745 /* Optimize (X - 1) * Y + Y to X * Y. */
2746 lhs = op0;
2747 rhs = op1;
2748 if (GET_CODE (op0) == MULT)
2750 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2751 && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
2752 || (GET_CODE (XEXP (op0, 0)) == MINUS
2753 && XEXP (XEXP (op0, 0), 1) == const1_rtx))
2754 && rtx_equal_p (XEXP (op0, 1), op1))
2755 lhs = XEXP (XEXP (op0, 0), 0);
2756 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2757 && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
2758 || (GET_CODE (XEXP (op0, 1)) == MINUS
2759 && XEXP (XEXP (op0, 1), 1) == const1_rtx))
2760 && rtx_equal_p (XEXP (op0, 0), op1))
2761 lhs = XEXP (XEXP (op0, 1), 0);
2763 else if (GET_CODE (op1) == MULT)
2765 if (((GET_CODE (XEXP (op1, 0)) == PLUS
2766 && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
2767 || (GET_CODE (XEXP (op1, 0)) == MINUS
2768 && XEXP (XEXP (op1, 0), 1) == const1_rtx))
2769 && rtx_equal_p (XEXP (op1, 1), op0))
2770 rhs = XEXP (XEXP (op1, 0), 0);
2771 else if (((GET_CODE (XEXP (op1, 1)) == PLUS
2772 && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
2773 || (GET_CODE (XEXP (op1, 1)) == MINUS
2774 && XEXP (XEXP (op1, 1), 1) == const1_rtx))
2775 && rtx_equal_p (XEXP (op1, 0), op0))
2776 rhs = XEXP (XEXP (op1, 1), 0);
2778 if (lhs != op0 || rhs != op1)
2779 return simplify_gen_binary (MULT, int_mode, lhs, rhs);
2782 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2783 if (CONST_SCALAR_INT_P (op1)
2784 && GET_CODE (op0) == XOR
2785 && CONST_SCALAR_INT_P (XEXP (op0, 1))
2786 && mode_signbit_p (mode, op1))
2787 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2788 simplify_gen_binary (XOR, mode, op1,
2789 XEXP (op0, 1)));
2791 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2792 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2793 && GET_CODE (op0) == MULT
2794 && GET_CODE (XEXP (op0, 0)) == NEG)
2796 rtx in1, in2;
2798 in1 = XEXP (XEXP (op0, 0), 0);
2799 in2 = XEXP (op0, 1);
2800 return simplify_gen_binary (MINUS, mode, op1,
2801 simplify_gen_binary (MULT, mode,
2802 in1, in2));
2805 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2806 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2807 is 1. */
2808 if (COMPARISON_P (op0)
2809 && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2810 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2811 && (reversed = reversed_comparison (op0, mode)))
2812 return
2813 simplify_gen_unary (NEG, mode, reversed, mode);
2815 /* If one of the operands is a PLUS or a MINUS, see if we can
2816 simplify this by the associative law.
2817 Don't use the associative law for floating point.
2818 The inaccuracy makes it nonassociative,
2819 and subtle programs can break if operations are associated. */
2821 if (INTEGRAL_MODE_P (mode)
2822 && (plus_minus_operand_p (op0)
2823 || plus_minus_operand_p (op1))
2824 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2825 return tem;
2827 /* Reassociate floating point addition only when the user
2828 specifies associative math operations. */
2829 if (FLOAT_MODE_P (mode)
2830 && flag_associative_math)
2832 tem = simplify_associative_operation (code, mode, op0, op1);
2833 if (tem)
2834 return tem;
2837 /* Handle vector series. */
2838 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2840 tem = simplify_binary_operation_series (code, mode, op0, op1);
2841 if (tem)
2842 return tem;
2844 break;
2846 case COMPARE:
2847 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
2848 if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
2849 || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
2850 && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
2852 rtx xop00 = XEXP (op0, 0);
2853 rtx xop10 = XEXP (op1, 0);
2855 if (REG_P (xop00) && REG_P (xop10)
2856 && REGNO (xop00) == REGNO (xop10)
2857 && GET_MODE (xop00) == mode
2858 && GET_MODE (xop10) == mode
2859 && GET_MODE_CLASS (mode) == MODE_CC)
2860 return xop00;
2862 break;
2864 case MINUS:
2865 /* We can't assume x-x is 0 even with non-IEEE floating point,
2866 but since it is zero except in very strange circumstances, we
2867 will treat it as zero with -ffinite-math-only. */
2868 if (rtx_equal_p (trueop0, trueop1)
2869 && ! side_effects_p (op0)
2870 && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
2871 return CONST0_RTX (mode);
2873 /* Change subtraction from zero into negation. (0 - x) is the
2874 same as -x when x is NaN, infinite, or finite and nonzero.
2875 But if the mode has signed zeros, and does not round towards
2876 -infinity, then 0 - 0 is 0, not -0. */
2877 if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
2878 return simplify_gen_unary (NEG, mode, op1, mode);
2880 /* (-1 - a) is ~a, unless the expression contains symbolic
2881 constants, in which case not retaining additions and
2882 subtractions could cause invalid assembly to be produced. */
2883 if (trueop0 == constm1_rtx
2884 && !contains_symbolic_reference_p (op1))
2885 return simplify_gen_unary (NOT, mode, op1, mode);
2887 /* Subtracting 0 has no effect unless the mode has signalling NaNs,
2888 or has signed zeros and supports rounding towards -infinity.
2889 In such a case, 0 - 0 is -0. */
2890 if (!(HONOR_SIGNED_ZEROS (mode)
2891 && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2892 && !HONOR_SNANS (mode)
2893 && trueop1 == CONST0_RTX (mode))
2894 return op0;
2896 /* See if this is something like X * C - X or vice versa or
2897 if the multiplication is written as a shift. If so, we can
2898 distribute and make a new multiply, shift, or maybe just
2899 have X (if C is 2 in the example above). But don't make
2900 something more expensive than we had before. */
2902 if (is_a <scalar_int_mode> (mode, &int_mode))
2904 rtx lhs = op0, rhs = op1;
2906 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2907 wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2909 if (GET_CODE (lhs) == NEG)
2911 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2912 lhs = XEXP (lhs, 0);
2914 else if (GET_CODE (lhs) == MULT
2915 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2917 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2918 lhs = XEXP (lhs, 0);
2920 else if (GET_CODE (lhs) == ASHIFT
2921 && CONST_INT_P (XEXP (lhs, 1))
2922 && INTVAL (XEXP (lhs, 1)) >= 0
2923 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2925 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2926 GET_MODE_PRECISION (int_mode));
2927 lhs = XEXP (lhs, 0);
2930 if (GET_CODE (rhs) == NEG)
2932 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2933 rhs = XEXP (rhs, 0);
2935 else if (GET_CODE (rhs) == MULT
2936 && CONST_INT_P (XEXP (rhs, 1)))
2938 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
2939 rhs = XEXP (rhs, 0);
2941 else if (GET_CODE (rhs) == ASHIFT
2942 && CONST_INT_P (XEXP (rhs, 1))
2943 && INTVAL (XEXP (rhs, 1)) >= 0
2944 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2946 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2947 GET_MODE_PRECISION (int_mode));
2948 negcoeff1 = -negcoeff1;
2949 rhs = XEXP (rhs, 0);
2952 if (rtx_equal_p (lhs, rhs))
2954 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
2955 rtx coeff;
2956 bool speed = optimize_function_for_speed_p (cfun);
2958 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
2960 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2961 return (set_src_cost (tem, int_mode, speed)
2962 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2965 /* Optimize (X + 1) * Y - Y to X * Y. */
2966 lhs = op0;
2967 if (GET_CODE (op0) == MULT)
2969 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2970 && XEXP (XEXP (op0, 0), 1) == const1_rtx)
2971 || (GET_CODE (XEXP (op0, 0)) == MINUS
2972 && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
2973 && rtx_equal_p (XEXP (op0, 1), op1))
2974 lhs = XEXP (XEXP (op0, 0), 0);
2975 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2976 && XEXP (XEXP (op0, 1), 1) == const1_rtx)
2977 || (GET_CODE (XEXP (op0, 1)) == MINUS
2978 && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
2979 && rtx_equal_p (XEXP (op0, 0), op1))
2980 lhs = XEXP (XEXP (op0, 1), 0);
2982 if (lhs != op0)
2983 return simplify_gen_binary (MULT, int_mode, lhs, op1);
2986 /* (a - (-b)) -> (a + b). True even for IEEE. */
2987 if (GET_CODE (op1) == NEG)
2988 return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
2990 /* (-x - c) may be simplified as (-c - x). */
2991 if (GET_CODE (op0) == NEG
2992 && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
2994 tem = simplify_unary_operation (NEG, mode, op1, mode);
2995 if (tem)
2996 return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
2999 if ((GET_CODE (op0) == CONST
3000 || GET_CODE (op0) == SYMBOL_REF
3001 || GET_CODE (op0) == LABEL_REF)
3002 && poly_int_rtx_p (op1, &offset))
3003 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3005 /* Don't let a relocatable value get a negative coeff. */
3006 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
3007 return simplify_gen_binary (PLUS, mode,
3008 op0,
3009 neg_poly_int_rtx (mode, op1));
3011 /* (x - (x & y)) -> (x & ~y) */
3012 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3014 if (rtx_equal_p (op0, XEXP (op1, 0)))
3016 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3017 GET_MODE (XEXP (op1, 1)));
3018 return simplify_gen_binary (AND, mode, op0, tem);
3020 if (rtx_equal_p (op0, XEXP (op1, 1)))
3022 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3023 GET_MODE (XEXP (op1, 0)));
3024 return simplify_gen_binary (AND, mode, op0, tem);
3028 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3029 by reversing the comparison code if valid. */
3030 if (STORE_FLAG_VALUE == 1
3031 && trueop0 == const1_rtx
3032 && COMPARISON_P (op1)
3033 && (reversed = reversed_comparison (op1, mode)))
3034 return reversed;
3036 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3037 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3038 && GET_CODE (op1) == MULT
3039 && GET_CODE (XEXP (op1, 0)) == NEG)
3041 rtx in1, in2;
3043 in1 = XEXP (XEXP (op1, 0), 0);
3044 in2 = XEXP (op1, 1);
3045 return simplify_gen_binary (PLUS, mode,
3046 simplify_gen_binary (MULT, mode,
3047 in1, in2),
3048 op0);
3051 /* Canonicalize (minus (neg A) (mult B C)) to
3052 (minus (mult (neg B) C) A). */
3053 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3054 && GET_CODE (op1) == MULT
3055 && GET_CODE (op0) == NEG)
3057 rtx in1, in2;
3059 in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3060 in2 = XEXP (op1, 1);
3061 return simplify_gen_binary (MINUS, mode,
3062 simplify_gen_binary (MULT, mode,
3063 in1, in2),
3064 XEXP (op0, 0));
3067 /* If one of the operands is a PLUS or a MINUS, see if we can
3068 simplify this by the associative law. This will, for example,
3069 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3070 Don't use the associative law for floating point.
3071 The inaccuracy makes it nonassociative,
3072 and subtle programs can break if operations are associated. */
3074 if (INTEGRAL_MODE_P (mode)
3075 && (plus_minus_operand_p (op0)
3076 || plus_minus_operand_p (op1))
3077 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3078 return tem;
3080 /* Handle vector series. */
3081 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3083 tem = simplify_binary_operation_series (code, mode, op0, op1);
3084 if (tem)
3085 return tem;
3087 break;
3089 case MULT:
3090 if (trueop1 == constm1_rtx)
3091 return simplify_gen_unary (NEG, mode, op0, mode);
3093 if (GET_CODE (op0) == NEG)
3095 rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3096 /* If op1 is a MULT as well and simplify_unary_operation
3097 just moved the NEG to the second operand, simplify_gen_binary
3098 below could through simplify_associative_operation move
3099 the NEG around again and recurse endlessly. */
3100 if (temp
3101 && GET_CODE (op1) == MULT
3102 && GET_CODE (temp) == MULT
3103 && XEXP (op1, 0) == XEXP (temp, 0)
3104 && GET_CODE (XEXP (temp, 1)) == NEG
3105 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3106 temp = NULL_RTX;
3107 if (temp)
3108 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3110 if (GET_CODE (op1) == NEG)
3112 rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3113 /* If op0 is a MULT as well and simplify_unary_operation
3114 just moved the NEG to the second operand, simplify_gen_binary
3115 below could through simplify_associative_operation move
3116 the NEG around again and recurse endlessly. */
3117 if (temp
3118 && GET_CODE (op0) == MULT
3119 && GET_CODE (temp) == MULT
3120 && XEXP (op0, 0) == XEXP (temp, 0)
3121 && GET_CODE (XEXP (temp, 1)) == NEG
3122 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3123 temp = NULL_RTX;
3124 if (temp)
3125 return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3128 /* Maybe simplify x * 0 to 0. The reduction is not valid if
3129 x is NaN, since x * 0 is then also NaN. Nor is it valid
3130 when the mode has signed zeros, since multiplying a negative
3131 number by 0 will give -0, not 0. */
3132 if (!HONOR_NANS (mode)
3133 && !HONOR_SIGNED_ZEROS (mode)
3134 && trueop1 == CONST0_RTX (mode)
3135 && ! side_effects_p (op0))
3136 return op1;
3138 /* In IEEE floating point, x*1 is not equivalent to x for
3139 signalling NaNs. */
3140 if (!HONOR_SNANS (mode)
3141 && trueop1 == CONST1_RTX (mode))
3142 return op0;
3144 /* Convert multiply by constant power of two into shift. */
3145 if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3147 val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3148 if (val >= 0)
3149 return simplify_gen_binary (ASHIFT, mode, op0,
3150 gen_int_shift_amount (mode, val));
3153 /* x*2 is x+x and x*(-1) is -x */
3154 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3155 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3156 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3157 && GET_MODE (op0) == mode)
3159 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3161 if (real_equal (d1, &dconst2))
3162 return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3164 if (!HONOR_SNANS (mode)
3165 && real_equal (d1, &dconstm1))
3166 return simplify_gen_unary (NEG, mode, op0, mode);
3169 /* Optimize -x * -x as x * x. */
3170 if (FLOAT_MODE_P (mode)
3171 && GET_CODE (op0) == NEG
3172 && GET_CODE (op1) == NEG
3173 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3174 && !side_effects_p (XEXP (op0, 0)))
3175 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3177 /* Likewise, optimize abs(x) * abs(x) as x * x. */
3178 if (SCALAR_FLOAT_MODE_P (mode)
3179 && GET_CODE (op0) == ABS
3180 && GET_CODE (op1) == ABS
3181 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3182 && !side_effects_p (XEXP (op0, 0)))
3183 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3185 /* Reassociate multiplication, but for floating point MULTs
3186 only when the user specifies unsafe math optimizations. */
3187 if (! FLOAT_MODE_P (mode)
3188 || flag_unsafe_math_optimizations)
3190 tem = simplify_associative_operation (code, mode, op0, op1);
3191 if (tem)
3192 return tem;
3194 break;
3196 case IOR:
3197 if (trueop1 == CONST0_RTX (mode))
3198 return op0;
3199 if (INTEGRAL_MODE_P (mode)
3200 && trueop1 == CONSTM1_RTX (mode)
3201 && !side_effects_p (op0))
3202 return op1;
3203 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3204 return op0;
3205 /* A | (~A) -> -1 */
3206 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3207 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3208 && ! side_effects_p (op0)
3209 && SCALAR_INT_MODE_P (mode))
3210 return constm1_rtx;
3212 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3213 if (CONST_INT_P (op1)
3214 && HWI_COMPUTABLE_MODE_P (mode)
3215 && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3216 && !side_effects_p (op0))
3217 return op1;
3219 /* Canonicalize (X & C1) | C2. */
3220 if (GET_CODE (op0) == AND
3221 && CONST_INT_P (trueop1)
3222 && CONST_INT_P (XEXP (op0, 1)))
3224 HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3225 HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3226 HOST_WIDE_INT c2 = INTVAL (trueop1);
3228 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3229 if ((c1 & c2) == c1
3230 && !side_effects_p (XEXP (op0, 0)))
3231 return trueop1;
3233 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3234 if (((c1|c2) & mask) == mask)
3235 return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3238 /* Convert (A & B) | A to A. */
3239 if (GET_CODE (op0) == AND
3240 && (rtx_equal_p (XEXP (op0, 0), op1)
3241 || rtx_equal_p (XEXP (op0, 1), op1))
3242 && ! side_effects_p (XEXP (op0, 0))
3243 && ! side_effects_p (XEXP (op0, 1)))
3244 return op1;
3246 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3247 mode size to (rotate A CX). */
3249 if (GET_CODE (op1) == ASHIFT
3250 || GET_CODE (op1) == SUBREG)
3252 opleft = op1;
3253 opright = op0;
3255 else
3257 opright = op1;
3258 opleft = op0;
3261 if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3262 && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3263 && CONST_INT_P (XEXP (opleft, 1))
3264 && CONST_INT_P (XEXP (opright, 1))
3265 && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3266 == GET_MODE_UNIT_PRECISION (mode)))
3267 return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3269 /* Same, but for ashift that has been "simplified" to a wider mode
3270 by simplify_shift_const. */
3272 if (GET_CODE (opleft) == SUBREG
3273 && is_a <scalar_int_mode> (mode, &int_mode)
3274 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3275 &inner_mode)
3276 && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3277 && GET_CODE (opright) == LSHIFTRT
3278 && GET_CODE (XEXP (opright, 0)) == SUBREG
3279 && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3280 && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3281 && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3282 SUBREG_REG (XEXP (opright, 0)))
3283 && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3284 && CONST_INT_P (XEXP (opright, 1))
3285 && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3286 + INTVAL (XEXP (opright, 1))
3287 == GET_MODE_PRECISION (int_mode)))
3288 return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3289 XEXP (SUBREG_REG (opleft), 1));
3291 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3292 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3293 the PLUS does not affect any of the bits in OP1: then we can do
3294 the IOR as a PLUS and we can associate. This is valid if OP1
3295 can be safely shifted left C bits. */
3296 if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3297 && GET_CODE (XEXP (op0, 0)) == PLUS
3298 && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3299 && CONST_INT_P (XEXP (op0, 1))
3300 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3302 int count = INTVAL (XEXP (op0, 1));
3303 HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3305 if (mask >> count == INTVAL (trueop1)
3306 && trunc_int_for_mode (mask, mode) == mask
3307 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3308 return simplify_gen_binary (ASHIFTRT, mode,
3309 plus_constant (mode, XEXP (op0, 0),
3310 mask),
3311 XEXP (op0, 1));
3314 /* The following happens with bitfield merging.
3315 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3316 if (GET_CODE (op0) == AND
3317 && GET_CODE (op1) == AND
3318 && CONST_INT_P (XEXP (op0, 1))
3319 && CONST_INT_P (XEXP (op1, 1))
3320 && (INTVAL (XEXP (op0, 1))
3321 == ~INTVAL (XEXP (op1, 1))))
3323 /* The IOR may be on both sides. */
3324 rtx top0 = NULL_RTX, top1 = NULL_RTX;
3325 if (GET_CODE (XEXP (op1, 0)) == IOR)
3326 top0 = op0, top1 = op1;
3327 else if (GET_CODE (XEXP (op0, 0)) == IOR)
3328 top0 = op1, top1 = op0;
3329 if (top0 && top1)
3331 /* X may be on either side of the inner IOR. */
3332 rtx tem = NULL_RTX;
3333 if (rtx_equal_p (XEXP (top0, 0),
3334 XEXP (XEXP (top1, 0), 0)))
3335 tem = XEXP (XEXP (top1, 0), 1);
3336 else if (rtx_equal_p (XEXP (top0, 0),
3337 XEXP (XEXP (top1, 0), 1)))
3338 tem = XEXP (XEXP (top1, 0), 0);
3339 if (tem)
3340 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3341 simplify_gen_binary
3342 (AND, mode, tem, XEXP (top1, 1)));
3346 /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3347 if (GET_CODE (op0) == GET_CODE (op1)
3348 && (GET_CODE (op0) == AND
3349 || GET_CODE (op0) == IOR
3350 || GET_CODE (op0) == LSHIFTRT
3351 || GET_CODE (op0) == ASHIFTRT
3352 || GET_CODE (op0) == ASHIFT
3353 || GET_CODE (op0) == ROTATE
3354 || GET_CODE (op0) == ROTATERT))
3356 tem = simplify_distributive_operation (code, mode, op0, op1);
3357 if (tem)
3358 return tem;
3361 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3362 if (tem)
3363 return tem;
3365 tem = simplify_associative_operation (code, mode, op0, op1);
3366 if (tem)
3367 return tem;
3369 tem = simplify_logical_relational_operation (code, mode, op0, op1);
3370 if (tem)
3371 return tem;
3372 break;
3374 case XOR:
3375 if (trueop1 == CONST0_RTX (mode))
3376 return op0;
3377 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3378 return simplify_gen_unary (NOT, mode, op0, mode);
3379 if (rtx_equal_p (trueop0, trueop1)
3380 && ! side_effects_p (op0)
3381 && GET_MODE_CLASS (mode) != MODE_CC)
3382 return CONST0_RTX (mode);
3384 /* Canonicalize XOR of the most significant bit to PLUS. */
3385 if (CONST_SCALAR_INT_P (op1)
3386 && mode_signbit_p (mode, op1))
3387 return simplify_gen_binary (PLUS, mode, op0, op1);
3388 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3389 if (CONST_SCALAR_INT_P (op1)
3390 && GET_CODE (op0) == PLUS
3391 && CONST_SCALAR_INT_P (XEXP (op0, 1))
3392 && mode_signbit_p (mode, XEXP (op0, 1)))
3393 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3394 simplify_gen_binary (XOR, mode, op1,
3395 XEXP (op0, 1)));
3397 /* If we are XORing two things that have no bits in common,
3398 convert them into an IOR. This helps to detect rotation encoded
3399 using those methods and possibly other simplifications. */
3401 if (HWI_COMPUTABLE_MODE_P (mode)
3402 && (nonzero_bits (op0, mode)
3403 & nonzero_bits (op1, mode)) == 0)
3404 return (simplify_gen_binary (IOR, mode, op0, op1));
3406 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3407 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3408 (NOT y). */
3410 int num_negated = 0;
3412 if (GET_CODE (op0) == NOT)
3413 num_negated++, op0 = XEXP (op0, 0);
3414 if (GET_CODE (op1) == NOT)
3415 num_negated++, op1 = XEXP (op1, 0);
3417 if (num_negated == 2)
3418 return simplify_gen_binary (XOR, mode, op0, op1);
3419 else if (num_negated == 1)
3420 return simplify_gen_unary (NOT, mode,
3421 simplify_gen_binary (XOR, mode, op0, op1),
3422 mode);
3425 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3426 correspond to a machine insn or result in further simplifications
3427 if B is a constant. */
3429 if (GET_CODE (op0) == AND
3430 && rtx_equal_p (XEXP (op0, 1), op1)
3431 && ! side_effects_p (op1))
3432 return simplify_gen_binary (AND, mode,
3433 simplify_gen_unary (NOT, mode,
3434 XEXP (op0, 0), mode),
3435 op1);
3437 else if (GET_CODE (op0) == AND
3438 && rtx_equal_p (XEXP (op0, 0), op1)
3439 && ! side_effects_p (op1))
3440 return simplify_gen_binary (AND, mode,
3441 simplify_gen_unary (NOT, mode,
3442 XEXP (op0, 1), mode),
3443 op1);
3445 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3446 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3447 out bits inverted twice and not set by C. Similarly, given
3448 (xor (and (xor A B) C) D), simplify without inverting C in
3449 the xor operand: (xor (and A C) (B&C)^D).
3451 else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3452 && GET_CODE (XEXP (op0, 0)) == XOR
3453 && CONST_INT_P (op1)
3454 && CONST_INT_P (XEXP (op0, 1))
3455 && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3457 enum rtx_code op = GET_CODE (op0);
3458 rtx a = XEXP (XEXP (op0, 0), 0);
3459 rtx b = XEXP (XEXP (op0, 0), 1);
3460 rtx c = XEXP (op0, 1);
3461 rtx d = op1;
3462 HOST_WIDE_INT bval = INTVAL (b);
3463 HOST_WIDE_INT cval = INTVAL (c);
3464 HOST_WIDE_INT dval = INTVAL (d);
3465 HOST_WIDE_INT xcval;
3467 if (op == IOR)
3468 xcval = ~cval;
3469 else
3470 xcval = cval;
3472 return simplify_gen_binary (XOR, mode,
3473 simplify_gen_binary (op, mode, a, c),
3474 gen_int_mode ((bval & xcval) ^ dval,
3475 mode));
3478 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3479 we can transform like this:
3480 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3481 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3482 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3483 Attempt a few simplifications when B and C are both constants. */
3484 if (GET_CODE (op0) == AND
3485 && CONST_INT_P (op1)
3486 && CONST_INT_P (XEXP (op0, 1)))
3488 rtx a = XEXP (op0, 0);
3489 rtx b = XEXP (op0, 1);
3490 rtx c = op1;
3491 HOST_WIDE_INT bval = INTVAL (b);
3492 HOST_WIDE_INT cval = INTVAL (c);
3494 /* Instead of computing ~A&C, we compute its negated value,
3495 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3496 optimize for sure. If it does not simplify, we still try
3497 to compute ~A&C below, but since that always allocates
3498 RTL, we don't try that before committing to returning a
3499 simplified expression. */
3500 rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3501 GEN_INT (~cval));
3503 if ((~cval & bval) == 0)
3505 rtx na_c = NULL_RTX;
3506 if (n_na_c)
3507 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3508 else
3510 /* If ~A does not simplify, don't bother: we don't
3511 want to simplify 2 operations into 3, and if na_c
3512 were to simplify with na, n_na_c would have
3513 simplified as well. */
3514 rtx na = simplify_unary_operation (NOT, mode, a, mode);
3515 if (na)
3516 na_c = simplify_gen_binary (AND, mode, na, c);
3519 /* Try to simplify ~A&C | ~B&C. */
3520 if (na_c != NULL_RTX)
3521 return simplify_gen_binary (IOR, mode, na_c,
3522 gen_int_mode (~bval & cval, mode));
3524 else
3526 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3527 if (n_na_c == CONSTM1_RTX (mode))
3529 rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3530 gen_int_mode (~cval & bval,
3531 mode));
3532 return simplify_gen_binary (IOR, mode, a_nc_b,
3533 gen_int_mode (~bval & cval,
3534 mode));
3539 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3540 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3541 machines, and also has shorter instruction path length. */
3542 if (GET_CODE (op0) == AND
3543 && GET_CODE (XEXP (op0, 0)) == XOR
3544 && CONST_INT_P (XEXP (op0, 1))
3545 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3547 rtx a = trueop1;
3548 rtx b = XEXP (XEXP (op0, 0), 1);
3549 rtx c = XEXP (op0, 1);
3550 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3551 rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3552 rtx bc = simplify_gen_binary (AND, mode, b, c);
3553 return simplify_gen_binary (IOR, mode, a_nc, bc);
3555 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3556 else if (GET_CODE (op0) == AND
3557 && GET_CODE (XEXP (op0, 0)) == XOR
3558 && CONST_INT_P (XEXP (op0, 1))
3559 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3561 rtx a = XEXP (XEXP (op0, 0), 0);
3562 rtx b = trueop1;
3563 rtx c = XEXP (op0, 1);
3564 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3565 rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3566 rtx ac = simplify_gen_binary (AND, mode, a, c);
3567 return simplify_gen_binary (IOR, mode, ac, b_nc);
3570 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3571 comparison if STORE_FLAG_VALUE is 1. */
3572 if (STORE_FLAG_VALUE == 1
3573 && trueop1 == const1_rtx
3574 && COMPARISON_P (op0)
3575 && (reversed = reversed_comparison (op0, mode)))
3576 return reversed;
3578 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3579 is (lt foo (const_int 0)), so we can perform the above
3580 simplification if STORE_FLAG_VALUE is 1. */
3582 if (is_a <scalar_int_mode> (mode, &int_mode)
3583 && STORE_FLAG_VALUE == 1
3584 && trueop1 == const1_rtx
3585 && GET_CODE (op0) == LSHIFTRT
3586 && CONST_INT_P (XEXP (op0, 1))
3587 && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3588 return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3590 /* (xor (comparison foo bar) (const_int sign-bit))
3591 when STORE_FLAG_VALUE is the sign bit. */
3592 if (is_a <scalar_int_mode> (mode, &int_mode)
3593 && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3594 && trueop1 == const_true_rtx
3595 && COMPARISON_P (op0)
3596 && (reversed = reversed_comparison (op0, int_mode)))
3597 return reversed;
3599 /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3600 if (GET_CODE (op0) == GET_CODE (op1)
3601 && (GET_CODE (op0) == AND
3602 || GET_CODE (op0) == LSHIFTRT
3603 || GET_CODE (op0) == ASHIFTRT
3604 || GET_CODE (op0) == ASHIFT
3605 || GET_CODE (op0) == ROTATE
3606 || GET_CODE (op0) == ROTATERT))
3608 tem = simplify_distributive_operation (code, mode, op0, op1);
3609 if (tem)
3610 return tem;
3613 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3614 if (tem)
3615 return tem;
3617 tem = simplify_associative_operation (code, mode, op0, op1);
3618 if (tem)
3619 return tem;
3620 break;
3622 case AND:
3623 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3624 return trueop1;
3625 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3626 return op0;
3627 if (HWI_COMPUTABLE_MODE_P (mode))
3629 HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
3630 HOST_WIDE_INT nzop1;
3631 if (CONST_INT_P (trueop1))
3633 HOST_WIDE_INT val1 = INTVAL (trueop1);
3634 /* If we are turning off bits already known off in OP0, we need
3635 not do an AND. */
3636 if ((nzop0 & ~val1) == 0)
3637 return op0;
3639 nzop1 = nonzero_bits (trueop1, mode);
3640 /* If we are clearing all the nonzero bits, the result is zero. */
3641 if ((nzop1 & nzop0) == 0
3642 && !side_effects_p (op0) && !side_effects_p (op1))
3643 return CONST0_RTX (mode);
3645 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3646 && GET_MODE_CLASS (mode) != MODE_CC)
3647 return op0;
3648 /* A & (~A) -> 0 */
3649 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3650 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3651 && ! side_effects_p (op0)
3652 && GET_MODE_CLASS (mode) != MODE_CC)
3653 return CONST0_RTX (mode);
3655 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3656 there are no nonzero bits of C outside of X's mode. */
3657 if ((GET_CODE (op0) == SIGN_EXTEND
3658 || GET_CODE (op0) == ZERO_EXTEND)
3659 && CONST_INT_P (trueop1)
3660 && HWI_COMPUTABLE_MODE_P (mode)
3661 && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
3662 & UINTVAL (trueop1)) == 0)
3664 machine_mode imode = GET_MODE (XEXP (op0, 0));
3665 tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
3666 gen_int_mode (INTVAL (trueop1),
3667 imode));
3668 return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3671 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3672 we might be able to further simplify the AND with X and potentially
3673 remove the truncation altogether. */
3674 if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3676 rtx x = XEXP (op0, 0);
3677 machine_mode xmode = GET_MODE (x);
3678 tem = simplify_gen_binary (AND, xmode, x,
3679 gen_int_mode (INTVAL (trueop1), xmode));
3680 return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3683 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3684 if (GET_CODE (op0) == IOR
3685 && CONST_INT_P (trueop1)
3686 && CONST_INT_P (XEXP (op0, 1)))
3688 HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3689 return simplify_gen_binary (IOR, mode,
3690 simplify_gen_binary (AND, mode,
3691 XEXP (op0, 0), op1),
3692 gen_int_mode (tmp, mode));
3695 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3696 insn (and may simplify more). */
3697 if (GET_CODE (op0) == XOR
3698 && rtx_equal_p (XEXP (op0, 0), op1)
3699 && ! side_effects_p (op1))
3700 return simplify_gen_binary (AND, mode,
3701 simplify_gen_unary (NOT, mode,
3702 XEXP (op0, 1), mode),
3703 op1);
3705 if (GET_CODE (op0) == XOR
3706 && rtx_equal_p (XEXP (op0, 1), op1)
3707 && ! side_effects_p (op1))
3708 return simplify_gen_binary (AND, mode,
3709 simplify_gen_unary (NOT, mode,
3710 XEXP (op0, 0), mode),
3711 op1);
3713 /* Similarly for (~(A ^ B)) & A. */
3714 if (GET_CODE (op0) == NOT
3715 && GET_CODE (XEXP (op0, 0)) == XOR
3716 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3717 && ! side_effects_p (op1))
3718 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3720 if (GET_CODE (op0) == NOT
3721 && GET_CODE (XEXP (op0, 0)) == XOR
3722 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3723 && ! side_effects_p (op1))
3724 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3726 /* Convert (A | B) & A to A. */
3727 if (GET_CODE (op0) == IOR
3728 && (rtx_equal_p (XEXP (op0, 0), op1)
3729 || rtx_equal_p (XEXP (op0, 1), op1))
3730 && ! side_effects_p (XEXP (op0, 0))
3731 && ! side_effects_p (XEXP (op0, 1)))
3732 return op1;
3734 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3735 ((A & N) + B) & M -> (A + B) & M
3736 Similarly if (N & M) == 0,
3737 ((A | N) + B) & M -> (A + B) & M
3738 and for - instead of + and/or ^ instead of |.
3739 Also, if (N & M) == 0, then
3740 (A +- N) & M -> A & M. */
3741 if (CONST_INT_P (trueop1)
3742 && HWI_COMPUTABLE_MODE_P (mode)
3743 && ~UINTVAL (trueop1)
3744 && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3745 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3747 rtx pmop[2];
3748 int which;
3750 pmop[0] = XEXP (op0, 0);
3751 pmop[1] = XEXP (op0, 1);
3753 if (CONST_INT_P (pmop[1])
3754 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3755 return simplify_gen_binary (AND, mode, pmop[0], op1);
3757 for (which = 0; which < 2; which++)
3759 tem = pmop[which];
3760 switch (GET_CODE (tem))
3762 case AND:
3763 if (CONST_INT_P (XEXP (tem, 1))
3764 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3765 == UINTVAL (trueop1))
3766 pmop[which] = XEXP (tem, 0);
3767 break;
3768 case IOR:
3769 case XOR:
3770 if (CONST_INT_P (XEXP (tem, 1))
3771 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3772 pmop[which] = XEXP (tem, 0);
3773 break;
3774 default:
3775 break;
3779 if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3781 tem = simplify_gen_binary (GET_CODE (op0), mode,
3782 pmop[0], pmop[1]);
3783 return simplify_gen_binary (code, mode, tem, op1);
3787 /* (and X (ior (not X) Y) -> (and X Y) */
3788 if (GET_CODE (op1) == IOR
3789 && GET_CODE (XEXP (op1, 0)) == NOT
3790 && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3791 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3793 /* (and (ior (not X) Y) X) -> (and X Y) */
3794 if (GET_CODE (op0) == IOR
3795 && GET_CODE (XEXP (op0, 0)) == NOT
3796 && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3797 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3799 /* (and X (ior Y (not X)) -> (and X Y) */
3800 if (GET_CODE (op1) == IOR
3801 && GET_CODE (XEXP (op1, 1)) == NOT
3802 && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3803 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3805 /* (and (ior Y (not X)) X) -> (and X Y) */
3806 if (GET_CODE (op0) == IOR
3807 && GET_CODE (XEXP (op0, 1)) == NOT
3808 && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3809 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3811 /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
3812 if (GET_CODE (op0) == GET_CODE (op1)
3813 && (GET_CODE (op0) == AND
3814 || GET_CODE (op0) == IOR
3815 || GET_CODE (op0) == LSHIFTRT
3816 || GET_CODE (op0) == ASHIFTRT
3817 || GET_CODE (op0) == ASHIFT
3818 || GET_CODE (op0) == ROTATE
3819 || GET_CODE (op0) == ROTATERT))
3821 tem = simplify_distributive_operation (code, mode, op0, op1);
3822 if (tem)
3823 return tem;
3826 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3827 if (tem)
3828 return tem;
3830 tem = simplify_associative_operation (code, mode, op0, op1);
3831 if (tem)
3832 return tem;
3833 break;
3835 case UDIV:
3836 /* 0/x is 0 (or x&0 if x has side-effects). */
3837 if (trueop0 == CONST0_RTX (mode)
3838 && !cfun->can_throw_non_call_exceptions)
3840 if (side_effects_p (op1))
3841 return simplify_gen_binary (AND, mode, op1, trueop0);
3842 return trueop0;
3844 /* x/1 is x. */
3845 if (trueop1 == CONST1_RTX (mode))
3847 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3848 if (tem)
3849 return tem;
3851 /* Convert divide by power of two into shift. */
3852 if (CONST_INT_P (trueop1)
3853 && (val = exact_log2 (UINTVAL (trueop1))) > 0)
3854 return simplify_gen_binary (LSHIFTRT, mode, op0,
3855 gen_int_shift_amount (mode, val));
3856 break;
3858 case DIV:
3859 /* Handle floating point and integers separately. */
3860 if (SCALAR_FLOAT_MODE_P (mode))
3862 /* Maybe change 0.0 / x to 0.0. This transformation isn't
3863 safe for modes with NaNs, since 0.0 / 0.0 will then be
3864 NaN rather than 0.0. Nor is it safe for modes with signed
3865 zeros, since dividing 0 by a negative number gives -0.0 */
3866 if (trueop0 == CONST0_RTX (mode)
3867 && !HONOR_NANS (mode)
3868 && !HONOR_SIGNED_ZEROS (mode)
3869 && ! side_effects_p (op1))
3870 return op0;
3871 /* x/1.0 is x. */
3872 if (trueop1 == CONST1_RTX (mode)
3873 && !HONOR_SNANS (mode))
3874 return op0;
3876 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3877 && trueop1 != CONST0_RTX (mode))
3879 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3881 /* x/-1.0 is -x. */
3882 if (real_equal (d1, &dconstm1)
3883 && !HONOR_SNANS (mode))
3884 return simplify_gen_unary (NEG, mode, op0, mode);
3886 /* Change FP division by a constant into multiplication.
3887 Only do this with -freciprocal-math. */
3888 if (flag_reciprocal_math
3889 && !real_equal (d1, &dconst0))
3891 REAL_VALUE_TYPE d;
3892 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
3893 tem = const_double_from_real_value (d, mode);
3894 return simplify_gen_binary (MULT, mode, op0, tem);
3898 else if (SCALAR_INT_MODE_P (mode))
3900 /* 0/x is 0 (or x&0 if x has side-effects). */
3901 if (trueop0 == CONST0_RTX (mode)
3902 && !cfun->can_throw_non_call_exceptions)
3904 if (side_effects_p (op1))
3905 return simplify_gen_binary (AND, mode, op1, trueop0);
3906 return trueop0;
3908 /* x/1 is x. */
3909 if (trueop1 == CONST1_RTX (mode))
3911 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3912 if (tem)
3913 return tem;
3915 /* x/-1 is -x. */
3916 if (trueop1 == constm1_rtx)
3918 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3919 if (x)
3920 return simplify_gen_unary (NEG, mode, x, mode);
3923 break;
3925 case UMOD:
3926 /* 0%x is 0 (or x&0 if x has side-effects). */
3927 if (trueop0 == CONST0_RTX (mode))
3929 if (side_effects_p (op1))
3930 return simplify_gen_binary (AND, mode, op1, trueop0);
3931 return trueop0;
3933 /* x%1 is 0 (of x&0 if x has side-effects). */
3934 if (trueop1 == CONST1_RTX (mode))
3936 if (side_effects_p (op0))
3937 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3938 return CONST0_RTX (mode);
3940 /* Implement modulus by power of two as AND. */
3941 if (CONST_INT_P (trueop1)
3942 && exact_log2 (UINTVAL (trueop1)) > 0)
3943 return simplify_gen_binary (AND, mode, op0,
3944 gen_int_mode (UINTVAL (trueop1) - 1,
3945 mode));
3946 break;
3948 case MOD:
3949 /* 0%x is 0 (or x&0 if x has side-effects). */
3950 if (trueop0 == CONST0_RTX (mode))
3952 if (side_effects_p (op1))
3953 return simplify_gen_binary (AND, mode, op1, trueop0);
3954 return trueop0;
3956 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
3957 if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
3959 if (side_effects_p (op0))
3960 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3961 return CONST0_RTX (mode);
3963 break;
3965 case ROTATERT:
3966 case ROTATE:
3967 if (trueop1 == CONST0_RTX (mode))
3968 return op0;
3969 /* Canonicalize rotates by constant amount. If op1 is bitsize / 2,
3970 prefer left rotation, if op1 is from bitsize / 2 + 1 to
3971 bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
3972 amount instead. */
3973 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
3974 if (CONST_INT_P (trueop1)
3975 && IN_RANGE (INTVAL (trueop1),
3976 GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
3977 GET_MODE_UNIT_PRECISION (mode) - 1))
3979 int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
3980 rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
3981 return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
3982 mode, op0, new_amount_rtx);
3984 #endif
3985 /* FALLTHRU */
3986 case ASHIFTRT:
3987 if (trueop1 == CONST0_RTX (mode))
3988 return op0;
3989 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3990 return op0;
3991 /* Rotating ~0 always results in ~0. */
3992 if (CONST_INT_P (trueop0)
3993 && HWI_COMPUTABLE_MODE_P (mode)
3994 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
3995 && ! side_effects_p (op1))
3996 return op0;
3998 canonicalize_shift:
3999 /* Given:
4000 scalar modes M1, M2
4001 scalar constants c1, c2
4002 size (M2) > size (M1)
4003 c1 == size (M2) - size (M1)
4004 optimize:
4005 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4006 <low_part>)
4007 (const_int <c2>))
4009 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4010 <low_part>). */
4011 if ((code == ASHIFTRT || code == LSHIFTRT)
4012 && is_a <scalar_int_mode> (mode, &int_mode)
4013 && SUBREG_P (op0)
4014 && CONST_INT_P (op1)
4015 && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4016 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4017 &inner_mode)
4018 && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4019 && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4020 && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4021 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4022 && subreg_lowpart_p (op0))
4024 rtx tmp = gen_int_shift_amount
4025 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4027 /* Combine would usually zero out the value when combining two
4028 local shifts and the range becomes larger or equal to the mode.
4029 However since we fold away one of the shifts here combine won't
4030 see it so we should immediately zero the result if it's out of
4031 range. */
4032 if (code == LSHIFTRT
4033 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4034 tmp = const0_rtx;
4035 else
4036 tmp = simplify_gen_binary (code,
4037 inner_mode,
4038 XEXP (SUBREG_REG (op0), 0),
4039 tmp);
4041 return lowpart_subreg (int_mode, tmp, inner_mode);
4044 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4046 val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4047 if (val != INTVAL (op1))
4048 return simplify_gen_binary (code, mode, op0,
4049 gen_int_shift_amount (mode, val));
4051 break;
4053 case ASHIFT:
4054 case SS_ASHIFT:
4055 case US_ASHIFT:
4056 if (trueop1 == CONST0_RTX (mode))
4057 return op0;
4058 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4059 return op0;
4060 if (mem_depth
4061 && code == ASHIFT
4062 && CONST_INT_P (trueop1)
4063 && is_a <scalar_int_mode> (mode, &int_mode)
4064 && IN_RANGE (UINTVAL (trueop1),
4065 1, GET_MODE_PRECISION (int_mode) - 1))
4067 auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4068 << UINTVAL (trueop1));
4069 rtx new_op1 = immed_wide_int_const (c, int_mode);
4070 return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4072 goto canonicalize_shift;
4074 case LSHIFTRT:
4075 if (trueop1 == CONST0_RTX (mode))
4076 return op0;
4077 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4078 return op0;
4079 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4080 if (GET_CODE (op0) == CLZ
4081 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4082 && CONST_INT_P (trueop1)
4083 && STORE_FLAG_VALUE == 1
4084 && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4086 unsigned HOST_WIDE_INT zero_val = 0;
4088 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4089 && zero_val == GET_MODE_PRECISION (inner_mode)
4090 && INTVAL (trueop1) == exact_log2 (zero_val))
4091 return simplify_gen_relational (EQ, mode, inner_mode,
4092 XEXP (op0, 0), const0_rtx);
4094 goto canonicalize_shift;
4096 case SMIN:
4097 if (HWI_COMPUTABLE_MODE_P (mode)
4098 && mode_signbit_p (mode, trueop1)
4099 && ! side_effects_p (op0))
4100 return op1;
4101 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4102 return op0;
4103 tem = simplify_associative_operation (code, mode, op0, op1);
4104 if (tem)
4105 return tem;
4106 break;
4108 case SMAX:
4109 if (HWI_COMPUTABLE_MODE_P (mode)
4110 && CONST_INT_P (trueop1)
4111 && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4112 && ! side_effects_p (op0))
4113 return op1;
4114 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4115 return op0;
4116 tem = simplify_associative_operation (code, mode, op0, op1);
4117 if (tem)
4118 return tem;
4119 break;
4121 case UMIN:
4122 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4123 return op1;
4124 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4125 return op0;
4126 tem = simplify_associative_operation (code, mode, op0, op1);
4127 if (tem)
4128 return tem;
4129 break;
4131 case UMAX:
4132 if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4133 return op1;
4134 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4135 return op0;
4136 tem = simplify_associative_operation (code, mode, op0, op1);
4137 if (tem)
4138 return tem;
4139 break;
4141 case SS_PLUS:
4142 case US_PLUS:
4143 case SS_MINUS:
4144 case US_MINUS:
4145 case SS_MULT:
4146 case US_MULT:
4147 case SS_DIV:
4148 case US_DIV:
4149 /* ??? There are simplifications that can be done. */
4150 return 0;
4152 case VEC_SERIES:
4153 if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4154 return gen_vec_duplicate (mode, op0);
4155 if (valid_for_const_vector_p (mode, op0)
4156 && valid_for_const_vector_p (mode, op1))
4157 return gen_const_vec_series (mode, op0, op1);
4158 return 0;
4160 case VEC_SELECT:
4161 if (!VECTOR_MODE_P (mode))
4163 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4164 gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4165 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4166 gcc_assert (XVECLEN (trueop1, 0) == 1);
4168 /* We can't reason about selections made at runtime. */
4169 if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4170 return 0;
4172 if (vec_duplicate_p (trueop0, &elt0))
4173 return elt0;
4175 if (GET_CODE (trueop0) == CONST_VECTOR)
4176 return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4177 (trueop1, 0, 0)));
4179 /* Extract a scalar element from a nested VEC_SELECT expression
4180 (with optional nested VEC_CONCAT expression). Some targets
4181 (i386) extract scalar element from a vector using chain of
4182 nested VEC_SELECT expressions. When input operand is a memory
4183 operand, this operation can be simplified to a simple scalar
4184 load from an offseted memory address. */
4185 int n_elts;
4186 if (GET_CODE (trueop0) == VEC_SELECT
4187 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4188 .is_constant (&n_elts)))
4190 rtx op0 = XEXP (trueop0, 0);
4191 rtx op1 = XEXP (trueop0, 1);
4193 int i = INTVAL (XVECEXP (trueop1, 0, 0));
4194 int elem;
4196 rtvec vec;
4197 rtx tmp_op, tmp;
4199 gcc_assert (GET_CODE (op1) == PARALLEL);
4200 gcc_assert (i < n_elts);
4202 /* Select element, pointed by nested selector. */
4203 elem = INTVAL (XVECEXP (op1, 0, i));
4205 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4206 if (GET_CODE (op0) == VEC_CONCAT)
4208 rtx op00 = XEXP (op0, 0);
4209 rtx op01 = XEXP (op0, 1);
4211 machine_mode mode00, mode01;
4212 int n_elts00, n_elts01;
4214 mode00 = GET_MODE (op00);
4215 mode01 = GET_MODE (op01);
4217 /* Find out the number of elements of each operand.
4218 Since the concatenated result has a constant number
4219 of elements, the operands must too. */
4220 n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4221 n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4223 gcc_assert (n_elts == n_elts00 + n_elts01);
4225 /* Select correct operand of VEC_CONCAT
4226 and adjust selector. */
4227 if (elem < n_elts01)
4228 tmp_op = op00;
4229 else
4231 tmp_op = op01;
4232 elem -= n_elts00;
4235 else
4236 tmp_op = op0;
4238 vec = rtvec_alloc (1);
4239 RTVEC_ELT (vec, 0) = GEN_INT (elem);
4241 tmp = gen_rtx_fmt_ee (code, mode,
4242 tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
4243 return tmp;
4246 else
4248 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4249 gcc_assert (GET_MODE_INNER (mode)
4250 == GET_MODE_INNER (GET_MODE (trueop0)));
4251 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4253 if (vec_duplicate_p (trueop0, &elt0))
4254 /* It doesn't matter which elements are selected by trueop1,
4255 because they are all the same. */
4256 return gen_vec_duplicate (mode, elt0);
4258 if (GET_CODE (trueop0) == CONST_VECTOR)
4260 unsigned n_elts = XVECLEN (trueop1, 0);
4261 rtvec v = rtvec_alloc (n_elts);
4262 unsigned int i;
4264 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4265 for (i = 0; i < n_elts; i++)
4267 rtx x = XVECEXP (trueop1, 0, i);
4269 if (!CONST_INT_P (x))
4270 return 0;
4272 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
4273 INTVAL (x));
4276 return gen_rtx_CONST_VECTOR (mode, v);
4279 /* Recognize the identity. */
4280 if (GET_MODE (trueop0) == mode)
4282 bool maybe_ident = true;
4283 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4285 rtx j = XVECEXP (trueop1, 0, i);
4286 if (!CONST_INT_P (j) || INTVAL (j) != i)
4288 maybe_ident = false;
4289 break;
4292 if (maybe_ident)
4293 return trueop0;
4296 /* If we select a low-part subreg, return that. */
4297 if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
4299 rtx new_rtx = lowpart_subreg (mode, trueop0,
4300 GET_MODE (trueop0));
4301 if (new_rtx != NULL_RTX)
4302 return new_rtx;
4305 /* If we build {a,b} then permute it, build the result directly. */
4306 if (XVECLEN (trueop1, 0) == 2
4307 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4308 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4309 && GET_CODE (trueop0) == VEC_CONCAT
4310 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4311 && GET_MODE (XEXP (trueop0, 0)) == mode
4312 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4313 && GET_MODE (XEXP (trueop0, 1)) == mode)
4315 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4316 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4317 rtx subop0, subop1;
4319 gcc_assert (i0 < 4 && i1 < 4);
4320 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4321 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4323 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4326 if (XVECLEN (trueop1, 0) == 2
4327 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4328 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4329 && GET_CODE (trueop0) == VEC_CONCAT
4330 && GET_MODE (trueop0) == mode)
4332 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4333 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4334 rtx subop0, subop1;
4336 gcc_assert (i0 < 2 && i1 < 2);
4337 subop0 = XEXP (trueop0, i0);
4338 subop1 = XEXP (trueop0, i1);
4340 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4343 /* If we select one half of a vec_concat, return that. */
4344 int l0, l1;
4345 if (GET_CODE (trueop0) == VEC_CONCAT
4346 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4347 .is_constant (&l0))
4348 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4349 .is_constant (&l1))
4350 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4352 rtx subop0 = XEXP (trueop0, 0);
4353 rtx subop1 = XEXP (trueop0, 1);
4354 machine_mode mode0 = GET_MODE (subop0);
4355 machine_mode mode1 = GET_MODE (subop1);
4356 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4357 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4359 bool success = true;
4360 for (int i = 1; i < l0; ++i)
4362 rtx j = XVECEXP (trueop1, 0, i);
4363 if (!CONST_INT_P (j) || INTVAL (j) != i)
4365 success = false;
4366 break;
4369 if (success)
4370 return subop0;
4372 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4374 bool success = true;
4375 for (int i = 1; i < l1; ++i)
4377 rtx j = XVECEXP (trueop1, 0, i);
4378 if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4380 success = false;
4381 break;
4384 if (success)
4385 return subop1;
4389 /* Simplify vec_select of a subreg of X to just a vec_select of X
4390 when X has same component mode as vec_select. */
4391 unsigned HOST_WIDE_INT subreg_offset = 0;
4392 if (GET_CODE (trueop0) == SUBREG
4393 && GET_MODE_INNER (mode)
4394 == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
4395 && GET_MODE_NUNITS (mode).is_constant (&l1)
4396 && constant_multiple_p (subreg_memory_offset (trueop0),
4397 GET_MODE_UNIT_BITSIZE (mode),
4398 &subreg_offset))
4400 poly_uint64 nunits
4401 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
4402 bool success = true;
4403 for (int i = 0; i != l1; i++)
4405 rtx idx = XVECEXP (trueop1, 0, i);
4406 if (!CONST_INT_P (idx)
4407 || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
4409 success = false;
4410 break;
4414 if (success)
4416 rtx par = trueop1;
4417 if (subreg_offset)
4419 rtvec vec = rtvec_alloc (l1);
4420 for (int i = 0; i < l1; i++)
4421 RTVEC_ELT (vec, i)
4422 = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
4423 + subreg_offset);
4424 par = gen_rtx_PARALLEL (VOIDmode, vec);
4426 return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
4431 if (XVECLEN (trueop1, 0) == 1
4432 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4433 && GET_CODE (trueop0) == VEC_CONCAT)
4435 rtx vec = trueop0;
4436 offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4438 /* Try to find the element in the VEC_CONCAT. */
4439 while (GET_MODE (vec) != mode
4440 && GET_CODE (vec) == VEC_CONCAT)
4442 poly_int64 vec_size;
4444 if (CONST_INT_P (XEXP (vec, 0)))
4446 /* vec_concat of two const_ints doesn't make sense with
4447 respect to modes. */
4448 if (CONST_INT_P (XEXP (vec, 1)))
4449 return 0;
4451 vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4452 - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4454 else
4455 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4457 if (known_lt (offset, vec_size))
4458 vec = XEXP (vec, 0);
4459 else if (known_ge (offset, vec_size))
4461 offset -= vec_size;
4462 vec = XEXP (vec, 1);
4464 else
4465 break;
4466 vec = avoid_constant_pool_reference (vec);
4469 if (GET_MODE (vec) == mode)
4470 return vec;
4473 /* If we select elements in a vec_merge that all come from the same
4474 operand, select from that operand directly. */
4475 if (GET_CODE (op0) == VEC_MERGE)
4477 rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4478 if (CONST_INT_P (trueop02))
4480 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4481 bool all_operand0 = true;
4482 bool all_operand1 = true;
4483 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4485 rtx j = XVECEXP (trueop1, 0, i);
4486 if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4487 all_operand1 = false;
4488 else
4489 all_operand0 = false;
4491 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4492 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4493 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4494 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4498 /* If we have two nested selects that are inverses of each
4499 other, replace them with the source operand. */
4500 if (GET_CODE (trueop0) == VEC_SELECT
4501 && GET_MODE (XEXP (trueop0, 0)) == mode)
4503 rtx op0_subop1 = XEXP (trueop0, 1);
4504 gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4505 gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4507 /* Apply the outer ordering vector to the inner one. (The inner
4508 ordering vector is expressly permitted to be of a different
4509 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4510 then the two VEC_SELECTs cancel. */
4511 for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4513 rtx x = XVECEXP (trueop1, 0, i);
4514 if (!CONST_INT_P (x))
4515 return 0;
4516 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4517 if (!CONST_INT_P (y) || i != INTVAL (y))
4518 return 0;
4520 return XEXP (trueop0, 0);
4523 return 0;
4524 case VEC_CONCAT:
4526 machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4527 ? GET_MODE (trueop0)
4528 : GET_MODE_INNER (mode));
4529 machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4530 ? GET_MODE (trueop1)
4531 : GET_MODE_INNER (mode));
4533 gcc_assert (VECTOR_MODE_P (mode));
4534 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4535 + GET_MODE_SIZE (op1_mode),
4536 GET_MODE_SIZE (mode)));
4538 if (VECTOR_MODE_P (op0_mode))
4539 gcc_assert (GET_MODE_INNER (mode)
4540 == GET_MODE_INNER (op0_mode));
4541 else
4542 gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4544 if (VECTOR_MODE_P (op1_mode))
4545 gcc_assert (GET_MODE_INNER (mode)
4546 == GET_MODE_INNER (op1_mode));
4547 else
4548 gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4550 unsigned int n_elts, in_n_elts;
4551 if ((GET_CODE (trueop0) == CONST_VECTOR
4552 || CONST_SCALAR_INT_P (trueop0)
4553 || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4554 && (GET_CODE (trueop1) == CONST_VECTOR
4555 || CONST_SCALAR_INT_P (trueop1)
4556 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4557 && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4558 && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4560 rtvec v = rtvec_alloc (n_elts);
4561 unsigned int i;
4562 for (i = 0; i < n_elts; i++)
4564 if (i < in_n_elts)
4566 if (!VECTOR_MODE_P (op0_mode))
4567 RTVEC_ELT (v, i) = trueop0;
4568 else
4569 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4571 else
4573 if (!VECTOR_MODE_P (op1_mode))
4574 RTVEC_ELT (v, i) = trueop1;
4575 else
4576 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4577 i - in_n_elts);
4581 return gen_rtx_CONST_VECTOR (mode, v);
4584 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4585 Restrict the transformation to avoid generating a VEC_SELECT with a
4586 mode unrelated to its operand. */
4587 if (GET_CODE (trueop0) == VEC_SELECT
4588 && GET_CODE (trueop1) == VEC_SELECT
4589 && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4590 && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
4591 == GET_MODE_INNER(mode))
4593 rtx par0 = XEXP (trueop0, 1);
4594 rtx par1 = XEXP (trueop1, 1);
4595 int len0 = XVECLEN (par0, 0);
4596 int len1 = XVECLEN (par1, 0);
4597 rtvec vec = rtvec_alloc (len0 + len1);
4598 for (int i = 0; i < len0; i++)
4599 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4600 for (int i = 0; i < len1; i++)
4601 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4602 return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4603 gen_rtx_PARALLEL (VOIDmode, vec));
4606 return 0;
4608 default:
4609 gcc_unreachable ();
4612 if (mode == GET_MODE (op0)
4613 && mode == GET_MODE (op1)
4614 && vec_duplicate_p (op0, &elt0)
4615 && vec_duplicate_p (op1, &elt1))
4617 /* Try applying the operator to ELT and see if that simplifies.
4618 We can duplicate the result if so.
4620 The reason we don't use simplify_gen_binary is that it isn't
4621 necessarily a win to convert things like:
4623 (plus:V (vec_duplicate:V (reg:S R1))
4624 (vec_duplicate:V (reg:S R2)))
4628 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4630 The first might be done entirely in vector registers while the
4631 second might need a move between register files. */
4632 tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4633 elt0, elt1);
4634 if (tem)
4635 return gen_vec_duplicate (mode, tem);
4638 return 0;
4641 /* Return true if binary operation OP distributes over addition in operand
4642 OPNO, with the other operand being held constant. OPNO counts from 1. */
4644 static bool
4645 distributes_over_addition_p (rtx_code op, int opno)
4647 switch (op)
4649 case PLUS:
4650 case MINUS:
4651 case MULT:
4652 return true;
4654 case ASHIFT:
4655 return opno == 1;
4657 default:
4658 return false;
4663 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4664 rtx op0, rtx op1)
4666 if (VECTOR_MODE_P (mode)
4667 && code != VEC_CONCAT
4668 && GET_CODE (op0) == CONST_VECTOR
4669 && GET_CODE (op1) == CONST_VECTOR)
4671 bool step_ok_p;
4672 if (CONST_VECTOR_STEPPED_P (op0)
4673 && CONST_VECTOR_STEPPED_P (op1))
4674 /* We can operate directly on the encoding if:
4676 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4677 implies
4678 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4680 Addition and subtraction are the supported operators
4681 for which this is true. */
4682 step_ok_p = (code == PLUS || code == MINUS);
4683 else if (CONST_VECTOR_STEPPED_P (op0))
4684 /* We can operate directly on stepped encodings if:
4686 a3 - a2 == a2 - a1
4687 implies:
4688 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4690 which is true if (x -> x op c) distributes over addition. */
4691 step_ok_p = distributes_over_addition_p (code, 1);
4692 else
4693 /* Similarly in reverse. */
4694 step_ok_p = distributes_over_addition_p (code, 2);
4695 rtx_vector_builder builder;
4696 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4697 return 0;
4699 unsigned int count = builder.encoded_nelts ();
4700 for (unsigned int i = 0; i < count; i++)
4702 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4703 CONST_VECTOR_ELT (op0, i),
4704 CONST_VECTOR_ELT (op1, i));
4705 if (!x || !valid_for_const_vector_p (mode, x))
4706 return 0;
4707 builder.quick_push (x);
4709 return builder.build ();
4712 if (VECTOR_MODE_P (mode)
4713 && code == VEC_CONCAT
4714 && (CONST_SCALAR_INT_P (op0)
4715 || CONST_FIXED_P (op0)
4716 || CONST_DOUBLE_AS_FLOAT_P (op0))
4717 && (CONST_SCALAR_INT_P (op1)
4718 || CONST_DOUBLE_AS_FLOAT_P (op1)
4719 || CONST_FIXED_P (op1)))
4721 /* Both inputs have a constant number of elements, so the result
4722 must too. */
4723 unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4724 rtvec v = rtvec_alloc (n_elts);
4726 gcc_assert (n_elts >= 2);
4727 if (n_elts == 2)
4729 gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4730 gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4732 RTVEC_ELT (v, 0) = op0;
4733 RTVEC_ELT (v, 1) = op1;
4735 else
4737 unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4738 unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4739 unsigned i;
4741 gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4742 gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4743 gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4745 for (i = 0; i < op0_n_elts; ++i)
4746 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4747 for (i = 0; i < op1_n_elts; ++i)
4748 RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4751 return gen_rtx_CONST_VECTOR (mode, v);
4754 if (SCALAR_FLOAT_MODE_P (mode)
4755 && CONST_DOUBLE_AS_FLOAT_P (op0)
4756 && CONST_DOUBLE_AS_FLOAT_P (op1)
4757 && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4759 if (code == AND
4760 || code == IOR
4761 || code == XOR)
4763 long tmp0[4];
4764 long tmp1[4];
4765 REAL_VALUE_TYPE r;
4766 int i;
4768 real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4769 GET_MODE (op0));
4770 real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4771 GET_MODE (op1));
4772 for (i = 0; i < 4; i++)
4774 switch (code)
4776 case AND:
4777 tmp0[i] &= tmp1[i];
4778 break;
4779 case IOR:
4780 tmp0[i] |= tmp1[i];
4781 break;
4782 case XOR:
4783 tmp0[i] ^= tmp1[i];
4784 break;
4785 default:
4786 gcc_unreachable ();
4789 real_from_target (&r, tmp0, mode);
4790 return const_double_from_real_value (r, mode);
4792 else
4794 REAL_VALUE_TYPE f0, f1, value, result;
4795 const REAL_VALUE_TYPE *opr0, *opr1;
4796 bool inexact;
4798 opr0 = CONST_DOUBLE_REAL_VALUE (op0);
4799 opr1 = CONST_DOUBLE_REAL_VALUE (op1);
4801 if (HONOR_SNANS (mode)
4802 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
4803 || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
4804 return 0;
4806 real_convert (&f0, mode, opr0);
4807 real_convert (&f1, mode, opr1);
4809 if (code == DIV
4810 && real_equal (&f1, &dconst0)
4811 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
4812 return 0;
4814 if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4815 && flag_trapping_math
4816 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
4818 int s0 = REAL_VALUE_NEGATIVE (f0);
4819 int s1 = REAL_VALUE_NEGATIVE (f1);
4821 switch (code)
4823 case PLUS:
4824 /* Inf + -Inf = NaN plus exception. */
4825 if (s0 != s1)
4826 return 0;
4827 break;
4828 case MINUS:
4829 /* Inf - Inf = NaN plus exception. */
4830 if (s0 == s1)
4831 return 0;
4832 break;
4833 case DIV:
4834 /* Inf / Inf = NaN plus exception. */
4835 return 0;
4836 default:
4837 break;
4841 if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4842 && flag_trapping_math
4843 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
4844 || (REAL_VALUE_ISINF (f1)
4845 && real_equal (&f0, &dconst0))))
4846 /* Inf * 0 = NaN plus exception. */
4847 return 0;
4849 inexact = real_arithmetic (&value, rtx_to_tree_code (code),
4850 &f0, &f1);
4851 real_convert (&result, mode, &value);
4853 /* Don't constant fold this floating point operation if
4854 the result has overflowed and flag_trapping_math. */
4856 if (flag_trapping_math
4857 && MODE_HAS_INFINITIES (mode)
4858 && REAL_VALUE_ISINF (result)
4859 && !REAL_VALUE_ISINF (f0)
4860 && !REAL_VALUE_ISINF (f1))
4861 /* Overflow plus exception. */
4862 return 0;
4864 /* Don't constant fold this floating point operation if the
4865 result may dependent upon the run-time rounding mode and
4866 flag_rounding_math is set, or if GCC's software emulation
4867 is unable to accurately represent the result. */
4869 if ((flag_rounding_math
4870 || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
4871 && (inexact || !real_identical (&result, &value)))
4872 return NULL_RTX;
4874 return const_double_from_real_value (result, mode);
4878 /* We can fold some multi-word operations. */
4879 scalar_int_mode int_mode;
4880 if (is_a <scalar_int_mode> (mode, &int_mode)
4881 && CONST_SCALAR_INT_P (op0)
4882 && CONST_SCALAR_INT_P (op1)
4883 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
4885 wide_int result;
4886 wi::overflow_type overflow;
4887 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
4888 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
4890 #if TARGET_SUPPORTS_WIDE_INT == 0
4891 /* This assert keeps the simplification from producing a result
4892 that cannot be represented in a CONST_DOUBLE but a lot of
4893 upstream callers expect that this function never fails to
4894 simplify something and so you if you added this to the test
4895 above the code would die later anyway. If this assert
4896 happens, you just need to make the port support wide int. */
4897 gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
4898 #endif
4899 switch (code)
4901 case MINUS:
4902 result = wi::sub (pop0, pop1);
4903 break;
4905 case PLUS:
4906 result = wi::add (pop0, pop1);
4907 break;
4909 case MULT:
4910 result = wi::mul (pop0, pop1);
4911 break;
4913 case DIV:
4914 result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
4915 if (overflow)
4916 return NULL_RTX;
4917 break;
4919 case MOD:
4920 result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
4921 if (overflow)
4922 return NULL_RTX;
4923 break;
4925 case UDIV:
4926 result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
4927 if (overflow)
4928 return NULL_RTX;
4929 break;
4931 case UMOD:
4932 result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
4933 if (overflow)
4934 return NULL_RTX;
4935 break;
4937 case AND:
4938 result = wi::bit_and (pop0, pop1);
4939 break;
4941 case IOR:
4942 result = wi::bit_or (pop0, pop1);
4943 break;
4945 case XOR:
4946 result = wi::bit_xor (pop0, pop1);
4947 break;
4949 case SMIN:
4950 result = wi::smin (pop0, pop1);
4951 break;
4953 case SMAX:
4954 result = wi::smax (pop0, pop1);
4955 break;
4957 case UMIN:
4958 result = wi::umin (pop0, pop1);
4959 break;
4961 case UMAX:
4962 result = wi::umax (pop0, pop1);
4963 break;
4965 case LSHIFTRT:
4966 case ASHIFTRT:
4967 case ASHIFT:
4969 wide_int wop1 = pop1;
4970 if (SHIFT_COUNT_TRUNCATED)
4971 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
4972 else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
4973 return NULL_RTX;
4975 switch (code)
4977 case LSHIFTRT:
4978 result = wi::lrshift (pop0, wop1);
4979 break;
4981 case ASHIFTRT:
4982 result = wi::arshift (pop0, wop1);
4983 break;
4985 case ASHIFT:
4986 result = wi::lshift (pop0, wop1);
4987 break;
4989 default:
4990 gcc_unreachable ();
4992 break;
4994 case ROTATE:
4995 case ROTATERT:
4997 if (wi::neg_p (pop1))
4998 return NULL_RTX;
5000 switch (code)
5002 case ROTATE:
5003 result = wi::lrotate (pop0, pop1);
5004 break;
5006 case ROTATERT:
5007 result = wi::rrotate (pop0, pop1);
5008 break;
5010 default:
5011 gcc_unreachable ();
5013 break;
5015 default:
5016 return NULL_RTX;
5018 return immed_wide_int_const (result, int_mode);
5021 /* Handle polynomial integers. */
5022 if (NUM_POLY_INT_COEFFS > 1
5023 && is_a <scalar_int_mode> (mode, &int_mode)
5024 && poly_int_rtx_p (op0)
5025 && poly_int_rtx_p (op1))
5027 poly_wide_int result;
5028 switch (code)
5030 case PLUS:
5031 result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
5032 break;
5034 case MINUS:
5035 result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
5036 break;
5038 case MULT:
5039 if (CONST_SCALAR_INT_P (op1))
5040 result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
5041 else
5042 return NULL_RTX;
5043 break;
5045 case ASHIFT:
5046 if (CONST_SCALAR_INT_P (op1))
5048 wide_int shift = rtx_mode_t (op1, mode);
5049 if (SHIFT_COUNT_TRUNCATED)
5050 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
5051 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
5052 return NULL_RTX;
5053 result = wi::to_poly_wide (op0, mode) << shift;
5055 else
5056 return NULL_RTX;
5057 break;
5059 case IOR:
5060 if (!CONST_SCALAR_INT_P (op1)
5061 || !can_ior_p (wi::to_poly_wide (op0, mode),
5062 rtx_mode_t (op1, mode), &result))
5063 return NULL_RTX;
5064 break;
5066 default:
5067 return NULL_RTX;
5069 return immed_wide_int_const (result, int_mode);
5072 return NULL_RTX;
5077 /* Return a positive integer if X should sort after Y. The value
5078 returned is 1 if and only if X and Y are both regs. */
5080 static int
5081 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
5083 int result;
5085 result = (commutative_operand_precedence (y)
5086 - commutative_operand_precedence (x));
5087 if (result)
5088 return result + result;
5090 /* Group together equal REGs to do more simplification. */
5091 if (REG_P (x) && REG_P (y))
5092 return REGNO (x) > REGNO (y);
5094 return 0;
5097 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5098 operands may be another PLUS or MINUS.
5100 Rather than test for specific case, we do this by a brute-force method
5101 and do all possible simplifications until no more changes occur. Then
5102 we rebuild the operation.
5104 May return NULL_RTX when no changes were made. */
5107 simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
5108 rtx op0, rtx op1)
5110 struct simplify_plus_minus_op_data
5112 rtx op;
5113 short neg;
5114 } ops[16];
5115 rtx result, tem;
5116 int n_ops = 2;
5117 int changed, n_constants, canonicalized = 0;
5118 int i, j;
5120 memset (ops, 0, sizeof ops);
5122 /* Set up the two operands and then expand them until nothing has been
5123 changed. If we run out of room in our array, give up; this should
5124 almost never happen. */
5126 ops[0].op = op0;
5127 ops[0].neg = 0;
5128 ops[1].op = op1;
5129 ops[1].neg = (code == MINUS);
5133 changed = 0;
5134 n_constants = 0;
5136 for (i = 0; i < n_ops; i++)
5138 rtx this_op = ops[i].op;
5139 int this_neg = ops[i].neg;
5140 enum rtx_code this_code = GET_CODE (this_op);
5142 switch (this_code)
5144 case PLUS:
5145 case MINUS:
5146 if (n_ops == ARRAY_SIZE (ops))
5147 return NULL_RTX;
5149 ops[n_ops].op = XEXP (this_op, 1);
5150 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
5151 n_ops++;
5153 ops[i].op = XEXP (this_op, 0);
5154 changed = 1;
5155 /* If this operand was negated then we will potentially
5156 canonicalize the expression. Similarly if we don't
5157 place the operands adjacent we're re-ordering the
5158 expression and thus might be performing a
5159 canonicalization. Ignore register re-ordering.
5160 ??? It might be better to shuffle the ops array here,
5161 but then (plus (plus (A, B), plus (C, D))) wouldn't
5162 be seen as non-canonical. */
5163 if (this_neg
5164 || (i != n_ops - 2
5165 && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
5166 canonicalized = 1;
5167 break;
5169 case NEG:
5170 ops[i].op = XEXP (this_op, 0);
5171 ops[i].neg = ! this_neg;
5172 changed = 1;
5173 canonicalized = 1;
5174 break;
5176 case CONST:
5177 if (n_ops != ARRAY_SIZE (ops)
5178 && GET_CODE (XEXP (this_op, 0)) == PLUS
5179 && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
5180 && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
5182 ops[i].op = XEXP (XEXP (this_op, 0), 0);
5183 ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
5184 ops[n_ops].neg = this_neg;
5185 n_ops++;
5186 changed = 1;
5187 canonicalized = 1;
5189 break;
5191 case NOT:
5192 /* ~a -> (-a - 1) */
5193 if (n_ops != ARRAY_SIZE (ops))
5195 ops[n_ops].op = CONSTM1_RTX (mode);
5196 ops[n_ops++].neg = this_neg;
5197 ops[i].op = XEXP (this_op, 0);
5198 ops[i].neg = !this_neg;
5199 changed = 1;
5200 canonicalized = 1;
5202 break;
5204 CASE_CONST_SCALAR_INT:
5205 case CONST_POLY_INT:
5206 n_constants++;
5207 if (this_neg)
5209 ops[i].op = neg_poly_int_rtx (mode, this_op);
5210 ops[i].neg = 0;
5211 changed = 1;
5212 canonicalized = 1;
5214 break;
5216 default:
5217 break;
5221 while (changed);
5223 if (n_constants > 1)
5224 canonicalized = 1;
5226 gcc_assert (n_ops >= 2);
5228 /* If we only have two operands, we can avoid the loops. */
5229 if (n_ops == 2)
5231 enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
5232 rtx lhs, rhs;
5234 /* Get the two operands. Be careful with the order, especially for
5235 the cases where code == MINUS. */
5236 if (ops[0].neg && ops[1].neg)
5238 lhs = gen_rtx_NEG (mode, ops[0].op);
5239 rhs = ops[1].op;
5241 else if (ops[0].neg)
5243 lhs = ops[1].op;
5244 rhs = ops[0].op;
5246 else
5248 lhs = ops[0].op;
5249 rhs = ops[1].op;
5252 return simplify_const_binary_operation (code, mode, lhs, rhs);
5255 /* Now simplify each pair of operands until nothing changes. */
5256 while (1)
5258 /* Insertion sort is good enough for a small array. */
5259 for (i = 1; i < n_ops; i++)
5261 struct simplify_plus_minus_op_data save;
5262 int cmp;
5264 j = i - 1;
5265 cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
5266 if (cmp <= 0)
5267 continue;
5268 /* Just swapping registers doesn't count as canonicalization. */
5269 if (cmp != 1)
5270 canonicalized = 1;
5272 save = ops[i];
5274 ops[j + 1] = ops[j];
5275 while (j--
5276 && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
5277 ops[j + 1] = save;
5280 changed = 0;
5281 for (i = n_ops - 1; i > 0; i--)
5282 for (j = i - 1; j >= 0; j--)
5284 rtx lhs = ops[j].op, rhs = ops[i].op;
5285 int lneg = ops[j].neg, rneg = ops[i].neg;
5287 if (lhs != 0 && rhs != 0)
5289 enum rtx_code ncode = PLUS;
5291 if (lneg != rneg)
5293 ncode = MINUS;
5294 if (lneg)
5295 std::swap (lhs, rhs);
5297 else if (swap_commutative_operands_p (lhs, rhs))
5298 std::swap (lhs, rhs);
5300 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
5301 && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
5303 rtx tem_lhs, tem_rhs;
5305 tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
5306 tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
5307 tem = simplify_binary_operation (ncode, mode, tem_lhs,
5308 tem_rhs);
5310 if (tem && !CONSTANT_P (tem))
5311 tem = gen_rtx_CONST (GET_MODE (tem), tem);
5313 else
5314 tem = simplify_binary_operation (ncode, mode, lhs, rhs);
5316 if (tem)
5318 /* Reject "simplifications" that just wrap the two
5319 arguments in a CONST. Failure to do so can result
5320 in infinite recursion with simplify_binary_operation
5321 when it calls us to simplify CONST operations.
5322 Also, if we find such a simplification, don't try
5323 any more combinations with this rhs: We must have
5324 something like symbol+offset, ie. one of the
5325 trivial CONST expressions we handle later. */
5326 if (GET_CODE (tem) == CONST
5327 && GET_CODE (XEXP (tem, 0)) == ncode
5328 && XEXP (XEXP (tem, 0), 0) == lhs
5329 && XEXP (XEXP (tem, 0), 1) == rhs)
5330 break;
5331 lneg &= rneg;
5332 if (GET_CODE (tem) == NEG)
5333 tem = XEXP (tem, 0), lneg = !lneg;
5334 if (poly_int_rtx_p (tem) && lneg)
5335 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
5337 ops[i].op = tem;
5338 ops[i].neg = lneg;
5339 ops[j].op = NULL_RTX;
5340 changed = 1;
5341 canonicalized = 1;
5346 if (!changed)
5347 break;
5349 /* Pack all the operands to the lower-numbered entries. */
5350 for (i = 0, j = 0; j < n_ops; j++)
5351 if (ops[j].op)
5353 ops[i] = ops[j];
5354 i++;
5356 n_ops = i;
5359 /* If nothing changed, check that rematerialization of rtl instructions
5360 is still required. */
5361 if (!canonicalized)
5363 /* Perform rematerialization if only all operands are registers and
5364 all operations are PLUS. */
5365 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5366 around rs6000 and how it uses the CA register. See PR67145. */
5367 for (i = 0; i < n_ops; i++)
5368 if (ops[i].neg
5369 || !REG_P (ops[i].op)
5370 || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5371 && fixed_regs[REGNO (ops[i].op)]
5372 && !global_regs[REGNO (ops[i].op)]
5373 && ops[i].op != frame_pointer_rtx
5374 && ops[i].op != arg_pointer_rtx
5375 && ops[i].op != stack_pointer_rtx))
5376 return NULL_RTX;
5377 goto gen_result;
5380 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5381 if (n_ops == 2
5382 && CONST_INT_P (ops[1].op)
5383 && CONSTANT_P (ops[0].op)
5384 && ops[0].neg)
5385 return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5387 /* We suppressed creation of trivial CONST expressions in the
5388 combination loop to avoid recursion. Create one manually now.
5389 The combination loop should have ensured that there is exactly
5390 one CONST_INT, and the sort will have ensured that it is last
5391 in the array and that any other constant will be next-to-last. */
5393 if (n_ops > 1
5394 && poly_int_rtx_p (ops[n_ops - 1].op)
5395 && CONSTANT_P (ops[n_ops - 2].op))
5397 rtx value = ops[n_ops - 1].op;
5398 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5399 value = neg_poly_int_rtx (mode, value);
5400 if (CONST_INT_P (value))
5402 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5403 INTVAL (value));
5404 n_ops--;
5408 /* Put a non-negated operand first, if possible. */
5410 for (i = 0; i < n_ops && ops[i].neg; i++)
5411 continue;
5412 if (i == n_ops)
5413 ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5414 else if (i != 0)
5416 tem = ops[0].op;
5417 ops[0] = ops[i];
5418 ops[i].op = tem;
5419 ops[i].neg = 1;
5422 /* Now make the result by performing the requested operations. */
5423 gen_result:
5424 result = ops[0].op;
5425 for (i = 1; i < n_ops; i++)
5426 result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5427 mode, result, ops[i].op);
5429 return result;
5432 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5433 static bool
5434 plus_minus_operand_p (const_rtx x)
5436 return GET_CODE (x) == PLUS
5437 || GET_CODE (x) == MINUS
5438 || (GET_CODE (x) == CONST
5439 && GET_CODE (XEXP (x, 0)) == PLUS
5440 && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5441 && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5444 /* Like simplify_binary_operation except used for relational operators.
5445 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5446 not also be VOIDmode.
5448 CMP_MODE specifies in which mode the comparison is done in, so it is
5449 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5450 the operands or, if both are VOIDmode, the operands are compared in
5451 "infinite precision". */
5453 simplify_context::simplify_relational_operation (rtx_code code,
5454 machine_mode mode,
5455 machine_mode cmp_mode,
5456 rtx op0, rtx op1)
5458 rtx tem, trueop0, trueop1;
5460 if (cmp_mode == VOIDmode)
5461 cmp_mode = GET_MODE (op0);
5462 if (cmp_mode == VOIDmode)
5463 cmp_mode = GET_MODE (op1);
5465 tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5466 if (tem)
5467 return relational_result (mode, cmp_mode, tem);
5469 /* For the following tests, ensure const0_rtx is op1. */
5470 if (swap_commutative_operands_p (op0, op1)
5471 || (op0 == const0_rtx && op1 != const0_rtx))
5472 std::swap (op0, op1), code = swap_condition (code);
5474 /* If op0 is a compare, extract the comparison arguments from it. */
5475 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5476 return simplify_gen_relational (code, mode, VOIDmode,
5477 XEXP (op0, 0), XEXP (op0, 1));
5479 if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
5480 return NULL_RTX;
5482 trueop0 = avoid_constant_pool_reference (op0);
5483 trueop1 = avoid_constant_pool_reference (op1);
5484 return simplify_relational_operation_1 (code, mode, cmp_mode,
5485 trueop0, trueop1);
5488 /* This part of simplify_relational_operation is only used when CMP_MODE
5489 is not in class MODE_CC (i.e. it is a real comparison).
5491 MODE is the mode of the result, while CMP_MODE specifies in which
5492 mode the comparison is done in, so it is the mode of the operands. */
5495 simplify_context::simplify_relational_operation_1 (rtx_code code,
5496 machine_mode mode,
5497 machine_mode cmp_mode,
5498 rtx op0, rtx op1)
5500 enum rtx_code op0code = GET_CODE (op0);
5502 if (op1 == const0_rtx && COMPARISON_P (op0))
5504 /* If op0 is a comparison, extract the comparison arguments
5505 from it. */
5506 if (code == NE)
5508 if (GET_MODE (op0) == mode)
5509 return simplify_rtx (op0);
5510 else
5511 return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5512 XEXP (op0, 0), XEXP (op0, 1));
5514 else if (code == EQ)
5516 enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5517 if (new_code != UNKNOWN)
5518 return simplify_gen_relational (new_code, mode, VOIDmode,
5519 XEXP (op0, 0), XEXP (op0, 1));
5523 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5524 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5525 if ((code == LTU || code == GEU)
5526 && GET_CODE (op0) == PLUS
5527 && CONST_INT_P (XEXP (op0, 1))
5528 && (rtx_equal_p (op1, XEXP (op0, 0))
5529 || rtx_equal_p (op1, XEXP (op0, 1)))
5530 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5531 && XEXP (op0, 1) != const0_rtx)
5533 rtx new_cmp
5534 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5535 return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5536 cmp_mode, XEXP (op0, 0), new_cmp);
5539 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5540 transformed into (LTU a -C). */
5541 if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5542 && CONST_INT_P (XEXP (op0, 1))
5543 && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5544 && XEXP (op0, 1) != const0_rtx)
5546 rtx new_cmp
5547 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5548 return simplify_gen_relational (LTU, mode, cmp_mode,
5549 XEXP (op0, 0), new_cmp);
5552 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5553 if ((code == LTU || code == GEU)
5554 && GET_CODE (op0) == PLUS
5555 && rtx_equal_p (op1, XEXP (op0, 1))
5556 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5557 && !rtx_equal_p (op1, XEXP (op0, 0)))
5558 return simplify_gen_relational (code, mode, cmp_mode, op0,
5559 copy_rtx (XEXP (op0, 0)));
5561 if (op1 == const0_rtx)
5563 /* Canonicalize (GTU x 0) as (NE x 0). */
5564 if (code == GTU)
5565 return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5566 /* Canonicalize (LEU x 0) as (EQ x 0). */
5567 if (code == LEU)
5568 return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5570 else if (op1 == const1_rtx)
5572 switch (code)
5574 case GE:
5575 /* Canonicalize (GE x 1) as (GT x 0). */
5576 return simplify_gen_relational (GT, mode, cmp_mode,
5577 op0, const0_rtx);
5578 case GEU:
5579 /* Canonicalize (GEU x 1) as (NE x 0). */
5580 return simplify_gen_relational (NE, mode, cmp_mode,
5581 op0, const0_rtx);
5582 case LT:
5583 /* Canonicalize (LT x 1) as (LE x 0). */
5584 return simplify_gen_relational (LE, mode, cmp_mode,
5585 op0, const0_rtx);
5586 case LTU:
5587 /* Canonicalize (LTU x 1) as (EQ x 0). */
5588 return simplify_gen_relational (EQ, mode, cmp_mode,
5589 op0, const0_rtx);
5590 default:
5591 break;
5594 else if (op1 == constm1_rtx)
5596 /* Canonicalize (LE x -1) as (LT x 0). */
5597 if (code == LE)
5598 return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5599 /* Canonicalize (GT x -1) as (GE x 0). */
5600 if (code == GT)
5601 return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5604 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5605 if ((code == EQ || code == NE)
5606 && (op0code == PLUS || op0code == MINUS)
5607 && CONSTANT_P (op1)
5608 && CONSTANT_P (XEXP (op0, 1))
5609 && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5611 rtx x = XEXP (op0, 0);
5612 rtx c = XEXP (op0, 1);
5613 enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5614 rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5616 /* Detect an infinite recursive condition, where we oscillate at this
5617 simplification case between:
5618 A + B == C <---> C - B == A,
5619 where A, B, and C are all constants with non-simplifiable expressions,
5620 usually SYMBOL_REFs. */
5621 if (GET_CODE (tem) == invcode
5622 && CONSTANT_P (x)
5623 && rtx_equal_p (c, XEXP (tem, 1)))
5624 return NULL_RTX;
5626 return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5629 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5630 the same as (zero_extract:SI FOO (const_int 1) BAR). */
5631 scalar_int_mode int_mode, int_cmp_mode;
5632 if (code == NE
5633 && op1 == const0_rtx
5634 && is_int_mode (mode, &int_mode)
5635 && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5636 /* ??? Work-around BImode bugs in the ia64 backend. */
5637 && int_mode != BImode
5638 && int_cmp_mode != BImode
5639 && nonzero_bits (op0, int_cmp_mode) == 1
5640 && STORE_FLAG_VALUE == 1)
5641 return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5642 ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5643 : lowpart_subreg (int_mode, op0, int_cmp_mode);
5645 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
5646 if ((code == EQ || code == NE)
5647 && op1 == const0_rtx
5648 && op0code == XOR)
5649 return simplify_gen_relational (code, mode, cmp_mode,
5650 XEXP (op0, 0), XEXP (op0, 1));
5652 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
5653 if ((code == EQ || code == NE)
5654 && op0code == XOR
5655 && rtx_equal_p (XEXP (op0, 0), op1)
5656 && !side_effects_p (XEXP (op0, 0)))
5657 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5658 CONST0_RTX (mode));
5660 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
5661 if ((code == EQ || code == NE)
5662 && op0code == XOR
5663 && rtx_equal_p (XEXP (op0, 1), op1)
5664 && !side_effects_p (XEXP (op0, 1)))
5665 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5666 CONST0_RTX (mode));
5668 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
5669 if ((code == EQ || code == NE)
5670 && op0code == XOR
5671 && CONST_SCALAR_INT_P (op1)
5672 && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5673 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5674 simplify_gen_binary (XOR, cmp_mode,
5675 XEXP (op0, 1), op1));
5677 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5678 constant folding if x/y is a constant. */
5679 if ((code == EQ || code == NE)
5680 && (op0code == AND || op0code == IOR)
5681 && !side_effects_p (op1)
5682 && op1 != CONST0_RTX (cmp_mode))
5684 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5685 (eq/ne (and (not y) x) 0). */
5686 if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5687 || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5689 rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5690 cmp_mode);
5691 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5693 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5694 CONST0_RTX (cmp_mode));
5697 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5698 (eq/ne (and (not x) y) 0). */
5699 if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5700 || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5702 rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5703 cmp_mode);
5704 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
5706 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5707 CONST0_RTX (cmp_mode));
5711 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
5712 if ((code == EQ || code == NE)
5713 && GET_CODE (op0) == BSWAP
5714 && CONST_SCALAR_INT_P (op1))
5715 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5716 simplify_gen_unary (BSWAP, cmp_mode,
5717 op1, cmp_mode));
5719 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
5720 if ((code == EQ || code == NE)
5721 && GET_CODE (op0) == BSWAP
5722 && GET_CODE (op1) == BSWAP)
5723 return simplify_gen_relational (code, mode, cmp_mode,
5724 XEXP (op0, 0), XEXP (op1, 0));
5726 if (op0code == POPCOUNT && op1 == const0_rtx)
5727 switch (code)
5729 case EQ:
5730 case LE:
5731 case LEU:
5732 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
5733 return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
5734 XEXP (op0, 0), const0_rtx);
5736 case NE:
5737 case GT:
5738 case GTU:
5739 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
5740 return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
5741 XEXP (op0, 0), const0_rtx);
5743 default:
5744 break;
5747 return NULL_RTX;
5750 enum
5752 CMP_EQ = 1,
5753 CMP_LT = 2,
5754 CMP_GT = 4,
5755 CMP_LTU = 8,
5756 CMP_GTU = 16
5760 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
5761 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
5762 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
5763 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
5764 For floating-point comparisons, assume that the operands were ordered. */
5766 static rtx
5767 comparison_result (enum rtx_code code, int known_results)
5769 switch (code)
5771 case EQ:
5772 case UNEQ:
5773 return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
5774 case NE:
5775 case LTGT:
5776 return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
5778 case LT:
5779 case UNLT:
5780 return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
5781 case GE:
5782 case UNGE:
5783 return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
5785 case GT:
5786 case UNGT:
5787 return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
5788 case LE:
5789 case UNLE:
5790 return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
5792 case LTU:
5793 return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
5794 case GEU:
5795 return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
5797 case GTU:
5798 return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
5799 case LEU:
5800 return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
5802 case ORDERED:
5803 return const_true_rtx;
5804 case UNORDERED:
5805 return const0_rtx;
5806 default:
5807 gcc_unreachable ();
5811 /* Check if the given comparison (done in the given MODE) is actually
5812 a tautology or a contradiction. If the mode is VOIDmode, the
5813 comparison is done in "infinite precision". If no simplification
5814 is possible, this function returns zero. Otherwise, it returns
5815 either const_true_rtx or const0_rtx. */
5818 simplify_const_relational_operation (enum rtx_code code,
5819 machine_mode mode,
5820 rtx op0, rtx op1)
5822 rtx tem;
5823 rtx trueop0;
5824 rtx trueop1;
5826 gcc_assert (mode != VOIDmode
5827 || (GET_MODE (op0) == VOIDmode
5828 && GET_MODE (op1) == VOIDmode));
5830 /* If op0 is a compare, extract the comparison arguments from it. */
5831 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5833 op1 = XEXP (op0, 1);
5834 op0 = XEXP (op0, 0);
5836 if (GET_MODE (op0) != VOIDmode)
5837 mode = GET_MODE (op0);
5838 else if (GET_MODE (op1) != VOIDmode)
5839 mode = GET_MODE (op1);
5840 else
5841 return 0;
5844 /* We can't simplify MODE_CC values since we don't know what the
5845 actual comparison is. */
5846 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
5847 return 0;
5849 /* Make sure the constant is second. */
5850 if (swap_commutative_operands_p (op0, op1))
5852 std::swap (op0, op1);
5853 code = swap_condition (code);
5856 trueop0 = avoid_constant_pool_reference (op0);
5857 trueop1 = avoid_constant_pool_reference (op1);
5859 /* For integer comparisons of A and B maybe we can simplify A - B and can
5860 then simplify a comparison of that with zero. If A and B are both either
5861 a register or a CONST_INT, this can't help; testing for these cases will
5862 prevent infinite recursion here and speed things up.
5864 We can only do this for EQ and NE comparisons as otherwise we may
5865 lose or introduce overflow which we cannot disregard as undefined as
5866 we do not know the signedness of the operation on either the left or
5867 the right hand side of the comparison. */
5869 if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
5870 && (code == EQ || code == NE)
5871 && ! ((REG_P (op0) || CONST_INT_P (trueop0))
5872 && (REG_P (op1) || CONST_INT_P (trueop1)))
5873 && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
5874 /* We cannot do this if tem is a nonzero address. */
5875 && ! nonzero_address_p (tem))
5876 return simplify_const_relational_operation (signed_condition (code),
5877 mode, tem, const0_rtx);
5879 if (! HONOR_NANS (mode) && code == ORDERED)
5880 return const_true_rtx;
5882 if (! HONOR_NANS (mode) && code == UNORDERED)
5883 return const0_rtx;
5885 /* For modes without NaNs, if the two operands are equal, we know the
5886 result except if they have side-effects. Even with NaNs we know
5887 the result of unordered comparisons and, if signaling NaNs are
5888 irrelevant, also the result of LT/GT/LTGT. */
5889 if ((! HONOR_NANS (trueop0)
5890 || code == UNEQ || code == UNLE || code == UNGE
5891 || ((code == LT || code == GT || code == LTGT)
5892 && ! HONOR_SNANS (trueop0)))
5893 && rtx_equal_p (trueop0, trueop1)
5894 && ! side_effects_p (trueop0))
5895 return comparison_result (code, CMP_EQ);
5897 /* If the operands are floating-point constants, see if we can fold
5898 the result. */
5899 if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
5900 && CONST_DOUBLE_AS_FLOAT_P (trueop1)
5901 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
5903 const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
5904 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
5906 /* Comparisons are unordered iff at least one of the values is NaN. */
5907 if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
5908 switch (code)
5910 case UNEQ:
5911 case UNLT:
5912 case UNGT:
5913 case UNLE:
5914 case UNGE:
5915 case NE:
5916 case UNORDERED:
5917 return const_true_rtx;
5918 case EQ:
5919 case LT:
5920 case GT:
5921 case LE:
5922 case GE:
5923 case LTGT:
5924 case ORDERED:
5925 return const0_rtx;
5926 default:
5927 return 0;
5930 return comparison_result (code,
5931 (real_equal (d0, d1) ? CMP_EQ :
5932 real_less (d0, d1) ? CMP_LT : CMP_GT));
5935 /* Otherwise, see if the operands are both integers. */
5936 if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
5937 && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
5939 /* It would be nice if we really had a mode here. However, the
5940 largest int representable on the target is as good as
5941 infinite. */
5942 machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
5943 rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
5944 rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
5946 if (wi::eq_p (ptrueop0, ptrueop1))
5947 return comparison_result (code, CMP_EQ);
5948 else
5950 int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
5951 cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
5952 return comparison_result (code, cr);
5956 /* Optimize comparisons with upper and lower bounds. */
5957 scalar_int_mode int_mode;
5958 if (CONST_INT_P (trueop1)
5959 && is_a <scalar_int_mode> (mode, &int_mode)
5960 && HWI_COMPUTABLE_MODE_P (int_mode)
5961 && !side_effects_p (trueop0))
5963 int sign;
5964 unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
5965 HOST_WIDE_INT val = INTVAL (trueop1);
5966 HOST_WIDE_INT mmin, mmax;
5968 if (code == GEU
5969 || code == LEU
5970 || code == GTU
5971 || code == LTU)
5972 sign = 0;
5973 else
5974 sign = 1;
5976 /* Get a reduced range if the sign bit is zero. */
5977 if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
5979 mmin = 0;
5980 mmax = nonzero;
5982 else
5984 rtx mmin_rtx, mmax_rtx;
5985 get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
5987 mmin = INTVAL (mmin_rtx);
5988 mmax = INTVAL (mmax_rtx);
5989 if (sign)
5991 unsigned int sign_copies
5992 = num_sign_bit_copies (trueop0, int_mode);
5994 mmin >>= (sign_copies - 1);
5995 mmax >>= (sign_copies - 1);
5999 switch (code)
6001 /* x >= y is always true for y <= mmin, always false for y > mmax. */
6002 case GEU:
6003 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6004 return const_true_rtx;
6005 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6006 return const0_rtx;
6007 break;
6008 case GE:
6009 if (val <= mmin)
6010 return const_true_rtx;
6011 if (val > mmax)
6012 return const0_rtx;
6013 break;
6015 /* x <= y is always true for y >= mmax, always false for y < mmin. */
6016 case LEU:
6017 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6018 return const_true_rtx;
6019 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6020 return const0_rtx;
6021 break;
6022 case LE:
6023 if (val >= mmax)
6024 return const_true_rtx;
6025 if (val < mmin)
6026 return const0_rtx;
6027 break;
6029 case EQ:
6030 /* x == y is always false for y out of range. */
6031 if (val < mmin || val > mmax)
6032 return const0_rtx;
6033 break;
6035 /* x > y is always false for y >= mmax, always true for y < mmin. */
6036 case GTU:
6037 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6038 return const0_rtx;
6039 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6040 return const_true_rtx;
6041 break;
6042 case GT:
6043 if (val >= mmax)
6044 return const0_rtx;
6045 if (val < mmin)
6046 return const_true_rtx;
6047 break;
6049 /* x < y is always false for y <= mmin, always true for y > mmax. */
6050 case LTU:
6051 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6052 return const0_rtx;
6053 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6054 return const_true_rtx;
6055 break;
6056 case LT:
6057 if (val <= mmin)
6058 return const0_rtx;
6059 if (val > mmax)
6060 return const_true_rtx;
6061 break;
6063 case NE:
6064 /* x != y is always true for y out of range. */
6065 if (val < mmin || val > mmax)
6066 return const_true_rtx;
6067 break;
6069 default:
6070 break;
6074 /* Optimize integer comparisons with zero. */
6075 if (is_a <scalar_int_mode> (mode, &int_mode)
6076 && trueop1 == const0_rtx
6077 && !side_effects_p (trueop0))
6079 /* Some addresses are known to be nonzero. We don't know
6080 their sign, but equality comparisons are known. */
6081 if (nonzero_address_p (trueop0))
6083 if (code == EQ || code == LEU)
6084 return const0_rtx;
6085 if (code == NE || code == GTU)
6086 return const_true_rtx;
6089 /* See if the first operand is an IOR with a constant. If so, we
6090 may be able to determine the result of this comparison. */
6091 if (GET_CODE (op0) == IOR)
6093 rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
6094 if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
6096 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
6097 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
6098 && (UINTVAL (inner_const)
6099 & (HOST_WIDE_INT_1U
6100 << sign_bitnum)));
6102 switch (code)
6104 case EQ:
6105 case LEU:
6106 return const0_rtx;
6107 case NE:
6108 case GTU:
6109 return const_true_rtx;
6110 case LT:
6111 case LE:
6112 if (has_sign)
6113 return const_true_rtx;
6114 break;
6115 case GT:
6116 case GE:
6117 if (has_sign)
6118 return const0_rtx;
6119 break;
6120 default:
6121 break;
6127 /* Optimize comparison of ABS with zero. */
6128 if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
6129 && (GET_CODE (trueop0) == ABS
6130 || (GET_CODE (trueop0) == FLOAT_EXTEND
6131 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
6133 switch (code)
6135 case LT:
6136 /* Optimize abs(x) < 0.0. */
6137 if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
6138 return const0_rtx;
6139 break;
6141 case GE:
6142 /* Optimize abs(x) >= 0.0. */
6143 if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
6144 return const_true_rtx;
6145 break;
6147 case UNGE:
6148 /* Optimize ! (abs(x) < 0.0). */
6149 return const_true_rtx;
6151 default:
6152 break;
6156 return 0;
6159 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6160 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6161 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6162 can be simplified to that or NULL_RTX if not.
6163 Assume X is compared against zero with CMP_CODE and the true
6164 arm is TRUE_VAL and the false arm is FALSE_VAL. */
6167 simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
6168 rtx true_val, rtx false_val)
6170 if (cmp_code != EQ && cmp_code != NE)
6171 return NULL_RTX;
6173 /* Result on X == 0 and X !=0 respectively. */
6174 rtx on_zero, on_nonzero;
6175 if (cmp_code == EQ)
6177 on_zero = true_val;
6178 on_nonzero = false_val;
6180 else
6182 on_zero = false_val;
6183 on_nonzero = true_val;
6186 rtx_code op_code = GET_CODE (on_nonzero);
6187 if ((op_code != CLZ && op_code != CTZ)
6188 || !rtx_equal_p (XEXP (on_nonzero, 0), x)
6189 || !CONST_INT_P (on_zero))
6190 return NULL_RTX;
6192 HOST_WIDE_INT op_val;
6193 scalar_int_mode mode ATTRIBUTE_UNUSED
6194 = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
6195 if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
6196 || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
6197 && op_val == INTVAL (on_zero))
6198 return on_nonzero;
6200 return NULL_RTX;
6203 /* Try to simplify X given that it appears within operand OP of a
6204 VEC_MERGE operation whose mask is MASK. X need not use the same
6205 vector mode as the VEC_MERGE, but it must have the same number of
6206 elements.
6208 Return the simplified X on success, otherwise return NULL_RTX. */
6211 simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
6213 gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
6214 poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
6215 if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
6217 if (side_effects_p (XEXP (x, 1 - op)))
6218 return NULL_RTX;
6220 return XEXP (x, op);
6222 if (UNARY_P (x)
6223 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6224 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
6226 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6227 if (top0)
6228 return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
6229 GET_MODE (XEXP (x, 0)));
6231 if (BINARY_P (x)
6232 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6233 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6234 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6235 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
6237 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6238 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6239 if (top0 || top1)
6241 if (COMPARISON_P (x))
6242 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6243 GET_MODE (XEXP (x, 0)) != VOIDmode
6244 ? GET_MODE (XEXP (x, 0))
6245 : GET_MODE (XEXP (x, 1)),
6246 top0 ? top0 : XEXP (x, 0),
6247 top1 ? top1 : XEXP (x, 1));
6248 else
6249 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
6250 top0 ? top0 : XEXP (x, 0),
6251 top1 ? top1 : XEXP (x, 1));
6254 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
6255 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6256 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6257 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6258 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
6259 && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
6260 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
6262 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6263 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6264 rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
6265 if (top0 || top1 || top2)
6266 return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6267 GET_MODE (XEXP (x, 0)),
6268 top0 ? top0 : XEXP (x, 0),
6269 top1 ? top1 : XEXP (x, 1),
6270 top2 ? top2 : XEXP (x, 2));
6272 return NULL_RTX;
6276 /* Simplify CODE, an operation with result mode MODE and three operands,
6277 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6278 a constant. Return 0 if no simplifications is possible. */
6281 simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
6282 machine_mode op0_mode,
6283 rtx op0, rtx op1, rtx op2)
6285 bool any_change = false;
6286 rtx tem, trueop2;
6287 scalar_int_mode int_mode, int_op0_mode;
6288 unsigned int n_elts;
6290 switch (code)
6292 case FMA:
6293 /* Simplify negations around the multiplication. */
6294 /* -a * -b + c => a * b + c. */
6295 if (GET_CODE (op0) == NEG)
6297 tem = simplify_unary_operation (NEG, mode, op1, mode);
6298 if (tem)
6299 op1 = tem, op0 = XEXP (op0, 0), any_change = true;
6301 else if (GET_CODE (op1) == NEG)
6303 tem = simplify_unary_operation (NEG, mode, op0, mode);
6304 if (tem)
6305 op0 = tem, op1 = XEXP (op1, 0), any_change = true;
6308 /* Canonicalize the two multiplication operands. */
6309 /* a * -b + c => -b * a + c. */
6310 if (swap_commutative_operands_p (op0, op1))
6311 std::swap (op0, op1), any_change = true;
6313 if (any_change)
6314 return gen_rtx_FMA (mode, op0, op1, op2);
6315 return NULL_RTX;
6317 case SIGN_EXTRACT:
6318 case ZERO_EXTRACT:
6319 if (CONST_INT_P (op0)
6320 && CONST_INT_P (op1)
6321 && CONST_INT_P (op2)
6322 && is_a <scalar_int_mode> (mode, &int_mode)
6323 && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
6324 && HWI_COMPUTABLE_MODE_P (int_mode))
6326 /* Extracting a bit-field from a constant */
6327 unsigned HOST_WIDE_INT val = UINTVAL (op0);
6328 HOST_WIDE_INT op1val = INTVAL (op1);
6329 HOST_WIDE_INT op2val = INTVAL (op2);
6330 if (!BITS_BIG_ENDIAN)
6331 val >>= op2val;
6332 else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
6333 val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
6334 else
6335 /* Not enough information to calculate the bit position. */
6336 break;
6338 if (HOST_BITS_PER_WIDE_INT != op1val)
6340 /* First zero-extend. */
6341 val &= (HOST_WIDE_INT_1U << op1val) - 1;
6342 /* If desired, propagate sign bit. */
6343 if (code == SIGN_EXTRACT
6344 && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6345 != 0)
6346 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6349 return gen_int_mode (val, int_mode);
6351 break;
6353 case IF_THEN_ELSE:
6354 if (CONST_INT_P (op0))
6355 return op0 != const0_rtx ? op1 : op2;
6357 /* Convert c ? a : a into "a". */
6358 if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6359 return op1;
6361 /* Convert a != b ? a : b into "a". */
6362 if (GET_CODE (op0) == NE
6363 && ! side_effects_p (op0)
6364 && ! HONOR_NANS (mode)
6365 && ! HONOR_SIGNED_ZEROS (mode)
6366 && ((rtx_equal_p (XEXP (op0, 0), op1)
6367 && rtx_equal_p (XEXP (op0, 1), op2))
6368 || (rtx_equal_p (XEXP (op0, 0), op2)
6369 && rtx_equal_p (XEXP (op0, 1), op1))))
6370 return op1;
6372 /* Convert a == b ? a : b into "b". */
6373 if (GET_CODE (op0) == EQ
6374 && ! side_effects_p (op0)
6375 && ! HONOR_NANS (mode)
6376 && ! HONOR_SIGNED_ZEROS (mode)
6377 && ((rtx_equal_p (XEXP (op0, 0), op1)
6378 && rtx_equal_p (XEXP (op0, 1), op2))
6379 || (rtx_equal_p (XEXP (op0, 0), op2)
6380 && rtx_equal_p (XEXP (op0, 1), op1))))
6381 return op2;
6383 /* Convert (!c) != {0,...,0} ? a : b into
6384 c != {0,...,0} ? b : a for vector modes. */
6385 if (VECTOR_MODE_P (GET_MODE (op1))
6386 && GET_CODE (op0) == NE
6387 && GET_CODE (XEXP (op0, 0)) == NOT
6388 && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6390 rtx cv = XEXP (op0, 1);
6391 int nunits;
6392 bool ok = true;
6393 if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6394 ok = false;
6395 else
6396 for (int i = 0; i < nunits; ++i)
6397 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6399 ok = false;
6400 break;
6402 if (ok)
6404 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6405 XEXP (XEXP (op0, 0), 0),
6406 XEXP (op0, 1));
6407 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6408 return retval;
6412 /* Convert x == 0 ? N : clz (x) into clz (x) when
6413 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6414 Similarly for ctz (x). */
6415 if (COMPARISON_P (op0) && !side_effects_p (op0)
6416 && XEXP (op0, 1) == const0_rtx)
6418 rtx simplified
6419 = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6420 op1, op2);
6421 if (simplified)
6422 return simplified;
6425 if (COMPARISON_P (op0) && ! side_effects_p (op0))
6427 machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6428 ? GET_MODE (XEXP (op0, 1))
6429 : GET_MODE (XEXP (op0, 0)));
6430 rtx temp;
6432 /* Look for happy constants in op1 and op2. */
6433 if (CONST_INT_P (op1) && CONST_INT_P (op2))
6435 HOST_WIDE_INT t = INTVAL (op1);
6436 HOST_WIDE_INT f = INTVAL (op2);
6438 if (t == STORE_FLAG_VALUE && f == 0)
6439 code = GET_CODE (op0);
6440 else if (t == 0 && f == STORE_FLAG_VALUE)
6442 enum rtx_code tmp;
6443 tmp = reversed_comparison_code (op0, NULL);
6444 if (tmp == UNKNOWN)
6445 break;
6446 code = tmp;
6448 else
6449 break;
6451 return simplify_gen_relational (code, mode, cmp_mode,
6452 XEXP (op0, 0), XEXP (op0, 1));
6455 temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6456 cmp_mode, XEXP (op0, 0),
6457 XEXP (op0, 1));
6459 /* See if any simplifications were possible. */
6460 if (temp)
6462 if (CONST_INT_P (temp))
6463 return temp == const0_rtx ? op2 : op1;
6464 else if (temp)
6465 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6468 break;
6470 case VEC_MERGE:
6471 gcc_assert (GET_MODE (op0) == mode);
6472 gcc_assert (GET_MODE (op1) == mode);
6473 gcc_assert (VECTOR_MODE_P (mode));
6474 trueop2 = avoid_constant_pool_reference (op2);
6475 if (CONST_INT_P (trueop2)
6476 && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6478 unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6479 unsigned HOST_WIDE_INT mask;
6480 if (n_elts == HOST_BITS_PER_WIDE_INT)
6481 mask = -1;
6482 else
6483 mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6485 if (!(sel & mask) && !side_effects_p (op0))
6486 return op1;
6487 if ((sel & mask) == mask && !side_effects_p (op1))
6488 return op0;
6490 rtx trueop0 = avoid_constant_pool_reference (op0);
6491 rtx trueop1 = avoid_constant_pool_reference (op1);
6492 if (GET_CODE (trueop0) == CONST_VECTOR
6493 && GET_CODE (trueop1) == CONST_VECTOR)
6495 rtvec v = rtvec_alloc (n_elts);
6496 unsigned int i;
6498 for (i = 0; i < n_elts; i++)
6499 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6500 ? CONST_VECTOR_ELT (trueop0, i)
6501 : CONST_VECTOR_ELT (trueop1, i));
6502 return gen_rtx_CONST_VECTOR (mode, v);
6505 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6506 if no element from a appears in the result. */
6507 if (GET_CODE (op0) == VEC_MERGE)
6509 tem = avoid_constant_pool_reference (XEXP (op0, 2));
6510 if (CONST_INT_P (tem))
6512 unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6513 if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6514 return simplify_gen_ternary (code, mode, mode,
6515 XEXP (op0, 1), op1, op2);
6516 if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6517 return simplify_gen_ternary (code, mode, mode,
6518 XEXP (op0, 0), op1, op2);
6521 if (GET_CODE (op1) == VEC_MERGE)
6523 tem = avoid_constant_pool_reference (XEXP (op1, 2));
6524 if (CONST_INT_P (tem))
6526 unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6527 if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6528 return simplify_gen_ternary (code, mode, mode,
6529 op0, XEXP (op1, 1), op2);
6530 if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6531 return simplify_gen_ternary (code, mode, mode,
6532 op0, XEXP (op1, 0), op2);
6536 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6537 with a. */
6538 if (GET_CODE (op0) == VEC_DUPLICATE
6539 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6540 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6541 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6543 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6544 if (CONST_INT_P (tem) && CONST_INT_P (op2))
6546 if (XEXP (XEXP (op0, 0), 0) == op1
6547 && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6548 return op1;
6551 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6552 (const_int N))
6553 with (vec_concat (X) (B)) if N == 1 or
6554 (vec_concat (A) (X)) if N == 2. */
6555 if (GET_CODE (op0) == VEC_DUPLICATE
6556 && GET_CODE (op1) == CONST_VECTOR
6557 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6558 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6559 && IN_RANGE (sel, 1, 2))
6561 rtx newop0 = XEXP (op0, 0);
6562 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6563 if (sel == 2)
6564 std::swap (newop0, newop1);
6565 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6567 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6568 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6569 Only applies for vectors of two elements. */
6570 if (GET_CODE (op0) == VEC_DUPLICATE
6571 && GET_CODE (op1) == VEC_CONCAT
6572 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6573 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6574 && IN_RANGE (sel, 1, 2))
6576 rtx newop0 = XEXP (op0, 0);
6577 rtx newop1 = XEXP (op1, 2 - sel);
6578 rtx otherop = XEXP (op1, sel - 1);
6579 if (sel == 2)
6580 std::swap (newop0, newop1);
6581 /* Don't want to throw away the other part of the vec_concat if
6582 it has side-effects. */
6583 if (!side_effects_p (otherop))
6584 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6587 /* Replace:
6589 (vec_merge:outer (vec_duplicate:outer x:inner)
6590 (subreg:outer y:inner 0)
6591 (const_int N))
6593 with (vec_concat:outer x:inner y:inner) if N == 1,
6594 or (vec_concat:outer y:inner x:inner) if N == 2.
6596 Implicitly, this means we have a paradoxical subreg, but such
6597 a check is cheap, so make it anyway.
6599 Only applies for vectors of two elements. */
6600 if (GET_CODE (op0) == VEC_DUPLICATE
6601 && GET_CODE (op1) == SUBREG
6602 && GET_MODE (op1) == GET_MODE (op0)
6603 && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6604 && paradoxical_subreg_p (op1)
6605 && subreg_lowpart_p (op1)
6606 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6607 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6608 && IN_RANGE (sel, 1, 2))
6610 rtx newop0 = XEXP (op0, 0);
6611 rtx newop1 = SUBREG_REG (op1);
6612 if (sel == 2)
6613 std::swap (newop0, newop1);
6614 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6617 /* Same as above but with switched operands:
6618 Replace (vec_merge:outer (subreg:outer x:inner 0)
6619 (vec_duplicate:outer y:inner)
6620 (const_int N))
6622 with (vec_concat:outer x:inner y:inner) if N == 1,
6623 or (vec_concat:outer y:inner x:inner) if N == 2. */
6624 if (GET_CODE (op1) == VEC_DUPLICATE
6625 && GET_CODE (op0) == SUBREG
6626 && GET_MODE (op0) == GET_MODE (op1)
6627 && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
6628 && paradoxical_subreg_p (op0)
6629 && subreg_lowpart_p (op0)
6630 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6631 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6632 && IN_RANGE (sel, 1, 2))
6634 rtx newop0 = SUBREG_REG (op0);
6635 rtx newop1 = XEXP (op1, 0);
6636 if (sel == 2)
6637 std::swap (newop0, newop1);
6638 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6641 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
6642 (const_int n))
6643 with (vec_concat x y) or (vec_concat y x) depending on value
6644 of N. */
6645 if (GET_CODE (op0) == VEC_DUPLICATE
6646 && GET_CODE (op1) == VEC_DUPLICATE
6647 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6648 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6649 && IN_RANGE (sel, 1, 2))
6651 rtx newop0 = XEXP (op0, 0);
6652 rtx newop1 = XEXP (op1, 0);
6653 if (sel == 2)
6654 std::swap (newop0, newop1);
6656 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6660 if (rtx_equal_p (op0, op1)
6661 && !side_effects_p (op2) && !side_effects_p (op1))
6662 return op0;
6664 if (!side_effects_p (op2))
6666 rtx top0
6667 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6668 rtx top1
6669 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6670 if (top0 || top1)
6671 return simplify_gen_ternary (code, mode, mode,
6672 top0 ? top0 : op0,
6673 top1 ? top1 : op1, op2);
6676 break;
6678 default:
6679 gcc_unreachable ();
6682 return 0;
6685 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6686 starting at byte FIRST_BYTE. Return true on success and add the
6687 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6688 that the bytes follow target memory order. Leave BYTES unmodified
6689 on failure.
6691 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6692 BYTES before calling this function. */
6694 bool
6695 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6696 unsigned int first_byte, unsigned int num_bytes)
6698 /* Check the mode is sensible. */
6699 gcc_assert (GET_MODE (x) == VOIDmode
6700 ? is_a <scalar_int_mode> (mode)
6701 : mode == GET_MODE (x));
6703 if (GET_CODE (x) == CONST_VECTOR)
6705 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
6706 is necessary. The only complication is that MODE_VECTOR_BOOL
6707 vectors can have several elements per byte. */
6708 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6709 GET_MODE_NUNITS (mode));
6710 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
6711 if (elt_bits < BITS_PER_UNIT)
6713 /* This is the only case in which elements can be smaller than
6714 a byte. */
6715 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6716 for (unsigned int i = 0; i < num_bytes; ++i)
6718 target_unit value = 0;
6719 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
6721 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & 1) << j;
6722 elt += 1;
6724 bytes.quick_push (value);
6726 return true;
6729 unsigned int start = bytes.length ();
6730 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
6731 /* Make FIRST_BYTE relative to ELT. */
6732 first_byte %= elt_bytes;
6733 while (num_bytes > 0)
6735 /* Work out how many bytes we want from element ELT. */
6736 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
6737 if (!native_encode_rtx (GET_MODE_INNER (mode),
6738 CONST_VECTOR_ELT (x, elt), bytes,
6739 first_byte, chunk_bytes))
6741 bytes.truncate (start);
6742 return false;
6744 elt += 1;
6745 first_byte = 0;
6746 num_bytes -= chunk_bytes;
6748 return true;
6751 /* All subsequent cases are limited to scalars. */
6752 scalar_mode smode;
6753 if (!is_a <scalar_mode> (mode, &smode))
6754 return false;
6756 /* Make sure that the region is in range. */
6757 unsigned int end_byte = first_byte + num_bytes;
6758 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6759 gcc_assert (end_byte <= mode_bytes);
6761 if (CONST_SCALAR_INT_P (x))
6763 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
6764 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
6765 position of each byte. */
6766 rtx_mode_t value (x, smode);
6767 wide_int_ref value_wi (value);
6768 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6770 /* Always constant because the inputs are. */
6771 unsigned int lsb
6772 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6773 /* Operate directly on the encoding rather than using
6774 wi::extract_uhwi, so that we preserve the sign or zero
6775 extension for modes that are not a whole number of bits in
6776 size. (Zero extension is only used for the combination of
6777 innermode == BImode && STORE_FLAG_VALUE == 1). */
6778 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
6779 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
6780 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
6781 bytes.quick_push (uhwi >> shift);
6783 return true;
6786 if (CONST_DOUBLE_P (x))
6788 /* real_to_target produces an array of integers in target memory order.
6789 All integers before the last one have 32 bits; the last one may
6790 have 32 bits or fewer, depending on whether the mode bitsize
6791 is divisible by 32. Each of these integers is then laid out
6792 in target memory as any other integer would be. */
6793 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6794 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
6796 /* The (maximum) number of target bytes per element of el32. */
6797 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6798 gcc_assert (bytes_per_el32 != 0);
6800 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
6801 handling above. */
6802 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6804 unsigned int index = byte / bytes_per_el32;
6805 unsigned int subbyte = byte % bytes_per_el32;
6806 unsigned int int_bytes = MIN (bytes_per_el32,
6807 mode_bytes - index * bytes_per_el32);
6808 /* Always constant because the inputs are. */
6809 unsigned int lsb
6810 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6811 bytes.quick_push ((unsigned long) el32[index] >> lsb);
6813 return true;
6816 if (GET_CODE (x) == CONST_FIXED)
6818 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6820 /* Always constant because the inputs are. */
6821 unsigned int lsb
6822 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6823 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
6824 if (lsb >= HOST_BITS_PER_WIDE_INT)
6826 lsb -= HOST_BITS_PER_WIDE_INT;
6827 piece = CONST_FIXED_VALUE_HIGH (x);
6829 bytes.quick_push (piece >> lsb);
6831 return true;
6834 return false;
6837 /* Read a vector of mode MODE from the target memory image given by BYTES,
6838 starting at byte FIRST_BYTE. The vector is known to be encodable using
6839 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
6840 and BYTES is known to have enough bytes to supply NPATTERNS *
6841 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
6842 BITS_PER_UNIT bits and the bytes are in target memory order.
6844 Return the vector on success, otherwise return NULL_RTX. */
6847 native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
6848 unsigned int first_byte, unsigned int npatterns,
6849 unsigned int nelts_per_pattern)
6851 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
6853 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6854 GET_MODE_NUNITS (mode));
6855 if (elt_bits < BITS_PER_UNIT)
6857 /* This is the only case in which elements can be smaller than a byte.
6858 Element 0 is always in the lsb of the containing byte. */
6859 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6860 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6862 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
6863 unsigned int byte_index = bit_index / BITS_PER_UNIT;
6864 unsigned int lsb = bit_index % BITS_PER_UNIT;
6865 builder.quick_push (bytes[byte_index] & (1 << lsb)
6866 ? CONST1_RTX (BImode)
6867 : CONST0_RTX (BImode));
6870 else
6872 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6874 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
6875 if (!x)
6876 return NULL_RTX;
6877 builder.quick_push (x);
6878 first_byte += elt_bits / BITS_PER_UNIT;
6881 return builder.build ();
6884 /* Read an rtx of mode MODE from the target memory image given by BYTES,
6885 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
6886 bits and the bytes are in target memory order. The image has enough
6887 values to specify all bytes of MODE.
6889 Return the rtx on success, otherwise return NULL_RTX. */
6892 native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
6893 unsigned int first_byte)
6895 if (VECTOR_MODE_P (mode))
6897 /* If we know at compile time how many elements there are,
6898 pull each element directly from BYTES. */
6899 unsigned int nelts;
6900 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
6901 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
6902 return NULL_RTX;
6905 scalar_int_mode imode;
6906 if (is_a <scalar_int_mode> (mode, &imode)
6907 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
6909 /* Pull the bytes msb first, so that we can use simple
6910 shift-and-insert wide_int operations. */
6911 unsigned int size = GET_MODE_SIZE (imode);
6912 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
6913 for (unsigned int i = 0; i < size; ++i)
6915 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
6916 /* Always constant because the inputs are. */
6917 unsigned int subbyte
6918 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
6919 result <<= BITS_PER_UNIT;
6920 result |= bytes[first_byte + subbyte];
6922 return immed_wide_int_const (result, imode);
6925 scalar_float_mode fmode;
6926 if (is_a <scalar_float_mode> (mode, &fmode))
6928 /* We need to build an array of integers in target memory order.
6929 All integers before the last one have 32 bits; the last one may
6930 have 32 bits or fewer, depending on whether the mode bitsize
6931 is divisible by 32. */
6932 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6933 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
6934 memset (el32, 0, num_el32 * sizeof (long));
6936 /* The (maximum) number of target bytes per element of el32. */
6937 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6938 gcc_assert (bytes_per_el32 != 0);
6940 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
6941 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6943 unsigned int index = byte / bytes_per_el32;
6944 unsigned int subbyte = byte % bytes_per_el32;
6945 unsigned int int_bytes = MIN (bytes_per_el32,
6946 mode_bytes - index * bytes_per_el32);
6947 /* Always constant because the inputs are. */
6948 unsigned int lsb
6949 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6950 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
6952 REAL_VALUE_TYPE r;
6953 real_from_target (&r, el32, fmode);
6954 return const_double_from_real_value (r, fmode);
6957 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
6959 scalar_mode smode = as_a <scalar_mode> (mode);
6960 FIXED_VALUE_TYPE f;
6961 f.data.low = 0;
6962 f.data.high = 0;
6963 f.mode = smode;
6965 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6966 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6968 /* Always constant because the inputs are. */
6969 unsigned int lsb
6970 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6971 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
6972 if (lsb >= HOST_BITS_PER_WIDE_INT)
6973 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
6974 else
6975 f.data.low |= unit << lsb;
6977 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
6980 return NULL_RTX;
6983 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
6984 is to convert a runtime BYTE value into a constant one. */
6986 static poly_uint64
6987 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
6989 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6990 machine_mode mode = GET_MODE (x);
6991 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6992 GET_MODE_NUNITS (mode));
6993 /* The number of bits needed to encode one element from each pattern. */
6994 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
6996 /* Identify the start point in terms of a sequence number and a byte offset
6997 within that sequence. */
6998 poly_uint64 first_sequence;
6999 unsigned HOST_WIDE_INT subbit;
7000 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
7001 &first_sequence, &subbit))
7003 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7004 if (nelts_per_pattern == 1)
7005 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
7006 doesn't matter. */
7007 byte = subbit / BITS_PER_UNIT;
7008 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
7010 /* The subreg drops the first element from each pattern and
7011 only uses the second element. Find the first sequence
7012 that starts on a byte boundary. */
7013 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
7014 byte = subbit / BITS_PER_UNIT;
7017 return byte;
7020 /* Subroutine of simplify_subreg in which:
7022 - X is known to be a CONST_VECTOR
7023 - OUTERMODE is known to be a vector mode
7025 Try to handle the subreg by operating on the CONST_VECTOR encoding
7026 rather than on each individual element of the CONST_VECTOR.
7028 Return the simplified subreg on success, otherwise return NULL_RTX. */
7030 static rtx
7031 simplify_const_vector_subreg (machine_mode outermode, rtx x,
7032 machine_mode innermode, unsigned int first_byte)
7034 /* Paradoxical subregs of vectors have dubious semantics. */
7035 if (paradoxical_subreg_p (outermode, innermode))
7036 return NULL_RTX;
7038 /* We can only preserve the semantics of a stepped pattern if the new
7039 vector element is the same as the original one. */
7040 if (CONST_VECTOR_STEPPED_P (x)
7041 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
7042 return NULL_RTX;
7044 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7045 unsigned int x_elt_bits
7046 = vector_element_size (GET_MODE_BITSIZE (innermode),
7047 GET_MODE_NUNITS (innermode));
7048 unsigned int out_elt_bits
7049 = vector_element_size (GET_MODE_BITSIZE (outermode),
7050 GET_MODE_NUNITS (outermode));
7052 /* The number of bits needed to encode one element from every pattern
7053 of the original vector. */
7054 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
7056 /* The number of bits needed to encode one element from every pattern
7057 of the result. */
7058 unsigned int out_sequence_bits
7059 = least_common_multiple (x_sequence_bits, out_elt_bits);
7061 /* Work out the number of interleaved patterns in the output vector
7062 and the number of encoded elements per pattern. */
7063 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
7064 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7066 /* The encoding scheme requires the number of elements to be a multiple
7067 of the number of patterns, so that each pattern appears at least once
7068 and so that the same number of elements appear from each pattern. */
7069 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
7070 unsigned int const_nunits;
7071 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
7072 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
7074 /* Either the encoding is invalid, or applying it would give us
7075 more elements than we need. Just encode each element directly. */
7076 out_npatterns = const_nunits;
7077 nelts_per_pattern = 1;
7079 else if (!ok_p)
7080 return NULL_RTX;
7082 /* Get enough bytes of X to form the new encoding. */
7083 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
7084 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
7085 auto_vec<target_unit, 128> buffer (buffer_bytes);
7086 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
7087 return NULL_RTX;
7089 /* Reencode the bytes as OUTERMODE. */
7090 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
7091 nelts_per_pattern);
7094 /* Try to simplify a subreg of a constant by encoding the subreg region
7095 as a sequence of target bytes and reading them back in the new mode.
7096 Return the new value on success, otherwise return null.
7098 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7099 and byte offset FIRST_BYTE. */
7101 static rtx
7102 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
7103 machine_mode innermode, unsigned int first_byte)
7105 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
7106 auto_vec<target_unit, 128> buffer (buffer_bytes);
7108 /* Some ports misuse CCmode. */
7109 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
7110 return x;
7112 /* Paradoxical subregs read undefined values for bytes outside of the
7113 inner value. However, we have traditionally always sign-extended
7114 integer constants and zero-extended others. */
7115 unsigned int inner_bytes = buffer_bytes;
7116 if (paradoxical_subreg_p (outermode, innermode))
7118 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
7119 return NULL_RTX;
7121 target_unit filler = 0;
7122 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
7123 filler = -1;
7125 /* Add any leading bytes due to big-endian layout. The number of
7126 bytes must be constant because both modes have constant size. */
7127 unsigned int leading_bytes
7128 = -byte_lowpart_offset (outermode, innermode).to_constant ();
7129 for (unsigned int i = 0; i < leading_bytes; ++i)
7130 buffer.quick_push (filler);
7132 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7133 return NULL_RTX;
7135 /* Add any trailing bytes due to little-endian layout. */
7136 while (buffer.length () < buffer_bytes)
7137 buffer.quick_push (filler);
7139 else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7140 return NULL_RTX;
7141 rtx ret = native_decode_rtx (outermode, buffer, 0);
7142 if (ret && MODE_COMPOSITE_P (outermode))
7144 auto_vec<target_unit, 128> buffer2 (buffer_bytes);
7145 if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
7146 return NULL_RTX;
7147 for (unsigned int i = 0; i < buffer_bytes; ++i)
7148 if (buffer[i] != buffer2[i])
7149 return NULL_RTX;
7151 return ret;
7154 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7155 Return 0 if no simplifications are possible. */
7157 simplify_context::simplify_subreg (machine_mode outermode, rtx op,
7158 machine_mode innermode, poly_uint64 byte)
7160 /* Little bit of sanity checking. */
7161 gcc_assert (innermode != VOIDmode);
7162 gcc_assert (outermode != VOIDmode);
7163 gcc_assert (innermode != BLKmode);
7164 gcc_assert (outermode != BLKmode);
7166 gcc_assert (GET_MODE (op) == innermode
7167 || GET_MODE (op) == VOIDmode);
7169 poly_uint64 outersize = GET_MODE_SIZE (outermode);
7170 if (!multiple_p (byte, outersize))
7171 return NULL_RTX;
7173 poly_uint64 innersize = GET_MODE_SIZE (innermode);
7174 if (maybe_ge (byte, innersize))
7175 return NULL_RTX;
7177 if (outermode == innermode && known_eq (byte, 0U))
7178 return op;
7180 if (GET_CODE (op) == CONST_VECTOR)
7181 byte = simplify_const_vector_byte_offset (op, byte);
7183 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
7185 rtx elt;
7187 if (VECTOR_MODE_P (outermode)
7188 && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
7189 && vec_duplicate_p (op, &elt))
7190 return gen_vec_duplicate (outermode, elt);
7192 if (outermode == GET_MODE_INNER (innermode)
7193 && vec_duplicate_p (op, &elt))
7194 return elt;
7197 if (CONST_SCALAR_INT_P (op)
7198 || CONST_DOUBLE_AS_FLOAT_P (op)
7199 || CONST_FIXED_P (op)
7200 || GET_CODE (op) == CONST_VECTOR)
7202 unsigned HOST_WIDE_INT cbyte;
7203 if (byte.is_constant (&cbyte))
7205 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
7207 rtx tmp = simplify_const_vector_subreg (outermode, op,
7208 innermode, cbyte);
7209 if (tmp)
7210 return tmp;
7213 fixed_size_mode fs_outermode;
7214 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
7215 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
7219 /* Changing mode twice with SUBREG => just change it once,
7220 or not at all if changing back op starting mode. */
7221 if (GET_CODE (op) == SUBREG)
7223 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
7224 poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
7225 rtx newx;
7227 if (outermode == innermostmode
7228 && known_eq (byte, 0U)
7229 && known_eq (SUBREG_BYTE (op), 0))
7230 return SUBREG_REG (op);
7232 /* Work out the memory offset of the final OUTERMODE value relative
7233 to the inner value of OP. */
7234 poly_int64 mem_offset = subreg_memory_offset (outermode,
7235 innermode, byte);
7236 poly_int64 op_mem_offset = subreg_memory_offset (op);
7237 poly_int64 final_offset = mem_offset + op_mem_offset;
7239 /* See whether resulting subreg will be paradoxical. */
7240 if (!paradoxical_subreg_p (outermode, innermostmode))
7242 /* Bail out in case resulting subreg would be incorrect. */
7243 if (maybe_lt (final_offset, 0)
7244 || maybe_ge (poly_uint64 (final_offset), innermostsize)
7245 || !multiple_p (final_offset, outersize))
7246 return NULL_RTX;
7248 else
7250 poly_int64 required_offset = subreg_memory_offset (outermode,
7251 innermostmode, 0);
7252 if (maybe_ne (final_offset, required_offset))
7253 return NULL_RTX;
7254 /* Paradoxical subregs always have byte offset 0. */
7255 final_offset = 0;
7258 /* Recurse for further possible simplifications. */
7259 newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
7260 final_offset);
7261 if (newx)
7262 return newx;
7263 if (validate_subreg (outermode, innermostmode,
7264 SUBREG_REG (op), final_offset))
7266 newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
7267 if (SUBREG_PROMOTED_VAR_P (op)
7268 && SUBREG_PROMOTED_SIGN (op) >= 0
7269 && GET_MODE_CLASS (outermode) == MODE_INT
7270 && known_ge (outersize, innersize)
7271 && known_le (outersize, innermostsize)
7272 && subreg_lowpart_p (newx))
7274 SUBREG_PROMOTED_VAR_P (newx) = 1;
7275 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
7277 return newx;
7279 return NULL_RTX;
7282 /* SUBREG of a hard register => just change the register number
7283 and/or mode. If the hard register is not valid in that mode,
7284 suppress this simplification. If the hard register is the stack,
7285 frame, or argument pointer, leave this as a SUBREG. */
7287 if (REG_P (op) && HARD_REGISTER_P (op))
7289 unsigned int regno, final_regno;
7291 regno = REGNO (op);
7292 final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
7293 if (HARD_REGISTER_NUM_P (final_regno))
7295 rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
7296 subreg_memory_offset (outermode,
7297 innermode, byte));
7299 /* Propagate original regno. We don't have any way to specify
7300 the offset inside original regno, so do so only for lowpart.
7301 The information is used only by alias analysis that cannot
7302 grog partial register anyway. */
7304 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
7305 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
7306 return x;
7310 /* If we have a SUBREG of a register that we are replacing and we are
7311 replacing it with a MEM, make a new MEM and try replacing the
7312 SUBREG with it. Don't do this if the MEM has a mode-dependent address
7313 or if we would be widening it. */
7315 if (MEM_P (op)
7316 && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
7317 /* Allow splitting of volatile memory references in case we don't
7318 have instruction to move the whole thing. */
7319 && (! MEM_VOLATILE_P (op)
7320 || ! have_insn_for (SET, innermode))
7321 && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
7322 && known_le (outersize, innersize))
7323 return adjust_address_nv (op, outermode, byte);
7325 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7326 of two parts. */
7327 if (GET_CODE (op) == CONCAT
7328 || GET_CODE (op) == VEC_CONCAT)
7330 poly_uint64 final_offset;
7331 rtx part, res;
7333 machine_mode part_mode = GET_MODE (XEXP (op, 0));
7334 if (part_mode == VOIDmode)
7335 part_mode = GET_MODE_INNER (GET_MODE (op));
7336 poly_uint64 part_size = GET_MODE_SIZE (part_mode);
7337 if (known_lt (byte, part_size))
7339 part = XEXP (op, 0);
7340 final_offset = byte;
7342 else if (known_ge (byte, part_size))
7344 part = XEXP (op, 1);
7345 final_offset = byte - part_size;
7347 else
7348 return NULL_RTX;
7350 if (maybe_gt (final_offset + outersize, part_size))
7351 return NULL_RTX;
7353 part_mode = GET_MODE (part);
7354 if (part_mode == VOIDmode)
7355 part_mode = GET_MODE_INNER (GET_MODE (op));
7356 res = simplify_subreg (outermode, part, part_mode, final_offset);
7357 if (res)
7358 return res;
7359 if (validate_subreg (outermode, part_mode, part, final_offset))
7360 return gen_rtx_SUBREG (outermode, part, final_offset);
7361 return NULL_RTX;
7364 /* Simplify
7365 (subreg (vec_merge (X)
7366 (vector)
7367 (const_int ((1 << N) | M)))
7368 (N * sizeof (outermode)))
7370 (subreg (X) (N * sizeof (outermode)))
7372 unsigned int idx;
7373 if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7374 && idx < HOST_BITS_PER_WIDE_INT
7375 && GET_CODE (op) == VEC_MERGE
7376 && GET_MODE_INNER (innermode) == outermode
7377 && CONST_INT_P (XEXP (op, 2))
7378 && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7379 return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7381 /* A SUBREG resulting from a zero extension may fold to zero if
7382 it extracts higher bits that the ZERO_EXTEND's source bits. */
7383 if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7385 poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7386 if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7387 return CONST0_RTX (outermode);
7390 scalar_int_mode int_outermode, int_innermode;
7391 if (is_a <scalar_int_mode> (outermode, &int_outermode)
7392 && is_a <scalar_int_mode> (innermode, &int_innermode)
7393 && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7395 /* Handle polynomial integers. The upper bits of a paradoxical
7396 subreg are undefined, so this is safe regardless of whether
7397 we're truncating or extending. */
7398 if (CONST_POLY_INT_P (op))
7400 poly_wide_int val
7401 = poly_wide_int::from (const_poly_int_value (op),
7402 GET_MODE_PRECISION (int_outermode),
7403 SIGNED);
7404 return immed_wide_int_const (val, int_outermode);
7407 if (GET_MODE_PRECISION (int_outermode)
7408 < GET_MODE_PRECISION (int_innermode))
7410 rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7411 if (tem)
7412 return tem;
7416 /* If OP is a vector comparison and the subreg is not changing the
7417 number of elements or the size of the elements, change the result
7418 of the comparison to the new mode. */
7419 if (COMPARISON_P (op)
7420 && VECTOR_MODE_P (outermode)
7421 && VECTOR_MODE_P (innermode)
7422 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7423 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7424 GET_MODE_UNIT_SIZE (innermode)))
7425 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7426 XEXP (op, 0), XEXP (op, 1));
7427 return NULL_RTX;
7430 /* Make a SUBREG operation or equivalent if it folds. */
7433 simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
7434 machine_mode innermode,
7435 poly_uint64 byte)
7437 rtx newx;
7439 newx = simplify_subreg (outermode, op, innermode, byte);
7440 if (newx)
7441 return newx;
7443 if (GET_CODE (op) == SUBREG
7444 || GET_CODE (op) == CONCAT
7445 || GET_MODE (op) == VOIDmode)
7446 return NULL_RTX;
7448 if (MODE_COMPOSITE_P (outermode)
7449 && (CONST_SCALAR_INT_P (op)
7450 || CONST_DOUBLE_AS_FLOAT_P (op)
7451 || CONST_FIXED_P (op)
7452 || GET_CODE (op) == CONST_VECTOR))
7453 return NULL_RTX;
7455 if (validate_subreg (outermode, innermode, op, byte))
7456 return gen_rtx_SUBREG (outermode, op, byte);
7458 return NULL_RTX;
7461 /* Generates a subreg to get the least significant part of EXPR (in mode
7462 INNER_MODE) to OUTER_MODE. */
7465 simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
7466 machine_mode inner_mode)
7468 return simplify_gen_subreg (outer_mode, expr, inner_mode,
7469 subreg_lowpart_offset (outer_mode, inner_mode));
7472 /* Simplify X, an rtx expression.
7474 Return the simplified expression or NULL if no simplifications
7475 were possible.
7477 This is the preferred entry point into the simplification routines;
7478 however, we still allow passes to call the more specific routines.
7480 Right now GCC has three (yes, three) major bodies of RTL simplification
7481 code that need to be unified.
7483 1. fold_rtx in cse.c. This code uses various CSE specific
7484 information to aid in RTL simplification.
7486 2. simplify_rtx in combine.c. Similar to fold_rtx, except that
7487 it uses combine specific information to aid in RTL
7488 simplification.
7490 3. The routines in this file.
7493 Long term we want to only have one body of simplification code; to
7494 get to that state I recommend the following steps:
7496 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7497 which are not pass dependent state into these routines.
7499 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7500 use this routine whenever possible.
7502 3. Allow for pass dependent state to be provided to these
7503 routines and add simplifications based on the pass dependent
7504 state. Remove code from cse.c & combine.c that becomes
7505 redundant/dead.
7507 It will take time, but ultimately the compiler will be easier to
7508 maintain and improve. It's totally silly that when we add a
7509 simplification that it needs to be added to 4 places (3 for RTL
7510 simplification and 1 for tree simplification. */
7513 simplify_rtx (const_rtx x)
7515 const enum rtx_code code = GET_CODE (x);
7516 const machine_mode mode = GET_MODE (x);
7518 switch (GET_RTX_CLASS (code))
7520 case RTX_UNARY:
7521 return simplify_unary_operation (code, mode,
7522 XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7523 case RTX_COMM_ARITH:
7524 if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7525 return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7527 /* Fall through. */
7529 case RTX_BIN_ARITH:
7530 return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7532 case RTX_TERNARY:
7533 case RTX_BITFIELD_OPS:
7534 return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7535 XEXP (x, 0), XEXP (x, 1),
7536 XEXP (x, 2));
7538 case RTX_COMPARE:
7539 case RTX_COMM_COMPARE:
7540 return simplify_relational_operation (code, mode,
7541 ((GET_MODE (XEXP (x, 0))
7542 != VOIDmode)
7543 ? GET_MODE (XEXP (x, 0))
7544 : GET_MODE (XEXP (x, 1))),
7545 XEXP (x, 0),
7546 XEXP (x, 1));
7548 case RTX_EXTRA:
7549 if (code == SUBREG)
7550 return simplify_subreg (mode, SUBREG_REG (x),
7551 GET_MODE (SUBREG_REG (x)),
7552 SUBREG_BYTE (x));
7553 break;
7555 case RTX_OBJ:
7556 if (code == LO_SUM)
7558 /* Convert (lo_sum (high FOO) FOO) to FOO. */
7559 if (GET_CODE (XEXP (x, 0)) == HIGH
7560 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
7561 return XEXP (x, 1);
7563 break;
7565 default:
7566 break;
7568 return NULL;
7571 #if CHECKING_P
7573 namespace selftest {
7575 /* Make a unique pseudo REG of mode MODE for use by selftests. */
7577 static rtx
7578 make_test_reg (machine_mode mode)
7580 static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
7582 return gen_rtx_REG (mode, test_reg_num++);
7585 static void
7586 test_scalar_int_ops (machine_mode mode)
7588 rtx op0 = make_test_reg (mode);
7589 rtx op1 = make_test_reg (mode);
7590 rtx six = GEN_INT (6);
7592 rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
7593 rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
7594 rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
7596 rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
7597 rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
7598 rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
7600 rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
7601 rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
7603 /* Test some binary identities. */
7604 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
7605 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
7606 ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
7607 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
7608 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
7609 ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
7610 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
7611 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
7612 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
7613 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
7614 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
7615 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
7616 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
7617 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
7618 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
7619 ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
7620 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
7622 /* Test some self-inverse operations. */
7623 ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
7624 ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
7625 ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
7627 /* Test some reflexive operations. */
7628 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
7629 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
7630 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
7631 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
7632 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
7633 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
7635 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
7636 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
7638 /* Test simplify_distributive_operation. */
7639 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
7640 simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
7641 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
7642 simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
7643 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
7644 simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
7646 /* Test useless extensions are eliminated. */
7647 ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
7648 ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
7649 ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
7650 ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
7653 /* Verify some simplifications of integer extension/truncation.
7654 Machine mode BMODE is the guaranteed wider than SMODE. */
7656 static void
7657 test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
7659 rtx sreg = make_test_reg (smode);
7661 /* Check truncation of extension. */
7662 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7663 simplify_gen_unary (ZERO_EXTEND, bmode,
7664 sreg, smode),
7665 bmode),
7666 sreg);
7667 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7668 simplify_gen_unary (SIGN_EXTEND, bmode,
7669 sreg, smode),
7670 bmode),
7671 sreg);
7672 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7673 lowpart_subreg (bmode, sreg, smode),
7674 bmode),
7675 sreg);
7678 /* Verify more simplifications of integer extension/truncation.
7679 BMODE is wider than MMODE which is wider than SMODE. */
7681 static void
7682 test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
7683 machine_mode smode)
7685 rtx breg = make_test_reg (bmode);
7686 rtx mreg = make_test_reg (mmode);
7687 rtx sreg = make_test_reg (smode);
7689 /* Check truncate of truncate. */
7690 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7691 simplify_gen_unary (TRUNCATE, mmode,
7692 breg, bmode),
7693 mmode),
7694 simplify_gen_unary (TRUNCATE, smode, breg, bmode));
7696 /* Check extension of extension. */
7697 ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
7698 simplify_gen_unary (ZERO_EXTEND, mmode,
7699 sreg, smode),
7700 mmode),
7701 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
7702 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
7703 simplify_gen_unary (SIGN_EXTEND, mmode,
7704 sreg, smode),
7705 mmode),
7706 simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
7707 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
7708 simplify_gen_unary (ZERO_EXTEND, mmode,
7709 sreg, smode),
7710 mmode),
7711 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
7713 /* Check truncation of extension. */
7714 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7715 simplify_gen_unary (ZERO_EXTEND, bmode,
7716 mreg, mmode),
7717 bmode),
7718 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
7719 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7720 simplify_gen_unary (SIGN_EXTEND, bmode,
7721 mreg, mmode),
7722 bmode),
7723 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
7724 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7725 lowpart_subreg (bmode, mreg, mmode),
7726 bmode),
7727 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
7731 /* Verify some simplifications involving scalar expressions. */
7733 static void
7734 test_scalar_ops ()
7736 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
7738 machine_mode mode = (machine_mode) i;
7739 if (SCALAR_INT_MODE_P (mode) && mode != BImode)
7740 test_scalar_int_ops (mode);
7743 test_scalar_int_ext_ops (HImode, QImode);
7744 test_scalar_int_ext_ops (SImode, QImode);
7745 test_scalar_int_ext_ops (SImode, HImode);
7746 test_scalar_int_ext_ops (DImode, QImode);
7747 test_scalar_int_ext_ops (DImode, HImode);
7748 test_scalar_int_ext_ops (DImode, SImode);
7750 test_scalar_int_ext_ops2 (SImode, HImode, QImode);
7751 test_scalar_int_ext_ops2 (DImode, HImode, QImode);
7752 test_scalar_int_ext_ops2 (DImode, SImode, QImode);
7753 test_scalar_int_ext_ops2 (DImode, SImode, HImode);
7756 /* Test vector simplifications involving VEC_DUPLICATE in which the
7757 operands and result have vector mode MODE. SCALAR_REG is a pseudo
7758 register that holds one element of MODE. */
7760 static void
7761 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
7763 scalar_mode inner_mode = GET_MODE_INNER (mode);
7764 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
7765 poly_uint64 nunits = GET_MODE_NUNITS (mode);
7766 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
7768 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
7769 rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
7770 rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
7771 ASSERT_RTX_EQ (duplicate,
7772 simplify_unary_operation (NOT, mode,
7773 duplicate_not, mode));
7775 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
7776 rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
7777 ASSERT_RTX_EQ (duplicate,
7778 simplify_unary_operation (NEG, mode,
7779 duplicate_neg, mode));
7781 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
7782 ASSERT_RTX_EQ (duplicate,
7783 simplify_binary_operation (PLUS, mode, duplicate,
7784 CONST0_RTX (mode)));
7786 ASSERT_RTX_EQ (duplicate,
7787 simplify_binary_operation (MINUS, mode, duplicate,
7788 CONST0_RTX (mode)));
7790 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
7791 simplify_binary_operation (MINUS, mode, duplicate,
7792 duplicate));
7795 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
7796 rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
7797 ASSERT_RTX_PTR_EQ (scalar_reg,
7798 simplify_binary_operation (VEC_SELECT, inner_mode,
7799 duplicate, zero_par));
7801 unsigned HOST_WIDE_INT const_nunits;
7802 if (nunits.is_constant (&const_nunits))
7804 /* And again with the final element. */
7805 rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
7806 rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
7807 ASSERT_RTX_PTR_EQ (scalar_reg,
7808 simplify_binary_operation (VEC_SELECT, inner_mode,
7809 duplicate, last_par));
7811 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
7812 rtx vector_reg = make_test_reg (mode);
7813 for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
7815 if (i >= HOST_BITS_PER_WIDE_INT)
7816 break;
7817 rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
7818 rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
7819 poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
7820 ASSERT_RTX_EQ (scalar_reg,
7821 simplify_gen_subreg (inner_mode, vm,
7822 mode, offset));
7826 /* Test a scalar subreg of a VEC_DUPLICATE. */
7827 poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
7828 ASSERT_RTX_EQ (scalar_reg,
7829 simplify_gen_subreg (inner_mode, duplicate,
7830 mode, offset));
7832 machine_mode narrower_mode;
7833 if (maybe_ne (nunits, 2U)
7834 && multiple_p (nunits, 2)
7835 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
7836 && VECTOR_MODE_P (narrower_mode))
7838 /* Test VEC_DUPLICATE of a vector. */
7839 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
7840 nbuilder.quick_push (const0_rtx);
7841 nbuilder.quick_push (const1_rtx);
7842 rtx_vector_builder builder (mode, 2, 1);
7843 builder.quick_push (const0_rtx);
7844 builder.quick_push (const1_rtx);
7845 ASSERT_RTX_EQ (builder.build (),
7846 simplify_unary_operation (VEC_DUPLICATE, mode,
7847 nbuilder.build (),
7848 narrower_mode));
7850 /* Test VEC_SELECT of a vector. */
7851 rtx vec_par
7852 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
7853 rtx narrower_duplicate
7854 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
7855 ASSERT_RTX_EQ (narrower_duplicate,
7856 simplify_binary_operation (VEC_SELECT, narrower_mode,
7857 duplicate, vec_par));
7859 /* Test a vector subreg of a VEC_DUPLICATE. */
7860 poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
7861 ASSERT_RTX_EQ (narrower_duplicate,
7862 simplify_gen_subreg (narrower_mode, duplicate,
7863 mode, offset));
7867 /* Test vector simplifications involving VEC_SERIES in which the
7868 operands and result have vector mode MODE. SCALAR_REG is a pseudo
7869 register that holds one element of MODE. */
7871 static void
7872 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
7874 /* Test unary cases with VEC_SERIES arguments. */
7875 scalar_mode inner_mode = GET_MODE_INNER (mode);
7876 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
7877 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
7878 rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
7879 rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
7880 rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
7881 rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
7882 rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
7883 rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
7884 neg_scalar_reg);
7885 ASSERT_RTX_EQ (series_0_r,
7886 simplify_unary_operation (NEG, mode, series_0_nr, mode));
7887 ASSERT_RTX_EQ (series_r_m1,
7888 simplify_unary_operation (NEG, mode, series_nr_1, mode));
7889 ASSERT_RTX_EQ (series_r_r,
7890 simplify_unary_operation (NEG, mode, series_nr_nr, mode));
7892 /* Test that a VEC_SERIES with a zero step is simplified away. */
7893 ASSERT_RTX_EQ (duplicate,
7894 simplify_binary_operation (VEC_SERIES, mode,
7895 scalar_reg, const0_rtx));
7897 /* Test PLUS and MINUS with VEC_SERIES. */
7898 rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
7899 rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
7900 rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
7901 ASSERT_RTX_EQ (series_r_r,
7902 simplify_binary_operation (PLUS, mode, series_0_r,
7903 duplicate));
7904 ASSERT_RTX_EQ (series_r_1,
7905 simplify_binary_operation (PLUS, mode, duplicate,
7906 series_0_1));
7907 ASSERT_RTX_EQ (series_r_m1,
7908 simplify_binary_operation (PLUS, mode, duplicate,
7909 series_0_m1));
7910 ASSERT_RTX_EQ (series_0_r,
7911 simplify_binary_operation (MINUS, mode, series_r_r,
7912 duplicate));
7913 ASSERT_RTX_EQ (series_r_m1,
7914 simplify_binary_operation (MINUS, mode, duplicate,
7915 series_0_1));
7916 ASSERT_RTX_EQ (series_r_1,
7917 simplify_binary_operation (MINUS, mode, duplicate,
7918 series_0_m1));
7919 ASSERT_RTX_EQ (series_0_m1,
7920 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
7921 constm1_rtx));
7923 /* Test NEG on constant vector series. */
7924 ASSERT_RTX_EQ (series_0_m1,
7925 simplify_unary_operation (NEG, mode, series_0_1, mode));
7926 ASSERT_RTX_EQ (series_0_1,
7927 simplify_unary_operation (NEG, mode, series_0_m1, mode));
7929 /* Test PLUS and MINUS on constant vector series. */
7930 rtx scalar2 = gen_int_mode (2, inner_mode);
7931 rtx scalar3 = gen_int_mode (3, inner_mode);
7932 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
7933 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
7934 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
7935 ASSERT_RTX_EQ (series_1_1,
7936 simplify_binary_operation (PLUS, mode, series_0_1,
7937 CONST1_RTX (mode)));
7938 ASSERT_RTX_EQ (series_0_m1,
7939 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
7940 series_0_m1));
7941 ASSERT_RTX_EQ (series_1_3,
7942 simplify_binary_operation (PLUS, mode, series_1_1,
7943 series_0_2));
7944 ASSERT_RTX_EQ (series_0_1,
7945 simplify_binary_operation (MINUS, mode, series_1_1,
7946 CONST1_RTX (mode)));
7947 ASSERT_RTX_EQ (series_1_1,
7948 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
7949 series_0_m1));
7950 ASSERT_RTX_EQ (series_1_1,
7951 simplify_binary_operation (MINUS, mode, series_1_3,
7952 series_0_2));
7954 /* Test MULT between constant vectors. */
7955 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
7956 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
7957 rtx scalar9 = gen_int_mode (9, inner_mode);
7958 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
7959 ASSERT_RTX_EQ (series_0_2,
7960 simplify_binary_operation (MULT, mode, series_0_1, vec2));
7961 ASSERT_RTX_EQ (series_3_9,
7962 simplify_binary_operation (MULT, mode, vec3, series_1_3));
7963 if (!GET_MODE_NUNITS (mode).is_constant ())
7964 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
7965 series_0_1));
7967 /* Test ASHIFT between constant vectors. */
7968 ASSERT_RTX_EQ (series_0_2,
7969 simplify_binary_operation (ASHIFT, mode, series_0_1,
7970 CONST1_RTX (mode)));
7971 if (!GET_MODE_NUNITS (mode).is_constant ())
7972 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
7973 series_0_1));
7976 static rtx
7977 simplify_merge_mask (rtx x, rtx mask, int op)
7979 return simplify_context ().simplify_merge_mask (x, mask, op);
7982 /* Verify simplify_merge_mask works correctly. */
7984 static void
7985 test_vec_merge (machine_mode mode)
7987 rtx op0 = make_test_reg (mode);
7988 rtx op1 = make_test_reg (mode);
7989 rtx op2 = make_test_reg (mode);
7990 rtx op3 = make_test_reg (mode);
7991 rtx op4 = make_test_reg (mode);
7992 rtx op5 = make_test_reg (mode);
7993 rtx mask1 = make_test_reg (SImode);
7994 rtx mask2 = make_test_reg (SImode);
7995 rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
7996 rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
7997 rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
7999 /* Simple vec_merge. */
8000 ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
8001 ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
8002 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
8003 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
8005 /* Nested vec_merge.
8006 It's tempting to make this simplify right down to opN, but we don't
8007 because all the simplify_* functions assume that the operands have
8008 already been simplified. */
8009 rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
8010 ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
8011 ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
8013 /* Intermediate unary op. */
8014 rtx unop = gen_rtx_NOT (mode, vm1);
8015 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
8016 simplify_merge_mask (unop, mask1, 0));
8017 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
8018 simplify_merge_mask (unop, mask1, 1));
8020 /* Intermediate binary op. */
8021 rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
8022 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
8023 simplify_merge_mask (binop, mask1, 0));
8024 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
8025 simplify_merge_mask (binop, mask1, 1));
8027 /* Intermediate ternary op. */
8028 rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
8029 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
8030 simplify_merge_mask (tenop, mask1, 0));
8031 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
8032 simplify_merge_mask (tenop, mask1, 1));
8034 /* Side effects. */
8035 rtx badop0 = gen_rtx_PRE_INC (mode, op0);
8036 rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
8037 ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
8038 ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
8040 /* Called indirectly. */
8041 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
8042 simplify_rtx (nvm));
8045 /* Test subregs of integer vector constant X, trying elements in
8046 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
8047 where NELTS is the number of elements in X. Subregs involving
8048 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
8050 static void
8051 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
8052 unsigned int first_valid = 0)
8054 machine_mode inner_mode = GET_MODE (x);
8055 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8057 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
8059 machine_mode outer_mode = (machine_mode) modei;
8060 if (!VECTOR_MODE_P (outer_mode))
8061 continue;
8063 unsigned int outer_nunits;
8064 if (GET_MODE_INNER (outer_mode) == int_mode
8065 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
8066 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
8068 /* Test subregs in which the outer mode is a smaller,
8069 constant-sized vector of the same element type. */
8070 unsigned int limit
8071 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
8072 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
8074 rtx expected = NULL_RTX;
8075 if (elt >= first_valid)
8077 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
8078 for (unsigned int i = 0; i < outer_nunits; ++i)
8079 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
8080 expected = builder.build ();
8082 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
8083 ASSERT_RTX_EQ (expected,
8084 simplify_subreg (outer_mode, x,
8085 inner_mode, byte));
8088 else if (known_eq (GET_MODE_SIZE (outer_mode),
8089 GET_MODE_SIZE (inner_mode))
8090 && known_eq (elt_bias, 0U)
8091 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
8092 || known_eq (GET_MODE_BITSIZE (outer_mode),
8093 GET_MODE_NUNITS (outer_mode)))
8094 && (!FLOAT_MODE_P (outer_mode)
8095 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
8096 == GET_MODE_UNIT_PRECISION (outer_mode)))
8097 && (GET_MODE_SIZE (inner_mode).is_constant ()
8098 || !CONST_VECTOR_STEPPED_P (x)))
8100 /* Try converting to OUTER_MODE and back. */
8101 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
8102 ASSERT_TRUE (outer_x != NULL_RTX);
8103 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
8104 outer_mode, 0));
8108 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
8110 /* Test each byte in the element range. */
8111 unsigned int limit
8112 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
8113 for (unsigned int i = 0; i < limit; ++i)
8115 unsigned int elt = i / GET_MODE_SIZE (int_mode);
8116 rtx expected = NULL_RTX;
8117 if (elt >= first_valid)
8119 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
8120 if (BYTES_BIG_ENDIAN)
8121 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
8122 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
8123 wide_int shifted_elt
8124 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
8125 expected = immed_wide_int_const (shifted_elt, QImode);
8127 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
8128 ASSERT_RTX_EQ (expected,
8129 simplify_subreg (QImode, x, inner_mode, byte));
8134 /* Test constant subregs of integer vector mode INNER_MODE, using 1
8135 element per pattern. */
8137 static void
8138 test_vector_subregs_repeating (machine_mode inner_mode)
8140 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8141 unsigned int min_nunits = constant_lower_bound (nunits);
8142 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8143 unsigned int count = gcd (min_nunits, 8);
8145 rtx_vector_builder builder (inner_mode, count, 1);
8146 for (unsigned int i = 0; i < count; ++i)
8147 builder.quick_push (gen_int_mode (8 - i, int_mode));
8148 rtx x = builder.build ();
8150 test_vector_subregs_modes (x);
8151 if (!nunits.is_constant ())
8152 test_vector_subregs_modes (x, nunits - min_nunits);
8155 /* Test constant subregs of integer vector mode INNER_MODE, using 2
8156 elements per pattern. */
8158 static void
8159 test_vector_subregs_fore_back (machine_mode inner_mode)
8161 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8162 unsigned int min_nunits = constant_lower_bound (nunits);
8163 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8164 unsigned int count = gcd (min_nunits, 4);
8166 rtx_vector_builder builder (inner_mode, count, 2);
8167 for (unsigned int i = 0; i < count; ++i)
8168 builder.quick_push (gen_int_mode (i, int_mode));
8169 for (unsigned int i = 0; i < count; ++i)
8170 builder.quick_push (gen_int_mode (-(int) i, int_mode));
8171 rtx x = builder.build ();
8173 test_vector_subregs_modes (x);
8174 if (!nunits.is_constant ())
8175 test_vector_subregs_modes (x, nunits - min_nunits, count);
8178 /* Test constant subregs of integer vector mode INNER_MODE, using 3
8179 elements per pattern. */
8181 static void
8182 test_vector_subregs_stepped (machine_mode inner_mode)
8184 /* Build { 0, 1, 2, 3, ... }. */
8185 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8186 rtx_vector_builder builder (inner_mode, 1, 3);
8187 for (unsigned int i = 0; i < 3; ++i)
8188 builder.quick_push (gen_int_mode (i, int_mode));
8189 rtx x = builder.build ();
8191 test_vector_subregs_modes (x);
8194 /* Test constant subregs of integer vector mode INNER_MODE. */
8196 static void
8197 test_vector_subregs (machine_mode inner_mode)
8199 test_vector_subregs_repeating (inner_mode);
8200 test_vector_subregs_fore_back (inner_mode);
8201 test_vector_subregs_stepped (inner_mode);
8204 /* Verify some simplifications involving vectors. */
8206 static void
8207 test_vector_ops ()
8209 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8211 machine_mode mode = (machine_mode) i;
8212 if (VECTOR_MODE_P (mode))
8214 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
8215 test_vector_ops_duplicate (mode, scalar_reg);
8216 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
8217 && maybe_gt (GET_MODE_NUNITS (mode), 2))
8219 test_vector_ops_series (mode, scalar_reg);
8220 test_vector_subregs (mode);
8222 test_vec_merge (mode);
8227 template<unsigned int N>
8228 struct simplify_const_poly_int_tests
8230 static void run ();
8233 template<>
8234 struct simplify_const_poly_int_tests<1>
8236 static void run () {}
8239 /* Test various CONST_POLY_INT properties. */
8241 template<unsigned int N>
8242 void
8243 simplify_const_poly_int_tests<N>::run ()
8245 rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
8246 rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
8247 rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
8248 rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
8249 rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
8250 rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
8251 rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
8252 rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
8253 rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
8254 rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
8255 rtx two = GEN_INT (2);
8256 rtx six = GEN_INT (6);
8257 poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
8259 /* These tests only try limited operation combinations. Fuller arithmetic
8260 testing is done directly on poly_ints. */
8261 ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
8262 ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
8263 ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
8264 ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
8265 ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
8266 ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
8267 ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
8268 ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
8269 ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
8270 ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
8271 ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
8274 /* Run all of the selftests within this file. */
8276 void
8277 simplify_rtx_c_tests ()
8279 test_scalar_ops ();
8280 test_vector_ops ();
8281 simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
8284 } // namespace selftest
8286 #endif /* CHECKING_P */