Don't build libgcc_stub.a on hppa[12]*-*-hpux11*.
[official-gcc.git] / gcc / simplify-rtx.c
bloba719f57870fc5e1d363486e9c4c8df23aa006849
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 /* (truncate:A (subreg:B (truncate:C X) 0)) is
817 (truncate:A X). */
818 if (GET_CODE (op) == SUBREG
819 && is_a <scalar_int_mode> (mode, &int_mode)
820 && SCALAR_INT_MODE_P (op_mode)
821 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
822 && GET_CODE (SUBREG_REG (op)) == TRUNCATE
823 && subreg_lowpart_p (op))
825 rtx inner = XEXP (SUBREG_REG (op), 0);
826 if (GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (subreg_mode))
827 return simplify_gen_unary (TRUNCATE, int_mode, inner,
828 GET_MODE (inner));
829 else
830 /* If subreg above is paradoxical and C is narrower
831 than A, return (subreg:A (truncate:C X) 0). */
832 return simplify_gen_subreg (int_mode, SUBREG_REG (op), subreg_mode, 0);
835 /* (truncate:A (truncate:B X)) is (truncate:A X). */
836 if (GET_CODE (op) == TRUNCATE)
837 return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
838 GET_MODE (XEXP (op, 0)));
840 /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
841 in mode A. */
842 if (GET_CODE (op) == IOR
843 && SCALAR_INT_MODE_P (mode)
844 && SCALAR_INT_MODE_P (op_mode)
845 && CONST_INT_P (XEXP (op, 1))
846 && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
847 return constm1_rtx;
849 return NULL_RTX;
852 /* Try to simplify a unary operation CODE whose output mode is to be
853 MODE with input operand OP whose mode was originally OP_MODE.
854 Return zero if no simplification can be made. */
856 simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
857 rtx op, machine_mode op_mode)
859 rtx trueop, tem;
861 trueop = avoid_constant_pool_reference (op);
863 tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
864 if (tem)
865 return tem;
867 return simplify_unary_operation_1 (code, mode, op);
870 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
871 to be exact. */
873 static bool
874 exact_int_to_float_conversion_p (const_rtx op)
876 int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
877 machine_mode op0_mode = GET_MODE (XEXP (op, 0));
878 /* Constants shouldn't reach here. */
879 gcc_assert (op0_mode != VOIDmode);
880 int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
881 int in_bits = in_prec;
882 if (HWI_COMPUTABLE_MODE_P (op0_mode))
884 unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
885 if (GET_CODE (op) == FLOAT)
886 in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
887 else if (GET_CODE (op) == UNSIGNED_FLOAT)
888 in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
889 else
890 gcc_unreachable ();
891 in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
893 return in_bits <= out_bits;
896 /* Perform some simplifications we can do even if the operands
897 aren't constant. */
899 simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
900 rtx op)
902 enum rtx_code reversed;
903 rtx temp, elt, base, step;
904 scalar_int_mode inner, int_mode, op_mode, op0_mode;
906 switch (code)
908 case NOT:
909 /* (not (not X)) == X. */
910 if (GET_CODE (op) == NOT)
911 return XEXP (op, 0);
913 /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
914 comparison is all ones. */
915 if (COMPARISON_P (op)
916 && (mode == BImode || STORE_FLAG_VALUE == -1)
917 && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
918 return simplify_gen_relational (reversed, mode, VOIDmode,
919 XEXP (op, 0), XEXP (op, 1));
921 /* (not (plus X -1)) can become (neg X). */
922 if (GET_CODE (op) == PLUS
923 && XEXP (op, 1) == constm1_rtx)
924 return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
926 /* Similarly, (not (neg X)) is (plus X -1). Only do this for
927 modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
928 and MODE_VECTOR_INT. */
929 if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
930 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
931 CONSTM1_RTX (mode));
933 /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
934 if (GET_CODE (op) == XOR
935 && CONST_INT_P (XEXP (op, 1))
936 && (temp = simplify_unary_operation (NOT, mode,
937 XEXP (op, 1), mode)) != 0)
938 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
940 /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
941 if (GET_CODE (op) == PLUS
942 && CONST_INT_P (XEXP (op, 1))
943 && mode_signbit_p (mode, XEXP (op, 1))
944 && (temp = simplify_unary_operation (NOT, mode,
945 XEXP (op, 1), mode)) != 0)
946 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
949 /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
950 operands other than 1, but that is not valid. We could do a
951 similar simplification for (not (lshiftrt C X)) where C is
952 just the sign bit, but this doesn't seem common enough to
953 bother with. */
954 if (GET_CODE (op) == ASHIFT
955 && XEXP (op, 0) == const1_rtx)
957 temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
958 return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
961 /* (not (ashiftrt foo C)) where C is the number of bits in FOO
962 minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
963 so we can perform the above simplification. */
964 if (STORE_FLAG_VALUE == -1
965 && is_a <scalar_int_mode> (mode, &int_mode)
966 && GET_CODE (op) == ASHIFTRT
967 && CONST_INT_P (XEXP (op, 1))
968 && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
969 return simplify_gen_relational (GE, int_mode, VOIDmode,
970 XEXP (op, 0), const0_rtx);
973 if (partial_subreg_p (op)
974 && subreg_lowpart_p (op)
975 && GET_CODE (SUBREG_REG (op)) == ASHIFT
976 && XEXP (SUBREG_REG (op), 0) == const1_rtx)
978 machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
979 rtx x;
981 x = gen_rtx_ROTATE (inner_mode,
982 simplify_gen_unary (NOT, inner_mode, const1_rtx,
983 inner_mode),
984 XEXP (SUBREG_REG (op), 1));
985 temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
986 if (temp)
987 return temp;
990 /* Apply De Morgan's laws to reduce number of patterns for machines
991 with negating logical insns (and-not, nand, etc.). If result has
992 only one NOT, put it first, since that is how the patterns are
993 coded. */
994 if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
996 rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
997 machine_mode op_mode;
999 op_mode = GET_MODE (in1);
1000 in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1002 op_mode = GET_MODE (in2);
1003 if (op_mode == VOIDmode)
1004 op_mode = mode;
1005 in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1007 if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1008 std::swap (in1, in2);
1010 return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1011 mode, in1, in2);
1014 /* (not (bswap x)) -> (bswap (not x)). */
1015 if (GET_CODE (op) == BSWAP)
1017 rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1018 return simplify_gen_unary (BSWAP, mode, x, mode);
1020 break;
1022 case NEG:
1023 /* (neg (neg X)) == X. */
1024 if (GET_CODE (op) == NEG)
1025 return XEXP (op, 0);
1027 /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1028 If comparison is not reversible use
1029 x ? y : (neg y). */
1030 if (GET_CODE (op) == IF_THEN_ELSE)
1032 rtx cond = XEXP (op, 0);
1033 rtx true_rtx = XEXP (op, 1);
1034 rtx false_rtx = XEXP (op, 2);
1036 if ((GET_CODE (true_rtx) == NEG
1037 && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1038 || (GET_CODE (false_rtx) == NEG
1039 && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1041 if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1042 temp = reversed_comparison (cond, mode);
1043 else
1045 temp = cond;
1046 std::swap (true_rtx, false_rtx);
1048 return simplify_gen_ternary (IF_THEN_ELSE, mode,
1049 mode, temp, true_rtx, false_rtx);
1053 /* (neg (plus X 1)) can become (not X). */
1054 if (GET_CODE (op) == PLUS
1055 && XEXP (op, 1) == const1_rtx)
1056 return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1058 /* Similarly, (neg (not X)) is (plus X 1). */
1059 if (GET_CODE (op) == NOT)
1060 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1061 CONST1_RTX (mode));
1063 /* (neg (minus X Y)) can become (minus Y X). This transformation
1064 isn't safe for modes with signed zeros, since if X and Y are
1065 both +0, (minus Y X) is the same as (minus X Y). If the
1066 rounding mode is towards +infinity (or -infinity) then the two
1067 expressions will be rounded differently. */
1068 if (GET_CODE (op) == MINUS
1069 && !HONOR_SIGNED_ZEROS (mode)
1070 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1071 return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1073 if (GET_CODE (op) == PLUS
1074 && !HONOR_SIGNED_ZEROS (mode)
1075 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1077 /* (neg (plus A C)) is simplified to (minus -C A). */
1078 if (CONST_SCALAR_INT_P (XEXP (op, 1))
1079 || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1081 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1082 if (temp)
1083 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1086 /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1087 temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1088 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1091 /* (neg (mult A B)) becomes (mult A (neg B)).
1092 This works even for floating-point values. */
1093 if (GET_CODE (op) == MULT
1094 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1096 temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1097 return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1100 /* NEG commutes with ASHIFT since it is multiplication. Only do
1101 this if we can then eliminate the NEG (e.g., if the operand
1102 is a constant). */
1103 if (GET_CODE (op) == ASHIFT)
1105 temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1106 if (temp)
1107 return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1110 /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1111 C is equal to the width of MODE minus 1. */
1112 if (GET_CODE (op) == ASHIFTRT
1113 && CONST_INT_P (XEXP (op, 1))
1114 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1115 return simplify_gen_binary (LSHIFTRT, mode,
1116 XEXP (op, 0), XEXP (op, 1));
1118 /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1119 C is equal to the width of MODE minus 1. */
1120 if (GET_CODE (op) == LSHIFTRT
1121 && CONST_INT_P (XEXP (op, 1))
1122 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1123 return simplify_gen_binary (ASHIFTRT, mode,
1124 XEXP (op, 0), XEXP (op, 1));
1126 /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1127 if (GET_CODE (op) == XOR
1128 && XEXP (op, 1) == const1_rtx
1129 && nonzero_bits (XEXP (op, 0), mode) == 1)
1130 return plus_constant (mode, XEXP (op, 0), -1);
1132 /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1133 /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1134 if (GET_CODE (op) == LT
1135 && XEXP (op, 1) == const0_rtx
1136 && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1138 int_mode = as_a <scalar_int_mode> (mode);
1139 int isize = GET_MODE_PRECISION (inner);
1140 if (STORE_FLAG_VALUE == 1)
1142 temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1143 gen_int_shift_amount (inner,
1144 isize - 1));
1145 if (int_mode == inner)
1146 return temp;
1147 if (GET_MODE_PRECISION (int_mode) > isize)
1148 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1149 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1151 else if (STORE_FLAG_VALUE == -1)
1153 temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1154 gen_int_shift_amount (inner,
1155 isize - 1));
1156 if (int_mode == inner)
1157 return temp;
1158 if (GET_MODE_PRECISION (int_mode) > isize)
1159 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1160 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1164 if (vec_series_p (op, &base, &step))
1166 /* Only create a new series if we can simplify both parts. In other
1167 cases this isn't really a simplification, and it's not necessarily
1168 a win to replace a vector operation with a scalar operation. */
1169 scalar_mode inner_mode = GET_MODE_INNER (mode);
1170 base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1171 if (base)
1173 step = simplify_unary_operation (NEG, inner_mode,
1174 step, inner_mode);
1175 if (step)
1176 return gen_vec_series (mode, base, step);
1179 break;
1181 case TRUNCATE:
1182 /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1183 with the umulXi3_highpart patterns. */
1184 if (GET_CODE (op) == LSHIFTRT
1185 && GET_CODE (XEXP (op, 0)) == MULT)
1186 break;
1188 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1190 if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1192 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1193 if (temp)
1194 return temp;
1196 /* We can't handle truncation to a partial integer mode here
1197 because we don't know the real bitsize of the partial
1198 integer mode. */
1199 break;
1202 if (GET_MODE (op) != VOIDmode)
1204 temp = simplify_truncation (mode, op, GET_MODE (op));
1205 if (temp)
1206 return temp;
1209 /* If we know that the value is already truncated, we can
1210 replace the TRUNCATE with a SUBREG. */
1211 if (known_eq (GET_MODE_NUNITS (mode), 1)
1212 && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1213 || truncated_to_mode (mode, op)))
1215 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1216 if (temp)
1217 return temp;
1220 /* A truncate of a comparison can be replaced with a subreg if
1221 STORE_FLAG_VALUE permits. This is like the previous test,
1222 but it works even if the comparison is done in a mode larger
1223 than HOST_BITS_PER_WIDE_INT. */
1224 if (HWI_COMPUTABLE_MODE_P (mode)
1225 && COMPARISON_P (op)
1226 && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
1228 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1229 if (temp)
1230 return temp;
1233 /* A truncate of a memory is just loading the low part of the memory
1234 if we are not changing the meaning of the address. */
1235 if (GET_CODE (op) == MEM
1236 && !VECTOR_MODE_P (mode)
1237 && !MEM_VOLATILE_P (op)
1238 && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1240 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1241 if (temp)
1242 return temp;
1245 break;
1247 case FLOAT_TRUNCATE:
1248 if (DECIMAL_FLOAT_MODE_P (mode))
1249 break;
1251 /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1252 if (GET_CODE (op) == FLOAT_EXTEND
1253 && GET_MODE (XEXP (op, 0)) == mode)
1254 return XEXP (op, 0);
1256 /* (float_truncate:SF (float_truncate:DF foo:XF))
1257 = (float_truncate:SF foo:XF).
1258 This may eliminate double rounding, so it is unsafe.
1260 (float_truncate:SF (float_extend:XF foo:DF))
1261 = (float_truncate:SF foo:DF).
1263 (float_truncate:DF (float_extend:XF foo:SF))
1264 = (float_extend:DF foo:SF). */
1265 if ((GET_CODE (op) == FLOAT_TRUNCATE
1266 && flag_unsafe_math_optimizations)
1267 || GET_CODE (op) == FLOAT_EXTEND)
1268 return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1269 > GET_MODE_UNIT_SIZE (mode)
1270 ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1271 mode,
1272 XEXP (op, 0), mode);
1274 /* (float_truncate (float x)) is (float x) */
1275 if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1276 && (flag_unsafe_math_optimizations
1277 || exact_int_to_float_conversion_p (op)))
1278 return simplify_gen_unary (GET_CODE (op), mode,
1279 XEXP (op, 0),
1280 GET_MODE (XEXP (op, 0)));
1282 /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1283 (OP:SF foo:SF) if OP is NEG or ABS. */
1284 if ((GET_CODE (op) == ABS
1285 || GET_CODE (op) == NEG)
1286 && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1287 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1288 return simplify_gen_unary (GET_CODE (op), mode,
1289 XEXP (XEXP (op, 0), 0), mode);
1291 /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1292 is (float_truncate:SF x). */
1293 if (GET_CODE (op) == SUBREG
1294 && subreg_lowpart_p (op)
1295 && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1296 return SUBREG_REG (op);
1297 break;
1299 case FLOAT_EXTEND:
1300 if (DECIMAL_FLOAT_MODE_P (mode))
1301 break;
1303 /* (float_extend (float_extend x)) is (float_extend x)
1305 (float_extend (float x)) is (float x) assuming that double
1306 rounding can't happen.
1308 if (GET_CODE (op) == FLOAT_EXTEND
1309 || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1310 && exact_int_to_float_conversion_p (op)))
1311 return simplify_gen_unary (GET_CODE (op), mode,
1312 XEXP (op, 0),
1313 GET_MODE (XEXP (op, 0)));
1315 break;
1317 case ABS:
1318 /* (abs (neg <foo>)) -> (abs <foo>) */
1319 if (GET_CODE (op) == NEG)
1320 return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1321 GET_MODE (XEXP (op, 0)));
1323 /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1324 do nothing. */
1325 if (GET_MODE (op) == VOIDmode)
1326 break;
1328 /* If operand is something known to be positive, ignore the ABS. */
1329 if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
1330 || val_signbit_known_clear_p (GET_MODE (op),
1331 nonzero_bits (op, GET_MODE (op))))
1332 return op;
1334 /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1335 if (is_a <scalar_int_mode> (mode, &int_mode)
1336 && (num_sign_bit_copies (op, int_mode)
1337 == GET_MODE_PRECISION (int_mode)))
1338 return gen_rtx_NEG (int_mode, op);
1340 break;
1342 case FFS:
1343 /* (ffs (*_extend <X>)) = (ffs <X>) */
1344 if (GET_CODE (op) == SIGN_EXTEND
1345 || GET_CODE (op) == ZERO_EXTEND)
1346 return simplify_gen_unary (FFS, mode, XEXP (op, 0),
1347 GET_MODE (XEXP (op, 0)));
1348 break;
1350 case POPCOUNT:
1351 switch (GET_CODE (op))
1353 case BSWAP:
1354 case ZERO_EXTEND:
1355 /* (popcount (zero_extend <X>)) = (popcount <X>) */
1356 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1357 GET_MODE (XEXP (op, 0)));
1359 case ROTATE:
1360 case ROTATERT:
1361 /* Rotations don't affect popcount. */
1362 if (!side_effects_p (XEXP (op, 1)))
1363 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1364 GET_MODE (XEXP (op, 0)));
1365 break;
1367 default:
1368 break;
1370 break;
1372 case PARITY:
1373 switch (GET_CODE (op))
1375 case NOT:
1376 case BSWAP:
1377 case ZERO_EXTEND:
1378 case SIGN_EXTEND:
1379 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1380 GET_MODE (XEXP (op, 0)));
1382 case ROTATE:
1383 case ROTATERT:
1384 /* Rotations don't affect parity. */
1385 if (!side_effects_p (XEXP (op, 1)))
1386 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1387 GET_MODE (XEXP (op, 0)));
1388 break;
1390 case PARITY:
1391 /* (parity (parity x)) -> parity (x). */
1392 return op;
1394 default:
1395 break;
1397 break;
1399 case BSWAP:
1400 /* (bswap (bswap x)) -> x. */
1401 if (GET_CODE (op) == BSWAP)
1402 return XEXP (op, 0);
1403 break;
1405 case FLOAT:
1406 /* (float (sign_extend <X>)) = (float <X>). */
1407 if (GET_CODE (op) == SIGN_EXTEND)
1408 return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1409 GET_MODE (XEXP (op, 0)));
1410 break;
1412 case SIGN_EXTEND:
1413 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1414 becomes just the MINUS if its mode is MODE. This allows
1415 folding switch statements on machines using casesi (such as
1416 the VAX). */
1417 if (GET_CODE (op) == TRUNCATE
1418 && GET_MODE (XEXP (op, 0)) == mode
1419 && GET_CODE (XEXP (op, 0)) == MINUS
1420 && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1421 && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1422 return XEXP (op, 0);
1424 /* Extending a widening multiplication should be canonicalized to
1425 a wider widening multiplication. */
1426 if (GET_CODE (op) == MULT)
1428 rtx lhs = XEXP (op, 0);
1429 rtx rhs = XEXP (op, 1);
1430 enum rtx_code lcode = GET_CODE (lhs);
1431 enum rtx_code rcode = GET_CODE (rhs);
1433 /* Widening multiplies usually extend both operands, but sometimes
1434 they use a shift to extract a portion of a register. */
1435 if ((lcode == SIGN_EXTEND
1436 || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1437 && (rcode == SIGN_EXTEND
1438 || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1440 machine_mode lmode = GET_MODE (lhs);
1441 machine_mode rmode = GET_MODE (rhs);
1442 int bits;
1444 if (lcode == ASHIFTRT)
1445 /* Number of bits not shifted off the end. */
1446 bits = (GET_MODE_UNIT_PRECISION (lmode)
1447 - INTVAL (XEXP (lhs, 1)));
1448 else /* lcode == SIGN_EXTEND */
1449 /* Size of inner mode. */
1450 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1452 if (rcode == ASHIFTRT)
1453 bits += (GET_MODE_UNIT_PRECISION (rmode)
1454 - INTVAL (XEXP (rhs, 1)));
1455 else /* rcode == SIGN_EXTEND */
1456 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1458 /* We can only widen multiplies if the result is mathematiclly
1459 equivalent. I.e. if overflow was impossible. */
1460 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1461 return simplify_gen_binary
1462 (MULT, mode,
1463 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1464 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1468 /* Check for a sign extension of a subreg of a promoted
1469 variable, where the promotion is sign-extended, and the
1470 target mode is the same as the variable's promotion. */
1471 if (GET_CODE (op) == SUBREG
1472 && SUBREG_PROMOTED_VAR_P (op)
1473 && SUBREG_PROMOTED_SIGNED_P (op)
1474 && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
1476 temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
1477 if (temp)
1478 return temp;
1481 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1482 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1483 if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1485 gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1486 > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1487 return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1488 GET_MODE (XEXP (op, 0)));
1491 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1492 is (sign_extend:M (subreg:O <X>)) if there is mode with
1493 GET_MODE_BITSIZE (N) - I bits.
1494 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1495 is similarly (zero_extend:M (subreg:O <X>)). */
1496 if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1497 && GET_CODE (XEXP (op, 0)) == ASHIFT
1498 && is_a <scalar_int_mode> (mode, &int_mode)
1499 && CONST_INT_P (XEXP (op, 1))
1500 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1501 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1502 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1504 scalar_int_mode tmode;
1505 gcc_assert (GET_MODE_PRECISION (int_mode)
1506 > GET_MODE_PRECISION (op_mode));
1507 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1508 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1510 rtx inner =
1511 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1512 if (inner)
1513 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1514 ? SIGN_EXTEND : ZERO_EXTEND,
1515 int_mode, inner, tmode);
1519 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1520 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1521 if (GET_CODE (op) == LSHIFTRT
1522 && CONST_INT_P (XEXP (op, 1))
1523 && XEXP (op, 1) != const0_rtx)
1524 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1526 /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1527 I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1528 (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1529 (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1530 O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1531 wider than O. */
1532 if (GET_CODE (op) == TRUNCATE
1533 && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1534 && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1536 scalar_int_mode m_mode, n_mode, o_mode;
1537 rtx old_shift = XEXP (op, 0);
1538 if (is_a <scalar_int_mode> (mode, &m_mode)
1539 && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1540 && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1541 && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1542 == INTVAL (XEXP (old_shift, 1)))
1544 rtx new_shift = simplify_gen_binary (ASHIFTRT,
1545 GET_MODE (old_shift),
1546 XEXP (old_shift, 0),
1547 XEXP (old_shift, 1));
1548 if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1549 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1550 GET_MODE (new_shift));
1551 if (mode != GET_MODE (new_shift))
1552 return simplify_gen_unary (TRUNCATE, mode, new_shift,
1553 GET_MODE (new_shift));
1554 return new_shift;
1558 #if defined(POINTERS_EXTEND_UNSIGNED)
1559 /* As we do not know which address space the pointer is referring to,
1560 we can do this only if the target does not support different pointer
1561 or address modes depending on the address space. */
1562 if (target_default_pointer_address_modes_p ()
1563 && ! POINTERS_EXTEND_UNSIGNED
1564 && mode == Pmode && GET_MODE (op) == ptr_mode
1565 && (CONSTANT_P (op)
1566 || (GET_CODE (op) == SUBREG
1567 && REG_P (SUBREG_REG (op))
1568 && REG_POINTER (SUBREG_REG (op))
1569 && GET_MODE (SUBREG_REG (op)) == Pmode))
1570 && !targetm.have_ptr_extend ())
1572 temp
1573 = convert_memory_address_addr_space_1 (Pmode, op,
1574 ADDR_SPACE_GENERIC, false,
1575 true);
1576 if (temp)
1577 return temp;
1579 #endif
1580 break;
1582 case ZERO_EXTEND:
1583 /* Check for a zero extension of a subreg of a promoted
1584 variable, where the promotion is zero-extended, and the
1585 target mode is the same as the variable's promotion. */
1586 if (GET_CODE (op) == SUBREG
1587 && SUBREG_PROMOTED_VAR_P (op)
1588 && SUBREG_PROMOTED_UNSIGNED_P (op)
1589 && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
1591 temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
1592 if (temp)
1593 return temp;
1596 /* Extending a widening multiplication should be canonicalized to
1597 a wider widening multiplication. */
1598 if (GET_CODE (op) == MULT)
1600 rtx lhs = XEXP (op, 0);
1601 rtx rhs = XEXP (op, 1);
1602 enum rtx_code lcode = GET_CODE (lhs);
1603 enum rtx_code rcode = GET_CODE (rhs);
1605 /* Widening multiplies usually extend both operands, but sometimes
1606 they use a shift to extract a portion of a register. */
1607 if ((lcode == ZERO_EXTEND
1608 || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1609 && (rcode == ZERO_EXTEND
1610 || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1612 machine_mode lmode = GET_MODE (lhs);
1613 machine_mode rmode = GET_MODE (rhs);
1614 int bits;
1616 if (lcode == LSHIFTRT)
1617 /* Number of bits not shifted off the end. */
1618 bits = (GET_MODE_UNIT_PRECISION (lmode)
1619 - INTVAL (XEXP (lhs, 1)));
1620 else /* lcode == ZERO_EXTEND */
1621 /* Size of inner mode. */
1622 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1624 if (rcode == LSHIFTRT)
1625 bits += (GET_MODE_UNIT_PRECISION (rmode)
1626 - INTVAL (XEXP (rhs, 1)));
1627 else /* rcode == ZERO_EXTEND */
1628 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1630 /* We can only widen multiplies if the result is mathematiclly
1631 equivalent. I.e. if overflow was impossible. */
1632 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1633 return simplify_gen_binary
1634 (MULT, mode,
1635 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1636 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1640 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1641 if (GET_CODE (op) == ZERO_EXTEND)
1642 return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1643 GET_MODE (XEXP (op, 0)));
1645 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1646 is (zero_extend:M (subreg:O <X>)) if there is mode with
1647 GET_MODE_PRECISION (N) - I bits. */
1648 if (GET_CODE (op) == LSHIFTRT
1649 && GET_CODE (XEXP (op, 0)) == ASHIFT
1650 && is_a <scalar_int_mode> (mode, &int_mode)
1651 && CONST_INT_P (XEXP (op, 1))
1652 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1653 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1654 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1656 scalar_int_mode tmode;
1657 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1658 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1660 rtx inner =
1661 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1662 if (inner)
1663 return simplify_gen_unary (ZERO_EXTEND, int_mode,
1664 inner, tmode);
1668 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1669 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1670 of mode N. E.g.
1671 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1672 (and:SI (reg:SI) (const_int 63)). */
1673 if (partial_subreg_p (op)
1674 && is_a <scalar_int_mode> (mode, &int_mode)
1675 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1676 && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1677 && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1678 && subreg_lowpart_p (op)
1679 && (nonzero_bits (SUBREG_REG (op), op0_mode)
1680 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1682 if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1683 return SUBREG_REG (op);
1684 return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1685 op0_mode);
1688 #if defined(POINTERS_EXTEND_UNSIGNED)
1689 /* As we do not know which address space the pointer is referring to,
1690 we can do this only if the target does not support different pointer
1691 or address modes depending on the address space. */
1692 if (target_default_pointer_address_modes_p ()
1693 && POINTERS_EXTEND_UNSIGNED > 0
1694 && mode == Pmode && GET_MODE (op) == ptr_mode
1695 && (CONSTANT_P (op)
1696 || (GET_CODE (op) == SUBREG
1697 && REG_P (SUBREG_REG (op))
1698 && REG_POINTER (SUBREG_REG (op))
1699 && GET_MODE (SUBREG_REG (op)) == Pmode))
1700 && !targetm.have_ptr_extend ())
1702 temp
1703 = convert_memory_address_addr_space_1 (Pmode, op,
1704 ADDR_SPACE_GENERIC, false,
1705 true);
1706 if (temp)
1707 return temp;
1709 #endif
1710 break;
1712 default:
1713 break;
1716 if (VECTOR_MODE_P (mode)
1717 && vec_duplicate_p (op, &elt)
1718 && code != VEC_DUPLICATE)
1720 if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1721 /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1722 operations by promoting VEC_DUPLICATE to the root of the expression
1723 (as far as possible). */
1724 temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1725 elt, GET_MODE_INNER (GET_MODE (op)));
1726 else
1727 /* Try applying the operator to ELT and see if that simplifies.
1728 We can duplicate the result if so.
1730 The reason we traditionally haven't used simplify_gen_unary
1731 for these codes is that it didn't necessarily seem to be a
1732 win to convert things like:
1734 (neg:V (vec_duplicate:V (reg:S R)))
1738 (vec_duplicate:V (neg:S (reg:S R)))
1740 The first might be done entirely in vector registers while the
1741 second might need a move between register files.
1743 However, there also cases where promoting the vec_duplicate is
1744 more efficient, and there is definite value in having a canonical
1745 form when matching instruction patterns. We should consider
1746 extending the simplify_gen_unary code above to more cases. */
1747 temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1748 elt, GET_MODE_INNER (GET_MODE (op)));
1749 if (temp)
1750 return gen_vec_duplicate (mode, temp);
1753 return 0;
1756 /* Try to compute the value of a unary operation CODE whose output mode is to
1757 be MODE with input operand OP whose mode was originally OP_MODE.
1758 Return zero if the value cannot be computed. */
1760 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1761 rtx op, machine_mode op_mode)
1763 scalar_int_mode result_mode;
1765 if (code == VEC_DUPLICATE)
1767 gcc_assert (VECTOR_MODE_P (mode));
1768 if (GET_MODE (op) != VOIDmode)
1770 if (!VECTOR_MODE_P (GET_MODE (op)))
1771 gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1772 else
1773 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1774 (GET_MODE (op)));
1776 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1777 return gen_const_vec_duplicate (mode, op);
1778 if (GET_CODE (op) == CONST_VECTOR
1779 && (CONST_VECTOR_DUPLICATE_P (op)
1780 || CONST_VECTOR_NUNITS (op).is_constant ()))
1782 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1783 ? CONST_VECTOR_NPATTERNS (op)
1784 : CONST_VECTOR_NUNITS (op).to_constant ());
1785 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1786 rtx_vector_builder builder (mode, npatterns, 1);
1787 for (unsigned i = 0; i < npatterns; i++)
1788 builder.quick_push (CONST_VECTOR_ELT (op, i));
1789 return builder.build ();
1793 if (VECTOR_MODE_P (mode)
1794 && GET_CODE (op) == CONST_VECTOR
1795 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1797 gcc_assert (GET_MODE (op) == op_mode);
1799 rtx_vector_builder builder;
1800 if (!builder.new_unary_operation (mode, op, false))
1801 return 0;
1803 unsigned int count = builder.encoded_nelts ();
1804 for (unsigned int i = 0; i < count; i++)
1806 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1807 CONST_VECTOR_ELT (op, i),
1808 GET_MODE_INNER (op_mode));
1809 if (!x || !valid_for_const_vector_p (mode, x))
1810 return 0;
1811 builder.quick_push (x);
1813 return builder.build ();
1816 /* The order of these tests is critical so that, for example, we don't
1817 check the wrong mode (input vs. output) for a conversion operation,
1818 such as FIX. At some point, this should be simplified. */
1820 if (code == FLOAT && CONST_SCALAR_INT_P (op))
1822 REAL_VALUE_TYPE d;
1824 if (op_mode == VOIDmode)
1826 /* CONST_INT have VOIDmode as the mode. We assume that all
1827 the bits of the constant are significant, though, this is
1828 a dangerous assumption as many times CONST_INTs are
1829 created and used with garbage in the bits outside of the
1830 precision of the implied mode of the const_int. */
1831 op_mode = MAX_MODE_INT;
1834 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1836 /* Avoid the folding if flag_signaling_nans is on and
1837 operand is a signaling NaN. */
1838 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1839 return 0;
1841 d = real_value_truncate (mode, d);
1842 return const_double_from_real_value (d, mode);
1844 else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
1846 REAL_VALUE_TYPE d;
1848 if (op_mode == VOIDmode)
1850 /* CONST_INT have VOIDmode as the mode. We assume that all
1851 the bits of the constant are significant, though, this is
1852 a dangerous assumption as many times CONST_INTs are
1853 created and used with garbage in the bits outside of the
1854 precision of the implied mode of the const_int. */
1855 op_mode = MAX_MODE_INT;
1858 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
1860 /* Avoid the folding if flag_signaling_nans is on and
1861 operand is a signaling NaN. */
1862 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1863 return 0;
1865 d = real_value_truncate (mode, d);
1866 return const_double_from_real_value (d, mode);
1869 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
1871 unsigned int width = GET_MODE_PRECISION (result_mode);
1872 if (width > MAX_BITSIZE_MODE_ANY_INT)
1873 return 0;
1875 wide_int result;
1876 scalar_int_mode imode = (op_mode == VOIDmode
1877 ? result_mode
1878 : as_a <scalar_int_mode> (op_mode));
1879 rtx_mode_t op0 = rtx_mode_t (op, imode);
1880 int int_value;
1882 #if TARGET_SUPPORTS_WIDE_INT == 0
1883 /* This assert keeps the simplification from producing a result
1884 that cannot be represented in a CONST_DOUBLE but a lot of
1885 upstream callers expect that this function never fails to
1886 simplify something and so you if you added this to the test
1887 above the code would die later anyway. If this assert
1888 happens, you just need to make the port support wide int. */
1889 gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
1890 #endif
1892 switch (code)
1894 case NOT:
1895 result = wi::bit_not (op0);
1896 break;
1898 case NEG:
1899 result = wi::neg (op0);
1900 break;
1902 case ABS:
1903 result = wi::abs (op0);
1904 break;
1906 case FFS:
1907 result = wi::shwi (wi::ffs (op0), result_mode);
1908 break;
1910 case CLZ:
1911 if (wi::ne_p (op0, 0))
1912 int_value = wi::clz (op0);
1913 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1914 return NULL_RTX;
1915 result = wi::shwi (int_value, result_mode);
1916 break;
1918 case CLRSB:
1919 result = wi::shwi (wi::clrsb (op0), result_mode);
1920 break;
1922 case CTZ:
1923 if (wi::ne_p (op0, 0))
1924 int_value = wi::ctz (op0);
1925 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1926 return NULL_RTX;
1927 result = wi::shwi (int_value, result_mode);
1928 break;
1930 case POPCOUNT:
1931 result = wi::shwi (wi::popcount (op0), result_mode);
1932 break;
1934 case PARITY:
1935 result = wi::shwi (wi::parity (op0), result_mode);
1936 break;
1938 case BSWAP:
1939 result = wide_int (op0).bswap ();
1940 break;
1942 case TRUNCATE:
1943 case ZERO_EXTEND:
1944 result = wide_int::from (op0, width, UNSIGNED);
1945 break;
1947 case SIGN_EXTEND:
1948 result = wide_int::from (op0, width, SIGNED);
1949 break;
1951 case SQRT:
1952 default:
1953 return 0;
1956 return immed_wide_int_const (result, result_mode);
1959 else if (CONST_DOUBLE_AS_FLOAT_P (op)
1960 && SCALAR_FLOAT_MODE_P (mode)
1961 && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
1963 REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
1964 switch (code)
1966 case SQRT:
1967 return 0;
1968 case ABS:
1969 d = real_value_abs (&d);
1970 break;
1971 case NEG:
1972 d = real_value_negate (&d);
1973 break;
1974 case FLOAT_TRUNCATE:
1975 /* Don't perform the operation if flag_signaling_nans is on
1976 and the operand is a signaling NaN. */
1977 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1978 return NULL_RTX;
1979 d = real_value_truncate (mode, d);
1980 break;
1981 case FLOAT_EXTEND:
1982 /* Don't perform the operation if flag_signaling_nans is on
1983 and the operand is a signaling NaN. */
1984 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1985 return NULL_RTX;
1986 /* All this does is change the mode, unless changing
1987 mode class. */
1988 if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
1989 real_convert (&d, mode, &d);
1990 break;
1991 case FIX:
1992 /* Don't perform the operation if flag_signaling_nans is on
1993 and the operand is a signaling NaN. */
1994 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1995 return NULL_RTX;
1996 real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
1997 break;
1998 case NOT:
2000 long tmp[4];
2001 int i;
2003 real_to_target (tmp, &d, GET_MODE (op));
2004 for (i = 0; i < 4; i++)
2005 tmp[i] = ~tmp[i];
2006 real_from_target (&d, tmp, mode);
2007 break;
2009 default:
2010 gcc_unreachable ();
2012 return const_double_from_real_value (d, mode);
2014 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2015 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2016 && is_int_mode (mode, &result_mode))
2018 unsigned int width = GET_MODE_PRECISION (result_mode);
2019 if (width > MAX_BITSIZE_MODE_ANY_INT)
2020 return 0;
2022 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2023 operators are intentionally left unspecified (to ease implementation
2024 by target backends), for consistency, this routine implements the
2025 same semantics for constant folding as used by the middle-end. */
2027 /* This was formerly used only for non-IEEE float.
2028 eggert@twinsun.com says it is safe for IEEE also. */
2029 REAL_VALUE_TYPE t;
2030 const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2031 wide_int wmax, wmin;
2032 /* This is part of the abi to real_to_integer, but we check
2033 things before making this call. */
2034 bool fail;
2036 switch (code)
2038 case FIX:
2039 if (REAL_VALUE_ISNAN (*x))
2040 return const0_rtx;
2042 /* Test against the signed upper bound. */
2043 wmax = wi::max_value (width, SIGNED);
2044 real_from_integer (&t, VOIDmode, wmax, SIGNED);
2045 if (real_less (&t, x))
2046 return immed_wide_int_const (wmax, mode);
2048 /* Test against the signed lower bound. */
2049 wmin = wi::min_value (width, SIGNED);
2050 real_from_integer (&t, VOIDmode, wmin, SIGNED);
2051 if (real_less (x, &t))
2052 return immed_wide_int_const (wmin, mode);
2054 return immed_wide_int_const (real_to_integer (x, &fail, width),
2055 mode);
2057 case UNSIGNED_FIX:
2058 if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2059 return const0_rtx;
2061 /* Test against the unsigned upper bound. */
2062 wmax = wi::max_value (width, UNSIGNED);
2063 real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2064 if (real_less (&t, x))
2065 return immed_wide_int_const (wmax, mode);
2067 return immed_wide_int_const (real_to_integer (x, &fail, width),
2068 mode);
2070 default:
2071 gcc_unreachable ();
2075 /* Handle polynomial integers. */
2076 else if (CONST_POLY_INT_P (op))
2078 poly_wide_int result;
2079 switch (code)
2081 case NEG:
2082 result = -const_poly_int_value (op);
2083 break;
2085 case NOT:
2086 result = ~const_poly_int_value (op);
2087 break;
2089 default:
2090 return NULL_RTX;
2092 return immed_wide_int_const (result, mode);
2095 return NULL_RTX;
2098 /* Subroutine of simplify_binary_operation to simplify a binary operation
2099 CODE that can commute with byte swapping, with result mode MODE and
2100 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2101 Return zero if no simplification or canonicalization is possible. */
2104 simplify_context::simplify_byte_swapping_operation (rtx_code code,
2105 machine_mode mode,
2106 rtx op0, rtx op1)
2108 rtx tem;
2110 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2111 if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2113 tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2114 simplify_gen_unary (BSWAP, mode, op1, mode));
2115 return simplify_gen_unary (BSWAP, mode, tem, mode);
2118 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2119 if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2121 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2122 return simplify_gen_unary (BSWAP, mode, tem, mode);
2125 return NULL_RTX;
2128 /* Subroutine of simplify_binary_operation to simplify a commutative,
2129 associative binary operation CODE with result mode MODE, operating
2130 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2131 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2132 canonicalization is possible. */
2135 simplify_context::simplify_associative_operation (rtx_code code,
2136 machine_mode mode,
2137 rtx op0, rtx op1)
2139 rtx tem;
2141 /* Linearize the operator to the left. */
2142 if (GET_CODE (op1) == code)
2144 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2145 if (GET_CODE (op0) == code)
2147 tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2148 return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2151 /* "a op (b op c)" becomes "(b op c) op a". */
2152 if (! swap_commutative_operands_p (op1, op0))
2153 return simplify_gen_binary (code, mode, op1, op0);
2155 std::swap (op0, op1);
2158 if (GET_CODE (op0) == code)
2160 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2161 if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2163 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2164 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2167 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2168 tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2169 if (tem != 0)
2170 return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2172 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2173 tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2174 if (tem != 0)
2175 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2178 return 0;
2181 /* Return a mask describing the COMPARISON. */
2182 static int
2183 comparison_to_mask (enum rtx_code comparison)
2185 switch (comparison)
2187 case LT:
2188 return 8;
2189 case GT:
2190 return 4;
2191 case EQ:
2192 return 2;
2193 case UNORDERED:
2194 return 1;
2196 case LTGT:
2197 return 12;
2198 case LE:
2199 return 10;
2200 case GE:
2201 return 6;
2202 case UNLT:
2203 return 9;
2204 case UNGT:
2205 return 5;
2206 case UNEQ:
2207 return 3;
2209 case ORDERED:
2210 return 14;
2211 case NE:
2212 return 13;
2213 case UNLE:
2214 return 11;
2215 case UNGE:
2216 return 7;
2218 default:
2219 gcc_unreachable ();
2223 /* Return a comparison corresponding to the MASK. */
2224 static enum rtx_code
2225 mask_to_comparison (int mask)
2227 switch (mask)
2229 case 8:
2230 return LT;
2231 case 4:
2232 return GT;
2233 case 2:
2234 return EQ;
2235 case 1:
2236 return UNORDERED;
2238 case 12:
2239 return LTGT;
2240 case 10:
2241 return LE;
2242 case 6:
2243 return GE;
2244 case 9:
2245 return UNLT;
2246 case 5:
2247 return UNGT;
2248 case 3:
2249 return UNEQ;
2251 case 14:
2252 return ORDERED;
2253 case 13:
2254 return NE;
2255 case 11:
2256 return UNLE;
2257 case 7:
2258 return UNGE;
2260 default:
2261 gcc_unreachable ();
2265 /* Return true if CODE is valid for comparisons of mode MODE, false
2266 otherwise.
2268 It is always safe to return false, even if the code was valid for the
2269 given mode as that will merely suppress optimizations. */
2271 static bool
2272 comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2274 switch (code)
2276 /* These are valid for integral, floating and vector modes. */
2277 case NE:
2278 case EQ:
2279 case GE:
2280 case GT:
2281 case LE:
2282 case LT:
2283 return (INTEGRAL_MODE_P (mode)
2284 || FLOAT_MODE_P (mode)
2285 || VECTOR_MODE_P (mode));
2287 /* These are valid for floating point modes. */
2288 case LTGT:
2289 case UNORDERED:
2290 case ORDERED:
2291 case UNEQ:
2292 case UNGE:
2293 case UNGT:
2294 case UNLE:
2295 case UNLT:
2296 return FLOAT_MODE_P (mode);
2298 /* These are filtered out in simplify_logical_operation, but
2299 we check for them too as a matter of safety. They are valid
2300 for integral and vector modes. */
2301 case GEU:
2302 case GTU:
2303 case LEU:
2304 case LTU:
2305 return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2307 default:
2308 gcc_unreachable ();
2312 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2313 false/true value of comparison with MODE where comparison operands
2314 have CMP_MODE. */
2316 static rtx
2317 relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2319 if (SCALAR_FLOAT_MODE_P (mode))
2321 if (res == const0_rtx)
2322 return CONST0_RTX (mode);
2323 #ifdef FLOAT_STORE_FLAG_VALUE
2324 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2325 return const_double_from_real_value (val, mode);
2326 #else
2327 return NULL_RTX;
2328 #endif
2330 if (VECTOR_MODE_P (mode))
2332 if (res == const0_rtx)
2333 return CONST0_RTX (mode);
2334 #ifdef VECTOR_STORE_FLAG_VALUE
2335 rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2336 if (val == NULL_RTX)
2337 return NULL_RTX;
2338 if (val == const1_rtx)
2339 return CONST1_RTX (mode);
2341 return gen_const_vec_duplicate (mode, val);
2342 #else
2343 return NULL_RTX;
2344 #endif
2346 /* For vector comparison with scalar int result, it is unknown
2347 if the target means here a comparison into an integral bitmask,
2348 or comparison where all comparisons true mean const_true_rtx
2349 whole result, or where any comparisons true mean const_true_rtx
2350 whole result. For const0_rtx all the cases are the same. */
2351 if (VECTOR_MODE_P (cmp_mode)
2352 && SCALAR_INT_MODE_P (mode)
2353 && res == const_true_rtx)
2354 return NULL_RTX;
2356 return res;
2359 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2360 and OP1, which should be both relational operations. Return 0 if no such
2361 simplification is possible. */
2363 simplify_context::simplify_logical_relational_operation (rtx_code code,
2364 machine_mode mode,
2365 rtx op0, rtx op1)
2367 /* We only handle IOR of two relational operations. */
2368 if (code != IOR)
2369 return 0;
2371 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2372 return 0;
2374 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2375 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2376 return 0;
2378 enum rtx_code code0 = GET_CODE (op0);
2379 enum rtx_code code1 = GET_CODE (op1);
2381 /* We don't handle unsigned comparisons currently. */
2382 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2383 return 0;
2384 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2385 return 0;
2387 int mask0 = comparison_to_mask (code0);
2388 int mask1 = comparison_to_mask (code1);
2390 int mask = mask0 | mask1;
2392 if (mask == 15)
2393 return relational_result (mode, GET_MODE (op0), const_true_rtx);
2395 code = mask_to_comparison (mask);
2397 /* Many comparison codes are only valid for certain mode classes. */
2398 if (!comparison_code_valid_for_mode (code, mode))
2399 return 0;
2401 op0 = XEXP (op1, 0);
2402 op1 = XEXP (op1, 1);
2404 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2407 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2408 and OP1. Return 0 if no simplification is possible.
2410 Don't use this for relational operations such as EQ or LT.
2411 Use simplify_relational_operation instead. */
2413 simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2414 rtx op0, rtx op1)
2416 rtx trueop0, trueop1;
2417 rtx tem;
2419 /* Relational operations don't work here. We must know the mode
2420 of the operands in order to do the comparison correctly.
2421 Assuming a full word can give incorrect results.
2422 Consider comparing 128 with -128 in QImode. */
2423 gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2424 gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2426 /* Make sure the constant is second. */
2427 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2428 && swap_commutative_operands_p (op0, op1))
2429 std::swap (op0, op1);
2431 trueop0 = avoid_constant_pool_reference (op0);
2432 trueop1 = avoid_constant_pool_reference (op1);
2434 tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2435 if (tem)
2436 return tem;
2437 tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2439 if (tem)
2440 return tem;
2442 /* If the above steps did not result in a simplification and op0 or op1
2443 were constant pool references, use the referenced constants directly. */
2444 if (trueop0 != op0 || trueop1 != op1)
2445 return simplify_gen_binary (code, mode, trueop0, trueop1);
2447 return NULL_RTX;
2450 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2451 which OP0 and OP1 are both vector series or vector duplicates
2452 (which are really just series with a step of 0). If so, try to
2453 form a new series by applying CODE to the bases and to the steps.
2454 Return null if no simplification is possible.
2456 MODE is the mode of the operation and is known to be a vector
2457 integer mode. */
2460 simplify_context::simplify_binary_operation_series (rtx_code code,
2461 machine_mode mode,
2462 rtx op0, rtx op1)
2464 rtx base0, step0;
2465 if (vec_duplicate_p (op0, &base0))
2466 step0 = const0_rtx;
2467 else if (!vec_series_p (op0, &base0, &step0))
2468 return NULL_RTX;
2470 rtx base1, step1;
2471 if (vec_duplicate_p (op1, &base1))
2472 step1 = const0_rtx;
2473 else if (!vec_series_p (op1, &base1, &step1))
2474 return NULL_RTX;
2476 /* Only create a new series if we can simplify both parts. In other
2477 cases this isn't really a simplification, and it's not necessarily
2478 a win to replace a vector operation with a scalar operation. */
2479 scalar_mode inner_mode = GET_MODE_INNER (mode);
2480 rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2481 if (!new_base)
2482 return NULL_RTX;
2484 rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2485 if (!new_step)
2486 return NULL_RTX;
2488 return gen_vec_series (mode, new_base, new_step);
2491 /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2492 operation CODE with result mode MODE, operating on OP0 and OP1.
2493 e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2494 Returns NULL_RTX if no simplification is possible. */
2497 simplify_context::simplify_distributive_operation (rtx_code code,
2498 machine_mode mode,
2499 rtx op0, rtx op1)
2501 enum rtx_code op = GET_CODE (op0);
2502 gcc_assert (GET_CODE (op1) == op);
2504 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2505 && ! side_effects_p (XEXP (op0, 1)))
2506 return simplify_gen_binary (op, mode,
2507 simplify_gen_binary (code, mode,
2508 XEXP (op0, 0),
2509 XEXP (op1, 0)),
2510 XEXP (op0, 1));
2512 if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2514 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2515 && ! side_effects_p (XEXP (op0, 0)))
2516 return simplify_gen_binary (op, mode,
2517 simplify_gen_binary (code, mode,
2518 XEXP (op0, 1),
2519 XEXP (op1, 1)),
2520 XEXP (op0, 0));
2521 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2522 && ! side_effects_p (XEXP (op0, 0)))
2523 return simplify_gen_binary (op, mode,
2524 simplify_gen_binary (code, mode,
2525 XEXP (op0, 1),
2526 XEXP (op1, 0)),
2527 XEXP (op0, 0));
2528 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2529 && ! side_effects_p (XEXP (op0, 1)))
2530 return simplify_gen_binary (op, mode,
2531 simplify_gen_binary (code, mode,
2532 XEXP (op0, 0),
2533 XEXP (op1, 1)),
2534 XEXP (op0, 1));
2537 return NULL_RTX;
2540 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2541 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2542 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2543 actual constants. */
2546 simplify_context::simplify_binary_operation_1 (rtx_code code,
2547 machine_mode mode,
2548 rtx op0, rtx op1,
2549 rtx trueop0, rtx trueop1)
2551 rtx tem, reversed, opleft, opright, elt0, elt1;
2552 HOST_WIDE_INT val;
2553 scalar_int_mode int_mode, inner_mode;
2554 poly_int64 offset;
2556 /* Even if we can't compute a constant result,
2557 there are some cases worth simplifying. */
2559 switch (code)
2561 case PLUS:
2562 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2563 when x is NaN, infinite, or finite and nonzero. They aren't
2564 when x is -0 and the rounding mode is not towards -infinity,
2565 since (-0) + 0 is then 0. */
2566 if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2567 return op0;
2569 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2570 transformations are safe even for IEEE. */
2571 if (GET_CODE (op0) == NEG)
2572 return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2573 else if (GET_CODE (op1) == NEG)
2574 return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2576 /* (~a) + 1 -> -a */
2577 if (INTEGRAL_MODE_P (mode)
2578 && GET_CODE (op0) == NOT
2579 && trueop1 == const1_rtx)
2580 return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2582 /* Handle both-operands-constant cases. We can only add
2583 CONST_INTs to constants since the sum of relocatable symbols
2584 can't be handled by most assemblers. Don't add CONST_INT
2585 to CONST_INT since overflow won't be computed properly if wider
2586 than HOST_BITS_PER_WIDE_INT. */
2588 if ((GET_CODE (op0) == CONST
2589 || GET_CODE (op0) == SYMBOL_REF
2590 || GET_CODE (op0) == LABEL_REF)
2591 && poly_int_rtx_p (op1, &offset))
2592 return plus_constant (mode, op0, offset);
2593 else if ((GET_CODE (op1) == CONST
2594 || GET_CODE (op1) == SYMBOL_REF
2595 || GET_CODE (op1) == LABEL_REF)
2596 && poly_int_rtx_p (op0, &offset))
2597 return plus_constant (mode, op1, offset);
2599 /* See if this is something like X * C - X or vice versa or
2600 if the multiplication is written as a shift. If so, we can
2601 distribute and make a new multiply, shift, or maybe just
2602 have X (if C is 2 in the example above). But don't make
2603 something more expensive than we had before. */
2605 if (is_a <scalar_int_mode> (mode, &int_mode))
2607 rtx lhs = op0, rhs = op1;
2609 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2610 wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2612 if (GET_CODE (lhs) == NEG)
2614 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2615 lhs = XEXP (lhs, 0);
2617 else if (GET_CODE (lhs) == MULT
2618 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2620 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2621 lhs = XEXP (lhs, 0);
2623 else if (GET_CODE (lhs) == ASHIFT
2624 && CONST_INT_P (XEXP (lhs, 1))
2625 && INTVAL (XEXP (lhs, 1)) >= 0
2626 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2628 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2629 GET_MODE_PRECISION (int_mode));
2630 lhs = XEXP (lhs, 0);
2633 if (GET_CODE (rhs) == NEG)
2635 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2636 rhs = XEXP (rhs, 0);
2638 else if (GET_CODE (rhs) == MULT
2639 && CONST_INT_P (XEXP (rhs, 1)))
2641 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2642 rhs = XEXP (rhs, 0);
2644 else if (GET_CODE (rhs) == ASHIFT
2645 && CONST_INT_P (XEXP (rhs, 1))
2646 && INTVAL (XEXP (rhs, 1)) >= 0
2647 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2649 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2650 GET_MODE_PRECISION (int_mode));
2651 rhs = XEXP (rhs, 0);
2654 if (rtx_equal_p (lhs, rhs))
2656 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2657 rtx coeff;
2658 bool speed = optimize_function_for_speed_p (cfun);
2660 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2662 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2663 return (set_src_cost (tem, int_mode, speed)
2664 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2667 /* Optimize (X - 1) * Y + Y to X * Y. */
2668 lhs = op0;
2669 rhs = op1;
2670 if (GET_CODE (op0) == MULT)
2672 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2673 && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
2674 || (GET_CODE (XEXP (op0, 0)) == MINUS
2675 && XEXP (XEXP (op0, 0), 1) == const1_rtx))
2676 && rtx_equal_p (XEXP (op0, 1), op1))
2677 lhs = XEXP (XEXP (op0, 0), 0);
2678 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2679 && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
2680 || (GET_CODE (XEXP (op0, 1)) == MINUS
2681 && XEXP (XEXP (op0, 1), 1) == const1_rtx))
2682 && rtx_equal_p (XEXP (op0, 0), op1))
2683 lhs = XEXP (XEXP (op0, 1), 0);
2685 else if (GET_CODE (op1) == MULT)
2687 if (((GET_CODE (XEXP (op1, 0)) == PLUS
2688 && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
2689 || (GET_CODE (XEXP (op1, 0)) == MINUS
2690 && XEXP (XEXP (op1, 0), 1) == const1_rtx))
2691 && rtx_equal_p (XEXP (op1, 1), op0))
2692 rhs = XEXP (XEXP (op1, 0), 0);
2693 else if (((GET_CODE (XEXP (op1, 1)) == PLUS
2694 && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
2695 || (GET_CODE (XEXP (op1, 1)) == MINUS
2696 && XEXP (XEXP (op1, 1), 1) == const1_rtx))
2697 && rtx_equal_p (XEXP (op1, 0), op0))
2698 rhs = XEXP (XEXP (op1, 1), 0);
2700 if (lhs != op0 || rhs != op1)
2701 return simplify_gen_binary (MULT, int_mode, lhs, rhs);
2704 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2705 if (CONST_SCALAR_INT_P (op1)
2706 && GET_CODE (op0) == XOR
2707 && CONST_SCALAR_INT_P (XEXP (op0, 1))
2708 && mode_signbit_p (mode, op1))
2709 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2710 simplify_gen_binary (XOR, mode, op1,
2711 XEXP (op0, 1)));
2713 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2714 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2715 && GET_CODE (op0) == MULT
2716 && GET_CODE (XEXP (op0, 0)) == NEG)
2718 rtx in1, in2;
2720 in1 = XEXP (XEXP (op0, 0), 0);
2721 in2 = XEXP (op0, 1);
2722 return simplify_gen_binary (MINUS, mode, op1,
2723 simplify_gen_binary (MULT, mode,
2724 in1, in2));
2727 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2728 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2729 is 1. */
2730 if (COMPARISON_P (op0)
2731 && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2732 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2733 && (reversed = reversed_comparison (op0, mode)))
2734 return
2735 simplify_gen_unary (NEG, mode, reversed, mode);
2737 /* If one of the operands is a PLUS or a MINUS, see if we can
2738 simplify this by the associative law.
2739 Don't use the associative law for floating point.
2740 The inaccuracy makes it nonassociative,
2741 and subtle programs can break if operations are associated. */
2743 if (INTEGRAL_MODE_P (mode)
2744 && (plus_minus_operand_p (op0)
2745 || plus_minus_operand_p (op1))
2746 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2747 return tem;
2749 /* Reassociate floating point addition only when the user
2750 specifies associative math operations. */
2751 if (FLOAT_MODE_P (mode)
2752 && flag_associative_math)
2754 tem = simplify_associative_operation (code, mode, op0, op1);
2755 if (tem)
2756 return tem;
2759 /* Handle vector series. */
2760 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2762 tem = simplify_binary_operation_series (code, mode, op0, op1);
2763 if (tem)
2764 return tem;
2766 break;
2768 case COMPARE:
2769 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
2770 if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
2771 || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
2772 && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
2774 rtx xop00 = XEXP (op0, 0);
2775 rtx xop10 = XEXP (op1, 0);
2777 if (REG_P (xop00) && REG_P (xop10)
2778 && REGNO (xop00) == REGNO (xop10)
2779 && GET_MODE (xop00) == mode
2780 && GET_MODE (xop10) == mode
2781 && GET_MODE_CLASS (mode) == MODE_CC)
2782 return xop00;
2784 break;
2786 case MINUS:
2787 /* We can't assume x-x is 0 even with non-IEEE floating point,
2788 but since it is zero except in very strange circumstances, we
2789 will treat it as zero with -ffinite-math-only. */
2790 if (rtx_equal_p (trueop0, trueop1)
2791 && ! side_effects_p (op0)
2792 && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
2793 return CONST0_RTX (mode);
2795 /* Change subtraction from zero into negation. (0 - x) is the
2796 same as -x when x is NaN, infinite, or finite and nonzero.
2797 But if the mode has signed zeros, and does not round towards
2798 -infinity, then 0 - 0 is 0, not -0. */
2799 if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
2800 return simplify_gen_unary (NEG, mode, op1, mode);
2802 /* (-1 - a) is ~a, unless the expression contains symbolic
2803 constants, in which case not retaining additions and
2804 subtractions could cause invalid assembly to be produced. */
2805 if (trueop0 == constm1_rtx
2806 && !contains_symbolic_reference_p (op1))
2807 return simplify_gen_unary (NOT, mode, op1, mode);
2809 /* Subtracting 0 has no effect unless the mode has signalling NaNs,
2810 or has signed zeros and supports rounding towards -infinity.
2811 In such a case, 0 - 0 is -0. */
2812 if (!(HONOR_SIGNED_ZEROS (mode)
2813 && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2814 && !HONOR_SNANS (mode)
2815 && trueop1 == CONST0_RTX (mode))
2816 return op0;
2818 /* See if this is something like X * C - X or vice versa or
2819 if the multiplication is written as a shift. If so, we can
2820 distribute and make a new multiply, shift, or maybe just
2821 have X (if C is 2 in the example above). But don't make
2822 something more expensive than we had before. */
2824 if (is_a <scalar_int_mode> (mode, &int_mode))
2826 rtx lhs = op0, rhs = op1;
2828 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2829 wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2831 if (GET_CODE (lhs) == NEG)
2833 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2834 lhs = XEXP (lhs, 0);
2836 else if (GET_CODE (lhs) == MULT
2837 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2839 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2840 lhs = XEXP (lhs, 0);
2842 else if (GET_CODE (lhs) == ASHIFT
2843 && CONST_INT_P (XEXP (lhs, 1))
2844 && INTVAL (XEXP (lhs, 1)) >= 0
2845 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2847 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2848 GET_MODE_PRECISION (int_mode));
2849 lhs = XEXP (lhs, 0);
2852 if (GET_CODE (rhs) == NEG)
2854 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2855 rhs = XEXP (rhs, 0);
2857 else if (GET_CODE (rhs) == MULT
2858 && CONST_INT_P (XEXP (rhs, 1)))
2860 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
2861 rhs = XEXP (rhs, 0);
2863 else if (GET_CODE (rhs) == ASHIFT
2864 && CONST_INT_P (XEXP (rhs, 1))
2865 && INTVAL (XEXP (rhs, 1)) >= 0
2866 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2868 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2869 GET_MODE_PRECISION (int_mode));
2870 negcoeff1 = -negcoeff1;
2871 rhs = XEXP (rhs, 0);
2874 if (rtx_equal_p (lhs, rhs))
2876 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
2877 rtx coeff;
2878 bool speed = optimize_function_for_speed_p (cfun);
2880 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
2882 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2883 return (set_src_cost (tem, int_mode, speed)
2884 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2887 /* Optimize (X + 1) * Y - Y to X * Y. */
2888 lhs = op0;
2889 if (GET_CODE (op0) == MULT)
2891 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2892 && XEXP (XEXP (op0, 0), 1) == const1_rtx)
2893 || (GET_CODE (XEXP (op0, 0)) == MINUS
2894 && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
2895 && rtx_equal_p (XEXP (op0, 1), op1))
2896 lhs = XEXP (XEXP (op0, 0), 0);
2897 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2898 && XEXP (XEXP (op0, 1), 1) == const1_rtx)
2899 || (GET_CODE (XEXP (op0, 1)) == MINUS
2900 && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
2901 && rtx_equal_p (XEXP (op0, 0), op1))
2902 lhs = XEXP (XEXP (op0, 1), 0);
2904 if (lhs != op0)
2905 return simplify_gen_binary (MULT, int_mode, lhs, op1);
2908 /* (a - (-b)) -> (a + b). True even for IEEE. */
2909 if (GET_CODE (op1) == NEG)
2910 return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
2912 /* (-x - c) may be simplified as (-c - x). */
2913 if (GET_CODE (op0) == NEG
2914 && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
2916 tem = simplify_unary_operation (NEG, mode, op1, mode);
2917 if (tem)
2918 return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
2921 if ((GET_CODE (op0) == CONST
2922 || GET_CODE (op0) == SYMBOL_REF
2923 || GET_CODE (op0) == LABEL_REF)
2924 && poly_int_rtx_p (op1, &offset))
2925 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
2927 /* Don't let a relocatable value get a negative coeff. */
2928 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
2929 return simplify_gen_binary (PLUS, mode,
2930 op0,
2931 neg_poly_int_rtx (mode, op1));
2933 /* (x - (x & y)) -> (x & ~y) */
2934 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
2936 if (rtx_equal_p (op0, XEXP (op1, 0)))
2938 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
2939 GET_MODE (XEXP (op1, 1)));
2940 return simplify_gen_binary (AND, mode, op0, tem);
2942 if (rtx_equal_p (op0, XEXP (op1, 1)))
2944 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
2945 GET_MODE (XEXP (op1, 0)));
2946 return simplify_gen_binary (AND, mode, op0, tem);
2950 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
2951 by reversing the comparison code if valid. */
2952 if (STORE_FLAG_VALUE == 1
2953 && trueop0 == const1_rtx
2954 && COMPARISON_P (op1)
2955 && (reversed = reversed_comparison (op1, mode)))
2956 return reversed;
2958 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
2959 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2960 && GET_CODE (op1) == MULT
2961 && GET_CODE (XEXP (op1, 0)) == NEG)
2963 rtx in1, in2;
2965 in1 = XEXP (XEXP (op1, 0), 0);
2966 in2 = XEXP (op1, 1);
2967 return simplify_gen_binary (PLUS, mode,
2968 simplify_gen_binary (MULT, mode,
2969 in1, in2),
2970 op0);
2973 /* Canonicalize (minus (neg A) (mult B C)) to
2974 (minus (mult (neg B) C) A). */
2975 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2976 && GET_CODE (op1) == MULT
2977 && GET_CODE (op0) == NEG)
2979 rtx in1, in2;
2981 in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
2982 in2 = XEXP (op1, 1);
2983 return simplify_gen_binary (MINUS, mode,
2984 simplify_gen_binary (MULT, mode,
2985 in1, in2),
2986 XEXP (op0, 0));
2989 /* If one of the operands is a PLUS or a MINUS, see if we can
2990 simplify this by the associative law. This will, for example,
2991 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
2992 Don't use the associative law for floating point.
2993 The inaccuracy makes it nonassociative,
2994 and subtle programs can break if operations are associated. */
2996 if (INTEGRAL_MODE_P (mode)
2997 && (plus_minus_operand_p (op0)
2998 || plus_minus_operand_p (op1))
2999 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3000 return tem;
3002 /* Handle vector series. */
3003 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3005 tem = simplify_binary_operation_series (code, mode, op0, op1);
3006 if (tem)
3007 return tem;
3009 break;
3011 case MULT:
3012 if (trueop1 == constm1_rtx)
3013 return simplify_gen_unary (NEG, mode, op0, mode);
3015 if (GET_CODE (op0) == NEG)
3017 rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3018 /* If op1 is a MULT as well and simplify_unary_operation
3019 just moved the NEG to the second operand, simplify_gen_binary
3020 below could through simplify_associative_operation move
3021 the NEG around again and recurse endlessly. */
3022 if (temp
3023 && GET_CODE (op1) == MULT
3024 && GET_CODE (temp) == MULT
3025 && XEXP (op1, 0) == XEXP (temp, 0)
3026 && GET_CODE (XEXP (temp, 1)) == NEG
3027 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3028 temp = NULL_RTX;
3029 if (temp)
3030 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3032 if (GET_CODE (op1) == NEG)
3034 rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3035 /* If op0 is a MULT as well and simplify_unary_operation
3036 just moved the NEG to the second operand, simplify_gen_binary
3037 below could through simplify_associative_operation move
3038 the NEG around again and recurse endlessly. */
3039 if (temp
3040 && GET_CODE (op0) == MULT
3041 && GET_CODE (temp) == MULT
3042 && XEXP (op0, 0) == XEXP (temp, 0)
3043 && GET_CODE (XEXP (temp, 1)) == NEG
3044 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3045 temp = NULL_RTX;
3046 if (temp)
3047 return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3050 /* Maybe simplify x * 0 to 0. The reduction is not valid if
3051 x is NaN, since x * 0 is then also NaN. Nor is it valid
3052 when the mode has signed zeros, since multiplying a negative
3053 number by 0 will give -0, not 0. */
3054 if (!HONOR_NANS (mode)
3055 && !HONOR_SIGNED_ZEROS (mode)
3056 && trueop1 == CONST0_RTX (mode)
3057 && ! side_effects_p (op0))
3058 return op1;
3060 /* In IEEE floating point, x*1 is not equivalent to x for
3061 signalling NaNs. */
3062 if (!HONOR_SNANS (mode)
3063 && trueop1 == CONST1_RTX (mode))
3064 return op0;
3066 /* Convert multiply by constant power of two into shift. */
3067 if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3069 val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3070 if (val >= 0)
3071 return simplify_gen_binary (ASHIFT, mode, op0,
3072 gen_int_shift_amount (mode, val));
3075 /* x*2 is x+x and x*(-1) is -x */
3076 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3077 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3078 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3079 && GET_MODE (op0) == mode)
3081 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3083 if (real_equal (d1, &dconst2))
3084 return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3086 if (!HONOR_SNANS (mode)
3087 && real_equal (d1, &dconstm1))
3088 return simplify_gen_unary (NEG, mode, op0, mode);
3091 /* Optimize -x * -x as x * x. */
3092 if (FLOAT_MODE_P (mode)
3093 && GET_CODE (op0) == NEG
3094 && GET_CODE (op1) == NEG
3095 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3096 && !side_effects_p (XEXP (op0, 0)))
3097 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3099 /* Likewise, optimize abs(x) * abs(x) as x * x. */
3100 if (SCALAR_FLOAT_MODE_P (mode)
3101 && GET_CODE (op0) == ABS
3102 && GET_CODE (op1) == ABS
3103 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3104 && !side_effects_p (XEXP (op0, 0)))
3105 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3107 /* Reassociate multiplication, but for floating point MULTs
3108 only when the user specifies unsafe math optimizations. */
3109 if (! FLOAT_MODE_P (mode)
3110 || flag_unsafe_math_optimizations)
3112 tem = simplify_associative_operation (code, mode, op0, op1);
3113 if (tem)
3114 return tem;
3116 break;
3118 case IOR:
3119 if (trueop1 == CONST0_RTX (mode))
3120 return op0;
3121 if (INTEGRAL_MODE_P (mode)
3122 && trueop1 == CONSTM1_RTX (mode)
3123 && !side_effects_p (op0))
3124 return op1;
3125 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3126 return op0;
3127 /* A | (~A) -> -1 */
3128 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3129 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3130 && ! side_effects_p (op0)
3131 && SCALAR_INT_MODE_P (mode))
3132 return constm1_rtx;
3134 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3135 if (CONST_INT_P (op1)
3136 && HWI_COMPUTABLE_MODE_P (mode)
3137 && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3138 && !side_effects_p (op0))
3139 return op1;
3141 /* Canonicalize (X & C1) | C2. */
3142 if (GET_CODE (op0) == AND
3143 && CONST_INT_P (trueop1)
3144 && CONST_INT_P (XEXP (op0, 1)))
3146 HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3147 HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3148 HOST_WIDE_INT c2 = INTVAL (trueop1);
3150 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3151 if ((c1 & c2) == c1
3152 && !side_effects_p (XEXP (op0, 0)))
3153 return trueop1;
3155 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3156 if (((c1|c2) & mask) == mask)
3157 return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3160 /* Convert (A & B) | A to A. */
3161 if (GET_CODE (op0) == AND
3162 && (rtx_equal_p (XEXP (op0, 0), op1)
3163 || rtx_equal_p (XEXP (op0, 1), op1))
3164 && ! side_effects_p (XEXP (op0, 0))
3165 && ! side_effects_p (XEXP (op0, 1)))
3166 return op1;
3168 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3169 mode size to (rotate A CX). */
3171 if (GET_CODE (op1) == ASHIFT
3172 || GET_CODE (op1) == SUBREG)
3174 opleft = op1;
3175 opright = op0;
3177 else
3179 opright = op1;
3180 opleft = op0;
3183 if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3184 && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3185 && CONST_INT_P (XEXP (opleft, 1))
3186 && CONST_INT_P (XEXP (opright, 1))
3187 && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3188 == GET_MODE_UNIT_PRECISION (mode)))
3189 return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3191 /* Same, but for ashift that has been "simplified" to a wider mode
3192 by simplify_shift_const. */
3194 if (GET_CODE (opleft) == SUBREG
3195 && is_a <scalar_int_mode> (mode, &int_mode)
3196 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3197 &inner_mode)
3198 && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3199 && GET_CODE (opright) == LSHIFTRT
3200 && GET_CODE (XEXP (opright, 0)) == SUBREG
3201 && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3202 && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3203 && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3204 SUBREG_REG (XEXP (opright, 0)))
3205 && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3206 && CONST_INT_P (XEXP (opright, 1))
3207 && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3208 + INTVAL (XEXP (opright, 1))
3209 == GET_MODE_PRECISION (int_mode)))
3210 return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3211 XEXP (SUBREG_REG (opleft), 1));
3213 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3214 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3215 the PLUS does not affect any of the bits in OP1: then we can do
3216 the IOR as a PLUS and we can associate. This is valid if OP1
3217 can be safely shifted left C bits. */
3218 if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3219 && GET_CODE (XEXP (op0, 0)) == PLUS
3220 && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3221 && CONST_INT_P (XEXP (op0, 1))
3222 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3224 int count = INTVAL (XEXP (op0, 1));
3225 HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3227 if (mask >> count == INTVAL (trueop1)
3228 && trunc_int_for_mode (mask, mode) == mask
3229 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3230 return simplify_gen_binary (ASHIFTRT, mode,
3231 plus_constant (mode, XEXP (op0, 0),
3232 mask),
3233 XEXP (op0, 1));
3236 /* The following happens with bitfield merging.
3237 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3238 if (GET_CODE (op0) == AND
3239 && GET_CODE (op1) == AND
3240 && CONST_INT_P (XEXP (op0, 1))
3241 && CONST_INT_P (XEXP (op1, 1))
3242 && (INTVAL (XEXP (op0, 1))
3243 == ~INTVAL (XEXP (op1, 1))))
3245 /* The IOR may be on both sides. */
3246 rtx top0 = NULL_RTX, top1 = NULL_RTX;
3247 if (GET_CODE (XEXP (op1, 0)) == IOR)
3248 top0 = op0, top1 = op1;
3249 else if (GET_CODE (XEXP (op0, 0)) == IOR)
3250 top0 = op1, top1 = op0;
3251 if (top0 && top1)
3253 /* X may be on either side of the inner IOR. */
3254 rtx tem = NULL_RTX;
3255 if (rtx_equal_p (XEXP (top0, 0),
3256 XEXP (XEXP (top1, 0), 0)))
3257 tem = XEXP (XEXP (top1, 0), 1);
3258 else if (rtx_equal_p (XEXP (top0, 0),
3259 XEXP (XEXP (top1, 0), 1)))
3260 tem = XEXP (XEXP (top1, 0), 0);
3261 if (tem)
3262 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3263 simplify_gen_binary
3264 (AND, mode, tem, XEXP (top1, 1)));
3268 /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3269 if (GET_CODE (op0) == GET_CODE (op1)
3270 && (GET_CODE (op0) == AND
3271 || GET_CODE (op0) == IOR
3272 || GET_CODE (op0) == LSHIFTRT
3273 || GET_CODE (op0) == ASHIFTRT
3274 || GET_CODE (op0) == ASHIFT
3275 || GET_CODE (op0) == ROTATE
3276 || GET_CODE (op0) == ROTATERT))
3278 tem = simplify_distributive_operation (code, mode, op0, op1);
3279 if (tem)
3280 return tem;
3283 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3284 if (tem)
3285 return tem;
3287 tem = simplify_associative_operation (code, mode, op0, op1);
3288 if (tem)
3289 return tem;
3291 tem = simplify_logical_relational_operation (code, mode, op0, op1);
3292 if (tem)
3293 return tem;
3294 break;
3296 case XOR:
3297 if (trueop1 == CONST0_RTX (mode))
3298 return op0;
3299 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3300 return simplify_gen_unary (NOT, mode, op0, mode);
3301 if (rtx_equal_p (trueop0, trueop1)
3302 && ! side_effects_p (op0)
3303 && GET_MODE_CLASS (mode) != MODE_CC)
3304 return CONST0_RTX (mode);
3306 /* Canonicalize XOR of the most significant bit to PLUS. */
3307 if (CONST_SCALAR_INT_P (op1)
3308 && mode_signbit_p (mode, op1))
3309 return simplify_gen_binary (PLUS, mode, op0, op1);
3310 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3311 if (CONST_SCALAR_INT_P (op1)
3312 && GET_CODE (op0) == PLUS
3313 && CONST_SCALAR_INT_P (XEXP (op0, 1))
3314 && mode_signbit_p (mode, XEXP (op0, 1)))
3315 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3316 simplify_gen_binary (XOR, mode, op1,
3317 XEXP (op0, 1)));
3319 /* If we are XORing two things that have no bits in common,
3320 convert them into an IOR. This helps to detect rotation encoded
3321 using those methods and possibly other simplifications. */
3323 if (HWI_COMPUTABLE_MODE_P (mode)
3324 && (nonzero_bits (op0, mode)
3325 & nonzero_bits (op1, mode)) == 0)
3326 return (simplify_gen_binary (IOR, mode, op0, op1));
3328 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3329 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3330 (NOT y). */
3332 int num_negated = 0;
3334 if (GET_CODE (op0) == NOT)
3335 num_negated++, op0 = XEXP (op0, 0);
3336 if (GET_CODE (op1) == NOT)
3337 num_negated++, op1 = XEXP (op1, 0);
3339 if (num_negated == 2)
3340 return simplify_gen_binary (XOR, mode, op0, op1);
3341 else if (num_negated == 1)
3342 return simplify_gen_unary (NOT, mode,
3343 simplify_gen_binary (XOR, mode, op0, op1),
3344 mode);
3347 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3348 correspond to a machine insn or result in further simplifications
3349 if B is a constant. */
3351 if (GET_CODE (op0) == AND
3352 && rtx_equal_p (XEXP (op0, 1), op1)
3353 && ! side_effects_p (op1))
3354 return simplify_gen_binary (AND, mode,
3355 simplify_gen_unary (NOT, mode,
3356 XEXP (op0, 0), mode),
3357 op1);
3359 else if (GET_CODE (op0) == AND
3360 && rtx_equal_p (XEXP (op0, 0), op1)
3361 && ! side_effects_p (op1))
3362 return simplify_gen_binary (AND, mode,
3363 simplify_gen_unary (NOT, mode,
3364 XEXP (op0, 1), mode),
3365 op1);
3367 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3368 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3369 out bits inverted twice and not set by C. Similarly, given
3370 (xor (and (xor A B) C) D), simplify without inverting C in
3371 the xor operand: (xor (and A C) (B&C)^D).
3373 else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3374 && GET_CODE (XEXP (op0, 0)) == XOR
3375 && CONST_INT_P (op1)
3376 && CONST_INT_P (XEXP (op0, 1))
3377 && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3379 enum rtx_code op = GET_CODE (op0);
3380 rtx a = XEXP (XEXP (op0, 0), 0);
3381 rtx b = XEXP (XEXP (op0, 0), 1);
3382 rtx c = XEXP (op0, 1);
3383 rtx d = op1;
3384 HOST_WIDE_INT bval = INTVAL (b);
3385 HOST_WIDE_INT cval = INTVAL (c);
3386 HOST_WIDE_INT dval = INTVAL (d);
3387 HOST_WIDE_INT xcval;
3389 if (op == IOR)
3390 xcval = ~cval;
3391 else
3392 xcval = cval;
3394 return simplify_gen_binary (XOR, mode,
3395 simplify_gen_binary (op, mode, a, c),
3396 gen_int_mode ((bval & xcval) ^ dval,
3397 mode));
3400 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3401 we can transform like this:
3402 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3403 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3404 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3405 Attempt a few simplifications when B and C are both constants. */
3406 if (GET_CODE (op0) == AND
3407 && CONST_INT_P (op1)
3408 && CONST_INT_P (XEXP (op0, 1)))
3410 rtx a = XEXP (op0, 0);
3411 rtx b = XEXP (op0, 1);
3412 rtx c = op1;
3413 HOST_WIDE_INT bval = INTVAL (b);
3414 HOST_WIDE_INT cval = INTVAL (c);
3416 /* Instead of computing ~A&C, we compute its negated value,
3417 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3418 optimize for sure. If it does not simplify, we still try
3419 to compute ~A&C below, but since that always allocates
3420 RTL, we don't try that before committing to returning a
3421 simplified expression. */
3422 rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3423 GEN_INT (~cval));
3425 if ((~cval & bval) == 0)
3427 rtx na_c = NULL_RTX;
3428 if (n_na_c)
3429 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3430 else
3432 /* If ~A does not simplify, don't bother: we don't
3433 want to simplify 2 operations into 3, and if na_c
3434 were to simplify with na, n_na_c would have
3435 simplified as well. */
3436 rtx na = simplify_unary_operation (NOT, mode, a, mode);
3437 if (na)
3438 na_c = simplify_gen_binary (AND, mode, na, c);
3441 /* Try to simplify ~A&C | ~B&C. */
3442 if (na_c != NULL_RTX)
3443 return simplify_gen_binary (IOR, mode, na_c,
3444 gen_int_mode (~bval & cval, mode));
3446 else
3448 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3449 if (n_na_c == CONSTM1_RTX (mode))
3451 rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3452 gen_int_mode (~cval & bval,
3453 mode));
3454 return simplify_gen_binary (IOR, mode, a_nc_b,
3455 gen_int_mode (~bval & cval,
3456 mode));
3461 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3462 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3463 machines, and also has shorter instruction path length. */
3464 if (GET_CODE (op0) == AND
3465 && GET_CODE (XEXP (op0, 0)) == XOR
3466 && CONST_INT_P (XEXP (op0, 1))
3467 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3469 rtx a = trueop1;
3470 rtx b = XEXP (XEXP (op0, 0), 1);
3471 rtx c = XEXP (op0, 1);
3472 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3473 rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3474 rtx bc = simplify_gen_binary (AND, mode, b, c);
3475 return simplify_gen_binary (IOR, mode, a_nc, bc);
3477 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3478 else if (GET_CODE (op0) == AND
3479 && GET_CODE (XEXP (op0, 0)) == XOR
3480 && CONST_INT_P (XEXP (op0, 1))
3481 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3483 rtx a = XEXP (XEXP (op0, 0), 0);
3484 rtx b = trueop1;
3485 rtx c = XEXP (op0, 1);
3486 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3487 rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3488 rtx ac = simplify_gen_binary (AND, mode, a, c);
3489 return simplify_gen_binary (IOR, mode, ac, b_nc);
3492 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3493 comparison if STORE_FLAG_VALUE is 1. */
3494 if (STORE_FLAG_VALUE == 1
3495 && trueop1 == const1_rtx
3496 && COMPARISON_P (op0)
3497 && (reversed = reversed_comparison (op0, mode)))
3498 return reversed;
3500 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3501 is (lt foo (const_int 0)), so we can perform the above
3502 simplification if STORE_FLAG_VALUE is 1. */
3504 if (is_a <scalar_int_mode> (mode, &int_mode)
3505 && STORE_FLAG_VALUE == 1
3506 && trueop1 == const1_rtx
3507 && GET_CODE (op0) == LSHIFTRT
3508 && CONST_INT_P (XEXP (op0, 1))
3509 && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3510 return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3512 /* (xor (comparison foo bar) (const_int sign-bit))
3513 when STORE_FLAG_VALUE is the sign bit. */
3514 if (is_a <scalar_int_mode> (mode, &int_mode)
3515 && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3516 && trueop1 == const_true_rtx
3517 && COMPARISON_P (op0)
3518 && (reversed = reversed_comparison (op0, int_mode)))
3519 return reversed;
3521 /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3522 if (GET_CODE (op0) == GET_CODE (op1)
3523 && (GET_CODE (op0) == AND
3524 || GET_CODE (op0) == LSHIFTRT
3525 || GET_CODE (op0) == ASHIFTRT
3526 || GET_CODE (op0) == ASHIFT
3527 || GET_CODE (op0) == ROTATE
3528 || GET_CODE (op0) == ROTATERT))
3530 tem = simplify_distributive_operation (code, mode, op0, op1);
3531 if (tem)
3532 return tem;
3535 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3536 if (tem)
3537 return tem;
3539 tem = simplify_associative_operation (code, mode, op0, op1);
3540 if (tem)
3541 return tem;
3542 break;
3544 case AND:
3545 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3546 return trueop1;
3547 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3548 return op0;
3549 if (HWI_COMPUTABLE_MODE_P (mode))
3551 HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
3552 HOST_WIDE_INT nzop1;
3553 if (CONST_INT_P (trueop1))
3555 HOST_WIDE_INT val1 = INTVAL (trueop1);
3556 /* If we are turning off bits already known off in OP0, we need
3557 not do an AND. */
3558 if ((nzop0 & ~val1) == 0)
3559 return op0;
3561 nzop1 = nonzero_bits (trueop1, mode);
3562 /* If we are clearing all the nonzero bits, the result is zero. */
3563 if ((nzop1 & nzop0) == 0
3564 && !side_effects_p (op0) && !side_effects_p (op1))
3565 return CONST0_RTX (mode);
3567 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3568 && GET_MODE_CLASS (mode) != MODE_CC)
3569 return op0;
3570 /* A & (~A) -> 0 */
3571 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3572 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3573 && ! side_effects_p (op0)
3574 && GET_MODE_CLASS (mode) != MODE_CC)
3575 return CONST0_RTX (mode);
3577 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3578 there are no nonzero bits of C outside of X's mode. */
3579 if ((GET_CODE (op0) == SIGN_EXTEND
3580 || GET_CODE (op0) == ZERO_EXTEND)
3581 && CONST_INT_P (trueop1)
3582 && HWI_COMPUTABLE_MODE_P (mode)
3583 && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
3584 & UINTVAL (trueop1)) == 0)
3586 machine_mode imode = GET_MODE (XEXP (op0, 0));
3587 tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
3588 gen_int_mode (INTVAL (trueop1),
3589 imode));
3590 return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3593 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3594 we might be able to further simplify the AND with X and potentially
3595 remove the truncation altogether. */
3596 if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3598 rtx x = XEXP (op0, 0);
3599 machine_mode xmode = GET_MODE (x);
3600 tem = simplify_gen_binary (AND, xmode, x,
3601 gen_int_mode (INTVAL (trueop1), xmode));
3602 return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3605 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3606 if (GET_CODE (op0) == IOR
3607 && CONST_INT_P (trueop1)
3608 && CONST_INT_P (XEXP (op0, 1)))
3610 HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3611 return simplify_gen_binary (IOR, mode,
3612 simplify_gen_binary (AND, mode,
3613 XEXP (op0, 0), op1),
3614 gen_int_mode (tmp, mode));
3617 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3618 insn (and may simplify more). */
3619 if (GET_CODE (op0) == XOR
3620 && rtx_equal_p (XEXP (op0, 0), op1)
3621 && ! side_effects_p (op1))
3622 return simplify_gen_binary (AND, mode,
3623 simplify_gen_unary (NOT, mode,
3624 XEXP (op0, 1), mode),
3625 op1);
3627 if (GET_CODE (op0) == XOR
3628 && rtx_equal_p (XEXP (op0, 1), op1)
3629 && ! side_effects_p (op1))
3630 return simplify_gen_binary (AND, mode,
3631 simplify_gen_unary (NOT, mode,
3632 XEXP (op0, 0), mode),
3633 op1);
3635 /* Similarly for (~(A ^ B)) & A. */
3636 if (GET_CODE (op0) == NOT
3637 && GET_CODE (XEXP (op0, 0)) == XOR
3638 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3639 && ! side_effects_p (op1))
3640 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3642 if (GET_CODE (op0) == NOT
3643 && GET_CODE (XEXP (op0, 0)) == XOR
3644 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3645 && ! side_effects_p (op1))
3646 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3648 /* Convert (A | B) & A to A. */
3649 if (GET_CODE (op0) == IOR
3650 && (rtx_equal_p (XEXP (op0, 0), op1)
3651 || rtx_equal_p (XEXP (op0, 1), op1))
3652 && ! side_effects_p (XEXP (op0, 0))
3653 && ! side_effects_p (XEXP (op0, 1)))
3654 return op1;
3656 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3657 ((A & N) + B) & M -> (A + B) & M
3658 Similarly if (N & M) == 0,
3659 ((A | N) + B) & M -> (A + B) & M
3660 and for - instead of + and/or ^ instead of |.
3661 Also, if (N & M) == 0, then
3662 (A +- N) & M -> A & M. */
3663 if (CONST_INT_P (trueop1)
3664 && HWI_COMPUTABLE_MODE_P (mode)
3665 && ~UINTVAL (trueop1)
3666 && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3667 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3669 rtx pmop[2];
3670 int which;
3672 pmop[0] = XEXP (op0, 0);
3673 pmop[1] = XEXP (op0, 1);
3675 if (CONST_INT_P (pmop[1])
3676 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3677 return simplify_gen_binary (AND, mode, pmop[0], op1);
3679 for (which = 0; which < 2; which++)
3681 tem = pmop[which];
3682 switch (GET_CODE (tem))
3684 case AND:
3685 if (CONST_INT_P (XEXP (tem, 1))
3686 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3687 == UINTVAL (trueop1))
3688 pmop[which] = XEXP (tem, 0);
3689 break;
3690 case IOR:
3691 case XOR:
3692 if (CONST_INT_P (XEXP (tem, 1))
3693 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3694 pmop[which] = XEXP (tem, 0);
3695 break;
3696 default:
3697 break;
3701 if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3703 tem = simplify_gen_binary (GET_CODE (op0), mode,
3704 pmop[0], pmop[1]);
3705 return simplify_gen_binary (code, mode, tem, op1);
3709 /* (and X (ior (not X) Y) -> (and X Y) */
3710 if (GET_CODE (op1) == IOR
3711 && GET_CODE (XEXP (op1, 0)) == NOT
3712 && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3713 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3715 /* (and (ior (not X) Y) X) -> (and X Y) */
3716 if (GET_CODE (op0) == IOR
3717 && GET_CODE (XEXP (op0, 0)) == NOT
3718 && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3719 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3721 /* (and X (ior Y (not X)) -> (and X Y) */
3722 if (GET_CODE (op1) == IOR
3723 && GET_CODE (XEXP (op1, 1)) == NOT
3724 && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3725 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3727 /* (and (ior Y (not X)) X) -> (and X Y) */
3728 if (GET_CODE (op0) == IOR
3729 && GET_CODE (XEXP (op0, 1)) == NOT
3730 && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3731 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3733 /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
3734 if (GET_CODE (op0) == GET_CODE (op1)
3735 && (GET_CODE (op0) == AND
3736 || GET_CODE (op0) == IOR
3737 || GET_CODE (op0) == LSHIFTRT
3738 || GET_CODE (op0) == ASHIFTRT
3739 || GET_CODE (op0) == ASHIFT
3740 || GET_CODE (op0) == ROTATE
3741 || GET_CODE (op0) == ROTATERT))
3743 tem = simplify_distributive_operation (code, mode, op0, op1);
3744 if (tem)
3745 return tem;
3748 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3749 if (tem)
3750 return tem;
3752 tem = simplify_associative_operation (code, mode, op0, op1);
3753 if (tem)
3754 return tem;
3755 break;
3757 case UDIV:
3758 /* 0/x is 0 (or x&0 if x has side-effects). */
3759 if (trueop0 == CONST0_RTX (mode)
3760 && !cfun->can_throw_non_call_exceptions)
3762 if (side_effects_p (op1))
3763 return simplify_gen_binary (AND, mode, op1, trueop0);
3764 return trueop0;
3766 /* x/1 is x. */
3767 if (trueop1 == CONST1_RTX (mode))
3769 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3770 if (tem)
3771 return tem;
3773 /* Convert divide by power of two into shift. */
3774 if (CONST_INT_P (trueop1)
3775 && (val = exact_log2 (UINTVAL (trueop1))) > 0)
3776 return simplify_gen_binary (LSHIFTRT, mode, op0,
3777 gen_int_shift_amount (mode, val));
3778 break;
3780 case DIV:
3781 /* Handle floating point and integers separately. */
3782 if (SCALAR_FLOAT_MODE_P (mode))
3784 /* Maybe change 0.0 / x to 0.0. This transformation isn't
3785 safe for modes with NaNs, since 0.0 / 0.0 will then be
3786 NaN rather than 0.0. Nor is it safe for modes with signed
3787 zeros, since dividing 0 by a negative number gives -0.0 */
3788 if (trueop0 == CONST0_RTX (mode)
3789 && !HONOR_NANS (mode)
3790 && !HONOR_SIGNED_ZEROS (mode)
3791 && ! side_effects_p (op1))
3792 return op0;
3793 /* x/1.0 is x. */
3794 if (trueop1 == CONST1_RTX (mode)
3795 && !HONOR_SNANS (mode))
3796 return op0;
3798 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3799 && trueop1 != CONST0_RTX (mode))
3801 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3803 /* x/-1.0 is -x. */
3804 if (real_equal (d1, &dconstm1)
3805 && !HONOR_SNANS (mode))
3806 return simplify_gen_unary (NEG, mode, op0, mode);
3808 /* Change FP division by a constant into multiplication.
3809 Only do this with -freciprocal-math. */
3810 if (flag_reciprocal_math
3811 && !real_equal (d1, &dconst0))
3813 REAL_VALUE_TYPE d;
3814 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
3815 tem = const_double_from_real_value (d, mode);
3816 return simplify_gen_binary (MULT, mode, op0, tem);
3820 else if (SCALAR_INT_MODE_P (mode))
3822 /* 0/x is 0 (or x&0 if x has side-effects). */
3823 if (trueop0 == CONST0_RTX (mode)
3824 && !cfun->can_throw_non_call_exceptions)
3826 if (side_effects_p (op1))
3827 return simplify_gen_binary (AND, mode, op1, trueop0);
3828 return trueop0;
3830 /* x/1 is x. */
3831 if (trueop1 == CONST1_RTX (mode))
3833 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3834 if (tem)
3835 return tem;
3837 /* x/-1 is -x. */
3838 if (trueop1 == constm1_rtx)
3840 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3841 if (x)
3842 return simplify_gen_unary (NEG, mode, x, mode);
3845 break;
3847 case UMOD:
3848 /* 0%x is 0 (or x&0 if x has side-effects). */
3849 if (trueop0 == CONST0_RTX (mode))
3851 if (side_effects_p (op1))
3852 return simplify_gen_binary (AND, mode, op1, trueop0);
3853 return trueop0;
3855 /* x%1 is 0 (of x&0 if x has side-effects). */
3856 if (trueop1 == CONST1_RTX (mode))
3858 if (side_effects_p (op0))
3859 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3860 return CONST0_RTX (mode);
3862 /* Implement modulus by power of two as AND. */
3863 if (CONST_INT_P (trueop1)
3864 && exact_log2 (UINTVAL (trueop1)) > 0)
3865 return simplify_gen_binary (AND, mode, op0,
3866 gen_int_mode (UINTVAL (trueop1) - 1,
3867 mode));
3868 break;
3870 case MOD:
3871 /* 0%x is 0 (or x&0 if x has side-effects). */
3872 if (trueop0 == CONST0_RTX (mode))
3874 if (side_effects_p (op1))
3875 return simplify_gen_binary (AND, mode, op1, trueop0);
3876 return trueop0;
3878 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
3879 if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
3881 if (side_effects_p (op0))
3882 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3883 return CONST0_RTX (mode);
3885 break;
3887 case ROTATERT:
3888 case ROTATE:
3889 if (trueop1 == CONST0_RTX (mode))
3890 return op0;
3891 /* Canonicalize rotates by constant amount. If op1 is bitsize / 2,
3892 prefer left rotation, if op1 is from bitsize / 2 + 1 to
3893 bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
3894 amount instead. */
3895 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
3896 if (CONST_INT_P (trueop1)
3897 && IN_RANGE (INTVAL (trueop1),
3898 GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
3899 GET_MODE_UNIT_PRECISION (mode) - 1))
3901 int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
3902 rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
3903 return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
3904 mode, op0, new_amount_rtx);
3906 #endif
3907 /* FALLTHRU */
3908 case ASHIFTRT:
3909 if (trueop1 == CONST0_RTX (mode))
3910 return op0;
3911 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3912 return op0;
3913 /* Rotating ~0 always results in ~0. */
3914 if (CONST_INT_P (trueop0)
3915 && HWI_COMPUTABLE_MODE_P (mode)
3916 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
3917 && ! side_effects_p (op1))
3918 return op0;
3920 canonicalize_shift:
3921 /* Given:
3922 scalar modes M1, M2
3923 scalar constants c1, c2
3924 size (M2) > size (M1)
3925 c1 == size (M2) - size (M1)
3926 optimize:
3927 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
3928 <low_part>)
3929 (const_int <c2>))
3931 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
3932 <low_part>). */
3933 if ((code == ASHIFTRT || code == LSHIFTRT)
3934 && is_a <scalar_int_mode> (mode, &int_mode)
3935 && SUBREG_P (op0)
3936 && CONST_INT_P (op1)
3937 && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
3938 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
3939 &inner_mode)
3940 && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
3941 && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
3942 && (INTVAL (XEXP (SUBREG_REG (op0), 1))
3943 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
3944 && subreg_lowpart_p (op0))
3946 rtx tmp = gen_int_shift_amount
3947 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
3949 /* Combine would usually zero out the value when combining two
3950 local shifts and the range becomes larger or equal to the mode.
3951 However since we fold away one of the shifts here combine won't
3952 see it so we should immediately zero the result if it's out of
3953 range. */
3954 if (code == LSHIFTRT
3955 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
3956 tmp = const0_rtx;
3957 else
3958 tmp = simplify_gen_binary (code,
3959 inner_mode,
3960 XEXP (SUBREG_REG (op0), 0),
3961 tmp);
3963 return lowpart_subreg (int_mode, tmp, inner_mode);
3966 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
3968 val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
3969 if (val != INTVAL (op1))
3970 return simplify_gen_binary (code, mode, op0,
3971 gen_int_shift_amount (mode, val));
3973 break;
3975 case ASHIFT:
3976 case SS_ASHIFT:
3977 case US_ASHIFT:
3978 if (trueop1 == CONST0_RTX (mode))
3979 return op0;
3980 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3981 return op0;
3982 if (mem_depth
3983 && code == ASHIFT
3984 && CONST_INT_P (trueop1)
3985 && is_a <scalar_int_mode> (mode, &int_mode)
3986 && IN_RANGE (UINTVAL (trueop1),
3987 1, GET_MODE_PRECISION (int_mode) - 1))
3989 auto c = (wi::one (GET_MODE_PRECISION (int_mode))
3990 << UINTVAL (trueop1));
3991 rtx new_op1 = immed_wide_int_const (c, int_mode);
3992 return simplify_gen_binary (MULT, int_mode, op0, new_op1);
3994 goto canonicalize_shift;
3996 case LSHIFTRT:
3997 if (trueop1 == CONST0_RTX (mode))
3998 return op0;
3999 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4000 return op0;
4001 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4002 if (GET_CODE (op0) == CLZ
4003 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4004 && CONST_INT_P (trueop1)
4005 && STORE_FLAG_VALUE == 1
4006 && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4008 unsigned HOST_WIDE_INT zero_val = 0;
4010 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4011 && zero_val == GET_MODE_PRECISION (inner_mode)
4012 && INTVAL (trueop1) == exact_log2 (zero_val))
4013 return simplify_gen_relational (EQ, mode, inner_mode,
4014 XEXP (op0, 0), const0_rtx);
4016 goto canonicalize_shift;
4018 case SMIN:
4019 if (HWI_COMPUTABLE_MODE_P (mode)
4020 && mode_signbit_p (mode, trueop1)
4021 && ! side_effects_p (op0))
4022 return op1;
4023 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4024 return op0;
4025 tem = simplify_associative_operation (code, mode, op0, op1);
4026 if (tem)
4027 return tem;
4028 break;
4030 case SMAX:
4031 if (HWI_COMPUTABLE_MODE_P (mode)
4032 && CONST_INT_P (trueop1)
4033 && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4034 && ! side_effects_p (op0))
4035 return op1;
4036 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4037 return op0;
4038 tem = simplify_associative_operation (code, mode, op0, op1);
4039 if (tem)
4040 return tem;
4041 break;
4043 case UMIN:
4044 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4045 return op1;
4046 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4047 return op0;
4048 tem = simplify_associative_operation (code, mode, op0, op1);
4049 if (tem)
4050 return tem;
4051 break;
4053 case UMAX:
4054 if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4055 return op1;
4056 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4057 return op0;
4058 tem = simplify_associative_operation (code, mode, op0, op1);
4059 if (tem)
4060 return tem;
4061 break;
4063 case SS_PLUS:
4064 case US_PLUS:
4065 case SS_MINUS:
4066 case US_MINUS:
4067 case SS_MULT:
4068 case US_MULT:
4069 case SS_DIV:
4070 case US_DIV:
4071 /* ??? There are simplifications that can be done. */
4072 return 0;
4074 case VEC_SERIES:
4075 if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4076 return gen_vec_duplicate (mode, op0);
4077 if (valid_for_const_vector_p (mode, op0)
4078 && valid_for_const_vector_p (mode, op1))
4079 return gen_const_vec_series (mode, op0, op1);
4080 return 0;
4082 case VEC_SELECT:
4083 if (!VECTOR_MODE_P (mode))
4085 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4086 gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4087 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4088 gcc_assert (XVECLEN (trueop1, 0) == 1);
4090 /* We can't reason about selections made at runtime. */
4091 if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4092 return 0;
4094 if (vec_duplicate_p (trueop0, &elt0))
4095 return elt0;
4097 if (GET_CODE (trueop0) == CONST_VECTOR)
4098 return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4099 (trueop1, 0, 0)));
4101 /* Extract a scalar element from a nested VEC_SELECT expression
4102 (with optional nested VEC_CONCAT expression). Some targets
4103 (i386) extract scalar element from a vector using chain of
4104 nested VEC_SELECT expressions. When input operand is a memory
4105 operand, this operation can be simplified to a simple scalar
4106 load from an offseted memory address. */
4107 int n_elts;
4108 if (GET_CODE (trueop0) == VEC_SELECT
4109 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4110 .is_constant (&n_elts)))
4112 rtx op0 = XEXP (trueop0, 0);
4113 rtx op1 = XEXP (trueop0, 1);
4115 int i = INTVAL (XVECEXP (trueop1, 0, 0));
4116 int elem;
4118 rtvec vec;
4119 rtx tmp_op, tmp;
4121 gcc_assert (GET_CODE (op1) == PARALLEL);
4122 gcc_assert (i < n_elts);
4124 /* Select element, pointed by nested selector. */
4125 elem = INTVAL (XVECEXP (op1, 0, i));
4127 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4128 if (GET_CODE (op0) == VEC_CONCAT)
4130 rtx op00 = XEXP (op0, 0);
4131 rtx op01 = XEXP (op0, 1);
4133 machine_mode mode00, mode01;
4134 int n_elts00, n_elts01;
4136 mode00 = GET_MODE (op00);
4137 mode01 = GET_MODE (op01);
4139 /* Find out the number of elements of each operand.
4140 Since the concatenated result has a constant number
4141 of elements, the operands must too. */
4142 n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4143 n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4145 gcc_assert (n_elts == n_elts00 + n_elts01);
4147 /* Select correct operand of VEC_CONCAT
4148 and adjust selector. */
4149 if (elem < n_elts01)
4150 tmp_op = op00;
4151 else
4153 tmp_op = op01;
4154 elem -= n_elts00;
4157 else
4158 tmp_op = op0;
4160 vec = rtvec_alloc (1);
4161 RTVEC_ELT (vec, 0) = GEN_INT (elem);
4163 tmp = gen_rtx_fmt_ee (code, mode,
4164 tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
4165 return tmp;
4168 else
4170 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4171 gcc_assert (GET_MODE_INNER (mode)
4172 == GET_MODE_INNER (GET_MODE (trueop0)));
4173 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4175 if (vec_duplicate_p (trueop0, &elt0))
4176 /* It doesn't matter which elements are selected by trueop1,
4177 because they are all the same. */
4178 return gen_vec_duplicate (mode, elt0);
4180 if (GET_CODE (trueop0) == CONST_VECTOR)
4182 unsigned n_elts = XVECLEN (trueop1, 0);
4183 rtvec v = rtvec_alloc (n_elts);
4184 unsigned int i;
4186 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4187 for (i = 0; i < n_elts; i++)
4189 rtx x = XVECEXP (trueop1, 0, i);
4191 if (!CONST_INT_P (x))
4192 return 0;
4194 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
4195 INTVAL (x));
4198 return gen_rtx_CONST_VECTOR (mode, v);
4201 /* Recognize the identity. */
4202 if (GET_MODE (trueop0) == mode)
4204 bool maybe_ident = true;
4205 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4207 rtx j = XVECEXP (trueop1, 0, i);
4208 if (!CONST_INT_P (j) || INTVAL (j) != i)
4210 maybe_ident = false;
4211 break;
4214 if (maybe_ident)
4215 return trueop0;
4218 /* If we select a low-part subreg, return that. */
4219 if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
4221 rtx new_rtx = lowpart_subreg (mode, trueop0,
4222 GET_MODE (trueop0));
4223 if (new_rtx != NULL_RTX)
4224 return new_rtx;
4227 /* If we build {a,b} then permute it, build the result directly. */
4228 if (XVECLEN (trueop1, 0) == 2
4229 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4230 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4231 && GET_CODE (trueop0) == VEC_CONCAT
4232 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4233 && GET_MODE (XEXP (trueop0, 0)) == mode
4234 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4235 && GET_MODE (XEXP (trueop0, 1)) == mode)
4237 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4238 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4239 rtx subop0, subop1;
4241 gcc_assert (i0 < 4 && i1 < 4);
4242 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4243 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4245 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4248 if (XVECLEN (trueop1, 0) == 2
4249 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4250 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4251 && GET_CODE (trueop0) == VEC_CONCAT
4252 && GET_MODE (trueop0) == mode)
4254 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4255 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4256 rtx subop0, subop1;
4258 gcc_assert (i0 < 2 && i1 < 2);
4259 subop0 = XEXP (trueop0, i0);
4260 subop1 = XEXP (trueop0, i1);
4262 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4265 /* If we select one half of a vec_concat, return that. */
4266 int l0, l1;
4267 if (GET_CODE (trueop0) == VEC_CONCAT
4268 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4269 .is_constant (&l0))
4270 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4271 .is_constant (&l1))
4272 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4274 rtx subop0 = XEXP (trueop0, 0);
4275 rtx subop1 = XEXP (trueop0, 1);
4276 machine_mode mode0 = GET_MODE (subop0);
4277 machine_mode mode1 = GET_MODE (subop1);
4278 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4279 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4281 bool success = true;
4282 for (int i = 1; i < l0; ++i)
4284 rtx j = XVECEXP (trueop1, 0, i);
4285 if (!CONST_INT_P (j) || INTVAL (j) != i)
4287 success = false;
4288 break;
4291 if (success)
4292 return subop0;
4294 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4296 bool success = true;
4297 for (int i = 1; i < l1; ++i)
4299 rtx j = XVECEXP (trueop1, 0, i);
4300 if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4302 success = false;
4303 break;
4306 if (success)
4307 return subop1;
4311 /* Simplify vec_select of a subreg of X to just a vec_select of X
4312 when X has same component mode as vec_select. */
4313 unsigned HOST_WIDE_INT subreg_offset = 0;
4314 if (GET_CODE (trueop0) == SUBREG
4315 && GET_MODE_INNER (mode)
4316 == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
4317 && GET_MODE_NUNITS (mode).is_constant (&l1)
4318 && constant_multiple_p (subreg_memory_offset (trueop0),
4319 GET_MODE_UNIT_BITSIZE (mode),
4320 &subreg_offset))
4322 poly_uint64 nunits
4323 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
4324 bool success = true;
4325 for (int i = 0; i != l1; i++)
4327 rtx idx = XVECEXP (trueop1, 0, i);
4328 if (!CONST_INT_P (idx)
4329 || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
4331 success = false;
4332 break;
4336 if (success)
4338 rtx par = trueop1;
4339 if (subreg_offset)
4341 rtvec vec = rtvec_alloc (l1);
4342 for (int i = 0; i < l1; i++)
4343 RTVEC_ELT (vec, i)
4344 = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
4345 + subreg_offset);
4346 par = gen_rtx_PARALLEL (VOIDmode, vec);
4348 return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
4353 if (XVECLEN (trueop1, 0) == 1
4354 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4355 && GET_CODE (trueop0) == VEC_CONCAT)
4357 rtx vec = trueop0;
4358 offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4360 /* Try to find the element in the VEC_CONCAT. */
4361 while (GET_MODE (vec) != mode
4362 && GET_CODE (vec) == VEC_CONCAT)
4364 poly_int64 vec_size;
4366 if (CONST_INT_P (XEXP (vec, 0)))
4368 /* vec_concat of two const_ints doesn't make sense with
4369 respect to modes. */
4370 if (CONST_INT_P (XEXP (vec, 1)))
4371 return 0;
4373 vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4374 - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4376 else
4377 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4379 if (known_lt (offset, vec_size))
4380 vec = XEXP (vec, 0);
4381 else if (known_ge (offset, vec_size))
4383 offset -= vec_size;
4384 vec = XEXP (vec, 1);
4386 else
4387 break;
4388 vec = avoid_constant_pool_reference (vec);
4391 if (GET_MODE (vec) == mode)
4392 return vec;
4395 /* If we select elements in a vec_merge that all come from the same
4396 operand, select from that operand directly. */
4397 if (GET_CODE (op0) == VEC_MERGE)
4399 rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4400 if (CONST_INT_P (trueop02))
4402 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4403 bool all_operand0 = true;
4404 bool all_operand1 = true;
4405 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4407 rtx j = XVECEXP (trueop1, 0, i);
4408 if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4409 all_operand1 = false;
4410 else
4411 all_operand0 = false;
4413 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4414 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4415 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4416 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4420 /* If we have two nested selects that are inverses of each
4421 other, replace them with the source operand. */
4422 if (GET_CODE (trueop0) == VEC_SELECT
4423 && GET_MODE (XEXP (trueop0, 0)) == mode)
4425 rtx op0_subop1 = XEXP (trueop0, 1);
4426 gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4427 gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4429 /* Apply the outer ordering vector to the inner one. (The inner
4430 ordering vector is expressly permitted to be of a different
4431 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4432 then the two VEC_SELECTs cancel. */
4433 for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4435 rtx x = XVECEXP (trueop1, 0, i);
4436 if (!CONST_INT_P (x))
4437 return 0;
4438 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4439 if (!CONST_INT_P (y) || i != INTVAL (y))
4440 return 0;
4442 return XEXP (trueop0, 0);
4445 return 0;
4446 case VEC_CONCAT:
4448 machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4449 ? GET_MODE (trueop0)
4450 : GET_MODE_INNER (mode));
4451 machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4452 ? GET_MODE (trueop1)
4453 : GET_MODE_INNER (mode));
4455 gcc_assert (VECTOR_MODE_P (mode));
4456 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4457 + GET_MODE_SIZE (op1_mode),
4458 GET_MODE_SIZE (mode)));
4460 if (VECTOR_MODE_P (op0_mode))
4461 gcc_assert (GET_MODE_INNER (mode)
4462 == GET_MODE_INNER (op0_mode));
4463 else
4464 gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4466 if (VECTOR_MODE_P (op1_mode))
4467 gcc_assert (GET_MODE_INNER (mode)
4468 == GET_MODE_INNER (op1_mode));
4469 else
4470 gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4472 unsigned int n_elts, in_n_elts;
4473 if ((GET_CODE (trueop0) == CONST_VECTOR
4474 || CONST_SCALAR_INT_P (trueop0)
4475 || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4476 && (GET_CODE (trueop1) == CONST_VECTOR
4477 || CONST_SCALAR_INT_P (trueop1)
4478 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4479 && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4480 && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4482 rtvec v = rtvec_alloc (n_elts);
4483 unsigned int i;
4484 for (i = 0; i < n_elts; i++)
4486 if (i < in_n_elts)
4488 if (!VECTOR_MODE_P (op0_mode))
4489 RTVEC_ELT (v, i) = trueop0;
4490 else
4491 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4493 else
4495 if (!VECTOR_MODE_P (op1_mode))
4496 RTVEC_ELT (v, i) = trueop1;
4497 else
4498 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4499 i - in_n_elts);
4503 return gen_rtx_CONST_VECTOR (mode, v);
4506 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4507 Restrict the transformation to avoid generating a VEC_SELECT with a
4508 mode unrelated to its operand. */
4509 if (GET_CODE (trueop0) == VEC_SELECT
4510 && GET_CODE (trueop1) == VEC_SELECT
4511 && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4512 && GET_MODE (XEXP (trueop0, 0)) == mode)
4514 rtx par0 = XEXP (trueop0, 1);
4515 rtx par1 = XEXP (trueop1, 1);
4516 int len0 = XVECLEN (par0, 0);
4517 int len1 = XVECLEN (par1, 0);
4518 rtvec vec = rtvec_alloc (len0 + len1);
4519 for (int i = 0; i < len0; i++)
4520 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4521 for (int i = 0; i < len1; i++)
4522 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4523 return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4524 gen_rtx_PARALLEL (VOIDmode, vec));
4527 return 0;
4529 default:
4530 gcc_unreachable ();
4533 if (mode == GET_MODE (op0)
4534 && mode == GET_MODE (op1)
4535 && vec_duplicate_p (op0, &elt0)
4536 && vec_duplicate_p (op1, &elt1))
4538 /* Try applying the operator to ELT and see if that simplifies.
4539 We can duplicate the result if so.
4541 The reason we don't use simplify_gen_binary is that it isn't
4542 necessarily a win to convert things like:
4544 (plus:V (vec_duplicate:V (reg:S R1))
4545 (vec_duplicate:V (reg:S R2)))
4549 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4551 The first might be done entirely in vector registers while the
4552 second might need a move between register files. */
4553 tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4554 elt0, elt1);
4555 if (tem)
4556 return gen_vec_duplicate (mode, tem);
4559 return 0;
4562 /* Return true if binary operation OP distributes over addition in operand
4563 OPNO, with the other operand being held constant. OPNO counts from 1. */
4565 static bool
4566 distributes_over_addition_p (rtx_code op, int opno)
4568 switch (op)
4570 case PLUS:
4571 case MINUS:
4572 case MULT:
4573 return true;
4575 case ASHIFT:
4576 return opno == 1;
4578 default:
4579 return false;
4584 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4585 rtx op0, rtx op1)
4587 if (VECTOR_MODE_P (mode)
4588 && code != VEC_CONCAT
4589 && GET_CODE (op0) == CONST_VECTOR
4590 && GET_CODE (op1) == CONST_VECTOR)
4592 bool step_ok_p;
4593 if (CONST_VECTOR_STEPPED_P (op0)
4594 && CONST_VECTOR_STEPPED_P (op1))
4595 /* We can operate directly on the encoding if:
4597 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4598 implies
4599 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4601 Addition and subtraction are the supported operators
4602 for which this is true. */
4603 step_ok_p = (code == PLUS || code == MINUS);
4604 else if (CONST_VECTOR_STEPPED_P (op0))
4605 /* We can operate directly on stepped encodings if:
4607 a3 - a2 == a2 - a1
4608 implies:
4609 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4611 which is true if (x -> x op c) distributes over addition. */
4612 step_ok_p = distributes_over_addition_p (code, 1);
4613 else
4614 /* Similarly in reverse. */
4615 step_ok_p = distributes_over_addition_p (code, 2);
4616 rtx_vector_builder builder;
4617 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4618 return 0;
4620 unsigned int count = builder.encoded_nelts ();
4621 for (unsigned int i = 0; i < count; i++)
4623 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4624 CONST_VECTOR_ELT (op0, i),
4625 CONST_VECTOR_ELT (op1, i));
4626 if (!x || !valid_for_const_vector_p (mode, x))
4627 return 0;
4628 builder.quick_push (x);
4630 return builder.build ();
4633 if (VECTOR_MODE_P (mode)
4634 && code == VEC_CONCAT
4635 && (CONST_SCALAR_INT_P (op0)
4636 || CONST_FIXED_P (op0)
4637 || CONST_DOUBLE_AS_FLOAT_P (op0))
4638 && (CONST_SCALAR_INT_P (op1)
4639 || CONST_DOUBLE_AS_FLOAT_P (op1)
4640 || CONST_FIXED_P (op1)))
4642 /* Both inputs have a constant number of elements, so the result
4643 must too. */
4644 unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4645 rtvec v = rtvec_alloc (n_elts);
4647 gcc_assert (n_elts >= 2);
4648 if (n_elts == 2)
4650 gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4651 gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4653 RTVEC_ELT (v, 0) = op0;
4654 RTVEC_ELT (v, 1) = op1;
4656 else
4658 unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4659 unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4660 unsigned i;
4662 gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4663 gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4664 gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4666 for (i = 0; i < op0_n_elts; ++i)
4667 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4668 for (i = 0; i < op1_n_elts; ++i)
4669 RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4672 return gen_rtx_CONST_VECTOR (mode, v);
4675 if (SCALAR_FLOAT_MODE_P (mode)
4676 && CONST_DOUBLE_AS_FLOAT_P (op0)
4677 && CONST_DOUBLE_AS_FLOAT_P (op1)
4678 && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4680 if (code == AND
4681 || code == IOR
4682 || code == XOR)
4684 long tmp0[4];
4685 long tmp1[4];
4686 REAL_VALUE_TYPE r;
4687 int i;
4689 real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4690 GET_MODE (op0));
4691 real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4692 GET_MODE (op1));
4693 for (i = 0; i < 4; i++)
4695 switch (code)
4697 case AND:
4698 tmp0[i] &= tmp1[i];
4699 break;
4700 case IOR:
4701 tmp0[i] |= tmp1[i];
4702 break;
4703 case XOR:
4704 tmp0[i] ^= tmp1[i];
4705 break;
4706 default:
4707 gcc_unreachable ();
4710 real_from_target (&r, tmp0, mode);
4711 return const_double_from_real_value (r, mode);
4713 else
4715 REAL_VALUE_TYPE f0, f1, value, result;
4716 const REAL_VALUE_TYPE *opr0, *opr1;
4717 bool inexact;
4719 opr0 = CONST_DOUBLE_REAL_VALUE (op0);
4720 opr1 = CONST_DOUBLE_REAL_VALUE (op1);
4722 if (HONOR_SNANS (mode)
4723 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
4724 || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
4725 return 0;
4727 real_convert (&f0, mode, opr0);
4728 real_convert (&f1, mode, opr1);
4730 if (code == DIV
4731 && real_equal (&f1, &dconst0)
4732 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
4733 return 0;
4735 if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4736 && flag_trapping_math
4737 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
4739 int s0 = REAL_VALUE_NEGATIVE (f0);
4740 int s1 = REAL_VALUE_NEGATIVE (f1);
4742 switch (code)
4744 case PLUS:
4745 /* Inf + -Inf = NaN plus exception. */
4746 if (s0 != s1)
4747 return 0;
4748 break;
4749 case MINUS:
4750 /* Inf - Inf = NaN plus exception. */
4751 if (s0 == s1)
4752 return 0;
4753 break;
4754 case DIV:
4755 /* Inf / Inf = NaN plus exception. */
4756 return 0;
4757 default:
4758 break;
4762 if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4763 && flag_trapping_math
4764 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
4765 || (REAL_VALUE_ISINF (f1)
4766 && real_equal (&f0, &dconst0))))
4767 /* Inf * 0 = NaN plus exception. */
4768 return 0;
4770 inexact = real_arithmetic (&value, rtx_to_tree_code (code),
4771 &f0, &f1);
4772 real_convert (&result, mode, &value);
4774 /* Don't constant fold this floating point operation if
4775 the result has overflowed and flag_trapping_math. */
4777 if (flag_trapping_math
4778 && MODE_HAS_INFINITIES (mode)
4779 && REAL_VALUE_ISINF (result)
4780 && !REAL_VALUE_ISINF (f0)
4781 && !REAL_VALUE_ISINF (f1))
4782 /* Overflow plus exception. */
4783 return 0;
4785 /* Don't constant fold this floating point operation if the
4786 result may dependent upon the run-time rounding mode and
4787 flag_rounding_math is set, or if GCC's software emulation
4788 is unable to accurately represent the result. */
4790 if ((flag_rounding_math
4791 || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
4792 && (inexact || !real_identical (&result, &value)))
4793 return NULL_RTX;
4795 return const_double_from_real_value (result, mode);
4799 /* We can fold some multi-word operations. */
4800 scalar_int_mode int_mode;
4801 if (is_a <scalar_int_mode> (mode, &int_mode)
4802 && CONST_SCALAR_INT_P (op0)
4803 && CONST_SCALAR_INT_P (op1)
4804 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
4806 wide_int result;
4807 wi::overflow_type overflow;
4808 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
4809 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
4811 #if TARGET_SUPPORTS_WIDE_INT == 0
4812 /* This assert keeps the simplification from producing a result
4813 that cannot be represented in a CONST_DOUBLE but a lot of
4814 upstream callers expect that this function never fails to
4815 simplify something and so you if you added this to the test
4816 above the code would die later anyway. If this assert
4817 happens, you just need to make the port support wide int. */
4818 gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
4819 #endif
4820 switch (code)
4822 case MINUS:
4823 result = wi::sub (pop0, pop1);
4824 break;
4826 case PLUS:
4827 result = wi::add (pop0, pop1);
4828 break;
4830 case MULT:
4831 result = wi::mul (pop0, pop1);
4832 break;
4834 case DIV:
4835 result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
4836 if (overflow)
4837 return NULL_RTX;
4838 break;
4840 case MOD:
4841 result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
4842 if (overflow)
4843 return NULL_RTX;
4844 break;
4846 case UDIV:
4847 result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
4848 if (overflow)
4849 return NULL_RTX;
4850 break;
4852 case UMOD:
4853 result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
4854 if (overflow)
4855 return NULL_RTX;
4856 break;
4858 case AND:
4859 result = wi::bit_and (pop0, pop1);
4860 break;
4862 case IOR:
4863 result = wi::bit_or (pop0, pop1);
4864 break;
4866 case XOR:
4867 result = wi::bit_xor (pop0, pop1);
4868 break;
4870 case SMIN:
4871 result = wi::smin (pop0, pop1);
4872 break;
4874 case SMAX:
4875 result = wi::smax (pop0, pop1);
4876 break;
4878 case UMIN:
4879 result = wi::umin (pop0, pop1);
4880 break;
4882 case UMAX:
4883 result = wi::umax (pop0, pop1);
4884 break;
4886 case LSHIFTRT:
4887 case ASHIFTRT:
4888 case ASHIFT:
4890 wide_int wop1 = pop1;
4891 if (SHIFT_COUNT_TRUNCATED)
4892 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
4893 else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
4894 return NULL_RTX;
4896 switch (code)
4898 case LSHIFTRT:
4899 result = wi::lrshift (pop0, wop1);
4900 break;
4902 case ASHIFTRT:
4903 result = wi::arshift (pop0, wop1);
4904 break;
4906 case ASHIFT:
4907 result = wi::lshift (pop0, wop1);
4908 break;
4910 default:
4911 gcc_unreachable ();
4913 break;
4915 case ROTATE:
4916 case ROTATERT:
4918 if (wi::neg_p (pop1))
4919 return NULL_RTX;
4921 switch (code)
4923 case ROTATE:
4924 result = wi::lrotate (pop0, pop1);
4925 break;
4927 case ROTATERT:
4928 result = wi::rrotate (pop0, pop1);
4929 break;
4931 default:
4932 gcc_unreachable ();
4934 break;
4936 default:
4937 return NULL_RTX;
4939 return immed_wide_int_const (result, int_mode);
4942 /* Handle polynomial integers. */
4943 if (NUM_POLY_INT_COEFFS > 1
4944 && is_a <scalar_int_mode> (mode, &int_mode)
4945 && poly_int_rtx_p (op0)
4946 && poly_int_rtx_p (op1))
4948 poly_wide_int result;
4949 switch (code)
4951 case PLUS:
4952 result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
4953 break;
4955 case MINUS:
4956 result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
4957 break;
4959 case MULT:
4960 if (CONST_SCALAR_INT_P (op1))
4961 result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
4962 else
4963 return NULL_RTX;
4964 break;
4966 case ASHIFT:
4967 if (CONST_SCALAR_INT_P (op1))
4969 wide_int shift = rtx_mode_t (op1, mode);
4970 if (SHIFT_COUNT_TRUNCATED)
4971 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
4972 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
4973 return NULL_RTX;
4974 result = wi::to_poly_wide (op0, mode) << shift;
4976 else
4977 return NULL_RTX;
4978 break;
4980 case IOR:
4981 if (!CONST_SCALAR_INT_P (op1)
4982 || !can_ior_p (wi::to_poly_wide (op0, mode),
4983 rtx_mode_t (op1, mode), &result))
4984 return NULL_RTX;
4985 break;
4987 default:
4988 return NULL_RTX;
4990 return immed_wide_int_const (result, int_mode);
4993 return NULL_RTX;
4998 /* Return a positive integer if X should sort after Y. The value
4999 returned is 1 if and only if X and Y are both regs. */
5001 static int
5002 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
5004 int result;
5006 result = (commutative_operand_precedence (y)
5007 - commutative_operand_precedence (x));
5008 if (result)
5009 return result + result;
5011 /* Group together equal REGs to do more simplification. */
5012 if (REG_P (x) && REG_P (y))
5013 return REGNO (x) > REGNO (y);
5015 return 0;
5018 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5019 operands may be another PLUS or MINUS.
5021 Rather than test for specific case, we do this by a brute-force method
5022 and do all possible simplifications until no more changes occur. Then
5023 we rebuild the operation.
5025 May return NULL_RTX when no changes were made. */
5028 simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
5029 rtx op0, rtx op1)
5031 struct simplify_plus_minus_op_data
5033 rtx op;
5034 short neg;
5035 } ops[16];
5036 rtx result, tem;
5037 int n_ops = 2;
5038 int changed, n_constants, canonicalized = 0;
5039 int i, j;
5041 memset (ops, 0, sizeof ops);
5043 /* Set up the two operands and then expand them until nothing has been
5044 changed. If we run out of room in our array, give up; this should
5045 almost never happen. */
5047 ops[0].op = op0;
5048 ops[0].neg = 0;
5049 ops[1].op = op1;
5050 ops[1].neg = (code == MINUS);
5054 changed = 0;
5055 n_constants = 0;
5057 for (i = 0; i < n_ops; i++)
5059 rtx this_op = ops[i].op;
5060 int this_neg = ops[i].neg;
5061 enum rtx_code this_code = GET_CODE (this_op);
5063 switch (this_code)
5065 case PLUS:
5066 case MINUS:
5067 if (n_ops == ARRAY_SIZE (ops))
5068 return NULL_RTX;
5070 ops[n_ops].op = XEXP (this_op, 1);
5071 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
5072 n_ops++;
5074 ops[i].op = XEXP (this_op, 0);
5075 changed = 1;
5076 /* If this operand was negated then we will potentially
5077 canonicalize the expression. Similarly if we don't
5078 place the operands adjacent we're re-ordering the
5079 expression and thus might be performing a
5080 canonicalization. Ignore register re-ordering.
5081 ??? It might be better to shuffle the ops array here,
5082 but then (plus (plus (A, B), plus (C, D))) wouldn't
5083 be seen as non-canonical. */
5084 if (this_neg
5085 || (i != n_ops - 2
5086 && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
5087 canonicalized = 1;
5088 break;
5090 case NEG:
5091 ops[i].op = XEXP (this_op, 0);
5092 ops[i].neg = ! this_neg;
5093 changed = 1;
5094 canonicalized = 1;
5095 break;
5097 case CONST:
5098 if (n_ops != ARRAY_SIZE (ops)
5099 && GET_CODE (XEXP (this_op, 0)) == PLUS
5100 && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
5101 && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
5103 ops[i].op = XEXP (XEXP (this_op, 0), 0);
5104 ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
5105 ops[n_ops].neg = this_neg;
5106 n_ops++;
5107 changed = 1;
5108 canonicalized = 1;
5110 break;
5112 case NOT:
5113 /* ~a -> (-a - 1) */
5114 if (n_ops != ARRAY_SIZE (ops))
5116 ops[n_ops].op = CONSTM1_RTX (mode);
5117 ops[n_ops++].neg = this_neg;
5118 ops[i].op = XEXP (this_op, 0);
5119 ops[i].neg = !this_neg;
5120 changed = 1;
5121 canonicalized = 1;
5123 break;
5125 CASE_CONST_SCALAR_INT:
5126 case CONST_POLY_INT:
5127 n_constants++;
5128 if (this_neg)
5130 ops[i].op = neg_poly_int_rtx (mode, this_op);
5131 ops[i].neg = 0;
5132 changed = 1;
5133 canonicalized = 1;
5135 break;
5137 default:
5138 break;
5142 while (changed);
5144 if (n_constants > 1)
5145 canonicalized = 1;
5147 gcc_assert (n_ops >= 2);
5149 /* If we only have two operands, we can avoid the loops. */
5150 if (n_ops == 2)
5152 enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
5153 rtx lhs, rhs;
5155 /* Get the two operands. Be careful with the order, especially for
5156 the cases where code == MINUS. */
5157 if (ops[0].neg && ops[1].neg)
5159 lhs = gen_rtx_NEG (mode, ops[0].op);
5160 rhs = ops[1].op;
5162 else if (ops[0].neg)
5164 lhs = ops[1].op;
5165 rhs = ops[0].op;
5167 else
5169 lhs = ops[0].op;
5170 rhs = ops[1].op;
5173 return simplify_const_binary_operation (code, mode, lhs, rhs);
5176 /* Now simplify each pair of operands until nothing changes. */
5177 while (1)
5179 /* Insertion sort is good enough for a small array. */
5180 for (i = 1; i < n_ops; i++)
5182 struct simplify_plus_minus_op_data save;
5183 int cmp;
5185 j = i - 1;
5186 cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
5187 if (cmp <= 0)
5188 continue;
5189 /* Just swapping registers doesn't count as canonicalization. */
5190 if (cmp != 1)
5191 canonicalized = 1;
5193 save = ops[i];
5195 ops[j + 1] = ops[j];
5196 while (j--
5197 && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
5198 ops[j + 1] = save;
5201 changed = 0;
5202 for (i = n_ops - 1; i > 0; i--)
5203 for (j = i - 1; j >= 0; j--)
5205 rtx lhs = ops[j].op, rhs = ops[i].op;
5206 int lneg = ops[j].neg, rneg = ops[i].neg;
5208 if (lhs != 0 && rhs != 0)
5210 enum rtx_code ncode = PLUS;
5212 if (lneg != rneg)
5214 ncode = MINUS;
5215 if (lneg)
5216 std::swap (lhs, rhs);
5218 else if (swap_commutative_operands_p (lhs, rhs))
5219 std::swap (lhs, rhs);
5221 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
5222 && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
5224 rtx tem_lhs, tem_rhs;
5226 tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
5227 tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
5228 tem = simplify_binary_operation (ncode, mode, tem_lhs,
5229 tem_rhs);
5231 if (tem && !CONSTANT_P (tem))
5232 tem = gen_rtx_CONST (GET_MODE (tem), tem);
5234 else
5235 tem = simplify_binary_operation (ncode, mode, lhs, rhs);
5237 if (tem)
5239 /* Reject "simplifications" that just wrap the two
5240 arguments in a CONST. Failure to do so can result
5241 in infinite recursion with simplify_binary_operation
5242 when it calls us to simplify CONST operations.
5243 Also, if we find such a simplification, don't try
5244 any more combinations with this rhs: We must have
5245 something like symbol+offset, ie. one of the
5246 trivial CONST expressions we handle later. */
5247 if (GET_CODE (tem) == CONST
5248 && GET_CODE (XEXP (tem, 0)) == ncode
5249 && XEXP (XEXP (tem, 0), 0) == lhs
5250 && XEXP (XEXP (tem, 0), 1) == rhs)
5251 break;
5252 lneg &= rneg;
5253 if (GET_CODE (tem) == NEG)
5254 tem = XEXP (tem, 0), lneg = !lneg;
5255 if (poly_int_rtx_p (tem) && lneg)
5256 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
5258 ops[i].op = tem;
5259 ops[i].neg = lneg;
5260 ops[j].op = NULL_RTX;
5261 changed = 1;
5262 canonicalized = 1;
5267 if (!changed)
5268 break;
5270 /* Pack all the operands to the lower-numbered entries. */
5271 for (i = 0, j = 0; j < n_ops; j++)
5272 if (ops[j].op)
5274 ops[i] = ops[j];
5275 i++;
5277 n_ops = i;
5280 /* If nothing changed, check that rematerialization of rtl instructions
5281 is still required. */
5282 if (!canonicalized)
5284 /* Perform rematerialization if only all operands are registers and
5285 all operations are PLUS. */
5286 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5287 around rs6000 and how it uses the CA register. See PR67145. */
5288 for (i = 0; i < n_ops; i++)
5289 if (ops[i].neg
5290 || !REG_P (ops[i].op)
5291 || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5292 && fixed_regs[REGNO (ops[i].op)]
5293 && !global_regs[REGNO (ops[i].op)]
5294 && ops[i].op != frame_pointer_rtx
5295 && ops[i].op != arg_pointer_rtx
5296 && ops[i].op != stack_pointer_rtx))
5297 return NULL_RTX;
5298 goto gen_result;
5301 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5302 if (n_ops == 2
5303 && CONST_INT_P (ops[1].op)
5304 && CONSTANT_P (ops[0].op)
5305 && ops[0].neg)
5306 return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5308 /* We suppressed creation of trivial CONST expressions in the
5309 combination loop to avoid recursion. Create one manually now.
5310 The combination loop should have ensured that there is exactly
5311 one CONST_INT, and the sort will have ensured that it is last
5312 in the array and that any other constant will be next-to-last. */
5314 if (n_ops > 1
5315 && poly_int_rtx_p (ops[n_ops - 1].op)
5316 && CONSTANT_P (ops[n_ops - 2].op))
5318 rtx value = ops[n_ops - 1].op;
5319 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5320 value = neg_poly_int_rtx (mode, value);
5321 if (CONST_INT_P (value))
5323 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5324 INTVAL (value));
5325 n_ops--;
5329 /* Put a non-negated operand first, if possible. */
5331 for (i = 0; i < n_ops && ops[i].neg; i++)
5332 continue;
5333 if (i == n_ops)
5334 ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5335 else if (i != 0)
5337 tem = ops[0].op;
5338 ops[0] = ops[i];
5339 ops[i].op = tem;
5340 ops[i].neg = 1;
5343 /* Now make the result by performing the requested operations. */
5344 gen_result:
5345 result = ops[0].op;
5346 for (i = 1; i < n_ops; i++)
5347 result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5348 mode, result, ops[i].op);
5350 return result;
5353 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5354 static bool
5355 plus_minus_operand_p (const_rtx x)
5357 return GET_CODE (x) == PLUS
5358 || GET_CODE (x) == MINUS
5359 || (GET_CODE (x) == CONST
5360 && GET_CODE (XEXP (x, 0)) == PLUS
5361 && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5362 && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5365 /* Like simplify_binary_operation except used for relational operators.
5366 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5367 not also be VOIDmode.
5369 CMP_MODE specifies in which mode the comparison is done in, so it is
5370 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5371 the operands or, if both are VOIDmode, the operands are compared in
5372 "infinite precision". */
5374 simplify_context::simplify_relational_operation (rtx_code code,
5375 machine_mode mode,
5376 machine_mode cmp_mode,
5377 rtx op0, rtx op1)
5379 rtx tem, trueop0, trueop1;
5381 if (cmp_mode == VOIDmode)
5382 cmp_mode = GET_MODE (op0);
5383 if (cmp_mode == VOIDmode)
5384 cmp_mode = GET_MODE (op1);
5386 tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5387 if (tem)
5388 return relational_result (mode, cmp_mode, tem);
5390 /* For the following tests, ensure const0_rtx is op1. */
5391 if (swap_commutative_operands_p (op0, op1)
5392 || (op0 == const0_rtx && op1 != const0_rtx))
5393 std::swap (op0, op1), code = swap_condition (code);
5395 /* If op0 is a compare, extract the comparison arguments from it. */
5396 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5397 return simplify_gen_relational (code, mode, VOIDmode,
5398 XEXP (op0, 0), XEXP (op0, 1));
5400 if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
5401 return NULL_RTX;
5403 trueop0 = avoid_constant_pool_reference (op0);
5404 trueop1 = avoid_constant_pool_reference (op1);
5405 return simplify_relational_operation_1 (code, mode, cmp_mode,
5406 trueop0, trueop1);
5409 /* This part of simplify_relational_operation is only used when CMP_MODE
5410 is not in class MODE_CC (i.e. it is a real comparison).
5412 MODE is the mode of the result, while CMP_MODE specifies in which
5413 mode the comparison is done in, so it is the mode of the operands. */
5416 simplify_context::simplify_relational_operation_1 (rtx_code code,
5417 machine_mode mode,
5418 machine_mode cmp_mode,
5419 rtx op0, rtx op1)
5421 enum rtx_code op0code = GET_CODE (op0);
5423 if (op1 == const0_rtx && COMPARISON_P (op0))
5425 /* If op0 is a comparison, extract the comparison arguments
5426 from it. */
5427 if (code == NE)
5429 if (GET_MODE (op0) == mode)
5430 return simplify_rtx (op0);
5431 else
5432 return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5433 XEXP (op0, 0), XEXP (op0, 1));
5435 else if (code == EQ)
5437 enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5438 if (new_code != UNKNOWN)
5439 return simplify_gen_relational (new_code, mode, VOIDmode,
5440 XEXP (op0, 0), XEXP (op0, 1));
5444 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5445 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5446 if ((code == LTU || code == GEU)
5447 && GET_CODE (op0) == PLUS
5448 && CONST_INT_P (XEXP (op0, 1))
5449 && (rtx_equal_p (op1, XEXP (op0, 0))
5450 || rtx_equal_p (op1, XEXP (op0, 1)))
5451 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5452 && XEXP (op0, 1) != const0_rtx)
5454 rtx new_cmp
5455 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5456 return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5457 cmp_mode, XEXP (op0, 0), new_cmp);
5460 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5461 transformed into (LTU a -C). */
5462 if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5463 && CONST_INT_P (XEXP (op0, 1))
5464 && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5465 && XEXP (op0, 1) != const0_rtx)
5467 rtx new_cmp
5468 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5469 return simplify_gen_relational (LTU, mode, cmp_mode,
5470 XEXP (op0, 0), new_cmp);
5473 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5474 if ((code == LTU || code == GEU)
5475 && GET_CODE (op0) == PLUS
5476 && rtx_equal_p (op1, XEXP (op0, 1))
5477 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5478 && !rtx_equal_p (op1, XEXP (op0, 0)))
5479 return simplify_gen_relational (code, mode, cmp_mode, op0,
5480 copy_rtx (XEXP (op0, 0)));
5482 if (op1 == const0_rtx)
5484 /* Canonicalize (GTU x 0) as (NE x 0). */
5485 if (code == GTU)
5486 return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5487 /* Canonicalize (LEU x 0) as (EQ x 0). */
5488 if (code == LEU)
5489 return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5491 else if (op1 == const1_rtx)
5493 switch (code)
5495 case GE:
5496 /* Canonicalize (GE x 1) as (GT x 0). */
5497 return simplify_gen_relational (GT, mode, cmp_mode,
5498 op0, const0_rtx);
5499 case GEU:
5500 /* Canonicalize (GEU x 1) as (NE x 0). */
5501 return simplify_gen_relational (NE, mode, cmp_mode,
5502 op0, const0_rtx);
5503 case LT:
5504 /* Canonicalize (LT x 1) as (LE x 0). */
5505 return simplify_gen_relational (LE, mode, cmp_mode,
5506 op0, const0_rtx);
5507 case LTU:
5508 /* Canonicalize (LTU x 1) as (EQ x 0). */
5509 return simplify_gen_relational (EQ, mode, cmp_mode,
5510 op0, const0_rtx);
5511 default:
5512 break;
5515 else if (op1 == constm1_rtx)
5517 /* Canonicalize (LE x -1) as (LT x 0). */
5518 if (code == LE)
5519 return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5520 /* Canonicalize (GT x -1) as (GE x 0). */
5521 if (code == GT)
5522 return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5525 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5526 if ((code == EQ || code == NE)
5527 && (op0code == PLUS || op0code == MINUS)
5528 && CONSTANT_P (op1)
5529 && CONSTANT_P (XEXP (op0, 1))
5530 && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5532 rtx x = XEXP (op0, 0);
5533 rtx c = XEXP (op0, 1);
5534 enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5535 rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5537 /* Detect an infinite recursive condition, where we oscillate at this
5538 simplification case between:
5539 A + B == C <---> C - B == A,
5540 where A, B, and C are all constants with non-simplifiable expressions,
5541 usually SYMBOL_REFs. */
5542 if (GET_CODE (tem) == invcode
5543 && CONSTANT_P (x)
5544 && rtx_equal_p (c, XEXP (tem, 1)))
5545 return NULL_RTX;
5547 return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5550 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5551 the same as (zero_extract:SI FOO (const_int 1) BAR). */
5552 scalar_int_mode int_mode, int_cmp_mode;
5553 if (code == NE
5554 && op1 == const0_rtx
5555 && is_int_mode (mode, &int_mode)
5556 && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5557 /* ??? Work-around BImode bugs in the ia64 backend. */
5558 && int_mode != BImode
5559 && int_cmp_mode != BImode
5560 && nonzero_bits (op0, int_cmp_mode) == 1
5561 && STORE_FLAG_VALUE == 1)
5562 return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5563 ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5564 : lowpart_subreg (int_mode, op0, int_cmp_mode);
5566 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
5567 if ((code == EQ || code == NE)
5568 && op1 == const0_rtx
5569 && op0code == XOR)
5570 return simplify_gen_relational (code, mode, cmp_mode,
5571 XEXP (op0, 0), XEXP (op0, 1));
5573 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
5574 if ((code == EQ || code == NE)
5575 && op0code == XOR
5576 && rtx_equal_p (XEXP (op0, 0), op1)
5577 && !side_effects_p (XEXP (op0, 0)))
5578 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5579 CONST0_RTX (mode));
5581 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
5582 if ((code == EQ || code == NE)
5583 && op0code == XOR
5584 && rtx_equal_p (XEXP (op0, 1), op1)
5585 && !side_effects_p (XEXP (op0, 1)))
5586 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5587 CONST0_RTX (mode));
5589 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
5590 if ((code == EQ || code == NE)
5591 && op0code == XOR
5592 && CONST_SCALAR_INT_P (op1)
5593 && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5594 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5595 simplify_gen_binary (XOR, cmp_mode,
5596 XEXP (op0, 1), op1));
5598 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5599 constant folding if x/y is a constant. */
5600 if ((code == EQ || code == NE)
5601 && (op0code == AND || op0code == IOR)
5602 && !side_effects_p (op1)
5603 && op1 != CONST0_RTX (cmp_mode))
5605 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5606 (eq/ne (and (not y) x) 0). */
5607 if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5608 || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5610 rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5611 cmp_mode);
5612 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5614 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5615 CONST0_RTX (cmp_mode));
5618 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5619 (eq/ne (and (not x) y) 0). */
5620 if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5621 || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5623 rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5624 cmp_mode);
5625 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
5627 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5628 CONST0_RTX (cmp_mode));
5632 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
5633 if ((code == EQ || code == NE)
5634 && GET_CODE (op0) == BSWAP
5635 && CONST_SCALAR_INT_P (op1))
5636 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5637 simplify_gen_unary (BSWAP, cmp_mode,
5638 op1, cmp_mode));
5640 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
5641 if ((code == EQ || code == NE)
5642 && GET_CODE (op0) == BSWAP
5643 && GET_CODE (op1) == BSWAP)
5644 return simplify_gen_relational (code, mode, cmp_mode,
5645 XEXP (op0, 0), XEXP (op1, 0));
5647 if (op0code == POPCOUNT && op1 == const0_rtx)
5648 switch (code)
5650 case EQ:
5651 case LE:
5652 case LEU:
5653 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
5654 return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
5655 XEXP (op0, 0), const0_rtx);
5657 case NE:
5658 case GT:
5659 case GTU:
5660 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
5661 return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
5662 XEXP (op0, 0), const0_rtx);
5664 default:
5665 break;
5668 return NULL_RTX;
5671 enum
5673 CMP_EQ = 1,
5674 CMP_LT = 2,
5675 CMP_GT = 4,
5676 CMP_LTU = 8,
5677 CMP_GTU = 16
5681 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
5682 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
5683 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
5684 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
5685 For floating-point comparisons, assume that the operands were ordered. */
5687 static rtx
5688 comparison_result (enum rtx_code code, int known_results)
5690 switch (code)
5692 case EQ:
5693 case UNEQ:
5694 return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
5695 case NE:
5696 case LTGT:
5697 return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
5699 case LT:
5700 case UNLT:
5701 return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
5702 case GE:
5703 case UNGE:
5704 return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
5706 case GT:
5707 case UNGT:
5708 return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
5709 case LE:
5710 case UNLE:
5711 return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
5713 case LTU:
5714 return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
5715 case GEU:
5716 return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
5718 case GTU:
5719 return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
5720 case LEU:
5721 return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
5723 case ORDERED:
5724 return const_true_rtx;
5725 case UNORDERED:
5726 return const0_rtx;
5727 default:
5728 gcc_unreachable ();
5732 /* Check if the given comparison (done in the given MODE) is actually
5733 a tautology or a contradiction. If the mode is VOIDmode, the
5734 comparison is done in "infinite precision". If no simplification
5735 is possible, this function returns zero. Otherwise, it returns
5736 either const_true_rtx or const0_rtx. */
5739 simplify_const_relational_operation (enum rtx_code code,
5740 machine_mode mode,
5741 rtx op0, rtx op1)
5743 rtx tem;
5744 rtx trueop0;
5745 rtx trueop1;
5747 gcc_assert (mode != VOIDmode
5748 || (GET_MODE (op0) == VOIDmode
5749 && GET_MODE (op1) == VOIDmode));
5751 /* If op0 is a compare, extract the comparison arguments from it. */
5752 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5754 op1 = XEXP (op0, 1);
5755 op0 = XEXP (op0, 0);
5757 if (GET_MODE (op0) != VOIDmode)
5758 mode = GET_MODE (op0);
5759 else if (GET_MODE (op1) != VOIDmode)
5760 mode = GET_MODE (op1);
5761 else
5762 return 0;
5765 /* We can't simplify MODE_CC values since we don't know what the
5766 actual comparison is. */
5767 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
5768 return 0;
5770 /* Make sure the constant is second. */
5771 if (swap_commutative_operands_p (op0, op1))
5773 std::swap (op0, op1);
5774 code = swap_condition (code);
5777 trueop0 = avoid_constant_pool_reference (op0);
5778 trueop1 = avoid_constant_pool_reference (op1);
5780 /* For integer comparisons of A and B maybe we can simplify A - B and can
5781 then simplify a comparison of that with zero. If A and B are both either
5782 a register or a CONST_INT, this can't help; testing for these cases will
5783 prevent infinite recursion here and speed things up.
5785 We can only do this for EQ and NE comparisons as otherwise we may
5786 lose or introduce overflow which we cannot disregard as undefined as
5787 we do not know the signedness of the operation on either the left or
5788 the right hand side of the comparison. */
5790 if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
5791 && (code == EQ || code == NE)
5792 && ! ((REG_P (op0) || CONST_INT_P (trueop0))
5793 && (REG_P (op1) || CONST_INT_P (trueop1)))
5794 && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
5795 /* We cannot do this if tem is a nonzero address. */
5796 && ! nonzero_address_p (tem))
5797 return simplify_const_relational_operation (signed_condition (code),
5798 mode, tem, const0_rtx);
5800 if (! HONOR_NANS (mode) && code == ORDERED)
5801 return const_true_rtx;
5803 if (! HONOR_NANS (mode) && code == UNORDERED)
5804 return const0_rtx;
5806 /* For modes without NaNs, if the two operands are equal, we know the
5807 result except if they have side-effects. Even with NaNs we know
5808 the result of unordered comparisons and, if signaling NaNs are
5809 irrelevant, also the result of LT/GT/LTGT. */
5810 if ((! HONOR_NANS (trueop0)
5811 || code == UNEQ || code == UNLE || code == UNGE
5812 || ((code == LT || code == GT || code == LTGT)
5813 && ! HONOR_SNANS (trueop0)))
5814 && rtx_equal_p (trueop0, trueop1)
5815 && ! side_effects_p (trueop0))
5816 return comparison_result (code, CMP_EQ);
5818 /* If the operands are floating-point constants, see if we can fold
5819 the result. */
5820 if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
5821 && CONST_DOUBLE_AS_FLOAT_P (trueop1)
5822 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
5824 const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
5825 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
5827 /* Comparisons are unordered iff at least one of the values is NaN. */
5828 if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
5829 switch (code)
5831 case UNEQ:
5832 case UNLT:
5833 case UNGT:
5834 case UNLE:
5835 case UNGE:
5836 case NE:
5837 case UNORDERED:
5838 return const_true_rtx;
5839 case EQ:
5840 case LT:
5841 case GT:
5842 case LE:
5843 case GE:
5844 case LTGT:
5845 case ORDERED:
5846 return const0_rtx;
5847 default:
5848 return 0;
5851 return comparison_result (code,
5852 (real_equal (d0, d1) ? CMP_EQ :
5853 real_less (d0, d1) ? CMP_LT : CMP_GT));
5856 /* Otherwise, see if the operands are both integers. */
5857 if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
5858 && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
5860 /* It would be nice if we really had a mode here. However, the
5861 largest int representable on the target is as good as
5862 infinite. */
5863 machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
5864 rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
5865 rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
5867 if (wi::eq_p (ptrueop0, ptrueop1))
5868 return comparison_result (code, CMP_EQ);
5869 else
5871 int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
5872 cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
5873 return comparison_result (code, cr);
5877 /* Optimize comparisons with upper and lower bounds. */
5878 scalar_int_mode int_mode;
5879 if (CONST_INT_P (trueop1)
5880 && is_a <scalar_int_mode> (mode, &int_mode)
5881 && HWI_COMPUTABLE_MODE_P (int_mode)
5882 && !side_effects_p (trueop0))
5884 int sign;
5885 unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
5886 HOST_WIDE_INT val = INTVAL (trueop1);
5887 HOST_WIDE_INT mmin, mmax;
5889 if (code == GEU
5890 || code == LEU
5891 || code == GTU
5892 || code == LTU)
5893 sign = 0;
5894 else
5895 sign = 1;
5897 /* Get a reduced range if the sign bit is zero. */
5898 if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
5900 mmin = 0;
5901 mmax = nonzero;
5903 else
5905 rtx mmin_rtx, mmax_rtx;
5906 get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
5908 mmin = INTVAL (mmin_rtx);
5909 mmax = INTVAL (mmax_rtx);
5910 if (sign)
5912 unsigned int sign_copies
5913 = num_sign_bit_copies (trueop0, int_mode);
5915 mmin >>= (sign_copies - 1);
5916 mmax >>= (sign_copies - 1);
5920 switch (code)
5922 /* x >= y is always true for y <= mmin, always false for y > mmax. */
5923 case GEU:
5924 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
5925 return const_true_rtx;
5926 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
5927 return const0_rtx;
5928 break;
5929 case GE:
5930 if (val <= mmin)
5931 return const_true_rtx;
5932 if (val > mmax)
5933 return const0_rtx;
5934 break;
5936 /* x <= y is always true for y >= mmax, always false for y < mmin. */
5937 case LEU:
5938 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
5939 return const_true_rtx;
5940 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
5941 return const0_rtx;
5942 break;
5943 case LE:
5944 if (val >= mmax)
5945 return const_true_rtx;
5946 if (val < mmin)
5947 return const0_rtx;
5948 break;
5950 case EQ:
5951 /* x == y is always false for y out of range. */
5952 if (val < mmin || val > mmax)
5953 return const0_rtx;
5954 break;
5956 /* x > y is always false for y >= mmax, always true for y < mmin. */
5957 case GTU:
5958 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
5959 return const0_rtx;
5960 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
5961 return const_true_rtx;
5962 break;
5963 case GT:
5964 if (val >= mmax)
5965 return const0_rtx;
5966 if (val < mmin)
5967 return const_true_rtx;
5968 break;
5970 /* x < y is always false for y <= mmin, always true for y > mmax. */
5971 case LTU:
5972 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
5973 return const0_rtx;
5974 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
5975 return const_true_rtx;
5976 break;
5977 case LT:
5978 if (val <= mmin)
5979 return const0_rtx;
5980 if (val > mmax)
5981 return const_true_rtx;
5982 break;
5984 case NE:
5985 /* x != y is always true for y out of range. */
5986 if (val < mmin || val > mmax)
5987 return const_true_rtx;
5988 break;
5990 default:
5991 break;
5995 /* Optimize integer comparisons with zero. */
5996 if (is_a <scalar_int_mode> (mode, &int_mode)
5997 && trueop1 == const0_rtx
5998 && !side_effects_p (trueop0))
6000 /* Some addresses are known to be nonzero. We don't know
6001 their sign, but equality comparisons are known. */
6002 if (nonzero_address_p (trueop0))
6004 if (code == EQ || code == LEU)
6005 return const0_rtx;
6006 if (code == NE || code == GTU)
6007 return const_true_rtx;
6010 /* See if the first operand is an IOR with a constant. If so, we
6011 may be able to determine the result of this comparison. */
6012 if (GET_CODE (op0) == IOR)
6014 rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
6015 if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
6017 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
6018 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
6019 && (UINTVAL (inner_const)
6020 & (HOST_WIDE_INT_1U
6021 << sign_bitnum)));
6023 switch (code)
6025 case EQ:
6026 case LEU:
6027 return const0_rtx;
6028 case NE:
6029 case GTU:
6030 return const_true_rtx;
6031 case LT:
6032 case LE:
6033 if (has_sign)
6034 return const_true_rtx;
6035 break;
6036 case GT:
6037 case GE:
6038 if (has_sign)
6039 return const0_rtx;
6040 break;
6041 default:
6042 break;
6048 /* Optimize comparison of ABS with zero. */
6049 if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
6050 && (GET_CODE (trueop0) == ABS
6051 || (GET_CODE (trueop0) == FLOAT_EXTEND
6052 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
6054 switch (code)
6056 case LT:
6057 /* Optimize abs(x) < 0.0. */
6058 if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
6059 return const0_rtx;
6060 break;
6062 case GE:
6063 /* Optimize abs(x) >= 0.0. */
6064 if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
6065 return const_true_rtx;
6066 break;
6068 case UNGE:
6069 /* Optimize ! (abs(x) < 0.0). */
6070 return const_true_rtx;
6072 default:
6073 break;
6077 return 0;
6080 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6081 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6082 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6083 can be simplified to that or NULL_RTX if not.
6084 Assume X is compared against zero with CMP_CODE and the true
6085 arm is TRUE_VAL and the false arm is FALSE_VAL. */
6088 simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
6089 rtx true_val, rtx false_val)
6091 if (cmp_code != EQ && cmp_code != NE)
6092 return NULL_RTX;
6094 /* Result on X == 0 and X !=0 respectively. */
6095 rtx on_zero, on_nonzero;
6096 if (cmp_code == EQ)
6098 on_zero = true_val;
6099 on_nonzero = false_val;
6101 else
6103 on_zero = false_val;
6104 on_nonzero = true_val;
6107 rtx_code op_code = GET_CODE (on_nonzero);
6108 if ((op_code != CLZ && op_code != CTZ)
6109 || !rtx_equal_p (XEXP (on_nonzero, 0), x)
6110 || !CONST_INT_P (on_zero))
6111 return NULL_RTX;
6113 HOST_WIDE_INT op_val;
6114 scalar_int_mode mode ATTRIBUTE_UNUSED
6115 = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
6116 if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
6117 || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
6118 && op_val == INTVAL (on_zero))
6119 return on_nonzero;
6121 return NULL_RTX;
6124 /* Try to simplify X given that it appears within operand OP of a
6125 VEC_MERGE operation whose mask is MASK. X need not use the same
6126 vector mode as the VEC_MERGE, but it must have the same number of
6127 elements.
6129 Return the simplified X on success, otherwise return NULL_RTX. */
6132 simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
6134 gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
6135 poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
6136 if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
6138 if (side_effects_p (XEXP (x, 1 - op)))
6139 return NULL_RTX;
6141 return XEXP (x, op);
6143 if (UNARY_P (x)
6144 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6145 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
6147 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6148 if (top0)
6149 return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
6150 GET_MODE (XEXP (x, 0)));
6152 if (BINARY_P (x)
6153 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6154 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6155 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6156 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
6158 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6159 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6160 if (top0 || top1)
6162 if (COMPARISON_P (x))
6163 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6164 GET_MODE (XEXP (x, 0)) != VOIDmode
6165 ? GET_MODE (XEXP (x, 0))
6166 : GET_MODE (XEXP (x, 1)),
6167 top0 ? top0 : XEXP (x, 0),
6168 top1 ? top1 : XEXP (x, 1));
6169 else
6170 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
6171 top0 ? top0 : XEXP (x, 0),
6172 top1 ? top1 : XEXP (x, 1));
6175 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
6176 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6177 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6178 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6179 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
6180 && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
6181 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
6183 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6184 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6185 rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
6186 if (top0 || top1 || top2)
6187 return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6188 GET_MODE (XEXP (x, 0)),
6189 top0 ? top0 : XEXP (x, 0),
6190 top1 ? top1 : XEXP (x, 1),
6191 top2 ? top2 : XEXP (x, 2));
6193 return NULL_RTX;
6197 /* Simplify CODE, an operation with result mode MODE and three operands,
6198 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6199 a constant. Return 0 if no simplifications is possible. */
6202 simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
6203 machine_mode op0_mode,
6204 rtx op0, rtx op1, rtx op2)
6206 bool any_change = false;
6207 rtx tem, trueop2;
6208 scalar_int_mode int_mode, int_op0_mode;
6209 unsigned int n_elts;
6211 switch (code)
6213 case FMA:
6214 /* Simplify negations around the multiplication. */
6215 /* -a * -b + c => a * b + c. */
6216 if (GET_CODE (op0) == NEG)
6218 tem = simplify_unary_operation (NEG, mode, op1, mode);
6219 if (tem)
6220 op1 = tem, op0 = XEXP (op0, 0), any_change = true;
6222 else if (GET_CODE (op1) == NEG)
6224 tem = simplify_unary_operation (NEG, mode, op0, mode);
6225 if (tem)
6226 op0 = tem, op1 = XEXP (op1, 0), any_change = true;
6229 /* Canonicalize the two multiplication operands. */
6230 /* a * -b + c => -b * a + c. */
6231 if (swap_commutative_operands_p (op0, op1))
6232 std::swap (op0, op1), any_change = true;
6234 if (any_change)
6235 return gen_rtx_FMA (mode, op0, op1, op2);
6236 return NULL_RTX;
6238 case SIGN_EXTRACT:
6239 case ZERO_EXTRACT:
6240 if (CONST_INT_P (op0)
6241 && CONST_INT_P (op1)
6242 && CONST_INT_P (op2)
6243 && is_a <scalar_int_mode> (mode, &int_mode)
6244 && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
6245 && HWI_COMPUTABLE_MODE_P (int_mode))
6247 /* Extracting a bit-field from a constant */
6248 unsigned HOST_WIDE_INT val = UINTVAL (op0);
6249 HOST_WIDE_INT op1val = INTVAL (op1);
6250 HOST_WIDE_INT op2val = INTVAL (op2);
6251 if (!BITS_BIG_ENDIAN)
6252 val >>= op2val;
6253 else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
6254 val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
6255 else
6256 /* Not enough information to calculate the bit position. */
6257 break;
6259 if (HOST_BITS_PER_WIDE_INT != op1val)
6261 /* First zero-extend. */
6262 val &= (HOST_WIDE_INT_1U << op1val) - 1;
6263 /* If desired, propagate sign bit. */
6264 if (code == SIGN_EXTRACT
6265 && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6266 != 0)
6267 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6270 return gen_int_mode (val, int_mode);
6272 break;
6274 case IF_THEN_ELSE:
6275 if (CONST_INT_P (op0))
6276 return op0 != const0_rtx ? op1 : op2;
6278 /* Convert c ? a : a into "a". */
6279 if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6280 return op1;
6282 /* Convert a != b ? a : b into "a". */
6283 if (GET_CODE (op0) == NE
6284 && ! side_effects_p (op0)
6285 && ! HONOR_NANS (mode)
6286 && ! HONOR_SIGNED_ZEROS (mode)
6287 && ((rtx_equal_p (XEXP (op0, 0), op1)
6288 && rtx_equal_p (XEXP (op0, 1), op2))
6289 || (rtx_equal_p (XEXP (op0, 0), op2)
6290 && rtx_equal_p (XEXP (op0, 1), op1))))
6291 return op1;
6293 /* Convert a == b ? a : b into "b". */
6294 if (GET_CODE (op0) == EQ
6295 && ! side_effects_p (op0)
6296 && ! HONOR_NANS (mode)
6297 && ! HONOR_SIGNED_ZEROS (mode)
6298 && ((rtx_equal_p (XEXP (op0, 0), op1)
6299 && rtx_equal_p (XEXP (op0, 1), op2))
6300 || (rtx_equal_p (XEXP (op0, 0), op2)
6301 && rtx_equal_p (XEXP (op0, 1), op1))))
6302 return op2;
6304 /* Convert (!c) != {0,...,0} ? a : b into
6305 c != {0,...,0} ? b : a for vector modes. */
6306 if (VECTOR_MODE_P (GET_MODE (op1))
6307 && GET_CODE (op0) == NE
6308 && GET_CODE (XEXP (op0, 0)) == NOT
6309 && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6311 rtx cv = XEXP (op0, 1);
6312 int nunits;
6313 bool ok = true;
6314 if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6315 ok = false;
6316 else
6317 for (int i = 0; i < nunits; ++i)
6318 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6320 ok = false;
6321 break;
6323 if (ok)
6325 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6326 XEXP (XEXP (op0, 0), 0),
6327 XEXP (op0, 1));
6328 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6329 return retval;
6333 /* Convert x == 0 ? N : clz (x) into clz (x) when
6334 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6335 Similarly for ctz (x). */
6336 if (COMPARISON_P (op0) && !side_effects_p (op0)
6337 && XEXP (op0, 1) == const0_rtx)
6339 rtx simplified
6340 = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6341 op1, op2);
6342 if (simplified)
6343 return simplified;
6346 if (COMPARISON_P (op0) && ! side_effects_p (op0))
6348 machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6349 ? GET_MODE (XEXP (op0, 1))
6350 : GET_MODE (XEXP (op0, 0)));
6351 rtx temp;
6353 /* Look for happy constants in op1 and op2. */
6354 if (CONST_INT_P (op1) && CONST_INT_P (op2))
6356 HOST_WIDE_INT t = INTVAL (op1);
6357 HOST_WIDE_INT f = INTVAL (op2);
6359 if (t == STORE_FLAG_VALUE && f == 0)
6360 code = GET_CODE (op0);
6361 else if (t == 0 && f == STORE_FLAG_VALUE)
6363 enum rtx_code tmp;
6364 tmp = reversed_comparison_code (op0, NULL);
6365 if (tmp == UNKNOWN)
6366 break;
6367 code = tmp;
6369 else
6370 break;
6372 return simplify_gen_relational (code, mode, cmp_mode,
6373 XEXP (op0, 0), XEXP (op0, 1));
6376 temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6377 cmp_mode, XEXP (op0, 0),
6378 XEXP (op0, 1));
6380 /* See if any simplifications were possible. */
6381 if (temp)
6383 if (CONST_INT_P (temp))
6384 return temp == const0_rtx ? op2 : op1;
6385 else if (temp)
6386 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6389 break;
6391 case VEC_MERGE:
6392 gcc_assert (GET_MODE (op0) == mode);
6393 gcc_assert (GET_MODE (op1) == mode);
6394 gcc_assert (VECTOR_MODE_P (mode));
6395 trueop2 = avoid_constant_pool_reference (op2);
6396 if (CONST_INT_P (trueop2)
6397 && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6399 unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6400 unsigned HOST_WIDE_INT mask;
6401 if (n_elts == HOST_BITS_PER_WIDE_INT)
6402 mask = -1;
6403 else
6404 mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6406 if (!(sel & mask) && !side_effects_p (op0))
6407 return op1;
6408 if ((sel & mask) == mask && !side_effects_p (op1))
6409 return op0;
6411 rtx trueop0 = avoid_constant_pool_reference (op0);
6412 rtx trueop1 = avoid_constant_pool_reference (op1);
6413 if (GET_CODE (trueop0) == CONST_VECTOR
6414 && GET_CODE (trueop1) == CONST_VECTOR)
6416 rtvec v = rtvec_alloc (n_elts);
6417 unsigned int i;
6419 for (i = 0; i < n_elts; i++)
6420 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6421 ? CONST_VECTOR_ELT (trueop0, i)
6422 : CONST_VECTOR_ELT (trueop1, i));
6423 return gen_rtx_CONST_VECTOR (mode, v);
6426 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6427 if no element from a appears in the result. */
6428 if (GET_CODE (op0) == VEC_MERGE)
6430 tem = avoid_constant_pool_reference (XEXP (op0, 2));
6431 if (CONST_INT_P (tem))
6433 unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6434 if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6435 return simplify_gen_ternary (code, mode, mode,
6436 XEXP (op0, 1), op1, op2);
6437 if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6438 return simplify_gen_ternary (code, mode, mode,
6439 XEXP (op0, 0), op1, op2);
6442 if (GET_CODE (op1) == VEC_MERGE)
6444 tem = avoid_constant_pool_reference (XEXP (op1, 2));
6445 if (CONST_INT_P (tem))
6447 unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6448 if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6449 return simplify_gen_ternary (code, mode, mode,
6450 op0, XEXP (op1, 1), op2);
6451 if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6452 return simplify_gen_ternary (code, mode, mode,
6453 op0, XEXP (op1, 0), op2);
6457 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6458 with a. */
6459 if (GET_CODE (op0) == VEC_DUPLICATE
6460 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6461 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6462 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6464 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6465 if (CONST_INT_P (tem) && CONST_INT_P (op2))
6467 if (XEXP (XEXP (op0, 0), 0) == op1
6468 && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6469 return op1;
6472 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6473 (const_int N))
6474 with (vec_concat (X) (B)) if N == 1 or
6475 (vec_concat (A) (X)) if N == 2. */
6476 if (GET_CODE (op0) == VEC_DUPLICATE
6477 && GET_CODE (op1) == CONST_VECTOR
6478 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6479 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6480 && IN_RANGE (sel, 1, 2))
6482 rtx newop0 = XEXP (op0, 0);
6483 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6484 if (sel == 2)
6485 std::swap (newop0, newop1);
6486 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6488 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6489 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6490 Only applies for vectors of two elements. */
6491 if (GET_CODE (op0) == VEC_DUPLICATE
6492 && GET_CODE (op1) == VEC_CONCAT
6493 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6494 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6495 && IN_RANGE (sel, 1, 2))
6497 rtx newop0 = XEXP (op0, 0);
6498 rtx newop1 = XEXP (op1, 2 - sel);
6499 rtx otherop = XEXP (op1, sel - 1);
6500 if (sel == 2)
6501 std::swap (newop0, newop1);
6502 /* Don't want to throw away the other part of the vec_concat if
6503 it has side-effects. */
6504 if (!side_effects_p (otherop))
6505 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6508 /* Replace:
6510 (vec_merge:outer (vec_duplicate:outer x:inner)
6511 (subreg:outer y:inner 0)
6512 (const_int N))
6514 with (vec_concat:outer x:inner y:inner) if N == 1,
6515 or (vec_concat:outer y:inner x:inner) if N == 2.
6517 Implicitly, this means we have a paradoxical subreg, but such
6518 a check is cheap, so make it anyway.
6520 Only applies for vectors of two elements. */
6521 if (GET_CODE (op0) == VEC_DUPLICATE
6522 && GET_CODE (op1) == SUBREG
6523 && GET_MODE (op1) == GET_MODE (op0)
6524 && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6525 && paradoxical_subreg_p (op1)
6526 && subreg_lowpart_p (op1)
6527 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6528 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6529 && IN_RANGE (sel, 1, 2))
6531 rtx newop0 = XEXP (op0, 0);
6532 rtx newop1 = SUBREG_REG (op1);
6533 if (sel == 2)
6534 std::swap (newop0, newop1);
6535 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6538 /* Same as above but with switched operands:
6539 Replace (vec_merge:outer (subreg:outer x:inner 0)
6540 (vec_duplicate:outer y:inner)
6541 (const_int N))
6543 with (vec_concat:outer x:inner y:inner) if N == 1,
6544 or (vec_concat:outer y:inner x:inner) if N == 2. */
6545 if (GET_CODE (op1) == VEC_DUPLICATE
6546 && GET_CODE (op0) == SUBREG
6547 && GET_MODE (op0) == GET_MODE (op1)
6548 && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
6549 && paradoxical_subreg_p (op0)
6550 && subreg_lowpart_p (op0)
6551 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6552 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6553 && IN_RANGE (sel, 1, 2))
6555 rtx newop0 = SUBREG_REG (op0);
6556 rtx newop1 = XEXP (op1, 0);
6557 if (sel == 2)
6558 std::swap (newop0, newop1);
6559 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6562 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
6563 (const_int n))
6564 with (vec_concat x y) or (vec_concat y x) depending on value
6565 of N. */
6566 if (GET_CODE (op0) == VEC_DUPLICATE
6567 && GET_CODE (op1) == VEC_DUPLICATE
6568 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6569 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6570 && IN_RANGE (sel, 1, 2))
6572 rtx newop0 = XEXP (op0, 0);
6573 rtx newop1 = XEXP (op1, 0);
6574 if (sel == 2)
6575 std::swap (newop0, newop1);
6577 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6581 if (rtx_equal_p (op0, op1)
6582 && !side_effects_p (op2) && !side_effects_p (op1))
6583 return op0;
6585 if (!side_effects_p (op2))
6587 rtx top0
6588 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6589 rtx top1
6590 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6591 if (top0 || top1)
6592 return simplify_gen_ternary (code, mode, mode,
6593 top0 ? top0 : op0,
6594 top1 ? top1 : op1, op2);
6597 break;
6599 default:
6600 gcc_unreachable ();
6603 return 0;
6606 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6607 starting at byte FIRST_BYTE. Return true on success and add the
6608 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6609 that the bytes follow target memory order. Leave BYTES unmodified
6610 on failure.
6612 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6613 BYTES before calling this function. */
6615 bool
6616 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6617 unsigned int first_byte, unsigned int num_bytes)
6619 /* Check the mode is sensible. */
6620 gcc_assert (GET_MODE (x) == VOIDmode
6621 ? is_a <scalar_int_mode> (mode)
6622 : mode == GET_MODE (x));
6624 if (GET_CODE (x) == CONST_VECTOR)
6626 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
6627 is necessary. The only complication is that MODE_VECTOR_BOOL
6628 vectors can have several elements per byte. */
6629 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6630 GET_MODE_NUNITS (mode));
6631 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
6632 if (elt_bits < BITS_PER_UNIT)
6634 /* This is the only case in which elements can be smaller than
6635 a byte. */
6636 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6637 for (unsigned int i = 0; i < num_bytes; ++i)
6639 target_unit value = 0;
6640 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
6642 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & 1) << j;
6643 elt += 1;
6645 bytes.quick_push (value);
6647 return true;
6650 unsigned int start = bytes.length ();
6651 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
6652 /* Make FIRST_BYTE relative to ELT. */
6653 first_byte %= elt_bytes;
6654 while (num_bytes > 0)
6656 /* Work out how many bytes we want from element ELT. */
6657 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
6658 if (!native_encode_rtx (GET_MODE_INNER (mode),
6659 CONST_VECTOR_ELT (x, elt), bytes,
6660 first_byte, chunk_bytes))
6662 bytes.truncate (start);
6663 return false;
6665 elt += 1;
6666 first_byte = 0;
6667 num_bytes -= chunk_bytes;
6669 return true;
6672 /* All subsequent cases are limited to scalars. */
6673 scalar_mode smode;
6674 if (!is_a <scalar_mode> (mode, &smode))
6675 return false;
6677 /* Make sure that the region is in range. */
6678 unsigned int end_byte = first_byte + num_bytes;
6679 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6680 gcc_assert (end_byte <= mode_bytes);
6682 if (CONST_SCALAR_INT_P (x))
6684 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
6685 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
6686 position of each byte. */
6687 rtx_mode_t value (x, smode);
6688 wide_int_ref value_wi (value);
6689 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6691 /* Always constant because the inputs are. */
6692 unsigned int lsb
6693 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6694 /* Operate directly on the encoding rather than using
6695 wi::extract_uhwi, so that we preserve the sign or zero
6696 extension for modes that are not a whole number of bits in
6697 size. (Zero extension is only used for the combination of
6698 innermode == BImode && STORE_FLAG_VALUE == 1). */
6699 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
6700 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
6701 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
6702 bytes.quick_push (uhwi >> shift);
6704 return true;
6707 if (CONST_DOUBLE_P (x))
6709 /* real_to_target produces an array of integers in target memory order.
6710 All integers before the last one have 32 bits; the last one may
6711 have 32 bits or fewer, depending on whether the mode bitsize
6712 is divisible by 32. Each of these integers is then laid out
6713 in target memory as any other integer would be. */
6714 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6715 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
6717 /* The (maximum) number of target bytes per element of el32. */
6718 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6719 gcc_assert (bytes_per_el32 != 0);
6721 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
6722 handling above. */
6723 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6725 unsigned int index = byte / bytes_per_el32;
6726 unsigned int subbyte = byte % bytes_per_el32;
6727 unsigned int int_bytes = MIN (bytes_per_el32,
6728 mode_bytes - index * bytes_per_el32);
6729 /* Always constant because the inputs are. */
6730 unsigned int lsb
6731 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6732 bytes.quick_push ((unsigned long) el32[index] >> lsb);
6734 return true;
6737 if (GET_CODE (x) == CONST_FIXED)
6739 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6741 /* Always constant because the inputs are. */
6742 unsigned int lsb
6743 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6744 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
6745 if (lsb >= HOST_BITS_PER_WIDE_INT)
6747 lsb -= HOST_BITS_PER_WIDE_INT;
6748 piece = CONST_FIXED_VALUE_HIGH (x);
6750 bytes.quick_push (piece >> lsb);
6752 return true;
6755 return false;
6758 /* Read a vector of mode MODE from the target memory image given by BYTES,
6759 starting at byte FIRST_BYTE. The vector is known to be encodable using
6760 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
6761 and BYTES is known to have enough bytes to supply NPATTERNS *
6762 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
6763 BITS_PER_UNIT bits and the bytes are in target memory order.
6765 Return the vector on success, otherwise return NULL_RTX. */
6768 native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
6769 unsigned int first_byte, unsigned int npatterns,
6770 unsigned int nelts_per_pattern)
6772 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
6774 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6775 GET_MODE_NUNITS (mode));
6776 if (elt_bits < BITS_PER_UNIT)
6778 /* This is the only case in which elements can be smaller than a byte.
6779 Element 0 is always in the lsb of the containing byte. */
6780 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6781 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6783 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
6784 unsigned int byte_index = bit_index / BITS_PER_UNIT;
6785 unsigned int lsb = bit_index % BITS_PER_UNIT;
6786 builder.quick_push (bytes[byte_index] & (1 << lsb)
6787 ? CONST1_RTX (BImode)
6788 : CONST0_RTX (BImode));
6791 else
6793 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6795 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
6796 if (!x)
6797 return NULL_RTX;
6798 builder.quick_push (x);
6799 first_byte += elt_bits / BITS_PER_UNIT;
6802 return builder.build ();
6805 /* Read an rtx of mode MODE from the target memory image given by BYTES,
6806 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
6807 bits and the bytes are in target memory order. The image has enough
6808 values to specify all bytes of MODE.
6810 Return the rtx on success, otherwise return NULL_RTX. */
6813 native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
6814 unsigned int first_byte)
6816 if (VECTOR_MODE_P (mode))
6818 /* If we know at compile time how many elements there are,
6819 pull each element directly from BYTES. */
6820 unsigned int nelts;
6821 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
6822 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
6823 return NULL_RTX;
6826 scalar_int_mode imode;
6827 if (is_a <scalar_int_mode> (mode, &imode)
6828 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
6830 /* Pull the bytes msb first, so that we can use simple
6831 shift-and-insert wide_int operations. */
6832 unsigned int size = GET_MODE_SIZE (imode);
6833 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
6834 for (unsigned int i = 0; i < size; ++i)
6836 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
6837 /* Always constant because the inputs are. */
6838 unsigned int subbyte
6839 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
6840 result <<= BITS_PER_UNIT;
6841 result |= bytes[first_byte + subbyte];
6843 return immed_wide_int_const (result, imode);
6846 scalar_float_mode fmode;
6847 if (is_a <scalar_float_mode> (mode, &fmode))
6849 /* We need to build an array of integers in target memory order.
6850 All integers before the last one have 32 bits; the last one may
6851 have 32 bits or fewer, depending on whether the mode bitsize
6852 is divisible by 32. */
6853 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6854 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
6855 memset (el32, 0, num_el32 * sizeof (long));
6857 /* The (maximum) number of target bytes per element of el32. */
6858 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6859 gcc_assert (bytes_per_el32 != 0);
6861 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
6862 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6864 unsigned int index = byte / bytes_per_el32;
6865 unsigned int subbyte = byte % bytes_per_el32;
6866 unsigned int int_bytes = MIN (bytes_per_el32,
6867 mode_bytes - index * bytes_per_el32);
6868 /* Always constant because the inputs are. */
6869 unsigned int lsb
6870 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6871 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
6873 REAL_VALUE_TYPE r;
6874 real_from_target (&r, el32, fmode);
6875 return const_double_from_real_value (r, fmode);
6878 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
6880 scalar_mode smode = as_a <scalar_mode> (mode);
6881 FIXED_VALUE_TYPE f;
6882 f.data.low = 0;
6883 f.data.high = 0;
6884 f.mode = smode;
6886 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6887 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6889 /* Always constant because the inputs are. */
6890 unsigned int lsb
6891 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6892 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
6893 if (lsb >= HOST_BITS_PER_WIDE_INT)
6894 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
6895 else
6896 f.data.low |= unit << lsb;
6898 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
6901 return NULL_RTX;
6904 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
6905 is to convert a runtime BYTE value into a constant one. */
6907 static poly_uint64
6908 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
6910 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6911 machine_mode mode = GET_MODE (x);
6912 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6913 GET_MODE_NUNITS (mode));
6914 /* The number of bits needed to encode one element from each pattern. */
6915 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
6917 /* Identify the start point in terms of a sequence number and a byte offset
6918 within that sequence. */
6919 poly_uint64 first_sequence;
6920 unsigned HOST_WIDE_INT subbit;
6921 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
6922 &first_sequence, &subbit))
6924 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
6925 if (nelts_per_pattern == 1)
6926 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
6927 doesn't matter. */
6928 byte = subbit / BITS_PER_UNIT;
6929 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
6931 /* The subreg drops the first element from each pattern and
6932 only uses the second element. Find the first sequence
6933 that starts on a byte boundary. */
6934 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
6935 byte = subbit / BITS_PER_UNIT;
6938 return byte;
6941 /* Subroutine of simplify_subreg in which:
6943 - X is known to be a CONST_VECTOR
6944 - OUTERMODE is known to be a vector mode
6946 Try to handle the subreg by operating on the CONST_VECTOR encoding
6947 rather than on each individual element of the CONST_VECTOR.
6949 Return the simplified subreg on success, otherwise return NULL_RTX. */
6951 static rtx
6952 simplify_const_vector_subreg (machine_mode outermode, rtx x,
6953 machine_mode innermode, unsigned int first_byte)
6955 /* Paradoxical subregs of vectors have dubious semantics. */
6956 if (paradoxical_subreg_p (outermode, innermode))
6957 return NULL_RTX;
6959 /* We can only preserve the semantics of a stepped pattern if the new
6960 vector element is the same as the original one. */
6961 if (CONST_VECTOR_STEPPED_P (x)
6962 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
6963 return NULL_RTX;
6965 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6966 unsigned int x_elt_bits
6967 = vector_element_size (GET_MODE_BITSIZE (innermode),
6968 GET_MODE_NUNITS (innermode));
6969 unsigned int out_elt_bits
6970 = vector_element_size (GET_MODE_BITSIZE (outermode),
6971 GET_MODE_NUNITS (outermode));
6973 /* The number of bits needed to encode one element from every pattern
6974 of the original vector. */
6975 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
6977 /* The number of bits needed to encode one element from every pattern
6978 of the result. */
6979 unsigned int out_sequence_bits
6980 = least_common_multiple (x_sequence_bits, out_elt_bits);
6982 /* Work out the number of interleaved patterns in the output vector
6983 and the number of encoded elements per pattern. */
6984 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
6985 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
6987 /* The encoding scheme requires the number of elements to be a multiple
6988 of the number of patterns, so that each pattern appears at least once
6989 and so that the same number of elements appear from each pattern. */
6990 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
6991 unsigned int const_nunits;
6992 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
6993 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
6995 /* Either the encoding is invalid, or applying it would give us
6996 more elements than we need. Just encode each element directly. */
6997 out_npatterns = const_nunits;
6998 nelts_per_pattern = 1;
7000 else if (!ok_p)
7001 return NULL_RTX;
7003 /* Get enough bytes of X to form the new encoding. */
7004 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
7005 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
7006 auto_vec<target_unit, 128> buffer (buffer_bytes);
7007 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
7008 return NULL_RTX;
7010 /* Reencode the bytes as OUTERMODE. */
7011 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
7012 nelts_per_pattern);
7015 /* Try to simplify a subreg of a constant by encoding the subreg region
7016 as a sequence of target bytes and reading them back in the new mode.
7017 Return the new value on success, otherwise return null.
7019 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7020 and byte offset FIRST_BYTE. */
7022 static rtx
7023 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
7024 machine_mode innermode, unsigned int first_byte)
7026 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
7027 auto_vec<target_unit, 128> buffer (buffer_bytes);
7029 /* Some ports misuse CCmode. */
7030 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
7031 return x;
7033 /* Paradoxical subregs read undefined values for bytes outside of the
7034 inner value. However, we have traditionally always sign-extended
7035 integer constants and zero-extended others. */
7036 unsigned int inner_bytes = buffer_bytes;
7037 if (paradoxical_subreg_p (outermode, innermode))
7039 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
7040 return NULL_RTX;
7042 target_unit filler = 0;
7043 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
7044 filler = -1;
7046 /* Add any leading bytes due to big-endian layout. The number of
7047 bytes must be constant because both modes have constant size. */
7048 unsigned int leading_bytes
7049 = -byte_lowpart_offset (outermode, innermode).to_constant ();
7050 for (unsigned int i = 0; i < leading_bytes; ++i)
7051 buffer.quick_push (filler);
7053 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7054 return NULL_RTX;
7056 /* Add any trailing bytes due to little-endian layout. */
7057 while (buffer.length () < buffer_bytes)
7058 buffer.quick_push (filler);
7060 else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7061 return NULL_RTX;
7062 rtx ret = native_decode_rtx (outermode, buffer, 0);
7063 if (ret && MODE_COMPOSITE_P (outermode))
7065 auto_vec<target_unit, 128> buffer2 (buffer_bytes);
7066 if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
7067 return NULL_RTX;
7068 for (unsigned int i = 0; i < buffer_bytes; ++i)
7069 if (buffer[i] != buffer2[i])
7070 return NULL_RTX;
7072 return ret;
7075 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7076 Return 0 if no simplifications are possible. */
7078 simplify_context::simplify_subreg (machine_mode outermode, rtx op,
7079 machine_mode innermode, poly_uint64 byte)
7081 /* Little bit of sanity checking. */
7082 gcc_assert (innermode != VOIDmode);
7083 gcc_assert (outermode != VOIDmode);
7084 gcc_assert (innermode != BLKmode);
7085 gcc_assert (outermode != BLKmode);
7087 gcc_assert (GET_MODE (op) == innermode
7088 || GET_MODE (op) == VOIDmode);
7090 poly_uint64 outersize = GET_MODE_SIZE (outermode);
7091 if (!multiple_p (byte, outersize))
7092 return NULL_RTX;
7094 poly_uint64 innersize = GET_MODE_SIZE (innermode);
7095 if (maybe_ge (byte, innersize))
7096 return NULL_RTX;
7098 if (outermode == innermode && known_eq (byte, 0U))
7099 return op;
7101 if (GET_CODE (op) == CONST_VECTOR)
7102 byte = simplify_const_vector_byte_offset (op, byte);
7104 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
7106 rtx elt;
7108 if (VECTOR_MODE_P (outermode)
7109 && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
7110 && vec_duplicate_p (op, &elt))
7111 return gen_vec_duplicate (outermode, elt);
7113 if (outermode == GET_MODE_INNER (innermode)
7114 && vec_duplicate_p (op, &elt))
7115 return elt;
7118 if (CONST_SCALAR_INT_P (op)
7119 || CONST_DOUBLE_AS_FLOAT_P (op)
7120 || CONST_FIXED_P (op)
7121 || GET_CODE (op) == CONST_VECTOR)
7123 unsigned HOST_WIDE_INT cbyte;
7124 if (byte.is_constant (&cbyte))
7126 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
7128 rtx tmp = simplify_const_vector_subreg (outermode, op,
7129 innermode, cbyte);
7130 if (tmp)
7131 return tmp;
7134 fixed_size_mode fs_outermode;
7135 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
7136 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
7140 /* Changing mode twice with SUBREG => just change it once,
7141 or not at all if changing back op starting mode. */
7142 if (GET_CODE (op) == SUBREG)
7144 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
7145 poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
7146 rtx newx;
7148 if (outermode == innermostmode
7149 && known_eq (byte, 0U)
7150 && known_eq (SUBREG_BYTE (op), 0))
7151 return SUBREG_REG (op);
7153 /* Work out the memory offset of the final OUTERMODE value relative
7154 to the inner value of OP. */
7155 poly_int64 mem_offset = subreg_memory_offset (outermode,
7156 innermode, byte);
7157 poly_int64 op_mem_offset = subreg_memory_offset (op);
7158 poly_int64 final_offset = mem_offset + op_mem_offset;
7160 /* See whether resulting subreg will be paradoxical. */
7161 if (!paradoxical_subreg_p (outermode, innermostmode))
7163 /* Bail out in case resulting subreg would be incorrect. */
7164 if (maybe_lt (final_offset, 0)
7165 || maybe_ge (poly_uint64 (final_offset), innermostsize)
7166 || !multiple_p (final_offset, outersize))
7167 return NULL_RTX;
7169 else
7171 poly_int64 required_offset = subreg_memory_offset (outermode,
7172 innermostmode, 0);
7173 if (maybe_ne (final_offset, required_offset))
7174 return NULL_RTX;
7175 /* Paradoxical subregs always have byte offset 0. */
7176 final_offset = 0;
7179 /* Recurse for further possible simplifications. */
7180 newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
7181 final_offset);
7182 if (newx)
7183 return newx;
7184 if (validate_subreg (outermode, innermostmode,
7185 SUBREG_REG (op), final_offset))
7187 newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
7188 if (SUBREG_PROMOTED_VAR_P (op)
7189 && SUBREG_PROMOTED_SIGN (op) >= 0
7190 && GET_MODE_CLASS (outermode) == MODE_INT
7191 && known_ge (outersize, innersize)
7192 && known_le (outersize, innermostsize)
7193 && subreg_lowpart_p (newx))
7195 SUBREG_PROMOTED_VAR_P (newx) = 1;
7196 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
7198 return newx;
7200 return NULL_RTX;
7203 /* SUBREG of a hard register => just change the register number
7204 and/or mode. If the hard register is not valid in that mode,
7205 suppress this simplification. If the hard register is the stack,
7206 frame, or argument pointer, leave this as a SUBREG. */
7208 if (REG_P (op) && HARD_REGISTER_P (op))
7210 unsigned int regno, final_regno;
7212 regno = REGNO (op);
7213 final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
7214 if (HARD_REGISTER_NUM_P (final_regno))
7216 rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
7217 subreg_memory_offset (outermode,
7218 innermode, byte));
7220 /* Propagate original regno. We don't have any way to specify
7221 the offset inside original regno, so do so only for lowpart.
7222 The information is used only by alias analysis that cannot
7223 grog partial register anyway. */
7225 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
7226 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
7227 return x;
7231 /* If we have a SUBREG of a register that we are replacing and we are
7232 replacing it with a MEM, make a new MEM and try replacing the
7233 SUBREG with it. Don't do this if the MEM has a mode-dependent address
7234 or if we would be widening it. */
7236 if (MEM_P (op)
7237 && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
7238 /* Allow splitting of volatile memory references in case we don't
7239 have instruction to move the whole thing. */
7240 && (! MEM_VOLATILE_P (op)
7241 || ! have_insn_for (SET, innermode))
7242 && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
7243 && known_le (outersize, innersize))
7244 return adjust_address_nv (op, outermode, byte);
7246 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7247 of two parts. */
7248 if (GET_CODE (op) == CONCAT
7249 || GET_CODE (op) == VEC_CONCAT)
7251 poly_uint64 final_offset;
7252 rtx part, res;
7254 machine_mode part_mode = GET_MODE (XEXP (op, 0));
7255 if (part_mode == VOIDmode)
7256 part_mode = GET_MODE_INNER (GET_MODE (op));
7257 poly_uint64 part_size = GET_MODE_SIZE (part_mode);
7258 if (known_lt (byte, part_size))
7260 part = XEXP (op, 0);
7261 final_offset = byte;
7263 else if (known_ge (byte, part_size))
7265 part = XEXP (op, 1);
7266 final_offset = byte - part_size;
7268 else
7269 return NULL_RTX;
7271 if (maybe_gt (final_offset + outersize, part_size))
7272 return NULL_RTX;
7274 part_mode = GET_MODE (part);
7275 if (part_mode == VOIDmode)
7276 part_mode = GET_MODE_INNER (GET_MODE (op));
7277 res = simplify_subreg (outermode, part, part_mode, final_offset);
7278 if (res)
7279 return res;
7280 if (validate_subreg (outermode, part_mode, part, final_offset))
7281 return gen_rtx_SUBREG (outermode, part, final_offset);
7282 return NULL_RTX;
7285 /* Simplify
7286 (subreg (vec_merge (X)
7287 (vector)
7288 (const_int ((1 << N) | M)))
7289 (N * sizeof (outermode)))
7291 (subreg (X) (N * sizeof (outermode)))
7293 unsigned int idx;
7294 if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7295 && idx < HOST_BITS_PER_WIDE_INT
7296 && GET_CODE (op) == VEC_MERGE
7297 && GET_MODE_INNER (innermode) == outermode
7298 && CONST_INT_P (XEXP (op, 2))
7299 && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7300 return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7302 /* A SUBREG resulting from a zero extension may fold to zero if
7303 it extracts higher bits that the ZERO_EXTEND's source bits. */
7304 if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7306 poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7307 if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7308 return CONST0_RTX (outermode);
7311 scalar_int_mode int_outermode, int_innermode;
7312 if (is_a <scalar_int_mode> (outermode, &int_outermode)
7313 && is_a <scalar_int_mode> (innermode, &int_innermode)
7314 && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7316 /* Handle polynomial integers. The upper bits of a paradoxical
7317 subreg are undefined, so this is safe regardless of whether
7318 we're truncating or extending. */
7319 if (CONST_POLY_INT_P (op))
7321 poly_wide_int val
7322 = poly_wide_int::from (const_poly_int_value (op),
7323 GET_MODE_PRECISION (int_outermode),
7324 SIGNED);
7325 return immed_wide_int_const (val, int_outermode);
7328 if (GET_MODE_PRECISION (int_outermode)
7329 < GET_MODE_PRECISION (int_innermode))
7331 rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7332 if (tem)
7333 return tem;
7337 /* If OP is a vector comparison and the subreg is not changing the
7338 number of elements or the size of the elements, change the result
7339 of the comparison to the new mode. */
7340 if (COMPARISON_P (op)
7341 && VECTOR_MODE_P (outermode)
7342 && VECTOR_MODE_P (innermode)
7343 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7344 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7345 GET_MODE_UNIT_SIZE (innermode)))
7346 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7347 XEXP (op, 0), XEXP (op, 1));
7348 return NULL_RTX;
7351 /* Make a SUBREG operation or equivalent if it folds. */
7354 simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
7355 machine_mode innermode,
7356 poly_uint64 byte)
7358 rtx newx;
7360 newx = simplify_subreg (outermode, op, innermode, byte);
7361 if (newx)
7362 return newx;
7364 if (GET_CODE (op) == SUBREG
7365 || GET_CODE (op) == CONCAT
7366 || GET_MODE (op) == VOIDmode)
7367 return NULL_RTX;
7369 if (MODE_COMPOSITE_P (outermode)
7370 && (CONST_SCALAR_INT_P (op)
7371 || CONST_DOUBLE_AS_FLOAT_P (op)
7372 || CONST_FIXED_P (op)
7373 || GET_CODE (op) == CONST_VECTOR))
7374 return NULL_RTX;
7376 if (validate_subreg (outermode, innermode, op, byte))
7377 return gen_rtx_SUBREG (outermode, op, byte);
7379 return NULL_RTX;
7382 /* Generates a subreg to get the least significant part of EXPR (in mode
7383 INNER_MODE) to OUTER_MODE. */
7386 simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
7387 machine_mode inner_mode)
7389 return simplify_gen_subreg (outer_mode, expr, inner_mode,
7390 subreg_lowpart_offset (outer_mode, inner_mode));
7393 /* Simplify X, an rtx expression.
7395 Return the simplified expression or NULL if no simplifications
7396 were possible.
7398 This is the preferred entry point into the simplification routines;
7399 however, we still allow passes to call the more specific routines.
7401 Right now GCC has three (yes, three) major bodies of RTL simplification
7402 code that need to be unified.
7404 1. fold_rtx in cse.c. This code uses various CSE specific
7405 information to aid in RTL simplification.
7407 2. simplify_rtx in combine.c. Similar to fold_rtx, except that
7408 it uses combine specific information to aid in RTL
7409 simplification.
7411 3. The routines in this file.
7414 Long term we want to only have one body of simplification code; to
7415 get to that state I recommend the following steps:
7417 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7418 which are not pass dependent state into these routines.
7420 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7421 use this routine whenever possible.
7423 3. Allow for pass dependent state to be provided to these
7424 routines and add simplifications based on the pass dependent
7425 state. Remove code from cse.c & combine.c that becomes
7426 redundant/dead.
7428 It will take time, but ultimately the compiler will be easier to
7429 maintain and improve. It's totally silly that when we add a
7430 simplification that it needs to be added to 4 places (3 for RTL
7431 simplification and 1 for tree simplification. */
7434 simplify_rtx (const_rtx x)
7436 const enum rtx_code code = GET_CODE (x);
7437 const machine_mode mode = GET_MODE (x);
7439 switch (GET_RTX_CLASS (code))
7441 case RTX_UNARY:
7442 return simplify_unary_operation (code, mode,
7443 XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7444 case RTX_COMM_ARITH:
7445 if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7446 return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7448 /* Fall through. */
7450 case RTX_BIN_ARITH:
7451 return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7453 case RTX_TERNARY:
7454 case RTX_BITFIELD_OPS:
7455 return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7456 XEXP (x, 0), XEXP (x, 1),
7457 XEXP (x, 2));
7459 case RTX_COMPARE:
7460 case RTX_COMM_COMPARE:
7461 return simplify_relational_operation (code, mode,
7462 ((GET_MODE (XEXP (x, 0))
7463 != VOIDmode)
7464 ? GET_MODE (XEXP (x, 0))
7465 : GET_MODE (XEXP (x, 1))),
7466 XEXP (x, 0),
7467 XEXP (x, 1));
7469 case RTX_EXTRA:
7470 if (code == SUBREG)
7471 return simplify_subreg (mode, SUBREG_REG (x),
7472 GET_MODE (SUBREG_REG (x)),
7473 SUBREG_BYTE (x));
7474 break;
7476 case RTX_OBJ:
7477 if (code == LO_SUM)
7479 /* Convert (lo_sum (high FOO) FOO) to FOO. */
7480 if (GET_CODE (XEXP (x, 0)) == HIGH
7481 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
7482 return XEXP (x, 1);
7484 break;
7486 default:
7487 break;
7489 return NULL;
7492 #if CHECKING_P
7494 namespace selftest {
7496 /* Make a unique pseudo REG of mode MODE for use by selftests. */
7498 static rtx
7499 make_test_reg (machine_mode mode)
7501 static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
7503 return gen_rtx_REG (mode, test_reg_num++);
7506 static void
7507 test_scalar_int_ops (machine_mode mode)
7509 rtx op0 = make_test_reg (mode);
7510 rtx op1 = make_test_reg (mode);
7511 rtx six = GEN_INT (6);
7513 rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
7514 rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
7515 rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
7517 rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
7518 rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
7519 rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
7521 rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
7522 rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
7524 /* Test some binary identities. */
7525 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
7526 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
7527 ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
7528 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
7529 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
7530 ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
7531 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
7532 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
7533 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
7534 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
7535 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
7536 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
7537 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
7538 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
7539 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
7540 ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
7541 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
7543 /* Test some self-inverse operations. */
7544 ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
7545 ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
7546 ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
7548 /* Test some reflexive operations. */
7549 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
7550 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
7551 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
7552 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
7553 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
7554 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
7556 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
7557 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
7559 /* Test simplify_distributive_operation. */
7560 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
7561 simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
7562 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
7563 simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
7564 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
7565 simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
7568 /* Verify some simplifications involving scalar expressions. */
7570 static void
7571 test_scalar_ops ()
7573 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
7575 machine_mode mode = (machine_mode) i;
7576 if (SCALAR_INT_MODE_P (mode) && mode != BImode)
7577 test_scalar_int_ops (mode);
7581 /* Test vector simplifications involving VEC_DUPLICATE in which the
7582 operands and result have vector mode MODE. SCALAR_REG is a pseudo
7583 register that holds one element of MODE. */
7585 static void
7586 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
7588 scalar_mode inner_mode = GET_MODE_INNER (mode);
7589 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
7590 poly_uint64 nunits = GET_MODE_NUNITS (mode);
7591 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
7593 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
7594 rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
7595 rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
7596 ASSERT_RTX_EQ (duplicate,
7597 simplify_unary_operation (NOT, mode,
7598 duplicate_not, mode));
7600 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
7601 rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
7602 ASSERT_RTX_EQ (duplicate,
7603 simplify_unary_operation (NEG, mode,
7604 duplicate_neg, mode));
7606 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
7607 ASSERT_RTX_EQ (duplicate,
7608 simplify_binary_operation (PLUS, mode, duplicate,
7609 CONST0_RTX (mode)));
7611 ASSERT_RTX_EQ (duplicate,
7612 simplify_binary_operation (MINUS, mode, duplicate,
7613 CONST0_RTX (mode)));
7615 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
7616 simplify_binary_operation (MINUS, mode, duplicate,
7617 duplicate));
7620 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
7621 rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
7622 ASSERT_RTX_PTR_EQ (scalar_reg,
7623 simplify_binary_operation (VEC_SELECT, inner_mode,
7624 duplicate, zero_par));
7626 unsigned HOST_WIDE_INT const_nunits;
7627 if (nunits.is_constant (&const_nunits))
7629 /* And again with the final element. */
7630 rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
7631 rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
7632 ASSERT_RTX_PTR_EQ (scalar_reg,
7633 simplify_binary_operation (VEC_SELECT, inner_mode,
7634 duplicate, last_par));
7636 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
7637 rtx vector_reg = make_test_reg (mode);
7638 for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
7640 if (i >= HOST_BITS_PER_WIDE_INT)
7641 break;
7642 rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
7643 rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
7644 poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
7645 ASSERT_RTX_EQ (scalar_reg,
7646 simplify_gen_subreg (inner_mode, vm,
7647 mode, offset));
7651 /* Test a scalar subreg of a VEC_DUPLICATE. */
7652 poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
7653 ASSERT_RTX_EQ (scalar_reg,
7654 simplify_gen_subreg (inner_mode, duplicate,
7655 mode, offset));
7657 machine_mode narrower_mode;
7658 if (maybe_ne (nunits, 2U)
7659 && multiple_p (nunits, 2)
7660 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
7661 && VECTOR_MODE_P (narrower_mode))
7663 /* Test VEC_DUPLICATE of a vector. */
7664 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
7665 nbuilder.quick_push (const0_rtx);
7666 nbuilder.quick_push (const1_rtx);
7667 rtx_vector_builder builder (mode, 2, 1);
7668 builder.quick_push (const0_rtx);
7669 builder.quick_push (const1_rtx);
7670 ASSERT_RTX_EQ (builder.build (),
7671 simplify_unary_operation (VEC_DUPLICATE, mode,
7672 nbuilder.build (),
7673 narrower_mode));
7675 /* Test VEC_SELECT of a vector. */
7676 rtx vec_par
7677 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
7678 rtx narrower_duplicate
7679 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
7680 ASSERT_RTX_EQ (narrower_duplicate,
7681 simplify_binary_operation (VEC_SELECT, narrower_mode,
7682 duplicate, vec_par));
7684 /* Test a vector subreg of a VEC_DUPLICATE. */
7685 poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
7686 ASSERT_RTX_EQ (narrower_duplicate,
7687 simplify_gen_subreg (narrower_mode, duplicate,
7688 mode, offset));
7692 /* Test vector simplifications involving VEC_SERIES in which the
7693 operands and result have vector mode MODE. SCALAR_REG is a pseudo
7694 register that holds one element of MODE. */
7696 static void
7697 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
7699 /* Test unary cases with VEC_SERIES arguments. */
7700 scalar_mode inner_mode = GET_MODE_INNER (mode);
7701 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
7702 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
7703 rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
7704 rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
7705 rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
7706 rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
7707 rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
7708 rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
7709 neg_scalar_reg);
7710 ASSERT_RTX_EQ (series_0_r,
7711 simplify_unary_operation (NEG, mode, series_0_nr, mode));
7712 ASSERT_RTX_EQ (series_r_m1,
7713 simplify_unary_operation (NEG, mode, series_nr_1, mode));
7714 ASSERT_RTX_EQ (series_r_r,
7715 simplify_unary_operation (NEG, mode, series_nr_nr, mode));
7717 /* Test that a VEC_SERIES with a zero step is simplified away. */
7718 ASSERT_RTX_EQ (duplicate,
7719 simplify_binary_operation (VEC_SERIES, mode,
7720 scalar_reg, const0_rtx));
7722 /* Test PLUS and MINUS with VEC_SERIES. */
7723 rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
7724 rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
7725 rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
7726 ASSERT_RTX_EQ (series_r_r,
7727 simplify_binary_operation (PLUS, mode, series_0_r,
7728 duplicate));
7729 ASSERT_RTX_EQ (series_r_1,
7730 simplify_binary_operation (PLUS, mode, duplicate,
7731 series_0_1));
7732 ASSERT_RTX_EQ (series_r_m1,
7733 simplify_binary_operation (PLUS, mode, duplicate,
7734 series_0_m1));
7735 ASSERT_RTX_EQ (series_0_r,
7736 simplify_binary_operation (MINUS, mode, series_r_r,
7737 duplicate));
7738 ASSERT_RTX_EQ (series_r_m1,
7739 simplify_binary_operation (MINUS, mode, duplicate,
7740 series_0_1));
7741 ASSERT_RTX_EQ (series_r_1,
7742 simplify_binary_operation (MINUS, mode, duplicate,
7743 series_0_m1));
7744 ASSERT_RTX_EQ (series_0_m1,
7745 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
7746 constm1_rtx));
7748 /* Test NEG on constant vector series. */
7749 ASSERT_RTX_EQ (series_0_m1,
7750 simplify_unary_operation (NEG, mode, series_0_1, mode));
7751 ASSERT_RTX_EQ (series_0_1,
7752 simplify_unary_operation (NEG, mode, series_0_m1, mode));
7754 /* Test PLUS and MINUS on constant vector series. */
7755 rtx scalar2 = gen_int_mode (2, inner_mode);
7756 rtx scalar3 = gen_int_mode (3, inner_mode);
7757 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
7758 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
7759 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
7760 ASSERT_RTX_EQ (series_1_1,
7761 simplify_binary_operation (PLUS, mode, series_0_1,
7762 CONST1_RTX (mode)));
7763 ASSERT_RTX_EQ (series_0_m1,
7764 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
7765 series_0_m1));
7766 ASSERT_RTX_EQ (series_1_3,
7767 simplify_binary_operation (PLUS, mode, series_1_1,
7768 series_0_2));
7769 ASSERT_RTX_EQ (series_0_1,
7770 simplify_binary_operation (MINUS, mode, series_1_1,
7771 CONST1_RTX (mode)));
7772 ASSERT_RTX_EQ (series_1_1,
7773 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
7774 series_0_m1));
7775 ASSERT_RTX_EQ (series_1_1,
7776 simplify_binary_operation (MINUS, mode, series_1_3,
7777 series_0_2));
7779 /* Test MULT between constant vectors. */
7780 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
7781 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
7782 rtx scalar9 = gen_int_mode (9, inner_mode);
7783 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
7784 ASSERT_RTX_EQ (series_0_2,
7785 simplify_binary_operation (MULT, mode, series_0_1, vec2));
7786 ASSERT_RTX_EQ (series_3_9,
7787 simplify_binary_operation (MULT, mode, vec3, series_1_3));
7788 if (!GET_MODE_NUNITS (mode).is_constant ())
7789 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
7790 series_0_1));
7792 /* Test ASHIFT between constant vectors. */
7793 ASSERT_RTX_EQ (series_0_2,
7794 simplify_binary_operation (ASHIFT, mode, series_0_1,
7795 CONST1_RTX (mode)));
7796 if (!GET_MODE_NUNITS (mode).is_constant ())
7797 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
7798 series_0_1));
7801 static rtx
7802 simplify_merge_mask (rtx x, rtx mask, int op)
7804 return simplify_context ().simplify_merge_mask (x, mask, op);
7807 /* Verify simplify_merge_mask works correctly. */
7809 static void
7810 test_vec_merge (machine_mode mode)
7812 rtx op0 = make_test_reg (mode);
7813 rtx op1 = make_test_reg (mode);
7814 rtx op2 = make_test_reg (mode);
7815 rtx op3 = make_test_reg (mode);
7816 rtx op4 = make_test_reg (mode);
7817 rtx op5 = make_test_reg (mode);
7818 rtx mask1 = make_test_reg (SImode);
7819 rtx mask2 = make_test_reg (SImode);
7820 rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
7821 rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
7822 rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
7824 /* Simple vec_merge. */
7825 ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
7826 ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
7827 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
7828 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
7830 /* Nested vec_merge.
7831 It's tempting to make this simplify right down to opN, but we don't
7832 because all the simplify_* functions assume that the operands have
7833 already been simplified. */
7834 rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
7835 ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
7836 ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
7838 /* Intermediate unary op. */
7839 rtx unop = gen_rtx_NOT (mode, vm1);
7840 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
7841 simplify_merge_mask (unop, mask1, 0));
7842 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
7843 simplify_merge_mask (unop, mask1, 1));
7845 /* Intermediate binary op. */
7846 rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
7847 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
7848 simplify_merge_mask (binop, mask1, 0));
7849 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
7850 simplify_merge_mask (binop, mask1, 1));
7852 /* Intermediate ternary op. */
7853 rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
7854 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
7855 simplify_merge_mask (tenop, mask1, 0));
7856 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
7857 simplify_merge_mask (tenop, mask1, 1));
7859 /* Side effects. */
7860 rtx badop0 = gen_rtx_PRE_INC (mode, op0);
7861 rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
7862 ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
7863 ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
7865 /* Called indirectly. */
7866 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
7867 simplify_rtx (nvm));
7870 /* Test subregs of integer vector constant X, trying elements in
7871 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
7872 where NELTS is the number of elements in X. Subregs involving
7873 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
7875 static void
7876 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
7877 unsigned int first_valid = 0)
7879 machine_mode inner_mode = GET_MODE (x);
7880 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7882 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
7884 machine_mode outer_mode = (machine_mode) modei;
7885 if (!VECTOR_MODE_P (outer_mode))
7886 continue;
7888 unsigned int outer_nunits;
7889 if (GET_MODE_INNER (outer_mode) == int_mode
7890 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
7891 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
7893 /* Test subregs in which the outer mode is a smaller,
7894 constant-sized vector of the same element type. */
7895 unsigned int limit
7896 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
7897 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
7899 rtx expected = NULL_RTX;
7900 if (elt >= first_valid)
7902 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
7903 for (unsigned int i = 0; i < outer_nunits; ++i)
7904 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
7905 expected = builder.build ();
7907 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
7908 ASSERT_RTX_EQ (expected,
7909 simplify_subreg (outer_mode, x,
7910 inner_mode, byte));
7913 else if (known_eq (GET_MODE_SIZE (outer_mode),
7914 GET_MODE_SIZE (inner_mode))
7915 && known_eq (elt_bias, 0U)
7916 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
7917 || known_eq (GET_MODE_BITSIZE (outer_mode),
7918 GET_MODE_NUNITS (outer_mode)))
7919 && (!FLOAT_MODE_P (outer_mode)
7920 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
7921 == GET_MODE_UNIT_PRECISION (outer_mode)))
7922 && (GET_MODE_SIZE (inner_mode).is_constant ()
7923 || !CONST_VECTOR_STEPPED_P (x)))
7925 /* Try converting to OUTER_MODE and back. */
7926 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
7927 ASSERT_TRUE (outer_x != NULL_RTX);
7928 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
7929 outer_mode, 0));
7933 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
7935 /* Test each byte in the element range. */
7936 unsigned int limit
7937 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
7938 for (unsigned int i = 0; i < limit; ++i)
7940 unsigned int elt = i / GET_MODE_SIZE (int_mode);
7941 rtx expected = NULL_RTX;
7942 if (elt >= first_valid)
7944 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
7945 if (BYTES_BIG_ENDIAN)
7946 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
7947 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
7948 wide_int shifted_elt
7949 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
7950 expected = immed_wide_int_const (shifted_elt, QImode);
7952 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
7953 ASSERT_RTX_EQ (expected,
7954 simplify_subreg (QImode, x, inner_mode, byte));
7959 /* Test constant subregs of integer vector mode INNER_MODE, using 1
7960 element per pattern. */
7962 static void
7963 test_vector_subregs_repeating (machine_mode inner_mode)
7965 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
7966 unsigned int min_nunits = constant_lower_bound (nunits);
7967 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7968 unsigned int count = gcd (min_nunits, 8);
7970 rtx_vector_builder builder (inner_mode, count, 1);
7971 for (unsigned int i = 0; i < count; ++i)
7972 builder.quick_push (gen_int_mode (8 - i, int_mode));
7973 rtx x = builder.build ();
7975 test_vector_subregs_modes (x);
7976 if (!nunits.is_constant ())
7977 test_vector_subregs_modes (x, nunits - min_nunits);
7980 /* Test constant subregs of integer vector mode INNER_MODE, using 2
7981 elements per pattern. */
7983 static void
7984 test_vector_subregs_fore_back (machine_mode inner_mode)
7986 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
7987 unsigned int min_nunits = constant_lower_bound (nunits);
7988 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7989 unsigned int count = gcd (min_nunits, 4);
7991 rtx_vector_builder builder (inner_mode, count, 2);
7992 for (unsigned int i = 0; i < count; ++i)
7993 builder.quick_push (gen_int_mode (i, int_mode));
7994 for (unsigned int i = 0; i < count; ++i)
7995 builder.quick_push (gen_int_mode (-(int) i, int_mode));
7996 rtx x = builder.build ();
7998 test_vector_subregs_modes (x);
7999 if (!nunits.is_constant ())
8000 test_vector_subregs_modes (x, nunits - min_nunits, count);
8003 /* Test constant subregs of integer vector mode INNER_MODE, using 3
8004 elements per pattern. */
8006 static void
8007 test_vector_subregs_stepped (machine_mode inner_mode)
8009 /* Build { 0, 1, 2, 3, ... }. */
8010 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8011 rtx_vector_builder builder (inner_mode, 1, 3);
8012 for (unsigned int i = 0; i < 3; ++i)
8013 builder.quick_push (gen_int_mode (i, int_mode));
8014 rtx x = builder.build ();
8016 test_vector_subregs_modes (x);
8019 /* Test constant subregs of integer vector mode INNER_MODE. */
8021 static void
8022 test_vector_subregs (machine_mode inner_mode)
8024 test_vector_subregs_repeating (inner_mode);
8025 test_vector_subregs_fore_back (inner_mode);
8026 test_vector_subregs_stepped (inner_mode);
8029 /* Verify some simplifications involving vectors. */
8031 static void
8032 test_vector_ops ()
8034 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8036 machine_mode mode = (machine_mode) i;
8037 if (VECTOR_MODE_P (mode))
8039 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
8040 test_vector_ops_duplicate (mode, scalar_reg);
8041 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
8042 && maybe_gt (GET_MODE_NUNITS (mode), 2))
8044 test_vector_ops_series (mode, scalar_reg);
8045 test_vector_subregs (mode);
8047 test_vec_merge (mode);
8052 template<unsigned int N>
8053 struct simplify_const_poly_int_tests
8055 static void run ();
8058 template<>
8059 struct simplify_const_poly_int_tests<1>
8061 static void run () {}
8064 /* Test various CONST_POLY_INT properties. */
8066 template<unsigned int N>
8067 void
8068 simplify_const_poly_int_tests<N>::run ()
8070 rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
8071 rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
8072 rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
8073 rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
8074 rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
8075 rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
8076 rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
8077 rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
8078 rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
8079 rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
8080 rtx two = GEN_INT (2);
8081 rtx six = GEN_INT (6);
8082 poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
8084 /* These tests only try limited operation combinations. Fuller arithmetic
8085 testing is done directly on poly_ints. */
8086 ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
8087 ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
8088 ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
8089 ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
8090 ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
8091 ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
8092 ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
8093 ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
8094 ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
8095 ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
8096 ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
8099 /* Run all of the selftests within this file. */
8101 void
8102 simplify_rtx_c_tests ()
8104 test_scalar_ops ();
8105 test_vector_ops ();
8106 simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
8109 } // namespace selftest
8111 #endif /* CHECKING_P */