ada: output.adb: fix newline being inserted when buffer is full
[official-gcc.git] / gcc / simplify-rtx.cc
blob7fb1e97fbea4e7b8b091f5724ebe0cb61eee7ec3
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>)) = (ffs <X>) */
1408 if (GET_CODE (op) == SIGN_EXTEND
1409 || GET_CODE (op) == ZERO_EXTEND)
1410 return simplify_gen_unary (FFS, mode, XEXP (op, 0),
1411 GET_MODE (XEXP (op, 0)));
1412 break;
1414 case POPCOUNT:
1415 switch (GET_CODE (op))
1417 case BSWAP:
1418 case ZERO_EXTEND:
1419 /* (popcount (zero_extend <X>)) = (popcount <X>) */
1420 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1421 GET_MODE (XEXP (op, 0)));
1423 case ROTATE:
1424 case ROTATERT:
1425 /* Rotations don't affect popcount. */
1426 if (!side_effects_p (XEXP (op, 1)))
1427 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1428 GET_MODE (XEXP (op, 0)));
1429 break;
1431 default:
1432 break;
1434 break;
1436 case PARITY:
1437 switch (GET_CODE (op))
1439 case NOT:
1440 case BSWAP:
1441 case ZERO_EXTEND:
1442 case SIGN_EXTEND:
1443 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1444 GET_MODE (XEXP (op, 0)));
1446 case ROTATE:
1447 case ROTATERT:
1448 /* Rotations don't affect parity. */
1449 if (!side_effects_p (XEXP (op, 1)))
1450 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1451 GET_MODE (XEXP (op, 0)));
1452 break;
1454 case PARITY:
1455 /* (parity (parity x)) -> parity (x). */
1456 return op;
1458 default:
1459 break;
1461 break;
1463 case BSWAP:
1464 /* (bswap (bswap x)) -> x. */
1465 if (GET_CODE (op) == BSWAP)
1466 return XEXP (op, 0);
1467 break;
1469 case FLOAT:
1470 /* (float (sign_extend <X>)) = (float <X>). */
1471 if (GET_CODE (op) == SIGN_EXTEND)
1472 return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1473 GET_MODE (XEXP (op, 0)));
1474 break;
1476 case SIGN_EXTEND:
1477 /* Check for useless extension. */
1478 if (GET_MODE (op) == mode)
1479 return op;
1481 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1482 becomes just the MINUS if its mode is MODE. This allows
1483 folding switch statements on machines using casesi (such as
1484 the VAX). */
1485 if (GET_CODE (op) == TRUNCATE
1486 && GET_MODE (XEXP (op, 0)) == mode
1487 && GET_CODE (XEXP (op, 0)) == MINUS
1488 && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1489 && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1490 return XEXP (op, 0);
1492 /* Extending a widening multiplication should be canonicalized to
1493 a wider widening multiplication. */
1494 if (GET_CODE (op) == MULT)
1496 rtx lhs = XEXP (op, 0);
1497 rtx rhs = XEXP (op, 1);
1498 enum rtx_code lcode = GET_CODE (lhs);
1499 enum rtx_code rcode = GET_CODE (rhs);
1501 /* Widening multiplies usually extend both operands, but sometimes
1502 they use a shift to extract a portion of a register. */
1503 if ((lcode == SIGN_EXTEND
1504 || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1505 && (rcode == SIGN_EXTEND
1506 || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1508 machine_mode lmode = GET_MODE (lhs);
1509 machine_mode rmode = GET_MODE (rhs);
1510 int bits;
1512 if (lcode == ASHIFTRT)
1513 /* Number of bits not shifted off the end. */
1514 bits = (GET_MODE_UNIT_PRECISION (lmode)
1515 - INTVAL (XEXP (lhs, 1)));
1516 else /* lcode == SIGN_EXTEND */
1517 /* Size of inner mode. */
1518 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1520 if (rcode == ASHIFTRT)
1521 bits += (GET_MODE_UNIT_PRECISION (rmode)
1522 - INTVAL (XEXP (rhs, 1)));
1523 else /* rcode == SIGN_EXTEND */
1524 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1526 /* We can only widen multiplies if the result is mathematiclly
1527 equivalent. I.e. if overflow was impossible. */
1528 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1529 return simplify_gen_binary
1530 (MULT, mode,
1531 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1532 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1536 /* Check for a sign extension of a subreg of a promoted
1537 variable, where the promotion is sign-extended, and the
1538 target mode is the same as the variable's promotion. */
1539 if (GET_CODE (op) == SUBREG
1540 && SUBREG_PROMOTED_VAR_P (op)
1541 && SUBREG_PROMOTED_SIGNED_P (op))
1543 rtx subreg = SUBREG_REG (op);
1544 machine_mode subreg_mode = GET_MODE (subreg);
1545 if (!paradoxical_subreg_p (mode, subreg_mode))
1547 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1548 if (temp)
1550 /* Preserve SUBREG_PROMOTED_VAR_P. */
1551 if (partial_subreg_p (temp))
1553 SUBREG_PROMOTED_VAR_P (temp) = 1;
1554 SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1556 return temp;
1559 else
1560 /* Sign-extending a sign-extended subreg. */
1561 return simplify_gen_unary (SIGN_EXTEND, mode,
1562 subreg, subreg_mode);
1565 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1566 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1567 if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1569 gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1570 > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1571 return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1572 GET_MODE (XEXP (op, 0)));
1575 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1576 is (sign_extend:M (subreg:O <X>)) if there is mode with
1577 GET_MODE_BITSIZE (N) - I bits.
1578 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1579 is similarly (zero_extend:M (subreg:O <X>)). */
1580 if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1581 && GET_CODE (XEXP (op, 0)) == ASHIFT
1582 && is_a <scalar_int_mode> (mode, &int_mode)
1583 && CONST_INT_P (XEXP (op, 1))
1584 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1585 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1586 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1588 scalar_int_mode tmode;
1589 gcc_assert (GET_MODE_PRECISION (int_mode)
1590 > GET_MODE_PRECISION (op_mode));
1591 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1592 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1594 rtx inner =
1595 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1596 if (inner)
1597 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1598 ? SIGN_EXTEND : ZERO_EXTEND,
1599 int_mode, inner, tmode);
1603 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1604 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1605 if (GET_CODE (op) == LSHIFTRT
1606 && CONST_INT_P (XEXP (op, 1))
1607 && XEXP (op, 1) != const0_rtx)
1608 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1610 /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1611 I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1612 (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1613 (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1614 O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1615 wider than O. */
1616 if (GET_CODE (op) == TRUNCATE
1617 && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1618 && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1620 scalar_int_mode m_mode, n_mode, o_mode;
1621 rtx old_shift = XEXP (op, 0);
1622 if (is_a <scalar_int_mode> (mode, &m_mode)
1623 && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1624 && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1625 && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1626 == INTVAL (XEXP (old_shift, 1)))
1628 rtx new_shift = simplify_gen_binary (ASHIFTRT,
1629 GET_MODE (old_shift),
1630 XEXP (old_shift, 0),
1631 XEXP (old_shift, 1));
1632 if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1633 return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1634 GET_MODE (new_shift));
1635 if (mode != GET_MODE (new_shift))
1636 return simplify_gen_unary (TRUNCATE, mode, new_shift,
1637 GET_MODE (new_shift));
1638 return new_shift;
1642 /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1643 we know the sign bit of OP must be clear. */
1644 if (val_signbit_known_clear_p (GET_MODE (op),
1645 nonzero_bits (op, GET_MODE (op))))
1646 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1648 /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1649 if (GET_CODE (op) == SUBREG
1650 && subreg_lowpart_p (op)
1651 && GET_MODE (SUBREG_REG (op)) == mode
1652 && is_a <scalar_int_mode> (mode, &int_mode)
1653 && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1654 && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1655 && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1656 && (nonzero_bits (SUBREG_REG (op), mode)
1657 & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1658 return SUBREG_REG (op);
1660 #if defined(POINTERS_EXTEND_UNSIGNED)
1661 /* As we do not know which address space the pointer is referring to,
1662 we can do this only if the target does not support different pointer
1663 or address modes depending on the address space. */
1664 if (target_default_pointer_address_modes_p ()
1665 && ! POINTERS_EXTEND_UNSIGNED
1666 && mode == Pmode && GET_MODE (op) == ptr_mode
1667 && (CONSTANT_P (op)
1668 || (GET_CODE (op) == SUBREG
1669 && REG_P (SUBREG_REG (op))
1670 && REG_POINTER (SUBREG_REG (op))
1671 && GET_MODE (SUBREG_REG (op)) == Pmode))
1672 && !targetm.have_ptr_extend ())
1674 temp
1675 = convert_memory_address_addr_space_1 (Pmode, op,
1676 ADDR_SPACE_GENERIC, false,
1677 true);
1678 if (temp)
1679 return temp;
1681 #endif
1682 break;
1684 case ZERO_EXTEND:
1685 /* Check for useless extension. */
1686 if (GET_MODE (op) == mode)
1687 return op;
1689 /* Check for a zero extension of a subreg of a promoted
1690 variable, where the promotion is zero-extended, and the
1691 target mode is the same as the variable's promotion. */
1692 if (GET_CODE (op) == SUBREG
1693 && SUBREG_PROMOTED_VAR_P (op)
1694 && SUBREG_PROMOTED_UNSIGNED_P (op))
1696 rtx subreg = SUBREG_REG (op);
1697 machine_mode subreg_mode = GET_MODE (subreg);
1698 if (!paradoxical_subreg_p (mode, subreg_mode))
1700 temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1701 if (temp)
1703 /* Preserve SUBREG_PROMOTED_VAR_P. */
1704 if (partial_subreg_p (temp))
1706 SUBREG_PROMOTED_VAR_P (temp) = 1;
1707 SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1709 return temp;
1712 else
1713 /* Zero-extending a zero-extended subreg. */
1714 return simplify_gen_unary (ZERO_EXTEND, mode,
1715 subreg, subreg_mode);
1718 /* Extending a widening multiplication should be canonicalized to
1719 a wider widening multiplication. */
1720 if (GET_CODE (op) == MULT)
1722 rtx lhs = XEXP (op, 0);
1723 rtx rhs = XEXP (op, 1);
1724 enum rtx_code lcode = GET_CODE (lhs);
1725 enum rtx_code rcode = GET_CODE (rhs);
1727 /* Widening multiplies usually extend both operands, but sometimes
1728 they use a shift to extract a portion of a register. */
1729 if ((lcode == ZERO_EXTEND
1730 || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1731 && (rcode == ZERO_EXTEND
1732 || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1734 machine_mode lmode = GET_MODE (lhs);
1735 machine_mode rmode = GET_MODE (rhs);
1736 int bits;
1738 if (lcode == LSHIFTRT)
1739 /* Number of bits not shifted off the end. */
1740 bits = (GET_MODE_UNIT_PRECISION (lmode)
1741 - INTVAL (XEXP (lhs, 1)));
1742 else /* lcode == ZERO_EXTEND */
1743 /* Size of inner mode. */
1744 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1746 if (rcode == LSHIFTRT)
1747 bits += (GET_MODE_UNIT_PRECISION (rmode)
1748 - INTVAL (XEXP (rhs, 1)));
1749 else /* rcode == ZERO_EXTEND */
1750 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1752 /* We can only widen multiplies if the result is mathematiclly
1753 equivalent. I.e. if overflow was impossible. */
1754 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1755 return simplify_gen_binary
1756 (MULT, mode,
1757 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1758 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1762 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1763 if (GET_CODE (op) == ZERO_EXTEND)
1764 return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1765 GET_MODE (XEXP (op, 0)));
1767 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1768 is (zero_extend:M (subreg:O <X>)) if there is mode with
1769 GET_MODE_PRECISION (N) - I bits. */
1770 if (GET_CODE (op) == LSHIFTRT
1771 && GET_CODE (XEXP (op, 0)) == ASHIFT
1772 && is_a <scalar_int_mode> (mode, &int_mode)
1773 && CONST_INT_P (XEXP (op, 1))
1774 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1775 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1776 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1778 scalar_int_mode tmode;
1779 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1780 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1782 rtx inner =
1783 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1784 if (inner)
1785 return simplify_gen_unary (ZERO_EXTEND, int_mode,
1786 inner, tmode);
1790 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1791 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1792 of mode N. E.g.
1793 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1794 (and:SI (reg:SI) (const_int 63)). */
1795 if (partial_subreg_p (op)
1796 && is_a <scalar_int_mode> (mode, &int_mode)
1797 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1798 && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1799 && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1800 && subreg_lowpart_p (op)
1801 && (nonzero_bits (SUBREG_REG (op), op0_mode)
1802 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1804 if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1805 return SUBREG_REG (op);
1806 return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1807 op0_mode);
1810 /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1811 if (GET_CODE (op) == SUBREG
1812 && subreg_lowpart_p (op)
1813 && GET_MODE (SUBREG_REG (op)) == mode
1814 && is_a <scalar_int_mode> (mode, &int_mode)
1815 && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1816 && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1817 && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1818 && (nonzero_bits (SUBREG_REG (op), mode)
1819 & ~GET_MODE_MASK (op_mode)) == 0)
1820 return SUBREG_REG (op);
1822 #if defined(POINTERS_EXTEND_UNSIGNED)
1823 /* As we do not know which address space the pointer is referring to,
1824 we can do this only if the target does not support different pointer
1825 or address modes depending on the address space. */
1826 if (target_default_pointer_address_modes_p ()
1827 && POINTERS_EXTEND_UNSIGNED > 0
1828 && mode == Pmode && GET_MODE (op) == ptr_mode
1829 && (CONSTANT_P (op)
1830 || (GET_CODE (op) == SUBREG
1831 && REG_P (SUBREG_REG (op))
1832 && REG_POINTER (SUBREG_REG (op))
1833 && GET_MODE (SUBREG_REG (op)) == Pmode))
1834 && !targetm.have_ptr_extend ())
1836 temp
1837 = convert_memory_address_addr_space_1 (Pmode, op,
1838 ADDR_SPACE_GENERIC, false,
1839 true);
1840 if (temp)
1841 return temp;
1843 #endif
1844 break;
1846 default:
1847 break;
1850 if (VECTOR_MODE_P (mode)
1851 && vec_duplicate_p (op, &elt)
1852 && code != VEC_DUPLICATE)
1854 if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1855 /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1856 operations by promoting VEC_DUPLICATE to the root of the expression
1857 (as far as possible). */
1858 temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1859 elt, GET_MODE_INNER (GET_MODE (op)));
1860 else
1861 /* Try applying the operator to ELT and see if that simplifies.
1862 We can duplicate the result if so.
1864 The reason we traditionally haven't used simplify_gen_unary
1865 for these codes is that it didn't necessarily seem to be a
1866 win to convert things like:
1868 (neg:V (vec_duplicate:V (reg:S R)))
1872 (vec_duplicate:V (neg:S (reg:S R)))
1874 The first might be done entirely in vector registers while the
1875 second might need a move between register files.
1877 However, there also cases where promoting the vec_duplicate is
1878 more efficient, and there is definite value in having a canonical
1879 form when matching instruction patterns. We should consider
1880 extending the simplify_gen_unary code above to more cases. */
1881 temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1882 elt, GET_MODE_INNER (GET_MODE (op)));
1883 if (temp)
1884 return gen_vec_duplicate (mode, temp);
1887 return 0;
1890 /* Try to compute the value of a unary operation CODE whose output mode is to
1891 be MODE with input operand OP whose mode was originally OP_MODE.
1892 Return zero if the value cannot be computed. */
1894 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1895 rtx op, machine_mode op_mode)
1897 scalar_int_mode result_mode;
1899 if (code == VEC_DUPLICATE)
1901 gcc_assert (VECTOR_MODE_P (mode));
1902 if (GET_MODE (op) != VOIDmode)
1904 if (!VECTOR_MODE_P (GET_MODE (op)))
1905 gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1906 else
1907 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1908 (GET_MODE (op)));
1910 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1911 return gen_const_vec_duplicate (mode, op);
1912 if (GET_CODE (op) == CONST_VECTOR
1913 && (CONST_VECTOR_DUPLICATE_P (op)
1914 || CONST_VECTOR_NUNITS (op).is_constant ()))
1916 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1917 ? CONST_VECTOR_NPATTERNS (op)
1918 : CONST_VECTOR_NUNITS (op).to_constant ());
1919 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1920 rtx_vector_builder builder (mode, npatterns, 1);
1921 for (unsigned i = 0; i < npatterns; i++)
1922 builder.quick_push (CONST_VECTOR_ELT (op, i));
1923 return builder.build ();
1927 if (VECTOR_MODE_P (mode)
1928 && GET_CODE (op) == CONST_VECTOR
1929 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1931 gcc_assert (GET_MODE (op) == op_mode);
1933 rtx_vector_builder builder;
1934 if (!builder.new_unary_operation (mode, op, false))
1935 return 0;
1937 unsigned int count = builder.encoded_nelts ();
1938 for (unsigned int i = 0; i < count; i++)
1940 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1941 CONST_VECTOR_ELT (op, i),
1942 GET_MODE_INNER (op_mode));
1943 if (!x || !valid_for_const_vector_p (mode, x))
1944 return 0;
1945 builder.quick_push (x);
1947 return builder.build ();
1950 /* The order of these tests is critical so that, for example, we don't
1951 check the wrong mode (input vs. output) for a conversion operation,
1952 such as FIX. At some point, this should be simplified. */
1954 if (code == FLOAT && CONST_SCALAR_INT_P (op))
1956 REAL_VALUE_TYPE d;
1958 if (op_mode == VOIDmode)
1960 /* CONST_INT have VOIDmode as the mode. We assume that all
1961 the bits of the constant are significant, though, this is
1962 a dangerous assumption as many times CONST_INTs are
1963 created and used with garbage in the bits outside of the
1964 precision of the implied mode of the const_int. */
1965 op_mode = MAX_MODE_INT;
1968 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1970 /* Avoid the folding if flag_signaling_nans is on and
1971 operand is a signaling NaN. */
1972 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1973 return 0;
1975 d = real_value_truncate (mode, d);
1977 /* Avoid the folding if flag_rounding_math is on and the
1978 conversion is not exact. */
1979 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1981 bool fail = false;
1982 wide_int w = real_to_integer (&d, &fail,
1983 GET_MODE_PRECISION
1984 (as_a <scalar_int_mode> (op_mode)));
1985 if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
1986 return 0;
1989 return const_double_from_real_value (d, mode);
1991 else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
1993 REAL_VALUE_TYPE d;
1995 if (op_mode == VOIDmode)
1997 /* CONST_INT have VOIDmode as the mode. We assume that all
1998 the bits of the constant are significant, though, this is
1999 a dangerous assumption as many times CONST_INTs are
2000 created and used with garbage in the bits outside of the
2001 precision of the implied mode of the const_int. */
2002 op_mode = MAX_MODE_INT;
2005 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2007 /* Avoid the folding if flag_signaling_nans is on and
2008 operand is a signaling NaN. */
2009 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2010 return 0;
2012 d = real_value_truncate (mode, d);
2014 /* Avoid the folding if flag_rounding_math is on and the
2015 conversion is not exact. */
2016 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2018 bool fail = false;
2019 wide_int w = real_to_integer (&d, &fail,
2020 GET_MODE_PRECISION
2021 (as_a <scalar_int_mode> (op_mode)));
2022 if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2023 return 0;
2026 return const_double_from_real_value (d, mode);
2029 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2031 unsigned int width = GET_MODE_PRECISION (result_mode);
2032 if (width > MAX_BITSIZE_MODE_ANY_INT)
2033 return 0;
2035 wide_int result;
2036 scalar_int_mode imode = (op_mode == VOIDmode
2037 ? result_mode
2038 : as_a <scalar_int_mode> (op_mode));
2039 rtx_mode_t op0 = rtx_mode_t (op, imode);
2040 int int_value;
2042 #if TARGET_SUPPORTS_WIDE_INT == 0
2043 /* This assert keeps the simplification from producing a result
2044 that cannot be represented in a CONST_DOUBLE but a lot of
2045 upstream callers expect that this function never fails to
2046 simplify something and so you if you added this to the test
2047 above the code would die later anyway. If this assert
2048 happens, you just need to make the port support wide int. */
2049 gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2050 #endif
2052 switch (code)
2054 case NOT:
2055 result = wi::bit_not (op0);
2056 break;
2058 case NEG:
2059 result = wi::neg (op0);
2060 break;
2062 case ABS:
2063 result = wi::abs (op0);
2064 break;
2066 case FFS:
2067 result = wi::shwi (wi::ffs (op0), result_mode);
2068 break;
2070 case CLZ:
2071 if (wi::ne_p (op0, 0))
2072 int_value = wi::clz (op0);
2073 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2074 return NULL_RTX;
2075 result = wi::shwi (int_value, result_mode);
2076 break;
2078 case CLRSB:
2079 result = wi::shwi (wi::clrsb (op0), result_mode);
2080 break;
2082 case CTZ:
2083 if (wi::ne_p (op0, 0))
2084 int_value = wi::ctz (op0);
2085 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2086 return NULL_RTX;
2087 result = wi::shwi (int_value, result_mode);
2088 break;
2090 case POPCOUNT:
2091 result = wi::shwi (wi::popcount (op0), result_mode);
2092 break;
2094 case PARITY:
2095 result = wi::shwi (wi::parity (op0), result_mode);
2096 break;
2098 case BSWAP:
2099 result = wide_int (op0).bswap ();
2100 break;
2102 case TRUNCATE:
2103 case ZERO_EXTEND:
2104 result = wide_int::from (op0, width, UNSIGNED);
2105 break;
2107 case SIGN_EXTEND:
2108 result = wide_int::from (op0, width, SIGNED);
2109 break;
2111 case SS_NEG:
2112 if (wi::only_sign_bit_p (op0))
2113 result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2114 else
2115 result = wi::neg (op0);
2116 break;
2118 case SS_ABS:
2119 if (wi::only_sign_bit_p (op0))
2120 result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2121 else
2122 result = wi::abs (op0);
2123 break;
2125 case SQRT:
2126 default:
2127 return 0;
2130 return immed_wide_int_const (result, result_mode);
2133 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2134 && SCALAR_FLOAT_MODE_P (mode)
2135 && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2137 REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2138 switch (code)
2140 case SQRT:
2141 return 0;
2142 case ABS:
2143 d = real_value_abs (&d);
2144 break;
2145 case NEG:
2146 d = real_value_negate (&d);
2147 break;
2148 case FLOAT_TRUNCATE:
2149 /* Don't perform the operation if flag_signaling_nans is on
2150 and the operand is a signaling NaN. */
2151 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2152 return NULL_RTX;
2153 /* Or if flag_rounding_math is on and the truncation is not
2154 exact. */
2155 if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2156 && !exact_real_truncate (mode, &d))
2157 return NULL_RTX;
2158 d = real_value_truncate (mode, d);
2159 break;
2160 case FLOAT_EXTEND:
2161 /* Don't perform the operation if flag_signaling_nans is on
2162 and the operand is a signaling NaN. */
2163 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2164 return NULL_RTX;
2165 /* All this does is change the mode, unless changing
2166 mode class. */
2167 if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2168 real_convert (&d, mode, &d);
2169 break;
2170 case FIX:
2171 /* Don't perform the operation if flag_signaling_nans is on
2172 and the operand is a signaling NaN. */
2173 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2174 return NULL_RTX;
2175 real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2176 break;
2177 case NOT:
2179 long tmp[4];
2180 int i;
2182 real_to_target (tmp, &d, GET_MODE (op));
2183 for (i = 0; i < 4; i++)
2184 tmp[i] = ~tmp[i];
2185 real_from_target (&d, tmp, mode);
2186 break;
2188 default:
2189 gcc_unreachable ();
2191 return const_double_from_real_value (d, mode);
2193 else if (CONST_DOUBLE_AS_FLOAT_P (op)
2194 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2195 && is_int_mode (mode, &result_mode))
2197 unsigned int width = GET_MODE_PRECISION (result_mode);
2198 if (width > MAX_BITSIZE_MODE_ANY_INT)
2199 return 0;
2201 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2202 operators are intentionally left unspecified (to ease implementation
2203 by target backends), for consistency, this routine implements the
2204 same semantics for constant folding as used by the middle-end. */
2206 /* This was formerly used only for non-IEEE float.
2207 eggert@twinsun.com says it is safe for IEEE also. */
2208 REAL_VALUE_TYPE t;
2209 const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2210 wide_int wmax, wmin;
2211 /* This is part of the abi to real_to_integer, but we check
2212 things before making this call. */
2213 bool fail;
2215 switch (code)
2217 case FIX:
2218 if (REAL_VALUE_ISNAN (*x))
2219 return const0_rtx;
2221 /* Test against the signed upper bound. */
2222 wmax = wi::max_value (width, SIGNED);
2223 real_from_integer (&t, VOIDmode, wmax, SIGNED);
2224 if (real_less (&t, x))
2225 return immed_wide_int_const (wmax, mode);
2227 /* Test against the signed lower bound. */
2228 wmin = wi::min_value (width, SIGNED);
2229 real_from_integer (&t, VOIDmode, wmin, SIGNED);
2230 if (real_less (x, &t))
2231 return immed_wide_int_const (wmin, mode);
2233 return immed_wide_int_const (real_to_integer (x, &fail, width),
2234 mode);
2236 case UNSIGNED_FIX:
2237 if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2238 return const0_rtx;
2240 /* Test against the unsigned upper bound. */
2241 wmax = wi::max_value (width, UNSIGNED);
2242 real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2243 if (real_less (&t, x))
2244 return immed_wide_int_const (wmax, mode);
2246 return immed_wide_int_const (real_to_integer (x, &fail, width),
2247 mode);
2249 default:
2250 gcc_unreachable ();
2254 /* Handle polynomial integers. */
2255 else if (CONST_POLY_INT_P (op))
2257 poly_wide_int result;
2258 switch (code)
2260 case NEG:
2261 result = -const_poly_int_value (op);
2262 break;
2264 case NOT:
2265 result = ~const_poly_int_value (op);
2266 break;
2268 default:
2269 return NULL_RTX;
2271 return immed_wide_int_const (result, mode);
2274 return NULL_RTX;
2277 /* Subroutine of simplify_binary_operation to simplify a binary operation
2278 CODE that can commute with byte swapping, with result mode MODE and
2279 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2280 Return zero if no simplification or canonicalization is possible. */
2283 simplify_context::simplify_byte_swapping_operation (rtx_code code,
2284 machine_mode mode,
2285 rtx op0, rtx op1)
2287 rtx tem;
2289 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2290 if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2292 tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2293 simplify_gen_unary (BSWAP, mode, op1, mode));
2294 return simplify_gen_unary (BSWAP, mode, tem, mode);
2297 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2298 if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2300 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2301 return simplify_gen_unary (BSWAP, mode, tem, mode);
2304 return NULL_RTX;
2307 /* Subroutine of simplify_binary_operation to simplify a commutative,
2308 associative binary operation CODE with result mode MODE, operating
2309 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2310 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2311 canonicalization is possible. */
2314 simplify_context::simplify_associative_operation (rtx_code code,
2315 machine_mode mode,
2316 rtx op0, rtx op1)
2318 rtx tem;
2320 /* Normally expressions simplified by simplify-rtx.cc are combined
2321 at most from a few machine instructions and therefore the
2322 expressions should be fairly small. During var-tracking
2323 we can see arbitrarily large expressions though and reassociating
2324 those can be quadratic, so punt after encountering max_assoc_count
2325 simplify_associative_operation calls during outermost simplify_*
2326 call. */
2327 if (++assoc_count >= max_assoc_count)
2328 return NULL_RTX;
2330 /* Linearize the operator to the left. */
2331 if (GET_CODE (op1) == code)
2333 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2334 if (GET_CODE (op0) == code)
2336 tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2337 return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2340 /* "a op (b op c)" becomes "(b op c) op a". */
2341 if (! swap_commutative_operands_p (op1, op0))
2342 return simplify_gen_binary (code, mode, op1, op0);
2344 std::swap (op0, op1);
2347 if (GET_CODE (op0) == code)
2349 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2350 if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2352 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2353 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2356 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2357 tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2358 if (tem != 0)
2359 return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2361 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2362 tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2363 if (tem != 0)
2364 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2367 return 0;
2370 /* Return a mask describing the COMPARISON. */
2371 static int
2372 comparison_to_mask (enum rtx_code comparison)
2374 switch (comparison)
2376 case LT:
2377 return 8;
2378 case GT:
2379 return 4;
2380 case EQ:
2381 return 2;
2382 case UNORDERED:
2383 return 1;
2385 case LTGT:
2386 return 12;
2387 case LE:
2388 return 10;
2389 case GE:
2390 return 6;
2391 case UNLT:
2392 return 9;
2393 case UNGT:
2394 return 5;
2395 case UNEQ:
2396 return 3;
2398 case ORDERED:
2399 return 14;
2400 case NE:
2401 return 13;
2402 case UNLE:
2403 return 11;
2404 case UNGE:
2405 return 7;
2407 default:
2408 gcc_unreachable ();
2412 /* Return a comparison corresponding to the MASK. */
2413 static enum rtx_code
2414 mask_to_comparison (int mask)
2416 switch (mask)
2418 case 8:
2419 return LT;
2420 case 4:
2421 return GT;
2422 case 2:
2423 return EQ;
2424 case 1:
2425 return UNORDERED;
2427 case 12:
2428 return LTGT;
2429 case 10:
2430 return LE;
2431 case 6:
2432 return GE;
2433 case 9:
2434 return UNLT;
2435 case 5:
2436 return UNGT;
2437 case 3:
2438 return UNEQ;
2440 case 14:
2441 return ORDERED;
2442 case 13:
2443 return NE;
2444 case 11:
2445 return UNLE;
2446 case 7:
2447 return UNGE;
2449 default:
2450 gcc_unreachable ();
2454 /* Return true if CODE is valid for comparisons of mode MODE, false
2455 otherwise.
2457 It is always safe to return false, even if the code was valid for the
2458 given mode as that will merely suppress optimizations. */
2460 static bool
2461 comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2463 switch (code)
2465 /* These are valid for integral, floating and vector modes. */
2466 case NE:
2467 case EQ:
2468 case GE:
2469 case GT:
2470 case LE:
2471 case LT:
2472 return (INTEGRAL_MODE_P (mode)
2473 || FLOAT_MODE_P (mode)
2474 || VECTOR_MODE_P (mode));
2476 /* These are valid for floating point modes. */
2477 case LTGT:
2478 case UNORDERED:
2479 case ORDERED:
2480 case UNEQ:
2481 case UNGE:
2482 case UNGT:
2483 case UNLE:
2484 case UNLT:
2485 return FLOAT_MODE_P (mode);
2487 /* These are filtered out in simplify_logical_operation, but
2488 we check for them too as a matter of safety. They are valid
2489 for integral and vector modes. */
2490 case GEU:
2491 case GTU:
2492 case LEU:
2493 case LTU:
2494 return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2496 default:
2497 gcc_unreachable ();
2501 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2502 false/true value of comparison with MODE where comparison operands
2503 have CMP_MODE. */
2505 static rtx
2506 relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2508 if (SCALAR_FLOAT_MODE_P (mode))
2510 if (res == const0_rtx)
2511 return CONST0_RTX (mode);
2512 #ifdef FLOAT_STORE_FLAG_VALUE
2513 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2514 return const_double_from_real_value (val, mode);
2515 #else
2516 return NULL_RTX;
2517 #endif
2519 if (VECTOR_MODE_P (mode))
2521 if (res == const0_rtx)
2522 return CONST0_RTX (mode);
2523 #ifdef VECTOR_STORE_FLAG_VALUE
2524 rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2525 if (val == NULL_RTX)
2526 return NULL_RTX;
2527 if (val == const1_rtx)
2528 return CONST1_RTX (mode);
2530 return gen_const_vec_duplicate (mode, val);
2531 #else
2532 return NULL_RTX;
2533 #endif
2535 /* For vector comparison with scalar int result, it is unknown
2536 if the target means here a comparison into an integral bitmask,
2537 or comparison where all comparisons true mean const_true_rtx
2538 whole result, or where any comparisons true mean const_true_rtx
2539 whole result. For const0_rtx all the cases are the same. */
2540 if (VECTOR_MODE_P (cmp_mode)
2541 && SCALAR_INT_MODE_P (mode)
2542 && res == const_true_rtx)
2543 return NULL_RTX;
2545 return res;
2548 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2549 and OP1, which should be both relational operations. Return 0 if no such
2550 simplification is possible. */
2552 simplify_context::simplify_logical_relational_operation (rtx_code code,
2553 machine_mode mode,
2554 rtx op0, rtx op1)
2556 /* We only handle IOR of two relational operations. */
2557 if (code != IOR)
2558 return 0;
2560 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2561 return 0;
2563 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2564 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2565 return 0;
2567 enum rtx_code code0 = GET_CODE (op0);
2568 enum rtx_code code1 = GET_CODE (op1);
2570 /* We don't handle unsigned comparisons currently. */
2571 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2572 return 0;
2573 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2574 return 0;
2576 int mask0 = comparison_to_mask (code0);
2577 int mask1 = comparison_to_mask (code1);
2579 int mask = mask0 | mask1;
2581 if (mask == 15)
2582 return relational_result (mode, GET_MODE (op0), const_true_rtx);
2584 code = mask_to_comparison (mask);
2586 /* Many comparison codes are only valid for certain mode classes. */
2587 if (!comparison_code_valid_for_mode (code, mode))
2588 return 0;
2590 op0 = XEXP (op1, 0);
2591 op1 = XEXP (op1, 1);
2593 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2596 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2597 and OP1. Return 0 if no simplification is possible.
2599 Don't use this for relational operations such as EQ or LT.
2600 Use simplify_relational_operation instead. */
2602 simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2603 rtx op0, rtx op1)
2605 rtx trueop0, trueop1;
2606 rtx tem;
2608 /* Relational operations don't work here. We must know the mode
2609 of the operands in order to do the comparison correctly.
2610 Assuming a full word can give incorrect results.
2611 Consider comparing 128 with -128 in QImode. */
2612 gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2613 gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2615 /* Make sure the constant is second. */
2616 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2617 && swap_commutative_operands_p (op0, op1))
2618 std::swap (op0, op1);
2620 trueop0 = avoid_constant_pool_reference (op0);
2621 trueop1 = avoid_constant_pool_reference (op1);
2623 tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2624 if (tem)
2625 return tem;
2626 tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2628 if (tem)
2629 return tem;
2631 /* If the above steps did not result in a simplification and op0 or op1
2632 were constant pool references, use the referenced constants directly. */
2633 if (trueop0 != op0 || trueop1 != op1)
2634 return simplify_gen_binary (code, mode, trueop0, trueop1);
2636 return NULL_RTX;
2639 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2640 which OP0 and OP1 are both vector series or vector duplicates
2641 (which are really just series with a step of 0). If so, try to
2642 form a new series by applying CODE to the bases and to the steps.
2643 Return null if no simplification is possible.
2645 MODE is the mode of the operation and is known to be a vector
2646 integer mode. */
2649 simplify_context::simplify_binary_operation_series (rtx_code code,
2650 machine_mode mode,
2651 rtx op0, rtx op1)
2653 rtx base0, step0;
2654 if (vec_duplicate_p (op0, &base0))
2655 step0 = const0_rtx;
2656 else if (!vec_series_p (op0, &base0, &step0))
2657 return NULL_RTX;
2659 rtx base1, step1;
2660 if (vec_duplicate_p (op1, &base1))
2661 step1 = const0_rtx;
2662 else if (!vec_series_p (op1, &base1, &step1))
2663 return NULL_RTX;
2665 /* Only create a new series if we can simplify both parts. In other
2666 cases this isn't really a simplification, and it's not necessarily
2667 a win to replace a vector operation with a scalar operation. */
2668 scalar_mode inner_mode = GET_MODE_INNER (mode);
2669 rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2670 if (!new_base)
2671 return NULL_RTX;
2673 rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2674 if (!new_step)
2675 return NULL_RTX;
2677 return gen_vec_series (mode, new_base, new_step);
2680 /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2681 operation CODE with result mode MODE, operating on OP0 and OP1.
2682 e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2683 Returns NULL_RTX if no simplification is possible. */
2686 simplify_context::simplify_distributive_operation (rtx_code code,
2687 machine_mode mode,
2688 rtx op0, rtx op1)
2690 enum rtx_code op = GET_CODE (op0);
2691 gcc_assert (GET_CODE (op1) == op);
2693 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2694 && ! side_effects_p (XEXP (op0, 1)))
2695 return simplify_gen_binary (op, mode,
2696 simplify_gen_binary (code, mode,
2697 XEXP (op0, 0),
2698 XEXP (op1, 0)),
2699 XEXP (op0, 1));
2701 if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2703 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2704 && ! side_effects_p (XEXP (op0, 0)))
2705 return simplify_gen_binary (op, mode,
2706 simplify_gen_binary (code, mode,
2707 XEXP (op0, 1),
2708 XEXP (op1, 1)),
2709 XEXP (op0, 0));
2710 if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2711 && ! side_effects_p (XEXP (op0, 0)))
2712 return simplify_gen_binary (op, mode,
2713 simplify_gen_binary (code, mode,
2714 XEXP (op0, 1),
2715 XEXP (op1, 0)),
2716 XEXP (op0, 0));
2717 if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2718 && ! side_effects_p (XEXP (op0, 1)))
2719 return simplify_gen_binary (op, mode,
2720 simplify_gen_binary (code, mode,
2721 XEXP (op0, 0),
2722 XEXP (op1, 1)),
2723 XEXP (op0, 1));
2726 return NULL_RTX;
2729 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2730 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2731 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2732 actual constants. */
2735 simplify_context::simplify_binary_operation_1 (rtx_code code,
2736 machine_mode mode,
2737 rtx op0, rtx op1,
2738 rtx trueop0, rtx trueop1)
2740 rtx tem, reversed, opleft, opright, elt0, elt1;
2741 HOST_WIDE_INT val;
2742 scalar_int_mode int_mode, inner_mode;
2743 poly_int64 offset;
2745 /* Even if we can't compute a constant result,
2746 there are some cases worth simplifying. */
2748 switch (code)
2750 case PLUS:
2751 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2752 when x is NaN, infinite, or finite and nonzero. They aren't
2753 when x is -0 and the rounding mode is not towards -infinity,
2754 since (-0) + 0 is then 0. */
2755 if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2756 return op0;
2758 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2759 transformations are safe even for IEEE. */
2760 if (GET_CODE (op0) == NEG)
2761 return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2762 else if (GET_CODE (op1) == NEG)
2763 return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2765 /* (~a) + 1 -> -a */
2766 if (INTEGRAL_MODE_P (mode)
2767 && GET_CODE (op0) == NOT
2768 && trueop1 == const1_rtx)
2769 return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2771 /* Handle both-operands-constant cases. We can only add
2772 CONST_INTs to constants since the sum of relocatable symbols
2773 can't be handled by most assemblers. Don't add CONST_INT
2774 to CONST_INT since overflow won't be computed properly if wider
2775 than HOST_BITS_PER_WIDE_INT. */
2777 if ((GET_CODE (op0) == CONST
2778 || GET_CODE (op0) == SYMBOL_REF
2779 || GET_CODE (op0) == LABEL_REF)
2780 && poly_int_rtx_p (op1, &offset))
2781 return plus_constant (mode, op0, offset);
2782 else if ((GET_CODE (op1) == CONST
2783 || GET_CODE (op1) == SYMBOL_REF
2784 || GET_CODE (op1) == LABEL_REF)
2785 && poly_int_rtx_p (op0, &offset))
2786 return plus_constant (mode, op1, offset);
2788 /* See if this is something like X * C - X or vice versa or
2789 if the multiplication is written as a shift. If so, we can
2790 distribute and make a new multiply, shift, or maybe just
2791 have X (if C is 2 in the example above). But don't make
2792 something more expensive than we had before. */
2794 if (is_a <scalar_int_mode> (mode, &int_mode))
2796 rtx lhs = op0, rhs = op1;
2798 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2799 wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2801 if (GET_CODE (lhs) == NEG)
2803 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2804 lhs = XEXP (lhs, 0);
2806 else if (GET_CODE (lhs) == MULT
2807 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2809 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2810 lhs = XEXP (lhs, 0);
2812 else if (GET_CODE (lhs) == ASHIFT
2813 && CONST_INT_P (XEXP (lhs, 1))
2814 && INTVAL (XEXP (lhs, 1)) >= 0
2815 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2817 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2818 GET_MODE_PRECISION (int_mode));
2819 lhs = XEXP (lhs, 0);
2822 if (GET_CODE (rhs) == NEG)
2824 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2825 rhs = XEXP (rhs, 0);
2827 else if (GET_CODE (rhs) == MULT
2828 && CONST_INT_P (XEXP (rhs, 1)))
2830 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2831 rhs = XEXP (rhs, 0);
2833 else if (GET_CODE (rhs) == ASHIFT
2834 && CONST_INT_P (XEXP (rhs, 1))
2835 && INTVAL (XEXP (rhs, 1)) >= 0
2836 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2838 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2839 GET_MODE_PRECISION (int_mode));
2840 rhs = XEXP (rhs, 0);
2843 if (rtx_equal_p (lhs, rhs))
2845 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2846 rtx coeff;
2847 bool speed = optimize_function_for_speed_p (cfun);
2849 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2851 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2852 return (set_src_cost (tem, int_mode, speed)
2853 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2856 /* Optimize (X - 1) * Y + Y to X * Y. */
2857 lhs = op0;
2858 rhs = op1;
2859 if (GET_CODE (op0) == MULT)
2861 if (((GET_CODE (XEXP (op0, 0)) == PLUS
2862 && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
2863 || (GET_CODE (XEXP (op0, 0)) == MINUS
2864 && XEXP (XEXP (op0, 0), 1) == const1_rtx))
2865 && rtx_equal_p (XEXP (op0, 1), op1))
2866 lhs = XEXP (XEXP (op0, 0), 0);
2867 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2868 && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
2869 || (GET_CODE (XEXP (op0, 1)) == MINUS
2870 && XEXP (XEXP (op0, 1), 1) == const1_rtx))
2871 && rtx_equal_p (XEXP (op0, 0), op1))
2872 lhs = XEXP (XEXP (op0, 1), 0);
2874 else if (GET_CODE (op1) == MULT)
2876 if (((GET_CODE (XEXP (op1, 0)) == PLUS
2877 && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
2878 || (GET_CODE (XEXP (op1, 0)) == MINUS
2879 && XEXP (XEXP (op1, 0), 1) == const1_rtx))
2880 && rtx_equal_p (XEXP (op1, 1), op0))
2881 rhs = XEXP (XEXP (op1, 0), 0);
2882 else if (((GET_CODE (XEXP (op1, 1)) == PLUS
2883 && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
2884 || (GET_CODE (XEXP (op1, 1)) == MINUS
2885 && XEXP (XEXP (op1, 1), 1) == const1_rtx))
2886 && rtx_equal_p (XEXP (op1, 0), op0))
2887 rhs = XEXP (XEXP (op1, 1), 0);
2889 if (lhs != op0 || rhs != op1)
2890 return simplify_gen_binary (MULT, int_mode, lhs, rhs);
2893 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2894 if (CONST_SCALAR_INT_P (op1)
2895 && GET_CODE (op0) == XOR
2896 && CONST_SCALAR_INT_P (XEXP (op0, 1))
2897 && mode_signbit_p (mode, op1))
2898 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2899 simplify_gen_binary (XOR, mode, op1,
2900 XEXP (op0, 1)));
2902 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2903 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2904 && GET_CODE (op0) == MULT
2905 && GET_CODE (XEXP (op0, 0)) == NEG)
2907 rtx in1, in2;
2909 in1 = XEXP (XEXP (op0, 0), 0);
2910 in2 = XEXP (op0, 1);
2911 return simplify_gen_binary (MINUS, mode, op1,
2912 simplify_gen_binary (MULT, mode,
2913 in1, in2));
2916 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2917 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2918 is 1. */
2919 if (COMPARISON_P (op0)
2920 && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2921 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2922 && (reversed = reversed_comparison (op0, mode)))
2923 return
2924 simplify_gen_unary (NEG, mode, reversed, mode);
2926 /* If one of the operands is a PLUS or a MINUS, see if we can
2927 simplify this by the associative law.
2928 Don't use the associative law for floating point.
2929 The inaccuracy makes it nonassociative,
2930 and subtle programs can break if operations are associated. */
2932 if (INTEGRAL_MODE_P (mode)
2933 && (plus_minus_operand_p (op0)
2934 || plus_minus_operand_p (op1))
2935 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2936 return tem;
2938 /* Reassociate floating point addition only when the user
2939 specifies associative math operations. */
2940 if (FLOAT_MODE_P (mode)
2941 && flag_associative_math)
2943 tem = simplify_associative_operation (code, mode, op0, op1);
2944 if (tem)
2945 return tem;
2948 /* Handle vector series. */
2949 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2951 tem = simplify_binary_operation_series (code, mode, op0, op1);
2952 if (tem)
2953 return tem;
2955 break;
2957 case COMPARE:
2958 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
2959 if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
2960 || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
2961 && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
2963 rtx xop00 = XEXP (op0, 0);
2964 rtx xop10 = XEXP (op1, 0);
2966 if (REG_P (xop00) && REG_P (xop10)
2967 && REGNO (xop00) == REGNO (xop10)
2968 && GET_MODE (xop00) == mode
2969 && GET_MODE (xop10) == mode
2970 && GET_MODE_CLASS (mode) == MODE_CC)
2971 return xop00;
2973 break;
2975 case MINUS:
2976 /* We can't assume x-x is 0 even with non-IEEE floating point,
2977 but since it is zero except in very strange circumstances, we
2978 will treat it as zero with -ffinite-math-only. */
2979 if (rtx_equal_p (trueop0, trueop1)
2980 && ! side_effects_p (op0)
2981 && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
2982 return CONST0_RTX (mode);
2984 /* Change subtraction from zero into negation. (0 - x) is the
2985 same as -x when x is NaN, infinite, or finite and nonzero.
2986 But if the mode has signed zeros, and does not round towards
2987 -infinity, then 0 - 0 is 0, not -0. */
2988 if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
2989 return simplify_gen_unary (NEG, mode, op1, mode);
2991 /* (-1 - a) is ~a, unless the expression contains symbolic
2992 constants, in which case not retaining additions and
2993 subtractions could cause invalid assembly to be produced. */
2994 if (trueop0 == constm1_rtx
2995 && !contains_symbolic_reference_p (op1))
2996 return simplify_gen_unary (NOT, mode, op1, mode);
2998 /* Subtracting 0 has no effect unless the mode has signalling NaNs,
2999 or has signed zeros and supports rounding towards -infinity.
3000 In such a case, 0 - 0 is -0. */
3001 if (!(HONOR_SIGNED_ZEROS (mode)
3002 && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3003 && !HONOR_SNANS (mode)
3004 && trueop1 == CONST0_RTX (mode))
3005 return op0;
3007 /* See if this is something like X * C - X or vice versa or
3008 if the multiplication is written as a shift. If so, we can
3009 distribute and make a new multiply, shift, or maybe just
3010 have X (if C is 2 in the example above). But don't make
3011 something more expensive than we had before. */
3013 if (is_a <scalar_int_mode> (mode, &int_mode))
3015 rtx lhs = op0, rhs = op1;
3017 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3018 wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3020 if (GET_CODE (lhs) == NEG)
3022 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3023 lhs = XEXP (lhs, 0);
3025 else if (GET_CODE (lhs) == MULT
3026 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3028 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3029 lhs = XEXP (lhs, 0);
3031 else if (GET_CODE (lhs) == ASHIFT
3032 && CONST_INT_P (XEXP (lhs, 1))
3033 && INTVAL (XEXP (lhs, 1)) >= 0
3034 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3036 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3037 GET_MODE_PRECISION (int_mode));
3038 lhs = XEXP (lhs, 0);
3041 if (GET_CODE (rhs) == NEG)
3043 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3044 rhs = XEXP (rhs, 0);
3046 else if (GET_CODE (rhs) == MULT
3047 && CONST_INT_P (XEXP (rhs, 1)))
3049 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3050 rhs = XEXP (rhs, 0);
3052 else if (GET_CODE (rhs) == ASHIFT
3053 && CONST_INT_P (XEXP (rhs, 1))
3054 && INTVAL (XEXP (rhs, 1)) >= 0
3055 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3057 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3058 GET_MODE_PRECISION (int_mode));
3059 negcoeff1 = -negcoeff1;
3060 rhs = XEXP (rhs, 0);
3063 if (rtx_equal_p (lhs, rhs))
3065 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3066 rtx coeff;
3067 bool speed = optimize_function_for_speed_p (cfun);
3069 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3071 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3072 return (set_src_cost (tem, int_mode, speed)
3073 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3076 /* Optimize (X + 1) * Y - Y to X * Y. */
3077 lhs = op0;
3078 if (GET_CODE (op0) == MULT)
3080 if (((GET_CODE (XEXP (op0, 0)) == PLUS
3081 && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3082 || (GET_CODE (XEXP (op0, 0)) == MINUS
3083 && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3084 && rtx_equal_p (XEXP (op0, 1), op1))
3085 lhs = XEXP (XEXP (op0, 0), 0);
3086 else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3087 && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3088 || (GET_CODE (XEXP (op0, 1)) == MINUS
3089 && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3090 && rtx_equal_p (XEXP (op0, 0), op1))
3091 lhs = XEXP (XEXP (op0, 1), 0);
3093 if (lhs != op0)
3094 return simplify_gen_binary (MULT, int_mode, lhs, op1);
3097 /* (a - (-b)) -> (a + b). True even for IEEE. */
3098 if (GET_CODE (op1) == NEG)
3099 return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3101 /* (-x - c) may be simplified as (-c - x). */
3102 if (GET_CODE (op0) == NEG
3103 && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3105 tem = simplify_unary_operation (NEG, mode, op1, mode);
3106 if (tem)
3107 return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3110 if ((GET_CODE (op0) == CONST
3111 || GET_CODE (op0) == SYMBOL_REF
3112 || GET_CODE (op0) == LABEL_REF)
3113 && poly_int_rtx_p (op1, &offset))
3114 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3116 /* Don't let a relocatable value get a negative coeff. */
3117 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
3118 return simplify_gen_binary (PLUS, mode,
3119 op0,
3120 neg_poly_int_rtx (mode, op1));
3122 /* (x - (x & y)) -> (x & ~y) */
3123 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3125 if (rtx_equal_p (op0, XEXP (op1, 0)))
3127 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3128 GET_MODE (XEXP (op1, 1)));
3129 return simplify_gen_binary (AND, mode, op0, tem);
3131 if (rtx_equal_p (op0, XEXP (op1, 1)))
3133 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3134 GET_MODE (XEXP (op1, 0)));
3135 return simplify_gen_binary (AND, mode, op0, tem);
3139 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3140 by reversing the comparison code if valid. */
3141 if (STORE_FLAG_VALUE == 1
3142 && trueop0 == const1_rtx
3143 && COMPARISON_P (op1)
3144 && (reversed = reversed_comparison (op1, mode)))
3145 return reversed;
3147 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3148 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3149 && GET_CODE (op1) == MULT
3150 && GET_CODE (XEXP (op1, 0)) == NEG)
3152 rtx in1, in2;
3154 in1 = XEXP (XEXP (op1, 0), 0);
3155 in2 = XEXP (op1, 1);
3156 return simplify_gen_binary (PLUS, mode,
3157 simplify_gen_binary (MULT, mode,
3158 in1, in2),
3159 op0);
3162 /* Canonicalize (minus (neg A) (mult B C)) to
3163 (minus (mult (neg B) C) A). */
3164 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3165 && GET_CODE (op1) == MULT
3166 && GET_CODE (op0) == NEG)
3168 rtx in1, in2;
3170 in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3171 in2 = XEXP (op1, 1);
3172 return simplify_gen_binary (MINUS, mode,
3173 simplify_gen_binary (MULT, mode,
3174 in1, in2),
3175 XEXP (op0, 0));
3178 /* If one of the operands is a PLUS or a MINUS, see if we can
3179 simplify this by the associative law. This will, for example,
3180 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3181 Don't use the associative law for floating point.
3182 The inaccuracy makes it nonassociative,
3183 and subtle programs can break if operations are associated. */
3185 if (INTEGRAL_MODE_P (mode)
3186 && (plus_minus_operand_p (op0)
3187 || plus_minus_operand_p (op1))
3188 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3189 return tem;
3191 /* Handle vector series. */
3192 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3194 tem = simplify_binary_operation_series (code, mode, op0, op1);
3195 if (tem)
3196 return tem;
3198 break;
3200 case MULT:
3201 if (trueop1 == constm1_rtx)
3202 return simplify_gen_unary (NEG, mode, op0, mode);
3204 if (GET_CODE (op0) == NEG)
3206 rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3207 /* If op1 is a MULT as well and simplify_unary_operation
3208 just moved the NEG to the second operand, simplify_gen_binary
3209 below could through simplify_associative_operation move
3210 the NEG around again and recurse endlessly. */
3211 if (temp
3212 && GET_CODE (op1) == MULT
3213 && GET_CODE (temp) == MULT
3214 && XEXP (op1, 0) == XEXP (temp, 0)
3215 && GET_CODE (XEXP (temp, 1)) == NEG
3216 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3217 temp = NULL_RTX;
3218 if (temp)
3219 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3221 if (GET_CODE (op1) == NEG)
3223 rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3224 /* If op0 is a MULT as well and simplify_unary_operation
3225 just moved the NEG to the second operand, simplify_gen_binary
3226 below could through simplify_associative_operation move
3227 the NEG around again and recurse endlessly. */
3228 if (temp
3229 && GET_CODE (op0) == MULT
3230 && GET_CODE (temp) == MULT
3231 && XEXP (op0, 0) == XEXP (temp, 0)
3232 && GET_CODE (XEXP (temp, 1)) == NEG
3233 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3234 temp = NULL_RTX;
3235 if (temp)
3236 return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3239 /* Maybe simplify x * 0 to 0. The reduction is not valid if
3240 x is NaN, since x * 0 is then also NaN. Nor is it valid
3241 when the mode has signed zeros, since multiplying a negative
3242 number by 0 will give -0, not 0. */
3243 if (!HONOR_NANS (mode)
3244 && !HONOR_SIGNED_ZEROS (mode)
3245 && trueop1 == CONST0_RTX (mode)
3246 && ! side_effects_p (op0))
3247 return op1;
3249 /* In IEEE floating point, x*1 is not equivalent to x for
3250 signalling NaNs. */
3251 if (!HONOR_SNANS (mode)
3252 && trueop1 == CONST1_RTX (mode))
3253 return op0;
3255 /* Convert multiply by constant power of two into shift. */
3256 if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3258 val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3259 if (val >= 0)
3260 return simplify_gen_binary (ASHIFT, mode, op0,
3261 gen_int_shift_amount (mode, val));
3264 /* x*2 is x+x and x*(-1) is -x */
3265 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3266 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3267 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3268 && GET_MODE (op0) == mode)
3270 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3272 if (real_equal (d1, &dconst2))
3273 return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3275 if (!HONOR_SNANS (mode)
3276 && real_equal (d1, &dconstm1))
3277 return simplify_gen_unary (NEG, mode, op0, mode);
3280 /* Optimize -x * -x as x * x. */
3281 if (FLOAT_MODE_P (mode)
3282 && GET_CODE (op0) == NEG
3283 && GET_CODE (op1) == NEG
3284 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3285 && !side_effects_p (XEXP (op0, 0)))
3286 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3288 /* Likewise, optimize abs(x) * abs(x) as x * x. */
3289 if (SCALAR_FLOAT_MODE_P (mode)
3290 && GET_CODE (op0) == ABS
3291 && GET_CODE (op1) == ABS
3292 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3293 && !side_effects_p (XEXP (op0, 0)))
3294 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3296 /* Reassociate multiplication, but for floating point MULTs
3297 only when the user specifies unsafe math optimizations. */
3298 if (! FLOAT_MODE_P (mode)
3299 || flag_unsafe_math_optimizations)
3301 tem = simplify_associative_operation (code, mode, op0, op1);
3302 if (tem)
3303 return tem;
3305 break;
3307 case IOR:
3308 if (trueop1 == CONST0_RTX (mode))
3309 return op0;
3310 if (INTEGRAL_MODE_P (mode)
3311 && trueop1 == CONSTM1_RTX (mode)
3312 && !side_effects_p (op0))
3313 return op1;
3314 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3315 return op0;
3316 /* A | (~A) -> -1 */
3317 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3318 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3319 && ! side_effects_p (op0)
3320 && SCALAR_INT_MODE_P (mode))
3321 return constm1_rtx;
3323 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3324 if (CONST_INT_P (op1)
3325 && HWI_COMPUTABLE_MODE_P (mode)
3326 && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3327 && !side_effects_p (op0))
3328 return op1;
3330 /* Canonicalize (X & C1) | C2. */
3331 if (GET_CODE (op0) == AND
3332 && CONST_INT_P (trueop1)
3333 && CONST_INT_P (XEXP (op0, 1)))
3335 HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3336 HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3337 HOST_WIDE_INT c2 = INTVAL (trueop1);
3339 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3340 if ((c1 & c2) == c1
3341 && !side_effects_p (XEXP (op0, 0)))
3342 return trueop1;
3344 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3345 if (((c1|c2) & mask) == mask)
3346 return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3349 /* Convert (A & B) | A to A. */
3350 if (GET_CODE (op0) == AND
3351 && (rtx_equal_p (XEXP (op0, 0), op1)
3352 || rtx_equal_p (XEXP (op0, 1), op1))
3353 && ! side_effects_p (XEXP (op0, 0))
3354 && ! side_effects_p (XEXP (op0, 1)))
3355 return op1;
3357 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3358 mode size to (rotate A CX). */
3360 if (GET_CODE (op1) == ASHIFT
3361 || GET_CODE (op1) == SUBREG)
3363 opleft = op1;
3364 opright = op0;
3366 else
3368 opright = op1;
3369 opleft = op0;
3372 if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3373 && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3374 && CONST_INT_P (XEXP (opleft, 1))
3375 && CONST_INT_P (XEXP (opright, 1))
3376 && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3377 == GET_MODE_UNIT_PRECISION (mode)))
3378 return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3380 /* Same, but for ashift that has been "simplified" to a wider mode
3381 by simplify_shift_const. */
3383 if (GET_CODE (opleft) == SUBREG
3384 && is_a <scalar_int_mode> (mode, &int_mode)
3385 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3386 &inner_mode)
3387 && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3388 && GET_CODE (opright) == LSHIFTRT
3389 && GET_CODE (XEXP (opright, 0)) == SUBREG
3390 && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3391 && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3392 && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3393 SUBREG_REG (XEXP (opright, 0)))
3394 && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3395 && CONST_INT_P (XEXP (opright, 1))
3396 && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3397 + INTVAL (XEXP (opright, 1))
3398 == GET_MODE_PRECISION (int_mode)))
3399 return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3400 XEXP (SUBREG_REG (opleft), 1));
3402 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3403 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3404 the PLUS does not affect any of the bits in OP1: then we can do
3405 the IOR as a PLUS and we can associate. This is valid if OP1
3406 can be safely shifted left C bits. */
3407 if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3408 && GET_CODE (XEXP (op0, 0)) == PLUS
3409 && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3410 && CONST_INT_P (XEXP (op0, 1))
3411 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3413 int count = INTVAL (XEXP (op0, 1));
3414 HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3416 if (mask >> count == INTVAL (trueop1)
3417 && trunc_int_for_mode (mask, mode) == mask
3418 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3419 return simplify_gen_binary (ASHIFTRT, mode,
3420 plus_constant (mode, XEXP (op0, 0),
3421 mask),
3422 XEXP (op0, 1));
3425 /* The following happens with bitfield merging.
3426 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3427 if (GET_CODE (op0) == AND
3428 && GET_CODE (op1) == AND
3429 && CONST_INT_P (XEXP (op0, 1))
3430 && CONST_INT_P (XEXP (op1, 1))
3431 && (INTVAL (XEXP (op0, 1))
3432 == ~INTVAL (XEXP (op1, 1))))
3434 /* The IOR may be on both sides. */
3435 rtx top0 = NULL_RTX, top1 = NULL_RTX;
3436 if (GET_CODE (XEXP (op1, 0)) == IOR)
3437 top0 = op0, top1 = op1;
3438 else if (GET_CODE (XEXP (op0, 0)) == IOR)
3439 top0 = op1, top1 = op0;
3440 if (top0 && top1)
3442 /* X may be on either side of the inner IOR. */
3443 rtx tem = NULL_RTX;
3444 if (rtx_equal_p (XEXP (top0, 0),
3445 XEXP (XEXP (top1, 0), 0)))
3446 tem = XEXP (XEXP (top1, 0), 1);
3447 else if (rtx_equal_p (XEXP (top0, 0),
3448 XEXP (XEXP (top1, 0), 1)))
3449 tem = XEXP (XEXP (top1, 0), 0);
3450 if (tem)
3451 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3452 simplify_gen_binary
3453 (AND, mode, tem, XEXP (top1, 1)));
3457 /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3458 if (GET_CODE (op0) == GET_CODE (op1)
3459 && (GET_CODE (op0) == AND
3460 || GET_CODE (op0) == IOR
3461 || GET_CODE (op0) == LSHIFTRT
3462 || GET_CODE (op0) == ASHIFTRT
3463 || GET_CODE (op0) == ASHIFT
3464 || GET_CODE (op0) == ROTATE
3465 || GET_CODE (op0) == ROTATERT))
3467 tem = simplify_distributive_operation (code, mode, op0, op1);
3468 if (tem)
3469 return tem;
3472 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3473 if (tem)
3474 return tem;
3476 tem = simplify_associative_operation (code, mode, op0, op1);
3477 if (tem)
3478 return tem;
3480 tem = simplify_logical_relational_operation (code, mode, op0, op1);
3481 if (tem)
3482 return tem;
3483 break;
3485 case XOR:
3486 if (trueop1 == CONST0_RTX (mode))
3487 return op0;
3488 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3489 return simplify_gen_unary (NOT, mode, op0, mode);
3490 if (rtx_equal_p (trueop0, trueop1)
3491 && ! side_effects_p (op0)
3492 && GET_MODE_CLASS (mode) != MODE_CC)
3493 return CONST0_RTX (mode);
3495 /* Canonicalize XOR of the most significant bit to PLUS. */
3496 if (CONST_SCALAR_INT_P (op1)
3497 && mode_signbit_p (mode, op1))
3498 return simplify_gen_binary (PLUS, mode, op0, op1);
3499 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3500 if (CONST_SCALAR_INT_P (op1)
3501 && GET_CODE (op0) == PLUS
3502 && CONST_SCALAR_INT_P (XEXP (op0, 1))
3503 && mode_signbit_p (mode, XEXP (op0, 1)))
3504 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3505 simplify_gen_binary (XOR, mode, op1,
3506 XEXP (op0, 1)));
3508 /* If we are XORing two things that have no bits in common,
3509 convert them into an IOR. This helps to detect rotation encoded
3510 using those methods and possibly other simplifications. */
3512 if (HWI_COMPUTABLE_MODE_P (mode)
3513 && (nonzero_bits (op0, mode)
3514 & nonzero_bits (op1, mode)) == 0)
3515 return (simplify_gen_binary (IOR, mode, op0, op1));
3517 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3518 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3519 (NOT y). */
3521 int num_negated = 0;
3523 if (GET_CODE (op0) == NOT)
3524 num_negated++, op0 = XEXP (op0, 0);
3525 if (GET_CODE (op1) == NOT)
3526 num_negated++, op1 = XEXP (op1, 0);
3528 if (num_negated == 2)
3529 return simplify_gen_binary (XOR, mode, op0, op1);
3530 else if (num_negated == 1)
3531 return simplify_gen_unary (NOT, mode,
3532 simplify_gen_binary (XOR, mode, op0, op1),
3533 mode);
3536 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3537 correspond to a machine insn or result in further simplifications
3538 if B is a constant. */
3540 if (GET_CODE (op0) == AND
3541 && rtx_equal_p (XEXP (op0, 1), op1)
3542 && ! side_effects_p (op1))
3543 return simplify_gen_binary (AND, mode,
3544 simplify_gen_unary (NOT, mode,
3545 XEXP (op0, 0), mode),
3546 op1);
3548 else if (GET_CODE (op0) == AND
3549 && rtx_equal_p (XEXP (op0, 0), op1)
3550 && ! side_effects_p (op1))
3551 return simplify_gen_binary (AND, mode,
3552 simplify_gen_unary (NOT, mode,
3553 XEXP (op0, 1), mode),
3554 op1);
3556 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3557 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3558 out bits inverted twice and not set by C. Similarly, given
3559 (xor (and (xor A B) C) D), simplify without inverting C in
3560 the xor operand: (xor (and A C) (B&C)^D).
3562 else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3563 && GET_CODE (XEXP (op0, 0)) == XOR
3564 && CONST_INT_P (op1)
3565 && CONST_INT_P (XEXP (op0, 1))
3566 && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3568 enum rtx_code op = GET_CODE (op0);
3569 rtx a = XEXP (XEXP (op0, 0), 0);
3570 rtx b = XEXP (XEXP (op0, 0), 1);
3571 rtx c = XEXP (op0, 1);
3572 rtx d = op1;
3573 HOST_WIDE_INT bval = INTVAL (b);
3574 HOST_WIDE_INT cval = INTVAL (c);
3575 HOST_WIDE_INT dval = INTVAL (d);
3576 HOST_WIDE_INT xcval;
3578 if (op == IOR)
3579 xcval = ~cval;
3580 else
3581 xcval = cval;
3583 return simplify_gen_binary (XOR, mode,
3584 simplify_gen_binary (op, mode, a, c),
3585 gen_int_mode ((bval & xcval) ^ dval,
3586 mode));
3589 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3590 we can transform like this:
3591 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3592 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3593 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3594 Attempt a few simplifications when B and C are both constants. */
3595 if (GET_CODE (op0) == AND
3596 && CONST_INT_P (op1)
3597 && CONST_INT_P (XEXP (op0, 1)))
3599 rtx a = XEXP (op0, 0);
3600 rtx b = XEXP (op0, 1);
3601 rtx c = op1;
3602 HOST_WIDE_INT bval = INTVAL (b);
3603 HOST_WIDE_INT cval = INTVAL (c);
3605 /* Instead of computing ~A&C, we compute its negated value,
3606 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3607 optimize for sure. If it does not simplify, we still try
3608 to compute ~A&C below, but since that always allocates
3609 RTL, we don't try that before committing to returning a
3610 simplified expression. */
3611 rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3612 GEN_INT (~cval));
3614 if ((~cval & bval) == 0)
3616 rtx na_c = NULL_RTX;
3617 if (n_na_c)
3618 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3619 else
3621 /* If ~A does not simplify, don't bother: we don't
3622 want to simplify 2 operations into 3, and if na_c
3623 were to simplify with na, n_na_c would have
3624 simplified as well. */
3625 rtx na = simplify_unary_operation (NOT, mode, a, mode);
3626 if (na)
3627 na_c = simplify_gen_binary (AND, mode, na, c);
3630 /* Try to simplify ~A&C | ~B&C. */
3631 if (na_c != NULL_RTX)
3632 return simplify_gen_binary (IOR, mode, na_c,
3633 gen_int_mode (~bval & cval, mode));
3635 else
3637 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3638 if (n_na_c == CONSTM1_RTX (mode))
3640 rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3641 gen_int_mode (~cval & bval,
3642 mode));
3643 return simplify_gen_binary (IOR, mode, a_nc_b,
3644 gen_int_mode (~bval & cval,
3645 mode));
3650 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3651 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3652 machines, and also has shorter instruction path length. */
3653 if (GET_CODE (op0) == AND
3654 && GET_CODE (XEXP (op0, 0)) == XOR
3655 && CONST_INT_P (XEXP (op0, 1))
3656 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3658 rtx a = trueop1;
3659 rtx b = XEXP (XEXP (op0, 0), 1);
3660 rtx c = XEXP (op0, 1);
3661 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3662 rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3663 rtx bc = simplify_gen_binary (AND, mode, b, c);
3664 return simplify_gen_binary (IOR, mode, a_nc, bc);
3666 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3667 else if (GET_CODE (op0) == AND
3668 && GET_CODE (XEXP (op0, 0)) == XOR
3669 && CONST_INT_P (XEXP (op0, 1))
3670 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3672 rtx a = XEXP (XEXP (op0, 0), 0);
3673 rtx b = trueop1;
3674 rtx c = XEXP (op0, 1);
3675 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3676 rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3677 rtx ac = simplify_gen_binary (AND, mode, a, c);
3678 return simplify_gen_binary (IOR, mode, ac, b_nc);
3681 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3682 comparison if STORE_FLAG_VALUE is 1. */
3683 if (STORE_FLAG_VALUE == 1
3684 && trueop1 == const1_rtx
3685 && COMPARISON_P (op0)
3686 && (reversed = reversed_comparison (op0, mode)))
3687 return reversed;
3689 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3690 is (lt foo (const_int 0)), so we can perform the above
3691 simplification if STORE_FLAG_VALUE is 1. */
3693 if (is_a <scalar_int_mode> (mode, &int_mode)
3694 && STORE_FLAG_VALUE == 1
3695 && trueop1 == const1_rtx
3696 && GET_CODE (op0) == LSHIFTRT
3697 && CONST_INT_P (XEXP (op0, 1))
3698 && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3699 return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3701 /* (xor (comparison foo bar) (const_int sign-bit))
3702 when STORE_FLAG_VALUE is the sign bit. */
3703 if (is_a <scalar_int_mode> (mode, &int_mode)
3704 && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3705 && trueop1 == const_true_rtx
3706 && COMPARISON_P (op0)
3707 && (reversed = reversed_comparison (op0, int_mode)))
3708 return reversed;
3710 /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3711 if (GET_CODE (op0) == GET_CODE (op1)
3712 && (GET_CODE (op0) == AND
3713 || GET_CODE (op0) == LSHIFTRT
3714 || GET_CODE (op0) == ASHIFTRT
3715 || GET_CODE (op0) == ASHIFT
3716 || GET_CODE (op0) == ROTATE
3717 || GET_CODE (op0) == ROTATERT))
3719 tem = simplify_distributive_operation (code, mode, op0, op1);
3720 if (tem)
3721 return tem;
3724 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3725 if (tem)
3726 return tem;
3728 tem = simplify_associative_operation (code, mode, op0, op1);
3729 if (tem)
3730 return tem;
3731 break;
3733 case AND:
3734 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3735 return trueop1;
3736 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3737 return op0;
3738 if (HWI_COMPUTABLE_MODE_P (mode))
3740 HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
3741 HOST_WIDE_INT nzop1;
3742 if (CONST_INT_P (trueop1))
3744 HOST_WIDE_INT val1 = INTVAL (trueop1);
3745 /* If we are turning off bits already known off in OP0, we need
3746 not do an AND. */
3747 if ((nzop0 & ~val1) == 0)
3748 return op0;
3750 nzop1 = nonzero_bits (trueop1, mode);
3751 /* If we are clearing all the nonzero bits, the result is zero. */
3752 if ((nzop1 & nzop0) == 0
3753 && !side_effects_p (op0) && !side_effects_p (op1))
3754 return CONST0_RTX (mode);
3756 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3757 && GET_MODE_CLASS (mode) != MODE_CC)
3758 return op0;
3759 /* A & (~A) -> 0 */
3760 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3761 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3762 && ! side_effects_p (op0)
3763 && GET_MODE_CLASS (mode) != MODE_CC)
3764 return CONST0_RTX (mode);
3766 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3767 there are no nonzero bits of C outside of X's mode. */
3768 if ((GET_CODE (op0) == SIGN_EXTEND
3769 || GET_CODE (op0) == ZERO_EXTEND)
3770 && CONST_INT_P (trueop1)
3771 && HWI_COMPUTABLE_MODE_P (mode)
3772 && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
3773 & UINTVAL (trueop1)) == 0)
3775 machine_mode imode = GET_MODE (XEXP (op0, 0));
3776 tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
3777 gen_int_mode (INTVAL (trueop1),
3778 imode));
3779 return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3782 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3783 we might be able to further simplify the AND with X and potentially
3784 remove the truncation altogether. */
3785 if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3787 rtx x = XEXP (op0, 0);
3788 machine_mode xmode = GET_MODE (x);
3789 tem = simplify_gen_binary (AND, xmode, x,
3790 gen_int_mode (INTVAL (trueop1), xmode));
3791 return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3794 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3795 if (GET_CODE (op0) == IOR
3796 && CONST_INT_P (trueop1)
3797 && CONST_INT_P (XEXP (op0, 1)))
3799 HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3800 return simplify_gen_binary (IOR, mode,
3801 simplify_gen_binary (AND, mode,
3802 XEXP (op0, 0), op1),
3803 gen_int_mode (tmp, mode));
3806 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3807 insn (and may simplify more). */
3808 if (GET_CODE (op0) == XOR
3809 && rtx_equal_p (XEXP (op0, 0), op1)
3810 && ! side_effects_p (op1))
3811 return simplify_gen_binary (AND, mode,
3812 simplify_gen_unary (NOT, mode,
3813 XEXP (op0, 1), mode),
3814 op1);
3816 if (GET_CODE (op0) == XOR
3817 && rtx_equal_p (XEXP (op0, 1), op1)
3818 && ! side_effects_p (op1))
3819 return simplify_gen_binary (AND, mode,
3820 simplify_gen_unary (NOT, mode,
3821 XEXP (op0, 0), mode),
3822 op1);
3824 /* Similarly for (~(A ^ B)) & A. */
3825 if (GET_CODE (op0) == NOT
3826 && GET_CODE (XEXP (op0, 0)) == XOR
3827 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3828 && ! side_effects_p (op1))
3829 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3831 if (GET_CODE (op0) == NOT
3832 && GET_CODE (XEXP (op0, 0)) == XOR
3833 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3834 && ! side_effects_p (op1))
3835 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3837 /* Convert (A | B) & A to A. */
3838 if (GET_CODE (op0) == IOR
3839 && (rtx_equal_p (XEXP (op0, 0), op1)
3840 || rtx_equal_p (XEXP (op0, 1), op1))
3841 && ! side_effects_p (XEXP (op0, 0))
3842 && ! side_effects_p (XEXP (op0, 1)))
3843 return op1;
3845 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3846 ((A & N) + B) & M -> (A + B) & M
3847 Similarly if (N & M) == 0,
3848 ((A | N) + B) & M -> (A + B) & M
3849 and for - instead of + and/or ^ instead of |.
3850 Also, if (N & M) == 0, then
3851 (A +- N) & M -> A & M. */
3852 if (CONST_INT_P (trueop1)
3853 && HWI_COMPUTABLE_MODE_P (mode)
3854 && ~UINTVAL (trueop1)
3855 && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3856 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3858 rtx pmop[2];
3859 int which;
3861 pmop[0] = XEXP (op0, 0);
3862 pmop[1] = XEXP (op0, 1);
3864 if (CONST_INT_P (pmop[1])
3865 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3866 return simplify_gen_binary (AND, mode, pmop[0], op1);
3868 for (which = 0; which < 2; which++)
3870 tem = pmop[which];
3871 switch (GET_CODE (tem))
3873 case AND:
3874 if (CONST_INT_P (XEXP (tem, 1))
3875 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3876 == UINTVAL (trueop1))
3877 pmop[which] = XEXP (tem, 0);
3878 break;
3879 case IOR:
3880 case XOR:
3881 if (CONST_INT_P (XEXP (tem, 1))
3882 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3883 pmop[which] = XEXP (tem, 0);
3884 break;
3885 default:
3886 break;
3890 if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3892 tem = simplify_gen_binary (GET_CODE (op0), mode,
3893 pmop[0], pmop[1]);
3894 return simplify_gen_binary (code, mode, tem, op1);
3898 /* (and X (ior (not X) Y) -> (and X Y) */
3899 if (GET_CODE (op1) == IOR
3900 && GET_CODE (XEXP (op1, 0)) == NOT
3901 && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3902 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3904 /* (and (ior (not X) Y) X) -> (and X Y) */
3905 if (GET_CODE (op0) == IOR
3906 && GET_CODE (XEXP (op0, 0)) == NOT
3907 && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3908 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3910 /* (and X (ior Y (not X)) -> (and X Y) */
3911 if (GET_CODE (op1) == IOR
3912 && GET_CODE (XEXP (op1, 1)) == NOT
3913 && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3914 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3916 /* (and (ior Y (not X)) X) -> (and X Y) */
3917 if (GET_CODE (op0) == IOR
3918 && GET_CODE (XEXP (op0, 1)) == NOT
3919 && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3920 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3922 /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
3923 if (GET_CODE (op0) == GET_CODE (op1)
3924 && (GET_CODE (op0) == AND
3925 || GET_CODE (op0) == IOR
3926 || GET_CODE (op0) == LSHIFTRT
3927 || GET_CODE (op0) == ASHIFTRT
3928 || GET_CODE (op0) == ASHIFT
3929 || GET_CODE (op0) == ROTATE
3930 || GET_CODE (op0) == ROTATERT))
3932 tem = simplify_distributive_operation (code, mode, op0, op1);
3933 if (tem)
3934 return tem;
3937 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3938 if (tem)
3939 return tem;
3941 tem = simplify_associative_operation (code, mode, op0, op1);
3942 if (tem)
3943 return tem;
3944 break;
3946 case UDIV:
3947 /* 0/x is 0 (or x&0 if x has side-effects). */
3948 if (trueop0 == CONST0_RTX (mode)
3949 && !cfun->can_throw_non_call_exceptions)
3951 if (side_effects_p (op1))
3952 return simplify_gen_binary (AND, mode, op1, trueop0);
3953 return trueop0;
3955 /* x/1 is x. */
3956 if (trueop1 == CONST1_RTX (mode))
3958 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3959 if (tem)
3960 return tem;
3962 /* Convert divide by power of two into shift. */
3963 if (CONST_INT_P (trueop1)
3964 && (val = exact_log2 (UINTVAL (trueop1))) > 0)
3965 return simplify_gen_binary (LSHIFTRT, mode, op0,
3966 gen_int_shift_amount (mode, val));
3967 break;
3969 case DIV:
3970 /* Handle floating point and integers separately. */
3971 if (SCALAR_FLOAT_MODE_P (mode))
3973 /* Maybe change 0.0 / x to 0.0. This transformation isn't
3974 safe for modes with NaNs, since 0.0 / 0.0 will then be
3975 NaN rather than 0.0. Nor is it safe for modes with signed
3976 zeros, since dividing 0 by a negative number gives -0.0 */
3977 if (trueop0 == CONST0_RTX (mode)
3978 && !HONOR_NANS (mode)
3979 && !HONOR_SIGNED_ZEROS (mode)
3980 && ! side_effects_p (op1))
3981 return op0;
3982 /* x/1.0 is x. */
3983 if (trueop1 == CONST1_RTX (mode)
3984 && !HONOR_SNANS (mode))
3985 return op0;
3987 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3988 && trueop1 != CONST0_RTX (mode))
3990 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3992 /* x/-1.0 is -x. */
3993 if (real_equal (d1, &dconstm1)
3994 && !HONOR_SNANS (mode))
3995 return simplify_gen_unary (NEG, mode, op0, mode);
3997 /* Change FP division by a constant into multiplication.
3998 Only do this with -freciprocal-math. */
3999 if (flag_reciprocal_math
4000 && !real_equal (d1, &dconst0))
4002 REAL_VALUE_TYPE d;
4003 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4004 tem = const_double_from_real_value (d, mode);
4005 return simplify_gen_binary (MULT, mode, op0, tem);
4009 else if (SCALAR_INT_MODE_P (mode))
4011 /* 0/x is 0 (or x&0 if x has side-effects). */
4012 if (trueop0 == CONST0_RTX (mode)
4013 && !cfun->can_throw_non_call_exceptions)
4015 if (side_effects_p (op1))
4016 return simplify_gen_binary (AND, mode, op1, trueop0);
4017 return trueop0;
4019 /* x/1 is x. */
4020 if (trueop1 == CONST1_RTX (mode))
4022 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4023 if (tem)
4024 return tem;
4026 /* x/-1 is -x. */
4027 if (trueop1 == constm1_rtx)
4029 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4030 if (x)
4031 return simplify_gen_unary (NEG, mode, x, mode);
4034 break;
4036 case UMOD:
4037 /* 0%x is 0 (or x&0 if x has side-effects). */
4038 if (trueop0 == CONST0_RTX (mode))
4040 if (side_effects_p (op1))
4041 return simplify_gen_binary (AND, mode, op1, trueop0);
4042 return trueop0;
4044 /* x%1 is 0 (of x&0 if x has side-effects). */
4045 if (trueop1 == CONST1_RTX (mode))
4047 if (side_effects_p (op0))
4048 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4049 return CONST0_RTX (mode);
4051 /* Implement modulus by power of two as AND. */
4052 if (CONST_INT_P (trueop1)
4053 && exact_log2 (UINTVAL (trueop1)) > 0)
4054 return simplify_gen_binary (AND, mode, op0,
4055 gen_int_mode (UINTVAL (trueop1) - 1,
4056 mode));
4057 break;
4059 case MOD:
4060 /* 0%x is 0 (or x&0 if x has side-effects). */
4061 if (trueop0 == CONST0_RTX (mode))
4063 if (side_effects_p (op1))
4064 return simplify_gen_binary (AND, mode, op1, trueop0);
4065 return trueop0;
4067 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4068 if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4070 if (side_effects_p (op0))
4071 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4072 return CONST0_RTX (mode);
4074 break;
4076 case ROTATERT:
4077 case ROTATE:
4078 if (trueop1 == CONST0_RTX (mode))
4079 return op0;
4080 /* Canonicalize rotates by constant amount. If op1 is bitsize / 2,
4081 prefer left rotation, if op1 is from bitsize / 2 + 1 to
4082 bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
4083 amount instead. */
4084 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4085 if (CONST_INT_P (trueop1)
4086 && IN_RANGE (INTVAL (trueop1),
4087 GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
4088 GET_MODE_UNIT_PRECISION (mode) - 1))
4090 int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4091 rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4092 return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4093 mode, op0, new_amount_rtx);
4095 #endif
4096 /* FALLTHRU */
4097 case ASHIFTRT:
4098 if (trueop1 == CONST0_RTX (mode))
4099 return op0;
4100 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4101 return op0;
4102 /* Rotating ~0 always results in ~0. */
4103 if (CONST_INT_P (trueop0)
4104 && HWI_COMPUTABLE_MODE_P (mode)
4105 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4106 && ! side_effects_p (op1))
4107 return op0;
4109 canonicalize_shift:
4110 /* Given:
4111 scalar modes M1, M2
4112 scalar constants c1, c2
4113 size (M2) > size (M1)
4114 c1 == size (M2) - size (M1)
4115 optimize:
4116 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4117 <low_part>)
4118 (const_int <c2>))
4120 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4121 <low_part>). */
4122 if ((code == ASHIFTRT || code == LSHIFTRT)
4123 && is_a <scalar_int_mode> (mode, &int_mode)
4124 && SUBREG_P (op0)
4125 && CONST_INT_P (op1)
4126 && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4127 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4128 &inner_mode)
4129 && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4130 && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4131 && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4132 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4133 && subreg_lowpart_p (op0))
4135 rtx tmp = gen_int_shift_amount
4136 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4138 /* Combine would usually zero out the value when combining two
4139 local shifts and the range becomes larger or equal to the mode.
4140 However since we fold away one of the shifts here combine won't
4141 see it so we should immediately zero the result if it's out of
4142 range. */
4143 if (code == LSHIFTRT
4144 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4145 tmp = const0_rtx;
4146 else
4147 tmp = simplify_gen_binary (code,
4148 inner_mode,
4149 XEXP (SUBREG_REG (op0), 0),
4150 tmp);
4152 return lowpart_subreg (int_mode, tmp, inner_mode);
4155 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4157 val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4158 if (val != INTVAL (op1))
4159 return simplify_gen_binary (code, mode, op0,
4160 gen_int_shift_amount (mode, val));
4162 break;
4164 case SS_ASHIFT:
4165 if (CONST_INT_P (trueop0)
4166 && HWI_COMPUTABLE_MODE_P (mode)
4167 && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4168 || mode_signbit_p (mode, trueop0))
4169 && ! side_effects_p (op1))
4170 return op0;
4171 goto simplify_ashift;
4173 case US_ASHIFT:
4174 if (CONST_INT_P (trueop0)
4175 && HWI_COMPUTABLE_MODE_P (mode)
4176 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4177 && ! side_effects_p (op1))
4178 return op0;
4179 /* FALLTHRU */
4181 case ASHIFT:
4182 simplify_ashift:
4183 if (trueop1 == CONST0_RTX (mode))
4184 return op0;
4185 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4186 return op0;
4187 if (mem_depth
4188 && code == ASHIFT
4189 && CONST_INT_P (trueop1)
4190 && is_a <scalar_int_mode> (mode, &int_mode)
4191 && IN_RANGE (UINTVAL (trueop1),
4192 1, GET_MODE_PRECISION (int_mode) - 1))
4194 auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4195 << UINTVAL (trueop1));
4196 rtx new_op1 = immed_wide_int_const (c, int_mode);
4197 return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4199 goto canonicalize_shift;
4201 case LSHIFTRT:
4202 if (trueop1 == CONST0_RTX (mode))
4203 return op0;
4204 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4205 return op0;
4206 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4207 if (GET_CODE (op0) == CLZ
4208 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4209 && CONST_INT_P (trueop1)
4210 && STORE_FLAG_VALUE == 1
4211 && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4213 unsigned HOST_WIDE_INT zero_val = 0;
4215 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4216 && zero_val == GET_MODE_PRECISION (inner_mode)
4217 && INTVAL (trueop1) == exact_log2 (zero_val))
4218 return simplify_gen_relational (EQ, mode, inner_mode,
4219 XEXP (op0, 0), const0_rtx);
4221 goto canonicalize_shift;
4223 case SMIN:
4224 if (HWI_COMPUTABLE_MODE_P (mode)
4225 && mode_signbit_p (mode, trueop1)
4226 && ! side_effects_p (op0))
4227 return op1;
4228 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4229 return op0;
4230 tem = simplify_associative_operation (code, mode, op0, op1);
4231 if (tem)
4232 return tem;
4233 break;
4235 case SMAX:
4236 if (HWI_COMPUTABLE_MODE_P (mode)
4237 && CONST_INT_P (trueop1)
4238 && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4239 && ! side_effects_p (op0))
4240 return op1;
4241 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4242 return op0;
4243 tem = simplify_associative_operation (code, mode, op0, op1);
4244 if (tem)
4245 return tem;
4246 break;
4248 case UMIN:
4249 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4250 return op1;
4251 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4252 return op0;
4253 tem = simplify_associative_operation (code, mode, op0, op1);
4254 if (tem)
4255 return tem;
4256 break;
4258 case UMAX:
4259 if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4260 return op1;
4261 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4262 return op0;
4263 tem = simplify_associative_operation (code, mode, op0, op1);
4264 if (tem)
4265 return tem;
4266 break;
4268 case SS_PLUS:
4269 case US_PLUS:
4270 case SS_MINUS:
4271 case US_MINUS:
4272 /* Simplify x +/- 0 to x, if possible. */
4273 if (trueop1 == CONST0_RTX (mode))
4274 return op0;
4275 return 0;
4277 case SS_MULT:
4278 case US_MULT:
4279 /* Simplify x * 0 to 0, if possible. */
4280 if (trueop1 == CONST0_RTX (mode)
4281 && !side_effects_p (op0))
4282 return op1;
4284 /* Simplify x * 1 to x, if possible. */
4285 if (trueop1 == CONST1_RTX (mode))
4286 return op0;
4287 return 0;
4289 case SMUL_HIGHPART:
4290 case UMUL_HIGHPART:
4291 /* Simplify x * 0 to 0, if possible. */
4292 if (trueop1 == CONST0_RTX (mode)
4293 && !side_effects_p (op0))
4294 return op1;
4295 return 0;
4297 case SS_DIV:
4298 case US_DIV:
4299 /* Simplify x / 1 to x, if possible. */
4300 if (trueop1 == CONST1_RTX (mode))
4301 return op0;
4302 return 0;
4304 case VEC_SERIES:
4305 if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4306 return gen_vec_duplicate (mode, op0);
4307 if (valid_for_const_vector_p (mode, op0)
4308 && valid_for_const_vector_p (mode, op1))
4309 return gen_const_vec_series (mode, op0, op1);
4310 return 0;
4312 case VEC_SELECT:
4313 if (!VECTOR_MODE_P (mode))
4315 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4316 gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4317 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4318 gcc_assert (XVECLEN (trueop1, 0) == 1);
4320 /* We can't reason about selections made at runtime. */
4321 if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4322 return 0;
4324 if (vec_duplicate_p (trueop0, &elt0))
4325 return elt0;
4327 if (GET_CODE (trueop0) == CONST_VECTOR)
4328 return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4329 (trueop1, 0, 0)));
4331 /* Extract a scalar element from a nested VEC_SELECT expression
4332 (with optional nested VEC_CONCAT expression). Some targets
4333 (i386) extract scalar element from a vector using chain of
4334 nested VEC_SELECT expressions. When input operand is a memory
4335 operand, this operation can be simplified to a simple scalar
4336 load from an offseted memory address. */
4337 int n_elts;
4338 if (GET_CODE (trueop0) == VEC_SELECT
4339 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4340 .is_constant (&n_elts)))
4342 rtx op0 = XEXP (trueop0, 0);
4343 rtx op1 = XEXP (trueop0, 1);
4345 int i = INTVAL (XVECEXP (trueop1, 0, 0));
4346 int elem;
4348 rtvec vec;
4349 rtx tmp_op, tmp;
4351 gcc_assert (GET_CODE (op1) == PARALLEL);
4352 gcc_assert (i < n_elts);
4354 /* Select element, pointed by nested selector. */
4355 elem = INTVAL (XVECEXP (op1, 0, i));
4357 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4358 if (GET_CODE (op0) == VEC_CONCAT)
4360 rtx op00 = XEXP (op0, 0);
4361 rtx op01 = XEXP (op0, 1);
4363 machine_mode mode00, mode01;
4364 int n_elts00, n_elts01;
4366 mode00 = GET_MODE (op00);
4367 mode01 = GET_MODE (op01);
4369 /* Find out the number of elements of each operand.
4370 Since the concatenated result has a constant number
4371 of elements, the operands must too. */
4372 n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4373 n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4375 gcc_assert (n_elts == n_elts00 + n_elts01);
4377 /* Select correct operand of VEC_CONCAT
4378 and adjust selector. */
4379 if (elem < n_elts01)
4380 tmp_op = op00;
4381 else
4383 tmp_op = op01;
4384 elem -= n_elts00;
4387 else
4388 tmp_op = op0;
4390 vec = rtvec_alloc (1);
4391 RTVEC_ELT (vec, 0) = GEN_INT (elem);
4393 tmp = gen_rtx_fmt_ee (code, mode,
4394 tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
4395 return tmp;
4398 else
4400 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4401 gcc_assert (GET_MODE_INNER (mode)
4402 == GET_MODE_INNER (GET_MODE (trueop0)));
4403 gcc_assert (GET_CODE (trueop1) == PARALLEL);
4405 if (vec_duplicate_p (trueop0, &elt0))
4406 /* It doesn't matter which elements are selected by trueop1,
4407 because they are all the same. */
4408 return gen_vec_duplicate (mode, elt0);
4410 if (GET_CODE (trueop0) == CONST_VECTOR)
4412 unsigned n_elts = XVECLEN (trueop1, 0);
4413 rtvec v = rtvec_alloc (n_elts);
4414 unsigned int i;
4416 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4417 for (i = 0; i < n_elts; i++)
4419 rtx x = XVECEXP (trueop1, 0, i);
4421 if (!CONST_INT_P (x))
4422 return 0;
4424 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
4425 INTVAL (x));
4428 return gen_rtx_CONST_VECTOR (mode, v);
4431 /* Recognize the identity. */
4432 if (GET_MODE (trueop0) == mode)
4434 bool maybe_ident = true;
4435 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4437 rtx j = XVECEXP (trueop1, 0, i);
4438 if (!CONST_INT_P (j) || INTVAL (j) != i)
4440 maybe_ident = false;
4441 break;
4444 if (maybe_ident)
4445 return trueop0;
4448 /* If we select a low-part subreg, return that. */
4449 if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
4451 rtx new_rtx = lowpart_subreg (mode, trueop0,
4452 GET_MODE (trueop0));
4453 if (new_rtx != NULL_RTX)
4454 return new_rtx;
4457 /* If we build {a,b} then permute it, build the result directly. */
4458 if (XVECLEN (trueop1, 0) == 2
4459 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4460 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4461 && GET_CODE (trueop0) == VEC_CONCAT
4462 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4463 && GET_MODE (XEXP (trueop0, 0)) == mode
4464 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4465 && GET_MODE (XEXP (trueop0, 1)) == mode)
4467 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4468 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4469 rtx subop0, subop1;
4471 gcc_assert (i0 < 4 && i1 < 4);
4472 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4473 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4475 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4478 if (XVECLEN (trueop1, 0) == 2
4479 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4480 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4481 && GET_CODE (trueop0) == VEC_CONCAT
4482 && GET_MODE (trueop0) == mode)
4484 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4485 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4486 rtx subop0, subop1;
4488 gcc_assert (i0 < 2 && i1 < 2);
4489 subop0 = XEXP (trueop0, i0);
4490 subop1 = XEXP (trueop0, i1);
4492 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4495 /* If we select one half of a vec_concat, return that. */
4496 int l0, l1;
4497 if (GET_CODE (trueop0) == VEC_CONCAT
4498 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4499 .is_constant (&l0))
4500 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4501 .is_constant (&l1))
4502 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4504 rtx subop0 = XEXP (trueop0, 0);
4505 rtx subop1 = XEXP (trueop0, 1);
4506 machine_mode mode0 = GET_MODE (subop0);
4507 machine_mode mode1 = GET_MODE (subop1);
4508 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4509 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4511 bool success = true;
4512 for (int i = 1; i < l0; ++i)
4514 rtx j = XVECEXP (trueop1, 0, i);
4515 if (!CONST_INT_P (j) || INTVAL (j) != i)
4517 success = false;
4518 break;
4521 if (success)
4522 return subop0;
4524 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4526 bool success = true;
4527 for (int i = 1; i < l1; ++i)
4529 rtx j = XVECEXP (trueop1, 0, i);
4530 if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4532 success = false;
4533 break;
4536 if (success)
4537 return subop1;
4541 /* Simplify vec_select of a subreg of X to just a vec_select of X
4542 when X has same component mode as vec_select. */
4543 unsigned HOST_WIDE_INT subreg_offset = 0;
4544 if (GET_CODE (trueop0) == SUBREG
4545 && GET_MODE_INNER (mode)
4546 == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
4547 && GET_MODE_NUNITS (mode).is_constant (&l1)
4548 && constant_multiple_p (subreg_memory_offset (trueop0),
4549 GET_MODE_UNIT_BITSIZE (mode),
4550 &subreg_offset))
4552 poly_uint64 nunits
4553 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
4554 bool success = true;
4555 for (int i = 0; i != l1; i++)
4557 rtx idx = XVECEXP (trueop1, 0, i);
4558 if (!CONST_INT_P (idx)
4559 || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
4561 success = false;
4562 break;
4566 if (success)
4568 rtx par = trueop1;
4569 if (subreg_offset)
4571 rtvec vec = rtvec_alloc (l1);
4572 for (int i = 0; i < l1; i++)
4573 RTVEC_ELT (vec, i)
4574 = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
4575 + subreg_offset);
4576 par = gen_rtx_PARALLEL (VOIDmode, vec);
4578 return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
4583 if (XVECLEN (trueop1, 0) == 1
4584 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4585 && GET_CODE (trueop0) == VEC_CONCAT)
4587 rtx vec = trueop0;
4588 offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4590 /* Try to find the element in the VEC_CONCAT. */
4591 while (GET_MODE (vec) != mode
4592 && GET_CODE (vec) == VEC_CONCAT)
4594 poly_int64 vec_size;
4596 if (CONST_INT_P (XEXP (vec, 0)))
4598 /* vec_concat of two const_ints doesn't make sense with
4599 respect to modes. */
4600 if (CONST_INT_P (XEXP (vec, 1)))
4601 return 0;
4603 vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4604 - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4606 else
4607 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4609 if (known_lt (offset, vec_size))
4610 vec = XEXP (vec, 0);
4611 else if (known_ge (offset, vec_size))
4613 offset -= vec_size;
4614 vec = XEXP (vec, 1);
4616 else
4617 break;
4618 vec = avoid_constant_pool_reference (vec);
4621 if (GET_MODE (vec) == mode)
4622 return vec;
4625 /* If we select elements in a vec_merge that all come from the same
4626 operand, select from that operand directly. */
4627 if (GET_CODE (op0) == VEC_MERGE)
4629 rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4630 if (CONST_INT_P (trueop02))
4632 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4633 bool all_operand0 = true;
4634 bool all_operand1 = true;
4635 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4637 rtx j = XVECEXP (trueop1, 0, i);
4638 if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4639 all_operand1 = false;
4640 else
4641 all_operand0 = false;
4643 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4644 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4645 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4646 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4650 /* If we have two nested selects that are inverses of each
4651 other, replace them with the source operand. */
4652 if (GET_CODE (trueop0) == VEC_SELECT
4653 && GET_MODE (XEXP (trueop0, 0)) == mode)
4655 rtx op0_subop1 = XEXP (trueop0, 1);
4656 gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4657 gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4659 /* Apply the outer ordering vector to the inner one. (The inner
4660 ordering vector is expressly permitted to be of a different
4661 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4662 then the two VEC_SELECTs cancel. */
4663 for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4665 rtx x = XVECEXP (trueop1, 0, i);
4666 if (!CONST_INT_P (x))
4667 return 0;
4668 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4669 if (!CONST_INT_P (y) || i != INTVAL (y))
4670 return 0;
4672 return XEXP (trueop0, 0);
4675 return 0;
4676 case VEC_CONCAT:
4678 machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4679 ? GET_MODE (trueop0)
4680 : GET_MODE_INNER (mode));
4681 machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4682 ? GET_MODE (trueop1)
4683 : GET_MODE_INNER (mode));
4685 gcc_assert (VECTOR_MODE_P (mode));
4686 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4687 + GET_MODE_SIZE (op1_mode),
4688 GET_MODE_SIZE (mode)));
4690 if (VECTOR_MODE_P (op0_mode))
4691 gcc_assert (GET_MODE_INNER (mode)
4692 == GET_MODE_INNER (op0_mode));
4693 else
4694 gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4696 if (VECTOR_MODE_P (op1_mode))
4697 gcc_assert (GET_MODE_INNER (mode)
4698 == GET_MODE_INNER (op1_mode));
4699 else
4700 gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4702 unsigned int n_elts, in_n_elts;
4703 if ((GET_CODE (trueop0) == CONST_VECTOR
4704 || CONST_SCALAR_INT_P (trueop0)
4705 || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4706 && (GET_CODE (trueop1) == CONST_VECTOR
4707 || CONST_SCALAR_INT_P (trueop1)
4708 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4709 && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4710 && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4712 rtvec v = rtvec_alloc (n_elts);
4713 unsigned int i;
4714 for (i = 0; i < n_elts; i++)
4716 if (i < in_n_elts)
4718 if (!VECTOR_MODE_P (op0_mode))
4719 RTVEC_ELT (v, i) = trueop0;
4720 else
4721 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4723 else
4725 if (!VECTOR_MODE_P (op1_mode))
4726 RTVEC_ELT (v, i) = trueop1;
4727 else
4728 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4729 i - in_n_elts);
4733 return gen_rtx_CONST_VECTOR (mode, v);
4736 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4737 Restrict the transformation to avoid generating a VEC_SELECT with a
4738 mode unrelated to its operand. */
4739 if (GET_CODE (trueop0) == VEC_SELECT
4740 && GET_CODE (trueop1) == VEC_SELECT
4741 && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4742 && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
4743 == GET_MODE_INNER(mode))
4745 rtx par0 = XEXP (trueop0, 1);
4746 rtx par1 = XEXP (trueop1, 1);
4747 int len0 = XVECLEN (par0, 0);
4748 int len1 = XVECLEN (par1, 0);
4749 rtvec vec = rtvec_alloc (len0 + len1);
4750 for (int i = 0; i < len0; i++)
4751 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4752 for (int i = 0; i < len1; i++)
4753 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4754 return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4755 gen_rtx_PARALLEL (VOIDmode, vec));
4758 return 0;
4760 default:
4761 gcc_unreachable ();
4764 if (mode == GET_MODE (op0)
4765 && mode == GET_MODE (op1)
4766 && vec_duplicate_p (op0, &elt0)
4767 && vec_duplicate_p (op1, &elt1))
4769 /* Try applying the operator to ELT and see if that simplifies.
4770 We can duplicate the result if so.
4772 The reason we don't use simplify_gen_binary is that it isn't
4773 necessarily a win to convert things like:
4775 (plus:V (vec_duplicate:V (reg:S R1))
4776 (vec_duplicate:V (reg:S R2)))
4780 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4782 The first might be done entirely in vector registers while the
4783 second might need a move between register files. */
4784 tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4785 elt0, elt1);
4786 if (tem)
4787 return gen_vec_duplicate (mode, tem);
4790 return 0;
4793 /* Return true if binary operation OP distributes over addition in operand
4794 OPNO, with the other operand being held constant. OPNO counts from 1. */
4796 static bool
4797 distributes_over_addition_p (rtx_code op, int opno)
4799 switch (op)
4801 case PLUS:
4802 case MINUS:
4803 case MULT:
4804 return true;
4806 case ASHIFT:
4807 return opno == 1;
4809 default:
4810 return false;
4815 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4816 rtx op0, rtx op1)
4818 if (VECTOR_MODE_P (mode)
4819 && code != VEC_CONCAT
4820 && GET_CODE (op0) == CONST_VECTOR
4821 && GET_CODE (op1) == CONST_VECTOR)
4823 bool step_ok_p;
4824 if (CONST_VECTOR_STEPPED_P (op0)
4825 && CONST_VECTOR_STEPPED_P (op1))
4826 /* We can operate directly on the encoding if:
4828 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4829 implies
4830 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4832 Addition and subtraction are the supported operators
4833 for which this is true. */
4834 step_ok_p = (code == PLUS || code == MINUS);
4835 else if (CONST_VECTOR_STEPPED_P (op0))
4836 /* We can operate directly on stepped encodings if:
4838 a3 - a2 == a2 - a1
4839 implies:
4840 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4842 which is true if (x -> x op c) distributes over addition. */
4843 step_ok_p = distributes_over_addition_p (code, 1);
4844 else
4845 /* Similarly in reverse. */
4846 step_ok_p = distributes_over_addition_p (code, 2);
4847 rtx_vector_builder builder;
4848 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4849 return 0;
4851 unsigned int count = builder.encoded_nelts ();
4852 for (unsigned int i = 0; i < count; i++)
4854 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4855 CONST_VECTOR_ELT (op0, i),
4856 CONST_VECTOR_ELT (op1, i));
4857 if (!x || !valid_for_const_vector_p (mode, x))
4858 return 0;
4859 builder.quick_push (x);
4861 return builder.build ();
4864 if (VECTOR_MODE_P (mode)
4865 && code == VEC_CONCAT
4866 && (CONST_SCALAR_INT_P (op0)
4867 || CONST_FIXED_P (op0)
4868 || CONST_DOUBLE_AS_FLOAT_P (op0))
4869 && (CONST_SCALAR_INT_P (op1)
4870 || CONST_DOUBLE_AS_FLOAT_P (op1)
4871 || CONST_FIXED_P (op1)))
4873 /* Both inputs have a constant number of elements, so the result
4874 must too. */
4875 unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4876 rtvec v = rtvec_alloc (n_elts);
4878 gcc_assert (n_elts >= 2);
4879 if (n_elts == 2)
4881 gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4882 gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4884 RTVEC_ELT (v, 0) = op0;
4885 RTVEC_ELT (v, 1) = op1;
4887 else
4889 unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4890 unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4891 unsigned i;
4893 gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4894 gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4895 gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4897 for (i = 0; i < op0_n_elts; ++i)
4898 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4899 for (i = 0; i < op1_n_elts; ++i)
4900 RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4903 return gen_rtx_CONST_VECTOR (mode, v);
4906 if (SCALAR_FLOAT_MODE_P (mode)
4907 && CONST_DOUBLE_AS_FLOAT_P (op0)
4908 && CONST_DOUBLE_AS_FLOAT_P (op1)
4909 && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4911 if (code == AND
4912 || code == IOR
4913 || code == XOR)
4915 long tmp0[4];
4916 long tmp1[4];
4917 REAL_VALUE_TYPE r;
4918 int i;
4920 real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4921 GET_MODE (op0));
4922 real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4923 GET_MODE (op1));
4924 for (i = 0; i < 4; i++)
4926 switch (code)
4928 case AND:
4929 tmp0[i] &= tmp1[i];
4930 break;
4931 case IOR:
4932 tmp0[i] |= tmp1[i];
4933 break;
4934 case XOR:
4935 tmp0[i] ^= tmp1[i];
4936 break;
4937 default:
4938 gcc_unreachable ();
4941 real_from_target (&r, tmp0, mode);
4942 return const_double_from_real_value (r, mode);
4944 else
4946 REAL_VALUE_TYPE f0, f1, value, result;
4947 const REAL_VALUE_TYPE *opr0, *opr1;
4948 bool inexact;
4950 opr0 = CONST_DOUBLE_REAL_VALUE (op0);
4951 opr1 = CONST_DOUBLE_REAL_VALUE (op1);
4953 if (HONOR_SNANS (mode)
4954 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
4955 || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
4956 return 0;
4958 real_convert (&f0, mode, opr0);
4959 real_convert (&f1, mode, opr1);
4961 if (code == DIV
4962 && real_equal (&f1, &dconst0)
4963 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
4964 return 0;
4966 if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4967 && flag_trapping_math
4968 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
4970 int s0 = REAL_VALUE_NEGATIVE (f0);
4971 int s1 = REAL_VALUE_NEGATIVE (f1);
4973 switch (code)
4975 case PLUS:
4976 /* Inf + -Inf = NaN plus exception. */
4977 if (s0 != s1)
4978 return 0;
4979 break;
4980 case MINUS:
4981 /* Inf - Inf = NaN plus exception. */
4982 if (s0 == s1)
4983 return 0;
4984 break;
4985 case DIV:
4986 /* Inf / Inf = NaN plus exception. */
4987 return 0;
4988 default:
4989 break;
4993 if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4994 && flag_trapping_math
4995 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
4996 || (REAL_VALUE_ISINF (f1)
4997 && real_equal (&f0, &dconst0))))
4998 /* Inf * 0 = NaN plus exception. */
4999 return 0;
5001 inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5002 &f0, &f1);
5003 real_convert (&result, mode, &value);
5005 /* Don't constant fold this floating point operation if
5006 the result has overflowed and flag_trapping_math. */
5008 if (flag_trapping_math
5009 && MODE_HAS_INFINITIES (mode)
5010 && REAL_VALUE_ISINF (result)
5011 && !REAL_VALUE_ISINF (f0)
5012 && !REAL_VALUE_ISINF (f1))
5013 /* Overflow plus exception. */
5014 return 0;
5016 /* Don't constant fold this floating point operation if the
5017 result may dependent upon the run-time rounding mode and
5018 flag_rounding_math is set, or if GCC's software emulation
5019 is unable to accurately represent the result. */
5021 if ((flag_rounding_math
5022 || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5023 && (inexact || !real_identical (&result, &value)))
5024 return NULL_RTX;
5026 return const_double_from_real_value (result, mode);
5030 /* We can fold some multi-word operations. */
5031 scalar_int_mode int_mode;
5032 if (is_a <scalar_int_mode> (mode, &int_mode)
5033 && CONST_SCALAR_INT_P (op0)
5034 && CONST_SCALAR_INT_P (op1)
5035 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5037 wide_int result;
5038 wi::overflow_type overflow;
5039 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5040 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5042 #if TARGET_SUPPORTS_WIDE_INT == 0
5043 /* This assert keeps the simplification from producing a result
5044 that cannot be represented in a CONST_DOUBLE but a lot of
5045 upstream callers expect that this function never fails to
5046 simplify something and so you if you added this to the test
5047 above the code would die later anyway. If this assert
5048 happens, you just need to make the port support wide int. */
5049 gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5050 #endif
5051 switch (code)
5053 case MINUS:
5054 result = wi::sub (pop0, pop1);
5055 break;
5057 case PLUS:
5058 result = wi::add (pop0, pop1);
5059 break;
5061 case MULT:
5062 result = wi::mul (pop0, pop1);
5063 break;
5065 case DIV:
5066 result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5067 if (overflow)
5068 return NULL_RTX;
5069 break;
5071 case MOD:
5072 result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5073 if (overflow)
5074 return NULL_RTX;
5075 break;
5077 case UDIV:
5078 result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5079 if (overflow)
5080 return NULL_RTX;
5081 break;
5083 case UMOD:
5084 result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5085 if (overflow)
5086 return NULL_RTX;
5087 break;
5089 case AND:
5090 result = wi::bit_and (pop0, pop1);
5091 break;
5093 case IOR:
5094 result = wi::bit_or (pop0, pop1);
5095 break;
5097 case XOR:
5098 result = wi::bit_xor (pop0, pop1);
5099 break;
5101 case SMIN:
5102 result = wi::smin (pop0, pop1);
5103 break;
5105 case SMAX:
5106 result = wi::smax (pop0, pop1);
5107 break;
5109 case UMIN:
5110 result = wi::umin (pop0, pop1);
5111 break;
5113 case UMAX:
5114 result = wi::umax (pop0, pop1);
5115 break;
5117 case LSHIFTRT:
5118 case ASHIFTRT:
5119 case ASHIFT:
5120 case SS_ASHIFT:
5121 case US_ASHIFT:
5123 /* The shift count might be in SImode while int_mode might
5124 be narrower. On IA-64 it is even DImode. If the shift
5125 count is too large and doesn't fit into int_mode, we'd
5126 ICE. So, if int_mode is narrower than word, use
5127 word_mode for the shift count. */
5128 if (GET_MODE (op1) == VOIDmode
5129 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5130 pop1 = rtx_mode_t (op1, word_mode);
5132 wide_int wop1 = pop1;
5133 if (SHIFT_COUNT_TRUNCATED)
5134 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
5135 else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
5136 return NULL_RTX;
5138 switch (code)
5140 case LSHIFTRT:
5141 result = wi::lrshift (pop0, wop1);
5142 break;
5144 case ASHIFTRT:
5145 result = wi::arshift (pop0, wop1);
5146 break;
5148 case ASHIFT:
5149 result = wi::lshift (pop0, wop1);
5150 break;
5152 case SS_ASHIFT:
5153 if (wi::leu_p (wop1, wi::clrsb (pop0)))
5154 result = wi::lshift (pop0, wop1);
5155 else if (wi::neg_p (pop0))
5156 result = wi::min_value (int_mode, SIGNED);
5157 else
5158 result = wi::max_value (int_mode, SIGNED);
5159 break;
5161 case US_ASHIFT:
5162 if (wi::eq_p (pop0, 0))
5163 result = pop0;
5164 else if (wi::leu_p (wop1, wi::clz (pop0)))
5165 result = wi::lshift (pop0, wop1);
5166 else
5167 result = wi::max_value (int_mode, UNSIGNED);
5168 break;
5170 default:
5171 gcc_unreachable ();
5173 break;
5175 case ROTATE:
5176 case ROTATERT:
5178 /* The rotate 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 if (wi::neg_p (pop1))
5188 return NULL_RTX;
5190 switch (code)
5192 case ROTATE:
5193 result = wi::lrotate (pop0, pop1);
5194 break;
5196 case ROTATERT:
5197 result = wi::rrotate (pop0, pop1);
5198 break;
5200 default:
5201 gcc_unreachable ();
5203 break;
5206 case SS_PLUS:
5207 result = wi::add (pop0, pop1, SIGNED, &overflow);
5208 clamp_signed_saturation:
5209 if (overflow == wi::OVF_OVERFLOW)
5210 result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
5211 else if (overflow == wi::OVF_UNDERFLOW)
5212 result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
5213 else if (overflow != wi::OVF_NONE)
5214 return NULL_RTX;
5215 break;
5217 case US_PLUS:
5218 result = wi::add (pop0, pop1, UNSIGNED, &overflow);
5219 clamp_unsigned_saturation:
5220 if (overflow != wi::OVF_NONE)
5221 result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5222 break;
5224 case SS_MINUS:
5225 result = wi::sub (pop0, pop1, SIGNED, &overflow);
5226 goto clamp_signed_saturation;
5228 case US_MINUS:
5229 result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
5230 if (overflow != wi::OVF_NONE)
5231 result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5232 break;
5234 case SS_MULT:
5235 result = wi::mul (pop0, pop1, SIGNED, &overflow);
5236 goto clamp_signed_saturation;
5238 case US_MULT:
5239 result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
5240 goto clamp_unsigned_saturation;
5242 case SMUL_HIGHPART:
5243 result = wi::mul_high (pop0, pop1, SIGNED);
5244 break;
5246 case UMUL_HIGHPART:
5247 result = wi::mul_high (pop0, pop1, UNSIGNED);
5248 break;
5250 default:
5251 return NULL_RTX;
5253 return immed_wide_int_const (result, int_mode);
5256 /* Handle polynomial integers. */
5257 if (NUM_POLY_INT_COEFFS > 1
5258 && is_a <scalar_int_mode> (mode, &int_mode)
5259 && poly_int_rtx_p (op0)
5260 && poly_int_rtx_p (op1))
5262 poly_wide_int result;
5263 switch (code)
5265 case PLUS:
5266 result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
5267 break;
5269 case MINUS:
5270 result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
5271 break;
5273 case MULT:
5274 if (CONST_SCALAR_INT_P (op1))
5275 result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
5276 else
5277 return NULL_RTX;
5278 break;
5280 case ASHIFT:
5281 if (CONST_SCALAR_INT_P (op1))
5283 wide_int shift
5284 = rtx_mode_t (op1,
5285 GET_MODE (op1) == VOIDmode
5286 && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
5287 ? word_mode : mode);
5288 if (SHIFT_COUNT_TRUNCATED)
5289 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
5290 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
5291 return NULL_RTX;
5292 result = wi::to_poly_wide (op0, mode) << shift;
5294 else
5295 return NULL_RTX;
5296 break;
5298 case IOR:
5299 if (!CONST_SCALAR_INT_P (op1)
5300 || !can_ior_p (wi::to_poly_wide (op0, mode),
5301 rtx_mode_t (op1, mode), &result))
5302 return NULL_RTX;
5303 break;
5305 default:
5306 return NULL_RTX;
5308 return immed_wide_int_const (result, int_mode);
5311 return NULL_RTX;
5316 /* Return a positive integer if X should sort after Y. The value
5317 returned is 1 if and only if X and Y are both regs. */
5319 static int
5320 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
5322 int result;
5324 result = (commutative_operand_precedence (y)
5325 - commutative_operand_precedence (x));
5326 if (result)
5327 return result + result;
5329 /* Group together equal REGs to do more simplification. */
5330 if (REG_P (x) && REG_P (y))
5331 return REGNO (x) > REGNO (y);
5333 return 0;
5336 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5337 operands may be another PLUS or MINUS.
5339 Rather than test for specific case, we do this by a brute-force method
5340 and do all possible simplifications until no more changes occur. Then
5341 we rebuild the operation.
5343 May return NULL_RTX when no changes were made. */
5346 simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
5347 rtx op0, rtx op1)
5349 struct simplify_plus_minus_op_data
5351 rtx op;
5352 short neg;
5353 } ops[16];
5354 rtx result, tem;
5355 int n_ops = 2;
5356 int changed, n_constants, canonicalized = 0;
5357 int i, j;
5359 memset (ops, 0, sizeof ops);
5361 /* Set up the two operands and then expand them until nothing has been
5362 changed. If we run out of room in our array, give up; this should
5363 almost never happen. */
5365 ops[0].op = op0;
5366 ops[0].neg = 0;
5367 ops[1].op = op1;
5368 ops[1].neg = (code == MINUS);
5372 changed = 0;
5373 n_constants = 0;
5375 for (i = 0; i < n_ops; i++)
5377 rtx this_op = ops[i].op;
5378 int this_neg = ops[i].neg;
5379 enum rtx_code this_code = GET_CODE (this_op);
5381 switch (this_code)
5383 case PLUS:
5384 case MINUS:
5385 if (n_ops == ARRAY_SIZE (ops))
5386 return NULL_RTX;
5388 ops[n_ops].op = XEXP (this_op, 1);
5389 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
5390 n_ops++;
5392 ops[i].op = XEXP (this_op, 0);
5393 changed = 1;
5394 /* If this operand was negated then we will potentially
5395 canonicalize the expression. Similarly if we don't
5396 place the operands adjacent we're re-ordering the
5397 expression and thus might be performing a
5398 canonicalization. Ignore register re-ordering.
5399 ??? It might be better to shuffle the ops array here,
5400 but then (plus (plus (A, B), plus (C, D))) wouldn't
5401 be seen as non-canonical. */
5402 if (this_neg
5403 || (i != n_ops - 2
5404 && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
5405 canonicalized = 1;
5406 break;
5408 case NEG:
5409 ops[i].op = XEXP (this_op, 0);
5410 ops[i].neg = ! this_neg;
5411 changed = 1;
5412 canonicalized = 1;
5413 break;
5415 case CONST:
5416 if (n_ops != ARRAY_SIZE (ops)
5417 && GET_CODE (XEXP (this_op, 0)) == PLUS
5418 && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
5419 && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
5421 ops[i].op = XEXP (XEXP (this_op, 0), 0);
5422 ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
5423 ops[n_ops].neg = this_neg;
5424 n_ops++;
5425 changed = 1;
5426 canonicalized = 1;
5428 break;
5430 case NOT:
5431 /* ~a -> (-a - 1) */
5432 if (n_ops != ARRAY_SIZE (ops))
5434 ops[n_ops].op = CONSTM1_RTX (mode);
5435 ops[n_ops++].neg = this_neg;
5436 ops[i].op = XEXP (this_op, 0);
5437 ops[i].neg = !this_neg;
5438 changed = 1;
5439 canonicalized = 1;
5441 break;
5443 CASE_CONST_SCALAR_INT:
5444 case CONST_POLY_INT:
5445 n_constants++;
5446 if (this_neg)
5448 ops[i].op = neg_poly_int_rtx (mode, this_op);
5449 ops[i].neg = 0;
5450 changed = 1;
5451 canonicalized = 1;
5453 break;
5455 default:
5456 break;
5460 while (changed);
5462 if (n_constants > 1)
5463 canonicalized = 1;
5465 gcc_assert (n_ops >= 2);
5467 /* If we only have two operands, we can avoid the loops. */
5468 if (n_ops == 2)
5470 enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
5471 rtx lhs, rhs;
5473 /* Get the two operands. Be careful with the order, especially for
5474 the cases where code == MINUS. */
5475 if (ops[0].neg && ops[1].neg)
5477 lhs = gen_rtx_NEG (mode, ops[0].op);
5478 rhs = ops[1].op;
5480 else if (ops[0].neg)
5482 lhs = ops[1].op;
5483 rhs = ops[0].op;
5485 else
5487 lhs = ops[0].op;
5488 rhs = ops[1].op;
5491 return simplify_const_binary_operation (code, mode, lhs, rhs);
5494 /* Now simplify each pair of operands until nothing changes. */
5495 while (1)
5497 /* Insertion sort is good enough for a small array. */
5498 for (i = 1; i < n_ops; i++)
5500 struct simplify_plus_minus_op_data save;
5501 int cmp;
5503 j = i - 1;
5504 cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
5505 if (cmp <= 0)
5506 continue;
5507 /* Just swapping registers doesn't count as canonicalization. */
5508 if (cmp != 1)
5509 canonicalized = 1;
5511 save = ops[i];
5513 ops[j + 1] = ops[j];
5514 while (j--
5515 && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
5516 ops[j + 1] = save;
5519 changed = 0;
5520 for (i = n_ops - 1; i > 0; i--)
5521 for (j = i - 1; j >= 0; j--)
5523 rtx lhs = ops[j].op, rhs = ops[i].op;
5524 int lneg = ops[j].neg, rneg = ops[i].neg;
5526 if (lhs != 0 && rhs != 0)
5528 enum rtx_code ncode = PLUS;
5530 if (lneg != rneg)
5532 ncode = MINUS;
5533 if (lneg)
5534 std::swap (lhs, rhs);
5536 else if (swap_commutative_operands_p (lhs, rhs))
5537 std::swap (lhs, rhs);
5539 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
5540 && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
5542 rtx tem_lhs, tem_rhs;
5544 tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
5545 tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
5546 tem = simplify_binary_operation (ncode, mode, tem_lhs,
5547 tem_rhs);
5549 if (tem && !CONSTANT_P (tem))
5550 tem = gen_rtx_CONST (GET_MODE (tem), tem);
5552 else
5553 tem = simplify_binary_operation (ncode, mode, lhs, rhs);
5555 if (tem)
5557 /* Reject "simplifications" that just wrap the two
5558 arguments in a CONST. Failure to do so can result
5559 in infinite recursion with simplify_binary_operation
5560 when it calls us to simplify CONST operations.
5561 Also, if we find such a simplification, don't try
5562 any more combinations with this rhs: We must have
5563 something like symbol+offset, ie. one of the
5564 trivial CONST expressions we handle later. */
5565 if (GET_CODE (tem) == CONST
5566 && GET_CODE (XEXP (tem, 0)) == ncode
5567 && XEXP (XEXP (tem, 0), 0) == lhs
5568 && XEXP (XEXP (tem, 0), 1) == rhs)
5569 break;
5570 lneg &= rneg;
5571 if (GET_CODE (tem) == NEG)
5572 tem = XEXP (tem, 0), lneg = !lneg;
5573 if (poly_int_rtx_p (tem) && lneg)
5574 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
5576 ops[i].op = tem;
5577 ops[i].neg = lneg;
5578 ops[j].op = NULL_RTX;
5579 changed = 1;
5580 canonicalized = 1;
5585 if (!changed)
5586 break;
5588 /* Pack all the operands to the lower-numbered entries. */
5589 for (i = 0, j = 0; j < n_ops; j++)
5590 if (ops[j].op)
5592 ops[i] = ops[j];
5593 i++;
5595 n_ops = i;
5598 /* If nothing changed, check that rematerialization of rtl instructions
5599 is still required. */
5600 if (!canonicalized)
5602 /* Perform rematerialization if only all operands are registers and
5603 all operations are PLUS. */
5604 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5605 around rs6000 and how it uses the CA register. See PR67145. */
5606 for (i = 0; i < n_ops; i++)
5607 if (ops[i].neg
5608 || !REG_P (ops[i].op)
5609 || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5610 && fixed_regs[REGNO (ops[i].op)]
5611 && !global_regs[REGNO (ops[i].op)]
5612 && ops[i].op != frame_pointer_rtx
5613 && ops[i].op != arg_pointer_rtx
5614 && ops[i].op != stack_pointer_rtx))
5615 return NULL_RTX;
5616 goto gen_result;
5619 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5620 if (n_ops == 2
5621 && CONST_INT_P (ops[1].op)
5622 && CONSTANT_P (ops[0].op)
5623 && ops[0].neg)
5624 return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5626 /* We suppressed creation of trivial CONST expressions in the
5627 combination loop to avoid recursion. Create one manually now.
5628 The combination loop should have ensured that there is exactly
5629 one CONST_INT, and the sort will have ensured that it is last
5630 in the array and that any other constant will be next-to-last. */
5632 if (n_ops > 1
5633 && poly_int_rtx_p (ops[n_ops - 1].op)
5634 && CONSTANT_P (ops[n_ops - 2].op))
5636 rtx value = ops[n_ops - 1].op;
5637 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5638 value = neg_poly_int_rtx (mode, value);
5639 if (CONST_INT_P (value))
5641 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5642 INTVAL (value));
5643 n_ops--;
5647 /* Put a non-negated operand first, if possible. */
5649 for (i = 0; i < n_ops && ops[i].neg; i++)
5650 continue;
5651 if (i == n_ops)
5652 ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5653 else if (i != 0)
5655 tem = ops[0].op;
5656 ops[0] = ops[i];
5657 ops[i].op = tem;
5658 ops[i].neg = 1;
5661 /* Now make the result by performing the requested operations. */
5662 gen_result:
5663 result = ops[0].op;
5664 for (i = 1; i < n_ops; i++)
5665 result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5666 mode, result, ops[i].op);
5668 return result;
5671 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5672 static bool
5673 plus_minus_operand_p (const_rtx x)
5675 return GET_CODE (x) == PLUS
5676 || GET_CODE (x) == MINUS
5677 || (GET_CODE (x) == CONST
5678 && GET_CODE (XEXP (x, 0)) == PLUS
5679 && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5680 && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5683 /* Like simplify_binary_operation except used for relational operators.
5684 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5685 not also be VOIDmode.
5687 CMP_MODE specifies in which mode the comparison is done in, so it is
5688 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5689 the operands or, if both are VOIDmode, the operands are compared in
5690 "infinite precision". */
5692 simplify_context::simplify_relational_operation (rtx_code code,
5693 machine_mode mode,
5694 machine_mode cmp_mode,
5695 rtx op0, rtx op1)
5697 rtx tem, trueop0, trueop1;
5699 if (cmp_mode == VOIDmode)
5700 cmp_mode = GET_MODE (op0);
5701 if (cmp_mode == VOIDmode)
5702 cmp_mode = GET_MODE (op1);
5704 tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5705 if (tem)
5706 return relational_result (mode, cmp_mode, tem);
5708 /* For the following tests, ensure const0_rtx is op1. */
5709 if (swap_commutative_operands_p (op0, op1)
5710 || (op0 == const0_rtx && op1 != const0_rtx))
5711 std::swap (op0, op1), code = swap_condition (code);
5713 /* If op0 is a compare, extract the comparison arguments from it. */
5714 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5715 return simplify_gen_relational (code, mode, VOIDmode,
5716 XEXP (op0, 0), XEXP (op0, 1));
5718 if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
5719 return NULL_RTX;
5721 trueop0 = avoid_constant_pool_reference (op0);
5722 trueop1 = avoid_constant_pool_reference (op1);
5723 return simplify_relational_operation_1 (code, mode, cmp_mode,
5724 trueop0, trueop1);
5727 /* This part of simplify_relational_operation is only used when CMP_MODE
5728 is not in class MODE_CC (i.e. it is a real comparison).
5730 MODE is the mode of the result, while CMP_MODE specifies in which
5731 mode the comparison is done in, so it is the mode of the operands. */
5734 simplify_context::simplify_relational_operation_1 (rtx_code code,
5735 machine_mode mode,
5736 machine_mode cmp_mode,
5737 rtx op0, rtx op1)
5739 enum rtx_code op0code = GET_CODE (op0);
5741 if (op1 == const0_rtx && COMPARISON_P (op0))
5743 /* If op0 is a comparison, extract the comparison arguments
5744 from it. */
5745 if (code == NE)
5747 if (GET_MODE (op0) == mode)
5748 return simplify_rtx (op0);
5749 else
5750 return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5751 XEXP (op0, 0), XEXP (op0, 1));
5753 else if (code == EQ)
5755 enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5756 if (new_code != UNKNOWN)
5757 return simplify_gen_relational (new_code, mode, VOIDmode,
5758 XEXP (op0, 0), XEXP (op0, 1));
5762 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5763 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5764 if ((code == LTU || code == GEU)
5765 && GET_CODE (op0) == PLUS
5766 && CONST_INT_P (XEXP (op0, 1))
5767 && (rtx_equal_p (op1, XEXP (op0, 0))
5768 || rtx_equal_p (op1, XEXP (op0, 1)))
5769 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5770 && XEXP (op0, 1) != const0_rtx)
5772 rtx new_cmp
5773 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5774 return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5775 cmp_mode, XEXP (op0, 0), new_cmp);
5778 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5779 transformed into (LTU a -C). */
5780 if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5781 && CONST_INT_P (XEXP (op0, 1))
5782 && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5783 && XEXP (op0, 1) != const0_rtx)
5785 rtx new_cmp
5786 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5787 return simplify_gen_relational (LTU, mode, cmp_mode,
5788 XEXP (op0, 0), new_cmp);
5791 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5792 if ((code == LTU || code == GEU)
5793 && GET_CODE (op0) == PLUS
5794 && rtx_equal_p (op1, XEXP (op0, 1))
5795 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5796 && !rtx_equal_p (op1, XEXP (op0, 0)))
5797 return simplify_gen_relational (code, mode, cmp_mode, op0,
5798 copy_rtx (XEXP (op0, 0)));
5800 if (op1 == const0_rtx)
5802 /* Canonicalize (GTU x 0) as (NE x 0). */
5803 if (code == GTU)
5804 return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5805 /* Canonicalize (LEU x 0) as (EQ x 0). */
5806 if (code == LEU)
5807 return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5809 else if (op1 == const1_rtx)
5811 switch (code)
5813 case GE:
5814 /* Canonicalize (GE x 1) as (GT x 0). */
5815 return simplify_gen_relational (GT, mode, cmp_mode,
5816 op0, const0_rtx);
5817 case GEU:
5818 /* Canonicalize (GEU x 1) as (NE x 0). */
5819 return simplify_gen_relational (NE, mode, cmp_mode,
5820 op0, const0_rtx);
5821 case LT:
5822 /* Canonicalize (LT x 1) as (LE x 0). */
5823 return simplify_gen_relational (LE, mode, cmp_mode,
5824 op0, const0_rtx);
5825 case LTU:
5826 /* Canonicalize (LTU x 1) as (EQ x 0). */
5827 return simplify_gen_relational (EQ, mode, cmp_mode,
5828 op0, const0_rtx);
5829 default:
5830 break;
5833 else if (op1 == constm1_rtx)
5835 /* Canonicalize (LE x -1) as (LT x 0). */
5836 if (code == LE)
5837 return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5838 /* Canonicalize (GT x -1) as (GE x 0). */
5839 if (code == GT)
5840 return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5843 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5844 if ((code == EQ || code == NE)
5845 && (op0code == PLUS || op0code == MINUS)
5846 && CONSTANT_P (op1)
5847 && CONSTANT_P (XEXP (op0, 1))
5848 && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5850 rtx x = XEXP (op0, 0);
5851 rtx c = XEXP (op0, 1);
5852 enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5853 rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5855 /* Detect an infinite recursive condition, where we oscillate at this
5856 simplification case between:
5857 A + B == C <---> C - B == A,
5858 where A, B, and C are all constants with non-simplifiable expressions,
5859 usually SYMBOL_REFs. */
5860 if (GET_CODE (tem) == invcode
5861 && CONSTANT_P (x)
5862 && rtx_equal_p (c, XEXP (tem, 1)))
5863 return NULL_RTX;
5865 return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5868 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5869 the same as (zero_extract:SI FOO (const_int 1) BAR). */
5870 scalar_int_mode int_mode, int_cmp_mode;
5871 if (code == NE
5872 && op1 == const0_rtx
5873 && is_int_mode (mode, &int_mode)
5874 && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5875 /* ??? Work-around BImode bugs in the ia64 backend. */
5876 && int_mode != BImode
5877 && int_cmp_mode != BImode
5878 && nonzero_bits (op0, int_cmp_mode) == 1
5879 && STORE_FLAG_VALUE == 1)
5880 return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5881 ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5882 : lowpart_subreg (int_mode, op0, int_cmp_mode);
5884 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
5885 if ((code == EQ || code == NE)
5886 && op1 == const0_rtx
5887 && op0code == XOR)
5888 return simplify_gen_relational (code, mode, cmp_mode,
5889 XEXP (op0, 0), XEXP (op0, 1));
5891 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
5892 if ((code == EQ || code == NE)
5893 && op0code == XOR
5894 && rtx_equal_p (XEXP (op0, 0), op1)
5895 && !side_effects_p (XEXP (op0, 0)))
5896 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5897 CONST0_RTX (mode));
5899 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
5900 if ((code == EQ || code == NE)
5901 && op0code == XOR
5902 && rtx_equal_p (XEXP (op0, 1), op1)
5903 && !side_effects_p (XEXP (op0, 1)))
5904 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5905 CONST0_RTX (mode));
5907 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
5908 if ((code == EQ || code == NE)
5909 && op0code == XOR
5910 && CONST_SCALAR_INT_P (op1)
5911 && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5912 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5913 simplify_gen_binary (XOR, cmp_mode,
5914 XEXP (op0, 1), op1));
5916 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5917 constant folding if x/y is a constant. */
5918 if ((code == EQ || code == NE)
5919 && (op0code == AND || op0code == IOR)
5920 && !side_effects_p (op1)
5921 && op1 != CONST0_RTX (cmp_mode))
5923 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5924 (eq/ne (and (not y) x) 0). */
5925 if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5926 || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5928 rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5929 cmp_mode);
5930 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5932 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5933 CONST0_RTX (cmp_mode));
5936 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5937 (eq/ne (and (not x) y) 0). */
5938 if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5939 || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5941 rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5942 cmp_mode);
5943 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
5945 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5946 CONST0_RTX (cmp_mode));
5950 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
5951 if ((code == EQ || code == NE)
5952 && GET_CODE (op0) == BSWAP
5953 && CONST_SCALAR_INT_P (op1))
5954 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5955 simplify_gen_unary (BSWAP, cmp_mode,
5956 op1, cmp_mode));
5958 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
5959 if ((code == EQ || code == NE)
5960 && GET_CODE (op0) == BSWAP
5961 && GET_CODE (op1) == BSWAP)
5962 return simplify_gen_relational (code, mode, cmp_mode,
5963 XEXP (op0, 0), XEXP (op1, 0));
5965 if (op0code == POPCOUNT && op1 == const0_rtx)
5966 switch (code)
5968 case EQ:
5969 case LE:
5970 case LEU:
5971 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
5972 return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
5973 XEXP (op0, 0), const0_rtx);
5975 case NE:
5976 case GT:
5977 case GTU:
5978 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
5979 return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
5980 XEXP (op0, 0), const0_rtx);
5982 default:
5983 break;
5986 return NULL_RTX;
5989 enum
5991 CMP_EQ = 1,
5992 CMP_LT = 2,
5993 CMP_GT = 4,
5994 CMP_LTU = 8,
5995 CMP_GTU = 16
5999 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6000 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6001 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6002 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6003 For floating-point comparisons, assume that the operands were ordered. */
6005 static rtx
6006 comparison_result (enum rtx_code code, int known_results)
6008 switch (code)
6010 case EQ:
6011 case UNEQ:
6012 return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
6013 case NE:
6014 case LTGT:
6015 return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
6017 case LT:
6018 case UNLT:
6019 return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
6020 case GE:
6021 case UNGE:
6022 return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
6024 case GT:
6025 case UNGT:
6026 return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
6027 case LE:
6028 case UNLE:
6029 return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
6031 case LTU:
6032 return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
6033 case GEU:
6034 return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
6036 case GTU:
6037 return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
6038 case LEU:
6039 return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
6041 case ORDERED:
6042 return const_true_rtx;
6043 case UNORDERED:
6044 return const0_rtx;
6045 default:
6046 gcc_unreachable ();
6050 /* Check if the given comparison (done in the given MODE) is actually
6051 a tautology or a contradiction. If the mode is VOIDmode, the
6052 comparison is done in "infinite precision". If no simplification
6053 is possible, this function returns zero. Otherwise, it returns
6054 either const_true_rtx or const0_rtx. */
6057 simplify_const_relational_operation (enum rtx_code code,
6058 machine_mode mode,
6059 rtx op0, rtx op1)
6061 rtx tem;
6062 rtx trueop0;
6063 rtx trueop1;
6065 gcc_assert (mode != VOIDmode
6066 || (GET_MODE (op0) == VOIDmode
6067 && GET_MODE (op1) == VOIDmode));
6069 /* If op0 is a compare, extract the comparison arguments from it. */
6070 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6072 op1 = XEXP (op0, 1);
6073 op0 = XEXP (op0, 0);
6075 if (GET_MODE (op0) != VOIDmode)
6076 mode = GET_MODE (op0);
6077 else if (GET_MODE (op1) != VOIDmode)
6078 mode = GET_MODE (op1);
6079 else
6080 return 0;
6083 /* We can't simplify MODE_CC values since we don't know what the
6084 actual comparison is. */
6085 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
6086 return 0;
6088 /* Make sure the constant is second. */
6089 if (swap_commutative_operands_p (op0, op1))
6091 std::swap (op0, op1);
6092 code = swap_condition (code);
6095 trueop0 = avoid_constant_pool_reference (op0);
6096 trueop1 = avoid_constant_pool_reference (op1);
6098 /* For integer comparisons of A and B maybe we can simplify A - B and can
6099 then simplify a comparison of that with zero. If A and B are both either
6100 a register or a CONST_INT, this can't help; testing for these cases will
6101 prevent infinite recursion here and speed things up.
6103 We can only do this for EQ and NE comparisons as otherwise we may
6104 lose or introduce overflow which we cannot disregard as undefined as
6105 we do not know the signedness of the operation on either the left or
6106 the right hand side of the comparison. */
6108 if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
6109 && (code == EQ || code == NE)
6110 && ! ((REG_P (op0) || CONST_INT_P (trueop0))
6111 && (REG_P (op1) || CONST_INT_P (trueop1)))
6112 && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
6113 /* We cannot do this if tem is a nonzero address. */
6114 && ! nonzero_address_p (tem))
6115 return simplify_const_relational_operation (signed_condition (code),
6116 mode, tem, const0_rtx);
6118 if (! HONOR_NANS (mode) && code == ORDERED)
6119 return const_true_rtx;
6121 if (! HONOR_NANS (mode) && code == UNORDERED)
6122 return const0_rtx;
6124 /* For modes without NaNs, if the two operands are equal, we know the
6125 result except if they have side-effects. Even with NaNs we know
6126 the result of unordered comparisons and, if signaling NaNs are
6127 irrelevant, also the result of LT/GT/LTGT. */
6128 if ((! HONOR_NANS (trueop0)
6129 || code == UNEQ || code == UNLE || code == UNGE
6130 || ((code == LT || code == GT || code == LTGT)
6131 && ! HONOR_SNANS (trueop0)))
6132 && rtx_equal_p (trueop0, trueop1)
6133 && ! side_effects_p (trueop0))
6134 return comparison_result (code, CMP_EQ);
6136 /* If the operands are floating-point constants, see if we can fold
6137 the result. */
6138 if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
6139 && CONST_DOUBLE_AS_FLOAT_P (trueop1)
6140 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
6142 const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
6143 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
6145 /* Comparisons are unordered iff at least one of the values is NaN. */
6146 if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
6147 switch (code)
6149 case UNEQ:
6150 case UNLT:
6151 case UNGT:
6152 case UNLE:
6153 case UNGE:
6154 case NE:
6155 case UNORDERED:
6156 return const_true_rtx;
6157 case EQ:
6158 case LT:
6159 case GT:
6160 case LE:
6161 case GE:
6162 case LTGT:
6163 case ORDERED:
6164 return const0_rtx;
6165 default:
6166 return 0;
6169 return comparison_result (code,
6170 (real_equal (d0, d1) ? CMP_EQ :
6171 real_less (d0, d1) ? CMP_LT : CMP_GT));
6174 /* Otherwise, see if the operands are both integers. */
6175 if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
6176 && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
6178 /* It would be nice if we really had a mode here. However, the
6179 largest int representable on the target is as good as
6180 infinite. */
6181 machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
6182 rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
6183 rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
6185 if (wi::eq_p (ptrueop0, ptrueop1))
6186 return comparison_result (code, CMP_EQ);
6187 else
6189 int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
6190 cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
6191 return comparison_result (code, cr);
6195 /* Optimize comparisons with upper and lower bounds. */
6196 scalar_int_mode int_mode;
6197 if (CONST_INT_P (trueop1)
6198 && is_a <scalar_int_mode> (mode, &int_mode)
6199 && HWI_COMPUTABLE_MODE_P (int_mode)
6200 && !side_effects_p (trueop0))
6202 int sign;
6203 unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
6204 HOST_WIDE_INT val = INTVAL (trueop1);
6205 HOST_WIDE_INT mmin, mmax;
6207 if (code == GEU
6208 || code == LEU
6209 || code == GTU
6210 || code == LTU)
6211 sign = 0;
6212 else
6213 sign = 1;
6215 /* Get a reduced range if the sign bit is zero. */
6216 if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
6218 mmin = 0;
6219 mmax = nonzero;
6221 else
6223 rtx mmin_rtx, mmax_rtx;
6224 get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
6226 mmin = INTVAL (mmin_rtx);
6227 mmax = INTVAL (mmax_rtx);
6228 if (sign)
6230 unsigned int sign_copies
6231 = num_sign_bit_copies (trueop0, int_mode);
6233 mmin >>= (sign_copies - 1);
6234 mmax >>= (sign_copies - 1);
6238 switch (code)
6240 /* x >= y is always true for y <= mmin, always false for y > mmax. */
6241 case GEU:
6242 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6243 return const_true_rtx;
6244 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6245 return const0_rtx;
6246 break;
6247 case GE:
6248 if (val <= mmin)
6249 return const_true_rtx;
6250 if (val > mmax)
6251 return const0_rtx;
6252 break;
6254 /* x <= y is always true for y >= mmax, always false for y < mmin. */
6255 case LEU:
6256 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6257 return const_true_rtx;
6258 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6259 return const0_rtx;
6260 break;
6261 case LE:
6262 if (val >= mmax)
6263 return const_true_rtx;
6264 if (val < mmin)
6265 return const0_rtx;
6266 break;
6268 case EQ:
6269 /* x == y is always false for y out of range. */
6270 if (val < mmin || val > mmax)
6271 return const0_rtx;
6272 break;
6274 /* x > y is always false for y >= mmax, always true for y < mmin. */
6275 case GTU:
6276 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6277 return const0_rtx;
6278 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6279 return const_true_rtx;
6280 break;
6281 case GT:
6282 if (val >= mmax)
6283 return const0_rtx;
6284 if (val < mmin)
6285 return const_true_rtx;
6286 break;
6288 /* x < y is always false for y <= mmin, always true for y > mmax. */
6289 case LTU:
6290 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6291 return const0_rtx;
6292 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6293 return const_true_rtx;
6294 break;
6295 case LT:
6296 if (val <= mmin)
6297 return const0_rtx;
6298 if (val > mmax)
6299 return const_true_rtx;
6300 break;
6302 case NE:
6303 /* x != y is always true for y out of range. */
6304 if (val < mmin || val > mmax)
6305 return const_true_rtx;
6306 break;
6308 default:
6309 break;
6313 /* Optimize integer comparisons with zero. */
6314 if (is_a <scalar_int_mode> (mode, &int_mode)
6315 && trueop1 == const0_rtx
6316 && !side_effects_p (trueop0))
6318 /* Some addresses are known to be nonzero. We don't know
6319 their sign, but equality comparisons are known. */
6320 if (nonzero_address_p (trueop0))
6322 if (code == EQ || code == LEU)
6323 return const0_rtx;
6324 if (code == NE || code == GTU)
6325 return const_true_rtx;
6328 /* See if the first operand is an IOR with a constant. If so, we
6329 may be able to determine the result of this comparison. */
6330 if (GET_CODE (op0) == IOR)
6332 rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
6333 if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
6335 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
6336 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
6337 && (UINTVAL (inner_const)
6338 & (HOST_WIDE_INT_1U
6339 << sign_bitnum)));
6341 switch (code)
6343 case EQ:
6344 case LEU:
6345 return const0_rtx;
6346 case NE:
6347 case GTU:
6348 return const_true_rtx;
6349 case LT:
6350 case LE:
6351 if (has_sign)
6352 return const_true_rtx;
6353 break;
6354 case GT:
6355 case GE:
6356 if (has_sign)
6357 return const0_rtx;
6358 break;
6359 default:
6360 break;
6366 /* Optimize comparison of ABS with zero. */
6367 if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
6368 && (GET_CODE (trueop0) == ABS
6369 || (GET_CODE (trueop0) == FLOAT_EXTEND
6370 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
6372 switch (code)
6374 case LT:
6375 /* Optimize abs(x) < 0.0. */
6376 if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
6377 return const0_rtx;
6378 break;
6380 case GE:
6381 /* Optimize abs(x) >= 0.0. */
6382 if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
6383 return const_true_rtx;
6384 break;
6386 case UNGE:
6387 /* Optimize ! (abs(x) < 0.0). */
6388 return const_true_rtx;
6390 default:
6391 break;
6395 return 0;
6398 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6399 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6400 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6401 can be simplified to that or NULL_RTX if not.
6402 Assume X is compared against zero with CMP_CODE and the true
6403 arm is TRUE_VAL and the false arm is FALSE_VAL. */
6406 simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
6407 rtx true_val, rtx false_val)
6409 if (cmp_code != EQ && cmp_code != NE)
6410 return NULL_RTX;
6412 /* Result on X == 0 and X !=0 respectively. */
6413 rtx on_zero, on_nonzero;
6414 if (cmp_code == EQ)
6416 on_zero = true_val;
6417 on_nonzero = false_val;
6419 else
6421 on_zero = false_val;
6422 on_nonzero = true_val;
6425 rtx_code op_code = GET_CODE (on_nonzero);
6426 if ((op_code != CLZ && op_code != CTZ)
6427 || !rtx_equal_p (XEXP (on_nonzero, 0), x)
6428 || !CONST_INT_P (on_zero))
6429 return NULL_RTX;
6431 HOST_WIDE_INT op_val;
6432 scalar_int_mode mode ATTRIBUTE_UNUSED
6433 = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
6434 if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
6435 || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
6436 && op_val == INTVAL (on_zero))
6437 return on_nonzero;
6439 return NULL_RTX;
6442 /* Try to simplify X given that it appears within operand OP of a
6443 VEC_MERGE operation whose mask is MASK. X need not use the same
6444 vector mode as the VEC_MERGE, but it must have the same number of
6445 elements.
6447 Return the simplified X on success, otherwise return NULL_RTX. */
6450 simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
6452 gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
6453 poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
6454 if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
6456 if (side_effects_p (XEXP (x, 1 - op)))
6457 return NULL_RTX;
6459 return XEXP (x, op);
6461 if (UNARY_P (x)
6462 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6463 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
6465 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6466 if (top0)
6467 return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
6468 GET_MODE (XEXP (x, 0)));
6470 if (BINARY_P (x)
6471 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6472 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6473 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6474 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
6476 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6477 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6478 if (top0 || top1)
6480 if (COMPARISON_P (x))
6481 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6482 GET_MODE (XEXP (x, 0)) != VOIDmode
6483 ? GET_MODE (XEXP (x, 0))
6484 : GET_MODE (XEXP (x, 1)),
6485 top0 ? top0 : XEXP (x, 0),
6486 top1 ? top1 : XEXP (x, 1));
6487 else
6488 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
6489 top0 ? top0 : XEXP (x, 0),
6490 top1 ? top1 : XEXP (x, 1));
6493 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
6494 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6495 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6496 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6497 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
6498 && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
6499 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
6501 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6502 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6503 rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
6504 if (top0 || top1 || top2)
6505 return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6506 GET_MODE (XEXP (x, 0)),
6507 top0 ? top0 : XEXP (x, 0),
6508 top1 ? top1 : XEXP (x, 1),
6509 top2 ? top2 : XEXP (x, 2));
6511 return NULL_RTX;
6515 /* Simplify CODE, an operation with result mode MODE and three operands,
6516 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6517 a constant. Return 0 if no simplifications is possible. */
6520 simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
6521 machine_mode op0_mode,
6522 rtx op0, rtx op1, rtx op2)
6524 bool any_change = false;
6525 rtx tem, trueop2;
6526 scalar_int_mode int_mode, int_op0_mode;
6527 unsigned int n_elts;
6529 switch (code)
6531 case FMA:
6532 /* Simplify negations around the multiplication. */
6533 /* -a * -b + c => a * b + c. */
6534 if (GET_CODE (op0) == NEG)
6536 tem = simplify_unary_operation (NEG, mode, op1, mode);
6537 if (tem)
6538 op1 = tem, op0 = XEXP (op0, 0), any_change = true;
6540 else if (GET_CODE (op1) == NEG)
6542 tem = simplify_unary_operation (NEG, mode, op0, mode);
6543 if (tem)
6544 op0 = tem, op1 = XEXP (op1, 0), any_change = true;
6547 /* Canonicalize the two multiplication operands. */
6548 /* a * -b + c => -b * a + c. */
6549 if (swap_commutative_operands_p (op0, op1))
6550 std::swap (op0, op1), any_change = true;
6552 if (any_change)
6553 return gen_rtx_FMA (mode, op0, op1, op2);
6554 return NULL_RTX;
6556 case SIGN_EXTRACT:
6557 case ZERO_EXTRACT:
6558 if (CONST_INT_P (op0)
6559 && CONST_INT_P (op1)
6560 && CONST_INT_P (op2)
6561 && is_a <scalar_int_mode> (mode, &int_mode)
6562 && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
6563 && HWI_COMPUTABLE_MODE_P (int_mode))
6565 /* Extracting a bit-field from a constant */
6566 unsigned HOST_WIDE_INT val = UINTVAL (op0);
6567 HOST_WIDE_INT op1val = INTVAL (op1);
6568 HOST_WIDE_INT op2val = INTVAL (op2);
6569 if (!BITS_BIG_ENDIAN)
6570 val >>= op2val;
6571 else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
6572 val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
6573 else
6574 /* Not enough information to calculate the bit position. */
6575 break;
6577 if (HOST_BITS_PER_WIDE_INT != op1val)
6579 /* First zero-extend. */
6580 val &= (HOST_WIDE_INT_1U << op1val) - 1;
6581 /* If desired, propagate sign bit. */
6582 if (code == SIGN_EXTRACT
6583 && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6584 != 0)
6585 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6588 return gen_int_mode (val, int_mode);
6590 break;
6592 case IF_THEN_ELSE:
6593 if (CONST_INT_P (op0))
6594 return op0 != const0_rtx ? op1 : op2;
6596 /* Convert c ? a : a into "a". */
6597 if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6598 return op1;
6600 /* Convert a != b ? a : b into "a". */
6601 if (GET_CODE (op0) == NE
6602 && ! side_effects_p (op0)
6603 && ! HONOR_NANS (mode)
6604 && ! HONOR_SIGNED_ZEROS (mode)
6605 && ((rtx_equal_p (XEXP (op0, 0), op1)
6606 && rtx_equal_p (XEXP (op0, 1), op2))
6607 || (rtx_equal_p (XEXP (op0, 0), op2)
6608 && rtx_equal_p (XEXP (op0, 1), op1))))
6609 return op1;
6611 /* Convert a == b ? a : b into "b". */
6612 if (GET_CODE (op0) == EQ
6613 && ! side_effects_p (op0)
6614 && ! HONOR_NANS (mode)
6615 && ! HONOR_SIGNED_ZEROS (mode)
6616 && ((rtx_equal_p (XEXP (op0, 0), op1)
6617 && rtx_equal_p (XEXP (op0, 1), op2))
6618 || (rtx_equal_p (XEXP (op0, 0), op2)
6619 && rtx_equal_p (XEXP (op0, 1), op1))))
6620 return op2;
6622 /* Convert (!c) != {0,...,0} ? a : b into
6623 c != {0,...,0} ? b : a for vector modes. */
6624 if (VECTOR_MODE_P (GET_MODE (op1))
6625 && GET_CODE (op0) == NE
6626 && GET_CODE (XEXP (op0, 0)) == NOT
6627 && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6629 rtx cv = XEXP (op0, 1);
6630 int nunits;
6631 bool ok = true;
6632 if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6633 ok = false;
6634 else
6635 for (int i = 0; i < nunits; ++i)
6636 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6638 ok = false;
6639 break;
6641 if (ok)
6643 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6644 XEXP (XEXP (op0, 0), 0),
6645 XEXP (op0, 1));
6646 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6647 return retval;
6651 /* Convert x == 0 ? N : clz (x) into clz (x) when
6652 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6653 Similarly for ctz (x). */
6654 if (COMPARISON_P (op0) && !side_effects_p (op0)
6655 && XEXP (op0, 1) == const0_rtx)
6657 rtx simplified
6658 = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6659 op1, op2);
6660 if (simplified)
6661 return simplified;
6664 if (COMPARISON_P (op0) && ! side_effects_p (op0))
6666 machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6667 ? GET_MODE (XEXP (op0, 1))
6668 : GET_MODE (XEXP (op0, 0)));
6669 rtx temp;
6671 /* Look for happy constants in op1 and op2. */
6672 if (CONST_INT_P (op1) && CONST_INT_P (op2))
6674 HOST_WIDE_INT t = INTVAL (op1);
6675 HOST_WIDE_INT f = INTVAL (op2);
6677 if (t == STORE_FLAG_VALUE && f == 0)
6678 code = GET_CODE (op0);
6679 else if (t == 0 && f == STORE_FLAG_VALUE)
6681 enum rtx_code tmp;
6682 tmp = reversed_comparison_code (op0, NULL);
6683 if (tmp == UNKNOWN)
6684 break;
6685 code = tmp;
6687 else
6688 break;
6690 return simplify_gen_relational (code, mode, cmp_mode,
6691 XEXP (op0, 0), XEXP (op0, 1));
6694 temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6695 cmp_mode, XEXP (op0, 0),
6696 XEXP (op0, 1));
6698 /* See if any simplifications were possible. */
6699 if (temp)
6701 if (CONST_INT_P (temp))
6702 return temp == const0_rtx ? op2 : op1;
6703 else if (temp)
6704 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6707 break;
6709 case VEC_MERGE:
6710 gcc_assert (GET_MODE (op0) == mode);
6711 gcc_assert (GET_MODE (op1) == mode);
6712 gcc_assert (VECTOR_MODE_P (mode));
6713 trueop2 = avoid_constant_pool_reference (op2);
6714 if (CONST_INT_P (trueop2)
6715 && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6717 unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6718 unsigned HOST_WIDE_INT mask;
6719 if (n_elts == HOST_BITS_PER_WIDE_INT)
6720 mask = -1;
6721 else
6722 mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6724 if (!(sel & mask) && !side_effects_p (op0))
6725 return op1;
6726 if ((sel & mask) == mask && !side_effects_p (op1))
6727 return op0;
6729 rtx trueop0 = avoid_constant_pool_reference (op0);
6730 rtx trueop1 = avoid_constant_pool_reference (op1);
6731 if (GET_CODE (trueop0) == CONST_VECTOR
6732 && GET_CODE (trueop1) == CONST_VECTOR)
6734 rtvec v = rtvec_alloc (n_elts);
6735 unsigned int i;
6737 for (i = 0; i < n_elts; i++)
6738 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6739 ? CONST_VECTOR_ELT (trueop0, i)
6740 : CONST_VECTOR_ELT (trueop1, i));
6741 return gen_rtx_CONST_VECTOR (mode, v);
6744 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6745 if no element from a appears in the result. */
6746 if (GET_CODE (op0) == VEC_MERGE)
6748 tem = avoid_constant_pool_reference (XEXP (op0, 2));
6749 if (CONST_INT_P (tem))
6751 unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6752 if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6753 return simplify_gen_ternary (code, mode, mode,
6754 XEXP (op0, 1), op1, op2);
6755 if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6756 return simplify_gen_ternary (code, mode, mode,
6757 XEXP (op0, 0), op1, op2);
6760 if (GET_CODE (op1) == VEC_MERGE)
6762 tem = avoid_constant_pool_reference (XEXP (op1, 2));
6763 if (CONST_INT_P (tem))
6765 unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6766 if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6767 return simplify_gen_ternary (code, mode, mode,
6768 op0, XEXP (op1, 1), op2);
6769 if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6770 return simplify_gen_ternary (code, mode, mode,
6771 op0, XEXP (op1, 0), op2);
6775 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6776 with a. */
6777 if (GET_CODE (op0) == VEC_DUPLICATE
6778 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6779 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6780 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6782 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6783 if (CONST_INT_P (tem) && CONST_INT_P (op2))
6785 if (XEXP (XEXP (op0, 0), 0) == op1
6786 && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6787 return op1;
6790 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6791 (const_int N))
6792 with (vec_concat (X) (B)) if N == 1 or
6793 (vec_concat (A) (X)) if N == 2. */
6794 if (GET_CODE (op0) == VEC_DUPLICATE
6795 && GET_CODE (op1) == CONST_VECTOR
6796 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6797 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6798 && IN_RANGE (sel, 1, 2))
6800 rtx newop0 = XEXP (op0, 0);
6801 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6802 if (sel == 2)
6803 std::swap (newop0, newop1);
6804 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6806 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6807 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6808 Only applies for vectors of two elements. */
6809 if (GET_CODE (op0) == VEC_DUPLICATE
6810 && GET_CODE (op1) == VEC_CONCAT
6811 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6812 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6813 && IN_RANGE (sel, 1, 2))
6815 rtx newop0 = XEXP (op0, 0);
6816 rtx newop1 = XEXP (op1, 2 - sel);
6817 rtx otherop = XEXP (op1, sel - 1);
6818 if (sel == 2)
6819 std::swap (newop0, newop1);
6820 /* Don't want to throw away the other part of the vec_concat if
6821 it has side-effects. */
6822 if (!side_effects_p (otherop))
6823 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6826 /* Replace:
6828 (vec_merge:outer (vec_duplicate:outer x:inner)
6829 (subreg:outer y:inner 0)
6830 (const_int N))
6832 with (vec_concat:outer x:inner y:inner) if N == 1,
6833 or (vec_concat:outer y:inner x:inner) if N == 2.
6835 Implicitly, this means we have a paradoxical subreg, but such
6836 a check is cheap, so make it anyway.
6838 Only applies for vectors of two elements. */
6839 if (GET_CODE (op0) == VEC_DUPLICATE
6840 && GET_CODE (op1) == SUBREG
6841 && GET_MODE (op1) == GET_MODE (op0)
6842 && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6843 && paradoxical_subreg_p (op1)
6844 && subreg_lowpart_p (op1)
6845 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6846 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6847 && IN_RANGE (sel, 1, 2))
6849 rtx newop0 = XEXP (op0, 0);
6850 rtx newop1 = SUBREG_REG (op1);
6851 if (sel == 2)
6852 std::swap (newop0, newop1);
6853 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6856 /* Same as above but with switched operands:
6857 Replace (vec_merge:outer (subreg:outer x:inner 0)
6858 (vec_duplicate:outer y:inner)
6859 (const_int N))
6861 with (vec_concat:outer x:inner y:inner) if N == 1,
6862 or (vec_concat:outer y:inner x:inner) if N == 2. */
6863 if (GET_CODE (op1) == VEC_DUPLICATE
6864 && GET_CODE (op0) == SUBREG
6865 && GET_MODE (op0) == GET_MODE (op1)
6866 && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
6867 && paradoxical_subreg_p (op0)
6868 && subreg_lowpart_p (op0)
6869 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6870 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6871 && IN_RANGE (sel, 1, 2))
6873 rtx newop0 = SUBREG_REG (op0);
6874 rtx newop1 = XEXP (op1, 0);
6875 if (sel == 2)
6876 std::swap (newop0, newop1);
6877 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6880 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
6881 (const_int n))
6882 with (vec_concat x y) or (vec_concat y x) depending on value
6883 of N. */
6884 if (GET_CODE (op0) == VEC_DUPLICATE
6885 && GET_CODE (op1) == VEC_DUPLICATE
6886 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6887 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6888 && IN_RANGE (sel, 1, 2))
6890 rtx newop0 = XEXP (op0, 0);
6891 rtx newop1 = XEXP (op1, 0);
6892 if (sel == 2)
6893 std::swap (newop0, newop1);
6895 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6899 if (rtx_equal_p (op0, op1)
6900 && !side_effects_p (op2) && !side_effects_p (op1))
6901 return op0;
6903 if (!side_effects_p (op2))
6905 rtx top0
6906 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6907 rtx top1
6908 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6909 if (top0 || top1)
6910 return simplify_gen_ternary (code, mode, mode,
6911 top0 ? top0 : op0,
6912 top1 ? top1 : op1, op2);
6915 break;
6917 default:
6918 gcc_unreachable ();
6921 return 0;
6924 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6925 starting at byte FIRST_BYTE. Return true on success and add the
6926 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6927 that the bytes follow target memory order. Leave BYTES unmodified
6928 on failure.
6930 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6931 BYTES before calling this function. */
6933 bool
6934 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6935 unsigned int first_byte, unsigned int num_bytes)
6937 /* Check the mode is sensible. */
6938 gcc_assert (GET_MODE (x) == VOIDmode
6939 ? is_a <scalar_int_mode> (mode)
6940 : mode == GET_MODE (x));
6942 if (GET_CODE (x) == CONST_VECTOR)
6944 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
6945 is necessary. The only complication is that MODE_VECTOR_BOOL
6946 vectors can have several elements per byte. */
6947 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6948 GET_MODE_NUNITS (mode));
6949 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
6950 if (elt_bits < BITS_PER_UNIT)
6952 /* This is the only case in which elements can be smaller than
6953 a byte. */
6954 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6955 auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
6956 for (unsigned int i = 0; i < num_bytes; ++i)
6958 target_unit value = 0;
6959 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
6961 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & mask) << j;
6962 elt += 1;
6964 bytes.quick_push (value);
6966 return true;
6969 unsigned int start = bytes.length ();
6970 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
6971 /* Make FIRST_BYTE relative to ELT. */
6972 first_byte %= elt_bytes;
6973 while (num_bytes > 0)
6975 /* Work out how many bytes we want from element ELT. */
6976 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
6977 if (!native_encode_rtx (GET_MODE_INNER (mode),
6978 CONST_VECTOR_ELT (x, elt), bytes,
6979 first_byte, chunk_bytes))
6981 bytes.truncate (start);
6982 return false;
6984 elt += 1;
6985 first_byte = 0;
6986 num_bytes -= chunk_bytes;
6988 return true;
6991 /* All subsequent cases are limited to scalars. */
6992 scalar_mode smode;
6993 if (!is_a <scalar_mode> (mode, &smode))
6994 return false;
6996 /* Make sure that the region is in range. */
6997 unsigned int end_byte = first_byte + num_bytes;
6998 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6999 gcc_assert (end_byte <= mode_bytes);
7001 if (CONST_SCALAR_INT_P (x))
7003 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7004 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7005 position of each byte. */
7006 rtx_mode_t value (x, smode);
7007 wide_int_ref value_wi (value);
7008 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7010 /* Always constant because the inputs are. */
7011 unsigned int lsb
7012 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7013 /* Operate directly on the encoding rather than using
7014 wi::extract_uhwi, so that we preserve the sign or zero
7015 extension for modes that are not a whole number of bits in
7016 size. (Zero extension is only used for the combination of
7017 innermode == BImode && STORE_FLAG_VALUE == 1). */
7018 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
7019 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
7020 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
7021 bytes.quick_push (uhwi >> shift);
7023 return true;
7026 if (CONST_DOUBLE_P (x))
7028 /* real_to_target produces an array of integers in target memory order.
7029 All integers before the last one have 32 bits; the last one may
7030 have 32 bits or fewer, depending on whether the mode bitsize
7031 is divisible by 32. Each of these integers is then laid out
7032 in target memory as any other integer would be. */
7033 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7034 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
7036 /* The (maximum) number of target bytes per element of el32. */
7037 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7038 gcc_assert (bytes_per_el32 != 0);
7040 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7041 handling above. */
7042 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7044 unsigned int index = byte / bytes_per_el32;
7045 unsigned int subbyte = byte % bytes_per_el32;
7046 unsigned int int_bytes = MIN (bytes_per_el32,
7047 mode_bytes - index * bytes_per_el32);
7048 /* Always constant because the inputs are. */
7049 unsigned int lsb
7050 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7051 bytes.quick_push ((unsigned long) el32[index] >> lsb);
7053 return true;
7056 if (GET_CODE (x) == CONST_FIXED)
7058 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7060 /* Always constant because the inputs are. */
7061 unsigned int lsb
7062 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7063 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
7064 if (lsb >= HOST_BITS_PER_WIDE_INT)
7066 lsb -= HOST_BITS_PER_WIDE_INT;
7067 piece = CONST_FIXED_VALUE_HIGH (x);
7069 bytes.quick_push (piece >> lsb);
7071 return true;
7074 return false;
7077 /* Read a vector of mode MODE from the target memory image given by BYTES,
7078 starting at byte FIRST_BYTE. The vector is known to be encodable using
7079 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
7080 and BYTES is known to have enough bytes to supply NPATTERNS *
7081 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
7082 BITS_PER_UNIT bits and the bytes are in target memory order.
7084 Return the vector on success, otherwise return NULL_RTX. */
7087 native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
7088 unsigned int first_byte, unsigned int npatterns,
7089 unsigned int nelts_per_pattern)
7091 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
7093 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7094 GET_MODE_NUNITS (mode));
7095 if (elt_bits < BITS_PER_UNIT)
7097 /* This is the only case in which elements can be smaller than a byte.
7098 Element 0 is always in the lsb of the containing byte. */
7099 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7100 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7102 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
7103 unsigned int byte_index = bit_index / BITS_PER_UNIT;
7104 unsigned int lsb = bit_index % BITS_PER_UNIT;
7105 unsigned int value = bytes[byte_index] >> lsb;
7106 builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
7109 else
7111 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7113 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
7114 if (!x)
7115 return NULL_RTX;
7116 builder.quick_push (x);
7117 first_byte += elt_bits / BITS_PER_UNIT;
7120 return builder.build ();
7123 /* Read an rtx of mode MODE from the target memory image given by BYTES,
7124 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
7125 bits and the bytes are in target memory order. The image has enough
7126 values to specify all bytes of MODE.
7128 Return the rtx on success, otherwise return NULL_RTX. */
7131 native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
7132 unsigned int first_byte)
7134 if (VECTOR_MODE_P (mode))
7136 /* If we know at compile time how many elements there are,
7137 pull each element directly from BYTES. */
7138 unsigned int nelts;
7139 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
7140 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
7141 return NULL_RTX;
7144 scalar_int_mode imode;
7145 if (is_a <scalar_int_mode> (mode, &imode)
7146 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
7148 /* Pull the bytes msb first, so that we can use simple
7149 shift-and-insert wide_int operations. */
7150 unsigned int size = GET_MODE_SIZE (imode);
7151 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
7152 for (unsigned int i = 0; i < size; ++i)
7154 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
7155 /* Always constant because the inputs are. */
7156 unsigned int subbyte
7157 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
7158 result <<= BITS_PER_UNIT;
7159 result |= bytes[first_byte + subbyte];
7161 return immed_wide_int_const (result, imode);
7164 scalar_float_mode fmode;
7165 if (is_a <scalar_float_mode> (mode, &fmode))
7167 /* We need to build an array of integers in target memory order.
7168 All integers before the last one have 32 bits; the last one may
7169 have 32 bits or fewer, depending on whether the mode bitsize
7170 is divisible by 32. */
7171 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7172 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
7173 memset (el32, 0, num_el32 * sizeof (long));
7175 /* The (maximum) number of target bytes per element of el32. */
7176 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7177 gcc_assert (bytes_per_el32 != 0);
7179 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
7180 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7182 unsigned int index = byte / bytes_per_el32;
7183 unsigned int subbyte = byte % bytes_per_el32;
7184 unsigned int int_bytes = MIN (bytes_per_el32,
7185 mode_bytes - index * bytes_per_el32);
7186 /* Always constant because the inputs are. */
7187 unsigned int lsb
7188 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7189 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
7191 REAL_VALUE_TYPE r;
7192 real_from_target (&r, el32, fmode);
7193 return const_double_from_real_value (r, fmode);
7196 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7198 scalar_mode smode = as_a <scalar_mode> (mode);
7199 FIXED_VALUE_TYPE f;
7200 f.data.low = 0;
7201 f.data.high = 0;
7202 f.mode = smode;
7204 unsigned int mode_bytes = GET_MODE_SIZE (smode);
7205 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7207 /* Always constant because the inputs are. */
7208 unsigned int lsb
7209 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7210 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
7211 if (lsb >= HOST_BITS_PER_WIDE_INT)
7212 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
7213 else
7214 f.data.low |= unit << lsb;
7216 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
7219 return NULL_RTX;
7222 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
7223 is to convert a runtime BYTE value into a constant one. */
7225 static poly_uint64
7226 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
7228 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7229 machine_mode mode = GET_MODE (x);
7230 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
7231 GET_MODE_NUNITS (mode));
7232 /* The number of bits needed to encode one element from each pattern. */
7233 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
7235 /* Identify the start point in terms of a sequence number and a byte offset
7236 within that sequence. */
7237 poly_uint64 first_sequence;
7238 unsigned HOST_WIDE_INT subbit;
7239 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
7240 &first_sequence, &subbit))
7242 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7243 if (nelts_per_pattern == 1)
7244 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
7245 doesn't matter. */
7246 byte = subbit / BITS_PER_UNIT;
7247 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
7249 /* The subreg drops the first element from each pattern and
7250 only uses the second element. Find the first sequence
7251 that starts on a byte boundary. */
7252 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
7253 byte = subbit / BITS_PER_UNIT;
7256 return byte;
7259 /* Subroutine of simplify_subreg in which:
7261 - X is known to be a CONST_VECTOR
7262 - OUTERMODE is known to be a vector mode
7264 Try to handle the subreg by operating on the CONST_VECTOR encoding
7265 rather than on each individual element of the CONST_VECTOR.
7267 Return the simplified subreg on success, otherwise return NULL_RTX. */
7269 static rtx
7270 simplify_const_vector_subreg (machine_mode outermode, rtx x,
7271 machine_mode innermode, unsigned int first_byte)
7273 /* Paradoxical subregs of vectors have dubious semantics. */
7274 if (paradoxical_subreg_p (outermode, innermode))
7275 return NULL_RTX;
7277 /* We can only preserve the semantics of a stepped pattern if the new
7278 vector element is the same as the original one. */
7279 if (CONST_VECTOR_STEPPED_P (x)
7280 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
7281 return NULL_RTX;
7283 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7284 unsigned int x_elt_bits
7285 = vector_element_size (GET_MODE_BITSIZE (innermode),
7286 GET_MODE_NUNITS (innermode));
7287 unsigned int out_elt_bits
7288 = vector_element_size (GET_MODE_BITSIZE (outermode),
7289 GET_MODE_NUNITS (outermode));
7291 /* The number of bits needed to encode one element from every pattern
7292 of the original vector. */
7293 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
7295 /* The number of bits needed to encode one element from every pattern
7296 of the result. */
7297 unsigned int out_sequence_bits
7298 = least_common_multiple (x_sequence_bits, out_elt_bits);
7300 /* Work out the number of interleaved patterns in the output vector
7301 and the number of encoded elements per pattern. */
7302 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
7303 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7305 /* The encoding scheme requires the number of elements to be a multiple
7306 of the number of patterns, so that each pattern appears at least once
7307 and so that the same number of elements appear from each pattern. */
7308 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
7309 unsigned int const_nunits;
7310 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
7311 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
7313 /* Either the encoding is invalid, or applying it would give us
7314 more elements than we need. Just encode each element directly. */
7315 out_npatterns = const_nunits;
7316 nelts_per_pattern = 1;
7318 else if (!ok_p)
7319 return NULL_RTX;
7321 /* Get enough bytes of X to form the new encoding. */
7322 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
7323 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
7324 auto_vec<target_unit, 128> buffer (buffer_bytes);
7325 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
7326 return NULL_RTX;
7328 /* Reencode the bytes as OUTERMODE. */
7329 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
7330 nelts_per_pattern);
7333 /* Try to simplify a subreg of a constant by encoding the subreg region
7334 as a sequence of target bytes and reading them back in the new mode.
7335 Return the new value on success, otherwise return null.
7337 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7338 and byte offset FIRST_BYTE. */
7340 static rtx
7341 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
7342 machine_mode innermode, unsigned int first_byte)
7344 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
7345 auto_vec<target_unit, 128> buffer (buffer_bytes);
7347 /* Some ports misuse CCmode. */
7348 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
7349 return x;
7351 /* Paradoxical subregs read undefined values for bytes outside of the
7352 inner value. However, we have traditionally always sign-extended
7353 integer constants and zero-extended others. */
7354 unsigned int inner_bytes = buffer_bytes;
7355 if (paradoxical_subreg_p (outermode, innermode))
7357 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
7358 return NULL_RTX;
7360 target_unit filler = 0;
7361 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
7362 filler = -1;
7364 /* Add any leading bytes due to big-endian layout. The number of
7365 bytes must be constant because both modes have constant size. */
7366 unsigned int leading_bytes
7367 = -byte_lowpart_offset (outermode, innermode).to_constant ();
7368 for (unsigned int i = 0; i < leading_bytes; ++i)
7369 buffer.quick_push (filler);
7371 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7372 return NULL_RTX;
7374 /* Add any trailing bytes due to little-endian layout. */
7375 while (buffer.length () < buffer_bytes)
7376 buffer.quick_push (filler);
7378 else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7379 return NULL_RTX;
7380 rtx ret = native_decode_rtx (outermode, buffer, 0);
7381 if (ret && FLOAT_MODE_P (outermode))
7383 auto_vec<target_unit, 128> buffer2 (buffer_bytes);
7384 if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
7385 return NULL_RTX;
7386 for (unsigned int i = 0; i < buffer_bytes; ++i)
7387 if (buffer[i] != buffer2[i])
7388 return NULL_RTX;
7390 return ret;
7393 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7394 Return 0 if no simplifications are possible. */
7396 simplify_context::simplify_subreg (machine_mode outermode, rtx op,
7397 machine_mode innermode, poly_uint64 byte)
7399 /* Little bit of sanity checking. */
7400 gcc_assert (innermode != VOIDmode);
7401 gcc_assert (outermode != VOIDmode);
7402 gcc_assert (innermode != BLKmode);
7403 gcc_assert (outermode != BLKmode);
7405 gcc_assert (GET_MODE (op) == innermode
7406 || GET_MODE (op) == VOIDmode);
7408 poly_uint64 outersize = GET_MODE_SIZE (outermode);
7409 if (!multiple_p (byte, outersize))
7410 return NULL_RTX;
7412 poly_uint64 innersize = GET_MODE_SIZE (innermode);
7413 if (maybe_ge (byte, innersize))
7414 return NULL_RTX;
7416 if (outermode == innermode && known_eq (byte, 0U))
7417 return op;
7419 if (GET_CODE (op) == CONST_VECTOR)
7420 byte = simplify_const_vector_byte_offset (op, byte);
7422 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
7424 rtx elt;
7426 if (VECTOR_MODE_P (outermode)
7427 && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
7428 && vec_duplicate_p (op, &elt))
7429 return gen_vec_duplicate (outermode, elt);
7431 if (outermode == GET_MODE_INNER (innermode)
7432 && vec_duplicate_p (op, &elt))
7433 return elt;
7436 if (CONST_SCALAR_INT_P (op)
7437 || CONST_DOUBLE_AS_FLOAT_P (op)
7438 || CONST_FIXED_P (op)
7439 || GET_CODE (op) == CONST_VECTOR)
7441 unsigned HOST_WIDE_INT cbyte;
7442 if (byte.is_constant (&cbyte))
7444 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
7446 rtx tmp = simplify_const_vector_subreg (outermode, op,
7447 innermode, cbyte);
7448 if (tmp)
7449 return tmp;
7452 fixed_size_mode fs_outermode;
7453 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
7454 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
7458 /* Changing mode twice with SUBREG => just change it once,
7459 or not at all if changing back op starting mode. */
7460 if (GET_CODE (op) == SUBREG)
7462 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
7463 poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
7464 rtx newx;
7466 if (outermode == innermostmode
7467 && known_eq (byte, 0U)
7468 && known_eq (SUBREG_BYTE (op), 0))
7469 return SUBREG_REG (op);
7471 /* Work out the memory offset of the final OUTERMODE value relative
7472 to the inner value of OP. */
7473 poly_int64 mem_offset = subreg_memory_offset (outermode,
7474 innermode, byte);
7475 poly_int64 op_mem_offset = subreg_memory_offset (op);
7476 poly_int64 final_offset = mem_offset + op_mem_offset;
7478 /* See whether resulting subreg will be paradoxical. */
7479 if (!paradoxical_subreg_p (outermode, innermostmode))
7481 /* Bail out in case resulting subreg would be incorrect. */
7482 if (maybe_lt (final_offset, 0)
7483 || maybe_ge (poly_uint64 (final_offset), innermostsize)
7484 || !multiple_p (final_offset, outersize))
7485 return NULL_RTX;
7487 else
7489 poly_int64 required_offset = subreg_memory_offset (outermode,
7490 innermostmode, 0);
7491 if (maybe_ne (final_offset, required_offset))
7492 return NULL_RTX;
7493 /* Paradoxical subregs always have byte offset 0. */
7494 final_offset = 0;
7497 /* Recurse for further possible simplifications. */
7498 newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
7499 final_offset);
7500 if (newx)
7501 return newx;
7502 if (validate_subreg (outermode, innermostmode,
7503 SUBREG_REG (op), final_offset))
7505 newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
7506 if (SUBREG_PROMOTED_VAR_P (op)
7507 && SUBREG_PROMOTED_SIGN (op) >= 0
7508 && GET_MODE_CLASS (outermode) == MODE_INT
7509 && known_ge (outersize, innersize)
7510 && known_le (outersize, innermostsize)
7511 && subreg_lowpart_p (newx))
7513 SUBREG_PROMOTED_VAR_P (newx) = 1;
7514 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
7516 return newx;
7518 return NULL_RTX;
7521 /* SUBREG of a hard register => just change the register number
7522 and/or mode. If the hard register is not valid in that mode,
7523 suppress this simplification. If the hard register is the stack,
7524 frame, or argument pointer, leave this as a SUBREG. */
7526 if (REG_P (op) && HARD_REGISTER_P (op))
7528 unsigned int regno, final_regno;
7530 regno = REGNO (op);
7531 final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
7532 if (HARD_REGISTER_NUM_P (final_regno))
7534 rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
7535 subreg_memory_offset (outermode,
7536 innermode, byte));
7538 /* Propagate original regno. We don't have any way to specify
7539 the offset inside original regno, so do so only for lowpart.
7540 The information is used only by alias analysis that cannot
7541 grog partial register anyway. */
7543 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
7544 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
7545 return x;
7549 /* If we have a SUBREG of a register that we are replacing and we are
7550 replacing it with a MEM, make a new MEM and try replacing the
7551 SUBREG with it. Don't do this if the MEM has a mode-dependent address
7552 or if we would be widening it. */
7554 if (MEM_P (op)
7555 && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
7556 /* Allow splitting of volatile memory references in case we don't
7557 have instruction to move the whole thing. */
7558 && (! MEM_VOLATILE_P (op)
7559 || ! have_insn_for (SET, innermode))
7560 && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
7561 && known_le (outersize, innersize))
7562 return adjust_address_nv (op, outermode, byte);
7564 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7565 of two parts. */
7566 if (GET_CODE (op) == CONCAT
7567 || GET_CODE (op) == VEC_CONCAT)
7569 poly_uint64 final_offset;
7570 rtx part, res;
7572 machine_mode part_mode = GET_MODE (XEXP (op, 0));
7573 if (part_mode == VOIDmode)
7574 part_mode = GET_MODE_INNER (GET_MODE (op));
7575 poly_uint64 part_size = GET_MODE_SIZE (part_mode);
7576 if (known_lt (byte, part_size))
7578 part = XEXP (op, 0);
7579 final_offset = byte;
7581 else if (known_ge (byte, part_size))
7583 part = XEXP (op, 1);
7584 final_offset = byte - part_size;
7586 else
7587 return NULL_RTX;
7589 if (maybe_gt (final_offset + outersize, part_size))
7590 return NULL_RTX;
7592 part_mode = GET_MODE (part);
7593 if (part_mode == VOIDmode)
7594 part_mode = GET_MODE_INNER (GET_MODE (op));
7595 res = simplify_subreg (outermode, part, part_mode, final_offset);
7596 if (res)
7597 return res;
7598 if (validate_subreg (outermode, part_mode, part, final_offset))
7599 return gen_rtx_SUBREG (outermode, part, final_offset);
7600 return NULL_RTX;
7603 /* Simplify
7604 (subreg (vec_merge (X)
7605 (vector)
7606 (const_int ((1 << N) | M)))
7607 (N * sizeof (outermode)))
7609 (subreg (X) (N * sizeof (outermode)))
7611 unsigned int idx;
7612 if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7613 && idx < HOST_BITS_PER_WIDE_INT
7614 && GET_CODE (op) == VEC_MERGE
7615 && GET_MODE_INNER (innermode) == outermode
7616 && CONST_INT_P (XEXP (op, 2))
7617 && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7618 return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7620 /* A SUBREG resulting from a zero extension may fold to zero if
7621 it extracts higher bits that the ZERO_EXTEND's source bits. */
7622 if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7624 poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7625 if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7626 return CONST0_RTX (outermode);
7629 scalar_int_mode int_outermode, int_innermode;
7630 if (is_a <scalar_int_mode> (outermode, &int_outermode)
7631 && is_a <scalar_int_mode> (innermode, &int_innermode)
7632 && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7634 /* Handle polynomial integers. The upper bits of a paradoxical
7635 subreg are undefined, so this is safe regardless of whether
7636 we're truncating or extending. */
7637 if (CONST_POLY_INT_P (op))
7639 poly_wide_int val
7640 = poly_wide_int::from (const_poly_int_value (op),
7641 GET_MODE_PRECISION (int_outermode),
7642 SIGNED);
7643 return immed_wide_int_const (val, int_outermode);
7646 if (GET_MODE_PRECISION (int_outermode)
7647 < GET_MODE_PRECISION (int_innermode))
7649 rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7650 if (tem)
7651 return tem;
7655 /* If OP is a vector comparison and the subreg is not changing the
7656 number of elements or the size of the elements, change the result
7657 of the comparison to the new mode. */
7658 if (COMPARISON_P (op)
7659 && VECTOR_MODE_P (outermode)
7660 && VECTOR_MODE_P (innermode)
7661 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7662 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7663 GET_MODE_UNIT_SIZE (innermode)))
7664 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7665 XEXP (op, 0), XEXP (op, 1));
7666 return NULL_RTX;
7669 /* Make a SUBREG operation or equivalent if it folds. */
7672 simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
7673 machine_mode innermode,
7674 poly_uint64 byte)
7676 rtx newx;
7678 newx = simplify_subreg (outermode, op, innermode, byte);
7679 if (newx)
7680 return newx;
7682 if (GET_CODE (op) == SUBREG
7683 || GET_CODE (op) == CONCAT
7684 || GET_MODE (op) == VOIDmode)
7685 return NULL_RTX;
7687 if (MODE_COMPOSITE_P (outermode)
7688 && (CONST_SCALAR_INT_P (op)
7689 || CONST_DOUBLE_AS_FLOAT_P (op)
7690 || CONST_FIXED_P (op)
7691 || GET_CODE (op) == CONST_VECTOR))
7692 return NULL_RTX;
7694 if (validate_subreg (outermode, innermode, op, byte))
7695 return gen_rtx_SUBREG (outermode, op, byte);
7697 return NULL_RTX;
7700 /* Generates a subreg to get the least significant part of EXPR (in mode
7701 INNER_MODE) to OUTER_MODE. */
7704 simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
7705 machine_mode inner_mode)
7707 return simplify_gen_subreg (outer_mode, expr, inner_mode,
7708 subreg_lowpart_offset (outer_mode, inner_mode));
7711 /* Generate RTX to select element at INDEX out of vector OP. */
7714 simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
7716 gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
7718 scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
7720 if (known_eq (index * GET_MODE_SIZE (imode),
7721 subreg_lowpart_offset (imode, GET_MODE (op))))
7723 rtx res = lowpart_subreg (imode, op, GET_MODE (op));
7724 if (res)
7725 return res;
7728 rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
7729 return gen_rtx_VEC_SELECT (imode, op, tmp);
7733 /* Simplify X, an rtx expression.
7735 Return the simplified expression or NULL if no simplifications
7736 were possible.
7738 This is the preferred entry point into the simplification routines;
7739 however, we still allow passes to call the more specific routines.
7741 Right now GCC has three (yes, three) major bodies of RTL simplification
7742 code that need to be unified.
7744 1. fold_rtx in cse.cc. This code uses various CSE specific
7745 information to aid in RTL simplification.
7747 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
7748 it uses combine specific information to aid in RTL
7749 simplification.
7751 3. The routines in this file.
7754 Long term we want to only have one body of simplification code; to
7755 get to that state I recommend the following steps:
7757 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7758 which are not pass dependent state into these routines.
7760 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7761 use this routine whenever possible.
7763 3. Allow for pass dependent state to be provided to these
7764 routines and add simplifications based on the pass dependent
7765 state. Remove code from cse.cc & combine.cc that becomes
7766 redundant/dead.
7768 It will take time, but ultimately the compiler will be easier to
7769 maintain and improve. It's totally silly that when we add a
7770 simplification that it needs to be added to 4 places (3 for RTL
7771 simplification and 1 for tree simplification. */
7774 simplify_rtx (const_rtx x)
7776 const enum rtx_code code = GET_CODE (x);
7777 const machine_mode mode = GET_MODE (x);
7779 switch (GET_RTX_CLASS (code))
7781 case RTX_UNARY:
7782 return simplify_unary_operation (code, mode,
7783 XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7784 case RTX_COMM_ARITH:
7785 if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7786 return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7788 /* Fall through. */
7790 case RTX_BIN_ARITH:
7791 return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7793 case RTX_TERNARY:
7794 case RTX_BITFIELD_OPS:
7795 return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7796 XEXP (x, 0), XEXP (x, 1),
7797 XEXP (x, 2));
7799 case RTX_COMPARE:
7800 case RTX_COMM_COMPARE:
7801 return simplify_relational_operation (code, mode,
7802 ((GET_MODE (XEXP (x, 0))
7803 != VOIDmode)
7804 ? GET_MODE (XEXP (x, 0))
7805 : GET_MODE (XEXP (x, 1))),
7806 XEXP (x, 0),
7807 XEXP (x, 1));
7809 case RTX_EXTRA:
7810 if (code == SUBREG)
7811 return simplify_subreg (mode, SUBREG_REG (x),
7812 GET_MODE (SUBREG_REG (x)),
7813 SUBREG_BYTE (x));
7814 break;
7816 case RTX_OBJ:
7817 if (code == LO_SUM)
7819 /* Convert (lo_sum (high FOO) FOO) to FOO. */
7820 if (GET_CODE (XEXP (x, 0)) == HIGH
7821 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
7822 return XEXP (x, 1);
7824 break;
7826 default:
7827 break;
7829 return NULL;
7832 #if CHECKING_P
7834 namespace selftest {
7836 /* Make a unique pseudo REG of mode MODE for use by selftests. */
7838 static rtx
7839 make_test_reg (machine_mode mode)
7841 static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
7843 return gen_rtx_REG (mode, test_reg_num++);
7846 static void
7847 test_scalar_int_ops (machine_mode mode)
7849 rtx op0 = make_test_reg (mode);
7850 rtx op1 = make_test_reg (mode);
7851 rtx six = GEN_INT (6);
7853 rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
7854 rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
7855 rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
7857 rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
7858 rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
7859 rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
7861 rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
7862 rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
7864 /* Test some binary identities. */
7865 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
7866 ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
7867 ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
7868 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
7869 ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
7870 ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
7871 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
7872 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
7873 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
7874 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
7875 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
7876 ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
7877 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
7878 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
7879 ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
7880 ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
7881 ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
7883 /* Test some self-inverse operations. */
7884 ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
7885 ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
7886 ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
7888 /* Test some reflexive operations. */
7889 ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
7890 ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
7891 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
7892 ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
7893 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
7894 ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
7896 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
7897 ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
7899 /* Test simplify_distributive_operation. */
7900 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
7901 simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
7902 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
7903 simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
7904 ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
7905 simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
7907 /* Test useless extensions are eliminated. */
7908 ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
7909 ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
7910 ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
7911 ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
7914 /* Verify some simplifications of integer extension/truncation.
7915 Machine mode BMODE is the guaranteed wider than SMODE. */
7917 static void
7918 test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
7920 rtx sreg = make_test_reg (smode);
7922 /* Check truncation of extension. */
7923 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7924 simplify_gen_unary (ZERO_EXTEND, bmode,
7925 sreg, smode),
7926 bmode),
7927 sreg);
7928 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7929 simplify_gen_unary (SIGN_EXTEND, bmode,
7930 sreg, smode),
7931 bmode),
7932 sreg);
7933 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7934 lowpart_subreg (bmode, sreg, smode),
7935 bmode),
7936 sreg);
7939 /* Verify more simplifications of integer extension/truncation.
7940 BMODE is wider than MMODE which is wider than SMODE. */
7942 static void
7943 test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
7944 machine_mode smode)
7946 rtx breg = make_test_reg (bmode);
7947 rtx mreg = make_test_reg (mmode);
7948 rtx sreg = make_test_reg (smode);
7950 /* Check truncate of truncate. */
7951 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7952 simplify_gen_unary (TRUNCATE, mmode,
7953 breg, bmode),
7954 mmode),
7955 simplify_gen_unary (TRUNCATE, smode, breg, bmode));
7957 /* Check extension of extension. */
7958 ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
7959 simplify_gen_unary (ZERO_EXTEND, mmode,
7960 sreg, smode),
7961 mmode),
7962 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
7963 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
7964 simplify_gen_unary (SIGN_EXTEND, mmode,
7965 sreg, smode),
7966 mmode),
7967 simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
7968 ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
7969 simplify_gen_unary (ZERO_EXTEND, mmode,
7970 sreg, smode),
7971 mmode),
7972 simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
7974 /* Check truncation of extension. */
7975 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7976 simplify_gen_unary (ZERO_EXTEND, bmode,
7977 mreg, mmode),
7978 bmode),
7979 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
7980 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7981 simplify_gen_unary (SIGN_EXTEND, bmode,
7982 mreg, mmode),
7983 bmode),
7984 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
7985 ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
7986 lowpart_subreg (bmode, mreg, mmode),
7987 bmode),
7988 simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
7992 /* Verify some simplifications involving scalar expressions. */
7994 static void
7995 test_scalar_ops ()
7997 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
7999 machine_mode mode = (machine_mode) i;
8000 if (SCALAR_INT_MODE_P (mode) && mode != BImode)
8001 test_scalar_int_ops (mode);
8004 test_scalar_int_ext_ops (HImode, QImode);
8005 test_scalar_int_ext_ops (SImode, QImode);
8006 test_scalar_int_ext_ops (SImode, HImode);
8007 test_scalar_int_ext_ops (DImode, QImode);
8008 test_scalar_int_ext_ops (DImode, HImode);
8009 test_scalar_int_ext_ops (DImode, SImode);
8011 test_scalar_int_ext_ops2 (SImode, HImode, QImode);
8012 test_scalar_int_ext_ops2 (DImode, HImode, QImode);
8013 test_scalar_int_ext_ops2 (DImode, SImode, QImode);
8014 test_scalar_int_ext_ops2 (DImode, SImode, HImode);
8017 /* Test vector simplifications involving VEC_DUPLICATE in which the
8018 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8019 register that holds one element of MODE. */
8021 static void
8022 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
8024 scalar_mode inner_mode = GET_MODE_INNER (mode);
8025 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8026 poly_uint64 nunits = GET_MODE_NUNITS (mode);
8027 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
8029 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
8030 rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
8031 rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
8032 ASSERT_RTX_EQ (duplicate,
8033 simplify_unary_operation (NOT, mode,
8034 duplicate_not, mode));
8036 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8037 rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
8038 ASSERT_RTX_EQ (duplicate,
8039 simplify_unary_operation (NEG, mode,
8040 duplicate_neg, mode));
8042 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
8043 ASSERT_RTX_EQ (duplicate,
8044 simplify_binary_operation (PLUS, mode, duplicate,
8045 CONST0_RTX (mode)));
8047 ASSERT_RTX_EQ (duplicate,
8048 simplify_binary_operation (MINUS, mode, duplicate,
8049 CONST0_RTX (mode)));
8051 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
8052 simplify_binary_operation (MINUS, mode, duplicate,
8053 duplicate));
8056 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
8057 rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
8058 ASSERT_RTX_PTR_EQ (scalar_reg,
8059 simplify_binary_operation (VEC_SELECT, inner_mode,
8060 duplicate, zero_par));
8062 unsigned HOST_WIDE_INT const_nunits;
8063 if (nunits.is_constant (&const_nunits))
8065 /* And again with the final element. */
8066 rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
8067 rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
8068 ASSERT_RTX_PTR_EQ (scalar_reg,
8069 simplify_binary_operation (VEC_SELECT, inner_mode,
8070 duplicate, last_par));
8072 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
8073 /* Skip this test for vectors of booleans, because offset is in bytes,
8074 while vec_merge indices are in elements (usually bits). */
8075 if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
8077 rtx vector_reg = make_test_reg (mode);
8078 for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
8080 if (i >= HOST_BITS_PER_WIDE_INT)
8081 break;
8082 rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
8083 rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
8084 poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
8086 ASSERT_RTX_EQ (scalar_reg,
8087 simplify_gen_subreg (inner_mode, vm,
8088 mode, offset));
8093 /* Test a scalar subreg of a VEC_DUPLICATE. */
8094 poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
8095 ASSERT_RTX_EQ (scalar_reg,
8096 simplify_gen_subreg (inner_mode, duplicate,
8097 mode, offset));
8099 machine_mode narrower_mode;
8100 if (maybe_ne (nunits, 2U)
8101 && multiple_p (nunits, 2)
8102 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
8103 && VECTOR_MODE_P (narrower_mode))
8105 /* Test VEC_DUPLICATE of a vector. */
8106 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
8107 nbuilder.quick_push (const0_rtx);
8108 nbuilder.quick_push (const1_rtx);
8109 rtx_vector_builder builder (mode, 2, 1);
8110 builder.quick_push (const0_rtx);
8111 builder.quick_push (const1_rtx);
8112 ASSERT_RTX_EQ (builder.build (),
8113 simplify_unary_operation (VEC_DUPLICATE, mode,
8114 nbuilder.build (),
8115 narrower_mode));
8117 /* Test VEC_SELECT of a vector. */
8118 rtx vec_par
8119 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
8120 rtx narrower_duplicate
8121 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
8122 ASSERT_RTX_EQ (narrower_duplicate,
8123 simplify_binary_operation (VEC_SELECT, narrower_mode,
8124 duplicate, vec_par));
8126 /* Test a vector subreg of a VEC_DUPLICATE. */
8127 poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
8128 ASSERT_RTX_EQ (narrower_duplicate,
8129 simplify_gen_subreg (narrower_mode, duplicate,
8130 mode, offset));
8134 /* Test vector simplifications involving VEC_SERIES in which the
8135 operands and result have vector mode MODE. SCALAR_REG is a pseudo
8136 register that holds one element of MODE. */
8138 static void
8139 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
8141 /* Test unary cases with VEC_SERIES arguments. */
8142 scalar_mode inner_mode = GET_MODE_INNER (mode);
8143 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8144 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8145 rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
8146 rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
8147 rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
8148 rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
8149 rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
8150 rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
8151 neg_scalar_reg);
8152 ASSERT_RTX_EQ (series_0_r,
8153 simplify_unary_operation (NEG, mode, series_0_nr, mode));
8154 ASSERT_RTX_EQ (series_r_m1,
8155 simplify_unary_operation (NEG, mode, series_nr_1, mode));
8156 ASSERT_RTX_EQ (series_r_r,
8157 simplify_unary_operation (NEG, mode, series_nr_nr, mode));
8159 /* Test that a VEC_SERIES with a zero step is simplified away. */
8160 ASSERT_RTX_EQ (duplicate,
8161 simplify_binary_operation (VEC_SERIES, mode,
8162 scalar_reg, const0_rtx));
8164 /* Test PLUS and MINUS with VEC_SERIES. */
8165 rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
8166 rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
8167 rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
8168 ASSERT_RTX_EQ (series_r_r,
8169 simplify_binary_operation (PLUS, mode, series_0_r,
8170 duplicate));
8171 ASSERT_RTX_EQ (series_r_1,
8172 simplify_binary_operation (PLUS, mode, duplicate,
8173 series_0_1));
8174 ASSERT_RTX_EQ (series_r_m1,
8175 simplify_binary_operation (PLUS, mode, duplicate,
8176 series_0_m1));
8177 ASSERT_RTX_EQ (series_0_r,
8178 simplify_binary_operation (MINUS, mode, series_r_r,
8179 duplicate));
8180 ASSERT_RTX_EQ (series_r_m1,
8181 simplify_binary_operation (MINUS, mode, duplicate,
8182 series_0_1));
8183 ASSERT_RTX_EQ (series_r_1,
8184 simplify_binary_operation (MINUS, mode, duplicate,
8185 series_0_m1));
8186 ASSERT_RTX_EQ (series_0_m1,
8187 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
8188 constm1_rtx));
8190 /* Test NEG on constant vector series. */
8191 ASSERT_RTX_EQ (series_0_m1,
8192 simplify_unary_operation (NEG, mode, series_0_1, mode));
8193 ASSERT_RTX_EQ (series_0_1,
8194 simplify_unary_operation (NEG, mode, series_0_m1, mode));
8196 /* Test PLUS and MINUS on constant vector series. */
8197 rtx scalar2 = gen_int_mode (2, inner_mode);
8198 rtx scalar3 = gen_int_mode (3, inner_mode);
8199 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
8200 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
8201 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
8202 ASSERT_RTX_EQ (series_1_1,
8203 simplify_binary_operation (PLUS, mode, series_0_1,
8204 CONST1_RTX (mode)));
8205 ASSERT_RTX_EQ (series_0_m1,
8206 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
8207 series_0_m1));
8208 ASSERT_RTX_EQ (series_1_3,
8209 simplify_binary_operation (PLUS, mode, series_1_1,
8210 series_0_2));
8211 ASSERT_RTX_EQ (series_0_1,
8212 simplify_binary_operation (MINUS, mode, series_1_1,
8213 CONST1_RTX (mode)));
8214 ASSERT_RTX_EQ (series_1_1,
8215 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
8216 series_0_m1));
8217 ASSERT_RTX_EQ (series_1_1,
8218 simplify_binary_operation (MINUS, mode, series_1_3,
8219 series_0_2));
8221 /* Test MULT between constant vectors. */
8222 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
8223 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
8224 rtx scalar9 = gen_int_mode (9, inner_mode);
8225 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
8226 ASSERT_RTX_EQ (series_0_2,
8227 simplify_binary_operation (MULT, mode, series_0_1, vec2));
8228 ASSERT_RTX_EQ (series_3_9,
8229 simplify_binary_operation (MULT, mode, vec3, series_1_3));
8230 if (!GET_MODE_NUNITS (mode).is_constant ())
8231 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
8232 series_0_1));
8234 /* Test ASHIFT between constant vectors. */
8235 ASSERT_RTX_EQ (series_0_2,
8236 simplify_binary_operation (ASHIFT, mode, series_0_1,
8237 CONST1_RTX (mode)));
8238 if (!GET_MODE_NUNITS (mode).is_constant ())
8239 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
8240 series_0_1));
8243 static rtx
8244 simplify_merge_mask (rtx x, rtx mask, int op)
8246 return simplify_context ().simplify_merge_mask (x, mask, op);
8249 /* Verify simplify_merge_mask works correctly. */
8251 static void
8252 test_vec_merge (machine_mode mode)
8254 rtx op0 = make_test_reg (mode);
8255 rtx op1 = make_test_reg (mode);
8256 rtx op2 = make_test_reg (mode);
8257 rtx op3 = make_test_reg (mode);
8258 rtx op4 = make_test_reg (mode);
8259 rtx op5 = make_test_reg (mode);
8260 rtx mask1 = make_test_reg (SImode);
8261 rtx mask2 = make_test_reg (SImode);
8262 rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
8263 rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
8264 rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
8266 /* Simple vec_merge. */
8267 ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
8268 ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
8269 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
8270 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
8272 /* Nested vec_merge.
8273 It's tempting to make this simplify right down to opN, but we don't
8274 because all the simplify_* functions assume that the operands have
8275 already been simplified. */
8276 rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
8277 ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
8278 ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
8280 /* Intermediate unary op. */
8281 rtx unop = gen_rtx_NOT (mode, vm1);
8282 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
8283 simplify_merge_mask (unop, mask1, 0));
8284 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
8285 simplify_merge_mask (unop, mask1, 1));
8287 /* Intermediate binary op. */
8288 rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
8289 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
8290 simplify_merge_mask (binop, mask1, 0));
8291 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
8292 simplify_merge_mask (binop, mask1, 1));
8294 /* Intermediate ternary op. */
8295 rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
8296 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
8297 simplify_merge_mask (tenop, mask1, 0));
8298 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
8299 simplify_merge_mask (tenop, mask1, 1));
8301 /* Side effects. */
8302 rtx badop0 = gen_rtx_PRE_INC (mode, op0);
8303 rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
8304 ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
8305 ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
8307 /* Called indirectly. */
8308 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
8309 simplify_rtx (nvm));
8312 /* Test subregs of integer vector constant X, trying elements in
8313 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
8314 where NELTS is the number of elements in X. Subregs involving
8315 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
8317 static void
8318 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
8319 unsigned int first_valid = 0)
8321 machine_mode inner_mode = GET_MODE (x);
8322 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8324 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
8326 machine_mode outer_mode = (machine_mode) modei;
8327 if (!VECTOR_MODE_P (outer_mode))
8328 continue;
8330 unsigned int outer_nunits;
8331 if (GET_MODE_INNER (outer_mode) == int_mode
8332 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
8333 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
8335 /* Test subregs in which the outer mode is a smaller,
8336 constant-sized vector of the same element type. */
8337 unsigned int limit
8338 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
8339 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
8341 rtx expected = NULL_RTX;
8342 if (elt >= first_valid)
8344 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
8345 for (unsigned int i = 0; i < outer_nunits; ++i)
8346 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
8347 expected = builder.build ();
8349 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
8350 ASSERT_RTX_EQ (expected,
8351 simplify_subreg (outer_mode, x,
8352 inner_mode, byte));
8355 else if (known_eq (GET_MODE_SIZE (outer_mode),
8356 GET_MODE_SIZE (inner_mode))
8357 && known_eq (elt_bias, 0U)
8358 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
8359 || known_eq (GET_MODE_BITSIZE (outer_mode),
8360 GET_MODE_NUNITS (outer_mode)))
8361 && (!FLOAT_MODE_P (outer_mode)
8362 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
8363 == GET_MODE_UNIT_PRECISION (outer_mode)))
8364 && (GET_MODE_SIZE (inner_mode).is_constant ()
8365 || !CONST_VECTOR_STEPPED_P (x)))
8367 /* Try converting to OUTER_MODE and back. */
8368 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
8369 ASSERT_TRUE (outer_x != NULL_RTX);
8370 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
8371 outer_mode, 0));
8375 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
8377 /* Test each byte in the element range. */
8378 unsigned int limit
8379 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
8380 for (unsigned int i = 0; i < limit; ++i)
8382 unsigned int elt = i / GET_MODE_SIZE (int_mode);
8383 rtx expected = NULL_RTX;
8384 if (elt >= first_valid)
8386 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
8387 if (BYTES_BIG_ENDIAN)
8388 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
8389 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
8390 wide_int shifted_elt
8391 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
8392 expected = immed_wide_int_const (shifted_elt, QImode);
8394 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
8395 ASSERT_RTX_EQ (expected,
8396 simplify_subreg (QImode, x, inner_mode, byte));
8401 /* Test constant subregs of integer vector mode INNER_MODE, using 1
8402 element per pattern. */
8404 static void
8405 test_vector_subregs_repeating (machine_mode inner_mode)
8407 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8408 unsigned int min_nunits = constant_lower_bound (nunits);
8409 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8410 unsigned int count = gcd (min_nunits, 8);
8412 rtx_vector_builder builder (inner_mode, count, 1);
8413 for (unsigned int i = 0; i < count; ++i)
8414 builder.quick_push (gen_int_mode (8 - i, int_mode));
8415 rtx x = builder.build ();
8417 test_vector_subregs_modes (x);
8418 if (!nunits.is_constant ())
8419 test_vector_subregs_modes (x, nunits - min_nunits);
8422 /* Test constant subregs of integer vector mode INNER_MODE, using 2
8423 elements per pattern. */
8425 static void
8426 test_vector_subregs_fore_back (machine_mode inner_mode)
8428 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8429 unsigned int min_nunits = constant_lower_bound (nunits);
8430 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8431 unsigned int count = gcd (min_nunits, 4);
8433 rtx_vector_builder builder (inner_mode, count, 2);
8434 for (unsigned int i = 0; i < count; ++i)
8435 builder.quick_push (gen_int_mode (i, int_mode));
8436 for (unsigned int i = 0; i < count; ++i)
8437 builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
8438 rtx x = builder.build ();
8440 test_vector_subregs_modes (x);
8441 if (!nunits.is_constant ())
8442 test_vector_subregs_modes (x, nunits - min_nunits, count);
8445 /* Test constant subregs of integer vector mode INNER_MODE, using 3
8446 elements per pattern. */
8448 static void
8449 test_vector_subregs_stepped (machine_mode inner_mode)
8451 /* Build { 0, 1, 2, 3, ... }. */
8452 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8453 rtx_vector_builder builder (inner_mode, 1, 3);
8454 for (unsigned int i = 0; i < 3; ++i)
8455 builder.quick_push (gen_int_mode (i, int_mode));
8456 rtx x = builder.build ();
8458 test_vector_subregs_modes (x);
8461 /* Test constant subregs of integer vector mode INNER_MODE. */
8463 static void
8464 test_vector_subregs (machine_mode inner_mode)
8466 test_vector_subregs_repeating (inner_mode);
8467 test_vector_subregs_fore_back (inner_mode);
8468 test_vector_subregs_stepped (inner_mode);
8471 /* Verify some simplifications involving vectors. */
8473 static void
8474 test_vector_ops ()
8476 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8478 machine_mode mode = (machine_mode) i;
8479 if (VECTOR_MODE_P (mode))
8481 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
8482 test_vector_ops_duplicate (mode, scalar_reg);
8483 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
8484 && maybe_gt (GET_MODE_NUNITS (mode), 2))
8486 test_vector_ops_series (mode, scalar_reg);
8487 test_vector_subregs (mode);
8489 test_vec_merge (mode);
8494 template<unsigned int N>
8495 struct simplify_const_poly_int_tests
8497 static void run ();
8500 template<>
8501 struct simplify_const_poly_int_tests<1>
8503 static void run () {}
8506 /* Test various CONST_POLY_INT properties. */
8508 template<unsigned int N>
8509 void
8510 simplify_const_poly_int_tests<N>::run ()
8512 rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
8513 rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
8514 rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
8515 rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
8516 rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
8517 rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
8518 rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
8519 rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
8520 rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
8521 rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
8522 rtx two = GEN_INT (2);
8523 rtx six = GEN_INT (6);
8524 poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
8526 /* These tests only try limited operation combinations. Fuller arithmetic
8527 testing is done directly on poly_ints. */
8528 ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
8529 ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
8530 ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
8531 ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
8532 ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
8533 ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
8534 ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
8535 ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
8536 ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
8537 ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
8538 ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
8541 /* Run all of the selftests within this file. */
8543 void
8544 simplify_rtx_cc_tests ()
8546 test_scalar_ops ();
8547 test_vector_ops ();
8548 simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
8551 } // namespace selftest
8553 #endif /* CHECKING_P */