c++: fix explicit/copy problem [PR109247]
[official-gcc.git] / gcc / simplify-rtx.cc
blob4e20a34197717c7267e7ab991dadc65a3752fcda
1 /* RTL simplification functions for GNU compiler.
2 Copyright (C) 1987-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "predict.h"
29 #include "memmodel.h"
30 #include "optabs.h"
31 #include "emit-rtl.h"
32 #include "recog.h"
33 #include "diagnostic-core.h"
34 #include "varasm.h"
35 #include "flags.h"
36 #include "selftest.h"
37 #include "selftest-rtl.h"
38 #include "rtx-vector-builder.h"
39 #include "rtlanal.h"
41 /* Simplification and canonicalization of RTL. */
43 /* Much code operates on (low, high) pairs; the low value is an
44 unsigned wide int, the high value a signed wide int. We
45 occasionally need to sign extend from low to high as if low were a
46 signed wide int. */
47 #define HWI_SIGN_EXTEND(low) \
48 ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
50 static bool plus_minus_operand_p (const_rtx);
52 /* Negate I, which satisfies poly_int_rtx_p. MODE is the mode of I. */
54 static rtx
55 neg_poly_int_rtx (machine_mode mode, const_rtx i)
57 return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
60 /* Test whether expression, X, is an immediate constant that represents
61 the most significant bit of machine mode MODE. */
63 bool
64 mode_signbit_p (machine_mode mode, const_rtx x)
66 unsigned HOST_WIDE_INT val;
67 unsigned int width;
68 scalar_int_mode int_mode;
70 if (!is_int_mode (mode, &int_mode))
71 return false;
73 width = GET_MODE_PRECISION (int_mode);
74 if (width == 0)
75 return false;
77 if (width <= HOST_BITS_PER_WIDE_INT
78 && CONST_INT_P (x))
79 val = INTVAL (x);
80 #if TARGET_SUPPORTS_WIDE_INT
81 else if (CONST_WIDE_INT_P (x))
83 unsigned int i;
84 unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 return false;
87 for (i = 0; i < elts - 1; i++)
88 if (CONST_WIDE_INT_ELT (x, i) != 0)
89 return false;
90 val = CONST_WIDE_INT_ELT (x, elts - 1);
91 width %= HOST_BITS_PER_WIDE_INT;
92 if (width == 0)
93 width = HOST_BITS_PER_WIDE_INT;
95 #else
96 else if (width <= HOST_BITS_PER_DOUBLE_INT
97 && CONST_DOUBLE_AS_INT_P (x)
98 && CONST_DOUBLE_LOW (x) == 0)
100 val = CONST_DOUBLE_HIGH (x);
101 width -= HOST_BITS_PER_WIDE_INT;
103 #endif
104 else
105 /* X is not an integer constant. */
106 return false;
108 if (width < HOST_BITS_PER_WIDE_INT)
109 val &= (HOST_WIDE_INT_1U << width) - 1;
110 return val == (HOST_WIDE_INT_1U << (width - 1));
113 /* Test whether VAL is equal to the most significant bit of mode MODE
114 (after masking with the mode mask of MODE). Returns false if the
115 precision of MODE is too large to handle. */
117 bool
118 val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
120 unsigned int width;
121 scalar_int_mode int_mode;
123 if (!is_int_mode (mode, &int_mode))
124 return false;
126 width = GET_MODE_PRECISION (int_mode);
127 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 return false;
130 val &= GET_MODE_MASK (int_mode);
131 return val == (HOST_WIDE_INT_1U << (width - 1));
134 /* Test whether the most significant bit of mode MODE is set in VAL.
135 Returns false if the precision of MODE is too large to handle. */
136 bool
137 val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
139 unsigned int width;
141 scalar_int_mode int_mode;
142 if (!is_int_mode (mode, &int_mode))
143 return false;
145 width = GET_MODE_PRECISION (int_mode);
146 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 return false;
149 val &= HOST_WIDE_INT_1U << (width - 1);
150 return val != 0;
153 /* Test whether the most significant bit of mode MODE is clear in VAL.
154 Returns false if the precision of MODE is too large to handle. */
155 bool
156 val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
158 unsigned int width;
160 scalar_int_mode int_mode;
161 if (!is_int_mode (mode, &int_mode))
162 return false;
164 width = GET_MODE_PRECISION (int_mode);
165 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 return false;
168 val &= HOST_WIDE_INT_1U << (width - 1);
169 return val == 0;
172 /* Make a binary operation by properly ordering the operands and
173 seeing if the expression folds. */
176 simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 rtx op0, rtx op1)
179 rtx tem;
181 /* If this simplifies, do it. */
182 tem = simplify_binary_operation (code, mode, op0, op1);
183 if (tem)
184 return tem;
186 /* Put complex operands first and constants second if commutative. */
187 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 && swap_commutative_operands_p (op0, op1))
189 std::swap (op0, op1);
191 return gen_rtx_fmt_ee (code, mode, op0, op1);
194 /* If X is a MEM referencing the constant pool, return the real value.
195 Otherwise return X. */
197 avoid_constant_pool_reference (rtx x)
199 rtx c, tmp, addr;
200 machine_mode cmode;
201 poly_int64 offset = 0;
203 switch (GET_CODE (x))
205 case MEM:
206 break;
208 case FLOAT_EXTEND:
209 /* Handle float extensions of constant pool references. */
210 tmp = XEXP (x, 0);
211 c = avoid_constant_pool_reference (tmp);
212 if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 GET_MODE (x));
215 return x;
217 default:
218 return x;
221 if (GET_MODE (x) == BLKmode)
222 return x;
224 addr = XEXP (x, 0);
226 /* Call target hook to avoid the effects of -fpic etc.... */
227 addr = targetm.delegitimize_address (addr);
229 /* Split the address into a base and integer offset. */
230 addr = strip_offset (addr, &offset);
232 if (GET_CODE (addr) == LO_SUM)
233 addr = XEXP (addr, 1);
235 /* If this is a constant pool reference, we can turn it into its
236 constant and hope that simplifications happen. */
237 if (GET_CODE (addr) == SYMBOL_REF
238 && CONSTANT_POOL_ADDRESS_P (addr))
240 c = get_pool_constant (addr);
241 cmode = get_pool_mode (addr);
243 /* If we're accessing the constant in a different mode than it was
244 originally stored, attempt to fix that up via subreg simplifications.
245 If that fails we have no choice but to return the original memory. */
246 if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 return c;
248 else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
250 rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 if (tem && CONSTANT_P (tem))
252 return tem;
256 return x;
259 /* Simplify a MEM based on its attributes. This is the default
260 delegitimize_address target hook, and it's recommended that every
261 overrider call it. */
264 delegitimize_mem_from_attrs (rtx x)
266 /* MEMs without MEM_OFFSETs may have been offset, so we can't just
267 use their base addresses as equivalent. */
268 if (MEM_P (x)
269 && MEM_EXPR (x)
270 && MEM_OFFSET_KNOWN_P (x))
272 tree decl = MEM_EXPR (x);
273 machine_mode mode = GET_MODE (x);
274 poly_int64 offset = 0;
276 switch (TREE_CODE (decl))
278 default:
279 decl = NULL;
280 break;
282 case VAR_DECL:
283 break;
285 case ARRAY_REF:
286 case ARRAY_RANGE_REF:
287 case COMPONENT_REF:
288 case BIT_FIELD_REF:
289 case REALPART_EXPR:
290 case IMAGPART_EXPR:
291 case VIEW_CONVERT_EXPR:
293 poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 tree toffset;
295 int unsignedp, reversep, volatilep = 0;
297 decl
298 = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 &unsignedp, &reversep, &volatilep);
300 if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 decl = NULL;
304 else
305 offset += bytepos + toffset_val;
306 break;
310 if (decl
311 && mode == GET_MODE (x)
312 && VAR_P (decl)
313 && (TREE_STATIC (decl)
314 || DECL_THREAD_LOCAL_P (decl))
315 && DECL_RTL_SET_P (decl)
316 && MEM_P (DECL_RTL (decl)))
318 rtx newx;
320 offset += MEM_OFFSET (x);
322 newx = DECL_RTL (decl);
324 if (MEM_P (newx))
326 rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 poly_int64 n_offset, o_offset;
329 /* Avoid creating a new MEM needlessly if we already had
330 the same address. We do if there's no OFFSET and the
331 old address X is identical to NEWX, or if X is of the
332 form (plus NEWX OFFSET), or the NEWX is of the form
333 (plus Y (const_int Z)) and X is that with the offset
334 added: (plus Y (const_int Z+OFFSET)). */
335 n = strip_offset (n, &n_offset);
336 o = strip_offset (o, &o_offset);
337 if (!(known_eq (o_offset, n_offset + offset)
338 && rtx_equal_p (o, n)))
339 x = adjust_address_nv (newx, mode, offset);
341 else if (GET_MODE (x) == GET_MODE (newx)
342 && known_eq (offset, 0))
343 x = newx;
347 return x;
350 /* Make a unary operation by first seeing if it folds and otherwise making
351 the specified operation. */
354 simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 machine_mode op_mode)
357 rtx tem;
359 /* If this simplifies, use it. */
360 if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 return tem;
363 return gen_rtx_fmt_e (code, mode, op);
366 /* Likewise for ternary operations. */
369 simplify_context::simplify_gen_ternary (rtx_code code, machine_mode mode,
370 machine_mode op0_mode,
371 rtx op0, rtx op1, rtx op2)
373 rtx tem;
375 /* If this simplifies, use it. */
376 if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 op0, op1, op2)) != 0)
378 return tem;
380 return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
383 /* Likewise, for relational operations.
384 CMP_MODE specifies mode comparison is done in. */
387 simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 machine_mode cmp_mode,
389 rtx op0, rtx op1)
391 rtx tem;
393 if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 op0, op1)) != 0)
395 return tem;
397 return gen_rtx_fmt_ee (code, mode, op0, op1);
400 /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
401 and simplify the result. If FN is non-NULL, call this callback on each
402 X, if it returns non-NULL, replace X with its return value and simplify the
403 result. */
406 simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 rtx (*fn) (rtx, const_rtx, void *), void *data)
409 enum rtx_code code = GET_CODE (x);
410 machine_mode mode = GET_MODE (x);
411 machine_mode op_mode;
412 const char *fmt;
413 rtx op0, op1, op2, newx, op;
414 rtvec vec, newvec;
415 int i, j;
417 if (UNLIKELY (fn != NULL))
419 newx = fn (x, old_rtx, data);
420 if (newx)
421 return newx;
423 else if (rtx_equal_p (x, old_rtx))
424 return copy_rtx ((rtx) data);
426 switch (GET_RTX_CLASS (code))
428 case RTX_UNARY:
429 op0 = XEXP (x, 0);
430 op_mode = GET_MODE (op0);
431 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 if (op0 == XEXP (x, 0))
433 return x;
434 return simplify_gen_unary (code, mode, op0, op_mode);
436 case RTX_BIN_ARITH:
437 case RTX_COMM_ARITH:
438 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 return x;
442 return simplify_gen_binary (code, mode, op0, op1);
444 case RTX_COMPARE:
445 case RTX_COMM_COMPARE:
446 op0 = XEXP (x, 0);
447 op1 = XEXP (x, 1);
448 op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 return x;
453 return simplify_gen_relational (code, mode, op_mode, op0, op1);
455 case RTX_TERNARY:
456 case RTX_BITFIELD_OPS:
457 op0 = XEXP (x, 0);
458 op_mode = GET_MODE (op0);
459 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 return x;
464 if (op_mode == VOIDmode)
465 op_mode = GET_MODE (op0);
466 return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
468 case RTX_EXTRA:
469 if (code == SUBREG)
471 op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 if (op0 == SUBREG_REG (x))
473 return x;
474 op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 GET_MODE (SUBREG_REG (x)),
476 SUBREG_BYTE (x));
477 return op0 ? op0 : x;
479 break;
481 case RTX_OBJ:
482 if (code == MEM)
484 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 if (op0 == XEXP (x, 0))
486 return x;
487 return replace_equiv_address_nv (x, op0);
489 else if (code == LO_SUM)
491 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
492 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
494 /* (lo_sum (high x) y) -> y where x and y have the same base. */
495 if (GET_CODE (op0) == HIGH)
497 rtx base0, base1, offset0, offset1;
498 split_const (XEXP (op0, 0), &base0, &offset0);
499 split_const (op1, &base1, &offset1);
500 if (rtx_equal_p (base0, base1))
501 return op1;
504 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
505 return x;
506 return gen_rtx_LO_SUM (mode, op0, op1);
508 break;
510 default:
511 break;
514 newx = x;
515 fmt = GET_RTX_FORMAT (code);
516 for (i = 0; fmt[i]; i++)
517 switch (fmt[i])
519 case 'E':
520 vec = XVEC (x, i);
521 newvec = XVEC (newx, i);
522 for (j = 0; j < GET_NUM_ELEM (vec); j++)
524 op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 old_rtx, fn, data);
526 if (op != RTVEC_ELT (vec, j))
528 if (newvec == vec)
530 newvec = shallow_copy_rtvec (vec);
531 if (x == newx)
532 newx = shallow_copy_rtx (x);
533 XVEC (newx, i) = newvec;
535 RTVEC_ELT (newvec, j) = op;
538 break;
540 case 'e':
541 if (XEXP (x, i))
543 op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 if (op != XEXP (x, i))
546 if (x == newx)
547 newx = shallow_copy_rtx (x);
548 XEXP (newx, i) = op;
551 break;
553 return newx;
556 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
557 resulting RTX. Return a new RTX which is as simplified as possible. */
560 simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
562 return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
565 /* Try to simplify a MODE truncation of OP, which has OP_MODE.
566 Only handle cases where the truncated value is inherently an rvalue.
568 RTL provides two ways of truncating a value:
570 1. a lowpart subreg. This form is only a truncation when both
571 the outer and inner modes (here MODE and OP_MODE respectively)
572 are scalar integers, and only then when the subreg is used as
573 an rvalue.
575 It is only valid to form such truncating subregs if the
576 truncation requires no action by the target. The onus for
577 proving this is on the creator of the subreg -- e.g. the
578 caller to simplify_subreg or simplify_gen_subreg -- and typically
579 involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
581 2. a TRUNCATE. This form handles both scalar and compound integers.
583 The first form is preferred where valid. However, the TRUNCATE
584 handling in simplify_unary_operation turns the second form into the
585 first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
586 so it is generally safe to form rvalue truncations using:
588 simplify_gen_unary (TRUNCATE, ...)
590 and leave simplify_unary_operation to work out which representation
591 should be used.
593 Because of the proof requirements on (1), simplify_truncation must
594 also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
595 regardless of whether the outer truncation came from a SUBREG or a
596 TRUNCATE. For example, if the caller has proven that an SImode
597 truncation of:
599 (and:DI X Y)
601 is a no-op and can be represented as a subreg, it does not follow
602 that SImode truncations of X and Y are also no-ops. On a target
603 like 64-bit MIPS that requires SImode values to be stored in
604 sign-extended form, an SImode truncation of:
606 (and:DI (reg:DI X) (const_int 63))
608 is trivially a no-op because only the lower 6 bits can be set.
609 However, X is still an arbitrary 64-bit number and so we cannot
610 assume that truncating it too is a no-op. */
613 simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 machine_mode op_mode)
616 unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 scalar_int_mode int_mode, int_op_mode, subreg_mode;
620 gcc_assert (precision <= op_precision);
622 /* Optimize truncations of zero and sign extended values. */
623 if (GET_CODE (op) == ZERO_EXTEND
624 || GET_CODE (op) == SIGN_EXTEND)
626 /* There are three possibilities. If MODE is the same as the
627 origmode, we can omit both the extension and the subreg.
628 If MODE is not larger than the origmode, we can apply the
629 truncation without the extension. Finally, if the outermode
630 is larger than the origmode, we can just extend to the appropriate
631 mode. */
632 machine_mode origmode = GET_MODE (XEXP (op, 0));
633 if (mode == origmode)
634 return XEXP (op, 0);
635 else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 return simplify_gen_unary (TRUNCATE, mode,
637 XEXP (op, 0), origmode);
638 else
639 return simplify_gen_unary (GET_CODE (op), mode,
640 XEXP (op, 0), origmode);
643 /* If the machine can perform operations in the truncated mode, distribute
644 the truncation, i.e. simplify (truncate:QI (op:SI (x:SI) (y:SI))) into
645 (op:QI (truncate:QI (x:SI)) (truncate:QI (y:SI))). */
646 if (1
647 && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 && (GET_CODE (op) == PLUS
649 || GET_CODE (op) == MINUS
650 || GET_CODE (op) == MULT))
652 rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 if (op0)
655 rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 if (op1)
657 return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
661 /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
662 to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
663 the outer subreg is effectively a truncation to the original mode. */
664 if ((GET_CODE (op) == LSHIFTRT
665 || GET_CODE (op) == ASHIFTRT)
666 /* Ensure that OP_MODE is at least twice as wide as MODE
667 to avoid the possibility that an outer LSHIFTRT shifts by more
668 than the sign extension's sign_bit_copies and introduces zeros
669 into the high bits of the result. */
670 && 2 * precision <= op_precision
671 && CONST_INT_P (XEXP (op, 1))
672 && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
673 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
674 && UINTVAL (XEXP (op, 1)) < precision)
675 return simplify_gen_binary (ASHIFTRT, mode,
676 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
678 /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
679 to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
680 the outer subreg is effectively a truncation to the original mode. */
681 if ((GET_CODE (op) == LSHIFTRT
682 || GET_CODE (op) == ASHIFTRT)
683 && CONST_INT_P (XEXP (op, 1))
684 && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 && UINTVAL (XEXP (op, 1)) < precision)
687 return simplify_gen_binary (LSHIFTRT, mode,
688 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
690 /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
691 to (ashift:QI (x:QI) C), where C is a suitable small constant and
692 the outer subreg is effectively a truncation to the original mode. */
693 if (GET_CODE (op) == ASHIFT
694 && CONST_INT_P (XEXP (op, 1))
695 && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 && UINTVAL (XEXP (op, 1)) < precision)
699 return simplify_gen_binary (ASHIFT, mode,
700 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
702 /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into
703 (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C
704 and C2. */
705 if (GET_CODE (op) == AND
706 && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 && CONST_INT_P (XEXP (op, 1)))
711 rtx op0 = (XEXP (XEXP (op, 0), 0));
712 rtx shift_op = XEXP (XEXP (op, 0), 1);
713 rtx mask_op = XEXP (op, 1);
714 unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
717 if (shift < precision
718 /* If doing this transform works for an X with all bits set,
719 it works for any X. */
720 && ((GET_MODE_MASK (mode) >> shift) & mask)
721 == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
725 mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 return simplify_gen_binary (AND, mode, op0, mask_op);
730 /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
731 (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
732 changing len. */
733 if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 && REG_P (XEXP (op, 0))
735 && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 && CONST_INT_P (XEXP (op, 1))
737 && CONST_INT_P (XEXP (op, 2)))
739 rtx op0 = XEXP (op, 0);
740 unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
744 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 if (op0)
747 pos -= op_precision - precision;
748 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 XEXP (op, 1), GEN_INT (pos));
752 else if (!BITS_BIG_ENDIAN && precision >= len + pos)
754 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 if (op0)
756 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 XEXP (op, 1), XEXP (op, 2));
761 /* Recognize a word extraction from a multi-word subreg. */
762 if ((GET_CODE (op) == LSHIFTRT
763 || GET_CODE (op) == ASHIFTRT)
764 && SCALAR_INT_MODE_P (mode)
765 && SCALAR_INT_MODE_P (op_mode)
766 && precision >= BITS_PER_WORD
767 && 2 * precision <= op_precision
768 && CONST_INT_P (XEXP (op, 1))
769 && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 && UINTVAL (XEXP (op, 1)) < op_precision)
772 poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 (WORDS_BIG_ENDIAN
776 ? byte - shifted_bytes
777 : byte + shifted_bytes));
780 /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
781 and try replacing the TRUNCATE and shift with it. Don't do this
782 if the MEM has a mode-dependent address. */
783 if ((GET_CODE (op) == LSHIFTRT
784 || GET_CODE (op) == ASHIFTRT)
785 && is_a <scalar_int_mode> (mode, &int_mode)
786 && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 && MEM_P (XEXP (op, 0))
788 && CONST_INT_P (XEXP (op, 1))
789 && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 && INTVAL (XEXP (op, 1)) > 0
791 && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 MEM_ADDR_SPACE (XEXP (op, 0)))
794 && ! MEM_VOLATILE_P (XEXP (op, 0))
795 && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
798 poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 return adjust_address_nv (XEXP (op, 0), int_mode,
801 (WORDS_BIG_ENDIAN
802 ? byte - shifted_bytes
803 : byte + shifted_bytes));
806 /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
807 (OP:SI foo:SI) if OP is NEG or ABS. */
808 if ((GET_CODE (op) == ABS
809 || GET_CODE (op) == NEG)
810 && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 return simplify_gen_unary (GET_CODE (op), mode,
814 XEXP (XEXP (op, 0), 0), mode);
816 /* Simplifications of (truncate:A (subreg:B X 0)). */
817 if (GET_CODE (op) == SUBREG
818 && is_a <scalar_int_mode> (mode, &int_mode)
819 && SCALAR_INT_MODE_P (op_mode)
820 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 && subreg_lowpart_p (op))
823 /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 if (GET_CODE (SUBREG_REG (op)) == TRUNCATE)
826 rtx inner = XEXP (SUBREG_REG (op), 0);
827 if (GET_MODE_PRECISION (int_mode)
828 <= GET_MODE_PRECISION (subreg_mode))
829 return simplify_gen_unary (TRUNCATE, int_mode, inner,
830 GET_MODE (inner));
831 else
832 /* If subreg above is paradoxical and C is narrower
833 than A, return (subreg:A (truncate:C X) 0). */
834 return simplify_gen_subreg (int_mode, SUBREG_REG (op),
835 subreg_mode, 0);
838 /* Simplifications of (truncate:A (subreg:B X:C 0)) with
839 paradoxical subregs (B is wider than C). */
840 if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
842 unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 if (int_op_prec > subreg_prec)
846 if (int_mode == subreg_mode)
847 return SUBREG_REG (op);
848 if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 return simplify_gen_unary (TRUNCATE, int_mode,
850 SUBREG_REG (op), subreg_mode);
852 /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 A is narrower than B and B is narrower than C. */
854 else if (int_op_prec < subreg_prec
855 && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 return simplify_gen_unary (TRUNCATE, int_mode,
857 SUBREG_REG (op), subreg_mode);
861 /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 if (GET_CODE (op) == TRUNCATE)
863 return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
864 GET_MODE (XEXP (op, 0)));
866 /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
867 in mode A. */
868 if (GET_CODE (op) == IOR
869 && SCALAR_INT_MODE_P (mode)
870 && SCALAR_INT_MODE_P (op_mode)
871 && CONST_INT_P (XEXP (op, 1))
872 && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
873 return constm1_rtx;
875 return NULL_RTX;
878 /* Try to simplify a unary operation CODE whose output mode is to be
879 MODE with input operand OP whose mode was originally OP_MODE.
880 Return zero if no simplification can be made. */
882 simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 rtx op, machine_mode op_mode)
885 rtx trueop, tem;
887 trueop = avoid_constant_pool_reference (op);
889 tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 if (tem)
891 return tem;
893 return simplify_unary_operation_1 (code, mode, op);
896 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
897 to be exact. */
899 static bool
900 exact_int_to_float_conversion_p (const_rtx op)
902 machine_mode op0_mode = GET_MODE (XEXP (op, 0));
903 /* Constants can reach here with -frounding-math, if they do then
904 the conversion isn't exact. */
905 if (op0_mode == VOIDmode)
906 return false;
907 int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 int in_bits = in_prec;
910 if (HWI_COMPUTABLE_MODE_P (op0_mode))
912 unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 if (GET_CODE (op) == FLOAT)
914 in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 else
918 gcc_unreachable ();
919 in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
921 return in_bits <= out_bits;
924 /* Perform some simplifications we can do even if the operands
925 aren't constant. */
927 simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 rtx op)
930 enum rtx_code reversed;
931 rtx temp, elt, base, step;
932 scalar_int_mode inner, int_mode, op_mode, op0_mode;
934 switch (code)
936 case NOT:
937 /* (not (not X)) == X. */
938 if (GET_CODE (op) == NOT)
939 return XEXP (op, 0);
941 /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
942 comparison is all ones. */
943 if (COMPARISON_P (op)
944 && (mode == BImode || STORE_FLAG_VALUE == -1)
945 && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
946 return simplify_gen_relational (reversed, mode, VOIDmode,
947 XEXP (op, 0), XEXP (op, 1));
949 /* (not (plus X -1)) can become (neg X). */
950 if (GET_CODE (op) == PLUS
951 && XEXP (op, 1) == constm1_rtx)
952 return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
954 /* Similarly, (not (neg X)) is (plus X -1). Only do this for
955 modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
956 and MODE_VECTOR_INT. */
957 if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 CONSTM1_RTX (mode));
961 /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 if (GET_CODE (op) == XOR
963 && CONST_INT_P (XEXP (op, 1))
964 && (temp = simplify_unary_operation (NOT, mode,
965 XEXP (op, 1), mode)) != 0)
966 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
968 /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
969 if (GET_CODE (op) == PLUS
970 && CONST_INT_P (XEXP (op, 1))
971 && mode_signbit_p (mode, XEXP (op, 1))
972 && (temp = simplify_unary_operation (NOT, mode,
973 XEXP (op, 1), mode)) != 0)
974 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
977 /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
978 operands other than 1, but that is not valid. We could do a
979 similar simplification for (not (lshiftrt C X)) where C is
980 just the sign bit, but this doesn't seem common enough to
981 bother with. */
982 if (GET_CODE (op) == ASHIFT
983 && XEXP (op, 0) == const1_rtx)
985 temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
989 /* (not (ashiftrt foo C)) where C is the number of bits in FOO
990 minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
991 so we can perform the above simplification. */
992 if (STORE_FLAG_VALUE == -1
993 && is_a <scalar_int_mode> (mode, &int_mode)
994 && GET_CODE (op) == ASHIFTRT
995 && CONST_INT_P (XEXP (op, 1))
996 && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
997 return simplify_gen_relational (GE, int_mode, VOIDmode,
998 XEXP (op, 0), const0_rtx);
1001 if (partial_subreg_p (op)
1002 && subreg_lowpart_p (op)
1003 && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1006 machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1007 rtx x;
1009 x = gen_rtx_ROTATE (inner_mode,
1010 simplify_gen_unary (NOT, inner_mode, const1_rtx,
1011 inner_mode),
1012 XEXP (SUBREG_REG (op), 1));
1013 temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1014 if (temp)
1015 return temp;
1018 /* Apply De Morgan's laws to reduce number of patterns for machines
1019 with negating logical insns (and-not, nand, etc.). If result has
1020 only one NOT, put it first, since that is how the patterns are
1021 coded. */
1022 if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1024 rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 machine_mode op_mode;
1027 op_mode = GET_MODE (in1);
1028 in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1030 op_mode = GET_MODE (in2);
1031 if (op_mode == VOIDmode)
1032 op_mode = mode;
1033 in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1035 if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 std::swap (in1, in2);
1038 return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1039 mode, in1, in2);
1042 /* (not (bswap x)) -> (bswap (not x)). */
1043 if (GET_CODE (op) == BSWAP)
1045 rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1046 return simplify_gen_unary (BSWAP, mode, x, mode);
1048 break;
1050 case NEG:
1051 /* (neg (neg X)) == X. */
1052 if (GET_CODE (op) == NEG)
1053 return XEXP (op, 0);
1055 /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1056 If comparison is not reversible use
1057 x ? y : (neg y). */
1058 if (GET_CODE (op) == IF_THEN_ELSE)
1060 rtx cond = XEXP (op, 0);
1061 rtx true_rtx = XEXP (op, 1);
1062 rtx false_rtx = XEXP (op, 2);
1064 if ((GET_CODE (true_rtx) == NEG
1065 && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 || (GET_CODE (false_rtx) == NEG
1067 && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1069 if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1070 temp = reversed_comparison (cond, mode);
1071 else
1073 temp = cond;
1074 std::swap (true_rtx, false_rtx);
1076 return simplify_gen_ternary (IF_THEN_ELSE, mode,
1077 mode, temp, true_rtx, false_rtx);
1081 /* (neg (plus X 1)) can become (not X). */
1082 if (GET_CODE (op) == PLUS
1083 && XEXP (op, 1) == const1_rtx)
1084 return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1086 /* Similarly, (neg (not X)) is (plus X 1). */
1087 if (GET_CODE (op) == NOT)
1088 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 CONST1_RTX (mode));
1091 /* (neg (minus X Y)) can become (minus Y X). This transformation
1092 isn't safe for modes with signed zeros, since if X and Y are
1093 both +0, (minus Y X) is the same as (minus X Y). If the
1094 rounding mode is towards +infinity (or -infinity) then the two
1095 expressions will be rounded differently. */
1096 if (GET_CODE (op) == MINUS
1097 && !HONOR_SIGNED_ZEROS (mode)
1098 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1101 if (GET_CODE (op) == PLUS
1102 && !HONOR_SIGNED_ZEROS (mode)
1103 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1105 /* (neg (plus A C)) is simplified to (minus -C A). */
1106 if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1109 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 if (temp)
1111 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1114 /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1115 temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1119 /* (neg (mult A B)) becomes (mult A (neg B)).
1120 This works even for floating-point values. */
1121 if (GET_CODE (op) == MULT
1122 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1124 temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1128 /* NEG commutes with ASHIFT since it is multiplication. Only do
1129 this if we can then eliminate the NEG (e.g., if the operand
1130 is a constant). */
1131 if (GET_CODE (op) == ASHIFT)
1133 temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 if (temp)
1135 return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1138 /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1139 C is equal to the width of MODE minus 1. */
1140 if (GET_CODE (op) == ASHIFTRT
1141 && CONST_INT_P (XEXP (op, 1))
1142 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1143 return simplify_gen_binary (LSHIFTRT, mode,
1144 XEXP (op, 0), XEXP (op, 1));
1146 /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1147 C is equal to the width of MODE minus 1. */
1148 if (GET_CODE (op) == LSHIFTRT
1149 && CONST_INT_P (XEXP (op, 1))
1150 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 return simplify_gen_binary (ASHIFTRT, mode,
1152 XEXP (op, 0), XEXP (op, 1));
1154 /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1155 if (GET_CODE (op) == XOR
1156 && XEXP (op, 1) == const1_rtx
1157 && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 return plus_constant (mode, XEXP (op, 0), -1);
1160 /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1161 /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1162 if (GET_CODE (op) == LT
1163 && XEXP (op, 1) == const0_rtx
1164 && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1166 int_mode = as_a <scalar_int_mode> (mode);
1167 int isize = GET_MODE_PRECISION (inner);
1168 if (STORE_FLAG_VALUE == 1)
1170 temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1171 gen_int_shift_amount (inner,
1172 isize - 1));
1173 if (int_mode == inner)
1174 return temp;
1175 if (GET_MODE_PRECISION (int_mode) > isize)
1176 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1177 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1179 else if (STORE_FLAG_VALUE == -1)
1181 temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1182 gen_int_shift_amount (inner,
1183 isize - 1));
1184 if (int_mode == inner)
1185 return temp;
1186 if (GET_MODE_PRECISION (int_mode) > isize)
1187 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1188 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1192 if (vec_series_p (op, &base, &step))
1194 /* Only create a new series if we can simplify both parts. In other
1195 cases this isn't really a simplification, and it's not necessarily
1196 a win to replace a vector operation with a scalar operation. */
1197 scalar_mode inner_mode = GET_MODE_INNER (mode);
1198 base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1199 if (base)
1201 step = simplify_unary_operation (NEG, inner_mode,
1202 step, inner_mode);
1203 if (step)
1204 return gen_vec_series (mode, base, step);
1207 break;
1209 case TRUNCATE:
1210 /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 with the umulXi3_highpart patterns. */
1212 if (GET_CODE (op) == LSHIFTRT
1213 && GET_CODE (XEXP (op, 0)) == MULT)
1214 break;
1216 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1218 if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1220 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1221 if (temp)
1222 return temp;
1224 /* We can't handle truncation to a partial integer mode here
1225 because we don't know the real bitsize of the partial
1226 integer mode. */
1227 break;
1230 if (GET_MODE (op) != VOIDmode)
1232 temp = simplify_truncation (mode, op, GET_MODE (op));
1233 if (temp)
1234 return temp;
1237 /* If we know that the value is already truncated, we can
1238 replace the TRUNCATE with a SUBREG. */
1239 if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 || truncated_to_mode (mode, op)))
1243 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 if (temp)
1245 return temp;
1248 /* A truncate of a comparison can be replaced with a subreg if
1249 STORE_FLAG_VALUE permits. This is like the previous test,
1250 but it works even if the comparison is done in a mode larger
1251 than HOST_BITS_PER_WIDE_INT. */
1252 if (HWI_COMPUTABLE_MODE_P (mode)
1253 && COMPARISON_P (op)
1254 && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1257 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1258 if (temp)
1259 return temp;
1262 /* A truncate of a memory is just loading the low part of the memory
1263 if we are not changing the meaning of the address. */
1264 if (GET_CODE (op) == MEM
1265 && !VECTOR_MODE_P (mode)
1266 && !MEM_VOLATILE_P (op)
1267 && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1269 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 if (temp)
1271 return temp;
1274 /* Check for useless truncation. */
1275 if (GET_MODE (op) == mode)
1276 return op;
1277 break;
1279 case FLOAT_TRUNCATE:
1280 /* Check for useless truncation. */
1281 if (GET_MODE (op) == mode)
1282 return op;
1284 if (DECIMAL_FLOAT_MODE_P (mode))
1285 break;
1287 /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 if (GET_CODE (op) == FLOAT_EXTEND
1289 && GET_MODE (XEXP (op, 0)) == mode)
1290 return XEXP (op, 0);
1292 /* (float_truncate:SF (float_truncate:DF foo:XF))
1293 = (float_truncate:SF foo:XF).
1294 This may eliminate double rounding, so it is unsafe.
1296 (float_truncate:SF (float_extend:XF foo:DF))
1297 = (float_truncate:SF foo:DF).
1299 (float_truncate:DF (float_extend:XF foo:SF))
1300 = (float_extend:DF foo:SF). */
1301 if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 && flag_unsafe_math_optimizations)
1303 || GET_CODE (op) == FLOAT_EXTEND)
1304 return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1305 > GET_MODE_UNIT_SIZE (mode)
1306 ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1307 mode,
1308 XEXP (op, 0), mode);
1310 /* (float_truncate (float x)) is (float x) */
1311 if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 && (flag_unsafe_math_optimizations
1313 || exact_int_to_float_conversion_p (op)))
1314 return simplify_gen_unary (GET_CODE (op), mode,
1315 XEXP (op, 0),
1316 GET_MODE (XEXP (op, 0)));
1318 /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1319 (OP:SF foo:SF) if OP is NEG or ABS. */
1320 if ((GET_CODE (op) == ABS
1321 || GET_CODE (op) == NEG)
1322 && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1323 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1324 return simplify_gen_unary (GET_CODE (op), mode,
1325 XEXP (XEXP (op, 0), 0), mode);
1327 /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1328 is (float_truncate:SF x). */
1329 if (GET_CODE (op) == SUBREG
1330 && subreg_lowpart_p (op)
1331 && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 return SUBREG_REG (op);
1333 break;
1335 case FLOAT_EXTEND:
1336 /* Check for useless extension. */
1337 if (GET_MODE (op) == mode)
1338 return op;
1340 if (DECIMAL_FLOAT_MODE_P (mode))
1341 break;
1343 /* (float_extend (float_extend x)) is (float_extend x)
1345 (float_extend (float x)) is (float x) assuming that double
1346 rounding can't happen.
1348 if (GET_CODE (op) == FLOAT_EXTEND
1349 || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 && exact_int_to_float_conversion_p (op)))
1351 return simplify_gen_unary (GET_CODE (op), mode,
1352 XEXP (op, 0),
1353 GET_MODE (XEXP (op, 0)));
1355 break;
1357 case ABS:
1358 /* (abs (neg <foo>)) -> (abs <foo>) */
1359 if (GET_CODE (op) == NEG)
1360 return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1361 GET_MODE (XEXP (op, 0)));
1363 /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1364 do nothing. */
1365 if (GET_MODE (op) == VOIDmode)
1366 break;
1368 /* If operand is something known to be positive, ignore the ABS. */
1369 if (val_signbit_known_clear_p (GET_MODE (op),
1370 nonzero_bits (op, GET_MODE (op))))
1371 return op;
1373 /* Using nonzero_bits doesn't (currently) work for modes wider than
1374 HOST_WIDE_INT, so the following transformations help simplify
1375 ABS for TImode and wider. */
1376 switch (GET_CODE (op))
1378 case ABS:
1379 case CLRSB:
1380 case FFS:
1381 case PARITY:
1382 case POPCOUNT:
1383 case SS_ABS:
1384 return op;
1386 case LSHIFTRT:
1387 if (CONST_INT_P (XEXP (op, 1))
1388 && INTVAL (XEXP (op, 1)) > 0
1389 && is_a <scalar_int_mode> (mode, &int_mode)
1390 && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1391 return op;
1392 break;
1394 default:
1395 break;
1398 /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1399 if (is_a <scalar_int_mode> (mode, &int_mode)
1400 && (num_sign_bit_copies (op, int_mode)
1401 == GET_MODE_PRECISION (int_mode)))
1402 return gen_rtx_NEG (int_mode, op);
1404 break;
1406 case FFS:
1407 /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1408 if (GET_CODE (op) == SIGN_EXTEND
1409 || GET_CODE (op) == ZERO_EXTEND)
1411 temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1412 XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1413 return simplify_gen_unary (GET_CODE (op), mode, temp,
1414 GET_MODE (temp));
1416 break;
1418 case POPCOUNT:
1419 switch (GET_CODE (op))
1421 case BSWAP:
1422 /* (popcount (bswap <X>)) = (popcount <X>). */
1423 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1424 GET_MODE (XEXP (op, 0)));
1426 case ZERO_EXTEND:
1427 /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1428 temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1429 XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1430 return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1431 GET_MODE (temp));
1433 case ROTATE:
1434 case ROTATERT:
1435 /* Rotations don't affect popcount. */
1436 if (!side_effects_p (XEXP (op, 1)))
1437 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1438 GET_MODE (XEXP (op, 0)));
1439 break;
1441 default:
1442 break;
1444 break;
1446 case PARITY:
1447 switch (GET_CODE (op))
1449 case NOT:
1450 case BSWAP:
1451 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1452 GET_MODE (XEXP (op, 0)));
1454 case ZERO_EXTEND:
1455 case SIGN_EXTEND:
1456 temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1457 XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1458 return simplify_gen_unary (GET_CODE (op), mode, temp,
1459 GET_MODE (temp));
1461 case ROTATE:
1462 case ROTATERT:
1463 /* Rotations don't affect parity. */
1464 if (!side_effects_p (XEXP (op, 1)))
1465 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1466 GET_MODE (XEXP (op, 0)));
1467 break;
1469 case PARITY:
1470 /* (parity (parity x)) -> parity (x). */
1471 return op;
1473 default:
1474 break;
1476 break;
1478 case BSWAP:
1479 /* (bswap (bswap x)) -> x. */
1480 if (GET_CODE (op) == BSWAP)
1481 return XEXP (op, 0);
1482 break;
1484 case FLOAT:
1485 /* (float (sign_extend <X>)) = (float <X>). */
1486 if (GET_CODE (op) == SIGN_EXTEND)
1487 return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1488 GET_MODE (XEXP (op, 0)));
1489 break;
1491 case SIGN_EXTEND:
1492 /* Check for useless extension. */
1493 if (GET_MODE (op) == mode)
1494 return op;
1496 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1497 becomes just the MINUS if its mode is MODE. This allows
1498 folding switch statements on machines using casesi (such as
1499 the VAX). */
1500 if (GET_CODE (op) == TRUNCATE
1501 && GET_MODE (XEXP (op, 0)) == mode
1502 && GET_CODE (XEXP (op, 0)) == MINUS
1503 && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1504 && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1505 return XEXP (op, 0);
1507 /* Extending a widening multiplication should be canonicalized to
1508 a wider widening multiplication. */
1509 if (GET_CODE (op) == MULT)
1511 rtx lhs = XEXP (op, 0);
1512 rtx rhs = XEXP (op, 1);
1513 enum rtx_code lcode = GET_CODE (lhs);
1514 enum rtx_code rcode = GET_CODE (rhs);
1516 /* Widening multiplies usually extend both operands, but sometimes
1517 they use a shift to extract a portion of a register. */
1518 if ((lcode == SIGN_EXTEND
1519 || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1520 && (rcode == SIGN_EXTEND
1521 || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1523 machine_mode lmode = GET_MODE (lhs);
1524 machine_mode rmode = GET_MODE (rhs);
1525 int bits;
1527 if (lcode == ASHIFTRT)
1528 /* Number of bits not shifted off the end. */
1529 bits = (GET_MODE_UNIT_PRECISION (lmode)
1530 - INTVAL (XEXP (lhs, 1)));
1531 else /* lcode == SIGN_EXTEND */
1532 /* Size of inner mode. */
1533 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1535 if (rcode == ASHIFTRT)
1536 bits += (GET_MODE_UNIT_PRECISION (rmode)
1537 - INTVAL (XEXP (rhs, 1)));
1538 else /* rcode == SIGN_EXTEND */
1539 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1541 /* We can only widen multiplies if the result is mathematiclly
1542 equivalent. I.e. if overflow was impossible. */
1543 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1544 return simplify_gen_binary
1545 (MULT, mode,
1546 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1547 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1551 /* Check for a sign extension of a subreg of a promoted
1552 variable, where the promotion is sign-extended, and the
1553 target mode is the same as the variable's promotion. */
1554 if (GET_CODE (op) == SUBREG
1555 && SUBREG_PROMOTED_VAR_P (op)
1556 && SUBREG_PROMOTED_SIGNED_P (op))
1558 rtx subreg = SUBREG_REG (op);
1559 machine_mode subreg_mode = GET_MODE (subreg);
1560 if (!paradoxical_subreg_p (mode, subreg_mode))
1562 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1563 if (temp)
1565 /* Preserve SUBREG_PROMOTED_VAR_P. */
1566 if (partial_subreg_p (temp))
1568 SUBREG_PROMOTED_VAR_P (temp) = 1;
1569 SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1571 return temp;
1574 else
1575 /* Sign-extending a sign-extended subreg. */
1576 return simplify_gen_unary (SIGN_EXTEND, mode,
1577 subreg, subreg_mode);
1580 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1581 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1582 if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1584 gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1585 > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1586 return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1587 GET_MODE (XEXP (op, 0)));
1590 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1591 is (sign_extend:M (subreg:O <X>)) if there is mode with
1592 GET_MODE_BITSIZE (N) - I bits.
1593 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1594 is similarly (zero_extend:M (subreg:O <X>)). */
1595 if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1596 && GET_CODE (XEXP (op, 0)) == ASHIFT
1597 && is_a <scalar_int_mode> (mode, &int_mode)
1598 && CONST_INT_P (XEXP (op, 1))
1599 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1600 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1601 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1603 scalar_int_mode tmode;
1604 gcc_assert (GET_MODE_PRECISION (int_mode)
1605 > GET_MODE_PRECISION (op_mode));
1606 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1607 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1609 rtx inner =
1610 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1611 if (inner)
1612 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1613 ? SIGN_EXTEND : ZERO_EXTEND,
1614 int_mode, inner, tmode);
1618 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1619 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1620 if (GET_CODE (op) == LSHIFTRT
1621 && CONST_INT_P (XEXP (op, 1))
1622 && XEXP (op, 1) != const0_rtx)
1623 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1625 /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1626 I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1627 (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1628 (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1629 O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1630 wider than O. */
1631 if (GET_CODE (op) == TRUNCATE
1632 && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1633 && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1635 scalar_int_mode m_mode, n_mode, o_mode;
1636 rtx old_shift = XEXP (op, 0);
1637 if (is_a <scalar_int_mode> (mode, &m_mode)
1638 && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1639 && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1640 && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1641 == INTVAL (XEXP (old_shift, 1)))
1643 rtx new_shift = simplify_gen_binary (ASHIFTRT,
1644 GET_MODE (old_shift),
1645 XEXP (old_shift, 0),
1646 XEXP (old_shift, 1));
1647 if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1648 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1649 GET_MODE (new_shift));
1650 if (mode != GET_MODE (new_shift))
1651 return simplify_gen_unary (TRUNCATE, mode, new_shift,
1652 GET_MODE (new_shift));
1653 return new_shift;
1657 /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1658 we know the sign bit of OP must be clear. */
1659 if (val_signbit_known_clear_p (GET_MODE (op),
1660 nonzero_bits (op, GET_MODE (op))))
1661 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1663 /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1664 if (GET_CODE (op) == SUBREG
1665 && subreg_lowpart_p (op)
1666 && GET_MODE (SUBREG_REG (op)) == mode
1667 && is_a <scalar_int_mode> (mode, &int_mode)
1668 && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1669 && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1670 && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1671 && (nonzero_bits (SUBREG_REG (op), mode)
1672 & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1673 return SUBREG_REG (op);
1675 #if defined(POINTERS_EXTEND_UNSIGNED)
1676 /* As we do not know which address space the pointer is referring to,
1677 we can do this only if the target does not support different pointer
1678 or address modes depending on the address space. */
1679 if (target_default_pointer_address_modes_p ()
1680 && ! POINTERS_EXTEND_UNSIGNED
1681 && mode == Pmode && GET_MODE (op) == ptr_mode
1682 && (CONSTANT_P (op)
1683 || (GET_CODE (op) == SUBREG
1684 && REG_P (SUBREG_REG (op))
1685 && REG_POINTER (SUBREG_REG (op))
1686 && GET_MODE (SUBREG_REG (op)) == Pmode))
1687 && !targetm.have_ptr_extend ())
1689 temp
1690 = convert_memory_address_addr_space_1 (Pmode, op,
1691 ADDR_SPACE_GENERIC, false,
1692 true);
1693 if (temp)
1694 return temp;
1696 #endif
1697 break;
1699 case ZERO_EXTEND:
1700 /* Check for useless extension. */
1701 if (GET_MODE (op) == mode)
1702 return op;
1704 /* Check for a zero extension of a subreg of a promoted
1705 variable, where the promotion is zero-extended, and the
1706 target mode is the same as the variable's promotion. */
1707 if (GET_CODE (op) == SUBREG
1708 && SUBREG_PROMOTED_VAR_P (op)
1709 && SUBREG_PROMOTED_UNSIGNED_P (op))
1711 rtx subreg = SUBREG_REG (op);
1712 machine_mode subreg_mode = GET_MODE (subreg);
1713 if (!paradoxical_subreg_p (mode, subreg_mode))
1715 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1716 if (temp)
1718 /* Preserve SUBREG_PROMOTED_VAR_P. */
1719 if (partial_subreg_p (temp))
1721 SUBREG_PROMOTED_VAR_P (temp) = 1;
1722 SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1724 return temp;
1727 else
1728 /* Zero-extending a zero-extended subreg. */
1729 return simplify_gen_unary (ZERO_EXTEND, mode,
1730 subreg, subreg_mode);
1733 /* Extending a widening multiplication should be canonicalized to
1734 a wider widening multiplication. */
1735 if (GET_CODE (op) == MULT)
1737 rtx lhs = XEXP (op, 0);
1738 rtx rhs = XEXP (op, 1);
1739 enum rtx_code lcode = GET_CODE (lhs);
1740 enum rtx_code rcode = GET_CODE (rhs);
1742 /* Widening multiplies usually extend both operands, but sometimes
1743 they use a shift to extract a portion of a register. */
1744 if ((lcode == ZERO_EXTEND
1745 || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1746 && (rcode == ZERO_EXTEND
1747 || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1749 machine_mode lmode = GET_MODE (lhs);
1750 machine_mode rmode = GET_MODE (rhs);
1751 int bits;
1753 if (lcode == LSHIFTRT)
1754 /* Number of bits not shifted off the end. */
1755 bits = (GET_MODE_UNIT_PRECISION (lmode)
1756 - INTVAL (XEXP (lhs, 1)));
1757 else /* lcode == ZERO_EXTEND */
1758 /* Size of inner mode. */
1759 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1761 if (rcode == LSHIFTRT)
1762 bits += (GET_MODE_UNIT_PRECISION (rmode)
1763 - INTVAL (XEXP (rhs, 1)));
1764 else /* rcode == ZERO_EXTEND */
1765 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1767 /* We can only widen multiplies if the result is mathematiclly
1768 equivalent. I.e. if overflow was impossible. */
1769 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1770 return simplify_gen_binary
1771 (MULT, mode,
1772 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1773 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1777 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1778 if (GET_CODE (op) == ZERO_EXTEND)
1779 return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1780 GET_MODE (XEXP (op, 0)));
1782 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1783 is (zero_extend:M (subreg:O <X>)) if there is mode with
1784 GET_MODE_PRECISION (N) - I bits. */
1785 if (GET_CODE (op) == LSHIFTRT
1786 && GET_CODE (XEXP (op, 0)) == ASHIFT
1787 && is_a <scalar_int_mode> (mode, &int_mode)
1788 && CONST_INT_P (XEXP (op, 1))
1789 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1790 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1791 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1793 scalar_int_mode tmode;
1794 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1795 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1797 rtx inner =
1798 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1799 if (inner)
1800 return simplify_gen_unary (ZERO_EXTEND, int_mode,
1801 inner, tmode);
1805 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1806 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1807 of mode N. E.g.
1808 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1809 (and:SI (reg:SI) (const_int 63)). */
1810 if (partial_subreg_p (op)
1811 && is_a <scalar_int_mode> (mode, &int_mode)
1812 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1813 && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1814 && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1815 && subreg_lowpart_p (op)
1816 && (nonzero_bits (SUBREG_REG (op), op0_mode)
1817 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1819 if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1820 return SUBREG_REG (op);
1821 return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1822 op0_mode);
1825 /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1826 if (GET_CODE (op) == SUBREG
1827 && subreg_lowpart_p (op)
1828 && GET_MODE (SUBREG_REG (op)) == mode
1829 && is_a <scalar_int_mode> (mode, &int_mode)
1830 && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1831 && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1832 && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1833 && (nonzero_bits (SUBREG_REG (op), mode)
1834 & ~GET_MODE_MASK (op_mode)) == 0)
1835 return SUBREG_REG (op);
1837 #if defined(POINTERS_EXTEND_UNSIGNED)
1838 /* As we do not know which address space the pointer is referring to,
1839 we can do this only if the target does not support different pointer
1840 or address modes depending on the address space. */
1841 if (target_default_pointer_address_modes_p ()
1842 && POINTERS_EXTEND_UNSIGNED > 0
1843 && mode == Pmode && GET_MODE (op) == ptr_mode
1844 && (CONSTANT_P (op)
1845 || (GET_CODE (op) == SUBREG
1846 && REG_P (SUBREG_REG (op))
1847 && REG_POINTER (SUBREG_REG (op))
1848 && GET_MODE (SUBREG_REG (op)) == Pmode))
1849 && !targetm.have_ptr_extend ())
1851 temp
1852 = convert_memory_address_addr_space_1 (Pmode, op,
1853 ADDR_SPACE_GENERIC, false,
1854 true);
1855 if (temp)
1856 return temp;
1858 #endif
1859 break;
1861 default:
1862 break;
1865 if (VECTOR_MODE_P (mode)
1866 && vec_duplicate_p (op, &elt)
1867 && code != VEC_DUPLICATE)
1869 if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1870 /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1871 operations by promoting VEC_DUPLICATE to the root of the expression
1872 (as far as possible). */
1873 temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1874 elt, GET_MODE_INNER (GET_MODE (op)));
1875 else
1876 /* Try applying the operator to ELT and see if that simplifies.
1877 We can duplicate the result if so.
1879 The reason we traditionally haven't used simplify_gen_unary
1880 for these codes is that it didn't necessarily seem to be a
1881 win to convert things like:
1883 (neg:V (vec_duplicate:V (reg:S R)))
1887 (vec_duplicate:V (neg:S (reg:S R)))
1889 The first might be done entirely in vector registers while the
1890 second might need a move between register files.
1892 However, there also cases where promoting the vec_duplicate is
1893 more efficient, and there is definite value in having a canonical
1894 form when matching instruction patterns. We should consider
1895 extending the simplify_gen_unary code above to more cases. */
1896 temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1897 elt, GET_MODE_INNER (GET_MODE (op)));
1898 if (temp)
1899 return gen_vec_duplicate (mode, temp);
1902 return 0;
1905 /* Try to compute the value of a unary operation CODE whose output mode is to
1906 be MODE with input operand OP whose mode was originally OP_MODE.
1907 Return zero if the value cannot be computed. */
1909 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1910 rtx op, machine_mode op_mode)
1912 scalar_int_mode result_mode;
1914 if (code == VEC_DUPLICATE)
1916 gcc_assert (VECTOR_MODE_P (mode));
1917 if (GET_MODE (op) != VOIDmode)
1919 if (!VECTOR_MODE_P (GET_MODE (op)))
1920 gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1921 else
1922 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1923 (GET_MODE (op)));
1925 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1926 return gen_const_vec_duplicate (mode, op);
1927 if (GET_CODE (op) == CONST_VECTOR
1928 && (CONST_VECTOR_DUPLICATE_P (op)
1929 || CONST_VECTOR_NUNITS (op).is_constant ()))
1931 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1932 ? CONST_VECTOR_NPATTERNS (op)
1933 : CONST_VECTOR_NUNITS (op).to_constant ());
1934 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1935 rtx_vector_builder builder (mode, npatterns, 1);
1936 for (unsigned i = 0; i < npatterns; i++)
1937 builder.quick_push (CONST_VECTOR_ELT (op, i));
1938 return builder.build ();
1942 if (VECTOR_MODE_P (mode)
1943 && GET_CODE (op) == CONST_VECTOR
1944 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1946 gcc_assert (GET_MODE (op) == op_mode);
1948 rtx_vector_builder builder;
1949 if (!builder.new_unary_operation (mode, op, false))
1950 return 0;
1952 unsigned int count = builder.encoded_nelts ();
1953 for (unsigned int i = 0; i < count; i++)
1955 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1956 CONST_VECTOR_ELT (op, i),
1957 GET_MODE_INNER (op_mode));
1958 if (!x || !valid_for_const_vector_p (mode, x))
1959 return 0;
1960 builder.quick_push (x);
1962 return builder.build ();
1965 /* The order of these tests is critical so that, for example, we don't
1966 check the wrong mode (input vs. output) for a conversion operation,
1967 such as FIX. At some point, this should be simplified. */
1969 if (code == FLOAT && CONST_SCALAR_INT_P (op))
1971 REAL_VALUE_TYPE d;
1973 if (op_mode == VOIDmode)
1975 /* CONST_INT have VOIDmode as the mode. We assume that all
1976 the bits of the constant are significant, though, this is
1977 a dangerous assumption as many times CONST_INTs are
1978 created and used with garbage in the bits outside of the
1979 precision of the implied mode of the const_int. */
1980 op_mode = MAX_MODE_INT;
1983 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1985 /* Avoid the folding if flag_signaling_nans is on and
1986 operand is a signaling NaN. */
1987 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1988 return 0;
1990 d = real_value_truncate (mode, d);
1992 /* Avoid the folding if flag_rounding_math is on and the
1993 conversion is not exact. */
1994 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1996 bool fail = false;
1997 wide_int w = real_to_integer (&d, &fail,
1998 GET_MODE_PRECISION
1999 (as_a <scalar_int_mode> (op_mode)));
2000 if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2001 return 0;
2004 return const_double_from_real_value (d, mode);
2006 else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2008 REAL_VALUE_TYPE d;
2010 if (op_mode == VOIDmode)
2012 /* CONST_INT have VOIDmode as the mode. We assume that all
2013 the bits of the constant are significant, though, this is
2014 a dangerous assumption as many times CONST_INTs are
2015 created and used with garbage in the bits outside of the
2016 precision of the implied mode of the const_int. */
2017 op_mode = MAX_MODE_INT;
2020 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2022 /* Avoid the folding if flag_signaling_nans is on and
2023 operand is a signaling NaN. */
2024 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2025 return 0;
2027 d = real_value_truncate (mode, d);
2029 /* Avoid the folding if flag_rounding_math is on and the
2030 conversion is not exact. */
2031 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2033 bool fail = false;
2034 wide_int w = real_to_integer (&d, &fail,
2035 GET_MODE_PRECISION
2036 (as_a <scalar_int_mode> (op_mode)));
2037 if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2038 return 0;
2041 return const_double_from_real_value (d, mode);
2044 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2046 unsigned int width = GET_MODE_PRECISION (result_mode);
2047 if (width > MAX_BITSIZE_MODE_ANY_INT)
2048 return 0;
2050 wide_int result;
2051 scalar_int_mode imode = (op_mode == VOIDmode
2052 ? result_mode
2053 : as_a <scalar_int_mode> (op_mode));
2054 rtx_mode_t op0 = rtx_mode_t (op, imode);
2055 int int_value;
2057 #if TARGET_SUPPORTS_WIDE_INT == 0
2058 /* This assert keeps the simplification from producing a result
2059 that cannot be represented in a CONST_DOUBLE but a lot of
2060 upstream callers expect that this function never fails to
2061 simplify something and so you if you added this to the test
2062 above the code would die later anyway. If this assert
2063 happens, you just need to make the port support wide int. */
2064 gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2065 #endif
2067 switch (code)
2069 case NOT:
2070 result = wi::bit_not (op0);
2071 break;
2073 case NEG:
2074 result = wi::neg (op0);
2075 break;
2077 case ABS:
2078 result = wi::abs (op0);
2079 break;
2081 case FFS:
2082 result = wi::shwi (wi::ffs (op0), result_mode);
2083 break;
2085 case CLZ:
2086 if (wi::ne_p (op0, 0))
2087 int_value = wi::clz (op0);
2088 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2089 return NULL_RTX;
2090 result = wi::shwi (int_value, result_mode);
2091 break;
2093 case CLRSB:
2094 result = wi::shwi (wi::clrsb (op0), result_mode);
2095 break;
2097 case CTZ:
2098 if (wi::ne_p (op0, 0))
2099 int_value = wi::ctz (op0);
2100 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2101 return NULL_RTX;
2102 result = wi::shwi (int_value, result_mode);
2103 break;
2105 case POPCOUNT:
2106 result = wi::shwi (wi::popcount (op0), result_mode);
2107 break;
2109 case PARITY:
2110 result = wi::shwi (wi::parity (op0), result_mode);
2111 break;
2113 case BSWAP:
2114 result = wi::bswap (op0);
2115 break;
2117 case TRUNCATE:
2118 case ZERO_EXTEND:
2119 result = wide_int::from (op0, width, UNSIGNED);
2120 break;
2122 case SIGN_EXTEND:
2123 result = wide_int::from (op0, width, SIGNED);
2124 break;
2126 case SS_NEG:
2127 if (wi::only_sign_bit_p (op0))
2128 result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2129 else
2130 result = wi::neg (op0);
2131 break;
2133 case SS_ABS:
2134 if (wi::only_sign_bit_p (op0))
2135 result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2136 else
2137 result = wi::abs (op0);
2138 break;
2140 case SQRT:
2141 default:
2142 return 0;
2145 return immed_wide_int_const (result, result_mode);
2148 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2149 && SCALAR_FLOAT_MODE_P (mode)
2150 && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2152 REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2153 switch (code)
2155 case SQRT:
2156 return 0;
2157 case ABS:
2158 d = real_value_abs (&d);
2159 break;
2160 case NEG:
2161 d = real_value_negate (&d);
2162 break;
2163 case FLOAT_TRUNCATE:
2164 /* Don't perform the operation if flag_signaling_nans is on
2165 and the operand is a signaling NaN. */
2166 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2167 return NULL_RTX;
2168 /* Or if flag_rounding_math is on and the truncation is not
2169 exact. */
2170 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2171 && !exact_real_truncate (mode, &d))
2172 return NULL_RTX;
2173 d = real_value_truncate (mode, d);
2174 break;
2175 case FLOAT_EXTEND:
2176 /* Don't perform the operation if flag_signaling_nans is on
2177 and the operand is a signaling NaN. */
2178 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2179 return NULL_RTX;
2180 /* All this does is change the mode, unless changing
2181 mode class. */
2182 if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2183 real_convert (&d, mode, &d);
2184 break;
2185 case FIX:
2186 /* Don't perform the operation if flag_signaling_nans is on
2187 and the operand is a signaling NaN. */
2188 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2189 return NULL_RTX;
2190 real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2191 break;
2192 case NOT:
2194 long tmp[4];
2195 int i;
2197 real_to_target (tmp, &d, GET_MODE (op));
2198 for (i = 0; i < 4; i++)
2199 tmp[i] = ~tmp[i];
2200 real_from_target (&d, tmp, mode);
2201 break;
2203 default:
2204 gcc_unreachable ();
2206 return const_double_from_real_value (d, mode);
2208 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2209 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2210 && is_int_mode (mode, &result_mode))
2212 unsigned int width = GET_MODE_PRECISION (result_mode);
2213 if (width > MAX_BITSIZE_MODE_ANY_INT)
2214 return 0;
2216 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2217 operators are intentionally left unspecified (to ease implementation
2218 by target backends), for consistency, this routine implements the
2219 same semantics for constant folding as used by the middle-end. */
2221 /* This was formerly used only for non-IEEE float.
2222 eggert@twinsun.com says it is safe for IEEE also. */
2223 REAL_VALUE_TYPE t;
2224 const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2225 wide_int wmax, wmin;
2226 /* This is part of the abi to real_to_integer, but we check
2227 things before making this call. */
2228 bool fail;
2230 switch (code)
2232 case FIX:
2233 if (REAL_VALUE_ISNAN (*x))
2234 return const0_rtx;
2236 /* Test against the signed upper bound. */
2237 wmax = wi::max_value (width, SIGNED);
2238 real_from_integer (&t, VOIDmode, wmax, SIGNED);
2239 if (real_less (&t, x))
2240 return immed_wide_int_const (wmax, mode);
2242 /* Test against the signed lower bound. */
2243 wmin = wi::min_value (width, SIGNED);
2244 real_from_integer (&t, VOIDmode, wmin, SIGNED);
2245 if (real_less (x, &t))
2246 return immed_wide_int_const (wmin, mode);
2248 return immed_wide_int_const (real_to_integer (x, &fail, width),
2249 mode);
2251 case UNSIGNED_FIX:
2252 if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2253 return const0_rtx;
2255 /* Test against the unsigned upper bound. */
2256 wmax = wi::max_value (width, UNSIGNED);
2257 real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2258 if (real_less (&t, x))
2259 return immed_wide_int_const (wmax, mode);
2261 return immed_wide_int_const (real_to_integer (x, &fail, width),
2262 mode);
2264 default:
2265 gcc_unreachable ();
2269 /* Handle polynomial integers. */
2270 else if (CONST_POLY_INT_P (op))
2272 poly_wide_int result;
2273 switch (code)
2275 case NEG:
2276 result = -const_poly_int_value (op);
2277 break;
2279 case NOT:
2280 result = ~const_poly_int_value (op);
2281 break;
2283 default:
2284 return NULL_RTX;
2286 return immed_wide_int_const (result, mode);
2289 return NULL_RTX;
2292 /* Subroutine of simplify_binary_operation to simplify a binary operation
2293 CODE that can commute with byte swapping, with result mode MODE and
2294 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2295 Return zero if no simplification or canonicalization is possible. */
2298 simplify_context::simplify_byte_swapping_operation (rtx_code code,
2299 machine_mode mode,
2300 rtx op0, rtx op1)
2302 rtx tem;
2304 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2305 if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2307 tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2308 simplify_gen_unary (BSWAP, mode, op1, mode));
2309 return simplify_gen_unary (BSWAP, mode, tem, mode);
2312 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2313 if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2315 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2316 return simplify_gen_unary (BSWAP, mode, tem, mode);
2319 return NULL_RTX;
2322 /* Subroutine of simplify_binary_operation to simplify a commutative,
2323 associative binary operation CODE with result mode MODE, operating
2324 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2325 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2326 canonicalization is possible. */
2329 simplify_context::simplify_associative_operation (rtx_code code,
2330 machine_mode mode,
2331 rtx op0, rtx op1)
2333 rtx tem;
2335 /* Normally expressions simplified by simplify-rtx.cc are combined
2336 at most from a few machine instructions and therefore the
2337 expressions should be fairly small. During var-tracking
2338 we can see arbitrarily large expressions though and reassociating
2339 those can be quadratic, so punt after encountering max_assoc_count
2340 simplify_associative_operation calls during outermost simplify_*
2341 call. */
2342 if (++assoc_count >= max_assoc_count)
2343 return NULL_RTX;
2345 /* Linearize the operator to the left. */
2346 if (GET_CODE (op1) == code)
2348 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2349 if (GET_CODE (op0) == code)
2351 tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2352 return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2355 /* "a op (b op c)" becomes "(b op c) op a". */
2356 if (! swap_commutative_operands_p (op1, op0))
2357 return simplify_gen_binary (code, mode, op1, op0);
2359 std::swap (op0, op1);
2362 if (GET_CODE (op0) == code)
2364 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2365 if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2367 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2368 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2371 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2372 tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2373 if (tem != 0)
2374 return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2376 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2377 tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2378 if (tem != 0)
2379 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2382 return 0;
2385 /* Return a mask describing the COMPARISON. */
2386 static int
2387 comparison_to_mask (enum rtx_code comparison)
2389 switch (comparison)
2391 case LT:
2392 return 8;
2393 case GT:
2394 return 4;
2395 case EQ:
2396 return 2;
2397 case UNORDERED:
2398 return 1;
2400 case LTGT:
2401 return 12;
2402 case LE:
2403 return 10;
2404 case GE:
2405 return 6;
2406 case UNLT:
2407 return 9;
2408 case UNGT:
2409 return 5;
2410 case UNEQ:
2411 return 3;
2413 case ORDERED:
2414 return 14;
2415 case NE:
2416 return 13;
2417 case UNLE:
2418 return 11;
2419 case UNGE:
2420 return 7;
2422 default:
2423 gcc_unreachable ();
2427 /* Return a comparison corresponding to the MASK. */
2428 static enum rtx_code
2429 mask_to_comparison (int mask)
2431 switch (mask)
2433 case 8:
2434 return LT;
2435 case 4:
2436 return GT;
2437 case 2:
2438 return EQ;
2439 case 1:
2440 return UNORDERED;
2442 case 12:
2443 return LTGT;
2444 case 10:
2445 return LE;
2446 case 6:
2447 return GE;
2448 case 9:
2449 return UNLT;
2450 case 5:
2451 return UNGT;
2452 case 3:
2453 return UNEQ;
2455 case 14:
2456 return ORDERED;
2457 case 13:
2458 return NE;
2459 case 11:
2460 return UNLE;
2461 case 7:
2462 return UNGE;
2464 default:
2465 gcc_unreachable ();
2469 /* Return true if CODE is valid for comparisons of mode MODE, false
2470 otherwise.
2472 It is always safe to return false, even if the code was valid for the
2473 given mode as that will merely suppress optimizations. */
2475 static bool
2476 comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2478 switch (code)
2480 /* These are valid for integral, floating and vector modes. */
2481 case NE:
2482 case EQ:
2483 case GE:
2484 case GT:
2485 case LE:
2486 case LT:
2487 return (INTEGRAL_MODE_P (mode)
2488 || FLOAT_MODE_P (mode)
2489 || VECTOR_MODE_P (mode));
2491 /* These are valid for floating point modes. */
2492 case LTGT:
2493 case UNORDERED:
2494 case ORDERED:
2495 case UNEQ:
2496 case UNGE:
2497 case UNGT:
2498 case UNLE:
2499 case UNLT:
2500 return FLOAT_MODE_P (mode);
2502 /* These are filtered out in simplify_logical_operation, but
2503 we check for them too as a matter of safety. They are valid
2504 for integral and vector modes. */
2505 case GEU:
2506 case GTU:
2507 case LEU:
2508 case LTU:
2509 return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2511 default:
2512 gcc_unreachable ();
2516 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2517 false/true value of comparison with MODE where comparison operands
2518 have CMP_MODE. */
2520 static rtx
2521 relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2523 if (SCALAR_FLOAT_MODE_P (mode))
2525 if (res == const0_rtx)
2526 return CONST0_RTX (mode);
2527 #ifdef FLOAT_STORE_FLAG_VALUE
2528 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2529 return const_double_from_real_value (val, mode);
2530 #else
2531 return NULL_RTX;
2532 #endif
2534 if (VECTOR_MODE_P (mode))
2536 if (res == const0_rtx)
2537 return CONST0_RTX (mode);
2538 #ifdef VECTOR_STORE_FLAG_VALUE
2539 rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2540 if (val == NULL_RTX)
2541 return NULL_RTX;
2542 if (val == const1_rtx)
2543 return CONST1_RTX (mode);
2545 return gen_const_vec_duplicate (mode, val);
2546 #else
2547 return NULL_RTX;
2548 #endif
2550 /* For vector comparison with scalar int result, it is unknown
2551 if the target means here a comparison into an integral bitmask,
2552 or comparison where all comparisons true mean const_true_rtx
2553 whole result, or where any comparisons true mean const_true_rtx
2554 whole result. For const0_rtx all the cases are the same. */
2555 if (VECTOR_MODE_P (cmp_mode)
2556 && SCALAR_INT_MODE_P (mode)
2557 && res == const_true_rtx)
2558 return NULL_RTX;
2560 return res;
2563 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2564 and OP1, which should be both relational operations. Return 0 if no such
2565 simplification is possible. */
2567 simplify_context::simplify_logical_relational_operation (rtx_code code,
2568 machine_mode mode,
2569 rtx op0, rtx op1)
2571 /* We only handle IOR of two relational operations. */
2572 if (code != IOR)
2573 return 0;
2575 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2576 return 0;
2578 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2579 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2580 return 0;
2582 enum rtx_code code0 = GET_CODE (op0);
2583 enum rtx_code code1 = GET_CODE (op1);
2585 /* We don't handle unsigned comparisons currently. */
2586 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2587 return 0;
2588 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2589 return 0;
2591 int mask0 = comparison_to_mask (code0);
2592 int mask1 = comparison_to_mask (code1);
2594 int mask = mask0 | mask1;
2596 if (mask == 15)
2597 return relational_result (mode, GET_MODE (op0), const_true_rtx);
2599 code = mask_to_comparison (mask);
2601 /* Many comparison codes are only valid for certain mode classes. */
2602 if (!comparison_code_valid_for_mode (code, mode))
2603 return 0;
2605 op0 = XEXP (op1, 0);
2606 op1 = XEXP (op1, 1);
2608 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2611 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2612 and OP1. Return 0 if no simplification is possible.
2614 Don't use this for relational operations such as EQ or LT.
2615 Use simplify_relational_operation instead. */
2617 simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2618 rtx op0, rtx op1)
2620 rtx trueop0, trueop1;
2621 rtx tem;
2623 /* Relational operations don't work here. We must know the mode
2624 of the operands in order to do the comparison correctly.
2625 Assuming a full word can give incorrect results.
2626 Consider comparing 128 with -128 in QImode. */
2627 gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2628 gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2630 /* Make sure the constant is second. */
2631 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2632 && swap_commutative_operands_p (op0, op1))
2633 std::swap (op0, op1);
2635 trueop0 = avoid_constant_pool_reference (op0);
2636 trueop1 = avoid_constant_pool_reference (op1);
2638 tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2639 if (tem)
2640 return tem;
2641 tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2643 if (tem)
2644 return tem;
2646 /* If the above steps did not result in a simplification and op0 or op1
2647 were constant pool references, use the referenced constants directly. */
2648 if (trueop0 != op0 || trueop1 != op1)
2649 return simplify_gen_binary (code, mode, trueop0, trueop1);
2651 return NULL_RTX;
2654 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2655 which OP0 and OP1 are both vector series or vector duplicates
2656 (which are really just series with a step of 0). If so, try to
2657 form a new series by applying CODE to the bases and to the steps.
2658 Return null if no simplification is possible.
2660 MODE is the mode of the operation and is known to be a vector
2661 integer mode. */
2664 simplify_context::simplify_binary_operation_series (rtx_code code,
2665 machine_mode mode,
2666 rtx op0, rtx op1)
2668 rtx base0, step0;
2669 if (vec_duplicate_p (op0, &base0))
2670 step0 = const0_rtx;
2671 else if (!vec_series_p (op0, &base0, &step0))
2672 return NULL_RTX;
2674 rtx base1, step1;
2675 if (vec_duplicate_p (op1, &base1))
2676 step1 = const0_rtx;
2677 else if (!vec_series_p (op1, &base1, &step1))
2678 return NULL_RTX;
2680 /* Only create a new series if we can simplify both parts. In other
2681 cases this isn't really a simplification, and it's not necessarily
2682 a win to replace a vector operation with a scalar operation. */
2683 scalar_mode inner_mode = GET_MODE_INNER (mode);
2684 rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2685 if (!new_base)
2686 return NULL_RTX;
2688 rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2689 if (!new_step)
2690 return NULL_RTX;
2692 return gen_vec_series (mode, new_base, new_step);
2695 /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2696 operation CODE with result mode MODE, operating on OP0 and OP1.
2697 e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2698 Returns NULL_RTX if no simplification is possible. */
2701 simplify_context::simplify_distributive_operation (rtx_code code,
2702 machine_mode mode,
2703 rtx op0, rtx op1)
2705 enum rtx_code op = GET_CODE (op0);
2706 gcc_assert (GET_CODE (op1) == op);
2708 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2709 && ! side_effects_p (XEXP (op0, 1)))
2710 return simplify_gen_binary (op, mode,
2711 simplify_gen_binary (code, mode,
2712 XEXP (op0, 0),
2713 XEXP (op1, 0)),
2714 XEXP (op0, 1));
2716 if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2718 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2719 && ! side_effects_p (XEXP (op0, 0)))
2720 return simplify_gen_binary (op, mode,
2721 simplify_gen_binary (code, mode,
2722 XEXP (op0, 1),
2723 XEXP (op1, 1)),
2724 XEXP (op0, 0));
2725 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2726 && ! side_effects_p (XEXP (op0, 0)))
2727 return simplify_gen_binary (op, mode,
2728 simplify_gen_binary (code, mode,
2729 XEXP (op0, 1),
2730 XEXP (op1, 0)),
2731 XEXP (op0, 0));
2732 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2733 && ! side_effects_p (XEXP (op0, 1)))
2734 return simplify_gen_binary (op, mode,
2735 simplify_gen_binary (code, mode,
2736 XEXP (op0, 0),
2737 XEXP (op1, 1)),
2738 XEXP (op0, 1));
2741 return NULL_RTX;
2744 /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2745 should be reversed.
2747 If the rotate should not be reversed, return FALSE.
2749 LEFT indicates if this is a rotate left or a rotate right. */
2751 bool
2752 reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2754 if (!CONST_INT_P (op1))
2755 return false;
2757 /* Some targets may only be able to rotate by a constant
2758 in one direction. So we need to query the optab interface
2759 to see what is possible. */
2760 optab binoptab = left ? rotl_optab : rotr_optab;
2761 optab re_binoptab = left ? rotr_optab : rotl_optab;
2762 enum insn_code icode = optab_handler (binoptab, mode);
2763 enum insn_code re_icode = optab_handler (re_binoptab, mode);
2765 /* If the target can not support the reversed optab, then there
2766 is nothing to do. */
2767 if (re_icode == CODE_FOR_nothing)
2768 return false;
2770 /* If the target does not support the requested rotate-by-immediate,
2771 then we want to try reversing the rotate. We also want to try
2772 reversing to minimize the count. */
2773 if ((icode == CODE_FOR_nothing)
2774 || (!insn_operand_matches (icode, 2, op1))
2775 || (IN_RANGE (INTVAL (op1),
2776 GET_MODE_UNIT_PRECISION (mode) / 2 + left,
2777 GET_MODE_UNIT_PRECISION (mode) - 1)))
2778 return (insn_operand_matches (re_icode, 2, op1));
2779 return false;
2782 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2783 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2784 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2785 actual constants. */
2788 simplify_context::simplify_binary_operation_1 (rtx_code code,
2789 machine_mode mode,
2790 rtx op0, rtx op1,
2791 rtx trueop0, rtx trueop1)
2793 rtx tem, reversed, opleft, opright, elt0, elt1;
2794 HOST_WIDE_INT val;
2795 scalar_int_mode int_mode, inner_mode;
2796 poly_int64 offset;
2798 /* Even if we can't compute a constant result,
2799 there are some cases worth simplifying. */
2801 switch (code)
2803 case PLUS:
2804 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2805 when x is NaN, infinite, or finite and nonzero. They aren't
2806 when x is -0 and the rounding mode is not towards -infinity,
2807 since (-0) + 0 is then 0. */
2808 if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2809 return op0;
2811 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2812 transformations are safe even for IEEE. */
2813 if (GET_CODE (op0) == NEG)
2814 return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2815 else if (GET_CODE (op1) == NEG)
2816 return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2818 /* (~a) + 1 -> -a */
2819 if (INTEGRAL_MODE_P (mode)
2820 && GET_CODE (op0) == NOT
2821 && trueop1 == const1_rtx)
2822 return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2824 /* Handle both-operands-constant cases. We can only add
2825 CONST_INTs to constants since the sum of relocatable symbols
2826 can't be handled by most assemblers. Don't add CONST_INT
2827 to CONST_INT since overflow won't be computed properly if wider
2828 than HOST_BITS_PER_WIDE_INT. */
2830 if ((GET_CODE (op0) == CONST
2831 || GET_CODE (op0) == SYMBOL_REF
2832 || GET_CODE (op0) == LABEL_REF)
2833 && poly_int_rtx_p (op1, &offset))
2834 return plus_constant (mode, op0, offset);
2835 else if ((GET_CODE (op1) == CONST
2836 || GET_CODE (op1) == SYMBOL_REF
2837 || GET_CODE (op1) == LABEL_REF)
2838 && poly_int_rtx_p (op0, &offset))
2839 return plus_constant (mode, op1, offset);
2841 /* See if this is something like X * C - X or vice versa or
2842 if the multiplication is written as a shift. If so, we can
2843 distribute and make a new multiply, shift, or maybe just
2844 have X (if C is 2 in the example above). But don't make
2845 something more expensive than we had before. */
2847 if (is_a <scalar_int_mode> (mode, &int_mode))
2849 rtx lhs = op0, rhs = op1;
2851 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2852 wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2854 if (GET_CODE (lhs) == NEG)
2856 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2857 lhs = XEXP (lhs, 0);
2859 else if (GET_CODE (lhs) == MULT
2860 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2862 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2863 lhs = XEXP (lhs, 0);
2865 else if (GET_CODE (lhs) == ASHIFT
2866 && CONST_INT_P (XEXP (lhs, 1))
2867 && INTVAL (XEXP (lhs, 1)) >= 0
2868 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2870 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2871 GET_MODE_PRECISION (int_mode));
2872 lhs = XEXP (lhs, 0);
2875 if (GET_CODE (rhs) == NEG)
2877 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2878 rhs = XEXP (rhs, 0);
2880 else if (GET_CODE (rhs) == MULT
2881 && CONST_INT_P (XEXP (rhs, 1)))
2883 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2884 rhs = XEXP (rhs, 0);
2886 else if (GET_CODE (rhs) == ASHIFT
2887 && CONST_INT_P (XEXP (rhs, 1))
2888 && INTVAL (XEXP (rhs, 1)) >= 0
2889 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2891 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2892 GET_MODE_PRECISION (int_mode));
2893 rhs = XEXP (rhs, 0);
2896 if (rtx_equal_p (lhs, rhs))
2898 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2899 rtx coeff;
2900 bool speed = optimize_function_for_speed_p (cfun);
2902 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2904 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2905 return (set_src_cost (tem, int_mode, speed)
2906 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2909 /* Optimize (X - 1) * Y + Y to X * Y. */
2910 lhs = op0;
2911 rhs = op1;
2912 if (GET_CODE (op0) == MULT)
2914 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2915 && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
2916 || (GET_CODE (XEXP (op0, 0)) == MINUS
2917 && XEXP (XEXP (op0, 0), 1) == const1_rtx))
2918 && rtx_equal_p (XEXP (op0, 1), op1))
2919 lhs = XEXP (XEXP (op0, 0), 0);
2920 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2921 && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
2922 || (GET_CODE (XEXP (op0, 1)) == MINUS
2923 && XEXP (XEXP (op0, 1), 1) == const1_rtx))
2924 && rtx_equal_p (XEXP (op0, 0), op1))
2925 lhs = XEXP (XEXP (op0, 1), 0);
2927 else if (GET_CODE (op1) == MULT)
2929 if (((GET_CODE (XEXP (op1, 0)) == PLUS
2930 && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
2931 || (GET_CODE (XEXP (op1, 0)) == MINUS
2932 && XEXP (XEXP (op1, 0), 1) == const1_rtx))
2933 && rtx_equal_p (XEXP (op1, 1), op0))
2934 rhs = XEXP (XEXP (op1, 0), 0);
2935 else if (((GET_CODE (XEXP (op1, 1)) == PLUS
2936 && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
2937 || (GET_CODE (XEXP (op1, 1)) == MINUS
2938 && XEXP (XEXP (op1, 1), 1) == const1_rtx))
2939 && rtx_equal_p (XEXP (op1, 0), op0))
2940 rhs = XEXP (XEXP (op1, 1), 0);
2942 if (lhs != op0 || rhs != op1)
2943 return simplify_gen_binary (MULT, int_mode, lhs, rhs);
2946 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2947 if (CONST_SCALAR_INT_P (op1)
2948 && GET_CODE (op0) == XOR
2949 && CONST_SCALAR_INT_P (XEXP (op0, 1))
2950 && mode_signbit_p (mode, op1))
2951 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2952 simplify_gen_binary (XOR, mode, op1,
2953 XEXP (op0, 1)));
2955 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2956 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2957 && GET_CODE (op0) == MULT
2958 && GET_CODE (XEXP (op0, 0)) == NEG)
2960 rtx in1, in2;
2962 in1 = XEXP (XEXP (op0, 0), 0);
2963 in2 = XEXP (op0, 1);
2964 return simplify_gen_binary (MINUS, mode, op1,
2965 simplify_gen_binary (MULT, mode,
2966 in1, in2));
2969 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2970 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2971 is 1. */
2972 if (COMPARISON_P (op0)
2973 && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2974 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2975 && (reversed = reversed_comparison (op0, mode)))
2976 return
2977 simplify_gen_unary (NEG, mode, reversed, mode);
2979 /* If one of the operands is a PLUS or a MINUS, see if we can
2980 simplify this by the associative law.
2981 Don't use the associative law for floating point.
2982 The inaccuracy makes it nonassociative,
2983 and subtle programs can break if operations are associated. */
2985 if (INTEGRAL_MODE_P (mode)
2986 && (plus_minus_operand_p (op0)
2987 || plus_minus_operand_p (op1))
2988 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2989 return tem;
2991 /* Reassociate floating point addition only when the user
2992 specifies associative math operations. */
2993 if (FLOAT_MODE_P (mode)
2994 && flag_associative_math)
2996 tem = simplify_associative_operation (code, mode, op0, op1);
2997 if (tem)
2998 return tem;
3001 /* Handle vector series. */
3002 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3004 tem = simplify_binary_operation_series (code, mode, op0, op1);
3005 if (tem)
3006 return tem;
3008 break;
3010 case COMPARE:
3011 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
3012 if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
3013 || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
3014 && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
3016 rtx xop00 = XEXP (op0, 0);
3017 rtx xop10 = XEXP (op1, 0);
3019 if (REG_P (xop00) && REG_P (xop10)
3020 && REGNO (xop00) == REGNO (xop10)
3021 && GET_MODE (xop00) == mode
3022 && GET_MODE (xop10) == mode
3023 && GET_MODE_CLASS (mode) == MODE_CC)
3024 return xop00;
3026 break;
3028 case MINUS:
3029 /* We can't assume x-x is 0 even with non-IEEE floating point,
3030 but since it is zero except in very strange circumstances, we
3031 will treat it as zero with -ffinite-math-only. */
3032 if (rtx_equal_p (trueop0, trueop1)
3033 && ! side_effects_p (op0)
3034 && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3035 return CONST0_RTX (mode);
3037 /* Change subtraction from zero into negation. (0 - x) is the
3038 same as -x when x is NaN, infinite, or finite and nonzero.
3039 But if the mode has signed zeros, and does not round towards
3040 -infinity, then 0 - 0 is 0, not -0. */
3041 if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3042 return simplify_gen_unary (NEG, mode, op1, mode);
3044 /* (-1 - a) is ~a, unless the expression contains symbolic
3045 constants, in which case not retaining additions and
3046 subtractions could cause invalid assembly to be produced. */
3047 if (trueop0 == constm1_rtx
3048 && !contains_symbolic_reference_p (op1))
3049 return simplify_gen_unary (NOT, mode, op1, mode);
3051 /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3052 or has signed zeros and supports rounding towards -infinity.
3053 In such a case, 0 - 0 is -0. */
3054 if (!(HONOR_SIGNED_ZEROS (mode)
3055 && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3056 && !HONOR_SNANS (mode)
3057 && trueop1 == CONST0_RTX (mode))
3058 return op0;
3060 /* See if this is something like X * C - X or vice versa or
3061 if the multiplication is written as a shift. If so, we can
3062 distribute and make a new multiply, shift, or maybe just
3063 have X (if C is 2 in the example above). But don't make
3064 something more expensive than we had before. */
3066 if (is_a <scalar_int_mode> (mode, &int_mode))
3068 rtx lhs = op0, rhs = op1;
3070 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3071 wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3073 if (GET_CODE (lhs) == NEG)
3075 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3076 lhs = XEXP (lhs, 0);
3078 else if (GET_CODE (lhs) == MULT
3079 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3081 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3082 lhs = XEXP (lhs, 0);
3084 else if (GET_CODE (lhs) == ASHIFT
3085 && CONST_INT_P (XEXP (lhs, 1))
3086 && INTVAL (XEXP (lhs, 1)) >= 0
3087 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3089 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3090 GET_MODE_PRECISION (int_mode));
3091 lhs = XEXP (lhs, 0);
3094 if (GET_CODE (rhs) == NEG)
3096 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3097 rhs = XEXP (rhs, 0);
3099 else if (GET_CODE (rhs) == MULT
3100 && CONST_INT_P (XEXP (rhs, 1)))
3102 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3103 rhs = XEXP (rhs, 0);
3105 else if (GET_CODE (rhs) == ASHIFT
3106 && CONST_INT_P (XEXP (rhs, 1))
3107 && INTVAL (XEXP (rhs, 1)) >= 0
3108 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3110 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3111 GET_MODE_PRECISION (int_mode));
3112 negcoeff1 = -negcoeff1;
3113 rhs = XEXP (rhs, 0);
3116 if (rtx_equal_p (lhs, rhs))
3118 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3119 rtx coeff;
3120 bool speed = optimize_function_for_speed_p (cfun);
3122 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3124 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3125 return (set_src_cost (tem, int_mode, speed)
3126 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3129 /* Optimize (X + 1) * Y - Y to X * Y. */
3130 lhs = op0;
3131 if (GET_CODE (op0) == MULT)
3133 if (((GET_CODE (XEXP (op0, 0)) == PLUS
3134 && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3135 || (GET_CODE (XEXP (op0, 0)) == MINUS
3136 && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3137 && rtx_equal_p (XEXP (op0, 1), op1))
3138 lhs = XEXP (XEXP (op0, 0), 0);
3139 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3140 && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3141 || (GET_CODE (XEXP (op0, 1)) == MINUS
3142 && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3143 && rtx_equal_p (XEXP (op0, 0), op1))
3144 lhs = XEXP (XEXP (op0, 1), 0);
3146 if (lhs != op0)
3147 return simplify_gen_binary (MULT, int_mode, lhs, op1);
3150 /* (a - (-b)) -> (a + b). True even for IEEE. */
3151 if (GET_CODE (op1) == NEG)
3152 return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3154 /* (-x - c) may be simplified as (-c - x). */
3155 if (GET_CODE (op0) == NEG
3156 && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3158 tem = simplify_unary_operation (NEG, mode, op1, mode);
3159 if (tem)
3160 return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3163 if ((GET_CODE (op0) == CONST
3164 || GET_CODE (op0) == SYMBOL_REF
3165 || GET_CODE (op0) == LABEL_REF)
3166 && poly_int_rtx_p (op1, &offset))
3167 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3169 /* Don't let a relocatable value get a negative coeff. */
3170 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
3171 return simplify_gen_binary (PLUS, mode,
3172 op0,
3173 neg_poly_int_rtx (mode, op1));
3175 /* (x - (x & y)) -> (x & ~y) */
3176 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3178 if (rtx_equal_p (op0, XEXP (op1, 0)))
3180 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3181 GET_MODE (XEXP (op1, 1)));
3182 return simplify_gen_binary (AND, mode, op0, tem);
3184 if (rtx_equal_p (op0, XEXP (op1, 1)))
3186 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3187 GET_MODE (XEXP (op1, 0)));
3188 return simplify_gen_binary (AND, mode, op0, tem);
3192 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3193 by reversing the comparison code if valid. */
3194 if (STORE_FLAG_VALUE == 1
3195 && trueop0 == const1_rtx
3196 && COMPARISON_P (op1)
3197 && (reversed = reversed_comparison (op1, mode)))
3198 return reversed;
3200 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3201 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3202 && GET_CODE (op1) == MULT
3203 && GET_CODE (XEXP (op1, 0)) == NEG)
3205 rtx in1, in2;
3207 in1 = XEXP (XEXP (op1, 0), 0);
3208 in2 = XEXP (op1, 1);
3209 return simplify_gen_binary (PLUS, mode,
3210 simplify_gen_binary (MULT, mode,
3211 in1, in2),
3212 op0);
3215 /* Canonicalize (minus (neg A) (mult B C)) to
3216 (minus (mult (neg B) C) A). */
3217 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3218 && GET_CODE (op1) == MULT
3219 && GET_CODE (op0) == NEG)
3221 rtx in1, in2;
3223 in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3224 in2 = XEXP (op1, 1);
3225 return simplify_gen_binary (MINUS, mode,
3226 simplify_gen_binary (MULT, mode,
3227 in1, in2),
3228 XEXP (op0, 0));
3231 /* If one of the operands is a PLUS or a MINUS, see if we can
3232 simplify this by the associative law. This will, for example,
3233 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3234 Don't use the associative law for floating point.
3235 The inaccuracy makes it nonassociative,
3236 and subtle programs can break if operations are associated. */
3238 if (INTEGRAL_MODE_P (mode)
3239 && (plus_minus_operand_p (op0)
3240 || plus_minus_operand_p (op1))
3241 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3242 return tem;
3244 /* Handle vector series. */
3245 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3247 tem = simplify_binary_operation_series (code, mode, op0, op1);
3248 if (tem)
3249 return tem;
3251 break;
3253 case MULT:
3254 if (trueop1 == constm1_rtx)
3255 return simplify_gen_unary (NEG, mode, op0, mode);
3257 if (GET_CODE (op0) == NEG)
3259 rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3260 /* If op1 is a MULT as well and simplify_unary_operation
3261 just moved the NEG to the second operand, simplify_gen_binary
3262 below could through simplify_associative_operation move
3263 the NEG around again and recurse endlessly. */
3264 if (temp
3265 && GET_CODE (op1) == MULT
3266 && GET_CODE (temp) == MULT
3267 && XEXP (op1, 0) == XEXP (temp, 0)
3268 && GET_CODE (XEXP (temp, 1)) == NEG
3269 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3270 temp = NULL_RTX;
3271 if (temp)
3272 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3274 if (GET_CODE (op1) == NEG)
3276 rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3277 /* If op0 is a MULT as well and simplify_unary_operation
3278 just moved the NEG to the second operand, simplify_gen_binary
3279 below could through simplify_associative_operation move
3280 the NEG around again and recurse endlessly. */
3281 if (temp
3282 && GET_CODE (op0) == MULT
3283 && GET_CODE (temp) == MULT
3284 && XEXP (op0, 0) == XEXP (temp, 0)
3285 && GET_CODE (XEXP (temp, 1)) == NEG
3286 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3287 temp = NULL_RTX;
3288 if (temp)
3289 return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3292 /* Maybe simplify x * 0 to 0. The reduction is not valid if
3293 x is NaN, since x * 0 is then also NaN. Nor is it valid
3294 when the mode has signed zeros, since multiplying a negative
3295 number by 0 will give -0, not 0. */
3296 if (!HONOR_NANS (mode)
3297 && !HONOR_SIGNED_ZEROS (mode)
3298 && trueop1 == CONST0_RTX (mode)
3299 && ! side_effects_p (op0))
3300 return op1;
3302 /* In IEEE floating point, x*1 is not equivalent to x for
3303 signalling NaNs. */
3304 if (!HONOR_SNANS (mode)
3305 && trueop1 == CONST1_RTX (mode))
3306 return op0;
3308 /* Convert multiply by constant power of two into shift. */
3309 if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3311 val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3312 if (val >= 0)
3313 return simplify_gen_binary (ASHIFT, mode, op0,
3314 gen_int_shift_amount (mode, val));
3317 /* x*2 is x+x and x*(-1) is -x */
3318 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3319 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3320 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3321 && GET_MODE (op0) == mode)
3323 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3325 if (real_equal (d1, &dconst2))
3326 return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3328 if (!HONOR_SNANS (mode)
3329 && real_equal (d1, &dconstm1))
3330 return simplify_gen_unary (NEG, mode, op0, mode);
3333 /* Optimize -x * -x as x * x. */
3334 if (FLOAT_MODE_P (mode)
3335 && GET_CODE (op0) == NEG
3336 && GET_CODE (op1) == NEG
3337 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3338 && !side_effects_p (XEXP (op0, 0)))
3339 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3341 /* Likewise, optimize abs(x) * abs(x) as x * x. */
3342 if (SCALAR_FLOAT_MODE_P (mode)
3343 && GET_CODE (op0) == ABS
3344 && GET_CODE (op1) == ABS
3345 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3346 && !side_effects_p (XEXP (op0, 0)))
3347 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3349 /* Reassociate multiplication, but for floating point MULTs
3350 only when the user specifies unsafe math optimizations. */
3351 if (! FLOAT_MODE_P (mode)
3352 || flag_unsafe_math_optimizations)
3354 tem = simplify_associative_operation (code, mode, op0, op1);
3355 if (tem)
3356 return tem;
3358 break;
3360 case IOR:
3361 if (trueop1 == CONST0_RTX (mode))
3362 return op0;
3363 if (INTEGRAL_MODE_P (mode)
3364 && trueop1 == CONSTM1_RTX (mode)
3365 && !side_effects_p (op0))
3366 return op1;
3367 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3368 return op0;
3369 /* A | (~A) -> -1 */
3370 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3371 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3372 && ! side_effects_p (op0)
3373 && GET_MODE_CLASS (mode) != MODE_CC)
3374 return CONSTM1_RTX (mode);
3376 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3377 if (CONST_INT_P (op1)
3378 && HWI_COMPUTABLE_MODE_P (mode)
3379 && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3380 && !side_effects_p (op0))
3381 return op1;
3383 /* Canonicalize (X & C1) | C2. */
3384 if (GET_CODE (op0) == AND
3385 && CONST_INT_P (trueop1)
3386 && CONST_INT_P (XEXP (op0, 1)))
3388 HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3389 HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3390 HOST_WIDE_INT c2 = INTVAL (trueop1);
3392 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3393 if ((c1 & c2) == c1
3394 && !side_effects_p (XEXP (op0, 0)))
3395 return trueop1;
3397 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3398 if (((c1|c2) & mask) == mask)
3399 return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3402 /* Convert (A & B) | A to A. */
3403 if (GET_CODE (op0) == AND
3404 && (rtx_equal_p (XEXP (op0, 0), op1)
3405 || rtx_equal_p (XEXP (op0, 1), op1))
3406 && ! side_effects_p (XEXP (op0, 0))
3407 && ! side_effects_p (XEXP (op0, 1)))
3408 return op1;
3410 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3411 mode size to (rotate A CX). */
3413 if (GET_CODE (op1) == ASHIFT
3414 || GET_CODE (op1) == SUBREG)
3416 opleft = op1;
3417 opright = op0;
3419 else
3421 opright = op1;
3422 opleft = op0;
3425 if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3426 && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3427 && CONST_INT_P (XEXP (opleft, 1))
3428 && CONST_INT_P (XEXP (opright, 1))
3429 && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3430 == GET_MODE_UNIT_PRECISION (mode)))
3431 return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3433 /* Same, but for ashift that has been "simplified" to a wider mode
3434 by simplify_shift_const. */
3436 if (GET_CODE (opleft) == SUBREG
3437 && is_a <scalar_int_mode> (mode, &int_mode)
3438 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3439 &inner_mode)
3440 && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3441 && GET_CODE (opright) == LSHIFTRT
3442 && GET_CODE (XEXP (opright, 0)) == SUBREG
3443 && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3444 && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3445 && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3446 SUBREG_REG (XEXP (opright, 0)))
3447 && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3448 && CONST_INT_P (XEXP (opright, 1))
3449 && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3450 + INTVAL (XEXP (opright, 1))
3451 == GET_MODE_PRECISION (int_mode)))
3452 return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3453 XEXP (SUBREG_REG (opleft), 1));
3455 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3456 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3457 the PLUS does not affect any of the bits in OP1: then we can do
3458 the IOR as a PLUS and we can associate. This is valid if OP1
3459 can be safely shifted left C bits. */
3460 if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3461 && GET_CODE (XEXP (op0, 0)) == PLUS
3462 && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3463 && CONST_INT_P (XEXP (op0, 1))
3464 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3466 int count = INTVAL (XEXP (op0, 1));
3467 HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3469 if (mask >> count == INTVAL (trueop1)
3470 && trunc_int_for_mode (mask, mode) == mask
3471 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3472 return simplify_gen_binary (ASHIFTRT, mode,
3473 plus_constant (mode, XEXP (op0, 0),
3474 mask),
3475 XEXP (op0, 1));
3478 /* The following happens with bitfield merging.
3479 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3480 if (GET_CODE (op0) == AND
3481 && GET_CODE (op1) == AND
3482 && CONST_INT_P (XEXP (op0, 1))
3483 && CONST_INT_P (XEXP (op1, 1))
3484 && (INTVAL (XEXP (op0, 1))
3485 == ~INTVAL (XEXP (op1, 1))))
3487 /* The IOR may be on both sides. */
3488 rtx top0 = NULL_RTX, top1 = NULL_RTX;
3489 if (GET_CODE (XEXP (op1, 0)) == IOR)
3490 top0 = op0, top1 = op1;
3491 else if (GET_CODE (XEXP (op0, 0)) == IOR)
3492 top0 = op1, top1 = op0;
3493 if (top0 && top1)
3495 /* X may be on either side of the inner IOR. */
3496 rtx tem = NULL_RTX;
3497 if (rtx_equal_p (XEXP (top0, 0),
3498 XEXP (XEXP (top1, 0), 0)))
3499 tem = XEXP (XEXP (top1, 0), 1);
3500 else if (rtx_equal_p (XEXP (top0, 0),
3501 XEXP (XEXP (top1, 0), 1)))
3502 tem = XEXP (XEXP (top1, 0), 0);
3503 if (tem)
3504 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3505 simplify_gen_binary
3506 (AND, mode, tem, XEXP (top1, 1)));
3510 /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3511 if (GET_CODE (op0) == GET_CODE (op1)
3512 && (GET_CODE (op0) == AND
3513 || GET_CODE (op0) == IOR
3514 || GET_CODE (op0) == LSHIFTRT
3515 || GET_CODE (op0) == ASHIFTRT
3516 || GET_CODE (op0) == ASHIFT
3517 || GET_CODE (op0) == ROTATE
3518 || GET_CODE (op0) == ROTATERT))
3520 tem = simplify_distributive_operation (code, mode, op0, op1);
3521 if (tem)
3522 return tem;
3525 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3526 if (tem)
3527 return tem;
3529 tem = simplify_associative_operation (code, mode, op0, op1);
3530 if (tem)
3531 return tem;
3533 tem = simplify_logical_relational_operation (code, mode, op0, op1);
3534 if (tem)
3535 return tem;
3536 break;
3538 case XOR:
3539 if (trueop1 == CONST0_RTX (mode))
3540 return op0;
3541 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3542 return simplify_gen_unary (NOT, mode, op0, mode);
3543 if (rtx_equal_p (trueop0, trueop1)
3544 && ! side_effects_p (op0)
3545 && GET_MODE_CLASS (mode) != MODE_CC)
3546 return CONST0_RTX (mode);
3548 /* Canonicalize XOR of the most significant bit to PLUS. */
3549 if (CONST_SCALAR_INT_P (op1)
3550 && mode_signbit_p (mode, op1))
3551 return simplify_gen_binary (PLUS, mode, op0, op1);
3552 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3553 if (CONST_SCALAR_INT_P (op1)
3554 && GET_CODE (op0) == PLUS
3555 && CONST_SCALAR_INT_P (XEXP (op0, 1))
3556 && mode_signbit_p (mode, XEXP (op0, 1)))
3557 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3558 simplify_gen_binary (XOR, mode, op1,
3559 XEXP (op0, 1)));
3561 /* If we are XORing two things that have no bits in common,
3562 convert them into an IOR. This helps to detect rotation encoded
3563 using those methods and possibly other simplifications. */
3565 if (HWI_COMPUTABLE_MODE_P (mode)
3566 && (nonzero_bits (op0, mode)
3567 & nonzero_bits (op1, mode)) == 0)
3568 return (simplify_gen_binary (IOR, mode, op0, op1));
3570 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3571 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3572 (NOT y). */
3574 int num_negated = 0;
3576 if (GET_CODE (op0) == NOT)
3577 num_negated++, op0 = XEXP (op0, 0);
3578 if (GET_CODE (op1) == NOT)
3579 num_negated++, op1 = XEXP (op1, 0);
3581 if (num_negated == 2)
3582 return simplify_gen_binary (XOR, mode, op0, op1);
3583 else if (num_negated == 1)
3584 return simplify_gen_unary (NOT, mode,
3585 simplify_gen_binary (XOR, mode, op0, op1),
3586 mode);
3589 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3590 correspond to a machine insn or result in further simplifications
3591 if B is a constant. */
3593 if (GET_CODE (op0) == AND
3594 && rtx_equal_p (XEXP (op0, 1), op1)
3595 && ! side_effects_p (op1))
3596 return simplify_gen_binary (AND, mode,
3597 simplify_gen_unary (NOT, mode,
3598 XEXP (op0, 0), mode),
3599 op1);
3601 else if (GET_CODE (op0) == AND
3602 && rtx_equal_p (XEXP (op0, 0), op1)
3603 && ! side_effects_p (op1))
3604 return simplify_gen_binary (AND, mode,
3605 simplify_gen_unary (NOT, mode,
3606 XEXP (op0, 1), mode),
3607 op1);
3609 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3610 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3611 out bits inverted twice and not set by C. Similarly, given
3612 (xor (and (xor A B) C) D), simplify without inverting C in
3613 the xor operand: (xor (and A C) (B&C)^D).
3615 else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3616 && GET_CODE (XEXP (op0, 0)) == XOR
3617 && CONST_INT_P (op1)
3618 && CONST_INT_P (XEXP (op0, 1))
3619 && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3621 enum rtx_code op = GET_CODE (op0);
3622 rtx a = XEXP (XEXP (op0, 0), 0);
3623 rtx b = XEXP (XEXP (op0, 0), 1);
3624 rtx c = XEXP (op0, 1);
3625 rtx d = op1;
3626 HOST_WIDE_INT bval = INTVAL (b);
3627 HOST_WIDE_INT cval = INTVAL (c);
3628 HOST_WIDE_INT dval = INTVAL (d);
3629 HOST_WIDE_INT xcval;
3631 if (op == IOR)
3632 xcval = ~cval;
3633 else
3634 xcval = cval;
3636 return simplify_gen_binary (XOR, mode,
3637 simplify_gen_binary (op, mode, a, c),
3638 gen_int_mode ((bval & xcval) ^ dval,
3639 mode));
3642 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3643 we can transform like this:
3644 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3645 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3646 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3647 Attempt a few simplifications when B and C are both constants. */
3648 if (GET_CODE (op0) == AND
3649 && CONST_INT_P (op1)
3650 && CONST_INT_P (XEXP (op0, 1)))
3652 rtx a = XEXP (op0, 0);
3653 rtx b = XEXP (op0, 1);
3654 rtx c = op1;
3655 HOST_WIDE_INT bval = INTVAL (b);
3656 HOST_WIDE_INT cval = INTVAL (c);
3658 /* Instead of computing ~A&C, we compute its negated value,
3659 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3660 optimize for sure. If it does not simplify, we still try
3661 to compute ~A&C below, but since that always allocates
3662 RTL, we don't try that before committing to returning a
3663 simplified expression. */
3664 rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3665 GEN_INT (~cval));
3667 if ((~cval & bval) == 0)
3669 rtx na_c = NULL_RTX;
3670 if (n_na_c)
3671 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3672 else
3674 /* If ~A does not simplify, don't bother: we don't
3675 want to simplify 2 operations into 3, and if na_c
3676 were to simplify with na, n_na_c would have
3677 simplified as well. */
3678 rtx na = simplify_unary_operation (NOT, mode, a, mode);
3679 if (na)
3680 na_c = simplify_gen_binary (AND, mode, na, c);
3683 /* Try to simplify ~A&C | ~B&C. */
3684 if (na_c != NULL_RTX)
3685 return simplify_gen_binary (IOR, mode, na_c,
3686 gen_int_mode (~bval & cval, mode));
3688 else
3690 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3691 if (n_na_c == CONSTM1_RTX (mode))
3693 rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3694 gen_int_mode (~cval & bval,
3695 mode));
3696 return simplify_gen_binary (IOR, mode, a_nc_b,
3697 gen_int_mode (~bval & cval,
3698 mode));
3703 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3704 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3705 machines, and also has shorter instruction path length. */
3706 if (GET_CODE (op0) == AND
3707 && GET_CODE (XEXP (op0, 0)) == XOR
3708 && CONST_INT_P (XEXP (op0, 1))
3709 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3711 rtx a = trueop1;
3712 rtx b = XEXP (XEXP (op0, 0), 1);
3713 rtx c = XEXP (op0, 1);
3714 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3715 rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3716 rtx bc = simplify_gen_binary (AND, mode, b, c);
3717 return simplify_gen_binary (IOR, mode, a_nc, bc);
3719 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3720 else if (GET_CODE (op0) == AND
3721 && GET_CODE (XEXP (op0, 0)) == XOR
3722 && CONST_INT_P (XEXP (op0, 1))
3723 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3725 rtx a = XEXP (XEXP (op0, 0), 0);
3726 rtx b = trueop1;
3727 rtx c = XEXP (op0, 1);
3728 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3729 rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3730 rtx ac = simplify_gen_binary (AND, mode, a, c);
3731 return simplify_gen_binary (IOR, mode, ac, b_nc);
3734 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3735 comparison if STORE_FLAG_VALUE is 1. */
3736 if (STORE_FLAG_VALUE == 1
3737 && trueop1 == const1_rtx
3738 && COMPARISON_P (op0)
3739 && (reversed = reversed_comparison (op0, mode)))
3740 return reversed;
3742 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3743 is (lt foo (const_int 0)), so we can perform the above
3744 simplification if STORE_FLAG_VALUE is 1. */
3746 if (is_a <scalar_int_mode> (mode, &int_mode)
3747 && STORE_FLAG_VALUE == 1
3748 && trueop1 == const1_rtx
3749 && GET_CODE (op0) == LSHIFTRT
3750 && CONST_INT_P (XEXP (op0, 1))
3751 && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3752 return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3754 /* (xor (comparison foo bar) (const_int sign-bit))
3755 when STORE_FLAG_VALUE is the sign bit. */
3756 if (is_a <scalar_int_mode> (mode, &int_mode)
3757 && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3758 && trueop1 == const_true_rtx
3759 && COMPARISON_P (op0)
3760 && (reversed = reversed_comparison (op0, int_mode)))
3761 return reversed;
3763 /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3764 if (GET_CODE (op0) == GET_CODE (op1)
3765 && (GET_CODE (op0) == AND
3766 || GET_CODE (op0) == LSHIFTRT
3767 || GET_CODE (op0) == ASHIFTRT
3768 || GET_CODE (op0) == ASHIFT
3769 || GET_CODE (op0) == ROTATE
3770 || GET_CODE (op0) == ROTATERT))
3772 tem = simplify_distributive_operation (code, mode, op0, op1);
3773 if (tem)
3774 return tem;
3777 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3778 if (tem)
3779 return tem;
3781 tem = simplify_associative_operation (code, mode, op0, op1);
3782 if (tem)
3783 return tem;
3784 break;
3786 case AND:
3787 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3788 return trueop1;
3789 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3790 return op0;
3791 if (HWI_COMPUTABLE_MODE_P (mode))
3793 /* When WORD_REGISTER_OPERATIONS is true, we need to know the
3794 nonzero bits in WORD_MODE rather than MODE. */
3795 scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
3796 if (WORD_REGISTER_OPERATIONS
3797 && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3798 tmode = word_mode;
3799 HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
3800 HOST_WIDE_INT nzop1;
3801 if (CONST_INT_P (trueop1))
3803 HOST_WIDE_INT val1 = INTVAL (trueop1);
3804 /* If we are turning off bits already known off in OP0, we need
3805 not do an AND. */
3806 if ((nzop0 & ~val1) == 0)
3807 return op0;
3809 nzop1 = nonzero_bits (trueop1, mode);
3810 /* If we are clearing all the nonzero bits, the result is zero. */
3811 if ((nzop1 & nzop0) == 0
3812 && !side_effects_p (op0) && !side_effects_p (op1))
3813 return CONST0_RTX (mode);
3815 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3816 && GET_MODE_CLASS (mode) != MODE_CC)
3817 return op0;
3818 /* A & (~A) -> 0 */
3819 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3820 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3821 && ! side_effects_p (op0)
3822 && GET_MODE_CLASS (mode) != MODE_CC)
3823 return CONST0_RTX (mode);
3825 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3826 there are no nonzero bits of C outside of X's mode. */
3827 if ((GET_CODE (op0) == SIGN_EXTEND
3828 || GET_CODE (op0) == ZERO_EXTEND)
3829 && CONST_SCALAR_INT_P (trueop1)
3830 && is_a <scalar_int_mode> (mode, &int_mode)
3831 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
3832 && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
3833 GET_MODE_PRECISION (int_mode))
3834 & rtx_mode_t (trueop1, mode)) == 0)
3836 machine_mode imode = GET_MODE (XEXP (op0, 0));
3837 tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
3838 tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
3839 return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3842 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3843 we might be able to further simplify the AND with X and potentially
3844 remove the truncation altogether. */
3845 if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3847 rtx x = XEXP (op0, 0);
3848 machine_mode xmode = GET_MODE (x);
3849 tem = simplify_gen_binary (AND, xmode, x,
3850 gen_int_mode (INTVAL (trueop1), xmode));
3851 return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3854 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3855 if (GET_CODE (op0) == IOR
3856 && CONST_INT_P (trueop1)
3857 && CONST_INT_P (XEXP (op0, 1)))
3859 HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3860 return simplify_gen_binary (IOR, mode,
3861 simplify_gen_binary (AND, mode,
3862 XEXP (op0, 0), op1),
3863 gen_int_mode (tmp, mode));
3866 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3867 insn (and may simplify more). */
3868 if (GET_CODE (op0) == XOR
3869 && rtx_equal_p (XEXP (op0, 0), op1)
3870 && ! side_effects_p (op1))
3871 return simplify_gen_binary (AND, mode,
3872 simplify_gen_unary (NOT, mode,
3873 XEXP (op0, 1), mode),
3874 op1);
3876 if (GET_CODE (op0) == XOR
3877 && rtx_equal_p (XEXP (op0, 1), op1)
3878 && ! side_effects_p (op1))
3879 return simplify_gen_binary (AND, mode,
3880 simplify_gen_unary (NOT, mode,
3881 XEXP (op0, 0), mode),
3882 op1);
3884 /* Similarly for (~(A ^ B)) & A. */
3885 if (GET_CODE (op0) == NOT
3886 && GET_CODE (XEXP (op0, 0)) == XOR
3887 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3888 && ! side_effects_p (op1))
3889 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3891 if (GET_CODE (op0) == NOT
3892 && GET_CODE (XEXP (op0, 0)) == XOR
3893 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3894 && ! side_effects_p (op1))
3895 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3897 /* Convert (A | B) & A to A. */
3898 if (GET_CODE (op0) == IOR
3899 && (rtx_equal_p (XEXP (op0, 0), op1)
3900 || rtx_equal_p (XEXP (op0, 1), op1))
3901 && ! side_effects_p (XEXP (op0, 0))
3902 && ! side_effects_p (XEXP (op0, 1)))
3903 return op1;
3905 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3906 ((A & N) + B) & M -> (A + B) & M
3907 Similarly if (N & M) == 0,
3908 ((A | N) + B) & M -> (A + B) & M
3909 and for - instead of + and/or ^ instead of |.
3910 Also, if (N & M) == 0, then
3911 (A +- N) & M -> A & M. */
3912 if (CONST_INT_P (trueop1)
3913 && HWI_COMPUTABLE_MODE_P (mode)
3914 && ~UINTVAL (trueop1)
3915 && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3916 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3918 rtx pmop[2];
3919 int which;
3921 pmop[0] = XEXP (op0, 0);
3922 pmop[1] = XEXP (op0, 1);
3924 if (CONST_INT_P (pmop[1])
3925 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3926 return simplify_gen_binary (AND, mode, pmop[0], op1);
3928 for (which = 0; which < 2; which++)
3930 tem = pmop[which];
3931 switch (GET_CODE (tem))
3933 case AND:
3934 if (CONST_INT_P (XEXP (tem, 1))
3935 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3936 == UINTVAL (trueop1))
3937 pmop[which] = XEXP (tem, 0);
3938 break;
3939 case IOR:
3940 case XOR:
3941 if (CONST_INT_P (XEXP (tem, 1))
3942 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3943 pmop[which] = XEXP (tem, 0);
3944 break;
3945 default:
3946 break;
3950 if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3952 tem = simplify_gen_binary (GET_CODE (op0), mode,
3953 pmop[0], pmop[1]);
3954 return simplify_gen_binary (code, mode, tem, op1);
3958 /* (and X (ior (not X) Y) -> (and X Y) */
3959 if (GET_CODE (op1) == IOR
3960 && GET_CODE (XEXP (op1, 0)) == NOT
3961 && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3962 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3964 /* (and (ior (not X) Y) X) -> (and X Y) */
3965 if (GET_CODE (op0) == IOR
3966 && GET_CODE (XEXP (op0, 0)) == NOT
3967 && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3968 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3970 /* (and X (ior Y (not X)) -> (and X Y) */
3971 if (GET_CODE (op1) == IOR
3972 && GET_CODE (XEXP (op1, 1)) == NOT
3973 && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3974 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3976 /* (and (ior Y (not X)) X) -> (and X Y) */
3977 if (GET_CODE (op0) == IOR
3978 && GET_CODE (XEXP (op0, 1)) == NOT
3979 && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3980 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3982 /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
3983 if (GET_CODE (op0) == GET_CODE (op1)
3984 && (GET_CODE (op0) == AND
3985 || GET_CODE (op0) == IOR
3986 || GET_CODE (op0) == LSHIFTRT
3987 || GET_CODE (op0) == ASHIFTRT
3988 || GET_CODE (op0) == ASHIFT
3989 || GET_CODE (op0) == ROTATE
3990 || GET_CODE (op0) == ROTATERT))
3992 tem = simplify_distributive_operation (code, mode, op0, op1);
3993 if (tem)
3994 return tem;
3997 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3998 if (tem)
3999 return tem;
4001 tem = simplify_associative_operation (code, mode, op0, op1);
4002 if (tem)
4003 return tem;
4004 break;
4006 case UDIV:
4007 /* 0/x is 0 (or x&0 if x has side-effects). */
4008 if (trueop0 == CONST0_RTX (mode)
4009 && !cfun->can_throw_non_call_exceptions)
4011 if (side_effects_p (op1))
4012 return simplify_gen_binary (AND, mode, op1, trueop0);
4013 return trueop0;
4015 /* x/1 is x. */
4016 if (trueop1 == CONST1_RTX (mode))
4018 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4019 if (tem)
4020 return tem;
4022 /* Convert divide by power of two into shift. */
4023 if (CONST_INT_P (trueop1)
4024 && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4025 return simplify_gen_binary (LSHIFTRT, mode, op0,
4026 gen_int_shift_amount (mode, val));
4027 break;
4029 case DIV:
4030 /* Handle floating point and integers separately. */
4031 if (SCALAR_FLOAT_MODE_P (mode))
4033 /* Maybe change 0.0 / x to 0.0. This transformation isn't
4034 safe for modes with NaNs, since 0.0 / 0.0 will then be
4035 NaN rather than 0.0. Nor is it safe for modes with signed
4036 zeros, since dividing 0 by a negative number gives -0.0 */
4037 if (trueop0 == CONST0_RTX (mode)
4038 && !HONOR_NANS (mode)
4039 && !HONOR_SIGNED_ZEROS (mode)
4040 && ! side_effects_p (op1))
4041 return op0;
4042 /* x/1.0 is x. */
4043 if (trueop1 == CONST1_RTX (mode)
4044 && !HONOR_SNANS (mode))
4045 return op0;
4047 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4048 && trueop1 != CONST0_RTX (mode))
4050 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4052 /* x/-1.0 is -x. */
4053 if (real_equal (d1, &dconstm1)
4054 && !HONOR_SNANS (mode))
4055 return simplify_gen_unary (NEG, mode, op0, mode);
4057 /* Change FP division by a constant into multiplication.
4058 Only do this with -freciprocal-math. */
4059 if (flag_reciprocal_math
4060 && !real_equal (d1, &dconst0))
4062 REAL_VALUE_TYPE d;
4063 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4064 tem = const_double_from_real_value (d, mode);
4065 return simplify_gen_binary (MULT, mode, op0, tem);
4069 else if (SCALAR_INT_MODE_P (mode))
4071 /* 0/x is 0 (or x&0 if x has side-effects). */
4072 if (trueop0 == CONST0_RTX (mode)
4073 && !cfun->can_throw_non_call_exceptions)
4075 if (side_effects_p (op1))
4076 return simplify_gen_binary (AND, mode, op1, trueop0);
4077 return trueop0;
4079 /* x/1 is x. */
4080 if (trueop1 == CONST1_RTX (mode))
4082 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4083 if (tem)
4084 return tem;
4086 /* x/-1 is -x. */
4087 if (trueop1 == constm1_rtx)
4089 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4090 if (x)
4091 return simplify_gen_unary (NEG, mode, x, mode);
4094 break;
4096 case UMOD:
4097 /* 0%x is 0 (or x&0 if x has side-effects). */
4098 if (trueop0 == CONST0_RTX (mode))
4100 if (side_effects_p (op1))
4101 return simplify_gen_binary (AND, mode, op1, trueop0);
4102 return trueop0;
4104 /* x%1 is 0 (of x&0 if x has side-effects). */
4105 if (trueop1 == CONST1_RTX (mode))
4107 if (side_effects_p (op0))
4108 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4109 return CONST0_RTX (mode);
4111 /* Implement modulus by power of two as AND. */
4112 if (CONST_INT_P (trueop1)
4113 && exact_log2 (UINTVAL (trueop1)) > 0)
4114 return simplify_gen_binary (AND, mode, op0,
4115 gen_int_mode (UINTVAL (trueop1) - 1,
4116 mode));
4117 break;
4119 case MOD:
4120 /* 0%x is 0 (or x&0 if x has side-effects). */
4121 if (trueop0 == CONST0_RTX (mode))
4123 if (side_effects_p (op1))
4124 return simplify_gen_binary (AND, mode, op1, trueop0);
4125 return trueop0;
4127 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4128 if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4130 if (side_effects_p (op0))
4131 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4132 return CONST0_RTX (mode);
4134 break;
4136 case ROTATERT:
4137 case ROTATE:
4138 if (trueop1 == CONST0_RTX (mode))
4139 return op0;
4140 /* Canonicalize rotates by constant amount. If the condition of
4141 reversing direction is met, then reverse the direction. */
4142 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4143 if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4145 int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4146 rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4147 return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4148 mode, op0, new_amount_rtx);
4150 #endif
4151 /* FALLTHRU */
4152 case ASHIFTRT:
4153 if (trueop1 == CONST0_RTX (mode))
4154 return op0;
4155 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4156 return op0;
4157 /* Rotating ~0 always results in ~0. */
4158 if (CONST_INT_P (trueop0)
4159 && HWI_COMPUTABLE_MODE_P (mode)
4160 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4161 && ! side_effects_p (op1))
4162 return op0;
4164 canonicalize_shift:
4165 /* Given:
4166 scalar modes M1, M2
4167 scalar constants c1, c2
4168 size (M2) > size (M1)
4169 c1 == size (M2) - size (M1)
4170 optimize:
4171 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4172 <low_part>)
4173 (const_int <c2>))
4175 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4176 <low_part>). */
4177 if ((code == ASHIFTRT || code == LSHIFTRT)
4178 && is_a <scalar_int_mode> (mode, &int_mode)
4179 && SUBREG_P (op0)
4180 && CONST_INT_P (op1)
4181 && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4182 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4183 &inner_mode)
4184 && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4185 && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4186 && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4187 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4188 && subreg_lowpart_p (op0))
4190 rtx tmp = gen_int_shift_amount
4191 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4193 /* Combine would usually zero out the value when combining two
4194 local shifts and the range becomes larger or equal to the mode.
4195 However since we fold away one of the shifts here combine won't
4196 see it so we should immediately zero the result if it's out of
4197 range. */
4198 if (code == LSHIFTRT
4199 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4200 tmp = const0_rtx;
4201 else
4202 tmp = simplify_gen_binary (code,
4203 inner_mode,
4204 XEXP (SUBREG_REG (op0), 0),
4205 tmp);
4207 return lowpart_subreg (int_mode, tmp, inner_mode);
4210 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4212 val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4213 if (val != INTVAL (op1))
4214 return simplify_gen_binary (code, mode, op0,
4215 gen_int_shift_amount (mode, val));
4217 break;
4219 case SS_ASHIFT:
4220 if (CONST_INT_P (trueop0)
4221 && HWI_COMPUTABLE_MODE_P (mode)
4222 && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4223 || mode_signbit_p (mode, trueop0))
4224 && ! side_effects_p (op1))
4225 return op0;
4226 goto simplify_ashift;
4228 case US_ASHIFT:
4229 if (CONST_INT_P (trueop0)
4230 && HWI_COMPUTABLE_MODE_P (mode)
4231 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4232 && ! side_effects_p (op1))
4233 return op0;
4234 /* FALLTHRU */
4236 case ASHIFT:
4237 simplify_ashift:
4238 if (trueop1 == CONST0_RTX (mode))
4239 return op0;
4240 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4241 return op0;
4242 if (mem_depth
4243 && code == ASHIFT
4244 && CONST_INT_P (trueop1)
4245 && is_a <scalar_int_mode> (mode, &int_mode)
4246 && IN_RANGE (UINTVAL (trueop1),
4247 1, GET_MODE_PRECISION (int_mode) - 1))
4249 auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4250 << UINTVAL (trueop1));
4251 rtx new_op1 = immed_wide_int_const (c, int_mode);
4252 return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4254 goto canonicalize_shift;
4256 case LSHIFTRT:
4257 if (trueop1 == CONST0_RTX (mode))
4258 return op0;
4259 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4260 return op0;
4261 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4262 if (GET_CODE (op0) == CLZ
4263 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4264 && CONST_INT_P (trueop1)
4265 && STORE_FLAG_VALUE == 1
4266 && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4268 unsigned HOST_WIDE_INT zero_val = 0;
4270 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4271 && zero_val == GET_MODE_PRECISION (inner_mode)
4272 && INTVAL (trueop1) == exact_log2 (zero_val))
4273 return simplify_gen_relational (EQ, mode, inner_mode,
4274 XEXP (op0, 0), const0_rtx);
4276 goto canonicalize_shift;
4278 case SMIN:
4279 if (HWI_COMPUTABLE_MODE_P (mode)
4280 && mode_signbit_p (mode, trueop1)
4281 && ! side_effects_p (op0))
4282 return op1;
4283 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4284 return op0;
4285 tem = simplify_associative_operation (code, mode, op0, op1);
4286 if (tem)
4287 return tem;
4288 break;
4290 case SMAX:
4291 if (HWI_COMPUTABLE_MODE_P (mode)
4292 && CONST_INT_P (trueop1)
4293 && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4294 && ! side_effects_p (op0))
4295 return op1;
4296 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4297 return op0;
4298 tem = simplify_associative_operation (code, mode, op0, op1);
4299 if (tem)
4300 return tem;
4301 break;
4303 case UMIN:
4304 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4305 return op1;
4306 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4307 return op0;
4308 tem = simplify_associative_operation (code, mode, op0, op1);
4309 if (tem)
4310 return tem;
4311 break;
4313 case UMAX:
4314 if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4315 return op1;
4316 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4317 return op0;
4318 tem = simplify_associative_operation (code, mode, op0, op1);
4319 if (tem)
4320 return tem;
4321 break;
4323 case SS_PLUS:
4324 case US_PLUS:
4325 case SS_MINUS:
4326 case US_MINUS:
4327 /* Simplify x +/- 0 to x, if possible. */
4328 if (trueop1 == CONST0_RTX (mode))
4329 return op0;
4330 return 0;
4332 case SS_MULT:
4333 case US_MULT:
4334 /* Simplify x * 0 to 0, if possible. */
4335 if (trueop1 == CONST0_RTX (mode)
4336 && !side_effects_p (op0))
4337 return op1;
4339 /* Simplify x * 1 to x, if possible. */
4340 if (trueop1 == CONST1_RTX (mode))
4341 return op0;
4342 return 0;
4344 case SMUL_HIGHPART:
4345 case UMUL_HIGHPART:
4346 /* Simplify x * 0 to 0, if possible. */
4347 if (trueop1 == CONST0_RTX (mode)
4348 && !side_effects_p (op0))
4349 return op1;
4350 return 0;
4352 case SS_DIV:
4353 case US_DIV:
4354 /* Simplify x / 1 to x, if possible. */
4355 if (trueop1 == CONST1_RTX (mode))
4356 return op0;
4357 return 0;
4359 case VEC_SERIES:
4360 if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4361 return gen_vec_duplicate (mode, op0);
4362 if (valid_for_const_vector_p (mode, op0)
4363 && valid_for_const_vector_p (mode, op1))
4364 return gen_const_vec_series (mode, op0, op1);
4365 return 0;
4367 case VEC_SELECT:
4368 if (!VECTOR_MODE_P (mode))
4370 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4371 gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4372 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4373 gcc_assert (XVECLEN (trueop1, 0) == 1);
4375 /* We can't reason about selections made at runtime. */
4376 if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4377 return 0;
4379 if (vec_duplicate_p (trueop0, &elt0))
4380 return elt0;
4382 if (GET_CODE (trueop0) == CONST_VECTOR)
4383 return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4384 (trueop1, 0, 0)));
4386 /* Extract a scalar element from a nested VEC_SELECT expression
4387 (with optional nested VEC_CONCAT expression). Some targets
4388 (i386) extract scalar element from a vector using chain of
4389 nested VEC_SELECT expressions. When input operand is a memory
4390 operand, this operation can be simplified to a simple scalar
4391 load from an offseted memory address. */
4392 int n_elts;
4393 if (GET_CODE (trueop0) == VEC_SELECT
4394 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4395 .is_constant (&n_elts)))
4397 rtx op0 = XEXP (trueop0, 0);
4398 rtx op1 = XEXP (trueop0, 1);
4400 int i = INTVAL (XVECEXP (trueop1, 0, 0));
4401 int elem;
4403 rtvec vec;
4404 rtx tmp_op, tmp;
4406 gcc_assert (GET_CODE (op1) == PARALLEL);
4407 gcc_assert (i < n_elts);
4409 /* Select element, pointed by nested selector. */
4410 elem = INTVAL (XVECEXP (op1, 0, i));
4412 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4413 if (GET_CODE (op0) == VEC_CONCAT)
4415 rtx op00 = XEXP (op0, 0);
4416 rtx op01 = XEXP (op0, 1);
4418 machine_mode mode00, mode01;
4419 int n_elts00, n_elts01;
4421 mode00 = GET_MODE (op00);
4422 mode01 = GET_MODE (op01);
4424 /* Find out the number of elements of each operand.
4425 Since the concatenated result has a constant number
4426 of elements, the operands must too. */
4427 n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4428 n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4430 gcc_assert (n_elts == n_elts00 + n_elts01);
4432 /* Select correct operand of VEC_CONCAT
4433 and adjust selector. */
4434 if (elem < n_elts01)
4435 tmp_op = op00;
4436 else
4438 tmp_op = op01;
4439 elem -= n_elts00;
4442 else
4443 tmp_op = op0;
4445 vec = rtvec_alloc (1);
4446 RTVEC_ELT (vec, 0) = GEN_INT (elem);
4448 tmp = gen_rtx_fmt_ee (code, mode,
4449 tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
4450 return tmp;
4453 else
4455 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4456 gcc_assert (GET_MODE_INNER (mode)
4457 == GET_MODE_INNER (GET_MODE (trueop0)));
4458 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4460 if (vec_duplicate_p (trueop0, &elt0))
4461 /* It doesn't matter which elements are selected by trueop1,
4462 because they are all the same. */
4463 return gen_vec_duplicate (mode, elt0);
4465 if (GET_CODE (trueop0) == CONST_VECTOR)
4467 unsigned n_elts = XVECLEN (trueop1, 0);
4468 rtvec v = rtvec_alloc (n_elts);
4469 unsigned int i;
4471 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4472 for (i = 0; i < n_elts; i++)
4474 rtx x = XVECEXP (trueop1, 0, i);
4476 if (!CONST_INT_P (x))
4477 return 0;
4479 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
4480 INTVAL (x));
4483 return gen_rtx_CONST_VECTOR (mode, v);
4486 /* Recognize the identity. */
4487 if (GET_MODE (trueop0) == mode)
4489 bool maybe_ident = true;
4490 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4492 rtx j = XVECEXP (trueop1, 0, i);
4493 if (!CONST_INT_P (j) || INTVAL (j) != i)
4495 maybe_ident = false;
4496 break;
4499 if (maybe_ident)
4500 return trueop0;
4503 /* If we select a low-part subreg, return that. */
4504 if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
4506 rtx new_rtx = lowpart_subreg (mode, trueop0,
4507 GET_MODE (trueop0));
4508 if (new_rtx != NULL_RTX)
4509 return new_rtx;
4512 /* If we build {a,b} then permute it, build the result directly. */
4513 if (XVECLEN (trueop1, 0) == 2
4514 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4515 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4516 && GET_CODE (trueop0) == VEC_CONCAT
4517 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4518 && GET_MODE (XEXP (trueop0, 0)) == mode
4519 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4520 && GET_MODE (XEXP (trueop0, 1)) == mode)
4522 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4523 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4524 rtx subop0, subop1;
4526 gcc_assert (i0 < 4 && i1 < 4);
4527 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4528 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4530 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4533 if (XVECLEN (trueop1, 0) == 2
4534 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4535 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4536 && GET_CODE (trueop0) == VEC_CONCAT
4537 && GET_MODE (trueop0) == mode)
4539 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4540 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4541 rtx subop0, subop1;
4543 gcc_assert (i0 < 2 && i1 < 2);
4544 subop0 = XEXP (trueop0, i0);
4545 subop1 = XEXP (trueop0, i1);
4547 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4550 /* If we select one half of a vec_concat, return that. */
4551 int l0, l1;
4552 if (GET_CODE (trueop0) == VEC_CONCAT
4553 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4554 .is_constant (&l0))
4555 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4556 .is_constant (&l1))
4557 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4559 rtx subop0 = XEXP (trueop0, 0);
4560 rtx subop1 = XEXP (trueop0, 1);
4561 machine_mode mode0 = GET_MODE (subop0);
4562 machine_mode mode1 = GET_MODE (subop1);
4563 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4564 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4566 bool success = true;
4567 for (int i = 1; i < l0; ++i)
4569 rtx j = XVECEXP (trueop1, 0, i);
4570 if (!CONST_INT_P (j) || INTVAL (j) != i)
4572 success = false;
4573 break;
4576 if (success)
4577 return subop0;
4579 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4581 bool success = true;
4582 for (int i = 1; i < l1; ++i)
4584 rtx j = XVECEXP (trueop1, 0, i);
4585 if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4587 success = false;
4588 break;
4591 if (success)
4592 return subop1;
4596 /* Simplify vec_select of a subreg of X to just a vec_select of X
4597 when X has same component mode as vec_select. */
4598 unsigned HOST_WIDE_INT subreg_offset = 0;
4599 if (GET_CODE (trueop0) == SUBREG
4600 && GET_MODE_INNER (mode)
4601 == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
4602 && GET_MODE_NUNITS (mode).is_constant (&l1)
4603 && constant_multiple_p (subreg_memory_offset (trueop0),
4604 GET_MODE_UNIT_BITSIZE (mode),
4605 &subreg_offset))
4607 poly_uint64 nunits
4608 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
4609 bool success = true;
4610 for (int i = 0; i != l1; i++)
4612 rtx idx = XVECEXP (trueop1, 0, i);
4613 if (!CONST_INT_P (idx)
4614 || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
4616 success = false;
4617 break;
4621 if (success)
4623 rtx par = trueop1;
4624 if (subreg_offset)
4626 rtvec vec = rtvec_alloc (l1);
4627 for (int i = 0; i < l1; i++)
4628 RTVEC_ELT (vec, i)
4629 = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
4630 + subreg_offset);
4631 par = gen_rtx_PARALLEL (VOIDmode, vec);
4633 return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
4638 if (XVECLEN (trueop1, 0) == 1
4639 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4640 && GET_CODE (trueop0) == VEC_CONCAT)
4642 rtx vec = trueop0;
4643 offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4645 /* Try to find the element in the VEC_CONCAT. */
4646 while (GET_MODE (vec) != mode
4647 && GET_CODE (vec) == VEC_CONCAT)
4649 poly_int64 vec_size;
4651 if (CONST_INT_P (XEXP (vec, 0)))
4653 /* vec_concat of two const_ints doesn't make sense with
4654 respect to modes. */
4655 if (CONST_INT_P (XEXP (vec, 1)))
4656 return 0;
4658 vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4659 - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4661 else
4662 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4664 if (known_lt (offset, vec_size))
4665 vec = XEXP (vec, 0);
4666 else if (known_ge (offset, vec_size))
4668 offset -= vec_size;
4669 vec = XEXP (vec, 1);
4671 else
4672 break;
4673 vec = avoid_constant_pool_reference (vec);
4676 if (GET_MODE (vec) == mode)
4677 return vec;
4680 /* If we select elements in a vec_merge that all come from the same
4681 operand, select from that operand directly. */
4682 if (GET_CODE (op0) == VEC_MERGE)
4684 rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4685 if (CONST_INT_P (trueop02))
4687 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4688 bool all_operand0 = true;
4689 bool all_operand1 = true;
4690 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4692 rtx j = XVECEXP (trueop1, 0, i);
4693 if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4694 all_operand1 = false;
4695 else
4696 all_operand0 = false;
4698 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4699 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4700 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4701 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4705 /* If we have two nested selects that are inverses of each
4706 other, replace them with the source operand. */
4707 if (GET_CODE (trueop0) == VEC_SELECT
4708 && GET_MODE (XEXP (trueop0, 0)) == mode)
4710 rtx op0_subop1 = XEXP (trueop0, 1);
4711 gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4712 gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4714 /* Apply the outer ordering vector to the inner one. (The inner
4715 ordering vector is expressly permitted to be of a different
4716 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4717 then the two VEC_SELECTs cancel. */
4718 for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4720 rtx x = XVECEXP (trueop1, 0, i);
4721 if (!CONST_INT_P (x))
4722 return 0;
4723 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4724 if (!CONST_INT_P (y) || i != INTVAL (y))
4725 return 0;
4727 return XEXP (trueop0, 0);
4730 return 0;
4731 case VEC_CONCAT:
4733 machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4734 ? GET_MODE (trueop0)
4735 : GET_MODE_INNER (mode));
4736 machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4737 ? GET_MODE (trueop1)
4738 : GET_MODE_INNER (mode));
4740 gcc_assert (VECTOR_MODE_P (mode));
4741 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4742 + GET_MODE_SIZE (op1_mode),
4743 GET_MODE_SIZE (mode)));
4745 if (VECTOR_MODE_P (op0_mode))
4746 gcc_assert (GET_MODE_INNER (mode)
4747 == GET_MODE_INNER (op0_mode));
4748 else
4749 gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4751 if (VECTOR_MODE_P (op1_mode))
4752 gcc_assert (GET_MODE_INNER (mode)
4753 == GET_MODE_INNER (op1_mode));
4754 else
4755 gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4757 unsigned int n_elts, in_n_elts;
4758 if ((GET_CODE (trueop0) == CONST_VECTOR
4759 || CONST_SCALAR_INT_P (trueop0)
4760 || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4761 && (GET_CODE (trueop1) == CONST_VECTOR
4762 || CONST_SCALAR_INT_P (trueop1)
4763 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4764 && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4765 && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4767 rtvec v = rtvec_alloc (n_elts);
4768 unsigned int i;
4769 for (i = 0; i < n_elts; i++)
4771 if (i < in_n_elts)
4773 if (!VECTOR_MODE_P (op0_mode))
4774 RTVEC_ELT (v, i) = trueop0;
4775 else
4776 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4778 else
4780 if (!VECTOR_MODE_P (op1_mode))
4781 RTVEC_ELT (v, i) = trueop1;
4782 else
4783 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4784 i - in_n_elts);
4788 return gen_rtx_CONST_VECTOR (mode, v);
4791 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4792 Restrict the transformation to avoid generating a VEC_SELECT with a
4793 mode unrelated to its operand. */
4794 if (GET_CODE (trueop0) == VEC_SELECT
4795 && GET_CODE (trueop1) == VEC_SELECT
4796 && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4797 && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
4798 == GET_MODE_INNER(mode))
4800 rtx par0 = XEXP (trueop0, 1);
4801 rtx par1 = XEXP (trueop1, 1);
4802 int len0 = XVECLEN (par0, 0);
4803 int len1 = XVECLEN (par1, 0);
4804 rtvec vec = rtvec_alloc (len0 + len1);
4805 for (int i = 0; i < len0; i++)
4806 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4807 for (int i = 0; i < len1; i++)
4808 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4809 return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4810 gen_rtx_PARALLEL (VOIDmode, vec));
4813 return 0;
4815 default:
4816 gcc_unreachable ();
4819 if (mode == GET_MODE (op0)
4820 && mode == GET_MODE (op1)
4821 && vec_duplicate_p (op0, &elt0)
4822 && vec_duplicate_p (op1, &elt1))
4824 /* Try applying the operator to ELT and see if that simplifies.
4825 We can duplicate the result if so.
4827 The reason we don't use simplify_gen_binary is that it isn't
4828 necessarily a win to convert things like:
4830 (plus:V (vec_duplicate:V (reg:S R1))
4831 (vec_duplicate:V (reg:S R2)))
4835 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4837 The first might be done entirely in vector registers while the
4838 second might need a move between register files. */
4839 tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4840 elt0, elt1);
4841 if (tem)
4842 return gen_vec_duplicate (mode, tem);
4845 return 0;
4848 /* Return true if binary operation OP distributes over addition in operand
4849 OPNO, with the other operand being held constant. OPNO counts from 1. */
4851 static bool
4852 distributes_over_addition_p (rtx_code op, int opno)
4854 switch (op)
4856 case PLUS:
4857 case MINUS:
4858 case MULT:
4859 return true;
4861 case ASHIFT:
4862 return opno == 1;
4864 default:
4865 return false;
4870 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4871 rtx op0, rtx op1)
4873 if (VECTOR_MODE_P (mode)
4874 && code != VEC_CONCAT
4875 && GET_CODE (op0) == CONST_VECTOR
4876 && GET_CODE (op1) == CONST_VECTOR)
4878 bool step_ok_p;
4879 if (CONST_VECTOR_STEPPED_P (op0)
4880 && CONST_VECTOR_STEPPED_P (op1))
4881 /* We can operate directly on the encoding if:
4883 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4884 implies
4885 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4887 Addition and subtraction are the supported operators
4888 for which this is true. */
4889 step_ok_p = (code == PLUS || code == MINUS);
4890 else if (CONST_VECTOR_STEPPED_P (op0))
4891 /* We can operate directly on stepped encodings if:
4893 a3 - a2 == a2 - a1
4894 implies:
4895 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4897 which is true if (x -> x op c) distributes over addition. */
4898 step_ok_p = distributes_over_addition_p (code, 1);
4899 else
4900 /* Similarly in reverse. */
4901 step_ok_p = distributes_over_addition_p (code, 2);
4902 rtx_vector_builder builder;
4903 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4904 return 0;
4906 unsigned int count = builder.encoded_nelts ();
4907 for (unsigned int i = 0; i < count; i++)
4909 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4910 CONST_VECTOR_ELT (op0, i),
4911 CONST_VECTOR_ELT (op1, i));
4912 if (!x || !valid_for_const_vector_p (mode, x))
4913 return 0;
4914 builder.quick_push (x);
4916 return builder.build ();
4919 if (VECTOR_MODE_P (mode)
4920 && code == VEC_CONCAT
4921 && (CONST_SCALAR_INT_P (op0)
4922 || CONST_FIXED_P (op0)
4923 || CONST_DOUBLE_AS_FLOAT_P (op0))
4924 && (CONST_SCALAR_INT_P (op1)
4925 || CONST_DOUBLE_AS_FLOAT_P (op1)
4926 || CONST_FIXED_P (op1)))
4928 /* Both inputs have a constant number of elements, so the result
4929 must too. */
4930 unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4931 rtvec v = rtvec_alloc (n_elts);
4933 gcc_assert (n_elts >= 2);
4934 if (n_elts == 2)
4936 gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4937 gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4939 RTVEC_ELT (v, 0) = op0;
4940 RTVEC_ELT (v, 1) = op1;
4942 else
4944 unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4945 unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4946 unsigned i;
4948 gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4949 gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4950 gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4952 for (i = 0; i < op0_n_elts; ++i)
4953 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4954 for (i = 0; i < op1_n_elts; ++i)
4955 RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4958 return gen_rtx_CONST_VECTOR (mode, v);
4961 if (SCALAR_FLOAT_MODE_P (mode)
4962 && CONST_DOUBLE_AS_FLOAT_P (op0)
4963 && CONST_DOUBLE_AS_FLOAT_P (op1)
4964 && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4966 if (code == AND
4967 || code == IOR
4968 || code == XOR)
4970 long tmp0[4];
4971 long tmp1[4];
4972 REAL_VALUE_TYPE r;
4973 int i;
4975 real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4976 GET_MODE (op0));
4977 real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4978 GET_MODE (op1));
4979 for (i = 0; i < 4; i++)
4981 switch (code)
4983 case AND:
4984 tmp0[i] &= tmp1[i];
4985 break;
4986 case IOR:
4987 tmp0[i] |= tmp1[i];
4988 break;
4989 case XOR:
4990 tmp0[i] ^= tmp1[i];
4991 break;
4992 default:
4993 gcc_unreachable ();
4996 real_from_target (&r, tmp0, mode);
4997 return const_double_from_real_value (r, mode);
4999 else
5001 REAL_VALUE_TYPE f0, f1, value, result;
5002 const REAL_VALUE_TYPE *opr0, *opr1;
5003 bool inexact;
5005 opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5006 opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5008 if (HONOR_SNANS (mode)
5009 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5010 || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5011 return 0;
5013 real_convert (&f0, mode, opr0);
5014 real_convert (&f1, mode, opr1);
5016 if (code == DIV
5017 && real_equal (&f1, &dconst0)
5018 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5019 return 0;
5021 if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5022 && flag_trapping_math
5023 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5025 int s0 = REAL_VALUE_NEGATIVE (f0);
5026 int s1 = REAL_VALUE_NEGATIVE (f1);
5028 switch (code)
5030 case PLUS:
5031 /* Inf + -Inf = NaN plus exception. */
5032 if (s0 != s1)
5033 return 0;
5034 break;
5035 case MINUS:
5036 /* Inf - Inf = NaN plus exception. */
5037 if (s0 == s1)
5038 return 0;
5039 break;
5040 case DIV:
5041 /* Inf / Inf = NaN plus exception. */
5042 return 0;
5043 default:
5044 break;
5048 if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5049 && flag_trapping_math
5050 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5051 || (REAL_VALUE_ISINF (f1)
5052 && real_equal (&f0, &dconst0))))
5053 /* Inf * 0 = NaN plus exception. */
5054 return 0;
5056 inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5057 &f0, &f1);
5058 real_convert (&result, mode, &value);
5060 /* Don't constant fold this floating point operation if
5061 the result has overflowed and flag_trapping_math. */
5063 if (flag_trapping_math
5064 && MODE_HAS_INFINITIES (mode)
5065 && REAL_VALUE_ISINF (result)
5066 && !REAL_VALUE_ISINF (f0)
5067 && !REAL_VALUE_ISINF (f1))
5068 /* Overflow plus exception. */
5069 return 0;
5071 /* Don't constant fold this floating point operation if the
5072 result may dependent upon the run-time rounding mode and
5073 flag_rounding_math is set, or if GCC's software emulation
5074 is unable to accurately represent the result. */
5076 if ((flag_rounding_math
5077 || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5078 && (inexact || !real_identical (&result, &value)))
5079 return NULL_RTX;
5081 return const_double_from_real_value (result, mode);
5085 /* We can fold some multi-word operations. */
5086 scalar_int_mode int_mode;
5087 if (is_a <scalar_int_mode> (mode, &int_mode)
5088 && CONST_SCALAR_INT_P (op0)
5089 && CONST_SCALAR_INT_P (op1)
5090 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5092 wide_int result;
5093 wi::overflow_type overflow;
5094 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5095 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5097 #if TARGET_SUPPORTS_WIDE_INT == 0
5098 /* This assert keeps the simplification from producing a result
5099 that cannot be represented in a CONST_DOUBLE but a lot of
5100 upstream callers expect that this function never fails to
5101 simplify something and so you if you added this to the test
5102 above the code would die later anyway. If this assert
5103 happens, you just need to make the port support wide int. */
5104 gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5105 #endif
5106 switch (code)
5108 case MINUS:
5109 result = wi::sub (pop0, pop1);
5110 break;
5112 case PLUS:
5113 result = wi::add (pop0, pop1);
5114 break;
5116 case MULT:
5117 result = wi::mul (pop0, pop1);
5118 break;
5120 case DIV:
5121 result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5122 if (overflow)
5123 return NULL_RTX;
5124 break;
5126 case MOD:
5127 result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5128 if (overflow)
5129 return NULL_RTX;
5130 break;
5132 case UDIV:
5133 result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5134 if (overflow)
5135 return NULL_RTX;
5136 break;
5138 case UMOD:
5139 result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5140 if (overflow)
5141 return NULL_RTX;
5142 break;
5144 case AND:
5145 result = wi::bit_and (pop0, pop1);
5146 break;
5148 case IOR:
5149 result = wi::bit_or (pop0, pop1);
5150 break;
5152 case XOR:
5153 result = wi::bit_xor (pop0, pop1);
5154 break;
5156 case SMIN:
5157 result = wi::smin (pop0, pop1);
5158 break;
5160 case SMAX:
5161 result = wi::smax (pop0, pop1);
5162 break;
5164 case UMIN:
5165 result = wi::umin (pop0, pop1);
5166 break;
5168 case UMAX:
5169 result = wi::umax (pop0, pop1);
5170 break;
5172 case LSHIFTRT:
5173 case ASHIFTRT:
5174 case ASHIFT:
5175 case SS_ASHIFT:
5176 case US_ASHIFT:
5178 /* The shift count might be in SImode while int_mode might
5179 be narrower. On IA-64 it is even DImode. If the shift
5180 count is too large and doesn't fit into int_mode, we'd
5181 ICE. So, if int_mode is narrower than word, use
5182 word_mode for the shift count. */
5183 if (GET_MODE (op1) == VOIDmode
5184 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5185 pop1 = rtx_mode_t (op1, word_mode);
5187 wide_int wop1 = pop1;
5188 if (SHIFT_COUNT_TRUNCATED)
5189 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
5190 else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
5191 return NULL_RTX;
5193 switch (code)
5195 case LSHIFTRT:
5196 result = wi::lrshift (pop0, wop1);
5197 break;
5199 case ASHIFTRT:
5200 result = wi::arshift (pop0, wop1);
5201 break;
5203 case ASHIFT:
5204 result = wi::lshift (pop0, wop1);
5205 break;
5207 case SS_ASHIFT:
5208 if (wi::leu_p (wop1, wi::clrsb (pop0)))
5209 result = wi::lshift (pop0, wop1);
5210 else if (wi::neg_p (pop0))
5211 result = wi::min_value (int_mode, SIGNED);
5212 else
5213 result = wi::max_value (int_mode, SIGNED);
5214 break;
5216 case US_ASHIFT:
5217 if (wi::eq_p (pop0, 0))
5218 result = pop0;
5219 else if (wi::leu_p (wop1, wi::clz (pop0)))
5220 result = wi::lshift (pop0, wop1);
5221 else
5222 result = wi::max_value (int_mode, UNSIGNED);
5223 break;
5225 default:
5226 gcc_unreachable ();
5228 break;
5230 case ROTATE:
5231 case ROTATERT:
5233 /* The rotate count might be in SImode while int_mode might
5234 be narrower. On IA-64 it is even DImode. If the shift
5235 count is too large and doesn't fit into int_mode, we'd
5236 ICE. So, if int_mode is narrower than word, use
5237 word_mode for the shift count. */
5238 if (GET_MODE (op1) == VOIDmode
5239 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5240 pop1 = rtx_mode_t (op1, word_mode);
5242 if (wi::neg_p (pop1))
5243 return NULL_RTX;
5245 switch (code)
5247 case ROTATE:
5248 result = wi::lrotate (pop0, pop1);
5249 break;
5251 case ROTATERT:
5252 result = wi::rrotate (pop0, pop1);
5253 break;
5255 default:
5256 gcc_unreachable ();
5258 break;
5261 case SS_PLUS:
5262 result = wi::add (pop0, pop1, SIGNED, &overflow);
5263 clamp_signed_saturation:
5264 if (overflow == wi::OVF_OVERFLOW)
5265 result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
5266 else if (overflow == wi::OVF_UNDERFLOW)
5267 result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
5268 else if (overflow != wi::OVF_NONE)
5269 return NULL_RTX;
5270 break;
5272 case US_PLUS:
5273 result = wi::add (pop0, pop1, UNSIGNED, &overflow);
5274 clamp_unsigned_saturation:
5275 if (overflow != wi::OVF_NONE)
5276 result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5277 break;
5279 case SS_MINUS:
5280 result = wi::sub (pop0, pop1, SIGNED, &overflow);
5281 goto clamp_signed_saturation;
5283 case US_MINUS:
5284 result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
5285 if (overflow != wi::OVF_NONE)
5286 result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5287 break;
5289 case SS_MULT:
5290 result = wi::mul (pop0, pop1, SIGNED, &overflow);
5291 goto clamp_signed_saturation;
5293 case US_MULT:
5294 result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
5295 goto clamp_unsigned_saturation;
5297 case SMUL_HIGHPART:
5298 result = wi::mul_high (pop0, pop1, SIGNED);
5299 break;
5301 case UMUL_HIGHPART:
5302 result = wi::mul_high (pop0, pop1, UNSIGNED);
5303 break;
5305 default:
5306 return NULL_RTX;
5308 return immed_wide_int_const (result, int_mode);
5311 /* Handle polynomial integers. */
5312 if (NUM_POLY_INT_COEFFS > 1
5313 && is_a <scalar_int_mode> (mode, &int_mode)
5314 && poly_int_rtx_p (op0)
5315 && poly_int_rtx_p (op1))
5317 poly_wide_int result;
5318 switch (code)
5320 case PLUS:
5321 result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
5322 break;
5324 case MINUS:
5325 result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
5326 break;
5328 case MULT:
5329 if (CONST_SCALAR_INT_P (op1))
5330 result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
5331 else
5332 return NULL_RTX;
5333 break;
5335 case ASHIFT:
5336 if (CONST_SCALAR_INT_P (op1))
5338 wide_int shift
5339 = rtx_mode_t (op1,
5340 GET_MODE (op1) == VOIDmode
5341 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
5342 ? word_mode : mode);
5343 if (SHIFT_COUNT_TRUNCATED)
5344 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
5345 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
5346 return NULL_RTX;
5347 result = wi::to_poly_wide (op0, mode) << shift;
5349 else
5350 return NULL_RTX;
5351 break;
5353 case IOR:
5354 if (!CONST_SCALAR_INT_P (op1)
5355 || !can_ior_p (wi::to_poly_wide (op0, mode),
5356 rtx_mode_t (op1, mode), &result))
5357 return NULL_RTX;
5358 break;
5360 default:
5361 return NULL_RTX;
5363 return immed_wide_int_const (result, int_mode);
5366 return NULL_RTX;
5371 /* Return a positive integer if X should sort after Y. The value
5372 returned is 1 if and only if X and Y are both regs. */
5374 static int
5375 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
5377 int result;
5379 result = (commutative_operand_precedence (y)
5380 - commutative_operand_precedence (x));
5381 if (result)
5382 return result + result;
5384 /* Group together equal REGs to do more simplification. */
5385 if (REG_P (x) && REG_P (y))
5386 return REGNO (x) > REGNO (y);
5388 return 0;
5391 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5392 operands may be another PLUS or MINUS.
5394 Rather than test for specific case, we do this by a brute-force method
5395 and do all possible simplifications until no more changes occur. Then
5396 we rebuild the operation.
5398 May return NULL_RTX when no changes were made. */
5401 simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
5402 rtx op0, rtx op1)
5404 struct simplify_plus_minus_op_data
5406 rtx op;
5407 short neg;
5408 } ops[16];
5409 rtx result, tem;
5410 int n_ops = 2;
5411 int changed, n_constants, canonicalized = 0;
5412 int i, j;
5414 memset (ops, 0, sizeof ops);
5416 /* Set up the two operands and then expand them until nothing has been
5417 changed. If we run out of room in our array, give up; this should
5418 almost never happen. */
5420 ops[0].op = op0;
5421 ops[0].neg = 0;
5422 ops[1].op = op1;
5423 ops[1].neg = (code == MINUS);
5427 changed = 0;
5428 n_constants = 0;
5430 for (i = 0; i < n_ops; i++)
5432 rtx this_op = ops[i].op;
5433 int this_neg = ops[i].neg;
5434 enum rtx_code this_code = GET_CODE (this_op);
5436 switch (this_code)
5438 case PLUS:
5439 case MINUS:
5440 if (n_ops == ARRAY_SIZE (ops))
5441 return NULL_RTX;
5443 ops[n_ops].op = XEXP (this_op, 1);
5444 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
5445 n_ops++;
5447 ops[i].op = XEXP (this_op, 0);
5448 changed = 1;
5449 /* If this operand was negated then we will potentially
5450 canonicalize the expression. Similarly if we don't
5451 place the operands adjacent we're re-ordering the
5452 expression and thus might be performing a
5453 canonicalization. Ignore register re-ordering.
5454 ??? It might be better to shuffle the ops array here,
5455 but then (plus (plus (A, B), plus (C, D))) wouldn't
5456 be seen as non-canonical. */
5457 if (this_neg
5458 || (i != n_ops - 2
5459 && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
5460 canonicalized = 1;
5461 break;
5463 case NEG:
5464 ops[i].op = XEXP (this_op, 0);
5465 ops[i].neg = ! this_neg;
5466 changed = 1;
5467 canonicalized = 1;
5468 break;
5470 case CONST:
5471 if (n_ops != ARRAY_SIZE (ops)
5472 && GET_CODE (XEXP (this_op, 0)) == PLUS
5473 && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
5474 && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
5476 ops[i].op = XEXP (XEXP (this_op, 0), 0);
5477 ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
5478 ops[n_ops].neg = this_neg;
5479 n_ops++;
5480 changed = 1;
5481 canonicalized = 1;
5483 break;
5485 case NOT:
5486 /* ~a -> (-a - 1) */
5487 if (n_ops != ARRAY_SIZE (ops))
5489 ops[n_ops].op = CONSTM1_RTX (mode);
5490 ops[n_ops++].neg = this_neg;
5491 ops[i].op = XEXP (this_op, 0);
5492 ops[i].neg = !this_neg;
5493 changed = 1;
5494 canonicalized = 1;
5496 break;
5498 CASE_CONST_SCALAR_INT:
5499 case CONST_POLY_INT:
5500 n_constants++;
5501 if (this_neg)
5503 ops[i].op = neg_poly_int_rtx (mode, this_op);
5504 ops[i].neg = 0;
5505 changed = 1;
5506 canonicalized = 1;
5508 break;
5510 default:
5511 break;
5515 while (changed);
5517 if (n_constants > 1)
5518 canonicalized = 1;
5520 gcc_assert (n_ops >= 2);
5522 /* If we only have two operands, we can avoid the loops. */
5523 if (n_ops == 2)
5525 enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
5526 rtx lhs, rhs;
5528 /* Get the two operands. Be careful with the order, especially for
5529 the cases where code == MINUS. */
5530 if (ops[0].neg && ops[1].neg)
5532 lhs = gen_rtx_NEG (mode, ops[0].op);
5533 rhs = ops[1].op;
5535 else if (ops[0].neg)
5537 lhs = ops[1].op;
5538 rhs = ops[0].op;
5540 else
5542 lhs = ops[0].op;
5543 rhs = ops[1].op;
5546 return simplify_const_binary_operation (code, mode, lhs, rhs);
5549 /* Now simplify each pair of operands until nothing changes. */
5550 while (1)
5552 /* Insertion sort is good enough for a small array. */
5553 for (i = 1; i < n_ops; i++)
5555 struct simplify_plus_minus_op_data save;
5556 int cmp;
5558 j = i - 1;
5559 cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
5560 if (cmp <= 0)
5561 continue;
5562 /* Just swapping registers doesn't count as canonicalization. */
5563 if (cmp != 1)
5564 canonicalized = 1;
5566 save = ops[i];
5568 ops[j + 1] = ops[j];
5569 while (j--
5570 && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
5571 ops[j + 1] = save;
5574 changed = 0;
5575 for (i = n_ops - 1; i > 0; i--)
5576 for (j = i - 1; j >= 0; j--)
5578 rtx lhs = ops[j].op, rhs = ops[i].op;
5579 int lneg = ops[j].neg, rneg = ops[i].neg;
5581 if (lhs != 0 && rhs != 0)
5583 enum rtx_code ncode = PLUS;
5585 if (lneg != rneg)
5587 ncode = MINUS;
5588 if (lneg)
5589 std::swap (lhs, rhs);
5591 else if (swap_commutative_operands_p (lhs, rhs))
5592 std::swap (lhs, rhs);
5594 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
5595 && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
5597 rtx tem_lhs, tem_rhs;
5599 tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
5600 tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
5601 tem = simplify_binary_operation (ncode, mode, tem_lhs,
5602 tem_rhs);
5604 if (tem && !CONSTANT_P (tem))
5605 tem = gen_rtx_CONST (GET_MODE (tem), tem);
5607 else
5608 tem = simplify_binary_operation (ncode, mode, lhs, rhs);
5610 if (tem)
5612 /* Reject "simplifications" that just wrap the two
5613 arguments in a CONST. Failure to do so can result
5614 in infinite recursion with simplify_binary_operation
5615 when it calls us to simplify CONST operations.
5616 Also, if we find such a simplification, don't try
5617 any more combinations with this rhs: We must have
5618 something like symbol+offset, ie. one of the
5619 trivial CONST expressions we handle later. */
5620 if (GET_CODE (tem) == CONST
5621 && GET_CODE (XEXP (tem, 0)) == ncode
5622 && XEXP (XEXP (tem, 0), 0) == lhs
5623 && XEXP (XEXP (tem, 0), 1) == rhs)
5624 break;
5625 lneg &= rneg;
5626 if (GET_CODE (tem) == NEG)
5627 tem = XEXP (tem, 0), lneg = !lneg;
5628 if (poly_int_rtx_p (tem) && lneg)
5629 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
5631 ops[i].op = tem;
5632 ops[i].neg = lneg;
5633 ops[j].op = NULL_RTX;
5634 changed = 1;
5635 canonicalized = 1;
5640 if (!changed)
5641 break;
5643 /* Pack all the operands to the lower-numbered entries. */
5644 for (i = 0, j = 0; j < n_ops; j++)
5645 if (ops[j].op)
5647 ops[i] = ops[j];
5648 i++;
5650 n_ops = i;
5653 /* If nothing changed, check that rematerialization of rtl instructions
5654 is still required. */
5655 if (!canonicalized)
5657 /* Perform rematerialization if only all operands are registers and
5658 all operations are PLUS. */
5659 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5660 around rs6000 and how it uses the CA register. See PR67145. */
5661 for (i = 0; i < n_ops; i++)
5662 if (ops[i].neg
5663 || !REG_P (ops[i].op)
5664 || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5665 && fixed_regs[REGNO (ops[i].op)]
5666 && !global_regs[REGNO (ops[i].op)]
5667 && ops[i].op != frame_pointer_rtx
5668 && ops[i].op != arg_pointer_rtx
5669 && ops[i].op != stack_pointer_rtx))
5670 return NULL_RTX;
5671 goto gen_result;
5674 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5675 if (n_ops == 2
5676 && CONST_INT_P (ops[1].op)
5677 && CONSTANT_P (ops[0].op)
5678 && ops[0].neg)
5679 return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5681 /* We suppressed creation of trivial CONST expressions in the
5682 combination loop to avoid recursion. Create one manually now.
5683 The combination loop should have ensured that there is exactly
5684 one CONST_INT, and the sort will have ensured that it is last
5685 in the array and that any other constant will be next-to-last. */
5687 if (n_ops > 1
5688 && poly_int_rtx_p (ops[n_ops - 1].op)
5689 && CONSTANT_P (ops[n_ops - 2].op))
5691 rtx value = ops[n_ops - 1].op;
5692 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5693 value = neg_poly_int_rtx (mode, value);
5694 if (CONST_INT_P (value))
5696 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5697 INTVAL (value));
5698 n_ops--;
5702 /* Put a non-negated operand first, if possible. */
5704 for (i = 0; i < n_ops && ops[i].neg; i++)
5705 continue;
5706 if (i == n_ops)
5707 ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5708 else if (i != 0)
5710 tem = ops[0].op;
5711 ops[0] = ops[i];
5712 ops[i].op = tem;
5713 ops[i].neg = 1;
5716 /* Now make the result by performing the requested operations. */
5717 gen_result:
5718 result = ops[0].op;
5719 for (i = 1; i < n_ops; i++)
5720 result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5721 mode, result, ops[i].op);
5723 return result;
5726 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5727 static bool
5728 plus_minus_operand_p (const_rtx x)
5730 return GET_CODE (x) == PLUS
5731 || GET_CODE (x) == MINUS
5732 || (GET_CODE (x) == CONST
5733 && GET_CODE (XEXP (x, 0)) == PLUS
5734 && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5735 && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5738 /* Like simplify_binary_operation except used for relational operators.
5739 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5740 not also be VOIDmode.
5742 CMP_MODE specifies in which mode the comparison is done in, so it is
5743 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5744 the operands or, if both are VOIDmode, the operands are compared in
5745 "infinite precision". */
5747 simplify_context::simplify_relational_operation (rtx_code code,
5748 machine_mode mode,
5749 machine_mode cmp_mode,
5750 rtx op0, rtx op1)
5752 rtx tem, trueop0, trueop1;
5754 if (cmp_mode == VOIDmode)
5755 cmp_mode = GET_MODE (op0);
5756 if (cmp_mode == VOIDmode)
5757 cmp_mode = GET_MODE (op1);
5759 tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5760 if (tem)
5761 return relational_result (mode, cmp_mode, tem);
5763 /* For the following tests, ensure const0_rtx is op1. */
5764 if (swap_commutative_operands_p (op0, op1)
5765 || (op0 == const0_rtx && op1 != const0_rtx))
5766 std::swap (op0, op1), code = swap_condition (code);
5768 /* If op0 is a compare, extract the comparison arguments from it. */
5769 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5770 return simplify_gen_relational (code, mode, VOIDmode,
5771 XEXP (op0, 0), XEXP (op0, 1));
5773 if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
5774 return NULL_RTX;
5776 trueop0 = avoid_constant_pool_reference (op0);
5777 trueop1 = avoid_constant_pool_reference (op1);
5778 return simplify_relational_operation_1 (code, mode, cmp_mode,
5779 trueop0, trueop1);
5782 /* This part of simplify_relational_operation is only used when CMP_MODE
5783 is not in class MODE_CC (i.e. it is a real comparison).
5785 MODE is the mode of the result, while CMP_MODE specifies in which
5786 mode the comparison is done in, so it is the mode of the operands. */
5789 simplify_context::simplify_relational_operation_1 (rtx_code code,
5790 machine_mode mode,
5791 machine_mode cmp_mode,
5792 rtx op0, rtx op1)
5794 enum rtx_code op0code = GET_CODE (op0);
5796 if (op1 == const0_rtx && COMPARISON_P (op0))
5798 /* If op0 is a comparison, extract the comparison arguments
5799 from it. */
5800 if (code == NE)
5802 if (GET_MODE (op0) == mode)
5803 return simplify_rtx (op0);
5804 else
5805 return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5806 XEXP (op0, 0), XEXP (op0, 1));
5808 else if (code == EQ)
5810 enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5811 if (new_code != UNKNOWN)
5812 return simplify_gen_relational (new_code, mode, VOIDmode,
5813 XEXP (op0, 0), XEXP (op0, 1));
5817 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5818 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5819 if ((code == LTU || code == GEU)
5820 && GET_CODE (op0) == PLUS
5821 && CONST_INT_P (XEXP (op0, 1))
5822 && (rtx_equal_p (op1, XEXP (op0, 0))
5823 || rtx_equal_p (op1, XEXP (op0, 1)))
5824 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5825 && XEXP (op0, 1) != const0_rtx)
5827 rtx new_cmp
5828 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5829 return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5830 cmp_mode, XEXP (op0, 0), new_cmp);
5833 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5834 transformed into (LTU a -C). */
5835 if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5836 && CONST_INT_P (XEXP (op0, 1))
5837 && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5838 && XEXP (op0, 1) != const0_rtx)
5840 rtx new_cmp
5841 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5842 return simplify_gen_relational (LTU, mode, cmp_mode,
5843 XEXP (op0, 0), new_cmp);
5846 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5847 if ((code == LTU || code == GEU)
5848 && GET_CODE (op0) == PLUS
5849 && rtx_equal_p (op1, XEXP (op0, 1))
5850 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5851 && !rtx_equal_p (op1, XEXP (op0, 0)))
5852 return simplify_gen_relational (code, mode, cmp_mode, op0,
5853 copy_rtx (XEXP (op0, 0)));
5855 if (op1 == const0_rtx)
5857 /* Canonicalize (GTU x 0) as (NE x 0). */
5858 if (code == GTU)
5859 return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5860 /* Canonicalize (LEU x 0) as (EQ x 0). */
5861 if (code == LEU)
5862 return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5864 else if (op1 == const1_rtx)
5866 switch (code)
5868 case GE:
5869 /* Canonicalize (GE x 1) as (GT x 0). */
5870 return simplify_gen_relational (GT, mode, cmp_mode,
5871 op0, const0_rtx);
5872 case GEU:
5873 /* Canonicalize (GEU x 1) as (NE x 0). */
5874 return simplify_gen_relational (NE, mode, cmp_mode,
5875 op0, const0_rtx);
5876 case LT:
5877 /* Canonicalize (LT x 1) as (LE x 0). */
5878 return simplify_gen_relational (LE, mode, cmp_mode,
5879 op0, const0_rtx);
5880 case LTU:
5881 /* Canonicalize (LTU x 1) as (EQ x 0). */
5882 return simplify_gen_relational (EQ, mode, cmp_mode,
5883 op0, const0_rtx);
5884 default:
5885 break;
5888 else if (op1 == constm1_rtx)
5890 /* Canonicalize (LE x -1) as (LT x 0). */
5891 if (code == LE)
5892 return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5893 /* Canonicalize (GT x -1) as (GE x 0). */
5894 if (code == GT)
5895 return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5898 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5899 if ((code == EQ || code == NE)
5900 && (op0code == PLUS || op0code == MINUS)
5901 && CONSTANT_P (op1)
5902 && CONSTANT_P (XEXP (op0, 1))
5903 && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5905 rtx x = XEXP (op0, 0);
5906 rtx c = XEXP (op0, 1);
5907 enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5908 rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5910 /* Detect an infinite recursive condition, where we oscillate at this
5911 simplification case between:
5912 A + B == C <---> C - B == A,
5913 where A, B, and C are all constants with non-simplifiable expressions,
5914 usually SYMBOL_REFs. */
5915 if (GET_CODE (tem) == invcode
5916 && CONSTANT_P (x)
5917 && rtx_equal_p (c, XEXP (tem, 1)))
5918 return NULL_RTX;
5920 return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5923 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5924 the same as (zero_extract:SI FOO (const_int 1) BAR). */
5925 scalar_int_mode int_mode, int_cmp_mode;
5926 if (code == NE
5927 && op1 == const0_rtx
5928 && is_int_mode (mode, &int_mode)
5929 && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5930 /* ??? Work-around BImode bugs in the ia64 backend. */
5931 && int_mode != BImode
5932 && int_cmp_mode != BImode
5933 && nonzero_bits (op0, int_cmp_mode) == 1
5934 && STORE_FLAG_VALUE == 1)
5935 return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5936 ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5937 : lowpart_subreg (int_mode, op0, int_cmp_mode);
5939 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
5940 if ((code == EQ || code == NE)
5941 && op1 == const0_rtx
5942 && op0code == XOR)
5943 return simplify_gen_relational (code, mode, cmp_mode,
5944 XEXP (op0, 0), XEXP (op0, 1));
5946 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
5947 if ((code == EQ || code == NE)
5948 && op0code == XOR
5949 && rtx_equal_p (XEXP (op0, 0), op1)
5950 && !side_effects_p (XEXP (op0, 0)))
5951 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5952 CONST0_RTX (mode));
5954 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
5955 if ((code == EQ || code == NE)
5956 && op0code == XOR
5957 && rtx_equal_p (XEXP (op0, 1), op1)
5958 && !side_effects_p (XEXP (op0, 1)))
5959 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5960 CONST0_RTX (mode));
5962 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
5963 if ((code == EQ || code == NE)
5964 && op0code == XOR
5965 && CONST_SCALAR_INT_P (op1)
5966 && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5967 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5968 simplify_gen_binary (XOR, cmp_mode,
5969 XEXP (op0, 1), op1));
5971 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5972 constant folding if x/y is a constant. */
5973 if ((code == EQ || code == NE)
5974 && (op0code == AND || op0code == IOR)
5975 && !side_effects_p (op1)
5976 && op1 != CONST0_RTX (cmp_mode))
5978 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5979 (eq/ne (and (not y) x) 0). */
5980 if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5981 || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5983 rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5984 cmp_mode);
5985 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5987 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5988 CONST0_RTX (cmp_mode));
5991 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5992 (eq/ne (and (not x) y) 0). */
5993 if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5994 || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5996 rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5997 cmp_mode);
5998 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6000 return simplify_gen_relational (code, mode, cmp_mode, lhs,
6001 CONST0_RTX (cmp_mode));
6005 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6006 if ((code == EQ || code == NE)
6007 && GET_CODE (op0) == BSWAP
6008 && CONST_SCALAR_INT_P (op1))
6009 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6010 simplify_gen_unary (BSWAP, cmp_mode,
6011 op1, cmp_mode));
6013 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6014 if ((code == EQ || code == NE)
6015 && GET_CODE (op0) == BSWAP
6016 && GET_CODE (op1) == BSWAP)
6017 return simplify_gen_relational (code, mode, cmp_mode,
6018 XEXP (op0, 0), XEXP (op1, 0));
6020 if (op0code == POPCOUNT && op1 == const0_rtx)
6021 switch (code)
6023 case EQ:
6024 case LE:
6025 case LEU:
6026 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6027 return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6028 XEXP (op0, 0), const0_rtx);
6030 case NE:
6031 case GT:
6032 case GTU:
6033 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6034 return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6035 XEXP (op0, 0), const0_rtx);
6037 default:
6038 break;
6041 return NULL_RTX;
6044 enum
6046 CMP_EQ = 1,
6047 CMP_LT = 2,
6048 CMP_GT = 4,
6049 CMP_LTU = 8,
6050 CMP_GTU = 16
6054 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6055 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6056 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6057 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6058 For floating-point comparisons, assume that the operands were ordered. */
6060 static rtx
6061 comparison_result (enum rtx_code code, int known_results)
6063 switch (code)
6065 case EQ:
6066 case UNEQ:
6067 return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
6068 case NE:
6069 case LTGT:
6070 return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
6072 case LT:
6073 case UNLT:
6074 return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
6075 case GE:
6076 case UNGE:
6077 return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
6079 case GT:
6080 case UNGT:
6081 return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
6082 case LE:
6083 case UNLE:
6084 return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
6086 case LTU:
6087 return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
6088 case GEU:
6089 return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
6091 case GTU:
6092 return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
6093 case LEU:
6094 return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
6096 case ORDERED:
6097 return const_true_rtx;
6098 case UNORDERED:
6099 return const0_rtx;
6100 default:
6101 gcc_unreachable ();
6105 /* Check if the given comparison (done in the given MODE) is actually
6106 a tautology or a contradiction. If the mode is VOIDmode, the
6107 comparison is done in "infinite precision". If no simplification
6108 is possible, this function returns zero. Otherwise, it returns
6109 either const_true_rtx or const0_rtx. */
6112 simplify_const_relational_operation (enum rtx_code code,
6113 machine_mode mode,
6114 rtx op0, rtx op1)
6116 rtx tem;
6117 rtx trueop0;
6118 rtx trueop1;
6120 gcc_assert (mode != VOIDmode
6121 || (GET_MODE (op0) == VOIDmode
6122 && GET_MODE (op1) == VOIDmode));
6124 /* We only handle MODE_CC comparisons that are COMPARE against zero. */
6125 if (GET_MODE_CLASS (mode) == MODE_CC
6126 && (op1 != const0_rtx
6127 || GET_CODE (op0) != COMPARE))
6128 return NULL_RTX;
6130 /* If op0 is a compare, extract the comparison arguments from it. */
6131 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6133 op1 = XEXP (op0, 1);
6134 op0 = XEXP (op0, 0);
6136 if (GET_MODE (op0) != VOIDmode)
6137 mode = GET_MODE (op0);
6138 else if (GET_MODE (op1) != VOIDmode)
6139 mode = GET_MODE (op1);
6140 else
6141 return 0;
6144 /* We can't simplify MODE_CC values since we don't know what the
6145 actual comparison is. */
6146 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
6147 return 0;
6149 /* Make sure the constant is second. */
6150 if (swap_commutative_operands_p (op0, op1))
6152 std::swap (op0, op1);
6153 code = swap_condition (code);
6156 trueop0 = avoid_constant_pool_reference (op0);
6157 trueop1 = avoid_constant_pool_reference (op1);
6159 /* For integer comparisons of A and B maybe we can simplify A - B and can
6160 then simplify a comparison of that with zero. If A and B are both either
6161 a register or a CONST_INT, this can't help; testing for these cases will
6162 prevent infinite recursion here and speed things up.
6164 We can only do this for EQ and NE comparisons as otherwise we may
6165 lose or introduce overflow which we cannot disregard as undefined as
6166 we do not know the signedness of the operation on either the left or
6167 the right hand side of the comparison. */
6169 if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
6170 && (code == EQ || code == NE)
6171 && ! ((REG_P (op0) || CONST_INT_P (trueop0))
6172 && (REG_P (op1) || CONST_INT_P (trueop1)))
6173 && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
6174 /* We cannot do this if tem is a nonzero address. */
6175 && ! nonzero_address_p (tem))
6176 return simplify_const_relational_operation (signed_condition (code),
6177 mode, tem, const0_rtx);
6179 if (! HONOR_NANS (mode) && code == ORDERED)
6180 return const_true_rtx;
6182 if (! HONOR_NANS (mode) && code == UNORDERED)
6183 return const0_rtx;
6185 /* For modes without NaNs, if the two operands are equal, we know the
6186 result except if they have side-effects. Even with NaNs we know
6187 the result of unordered comparisons and, if signaling NaNs are
6188 irrelevant, also the result of LT/GT/LTGT. */
6189 if ((! HONOR_NANS (trueop0)
6190 || code == UNEQ || code == UNLE || code == UNGE
6191 || ((code == LT || code == GT || code == LTGT)
6192 && ! HONOR_SNANS (trueop0)))
6193 && rtx_equal_p (trueop0, trueop1)
6194 && ! side_effects_p (trueop0))
6195 return comparison_result (code, CMP_EQ);
6197 /* If the operands are floating-point constants, see if we can fold
6198 the result. */
6199 if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
6200 && CONST_DOUBLE_AS_FLOAT_P (trueop1)
6201 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
6203 const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
6204 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
6206 /* Comparisons are unordered iff at least one of the values is NaN. */
6207 if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
6208 switch (code)
6210 case UNEQ:
6211 case UNLT:
6212 case UNGT:
6213 case UNLE:
6214 case UNGE:
6215 case NE:
6216 case UNORDERED:
6217 return const_true_rtx;
6218 case EQ:
6219 case LT:
6220 case GT:
6221 case LE:
6222 case GE:
6223 case LTGT:
6224 case ORDERED:
6225 return const0_rtx;
6226 default:
6227 return 0;
6230 return comparison_result (code,
6231 (real_equal (d0, d1) ? CMP_EQ :
6232 real_less (d0, d1) ? CMP_LT : CMP_GT));
6235 /* Otherwise, see if the operands are both integers. */
6236 if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
6237 && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
6239 /* It would be nice if we really had a mode here. However, the
6240 largest int representable on the target is as good as
6241 infinite. */
6242 machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
6243 rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
6244 rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
6246 if (wi::eq_p (ptrueop0, ptrueop1))
6247 return comparison_result (code, CMP_EQ);
6248 else
6250 int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
6251 cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
6252 return comparison_result (code, cr);
6256 /* Optimize comparisons with upper and lower bounds. */
6257 scalar_int_mode int_mode;
6258 if (CONST_INT_P (trueop1)
6259 && is_a <scalar_int_mode> (mode, &int_mode)
6260 && HWI_COMPUTABLE_MODE_P (int_mode)
6261 && !side_effects_p (trueop0))
6263 int sign;
6264 unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
6265 HOST_WIDE_INT val = INTVAL (trueop1);
6266 HOST_WIDE_INT mmin, mmax;
6268 if (code == GEU
6269 || code == LEU
6270 || code == GTU
6271 || code == LTU)
6272 sign = 0;
6273 else
6274 sign = 1;
6276 /* Get a reduced range if the sign bit is zero. */
6277 if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
6279 mmin = 0;
6280 mmax = nonzero;
6282 else
6284 rtx mmin_rtx, mmax_rtx;
6285 get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
6287 mmin = INTVAL (mmin_rtx);
6288 mmax = INTVAL (mmax_rtx);
6289 if (sign)
6291 unsigned int sign_copies
6292 = num_sign_bit_copies (trueop0, int_mode);
6294 mmin >>= (sign_copies - 1);
6295 mmax >>= (sign_copies - 1);
6299 switch (code)
6301 /* x >= y is always true for y <= mmin, always false for y > mmax. */
6302 case GEU:
6303 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6304 return const_true_rtx;
6305 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6306 return const0_rtx;
6307 break;
6308 case GE:
6309 if (val <= mmin)
6310 return const_true_rtx;
6311 if (val > mmax)
6312 return const0_rtx;
6313 break;
6315 /* x <= y is always true for y >= mmax, always false for y < mmin. */
6316 case LEU:
6317 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6318 return const_true_rtx;
6319 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6320 return const0_rtx;
6321 break;
6322 case LE:
6323 if (val >= mmax)
6324 return const_true_rtx;
6325 if (val < mmin)
6326 return const0_rtx;
6327 break;
6329 case EQ:
6330 /* x == y is always false for y out of range. */
6331 if (val < mmin || val > mmax)
6332 return const0_rtx;
6333 break;
6335 /* x > y is always false for y >= mmax, always true for y < mmin. */
6336 case GTU:
6337 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6338 return const0_rtx;
6339 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6340 return const_true_rtx;
6341 break;
6342 case GT:
6343 if (val >= mmax)
6344 return const0_rtx;
6345 if (val < mmin)
6346 return const_true_rtx;
6347 break;
6349 /* x < y is always false for y <= mmin, always true for y > mmax. */
6350 case LTU:
6351 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6352 return const0_rtx;
6353 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6354 return const_true_rtx;
6355 break;
6356 case LT:
6357 if (val <= mmin)
6358 return const0_rtx;
6359 if (val > mmax)
6360 return const_true_rtx;
6361 break;
6363 case NE:
6364 /* x != y is always true for y out of range. */
6365 if (val < mmin || val > mmax)
6366 return const_true_rtx;
6367 break;
6369 default:
6370 break;
6374 /* Optimize integer comparisons with zero. */
6375 if (is_a <scalar_int_mode> (mode, &int_mode)
6376 && trueop1 == const0_rtx
6377 && !side_effects_p (trueop0))
6379 /* Some addresses are known to be nonzero. We don't know
6380 their sign, but equality comparisons are known. */
6381 if (nonzero_address_p (trueop0))
6383 if (code == EQ || code == LEU)
6384 return const0_rtx;
6385 if (code == NE || code == GTU)
6386 return const_true_rtx;
6389 /* See if the first operand is an IOR with a constant. If so, we
6390 may be able to determine the result of this comparison. */
6391 if (GET_CODE (op0) == IOR)
6393 rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
6394 if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
6396 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
6397 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
6398 && (UINTVAL (inner_const)
6399 & (HOST_WIDE_INT_1U
6400 << sign_bitnum)));
6402 switch (code)
6404 case EQ:
6405 case LEU:
6406 return const0_rtx;
6407 case NE:
6408 case GTU:
6409 return const_true_rtx;
6410 case LT:
6411 case LE:
6412 if (has_sign)
6413 return const_true_rtx;
6414 break;
6415 case GT:
6416 case GE:
6417 if (has_sign)
6418 return const0_rtx;
6419 break;
6420 default:
6421 break;
6427 /* Optimize comparison of ABS with zero. */
6428 if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
6429 && (GET_CODE (trueop0) == ABS
6430 || (GET_CODE (trueop0) == FLOAT_EXTEND
6431 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
6433 switch (code)
6435 case LT:
6436 /* Optimize abs(x) < 0.0. */
6437 if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
6438 return const0_rtx;
6439 break;
6441 case GE:
6442 /* Optimize abs(x) >= 0.0. */
6443 if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
6444 return const_true_rtx;
6445 break;
6447 case UNGE:
6448 /* Optimize ! (abs(x) < 0.0). */
6449 return const_true_rtx;
6451 default:
6452 break;
6456 return 0;
6459 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6460 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6461 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6462 can be simplified to that or NULL_RTX if not.
6463 Assume X is compared against zero with CMP_CODE and the true
6464 arm is TRUE_VAL and the false arm is FALSE_VAL. */
6467 simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
6468 rtx true_val, rtx false_val)
6470 if (cmp_code != EQ && cmp_code != NE)
6471 return NULL_RTX;
6473 /* Result on X == 0 and X !=0 respectively. */
6474 rtx on_zero, on_nonzero;
6475 if (cmp_code == EQ)
6477 on_zero = true_val;
6478 on_nonzero = false_val;
6480 else
6482 on_zero = false_val;
6483 on_nonzero = true_val;
6486 rtx_code op_code = GET_CODE (on_nonzero);
6487 if ((op_code != CLZ && op_code != CTZ)
6488 || !rtx_equal_p (XEXP (on_nonzero, 0), x)
6489 || !CONST_INT_P (on_zero))
6490 return NULL_RTX;
6492 HOST_WIDE_INT op_val;
6493 scalar_int_mode mode ATTRIBUTE_UNUSED
6494 = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
6495 if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
6496 || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
6497 && op_val == INTVAL (on_zero))
6498 return on_nonzero;
6500 return NULL_RTX;
6503 /* Try to simplify X given that it appears within operand OP of a
6504 VEC_MERGE operation whose mask is MASK. X need not use the same
6505 vector mode as the VEC_MERGE, but it must have the same number of
6506 elements.
6508 Return the simplified X on success, otherwise return NULL_RTX. */
6511 simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
6513 gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
6514 poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
6515 if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
6517 if (side_effects_p (XEXP (x, 1 - op)))
6518 return NULL_RTX;
6520 return XEXP (x, op);
6522 if (UNARY_P (x)
6523 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6524 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
6526 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6527 if (top0)
6528 return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
6529 GET_MODE (XEXP (x, 0)));
6531 if (BINARY_P (x)
6532 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6533 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6534 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6535 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
6537 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6538 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6539 if (top0 || top1)
6541 if (COMPARISON_P (x))
6542 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6543 GET_MODE (XEXP (x, 0)) != VOIDmode
6544 ? GET_MODE (XEXP (x, 0))
6545 : GET_MODE (XEXP (x, 1)),
6546 top0 ? top0 : XEXP (x, 0),
6547 top1 ? top1 : XEXP (x, 1));
6548 else
6549 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
6550 top0 ? top0 : XEXP (x, 0),
6551 top1 ? top1 : XEXP (x, 1));
6554 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
6555 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6556 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6557 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6558 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
6559 && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
6560 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
6562 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6563 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6564 rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
6565 if (top0 || top1 || top2)
6566 return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6567 GET_MODE (XEXP (x, 0)),
6568 top0 ? top0 : XEXP (x, 0),
6569 top1 ? top1 : XEXP (x, 1),
6570 top2 ? top2 : XEXP (x, 2));
6572 return NULL_RTX;
6576 /* Simplify CODE, an operation with result mode MODE and three operands,
6577 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6578 a constant. Return 0 if no simplifications is possible. */
6581 simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
6582 machine_mode op0_mode,
6583 rtx op0, rtx op1, rtx op2)
6585 bool any_change = false;
6586 rtx tem, trueop2;
6587 scalar_int_mode int_mode, int_op0_mode;
6588 unsigned int n_elts;
6590 switch (code)
6592 case FMA:
6593 /* Simplify negations around the multiplication. */
6594 /* -a * -b + c => a * b + c. */
6595 if (GET_CODE (op0) == NEG)
6597 tem = simplify_unary_operation (NEG, mode, op1, mode);
6598 if (tem)
6599 op1 = tem, op0 = XEXP (op0, 0), any_change = true;
6601 else if (GET_CODE (op1) == NEG)
6603 tem = simplify_unary_operation (NEG, mode, op0, mode);
6604 if (tem)
6605 op0 = tem, op1 = XEXP (op1, 0), any_change = true;
6608 /* Canonicalize the two multiplication operands. */
6609 /* a * -b + c => -b * a + c. */
6610 if (swap_commutative_operands_p (op0, op1))
6611 std::swap (op0, op1), any_change = true;
6613 if (any_change)
6614 return gen_rtx_FMA (mode, op0, op1, op2);
6615 return NULL_RTX;
6617 case SIGN_EXTRACT:
6618 case ZERO_EXTRACT:
6619 if (CONST_INT_P (op0)
6620 && CONST_INT_P (op1)
6621 && CONST_INT_P (op2)
6622 && is_a <scalar_int_mode> (mode, &int_mode)
6623 && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
6624 && HWI_COMPUTABLE_MODE_P (int_mode))
6626 /* Extracting a bit-field from a constant */
6627 unsigned HOST_WIDE_INT val = UINTVAL (op0);
6628 HOST_WIDE_INT op1val = INTVAL (op1);
6629 HOST_WIDE_INT op2val = INTVAL (op2);
6630 if (!BITS_BIG_ENDIAN)
6631 val >>= op2val;
6632 else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
6633 val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
6634 else
6635 /* Not enough information to calculate the bit position. */
6636 break;
6638 if (HOST_BITS_PER_WIDE_INT != op1val)
6640 /* First zero-extend. */
6641 val &= (HOST_WIDE_INT_1U << op1val) - 1;
6642 /* If desired, propagate sign bit. */
6643 if (code == SIGN_EXTRACT
6644 && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6645 != 0)
6646 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6649 return gen_int_mode (val, int_mode);
6651 break;
6653 case IF_THEN_ELSE:
6654 if (CONST_INT_P (op0))
6655 return op0 != const0_rtx ? op1 : op2;
6657 /* Convert c ? a : a into "a". */
6658 if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6659 return op1;
6661 /* Convert a != b ? a : b into "a". */
6662 if (GET_CODE (op0) == NE
6663 && ! side_effects_p (op0)
6664 && ! HONOR_NANS (mode)
6665 && ! HONOR_SIGNED_ZEROS (mode)
6666 && ((rtx_equal_p (XEXP (op0, 0), op1)
6667 && rtx_equal_p (XEXP (op0, 1), op2))
6668 || (rtx_equal_p (XEXP (op0, 0), op2)
6669 && rtx_equal_p (XEXP (op0, 1), op1))))
6670 return op1;
6672 /* Convert a == b ? a : b into "b". */
6673 if (GET_CODE (op0) == EQ
6674 && ! side_effects_p (op0)
6675 && ! HONOR_NANS (mode)
6676 && ! HONOR_SIGNED_ZEROS (mode)
6677 && ((rtx_equal_p (XEXP (op0, 0), op1)
6678 && rtx_equal_p (XEXP (op0, 1), op2))
6679 || (rtx_equal_p (XEXP (op0, 0), op2)
6680 && rtx_equal_p (XEXP (op0, 1), op1))))
6681 return op2;
6683 /* Convert (!c) != {0,...,0} ? a : b into
6684 c != {0,...,0} ? b : a for vector modes. */
6685 if (VECTOR_MODE_P (GET_MODE (op1))
6686 && GET_CODE (op0) == NE
6687 && GET_CODE (XEXP (op0, 0)) == NOT
6688 && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6690 rtx cv = XEXP (op0, 1);
6691 int nunits;
6692 bool ok = true;
6693 if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6694 ok = false;
6695 else
6696 for (int i = 0; i < nunits; ++i)
6697 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6699 ok = false;
6700 break;
6702 if (ok)
6704 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6705 XEXP (XEXP (op0, 0), 0),
6706 XEXP (op0, 1));
6707 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6708 return retval;
6712 /* Convert x == 0 ? N : clz (x) into clz (x) when
6713 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6714 Similarly for ctz (x). */
6715 if (COMPARISON_P (op0) && !side_effects_p (op0)
6716 && XEXP (op0, 1) == const0_rtx)
6718 rtx simplified
6719 = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6720 op1, op2);
6721 if (simplified)
6722 return simplified;
6725 if (COMPARISON_P (op0) && ! side_effects_p (op0))
6727 machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6728 ? GET_MODE (XEXP (op0, 1))
6729 : GET_MODE (XEXP (op0, 0)));
6730 rtx temp;
6732 /* Look for happy constants in op1 and op2. */
6733 if (CONST_INT_P (op1) && CONST_INT_P (op2))
6735 HOST_WIDE_INT t = INTVAL (op1);
6736 HOST_WIDE_INT f = INTVAL (op2);
6738 if (t == STORE_FLAG_VALUE && f == 0)
6739 code = GET_CODE (op0);
6740 else if (t == 0 && f == STORE_FLAG_VALUE)
6742 enum rtx_code tmp;
6743 tmp = reversed_comparison_code (op0, NULL);
6744 if (tmp == UNKNOWN)
6745 break;
6746 code = tmp;
6748 else
6749 break;
6751 return simplify_gen_relational (code, mode, cmp_mode,
6752 XEXP (op0, 0), XEXP (op0, 1));
6755 temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6756 cmp_mode, XEXP (op0, 0),
6757 XEXP (op0, 1));
6759 /* See if any simplifications were possible. */
6760 if (temp)
6762 if (CONST_INT_P (temp))
6763 return temp == const0_rtx ? op2 : op1;
6764 else if (temp)
6765 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6768 break;
6770 case VEC_MERGE:
6771 gcc_assert (GET_MODE (op0) == mode);
6772 gcc_assert (GET_MODE (op1) == mode);
6773 gcc_assert (VECTOR_MODE_P (mode));
6774 trueop2 = avoid_constant_pool_reference (op2);
6775 if (CONST_INT_P (trueop2)
6776 && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6778 unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6779 unsigned HOST_WIDE_INT mask;
6780 if (n_elts == HOST_BITS_PER_WIDE_INT)
6781 mask = -1;
6782 else
6783 mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6785 if (!(sel & mask) && !side_effects_p (op0))
6786 return op1;
6787 if ((sel & mask) == mask && !side_effects_p (op1))
6788 return op0;
6790 rtx trueop0 = avoid_constant_pool_reference (op0);
6791 rtx trueop1 = avoid_constant_pool_reference (op1);
6792 if (GET_CODE (trueop0) == CONST_VECTOR
6793 && GET_CODE (trueop1) == CONST_VECTOR)
6795 rtvec v = rtvec_alloc (n_elts);
6796 unsigned int i;
6798 for (i = 0; i < n_elts; i++)
6799 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6800 ? CONST_VECTOR_ELT (trueop0, i)
6801 : CONST_VECTOR_ELT (trueop1, i));
6802 return gen_rtx_CONST_VECTOR (mode, v);
6805 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6806 if no element from a appears in the result. */
6807 if (GET_CODE (op0) == VEC_MERGE)
6809 tem = avoid_constant_pool_reference (XEXP (op0, 2));
6810 if (CONST_INT_P (tem))
6812 unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6813 if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6814 return simplify_gen_ternary (code, mode, mode,
6815 XEXP (op0, 1), op1, op2);
6816 if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6817 return simplify_gen_ternary (code, mode, mode,
6818 XEXP (op0, 0), op1, op2);
6821 if (GET_CODE (op1) == VEC_MERGE)
6823 tem = avoid_constant_pool_reference (XEXP (op1, 2));
6824 if (CONST_INT_P (tem))
6826 unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6827 if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6828 return simplify_gen_ternary (code, mode, mode,
6829 op0, XEXP (op1, 1), op2);
6830 if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6831 return simplify_gen_ternary (code, mode, mode,
6832 op0, XEXP (op1, 0), op2);
6836 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6837 with a. */
6838 if (GET_CODE (op0) == VEC_DUPLICATE
6839 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6840 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6841 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6843 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6844 if (CONST_INT_P (tem) && CONST_INT_P (op2))
6846 if (XEXP (XEXP (op0, 0), 0) == op1
6847 && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6848 return op1;
6851 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6852 (const_int N))
6853 with (vec_concat (X) (B)) if N == 1 or
6854 (vec_concat (A) (X)) if N == 2. */
6855 if (GET_CODE (op0) == VEC_DUPLICATE
6856 && GET_CODE (op1) == CONST_VECTOR
6857 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6858 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6859 && IN_RANGE (sel, 1, 2))
6861 rtx newop0 = XEXP (op0, 0);
6862 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6863 if (sel == 2)
6864 std::swap (newop0, newop1);
6865 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6867 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6868 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6869 Only applies for vectors of two elements. */
6870 if (GET_CODE (op0) == VEC_DUPLICATE
6871 && GET_CODE (op1) == VEC_CONCAT
6872 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6873 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6874 && IN_RANGE (sel, 1, 2))
6876 rtx newop0 = XEXP (op0, 0);
6877 rtx newop1 = XEXP (op1, 2 - sel);
6878 rtx otherop = XEXP (op1, sel - 1);
6879 if (sel == 2)
6880 std::swap (newop0, newop1);
6881 /* Don't want to throw away the other part of the vec_concat if
6882 it has side-effects. */
6883 if (!side_effects_p (otherop))
6884 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6887 /* Replace:
6889 (vec_merge:outer (vec_duplicate:outer x:inner)
6890 (subreg:outer y:inner 0)
6891 (const_int N))
6893 with (vec_concat:outer x:inner y:inner) if N == 1,
6894 or (vec_concat:outer y:inner x:inner) if N == 2.
6896 Implicitly, this means we have a paradoxical subreg, but such
6897 a check is cheap, so make it anyway.
6899 Only applies for vectors of two elements. */
6900 if (GET_CODE (op0) == VEC_DUPLICATE
6901 && GET_CODE (op1) == SUBREG
6902 && GET_MODE (op1) == GET_MODE (op0)
6903 && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6904 && paradoxical_subreg_p (op1)
6905 && subreg_lowpart_p (op1)
6906 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6907 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6908 && IN_RANGE (sel, 1, 2))
6910 rtx newop0 = XEXP (op0, 0);
6911 rtx newop1 = SUBREG_REG (op1);
6912 if (sel == 2)
6913 std::swap (newop0, newop1);
6914 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6917 /* Same as above but with switched operands:
6918 Replace (vec_merge:outer (subreg:outer x:inner 0)
6919 (vec_duplicate:outer y:inner)
6920 (const_int N))
6922 with (vec_concat:outer x:inner y:inner) if N == 1,
6923 or (vec_concat:outer y:inner x:inner) if N == 2. */
6924 if (GET_CODE (op1) == VEC_DUPLICATE
6925 && GET_CODE (op0) == SUBREG
6926 && GET_MODE (op0) == GET_MODE (op1)
6927 && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
6928 && paradoxical_subreg_p (op0)
6929 && subreg_lowpart_p (op0)
6930 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6931 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6932 && IN_RANGE (sel, 1, 2))
6934 rtx newop0 = SUBREG_REG (op0);
6935 rtx newop1 = XEXP (op1, 0);
6936 if (sel == 2)
6937 std::swap (newop0, newop1);
6938 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6941 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
6942 (const_int n))
6943 with (vec_concat x y) or (vec_concat y x) depending on value
6944 of N. */
6945 if (GET_CODE (op0) == VEC_DUPLICATE
6946 && GET_CODE (op1) == VEC_DUPLICATE
6947 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6948 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6949 && IN_RANGE (sel, 1, 2))
6951 rtx newop0 = XEXP (op0, 0);
6952 rtx newop1 = XEXP (op1, 0);
6953 if (sel == 2)
6954 std::swap (newop0, newop1);
6956 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6960 if (rtx_equal_p (op0, op1)
6961 && !side_effects_p (op2) && !side_effects_p (op1))
6962 return op0;
6964 if (!side_effects_p (op2))
6966 rtx top0
6967 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6968 rtx top1
6969 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6970 if (top0 || top1)
6971 return simplify_gen_ternary (code, mode, mode,
6972 top0 ? top0 : op0,
6973 top1 ? top1 : op1, op2);
6976 break;
6978 default:
6979 gcc_unreachable ();
6982 return 0;
6985 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6986 starting at byte FIRST_BYTE. Return true on success and add the
6987 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6988 that the bytes follow target memory order. Leave BYTES unmodified
6989 on failure.
6991 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6992 BYTES before calling this function. */
6994 bool
6995 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6996 unsigned int first_byte, unsigned int num_bytes)
6998 /* Check the mode is sensible. */
6999 gcc_assert (GET_MODE (x) == VOIDmode
7000 ? is_a <scalar_int_mode> (mode)
7001 : mode == GET_MODE (x));
7003 if (GET_CODE (x) == CONST_VECTOR)
7005 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7006 is necessary. The only complication is that MODE_VECTOR_BOOL
7007 vectors can have several elements per byte. */
7008 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7009 GET_MODE_NUNITS (mode));
7010 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
7011 if (elt_bits < BITS_PER_UNIT)
7013 /* This is the only case in which elements can be smaller than
7014 a byte. */
7015 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7016 auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
7017 for (unsigned int i = 0; i < num_bytes; ++i)
7019 target_unit value = 0;
7020 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
7022 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & mask) << j;
7023 elt += 1;
7025 bytes.quick_push (value);
7027 return true;
7030 unsigned int start = bytes.length ();
7031 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
7032 /* Make FIRST_BYTE relative to ELT. */
7033 first_byte %= elt_bytes;
7034 while (num_bytes > 0)
7036 /* Work out how many bytes we want from element ELT. */
7037 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
7038 if (!native_encode_rtx (GET_MODE_INNER (mode),
7039 CONST_VECTOR_ELT (x, elt), bytes,
7040 first_byte, chunk_bytes))
7042 bytes.truncate (start);
7043 return false;
7045 elt += 1;
7046 first_byte = 0;
7047 num_bytes -= chunk_bytes;
7049 return true;
7052 /* All subsequent cases are limited to scalars. */
7053 scalar_mode smode;
7054 if (!is_a <scalar_mode> (mode, &smode))
7055 return false;
7057 /* Make sure that the region is in range. */
7058 unsigned int end_byte = first_byte + num_bytes;
7059 unsigned int mode_bytes = GET_MODE_SIZE (smode);
7060 gcc_assert (end_byte <= mode_bytes);
7062 if (CONST_SCALAR_INT_P (x))
7064 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7065 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7066 position of each byte. */
7067 rtx_mode_t value (x, smode);
7068 wide_int_ref value_wi (value);
7069 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7071 /* Always constant because the inputs are. */
7072 unsigned int lsb
7073 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7074 /* Operate directly on the encoding rather than using
7075 wi::extract_uhwi, so that we preserve the sign or zero
7076 extension for modes that are not a whole number of bits in
7077 size. (Zero extension is only used for the combination of
7078 innermode == BImode && STORE_FLAG_VALUE == 1). */
7079 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
7080 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
7081 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
7082 bytes.quick_push (uhwi >> shift);
7084 return true;
7087 if (CONST_DOUBLE_P (x))
7089 /* real_to_target produces an array of integers in target memory order.
7090 All integers before the last one have 32 bits; the last one may
7091 have 32 bits or fewer, depending on whether the mode bitsize
7092 is divisible by 32. Each of these integers is then laid out
7093 in target memory as any other integer would be. */
7094 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7095 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
7097 /* The (maximum) number of target bytes per element of el32. */
7098 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7099 gcc_assert (bytes_per_el32 != 0);
7101 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7102 handling above. */
7103 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7105 unsigned int index = byte / bytes_per_el32;
7106 unsigned int subbyte = byte % bytes_per_el32;
7107 unsigned int int_bytes = MIN (bytes_per_el32,
7108 mode_bytes - index * bytes_per_el32);
7109 /* Always constant because the inputs are. */
7110 unsigned int lsb
7111 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7112 bytes.quick_push ((unsigned long) el32[index] >> lsb);
7114 return true;
7117 if (GET_CODE (x) == CONST_FIXED)
7119 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7121 /* Always constant because the inputs are. */
7122 unsigned int lsb
7123 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7124 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
7125 if (lsb >= HOST_BITS_PER_WIDE_INT)
7127 lsb -= HOST_BITS_PER_WIDE_INT;
7128 piece = CONST_FIXED_VALUE_HIGH (x);
7130 bytes.quick_push (piece >> lsb);
7132 return true;
7135 return false;
7138 /* Read a vector of mode MODE from the target memory image given by BYTES,
7139 starting at byte FIRST_BYTE. The vector is known to be encodable using
7140 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
7141 and BYTES is known to have enough bytes to supply NPATTERNS *
7142 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
7143 BITS_PER_UNIT bits and the bytes are in target memory order.
7145 Return the vector on success, otherwise return NULL_RTX. */
7148 native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
7149 unsigned int first_byte, unsigned int npatterns,
7150 unsigned int nelts_per_pattern)
7152 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
7154 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7155 GET_MODE_NUNITS (mode));
7156 if (elt_bits < BITS_PER_UNIT)
7158 /* This is the only case in which elements can be smaller than a byte.
7159 Element 0 is always in the lsb of the containing byte. */
7160 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7161 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7163 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
7164 unsigned int byte_index = bit_index / BITS_PER_UNIT;
7165 unsigned int lsb = bit_index % BITS_PER_UNIT;
7166 unsigned int value = bytes[byte_index] >> lsb;
7167 builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
7170 else
7172 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7174 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
7175 if (!x)
7176 return NULL_RTX;
7177 builder.quick_push (x);
7178 first_byte += elt_bits / BITS_PER_UNIT;
7181 return builder.build ();
7184 /* Read an rtx of mode MODE from the target memory image given by BYTES,
7185 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
7186 bits and the bytes are in target memory order. The image has enough
7187 values to specify all bytes of MODE.
7189 Return the rtx on success, otherwise return NULL_RTX. */
7192 native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
7193 unsigned int first_byte)
7195 if (VECTOR_MODE_P (mode))
7197 /* If we know at compile time how many elements there are,
7198 pull each element directly from BYTES. */
7199 unsigned int nelts;
7200 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
7201 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
7202 return NULL_RTX;
7205 scalar_int_mode imode;
7206 if (is_a <scalar_int_mode> (mode, &imode)
7207 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
7209 /* Pull the bytes msb first, so that we can use simple
7210 shift-and-insert wide_int operations. */
7211 unsigned int size = GET_MODE_SIZE (imode);
7212 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
7213 for (unsigned int i = 0; i < size; ++i)
7215 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
7216 /* Always constant because the inputs are. */
7217 unsigned int subbyte
7218 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
7219 result <<= BITS_PER_UNIT;
7220 result |= bytes[first_byte + subbyte];
7222 return immed_wide_int_const (result, imode);
7225 scalar_float_mode fmode;
7226 if (is_a <scalar_float_mode> (mode, &fmode))
7228 /* We need to build an array of integers in target memory order.
7229 All integers before the last one have 32 bits; the last one may
7230 have 32 bits or fewer, depending on whether the mode bitsize
7231 is divisible by 32. */
7232 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7233 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
7234 memset (el32, 0, num_el32 * sizeof (long));
7236 /* The (maximum) number of target bytes per element of el32. */
7237 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7238 gcc_assert (bytes_per_el32 != 0);
7240 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
7241 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7243 unsigned int index = byte / bytes_per_el32;
7244 unsigned int subbyte = byte % bytes_per_el32;
7245 unsigned int int_bytes = MIN (bytes_per_el32,
7246 mode_bytes - index * bytes_per_el32);
7247 /* Always constant because the inputs are. */
7248 unsigned int lsb
7249 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7250 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
7252 REAL_VALUE_TYPE r;
7253 real_from_target (&r, el32, fmode);
7254 return const_double_from_real_value (r, fmode);
7257 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7259 scalar_mode smode = as_a <scalar_mode> (mode);
7260 FIXED_VALUE_TYPE f;
7261 f.data.low = 0;
7262 f.data.high = 0;
7263 f.mode = smode;
7265 unsigned int mode_bytes = GET_MODE_SIZE (smode);
7266 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7268 /* Always constant because the inputs are. */
7269 unsigned int lsb
7270 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7271 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
7272 if (lsb >= HOST_BITS_PER_WIDE_INT)
7273 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
7274 else
7275 f.data.low |= unit << lsb;
7277 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
7280 return NULL_RTX;
7283 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
7284 is to convert a runtime BYTE value into a constant one. */
7286 static poly_uint64
7287 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
7289 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7290 machine_mode mode = GET_MODE (x);
7291 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7292 GET_MODE_NUNITS (mode));
7293 /* The number of bits needed to encode one element from each pattern. */
7294 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
7296 /* Identify the start point in terms of a sequence number and a byte offset
7297 within that sequence. */
7298 poly_uint64 first_sequence;
7299 unsigned HOST_WIDE_INT subbit;
7300 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
7301 &first_sequence, &subbit))
7303 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7304 if (nelts_per_pattern == 1)
7305 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
7306 doesn't matter. */
7307 byte = subbit / BITS_PER_UNIT;
7308 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
7310 /* The subreg drops the first element from each pattern and
7311 only uses the second element. Find the first sequence
7312 that starts on a byte boundary. */
7313 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
7314 byte = subbit / BITS_PER_UNIT;
7317 return byte;
7320 /* Subroutine of simplify_subreg in which:
7322 - X is known to be a CONST_VECTOR
7323 - OUTERMODE is known to be a vector mode
7325 Try to handle the subreg by operating on the CONST_VECTOR encoding
7326 rather than on each individual element of the CONST_VECTOR.
7328 Return the simplified subreg on success, otherwise return NULL_RTX. */
7330 static rtx
7331 simplify_const_vector_subreg (machine_mode outermode, rtx x,
7332 machine_mode innermode, unsigned int first_byte)
7334 /* Paradoxical subregs of vectors have dubious semantics. */
7335 if (paradoxical_subreg_p (outermode, innermode))
7336 return NULL_RTX;
7338 /* We can only preserve the semantics of a stepped pattern if the new
7339 vector element is the same as the original one. */
7340 if (CONST_VECTOR_STEPPED_P (x)
7341 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
7342 return NULL_RTX;
7344 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7345 unsigned int x_elt_bits
7346 = vector_element_size (GET_MODE_BITSIZE (innermode),
7347 GET_MODE_NUNITS (innermode));
7348 unsigned int out_elt_bits
7349 = vector_element_size (GET_MODE_BITSIZE (outermode),
7350 GET_MODE_NUNITS (outermode));
7352 /* The number of bits needed to encode one element from every pattern
7353 of the original vector. */
7354 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
7356 /* The number of bits needed to encode one element from every pattern
7357 of the result. */
7358 unsigned int out_sequence_bits
7359 = least_common_multiple (x_sequence_bits, out_elt_bits);
7361 /* Work out the number of interleaved patterns in the output vector
7362 and the number of encoded elements per pattern. */
7363 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
7364 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7366 /* The encoding scheme requires the number of elements to be a multiple
7367 of the number of patterns, so that each pattern appears at least once
7368 and so that the same number of elements appear from each pattern. */
7369 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
7370 unsigned int const_nunits;
7371 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
7372 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
7374 /* Either the encoding is invalid, or applying it would give us
7375 more elements than we need. Just encode each element directly. */
7376 out_npatterns = const_nunits;
7377 nelts_per_pattern = 1;
7379 else if (!ok_p)
7380 return NULL_RTX;
7382 /* Get enough bytes of X to form the new encoding. */
7383 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
7384 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
7385 auto_vec<target_unit, 128> buffer (buffer_bytes);
7386 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
7387 return NULL_RTX;
7389 /* Reencode the bytes as OUTERMODE. */
7390 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
7391 nelts_per_pattern);
7394 /* Try to simplify a subreg of a constant by encoding the subreg region
7395 as a sequence of target bytes and reading them back in the new mode.
7396 Return the new value on success, otherwise return null.
7398 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7399 and byte offset FIRST_BYTE. */
7401 static rtx
7402 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
7403 machine_mode innermode, unsigned int first_byte)
7405 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
7406 auto_vec<target_unit, 128> buffer (buffer_bytes);
7408 /* Some ports misuse CCmode. */
7409 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
7410 return x;
7412 /* Paradoxical subregs read undefined values for bytes outside of the
7413 inner value. However, we have traditionally always sign-extended
7414 integer constants and zero-extended others. */
7415 unsigned int inner_bytes = buffer_bytes;
7416 if (paradoxical_subreg_p (outermode, innermode))
7418 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
7419 return NULL_RTX;
7421 target_unit filler = 0;
7422 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
7423 filler = -1;
7425 /* Add any leading bytes due to big-endian layout. The number of
7426 bytes must be constant because both modes have constant size. */
7427 unsigned int leading_bytes
7428 = -byte_lowpart_offset (outermode, innermode).to_constant ();
7429 for (unsigned int i = 0; i < leading_bytes; ++i)
7430 buffer.quick_push (filler);
7432 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7433 return NULL_RTX;
7435 /* Add any trailing bytes due to little-endian layout. */
7436 while (buffer.length () < buffer_bytes)
7437 buffer.quick_push (filler);
7439 else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7440 return NULL_RTX;
7441 rtx ret = native_decode_rtx (outermode, buffer, 0);
7442 if (ret && FLOAT_MODE_P (outermode))
7444 auto_vec<target_unit, 128> buffer2 (buffer_bytes);
7445 if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
7446 return NULL_RTX;
7447 for (unsigned int i = 0; i < buffer_bytes; ++i)
7448 if (buffer[i] != buffer2[i])
7449 return NULL_RTX;
7451 return ret;
7454 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7455 Return 0 if no simplifications are possible. */
7457 simplify_context::simplify_subreg (machine_mode outermode, rtx op,
7458 machine_mode innermode, poly_uint64 byte)
7460 /* Little bit of sanity checking. */
7461 gcc_assert (innermode != VOIDmode);
7462 gcc_assert (outermode != VOIDmode);
7463 gcc_assert (innermode != BLKmode);
7464 gcc_assert (outermode != BLKmode);
7466 gcc_assert (GET_MODE (op) == innermode
7467 || GET_MODE (op) == VOIDmode);
7469 poly_uint64 outersize = GET_MODE_SIZE (outermode);
7470 if (!multiple_p (byte, outersize))
7471 return NULL_RTX;
7473 poly_uint64 innersize = GET_MODE_SIZE (innermode);
7474 if (maybe_ge (byte, innersize))
7475 return NULL_RTX;
7477 if (outermode == innermode && known_eq (byte, 0U))
7478 return op;
7480 if (GET_CODE (op) == CONST_VECTOR)
7481 byte = simplify_const_vector_byte_offset (op, byte);
7483 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
7485 rtx elt;
7487 if (VECTOR_MODE_P (outermode)
7488 && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
7489 && vec_duplicate_p (op, &elt))
7490 return gen_vec_duplicate (outermode, elt);
7492 if (outermode == GET_MODE_INNER (innermode)
7493 && vec_duplicate_p (op, &elt))
7494 return elt;
7497 if (CONST_SCALAR_INT_P (op)
7498 || CONST_DOUBLE_AS_FLOAT_P (op)
7499 || CONST_FIXED_P (op)
7500 || GET_CODE (op) == CONST_VECTOR)
7502 unsigned HOST_WIDE_INT cbyte;
7503 if (byte.is_constant (&cbyte))
7505 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
7507 rtx tmp = simplify_const_vector_subreg (outermode, op,
7508 innermode, cbyte);
7509 if (tmp)
7510 return tmp;
7513 fixed_size_mode fs_outermode;
7514 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
7515 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
7519 /* Changing mode twice with SUBREG => just change it once,
7520 or not at all if changing back op starting mode. */
7521 if (GET_CODE (op) == SUBREG)
7523 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
7524 poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
7525 rtx newx;
7527 if (outermode == innermostmode
7528 && known_eq (byte, 0U)
7529 && known_eq (SUBREG_BYTE (op), 0))
7530 return SUBREG_REG (op);
7532 /* Work out the memory offset of the final OUTERMODE value relative
7533 to the inner value of OP. */
7534 poly_int64 mem_offset = subreg_memory_offset (outermode,
7535 innermode, byte);
7536 poly_int64 op_mem_offset = subreg_memory_offset (op);
7537 poly_int64 final_offset = mem_offset + op_mem_offset;
7539 /* See whether resulting subreg will be paradoxical. */
7540 if (!paradoxical_subreg_p (outermode, innermostmode))
7542 /* Bail out in case resulting subreg would be incorrect. */
7543 if (maybe_lt (final_offset, 0)
7544 || maybe_ge (poly_uint64 (final_offset), innermostsize)
7545 || !multiple_p (final_offset, outersize))
7546 return NULL_RTX;
7548 else
7550 poly_int64 required_offset = subreg_memory_offset (outermode,
7551 innermostmode, 0);
7552 if (maybe_ne (final_offset, required_offset))
7553 return NULL_RTX;
7554 /* Paradoxical subregs always have byte offset 0. */
7555 final_offset = 0;
7558 /* Recurse for further possible simplifications. */
7559 newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
7560 final_offset);
7561 if (newx)
7562 return newx;
7563 if (validate_subreg (outermode, innermostmode,
7564 SUBREG_REG (op), final_offset))
7566 newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
7567 if (SUBREG_PROMOTED_VAR_P (op)
7568 && SUBREG_PROMOTED_SIGN (op) >= 0
7569 && GET_MODE_CLASS (outermode) == MODE_INT
7570 && known_ge (outersize, innersize)
7571 && known_le (outersize, innermostsize)
7572 && subreg_lowpart_p (newx))
7574 SUBREG_PROMOTED_VAR_P (newx) = 1;
7575 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
7577 return newx;
7579 return NULL_RTX;
7582 /* SUBREG of a hard register => just change the register number
7583 and/or mode. If the hard register is not valid in that mode,
7584 suppress this simplification. If the hard register is the stack,
7585 frame, or argument pointer, leave this as a SUBREG. */
7587 if (REG_P (op) && HARD_REGISTER_P (op))
7589 unsigned int regno, final_regno;
7591 regno = REGNO (op);
7592 final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
7593 if (HARD_REGISTER_NUM_P (final_regno))
7595 rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
7596 subreg_memory_offset (outermode,
7597 innermode, byte));
7599 /* Propagate original regno. We don't have any way to specify
7600 the offset inside original regno, so do so only for lowpart.
7601 The information is used only by alias analysis that cannot
7602 grog partial register anyway. */
7604 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
7605 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
7606 return x;
7610 /* If we have a SUBREG of a register that we are replacing and we are
7611 replacing it with a MEM, make a new MEM and try replacing the
7612 SUBREG with it. Don't do this if the MEM has a mode-dependent address
7613 or if we would be widening it. */
7615 if (MEM_P (op)
7616 && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
7617 /* Allow splitting of volatile memory references in case we don't
7618 have instruction to move the whole thing. */
7619 && (! MEM_VOLATILE_P (op)
7620 || ! have_insn_for (SET, innermode))
7621 && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
7622 && known_le (outersize, innersize))
7623 return adjust_address_nv (op, outermode, byte);
7625 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7626 of two parts. */
7627 if (GET_CODE (op) == CONCAT
7628 || GET_CODE (op) == VEC_CONCAT)
7630 poly_uint64 final_offset;
7631 rtx part, res;
7633 machine_mode part_mode = GET_MODE (XEXP (op, 0));
7634 if (part_mode == VOIDmode)
7635 part_mode = GET_MODE_INNER (GET_MODE (op));
7636 poly_uint64 part_size = GET_MODE_SIZE (part_mode);
7637 if (known_lt (byte, part_size))
7639 part = XEXP (op, 0);
7640 final_offset = byte;
7642 else if (known_ge (byte, part_size))
7644 part = XEXP (op, 1);
7645 final_offset = byte - part_size;
7647 else
7648 return NULL_RTX;
7650 if (maybe_gt (final_offset + outersize, part_size))
7651 return NULL_RTX;
7653 part_mode = GET_MODE (part);
7654 if (part_mode == VOIDmode)
7655 part_mode = GET_MODE_INNER (GET_MODE (op));
7656 res = simplify_subreg (outermode, part, part_mode, final_offset);
7657 if (res)
7658 return res;
7659 if (validate_subreg (outermode, part_mode, part, final_offset))
7660 return gen_rtx_SUBREG (outermode, part, final_offset);
7661 return NULL_RTX;
7664 /* Simplify
7665 (subreg (vec_merge (X)
7666 (vector)
7667 (const_int ((1 << N) | M)))
7668 (N * sizeof (outermode)))
7670 (subreg (X) (N * sizeof (outermode)))
7672 unsigned int idx;
7673 if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7674 && idx < HOST_BITS_PER_WIDE_INT
7675 && GET_CODE (op) == VEC_MERGE
7676 && GET_MODE_INNER (innermode) == outermode
7677 && CONST_INT_P (XEXP (op, 2))
7678 && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7679 return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7681 /* A SUBREG resulting from a zero extension may fold to zero if
7682 it extracts higher bits that the ZERO_EXTEND's source bits. */
7683 if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7685 poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7686 if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7687 return CONST0_RTX (outermode);
7690 scalar_int_mode int_outermode, int_innermode;
7691 if (is_a <scalar_int_mode> (outermode, &int_outermode)
7692 && is_a <scalar_int_mode> (innermode, &int_innermode)
7693 && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7695 /* Handle polynomial integers. The upper bits of a paradoxical
7696 subreg are undefined, so this is safe regardless of whether
7697 we're truncating or extending. */
7698 if (CONST_POLY_INT_P (op))
7700 poly_wide_int val
7701 = poly_wide_int::from (const_poly_int_value (op),
7702 GET_MODE_PRECISION (int_outermode),
7703 SIGNED);
7704 return immed_wide_int_const (val, int_outermode);
7707 if (GET_MODE_PRECISION (int_outermode)
7708 < GET_MODE_PRECISION (int_innermode))
7710 rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7711 if (tem)
7712 return tem;
7716 /* If the outer mode is not integral, try taking a subreg with the equivalent
7717 integer outer mode and then bitcasting the result.
7718 Other simplifications rely on integer to integer subregs and we'd
7719 potentially miss out on optimizations otherwise. */
7720 if (known_gt (GET_MODE_SIZE (innermode),
7721 GET_MODE_SIZE (outermode))
7722 && SCALAR_INT_MODE_P (innermode)
7723 && !SCALAR_INT_MODE_P (outermode)
7724 && int_mode_for_size (GET_MODE_BITSIZE (outermode),
7725 0).exists (&int_outermode))
7727 rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
7728 if (tem)
7729 return simplify_gen_subreg (outermode, tem, int_outermode, byte);
7732 /* If OP is a vector comparison and the subreg is not changing the
7733 number of elements or the size of the elements, change the result
7734 of the comparison to the new mode. */
7735 if (COMPARISON_P (op)
7736 && VECTOR_MODE_P (outermode)
7737 && VECTOR_MODE_P (innermode)
7738 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7739 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7740 GET_MODE_UNIT_SIZE (innermode)))
7741 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7742 XEXP (op, 0), XEXP (op, 1));
7743 return NULL_RTX;
7746 /* Make a SUBREG operation or equivalent if it folds. */
7749 simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
7750 machine_mode innermode,
7751 poly_uint64 byte)
7753 rtx newx;
7755 newx = simplify_subreg (outermode, op, innermode, byte);
7756 if (newx)
7757 return newx;
7759 if (GET_CODE (op) == SUBREG
7760 || GET_CODE (op) == CONCAT
7761 || GET_MODE (op) == VOIDmode)
7762 return NULL_RTX;
7764 if (MODE_COMPOSITE_P (outermode)
7765 && (CONST_SCALAR_INT_P (op)
7766 || CONST_DOUBLE_AS_FLOAT_P (op)
7767 || CONST_FIXED_P (op)
7768 || GET_CODE (op) == CONST_VECTOR))
7769 return NULL_RTX;
7771 if (validate_subreg (outermode, innermode, op, byte))
7772 return gen_rtx_SUBREG (outermode, op, byte);
7774 return NULL_RTX;
7777 /* Generates a subreg to get the least significant part of EXPR (in mode
7778 INNER_MODE) to OUTER_MODE. */
7781 simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
7782 machine_mode inner_mode)
7784 return simplify_gen_subreg (outer_mode, expr, inner_mode,
7785 subreg_lowpart_offset (outer_mode, inner_mode));
7788 /* Generate RTX to select element at INDEX out of vector OP. */
7791 simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
7793 gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
7795 scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
7797 if (known_eq (index * GET_MODE_SIZE (imode),
7798 subreg_lowpart_offset (imode, GET_MODE (op))))
7800 rtx res = lowpart_subreg (imode, op, GET_MODE (op));
7801 if (res)
7802 return res;
7805 rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
7806 return gen_rtx_VEC_SELECT (imode, op, tmp);
7810 /* Simplify X, an rtx expression.
7812 Return the simplified expression or NULL if no simplifications
7813 were possible.
7815 This is the preferred entry point into the simplification routines;
7816 however, we still allow passes to call the more specific routines.
7818 Right now GCC has three (yes, three) major bodies of RTL simplification
7819 code that need to be unified.
7821 1. fold_rtx in cse.cc. This code uses various CSE specific
7822 information to aid in RTL simplification.
7824 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
7825 it uses combine specific information to aid in RTL
7826 simplification.
7828 3. The routines in this file.
7831 Long term we want to only have one body of simplification code; to
7832 get to that state I recommend the following steps:
7834 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7835 which are not pass dependent state into these routines.
7837 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7838 use this routine whenever possible.
7840 3. Allow for pass dependent state to be provided to these
7841 routines and add simplifications based on the pass dependent
7842 state. Remove code from cse.cc & combine.cc that becomes
7843 redundant/dead.
7845 It will take time, but ultimately the compiler will be easier to
7846 maintain and improve. It's totally silly that when we add a
7847 simplification that it needs to be added to 4 places (3 for RTL
7848 simplification and 1 for tree simplification. */
7851 simplify_rtx (const_rtx x)
7853 const enum rtx_code code = GET_CODE (x);
7854 const machine_mode mode = GET_MODE (x);
7856 switch (GET_RTX_CLASS (code))
7858 case RTX_UNARY:
7859 return simplify_unary_operation (code, mode,
7860 XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7861 case RTX_COMM_ARITH:
7862 if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7863 return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7865 /* Fall through. */
7867 case RTX_BIN_ARITH:
7868 return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7870 case RTX_TERNARY:
7871 case RTX_BITFIELD_OPS:
7872 return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7873 XEXP (x, 0), XEXP (x, 1),
7874 XEXP (x, 2));
7876 case RTX_COMPARE:
7877 case RTX_COMM_COMPARE:
7878 return simplify_relational_operation (code, mode,
7879 ((GET_MODE (XEXP (x, 0))
7880 != VOIDmode)
7881 ? GET_MODE (XEXP (x, 0))
7882 : GET_MODE (XEXP (x, 1))),
7883 XEXP (x, 0),
7884 XEXP (x, 1));
7886 case RTX_EXTRA:
7887 if (code == SUBREG)
7888 return simplify_subreg (mode, SUBREG_REG (x),
7889 GET_MODE (SUBREG_REG (x)),
7890 SUBREG_BYTE (x));
7891 break;
7893 case RTX_OBJ:
7894 if (code == LO_SUM)
7896 /* Convert (lo_sum (high FOO) FOO) to FOO. */
7897 if (GET_CODE (XEXP (x, 0)) == HIGH
7898 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
7899 return XEXP (x, 1);
7901 break;
7903 default:
7904 break;
7906 return NULL;
7909 #if CHECKING_P
7911 namespace selftest {
7913 /* Make a unique pseudo REG of mode MODE for use by selftests. */
7915 static rtx
7916 make_test_reg (machine_mode mode)
7918 static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
7920 return gen_rtx_REG (mode, test_reg_num++);
7923 static void
7924 test_scalar_int_ops (machine_mode mode)
7926 rtx op0 = make_test_reg (mode);
7927 rtx op1 = make_test_reg (mode);
7928 rtx six = GEN_INT (6);
7930 rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
7931 rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
7932 rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
7934 rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
7935 rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
7936 rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
7938 rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
7939 rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
7941 /* Test some binary identities. */
7942 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
7943 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
7944 ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
7945 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
7946 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
7947 ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
7948 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
7949 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
7950 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
7951 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
7952 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
7953 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
7954 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
7955 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
7956 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
7957 ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
7958 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
7960 /* Test some self-inverse operations. */
7961 ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
7962 ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
7963 ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
7965 /* Test some reflexive operations. */
7966 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
7967 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
7968 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
7969 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
7970 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
7971 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
7973 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
7974 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
7976 /* Test simplify_distributive_operation. */
7977 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
7978 simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
7979 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
7980 simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
7981 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
7982 simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
7984 /* Test useless extensions are eliminated. */
7985 ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
7986 ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
7987 ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
7988 ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
7991 /* Verify some simplifications of integer extension/truncation.
7992 Machine mode BMODE is the guaranteed wider than SMODE. */
7994 static void
7995 test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
7997 rtx sreg = make_test_reg (smode);
7999 /* Check truncation of extension. */
8000 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8001 simplify_gen_unary (ZERO_EXTEND, bmode,
8002 sreg, smode),
8003 bmode),
8004 sreg);
8005 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8006 simplify_gen_unary (SIGN_EXTEND, bmode,
8007 sreg, smode),
8008 bmode),
8009 sreg);
8010 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8011 lowpart_subreg (bmode, sreg, smode),
8012 bmode),
8013 sreg);
8016 /* Verify more simplifications of integer extension/truncation.
8017 BMODE is wider than MMODE which is wider than SMODE. */
8019 static void
8020 test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
8021 machine_mode smode)
8023 rtx breg = make_test_reg (bmode);
8024 rtx mreg = make_test_reg (mmode);
8025 rtx sreg = make_test_reg (smode);
8027 /* Check truncate of truncate. */
8028 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8029 simplify_gen_unary (TRUNCATE, mmode,
8030 breg, bmode),
8031 mmode),
8032 simplify_gen_unary (TRUNCATE, smode, breg, bmode));
8034 /* Check extension of extension. */
8035 ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
8036 simplify_gen_unary (ZERO_EXTEND, mmode,
8037 sreg, smode),
8038 mmode),
8039 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8040 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8041 simplify_gen_unary (SIGN_EXTEND, mmode,
8042 sreg, smode),
8043 mmode),
8044 simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
8045 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8046 simplify_gen_unary (ZERO_EXTEND, mmode,
8047 sreg, smode),
8048 mmode),
8049 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8051 /* Check truncation of extension. */
8052 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8053 simplify_gen_unary (ZERO_EXTEND, bmode,
8054 mreg, mmode),
8055 bmode),
8056 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8057 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8058 simplify_gen_unary (SIGN_EXTEND, bmode,
8059 mreg, mmode),
8060 bmode),
8061 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8062 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8063 lowpart_subreg (bmode, mreg, mmode),
8064 bmode),
8065 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8069 /* Verify some simplifications involving scalar expressions. */
8071 static void
8072 test_scalar_ops ()
8074 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8076 machine_mode mode = (machine_mode) i;
8077 if (SCALAR_INT_MODE_P (mode) && mode != BImode)
8078 test_scalar_int_ops (mode);
8081 test_scalar_int_ext_ops (HImode, QImode);
8082 test_scalar_int_ext_ops (SImode, QImode);
8083 test_scalar_int_ext_ops (SImode, HImode);
8084 test_scalar_int_ext_ops (DImode, QImode);
8085 test_scalar_int_ext_ops (DImode, HImode);
8086 test_scalar_int_ext_ops (DImode, SImode);
8088 test_scalar_int_ext_ops2 (SImode, HImode, QImode);
8089 test_scalar_int_ext_ops2 (DImode, HImode, QImode);
8090 test_scalar_int_ext_ops2 (DImode, SImode, QImode);
8091 test_scalar_int_ext_ops2 (DImode, SImode, HImode);
8094 /* Test vector simplifications involving VEC_DUPLICATE in which the
8095 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8096 register that holds one element of MODE. */
8098 static void
8099 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
8101 scalar_mode inner_mode = GET_MODE_INNER (mode);
8102 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8103 poly_uint64 nunits = GET_MODE_NUNITS (mode);
8104 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
8106 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
8107 rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
8108 rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
8109 ASSERT_RTX_EQ (duplicate,
8110 simplify_unary_operation (NOT, mode,
8111 duplicate_not, mode));
8113 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8114 rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
8115 ASSERT_RTX_EQ (duplicate,
8116 simplify_unary_operation (NEG, mode,
8117 duplicate_neg, mode));
8119 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
8120 ASSERT_RTX_EQ (duplicate,
8121 simplify_binary_operation (PLUS, mode, duplicate,
8122 CONST0_RTX (mode)));
8124 ASSERT_RTX_EQ (duplicate,
8125 simplify_binary_operation (MINUS, mode, duplicate,
8126 CONST0_RTX (mode)));
8128 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
8129 simplify_binary_operation (MINUS, mode, duplicate,
8130 duplicate));
8133 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
8134 rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
8135 ASSERT_RTX_PTR_EQ (scalar_reg,
8136 simplify_binary_operation (VEC_SELECT, inner_mode,
8137 duplicate, zero_par));
8139 unsigned HOST_WIDE_INT const_nunits;
8140 if (nunits.is_constant (&const_nunits))
8142 /* And again with the final element. */
8143 rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
8144 rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
8145 ASSERT_RTX_PTR_EQ (scalar_reg,
8146 simplify_binary_operation (VEC_SELECT, inner_mode,
8147 duplicate, last_par));
8149 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
8150 /* Skip this test for vectors of booleans, because offset is in bytes,
8151 while vec_merge indices are in elements (usually bits). */
8152 if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
8154 rtx vector_reg = make_test_reg (mode);
8155 for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
8157 if (i >= HOST_BITS_PER_WIDE_INT)
8158 break;
8159 rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
8160 rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
8161 poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
8163 ASSERT_RTX_EQ (scalar_reg,
8164 simplify_gen_subreg (inner_mode, vm,
8165 mode, offset));
8170 /* Test a scalar subreg of a VEC_DUPLICATE. */
8171 poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
8172 ASSERT_RTX_EQ (scalar_reg,
8173 simplify_gen_subreg (inner_mode, duplicate,
8174 mode, offset));
8176 machine_mode narrower_mode;
8177 if (maybe_ne (nunits, 2U)
8178 && multiple_p (nunits, 2)
8179 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
8180 && VECTOR_MODE_P (narrower_mode))
8182 /* Test VEC_DUPLICATE of a vector. */
8183 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
8184 nbuilder.quick_push (const0_rtx);
8185 nbuilder.quick_push (const1_rtx);
8186 rtx_vector_builder builder (mode, 2, 1);
8187 builder.quick_push (const0_rtx);
8188 builder.quick_push (const1_rtx);
8189 ASSERT_RTX_EQ (builder.build (),
8190 simplify_unary_operation (VEC_DUPLICATE, mode,
8191 nbuilder.build (),
8192 narrower_mode));
8194 /* Test VEC_SELECT of a vector. */
8195 rtx vec_par
8196 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
8197 rtx narrower_duplicate
8198 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
8199 ASSERT_RTX_EQ (narrower_duplicate,
8200 simplify_binary_operation (VEC_SELECT, narrower_mode,
8201 duplicate, vec_par));
8203 /* Test a vector subreg of a VEC_DUPLICATE. */
8204 poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
8205 ASSERT_RTX_EQ (narrower_duplicate,
8206 simplify_gen_subreg (narrower_mode, duplicate,
8207 mode, offset));
8211 /* Test vector simplifications involving VEC_SERIES in which the
8212 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8213 register that holds one element of MODE. */
8215 static void
8216 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
8218 /* Test unary cases with VEC_SERIES arguments. */
8219 scalar_mode inner_mode = GET_MODE_INNER (mode);
8220 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8221 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8222 rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
8223 rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
8224 rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
8225 rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
8226 rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
8227 rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
8228 neg_scalar_reg);
8229 ASSERT_RTX_EQ (series_0_r,
8230 simplify_unary_operation (NEG, mode, series_0_nr, mode));
8231 ASSERT_RTX_EQ (series_r_m1,
8232 simplify_unary_operation (NEG, mode, series_nr_1, mode));
8233 ASSERT_RTX_EQ (series_r_r,
8234 simplify_unary_operation (NEG, mode, series_nr_nr, mode));
8236 /* Test that a VEC_SERIES with a zero step is simplified away. */
8237 ASSERT_RTX_EQ (duplicate,
8238 simplify_binary_operation (VEC_SERIES, mode,
8239 scalar_reg, const0_rtx));
8241 /* Test PLUS and MINUS with VEC_SERIES. */
8242 rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
8243 rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
8244 rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
8245 ASSERT_RTX_EQ (series_r_r,
8246 simplify_binary_operation (PLUS, mode, series_0_r,
8247 duplicate));
8248 ASSERT_RTX_EQ (series_r_1,
8249 simplify_binary_operation (PLUS, mode, duplicate,
8250 series_0_1));
8251 ASSERT_RTX_EQ (series_r_m1,
8252 simplify_binary_operation (PLUS, mode, duplicate,
8253 series_0_m1));
8254 ASSERT_RTX_EQ (series_0_r,
8255 simplify_binary_operation (MINUS, mode, series_r_r,
8256 duplicate));
8257 ASSERT_RTX_EQ (series_r_m1,
8258 simplify_binary_operation (MINUS, mode, duplicate,
8259 series_0_1));
8260 ASSERT_RTX_EQ (series_r_1,
8261 simplify_binary_operation (MINUS, mode, duplicate,
8262 series_0_m1));
8263 ASSERT_RTX_EQ (series_0_m1,
8264 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
8265 constm1_rtx));
8267 /* Test NEG on constant vector series. */
8268 ASSERT_RTX_EQ (series_0_m1,
8269 simplify_unary_operation (NEG, mode, series_0_1, mode));
8270 ASSERT_RTX_EQ (series_0_1,
8271 simplify_unary_operation (NEG, mode, series_0_m1, mode));
8273 /* Test PLUS and MINUS on constant vector series. */
8274 rtx scalar2 = gen_int_mode (2, inner_mode);
8275 rtx scalar3 = gen_int_mode (3, inner_mode);
8276 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
8277 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
8278 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
8279 ASSERT_RTX_EQ (series_1_1,
8280 simplify_binary_operation (PLUS, mode, series_0_1,
8281 CONST1_RTX (mode)));
8282 ASSERT_RTX_EQ (series_0_m1,
8283 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
8284 series_0_m1));
8285 ASSERT_RTX_EQ (series_1_3,
8286 simplify_binary_operation (PLUS, mode, series_1_1,
8287 series_0_2));
8288 ASSERT_RTX_EQ (series_0_1,
8289 simplify_binary_operation (MINUS, mode, series_1_1,
8290 CONST1_RTX (mode)));
8291 ASSERT_RTX_EQ (series_1_1,
8292 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
8293 series_0_m1));
8294 ASSERT_RTX_EQ (series_1_1,
8295 simplify_binary_operation (MINUS, mode, series_1_3,
8296 series_0_2));
8298 /* Test MULT between constant vectors. */
8299 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
8300 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
8301 rtx scalar9 = gen_int_mode (9, inner_mode);
8302 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
8303 ASSERT_RTX_EQ (series_0_2,
8304 simplify_binary_operation (MULT, mode, series_0_1, vec2));
8305 ASSERT_RTX_EQ (series_3_9,
8306 simplify_binary_operation (MULT, mode, vec3, series_1_3));
8307 if (!GET_MODE_NUNITS (mode).is_constant ())
8308 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
8309 series_0_1));
8311 /* Test ASHIFT between constant vectors. */
8312 ASSERT_RTX_EQ (series_0_2,
8313 simplify_binary_operation (ASHIFT, mode, series_0_1,
8314 CONST1_RTX (mode)));
8315 if (!GET_MODE_NUNITS (mode).is_constant ())
8316 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
8317 series_0_1));
8320 static rtx
8321 simplify_merge_mask (rtx x, rtx mask, int op)
8323 return simplify_context ().simplify_merge_mask (x, mask, op);
8326 /* Verify simplify_merge_mask works correctly. */
8328 static void
8329 test_vec_merge (machine_mode mode)
8331 rtx op0 = make_test_reg (mode);
8332 rtx op1 = make_test_reg (mode);
8333 rtx op2 = make_test_reg (mode);
8334 rtx op3 = make_test_reg (mode);
8335 rtx op4 = make_test_reg (mode);
8336 rtx op5 = make_test_reg (mode);
8337 rtx mask1 = make_test_reg (SImode);
8338 rtx mask2 = make_test_reg (SImode);
8339 rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
8340 rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
8341 rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
8343 /* Simple vec_merge. */
8344 ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
8345 ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
8346 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
8347 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
8349 /* Nested vec_merge.
8350 It's tempting to make this simplify right down to opN, but we don't
8351 because all the simplify_* functions assume that the operands have
8352 already been simplified. */
8353 rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
8354 ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
8355 ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
8357 /* Intermediate unary op. */
8358 rtx unop = gen_rtx_NOT (mode, vm1);
8359 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
8360 simplify_merge_mask (unop, mask1, 0));
8361 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
8362 simplify_merge_mask (unop, mask1, 1));
8364 /* Intermediate binary op. */
8365 rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
8366 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
8367 simplify_merge_mask (binop, mask1, 0));
8368 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
8369 simplify_merge_mask (binop, mask1, 1));
8371 /* Intermediate ternary op. */
8372 rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
8373 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
8374 simplify_merge_mask (tenop, mask1, 0));
8375 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
8376 simplify_merge_mask (tenop, mask1, 1));
8378 /* Side effects. */
8379 rtx badop0 = gen_rtx_PRE_INC (mode, op0);
8380 rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
8381 ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
8382 ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
8384 /* Called indirectly. */
8385 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
8386 simplify_rtx (nvm));
8389 /* Test subregs of integer vector constant X, trying elements in
8390 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
8391 where NELTS is the number of elements in X. Subregs involving
8392 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
8394 static void
8395 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
8396 unsigned int first_valid = 0)
8398 machine_mode inner_mode = GET_MODE (x);
8399 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8401 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
8403 machine_mode outer_mode = (machine_mode) modei;
8404 if (!VECTOR_MODE_P (outer_mode))
8405 continue;
8407 unsigned int outer_nunits;
8408 if (GET_MODE_INNER (outer_mode) == int_mode
8409 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
8410 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
8412 /* Test subregs in which the outer mode is a smaller,
8413 constant-sized vector of the same element type. */
8414 unsigned int limit
8415 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
8416 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
8418 rtx expected = NULL_RTX;
8419 if (elt >= first_valid)
8421 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
8422 for (unsigned int i = 0; i < outer_nunits; ++i)
8423 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
8424 expected = builder.build ();
8426 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
8427 ASSERT_RTX_EQ (expected,
8428 simplify_subreg (outer_mode, x,
8429 inner_mode, byte));
8432 else if (known_eq (GET_MODE_SIZE (outer_mode),
8433 GET_MODE_SIZE (inner_mode))
8434 && known_eq (elt_bias, 0U)
8435 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
8436 || known_eq (GET_MODE_BITSIZE (outer_mode),
8437 GET_MODE_NUNITS (outer_mode)))
8438 && (!FLOAT_MODE_P (outer_mode)
8439 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
8440 == GET_MODE_UNIT_PRECISION (outer_mode)))
8441 && (GET_MODE_SIZE (inner_mode).is_constant ()
8442 || !CONST_VECTOR_STEPPED_P (x)))
8444 /* Try converting to OUTER_MODE and back. */
8445 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
8446 ASSERT_TRUE (outer_x != NULL_RTX);
8447 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
8448 outer_mode, 0));
8452 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
8454 /* Test each byte in the element range. */
8455 unsigned int limit
8456 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
8457 for (unsigned int i = 0; i < limit; ++i)
8459 unsigned int elt = i / GET_MODE_SIZE (int_mode);
8460 rtx expected = NULL_RTX;
8461 if (elt >= first_valid)
8463 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
8464 if (BYTES_BIG_ENDIAN)
8465 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
8466 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
8467 wide_int shifted_elt
8468 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
8469 expected = immed_wide_int_const (shifted_elt, QImode);
8471 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
8472 ASSERT_RTX_EQ (expected,
8473 simplify_subreg (QImode, x, inner_mode, byte));
8478 /* Test constant subregs of integer vector mode INNER_MODE, using 1
8479 element per pattern. */
8481 static void
8482 test_vector_subregs_repeating (machine_mode inner_mode)
8484 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8485 unsigned int min_nunits = constant_lower_bound (nunits);
8486 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8487 unsigned int count = gcd (min_nunits, 8);
8489 rtx_vector_builder builder (inner_mode, count, 1);
8490 for (unsigned int i = 0; i < count; ++i)
8491 builder.quick_push (gen_int_mode (8 - i, int_mode));
8492 rtx x = builder.build ();
8494 test_vector_subregs_modes (x);
8495 if (!nunits.is_constant ())
8496 test_vector_subregs_modes (x, nunits - min_nunits);
8499 /* Test constant subregs of integer vector mode INNER_MODE, using 2
8500 elements per pattern. */
8502 static void
8503 test_vector_subregs_fore_back (machine_mode inner_mode)
8505 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8506 unsigned int min_nunits = constant_lower_bound (nunits);
8507 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8508 unsigned int count = gcd (min_nunits, 4);
8510 rtx_vector_builder builder (inner_mode, count, 2);
8511 for (unsigned int i = 0; i < count; ++i)
8512 builder.quick_push (gen_int_mode (i, int_mode));
8513 for (unsigned int i = 0; i < count; ++i)
8514 builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
8515 rtx x = builder.build ();
8517 test_vector_subregs_modes (x);
8518 if (!nunits.is_constant ())
8519 test_vector_subregs_modes (x, nunits - min_nunits, count);
8522 /* Test constant subregs of integer vector mode INNER_MODE, using 3
8523 elements per pattern. */
8525 static void
8526 test_vector_subregs_stepped (machine_mode inner_mode)
8528 /* Build { 0, 1, 2, 3, ... }. */
8529 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8530 rtx_vector_builder builder (inner_mode, 1, 3);
8531 for (unsigned int i = 0; i < 3; ++i)
8532 builder.quick_push (gen_int_mode (i, int_mode));
8533 rtx x = builder.build ();
8535 test_vector_subregs_modes (x);
8538 /* Test constant subregs of integer vector mode INNER_MODE. */
8540 static void
8541 test_vector_subregs (machine_mode inner_mode)
8543 test_vector_subregs_repeating (inner_mode);
8544 test_vector_subregs_fore_back (inner_mode);
8545 test_vector_subregs_stepped (inner_mode);
8548 /* Verify some simplifications involving vectors. */
8550 static void
8551 test_vector_ops ()
8553 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8555 machine_mode mode = (machine_mode) i;
8556 if (VECTOR_MODE_P (mode))
8558 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
8559 test_vector_ops_duplicate (mode, scalar_reg);
8560 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
8561 && maybe_gt (GET_MODE_NUNITS (mode), 2))
8563 test_vector_ops_series (mode, scalar_reg);
8564 test_vector_subregs (mode);
8566 test_vec_merge (mode);
8571 template<unsigned int N>
8572 struct simplify_const_poly_int_tests
8574 static void run ();
8577 template<>
8578 struct simplify_const_poly_int_tests<1>
8580 static void run () {}
8583 /* Test various CONST_POLY_INT properties. */
8585 template<unsigned int N>
8586 void
8587 simplify_const_poly_int_tests<N>::run ()
8589 rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
8590 rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
8591 rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
8592 rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
8593 rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
8594 rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
8595 rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
8596 rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
8597 rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
8598 rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
8599 rtx two = GEN_INT (2);
8600 rtx six = GEN_INT (6);
8601 poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
8603 /* These tests only try limited operation combinations. Fuller arithmetic
8604 testing is done directly on poly_ints. */
8605 ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
8606 ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
8607 ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
8608 ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
8609 ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
8610 ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
8611 ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
8612 ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
8613 ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
8614 ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
8615 ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
8618 /* Run all of the selftests within this file. */
8620 void
8621 simplify_rtx_cc_tests ()
8623 test_scalar_ops ();
8624 test_vector_ops ();
8625 simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
8628 } // namespace selftest
8630 #endif /* CHECKING_P */