Line data Source code
1 : /* RTL simplification functions for GNU compiler.
2 : Copyright (C) 1987-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
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.
10 :
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.
15 :
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/>. */
19 :
20 :
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"
40 :
41 : /* Simplification and canonicalization of RTL. */
42 :
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)
49 :
50 : static bool plus_minus_operand_p (const_rtx);
51 :
52 : /* Negate I, which satisfies poly_int_rtx_p. MODE is the mode of I. */
53 :
54 : static rtx
55 8774464 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 8774464 : return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
58 : }
59 :
60 : /* Test whether expression, X, is an immediate constant that represents
61 : the most significant bit of machine mode MODE. */
62 :
63 : bool
64 6182755 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6182755 : unsigned HOST_WIDE_INT val;
67 6182755 : unsigned int width;
68 6182755 : scalar_int_mode int_mode;
69 :
70 6182755 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6182747 : width = GET_MODE_PRECISION (int_mode);
74 6182747 : if (width == 0)
75 : return false;
76 :
77 6182747 : if (width <= HOST_BITS_PER_WIDE_INT
78 6181200 : && CONST_INT_P (x))
79 6029745 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 153002 : else if (CONST_WIDE_INT_P (x))
82 : {
83 483 : unsigned int i;
84 483 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 483 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : return false;
87 906 : for (i = 0; i < elts - 1; i++)
88 483 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : return false;
90 423 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 423 : width %= HOST_BITS_PER_WIDE_INT;
92 423 : if (width == 0)
93 : width = HOST_BITS_PER_WIDE_INT;
94 : }
95 : #else
96 : else if (width <= HOST_BITS_PER_DOUBLE_INT
97 : && CONST_DOUBLE_AS_INT_P (x)
98 : && CONST_DOUBLE_LOW (x) == 0)
99 : {
100 : val = CONST_DOUBLE_HIGH (x);
101 : width -= HOST_BITS_PER_WIDE_INT;
102 : }
103 : #endif
104 : else
105 : /* X is not an integer constant. */
106 : return false;
107 :
108 6029745 : if (width < HOST_BITS_PER_WIDE_INT)
109 5466452 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6030168 : return val == (HOST_WIDE_INT_1U << (width - 1));
111 : }
112 :
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. */
116 :
117 : bool
118 3592638 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3592638 : unsigned int width;
121 3592638 : scalar_int_mode int_mode;
122 :
123 3592638 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3592602 : width = GET_MODE_PRECISION (int_mode);
127 3592602 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3587752 : val &= GET_MODE_MASK (int_mode);
131 3587752 : return val == (HOST_WIDE_INT_1U << (width - 1));
132 : }
133 :
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 2620970 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2620970 : unsigned int width;
140 :
141 2620970 : scalar_int_mode int_mode;
142 2620970 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2587825 : width = GET_MODE_PRECISION (int_mode);
146 2587825 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2587825 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2587825 : return val != 0;
151 : }
152 :
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 7518023 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7518023 : unsigned int width;
159 :
160 7518023 : scalar_int_mode int_mode;
161 7518023 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7179316 : width = GET_MODE_PRECISION (int_mode);
165 7179316 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7068589 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7068589 : return val == 0;
170 : }
171 :
172 : /* Make a binary operation by properly ordering the operands and
173 : seeing if the expression folds. */
174 :
175 : rtx
176 117962888 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 117962888 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 117962888 : tem = simplify_binary_operation (code, mode, op0, op1);
183 117962888 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 74898733 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 74898733 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 74898733 : return gen_rtx_fmt_ee (code, mode, op0, op1);
192 : }
193 :
194 : /* If X is a MEM referencing the constant pool, return the real value.
195 : Otherwise return X. */
196 : rtx
197 2704407062 : avoid_constant_pool_reference (rtx x)
198 : {
199 2704407062 : rtx c, tmp, addr;
200 2704407062 : machine_mode cmode;
201 2704407062 : poly_int64 offset = 0;
202 :
203 2704407062 : switch (GET_CODE (x))
204 : {
205 256405647 : case MEM:
206 256405647 : break;
207 :
208 917087 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 917087 : tmp = XEXP (x, 0);
211 917087 : c = avoid_constant_pool_reference (tmp);
212 917087 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 123483 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 123483 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 256405647 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 252350181 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 252350181 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 252350181 : addr = strip_offset (addr, &offset);
231 :
232 252350181 : if (GET_CODE (addr) == LO_SUM)
233 0 : addr = XEXP (addr, 1);
234 :
235 : /* If this is a constant pool reference, we can turn it into its
236 : constant and hope that simplifications happen. */
237 252350181 : if (GET_CODE (addr) == SYMBOL_REF
238 252350181 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5323723 : c = get_pool_constant (addr);
241 5323723 : cmode = get_pool_mode (addr);
242 :
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 5323723 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 26050 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 13025 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 13025 : if (tem && CONSTANT_P (tem))
252 : return tem;
253 : }
254 : }
255 :
256 : return x;
257 : }
258 :
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. */
262 :
263 : rtx
264 3534622840 : delegitimize_mem_from_attrs (rtx x)
265 : {
266 : /* MEMs without MEM_OFFSETs may have been offset, so we can't just
267 : use their base addresses as equivalent. */
268 3534622840 : if (MEM_P (x)
269 61798783 : && MEM_EXPR (x)
270 3572524536 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 35059594 : tree decl = MEM_EXPR (x);
273 35059594 : machine_mode mode = GET_MODE (x);
274 35059594 : poly_int64 offset = 0;
275 :
276 35059594 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 9981973 : case ARRAY_REF:
286 9981973 : case ARRAY_RANGE_REF:
287 9981973 : case COMPONENT_REF:
288 9981973 : case BIT_FIELD_REF:
289 9981973 : case REALPART_EXPR:
290 9981973 : case IMAGPART_EXPR:
291 9981973 : case VIEW_CONVERT_EXPR:
292 9981973 : {
293 9981973 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 9981973 : tree toffset;
295 9981973 : int unsignedp, reversep, volatilep = 0;
296 :
297 9981973 : decl
298 9981973 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 19963946 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10269709 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 19524326 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9254617 : offset += bytepos + toffset_val;
306 9981973 : break;
307 : }
308 : }
309 :
310 727356 : if (decl
311 20634296 : && mode == GET_MODE (x)
312 20363716 : && VAR_P (decl)
313 13254709 : && (TREE_STATIC (decl)
314 12039349 : || DECL_THREAD_LOCAL_P (decl))
315 1251393 : && DECL_RTL_SET_P (decl)
316 10505510 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1250893 : rtx newx;
319 :
320 1250893 : offset += MEM_OFFSET (x);
321 :
322 1250893 : newx = DECL_RTL (decl);
323 :
324 1250893 : if (MEM_P (newx))
325 : {
326 1250893 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1250893 : poly_int64 n_offset, o_offset;
328 :
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 1250893 : n = strip_offset (n, &n_offset);
336 1250893 : o = strip_offset (o, &o_offset);
337 2474105 : if (!(known_eq (o_offset, n_offset + offset)
338 1223212 : && rtx_equal_p (o, n)))
339 211528 : x = adjust_address_nv (newx, mode, offset);
340 : }
341 0 : else if (GET_MODE (x) == GET_MODE (newx)
342 0 : && known_eq (offset, 0))
343 : x = newx;
344 : }
345 : }
346 :
347 3534622840 : return x;
348 : }
349 :
350 : /* Make a unary operation by first seeing if it folds and otherwise making
351 : the specified operation. */
352 :
353 : rtx
354 6300191 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 6300191 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 6300191 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 2276187 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2230487 : simplify_context::simplify_gen_ternary (rtx_code code, machine_mode mode,
370 : machine_mode op0_mode,
371 : rtx op0, rtx op1, rtx op2)
372 : {
373 2230487 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2230487 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 1984879 : return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
381 : }
382 :
383 : /* Likewise, for relational operations.
384 : CMP_MODE specifies mode comparison is done in. */
385 :
386 : rtx
387 21151110 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 21151110 : rtx tem;
392 :
393 21151110 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 18987723 : return gen_rtx_fmt_ee (code, mode, op0, op1);
398 : }
399 :
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. */
404 :
405 : rtx
406 474807824 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 474807824 : enum rtx_code code = GET_CODE (x);
410 474807824 : machine_mode mode = GET_MODE (x);
411 474807824 : machine_mode op_mode;
412 474807824 : const char *fmt;
413 474807824 : rtx op0, op1, op2, newx, op;
414 474807824 : rtvec vec, newvec;
415 474807824 : int i, j;
416 :
417 474807824 : if (UNLIKELY (fn != NULL))
418 : {
419 412018006 : newx = fn (x, old_rtx, data);
420 412018006 : if (newx)
421 : return newx;
422 : }
423 62789818 : else if (rtx_equal_p (x, old_rtx))
424 5171280 : return copy_rtx ((rtx) data);
425 :
426 372485149 : switch (GET_RTX_CLASS (code))
427 : {
428 1968568 : case RTX_UNARY:
429 1968568 : op0 = XEXP (x, 0);
430 1968568 : op_mode = GET_MODE (op0);
431 1968568 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 1968568 : if (op0 == XEXP (x, 0))
433 : return x;
434 643975 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 73739434 : case RTX_BIN_ARITH:
437 73739434 : case RTX_COMM_ARITH:
438 73739434 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 73739434 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 73739434 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 22660917 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 9702391 : case RTX_COMPARE:
445 9702391 : case RTX_COMM_COMPARE:
446 9702391 : op0 = XEXP (x, 0);
447 9702391 : op1 = XEXP (x, 1);
448 9702391 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 9702391 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 9702391 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 9702391 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2345103 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 5664344 : case RTX_TERNARY:
456 5664344 : case RTX_BITFIELD_OPS:
457 5664344 : op0 = XEXP (x, 0);
458 5664344 : op_mode = GET_MODE (op0);
459 5664344 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 5664344 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 5664344 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 5664344 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 1650165 : if (op_mode == VOIDmode)
465 1628782 : op_mode = GET_MODE (op0);
466 1650165 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 80644537 : case RTX_EXTRA:
469 80644537 : if (code == SUBREG)
470 : {
471 621334 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 621334 : if (op0 == SUBREG_REG (x))
473 : return x;
474 128988 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 64494 : GET_MODE (SUBREG_REG (x)),
476 64494 : SUBREG_BYTE (x));
477 64494 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 60485413 : case RTX_OBJ:
482 60485413 : if (code == MEM)
483 : {
484 10680103 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10680103 : if (op0 == XEXP (x, 0))
486 : return x;
487 158815 : return replace_equiv_address_nv (x, op0);
488 : }
489 49805310 : else if (code == LO_SUM)
490 : {
491 0 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
492 0 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
493 :
494 : /* (lo_sum (high x) y) -> y where x and y have the same base. */
495 0 : if (GET_CODE (op0) == HIGH)
496 : {
497 0 : rtx base0, base1, offset0, offset1;
498 0 : split_const (XEXP (op0, 0), &base0, &offset0);
499 0 : split_const (op1, &base1, &offset1);
500 0 : if (rtx_equal_p (base0, base1))
501 0 : return op1;
502 : }
503 :
504 0 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
505 : return x;
506 0 : return gen_rtx_LO_SUM (mode, op0, op1);
507 : }
508 : break;
509 :
510 : default:
511 : break;
512 : }
513 :
514 270108975 : newx = x;
515 270108975 : fmt = GET_RTX_FORMAT (code);
516 583178355 : for (i = 0; fmt[i]; i++)
517 313069380 : switch (fmt[i])
518 : {
519 3128598 : case 'E':
520 3128598 : vec = XVEC (x, i);
521 3128598 : newvec = XVEC (newx, i);
522 12998982 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 9870384 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 9870384 : if (op != RTVEC_ELT (vec, j))
527 : {
528 343455 : if (newvec == vec)
529 : {
530 332919 : newvec = shallow_copy_rtvec (vec);
531 332919 : if (x == newx)
532 332919 : newx = shallow_copy_rtx (x);
533 332919 : XVEC (newx, i) = newvec;
534 : }
535 343455 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 72938755 : case 'e':
541 72938755 : if (XEXP (x, i))
542 : {
543 72938755 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 72938755 : if (op != XEXP (x, i))
545 : {
546 4128109 : if (x == newx)
547 4124846 : newx = shallow_copy_rtx (x);
548 4128109 : XEXP (newx, i) = op;
549 : }
550 : }
551 : break;
552 : }
553 : return newx;
554 : }
555 :
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. */
558 :
559 : rtx
560 12905953 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 12905953 : return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
563 : }
564 :
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.
567 :
568 : RTL provides two ways of truncating a value:
569 :
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.
574 :
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.
580 :
581 : 2. a TRUNCATE. This form handles both scalar and compound integers.
582 :
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:
587 :
588 : simplify_gen_unary (TRUNCATE, ...)
589 :
590 : and leave simplify_unary_operation to work out which representation
591 : should be used.
592 :
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:
598 :
599 : (and:DI X Y)
600 :
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:
605 :
606 : (and:DI (reg:DI X) (const_int 63))
607 :
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. */
611 :
612 : rtx
613 20509438 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 20509438 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 20509438 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 20509438 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 20509438 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 20509438 : if (GET_CODE (op) == ZERO_EXTEND
624 20509438 : || GET_CODE (op) == SIGN_EXTEND)
625 : {
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 273460 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 273460 : if (mode == origmode)
634 : return XEXP (op, 0);
635 20894 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 7677 : return simplify_gen_unary (TRUNCATE, mode,
637 7677 : XEXP (op, 0), origmode);
638 : else
639 2770 : return simplify_gen_unary (GET_CODE (op), mode,
640 2770 : XEXP (op, 0), origmode);
641 : }
642 :
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 20235978 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 20235978 : || GET_CODE (op) == MULT))
651 : {
652 1161198 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 1161198 : if (op0)
654 : {
655 1161198 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 1161198 : if (op1)
657 1161198 : return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
658 : }
659 : }
660 :
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 19074780 : if ((GET_CODE (op) == LSHIFTRT
665 19074780 : || 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 1688111 : && 2 * precision <= op_precision
671 1688111 : && CONST_INT_P (XEXP (op, 1))
672 1591314 : && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
673 31 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
674 28 : && UINTVAL (XEXP (op, 1)) < precision)
675 24 : return simplify_gen_binary (ASHIFTRT, mode,
676 24 : XEXP (XEXP (op, 0), 0), XEXP (op, 1));
677 :
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 19074756 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1688087 : && CONST_INT_P (XEXP (op, 1))
684 1591290 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 732 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 732 : && UINTVAL (XEXP (op, 1)) < precision)
687 722 : return simplify_gen_binary (LSHIFTRT, mode,
688 722 : XEXP (XEXP (op, 0), 0), XEXP (op, 1));
689 :
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 19074034 : if (GET_CODE (op) == ASHIFT
694 702956 : && CONST_INT_P (XEXP (op, 1))
695 643289 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 643289 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 772 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 759 : && UINTVAL (XEXP (op, 1)) < precision)
699 714 : return simplify_gen_binary (ASHIFT, mode,
700 714 : XEXP (XEXP (op, 0), 0), XEXP (op, 1));
701 :
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 19073320 : if (GET_CODE (op) == AND
706 734375 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 734375 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 31243 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 31128 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 31128 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 31128 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 31128 : rtx mask_op = XEXP (op, 1);
714 31128 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 31128 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 31128 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 17867 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 17867 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 3211 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 34339 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 3211 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 3211 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : }
728 : }
729 :
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 19070109 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 368142 : && REG_P (XEXP (op, 0))
735 253166 : && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 252320 : && CONST_INT_P (XEXP (op, 1))
737 252320 : && CONST_INT_P (XEXP (op, 2)))
738 : {
739 220702 : rtx op0 = XEXP (op, 0);
740 220702 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 220702 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 220702 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
743 : {
744 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 : if (op0)
746 : {
747 : pos -= op_precision - precision;
748 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 : XEXP (op, 1), GEN_INT (pos));
750 : }
751 : }
752 220702 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
753 : {
754 7751 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 7751 : if (op0)
756 7751 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 7751 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 19062358 : if ((GET_CODE (op) == LSHIFTRT
763 19062358 : || GET_CODE (op) == ASHIFTRT)
764 1687365 : && SCALAR_INT_MODE_P (mode)
765 1684206 : && SCALAR_INT_MODE_P (op_mode)
766 1819841 : && precision >= BITS_PER_WORD
767 60471 : && 2 * precision <= op_precision
768 60471 : && CONST_INT_P (XEXP (op, 1))
769 51644 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 1829 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 1829 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 1829 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 1829 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 1829 : ? byte - shifted_bytes
777 1829 : : byte + shifted_bytes));
778 : }
779 :
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 19060529 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1682377 : && is_a <scalar_int_mode> (mode, &int_mode)
786 20741691 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1682377 : && MEM_P (XEXP (op, 0))
788 11536 : && CONST_INT_P (XEXP (op, 1))
789 21356 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 1258 : && INTVAL (XEXP (op, 1)) > 0
791 2516 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 1258 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 1258 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 1258 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 19060529 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 1215 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 1215 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 1215 : return adjust_address_nv (XEXP (op, 0), int_mode,
801 : (WORDS_BIG_ENDIAN
802 : ? byte - shifted_bytes
803 : : byte + shifted_bytes));
804 : }
805 :
806 : /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
807 : (OP:SI foo:SI) if OP is NEG or ABS. */
808 19059314 : if ((GET_CODE (op) == ABS
809 19059314 : || GET_CODE (op) == NEG)
810 20879 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 20879 : || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 17 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 1 : return simplify_gen_unary (GET_CODE (op), mode,
814 1 : XEXP (XEXP (op, 0), 0), mode);
815 :
816 : /* Simplifications of (truncate:A (subreg:B X 0)). */
817 19059313 : if (GET_CODE (op) == SUBREG
818 19059490 : && is_a <scalar_int_mode> (mode, &int_mode)
819 28427 : && SCALAR_INT_MODE_P (op_mode)
820 28427 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 19087600 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 28284 : if (GET_CODE (SUBREG_REG (op)) == TRUNCATE)
825 : {
826 0 : rtx inner = XEXP (SUBREG_REG (op), 0);
827 0 : if (GET_MODE_PRECISION (int_mode)
828 0 : <= GET_MODE_PRECISION (subreg_mode))
829 0 : return simplify_gen_unary (TRUNCATE, int_mode, inner,
830 0 : 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 0 : return simplify_gen_subreg (int_mode, SUBREG_REG (op),
835 : subreg_mode, 0);
836 : }
837 :
838 : /* Simplifications of (truncate:A (subreg:B X:C 0)) with
839 : paradoxical subregs (B is wider than C). */
840 28284 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 28284 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 28284 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 28284 : if (int_op_prec > subreg_prec)
845 : {
846 1489 : if (int_mode == subreg_mode)
847 : return SUBREG_REG (op);
848 61 : if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 27 : return simplify_gen_unary (TRUNCATE, int_mode,
850 27 : SUBREG_REG (op), subreg_mode);
851 : }
852 : /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 : A is narrower than B and B is narrower than C. */
854 26795 : else if (int_op_prec < subreg_prec
855 26795 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 26795 : return simplify_gen_unary (TRUNCATE, int_mode,
857 26795 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 19031063 : if (GET_CODE (op) == TRUNCATE)
863 0 : return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
864 0 : GET_MODE (XEXP (op, 0)));
865 :
866 : /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
867 : in mode A. */
868 19031063 : if (GET_CODE (op) == IOR
869 34995 : && SCALAR_INT_MODE_P (mode)
870 34995 : && SCALAR_INT_MODE_P (op_mode)
871 34995 : && CONST_INT_P (XEXP (op, 1))
872 19039849 : && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
873 42 : return constm1_rtx;
874 :
875 : return NULL_RTX;
876 : }
877 :
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. */
881 : rtx
882 28092245 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 28092245 : rtx trueop, tem;
886 :
887 28092245 : trueop = avoid_constant_pool_reference (op);
888 :
889 28092245 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 28092245 : if (tem)
891 : return tem;
892 :
893 22877478 : return simplify_unary_operation_1 (code, mode, op);
894 : }
895 :
896 : /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
897 : to be exact. */
898 :
899 : static bool
900 2684 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2684 : 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 2684 : if (op0_mode == VOIDmode)
906 : return false;
907 5366 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2683 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2683 : int in_bits = in_prec;
910 2683 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2593 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2593 : if (GET_CODE (op) == FLOAT)
914 2469 : in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 124 : else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 124 : in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 : else
918 0 : gcc_unreachable ();
919 2593 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2683 : return in_bits <= out_bits;
922 : }
923 :
924 : /* Perform some simplifications we can do even if the operands
925 : aren't constant. */
926 : rtx
927 22877478 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 22877478 : enum rtx_code reversed;
931 22877478 : rtx temp, elt, base, step;
932 22877478 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 22877478 : switch (code)
935 : {
936 2165665 : case NOT:
937 : /* (not (not X)) == X. */
938 2165665 : if (GET_CODE (op) == NOT)
939 3085 : return XEXP (op, 0);
940 :
941 : /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
942 : comparison is all ones. */
943 2162580 : if (COMPARISON_P (op)
944 13788 : && (mode == BImode || STORE_FLAG_VALUE == -1)
945 2162580 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
946 0 : return simplify_gen_relational (reversed, mode, VOIDmode,
947 0 : XEXP (op, 0), XEXP (op, 1));
948 :
949 : /* (not (plus X -1)) can become (neg X). */
950 2162580 : if (GET_CODE (op) == PLUS
951 287984 : && XEXP (op, 1) == constm1_rtx)
952 4537 : return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
953 :
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 2158043 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 70604 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 70604 : CONSTM1_RTX (mode));
960 :
961 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 2087439 : if (GET_CODE (op) == XOR
963 16078 : && CONST_INT_P (XEXP (op, 1))
964 2091453 : && (temp = simplify_unary_operation (NOT, mode,
965 : XEXP (op, 1), mode)) != 0)
966 4014 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
967 :
968 : /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
969 2083425 : if (GET_CODE (op) == PLUS
970 283447 : && CONST_INT_P (XEXP (op, 1))
971 165517 : && mode_signbit_p (mode, XEXP (op, 1))
972 2087120 : && (temp = simplify_unary_operation (NOT, mode,
973 : XEXP (op, 1), mode)) != 0)
974 3695 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
975 :
976 :
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 2079730 : if (GET_CODE (op) == ASHIFT
983 36543 : && XEXP (op, 0) == const1_rtx)
984 : {
985 1031 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 1031 : return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
987 : }
988 :
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 2078699 : 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);
999 :
1000 :
1001 2078699 : if (partial_subreg_p (op)
1002 438449 : && subreg_lowpart_p (op)
1003 438141 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 458366 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1005 : {
1006 163 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1007 163 : rtx x;
1008 :
1009 163 : 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 163 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1014 163 : if (temp)
1015 : return temp;
1016 : }
1017 :
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 2078536 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1023 : {
1024 12120 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 12120 : machine_mode op_mode;
1026 :
1027 12120 : op_mode = GET_MODE (in1);
1028 12120 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1029 :
1030 12120 : op_mode = GET_MODE (in2);
1031 12120 : if (op_mode == VOIDmode)
1032 5351 : op_mode = mode;
1033 12120 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1034 :
1035 12120 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 : std::swap (in1, in2);
1037 :
1038 24240 : return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1039 : mode, in1, in2);
1040 : }
1041 :
1042 : /* (not (bswap x)) -> (bswap (not x)). */
1043 2066416 : if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
1044 : {
1045 0 : rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1046 0 : return simplify_gen_unary (GET_CODE (op), mode, x, mode);
1047 : }
1048 : break;
1049 :
1050 1718242 : case NEG:
1051 : /* (neg (neg X)) == X. */
1052 1718242 : if (GET_CODE (op) == NEG)
1053 6280 : return XEXP (op, 0);
1054 :
1055 : /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1056 : If comparison is not reversible use
1057 : x ? y : (neg y). */
1058 1711962 : if (GET_CODE (op) == IF_THEN_ELSE)
1059 : {
1060 3089 : rtx cond = XEXP (op, 0);
1061 3089 : rtx true_rtx = XEXP (op, 1);
1062 3089 : rtx false_rtx = XEXP (op, 2);
1063 :
1064 3089 : if ((GET_CODE (true_rtx) == NEG
1065 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 3089 : || (GET_CODE (false_rtx) == NEG
1067 0 : && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1068 : {
1069 0 : if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1070 0 : temp = reversed_comparison (cond, mode);
1071 : else
1072 : {
1073 : temp = cond;
1074 : std::swap (true_rtx, false_rtx);
1075 : }
1076 0 : return simplify_gen_ternary (IF_THEN_ELSE, mode,
1077 0 : mode, temp, true_rtx, false_rtx);
1078 : }
1079 : }
1080 :
1081 : /* (neg (plus X 1)) can become (not X). */
1082 1711962 : if (GET_CODE (op) == PLUS
1083 137572 : && XEXP (op, 1) == const1_rtx)
1084 52954 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1085 :
1086 : /* Similarly, (neg (not X)) is (plus X 1). */
1087 1659008 : if (GET_CODE (op) == NOT)
1088 375 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 375 : CONST1_RTX (mode));
1090 :
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 1658633 : if (GET_CODE (op) == MINUS
1097 24159 : && !HONOR_SIGNED_ZEROS (mode)
1098 1681410 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 22777 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1100 :
1101 1635856 : if (GET_CODE (op) == PLUS
1102 84618 : && !HONOR_SIGNED_ZEROS (mode)
1103 1720050 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1104 : {
1105 : /* (neg (plus A C)) is simplified to (minus -C A). */
1106 84194 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 6326 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1108 : {
1109 77868 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 77868 : if (temp)
1111 77868 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1112 : }
1113 :
1114 : /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1115 6326 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 6326 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1117 : }
1118 :
1119 : /* (neg (mult A B)) becomes (mult A (neg B)).
1120 : This works even for floating-point values. */
1121 1551662 : if (GET_CODE (op) == MULT
1122 1551662 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 : {
1124 20066 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 20066 : return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1126 : }
1127 :
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 1531596 : if (GET_CODE (op) == ASHIFT)
1132 : {
1133 53312 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 53312 : if (temp)
1135 12556 : return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1136 : }
1137 :
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 1519040 : if (GET_CODE (op) == ASHIFTRT
1141 28613 : && CONST_INT_P (XEXP (op, 1))
1142 1576170 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1143 691 : return simplify_gen_binary (LSHIFTRT, mode,
1144 691 : XEXP (op, 0), XEXP (op, 1));
1145 :
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 1518349 : if (GET_CODE (op) == LSHIFTRT
1149 8733 : && CONST_INT_P (XEXP (op, 1))
1150 1535647 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 3358 : return simplify_gen_binary (ASHIFTRT, mode,
1152 3358 : XEXP (op, 0), XEXP (op, 1));
1153 :
1154 : /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1155 1514991 : if (GET_CODE (op) == XOR
1156 10385 : && XEXP (op, 1) == const1_rtx
1157 1515102 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 32 : return plus_constant (mode, XEXP (op, 0), -1);
1159 :
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 1514959 : if (GET_CODE (op) == LT
1163 2726 : && XEXP (op, 1) == const0_rtx
1164 1516903 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1165 : {
1166 355 : int_mode = as_a <scalar_int_mode> (mode);
1167 355 : int isize = GET_MODE_PRECISION (inner);
1168 355 : if (STORE_FLAG_VALUE == 1)
1169 : {
1170 355 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1171 : gen_int_shift_amount (inner,
1172 355 : isize - 1));
1173 355 : if (int_mode == inner)
1174 : return temp;
1175 190 : if (GET_MODE_PRECISION (int_mode) > isize)
1176 129 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1177 61 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1178 : }
1179 : else if (STORE_FLAG_VALUE == -1)
1180 : {
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);
1189 : }
1190 : }
1191 :
1192 1514604 : if (vec_series_p (op, &base, &step))
1193 : {
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 276 : scalar_mode inner_mode = GET_MODE_INNER (mode);
1198 276 : base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1199 276 : if (base)
1200 : {
1201 276 : step = simplify_unary_operation (NEG, inner_mode,
1202 : step, inner_mode);
1203 276 : if (step)
1204 276 : return gen_vec_series (mode, base, step);
1205 : }
1206 : }
1207 : break;
1208 :
1209 1750464 : case TRUNCATE:
1210 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 : with the umulXi3_highpart patterns. */
1212 1750464 : if (GET_CODE (op) == LSHIFTRT
1213 18910 : && GET_CODE (XEXP (op, 0)) == MULT)
1214 : break;
1215 :
1216 1743134 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1217 : {
1218 12 : if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1219 : {
1220 12 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1221 12 : if (temp)
1222 : return temp;
1223 : }
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;
1228 : }
1229 :
1230 1743122 : if (GET_MODE (op) != VOIDmode)
1231 : {
1232 1743122 : temp = simplify_truncation (mode, op, GET_MODE (op));
1233 1743122 : if (temp)
1234 : return temp;
1235 : }
1236 :
1237 : /* If we know that the value is already truncated, we can
1238 : replace the TRUNCATE with a SUBREG. */
1239 1625266 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 1625266 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 0 : || truncated_to_mode (mode, op)))
1242 : {
1243 1612583 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 1612583 : if (temp)
1245 : return temp;
1246 : }
1247 :
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 12877 : if (HWI_COMPUTABLE_MODE_P (mode)
1253 194 : && COMPARISON_P (op)
1254 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 12877 : && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1256 : {
1257 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1258 0 : if (temp)
1259 : return temp;
1260 : }
1261 :
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 12877 : if (GET_CODE (op) == MEM
1265 317 : && !VECTOR_MODE_P (mode)
1266 192 : && !MEM_VOLATILE_P (op)
1267 13063 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1268 : {
1269 186 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 186 : if (temp)
1271 : return temp;
1272 : }
1273 :
1274 : /* Check for useless truncation. */
1275 12877 : if (GET_MODE (op) == mode)
1276 : return op;
1277 : break;
1278 :
1279 172576 : case FLOAT_TRUNCATE:
1280 : /* Check for useless truncation. */
1281 172576 : if (GET_MODE (op) == mode)
1282 : return op;
1283 :
1284 172576 : if (DECIMAL_FLOAT_MODE_P (mode))
1285 : break;
1286 :
1287 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 172422 : if (GET_CODE (op) == FLOAT_EXTEND
1289 5 : && GET_MODE (XEXP (op, 0)) == mode)
1290 : return XEXP (op, 0);
1291 :
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.
1295 :
1296 : (float_truncate:SF (float_extend:XF foo:DF))
1297 : = (float_truncate:SF foo:DF).
1298 :
1299 : (float_truncate:DF (float_extend:XF foo:SF))
1300 : = (float_extend:DF foo:SF). */
1301 172420 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 145 : && flag_unsafe_math_optimizations)
1303 172416 : || GET_CODE (op) == FLOAT_EXTEND)
1304 14 : return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1305 7 : > GET_MODE_UNIT_SIZE (mode)
1306 : ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1307 : mode,
1308 14 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1309 :
1310 : /* (float_truncate (float x)) is (float x) */
1311 172413 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 172413 : && (flag_unsafe_math_optimizations
1313 1401 : || exact_int_to_float_conversion_p (op)))
1314 1400 : return simplify_gen_unary (GET_CODE (op), mode,
1315 : XEXP (op, 0),
1316 1400 : GET_MODE (XEXP (op, 0)));
1317 :
1318 : /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1319 : (OP:SF foo:SF) if OP is NEG or ABS. */
1320 171013 : if ((GET_CODE (op) == ABS
1321 171013 : || GET_CODE (op) == NEG)
1322 209 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1323 28 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1324 28 : return simplify_gen_unary (GET_CODE (op), mode,
1325 28 : XEXP (XEXP (op, 0), 0), mode);
1326 :
1327 : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1328 : is (float_truncate:SF x). */
1329 170985 : if (GET_CODE (op) == SUBREG
1330 307 : && subreg_lowpart_p (op)
1331 171289 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 : return SUBREG_REG (op);
1333 : break;
1334 :
1335 592109 : case FLOAT_EXTEND:
1336 : /* Check for useless extension. */
1337 592109 : if (GET_MODE (op) == mode)
1338 : return op;
1339 :
1340 592109 : if (DECIMAL_FLOAT_MODE_P (mode))
1341 : break;
1342 :
1343 : /* (float_extend (float_extend x)) is (float_extend x)
1344 :
1345 : (float_extend (float x)) is (float x) assuming that double
1346 : rounding can't happen.
1347 : */
1348 592006 : if (GET_CODE (op) == FLOAT_EXTEND
1349 592006 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 1283 : && exact_int_to_float_conversion_p (op)))
1351 569 : return simplify_gen_unary (GET_CODE (op), mode,
1352 : XEXP (op, 0),
1353 569 : GET_MODE (XEXP (op, 0)));
1354 :
1355 : break;
1356 :
1357 312143 : case ABS:
1358 : /* (abs (neg <foo>)) -> (abs <foo>) */
1359 312143 : if (GET_CODE (op) == NEG)
1360 29 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1361 29 : GET_MODE (XEXP (op, 0)));
1362 :
1363 : /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1364 : do nothing. */
1365 312114 : if (GET_MODE (op) == VOIDmode)
1366 : break;
1367 :
1368 : /* If operand is something known to be positive, ignore the ABS. */
1369 312114 : if (val_signbit_known_clear_p (GET_MODE (op),
1370 : nonzero_bits (op, GET_MODE (op))))
1371 : return op;
1372 :
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 311896 : switch (GET_CODE (op))
1377 : {
1378 : case ABS:
1379 : case CLRSB:
1380 : case FFS:
1381 : case PARITY:
1382 : case POPCOUNT:
1383 : case SS_ABS:
1384 : return op;
1385 :
1386 0 : case LSHIFTRT:
1387 0 : if (CONST_INT_P (XEXP (op, 1))
1388 0 : && INTVAL (XEXP (op, 1)) > 0
1389 311896 : && is_a <scalar_int_mode> (mode, &int_mode)
1390 0 : && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1391 : return op;
1392 : break;
1393 :
1394 : default:
1395 : break;
1396 : }
1397 :
1398 : /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1399 311896 : if (is_a <scalar_int_mode> (mode, &int_mode)
1400 55795 : && (num_sign_bit_copies (op, int_mode)
1401 55795 : == GET_MODE_PRECISION (int_mode)))
1402 74 : return gen_rtx_NEG (int_mode, op);
1403 :
1404 : break;
1405 :
1406 0 : case FFS:
1407 : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1408 0 : if (GET_CODE (op) == SIGN_EXTEND
1409 0 : || GET_CODE (op) == ZERO_EXTEND)
1410 : {
1411 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1412 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1413 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1414 0 : GET_MODE (temp));
1415 : }
1416 : break;
1417 :
1418 3445 : case POPCOUNT:
1419 3445 : switch (GET_CODE (op))
1420 : {
1421 0 : case BSWAP:
1422 0 : case BITREVERSE:
1423 : /* (popcount (bswap <X>)) = (popcount <X>). */
1424 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1425 0 : GET_MODE (XEXP (op, 0)));
1426 :
1427 44 : case ZERO_EXTEND:
1428 : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1429 88 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1430 44 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1431 44 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1432 44 : GET_MODE (temp));
1433 :
1434 0 : case ROTATE:
1435 0 : case ROTATERT:
1436 : /* Rotations don't affect popcount. */
1437 0 : if (!side_effects_p (XEXP (op, 1)))
1438 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1439 0 : GET_MODE (XEXP (op, 0)));
1440 : break;
1441 :
1442 : default:
1443 : break;
1444 : }
1445 : break;
1446 :
1447 0 : case PARITY:
1448 0 : switch (GET_CODE (op))
1449 : {
1450 0 : case NOT:
1451 0 : case BSWAP:
1452 0 : case BITREVERSE:
1453 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1454 0 : GET_MODE (XEXP (op, 0)));
1455 :
1456 0 : case ZERO_EXTEND:
1457 0 : case SIGN_EXTEND:
1458 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1459 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1460 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1461 0 : GET_MODE (temp));
1462 :
1463 0 : case ROTATE:
1464 0 : case ROTATERT:
1465 : /* Rotations don't affect parity. */
1466 0 : if (!side_effects_p (XEXP (op, 1)))
1467 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1468 0 : GET_MODE (XEXP (op, 0)));
1469 : break;
1470 :
1471 : case PARITY:
1472 : /* (parity (parity x)) -> parity (x). */
1473 : return op;
1474 :
1475 : default:
1476 : break;
1477 : }
1478 : break;
1479 :
1480 30104 : case BSWAP:
1481 : /* (bswap (bswap x)) -> x. */
1482 30104 : if (GET_CODE (op) == BSWAP)
1483 184 : return XEXP (op, 0);
1484 : break;
1485 :
1486 0 : case BITREVERSE:
1487 : /* (bitreverse (bitreverse x)) -> x. */
1488 0 : if (GET_CODE (op) == BITREVERSE)
1489 0 : return XEXP (op, 0);
1490 : break;
1491 :
1492 900051 : case FLOAT:
1493 : /* (float (sign_extend <X>)) = (float <X>). */
1494 900051 : if (GET_CODE (op) == SIGN_EXTEND)
1495 9352 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1496 9352 : GET_MODE (XEXP (op, 0)));
1497 : break;
1498 :
1499 2993485 : case SIGN_EXTEND:
1500 : /* Check for useless extension. */
1501 2993485 : if (GET_MODE (op) == mode)
1502 : return op;
1503 :
1504 : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1505 : becomes just the MINUS if its mode is MODE. This allows
1506 : folding switch statements on machines using casesi (such as
1507 : the VAX). */
1508 2993445 : if (GET_CODE (op) == TRUNCATE
1509 62 : && GET_MODE (XEXP (op, 0)) == mode
1510 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1511 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1512 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1513 : return XEXP (op, 0);
1514 :
1515 : /* Extending a widening multiplication should be canonicalized to
1516 : a wider widening multiplication. */
1517 2993445 : if (GET_CODE (op) == MULT)
1518 : {
1519 67394 : rtx lhs = XEXP (op, 0);
1520 67394 : rtx rhs = XEXP (op, 1);
1521 67394 : enum rtx_code lcode = GET_CODE (lhs);
1522 67394 : enum rtx_code rcode = GET_CODE (rhs);
1523 :
1524 : /* Widening multiplies usually extend both operands, but sometimes
1525 : they use a shift to extract a portion of a register. */
1526 67394 : if ((lcode == SIGN_EXTEND
1527 67245 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1528 880 : && (rcode == SIGN_EXTEND
1529 836 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1530 : {
1531 165 : machine_mode lmode = GET_MODE (lhs);
1532 165 : machine_mode rmode = GET_MODE (rhs);
1533 165 : int bits;
1534 :
1535 165 : if (lcode == ASHIFTRT)
1536 : /* Number of bits not shifted off the end. */
1537 125 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1538 125 : - INTVAL (XEXP (lhs, 1)));
1539 : else /* lcode == SIGN_EXTEND */
1540 : /* Size of inner mode. */
1541 80 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1542 :
1543 165 : if (rcode == ASHIFTRT)
1544 121 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1545 121 : - INTVAL (XEXP (rhs, 1)));
1546 : else /* rcode == SIGN_EXTEND */
1547 88 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1548 :
1549 : /* We can only widen multiplies if the result is mathematiclly
1550 : equivalent. I.e. if overflow was impossible. */
1551 330 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1552 108 : return simplify_gen_binary
1553 108 : (MULT, mode,
1554 : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1555 108 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1556 : }
1557 : }
1558 :
1559 : /* Check for a sign extension of a subreg of a promoted
1560 : variable, where the promotion is sign-extended, and the
1561 : target mode is the same as the variable's promotion. */
1562 2993337 : if (GET_CODE (op) == SUBREG
1563 150046 : && SUBREG_PROMOTED_VAR_P (op)
1564 2999004 : && SUBREG_PROMOTED_SIGNED_P (op))
1565 : {
1566 0 : rtx subreg = SUBREG_REG (op);
1567 0 : machine_mode subreg_mode = GET_MODE (subreg);
1568 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1569 : {
1570 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1571 0 : if (temp)
1572 : {
1573 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1574 0 : if (partial_subreg_p (temp))
1575 : {
1576 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1577 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1578 : }
1579 0 : return temp;
1580 : }
1581 : }
1582 : else
1583 : /* Sign-extending a sign-extended subreg. */
1584 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1585 0 : subreg, subreg_mode);
1586 : }
1587 :
1588 : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1589 : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1590 2993337 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1591 : {
1592 20250 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1593 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1594 6750 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1595 6750 : GET_MODE (XEXP (op, 0)));
1596 : }
1597 :
1598 : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1599 : is (sign_extend:M (subreg:O <X>)) if there is mode with
1600 : GET_MODE_BITSIZE (N) - I bits.
1601 : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1602 : is similarly (zero_extend:M (subreg:O <X>)). */
1603 2986587 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1604 88469 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1605 2989108 : && is_a <scalar_int_mode> (mode, &int_mode)
1606 5198 : && CONST_INT_P (XEXP (op, 1))
1607 5198 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1608 2991661 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1609 5074 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1610 : {
1611 5074 : scalar_int_mode tmode;
1612 5074 : gcc_assert (GET_MODE_PRECISION (int_mode)
1613 : > GET_MODE_PRECISION (op_mode));
1614 5074 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1615 7471 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1616 : {
1617 2677 : rtx inner =
1618 2677 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1619 2677 : if (inner)
1620 2677 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1621 : ? SIGN_EXTEND : ZERO_EXTEND,
1622 2677 : int_mode, inner, tmode);
1623 : }
1624 : }
1625 :
1626 : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1627 : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1628 2983910 : if (GET_CODE (op) == LSHIFTRT
1629 186 : && CONST_INT_P (XEXP (op, 1))
1630 186 : && XEXP (op, 1) != const0_rtx)
1631 186 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1632 :
1633 : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1634 : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1635 : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1636 : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1637 : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1638 : wider than O. */
1639 2983724 : if (GET_CODE (op) == TRUNCATE
1640 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1641 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1642 : {
1643 0 : scalar_int_mode m_mode, n_mode, o_mode;
1644 0 : rtx old_shift = XEXP (op, 0);
1645 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1646 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1647 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1648 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1649 0 : == INTVAL (XEXP (old_shift, 1)))
1650 : {
1651 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1652 : GET_MODE (old_shift),
1653 : XEXP (old_shift, 0),
1654 : XEXP (old_shift, 1));
1655 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1656 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1657 0 : GET_MODE (new_shift));
1658 0 : if (mode != GET_MODE (new_shift))
1659 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1660 0 : GET_MODE (new_shift));
1661 : return new_shift;
1662 : }
1663 : }
1664 :
1665 : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1666 : we know the sign bit of OP must be clear. */
1667 2983724 : if (val_signbit_known_clear_p (GET_MODE (op),
1668 2983724 : nonzero_bits (op, GET_MODE (op))))
1669 38036 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1670 :
1671 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1672 2945688 : if (GET_CODE (op) == SUBREG
1673 149794 : && subreg_lowpart_p (op)
1674 149698 : && GET_MODE (SUBREG_REG (op)) == mode
1675 3075126 : && is_a <scalar_int_mode> (mode, &int_mode)
1676 136216 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1677 136216 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1678 134347 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1679 3080035 : && (nonzero_bits (SUBREG_REG (op), mode)
1680 134347 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1681 6778 : return SUBREG_REG (op);
1682 :
1683 : #if defined(POINTERS_EXTEND_UNSIGNED)
1684 : /* As we do not know which address space the pointer is referring to,
1685 : we can do this only if the target does not support different pointer
1686 : or address modes depending on the address space. */
1687 2938910 : if (target_default_pointer_address_modes_p ()
1688 : && ! POINTERS_EXTEND_UNSIGNED
1689 : && mode == Pmode && GET_MODE (op) == ptr_mode
1690 : && (CONSTANT_P (op)
1691 : || (GET_CODE (op) == SUBREG
1692 : && REG_P (SUBREG_REG (op))
1693 : && REG_POINTER (SUBREG_REG (op))
1694 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1695 : && !targetm.have_ptr_extend ())
1696 : {
1697 : temp
1698 : = convert_memory_address_addr_space_1 (Pmode, op,
1699 : ADDR_SPACE_GENERIC, false,
1700 : true);
1701 : if (temp)
1702 : return temp;
1703 : }
1704 : #endif
1705 : break;
1706 :
1707 11363057 : case ZERO_EXTEND:
1708 : /* Check for useless extension. */
1709 11363057 : if (GET_MODE (op) == mode)
1710 : return op;
1711 :
1712 : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1713 : where const does not sign bit set. */
1714 11363015 : if (GET_CODE (op) == AND
1715 118526 : && CONST_INT_P (XEXP (op, 1))
1716 92003 : && INTVAL (XEXP (op, 1)) > 0)
1717 : {
1718 85004 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1719 85004 : if (tem)
1720 68847 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1721 : }
1722 :
1723 : /* Check for a zero extension of a subreg of a promoted
1724 : variable, where the promotion is zero-extended, and the
1725 : target mode is the same as the variable's promotion. */
1726 11294168 : if (GET_CODE (op) == SUBREG
1727 1468644 : && SUBREG_PROMOTED_VAR_P (op)
1728 11294645 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1729 : {
1730 477 : rtx subreg = SUBREG_REG (op);
1731 477 : machine_mode subreg_mode = GET_MODE (subreg);
1732 477 : if (!paradoxical_subreg_p (mode, subreg_mode))
1733 : {
1734 291 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1735 291 : if (temp)
1736 : {
1737 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1738 291 : if (partial_subreg_p (temp))
1739 : {
1740 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1741 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1742 : }
1743 291 : return temp;
1744 : }
1745 : }
1746 : else
1747 : /* Zero-extending a zero-extended subreg. */
1748 186 : return simplify_gen_unary (ZERO_EXTEND, mode,
1749 186 : subreg, subreg_mode);
1750 : }
1751 :
1752 : /* Extending a widening multiplication should be canonicalized to
1753 : a wider widening multiplication. */
1754 11293691 : if (GET_CODE (op) == MULT)
1755 : {
1756 165944 : rtx lhs = XEXP (op, 0);
1757 165944 : rtx rhs = XEXP (op, 1);
1758 165944 : enum rtx_code lcode = GET_CODE (lhs);
1759 165944 : enum rtx_code rcode = GET_CODE (rhs);
1760 :
1761 : /* Widening multiplies usually extend both operands, but sometimes
1762 : they use a shift to extract a portion of a register. */
1763 165944 : if ((lcode == ZERO_EXTEND
1764 165172 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1765 862 : && (rcode == ZERO_EXTEND
1766 750 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1767 : {
1768 112 : machine_mode lmode = GET_MODE (lhs);
1769 112 : machine_mode rmode = GET_MODE (rhs);
1770 112 : int bits;
1771 :
1772 112 : if (lcode == LSHIFTRT)
1773 : /* Number of bits not shifted off the end. */
1774 0 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1775 0 : - INTVAL (XEXP (lhs, 1)));
1776 : else /* lcode == ZERO_EXTEND */
1777 : /* Size of inner mode. */
1778 224 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1779 :
1780 112 : if (rcode == LSHIFTRT)
1781 0 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1782 0 : - INTVAL (XEXP (rhs, 1)));
1783 : else /* rcode == ZERO_EXTEND */
1784 224 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1785 :
1786 : /* We can only widen multiplies if the result is mathematiclly
1787 : equivalent. I.e. if overflow was impossible. */
1788 224 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1789 112 : return simplify_gen_binary
1790 112 : (MULT, mode,
1791 : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1792 112 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1793 : }
1794 : }
1795 :
1796 : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1797 11293579 : if (GET_CODE (op) == ZERO_EXTEND)
1798 21781 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1799 21781 : GET_MODE (XEXP (op, 0)));
1800 :
1801 : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1802 : is (zero_extend:M (subreg:O <X>)) if there is mode with
1803 : GET_MODE_PRECISION (N) - I bits. */
1804 11271798 : if (GET_CODE (op) == LSHIFTRT
1805 69567 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1806 11271821 : && is_a <scalar_int_mode> (mode, &int_mode)
1807 23 : && CONST_INT_P (XEXP (op, 1))
1808 18 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1809 11271798 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1810 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1811 : {
1812 0 : scalar_int_mode tmode;
1813 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1814 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1815 : {
1816 0 : rtx inner =
1817 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1818 0 : if (inner)
1819 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1820 0 : inner, tmode);
1821 : }
1822 : }
1823 :
1824 : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1825 : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1826 : of mode N. E.g.
1827 : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1828 : (and:SI (reg:SI) (const_int 63)). */
1829 11271798 : if (partial_subreg_p (op)
1830 12702602 : && is_a <scalar_int_mode> (mode, &int_mode)
1831 1449480 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1832 1448989 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1833 1135811 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1834 1113638 : && subreg_lowpart_p (op)
1835 2249048 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1836 780881 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1837 : {
1838 18676 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1839 11540 : return SUBREG_REG (op);
1840 7136 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1841 7136 : op0_mode);
1842 : }
1843 :
1844 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1845 11253122 : if (GET_CODE (op) == SUBREG
1846 1449491 : && subreg_lowpart_p (op)
1847 865525 : && GET_MODE (SUBREG_REG (op)) == mode
1848 12029070 : && is_a <scalar_int_mode> (mode, &int_mode)
1849 775948 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1850 775948 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1851 714770 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1852 11967892 : && (nonzero_bits (SUBREG_REG (op), mode)
1853 714770 : & ~GET_MODE_MASK (op_mode)) == 0)
1854 0 : return SUBREG_REG (op);
1855 :
1856 : /* Trying to optimize:
1857 : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1858 : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1859 : where the mask is GET_MODE_MASK (N).
1860 : For the cases when X:M doesn't have any non-zero bits
1861 : outside of mode N, (zero_extend:M (subreg:N (X:M))
1862 : will be simplified to just (X:M)
1863 : and whole optimization will be -> (xor:M (X:M, mask)). */
1864 11253122 : if (partial_subreg_p (op)
1865 1430804 : && GET_CODE (XEXP (op, 0)) == NOT
1866 1468 : && GET_MODE (XEXP (op, 0)) == mode
1867 1450 : && subreg_lowpart_p (op)
1868 11253536 : && HWI_COMPUTABLE_MODE_P (mode)
1869 418 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1870 1449909 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1871 418 : & ~GET_MODE_MASK (op_mode)) == 0)
1872 : {
1873 4 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1874 8 : return simplify_gen_binary (XOR, mode,
1875 4 : XEXP (XEXP (op, 0), 0),
1876 4 : gen_int_mode (mask, mode));
1877 : }
1878 :
1879 : #if defined(POINTERS_EXTEND_UNSIGNED)
1880 : /* As we do not know which address space the pointer is referring to,
1881 : we can do this only if the target does not support different pointer
1882 : or address modes depending on the address space. */
1883 11253118 : if (target_default_pointer_address_modes_p ()
1884 : && POINTERS_EXTEND_UNSIGNED > 0
1885 12655213 : && mode == Pmode && GET_MODE (op) == ptr_mode
1886 687 : && (CONSTANT_P (op)
1887 666 : || (GET_CODE (op) == SUBREG
1888 0 : && REG_P (SUBREG_REG (op))
1889 0 : && REG_POINTER (SUBREG_REG (op))
1890 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1891 11253139 : && !targetm.have_ptr_extend ())
1892 : {
1893 21 : temp
1894 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1895 : ADDR_SPACE_GENERIC, false,
1896 : true);
1897 21 : if (temp)
1898 : return temp;
1899 : }
1900 : #endif
1901 : break;
1902 :
1903 507671 : case VEC_DUPLICATE:
1904 507671 : if (GET_CODE (op) == VEC_DUPLICATE)
1905 2 : return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
1906 2 : GET_MODE (XEXP (op, 0)));
1907 : break;
1908 :
1909 : default:
1910 : break;
1911 : }
1912 :
1913 19136393 : if (VECTOR_MODE_P (mode)
1914 1531221 : && vec_duplicate_p (op, &elt)
1915 20673490 : && code != VEC_DUPLICATE)
1916 : {
1917 5876 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1918 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1919 : operations by promoting VEC_DUPLICATE to the root of the expression
1920 : (as far as possible). */
1921 4820 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1922 9640 : elt, GET_MODE_INNER (GET_MODE (op)));
1923 : else
1924 : /* Try applying the operator to ELT and see if that simplifies.
1925 : We can duplicate the result if so.
1926 :
1927 : The reason we traditionally haven't used simplify_gen_unary
1928 : for these codes is that it didn't necessarily seem to be a
1929 : win to convert things like:
1930 :
1931 : (neg:V (vec_duplicate:V (reg:S R)))
1932 :
1933 : to:
1934 :
1935 : (vec_duplicate:V (neg:S (reg:S R)))
1936 :
1937 : The first might be done entirely in vector registers while the
1938 : second might need a move between register files.
1939 :
1940 : However, there also cases where promoting the vec_duplicate is
1941 : more efficient, and there is definite value in having a canonical
1942 : form when matching instruction patterns. We should consider
1943 : extending the simplify_gen_unary code above to more cases. */
1944 1056 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1945 2112 : elt, GET_MODE_INNER (GET_MODE (op)));
1946 5876 : if (temp)
1947 5400 : return gen_vec_duplicate (mode, temp);
1948 : }
1949 :
1950 : return 0;
1951 : }
1952 :
1953 : /* Try to compute the value of a unary operation CODE whose output mode is to
1954 : be MODE with input operand OP whose mode was originally OP_MODE.
1955 : Return zero if the value cannot be computed. */
1956 : rtx
1957 28093203 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1958 : rtx op, machine_mode op_mode)
1959 : {
1960 28093203 : scalar_int_mode result_mode;
1961 :
1962 28093203 : if (code == VEC_DUPLICATE)
1963 : {
1964 1627974 : gcc_assert (VECTOR_MODE_P (mode));
1965 1627974 : if (GET_MODE (op) != VOIDmode)
1966 : {
1967 546666 : if (!VECTOR_MODE_P (GET_MODE (op)))
1968 1080054 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1969 : else
1970 19917 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1971 : (GET_MODE (op)));
1972 : }
1973 1627974 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1974 1119548 : return gen_const_vec_duplicate (mode, op);
1975 508426 : if (GET_CODE (op) == CONST_VECTOR
1976 508426 : && (CONST_VECTOR_DUPLICATE_P (op)
1977 : || CONST_VECTOR_NUNITS (op).is_constant ()))
1978 : {
1979 755 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1980 755 : ? CONST_VECTOR_NPATTERNS (op)
1981 1509 : : CONST_VECTOR_NUNITS (op).to_constant ());
1982 2265 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1983 755 : rtx_vector_builder builder (mode, npatterns, 1);
1984 3130 : for (unsigned i = 0; i < npatterns; i++)
1985 2375 : builder.quick_push (CONST_VECTOR_ELT (op, i));
1986 755 : return builder.build ();
1987 755 : }
1988 : }
1989 :
1990 25723009 : if (VECTOR_MODE_P (mode)
1991 1571935 : && GET_CODE (op) == CONST_VECTOR
1992 27072911 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1993 : {
1994 33337 : gcc_assert (GET_MODE (op) == op_mode);
1995 :
1996 33337 : rtx_vector_builder builder;
1997 33337 : if (!builder.new_unary_operation (mode, op, false))
1998 : return 0;
1999 :
2000 33337 : unsigned int count = builder.encoded_nelts ();
2001 148653 : for (unsigned int i = 0; i < count; i++)
2002 : {
2003 231670 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
2004 : CONST_VECTOR_ELT (op, i),
2005 231670 : GET_MODE_INNER (op_mode));
2006 115835 : if (!x || !valid_for_const_vector_p (mode, x))
2007 519 : return 0;
2008 115316 : builder.quick_push (x);
2009 : }
2010 32818 : return builder.build ();
2011 33337 : }
2012 :
2013 : /* The order of these tests is critical so that, for example, we don't
2014 : check the wrong mode (input vs. output) for a conversion operation,
2015 : such as FIX. At some point, this should be simplified. */
2016 :
2017 26939563 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2018 : {
2019 7400 : REAL_VALUE_TYPE d;
2020 :
2021 7400 : if (op_mode == VOIDmode)
2022 : {
2023 : /* CONST_INT have VOIDmode as the mode. We assume that all
2024 : the bits of the constant are significant, though, this is
2025 : a dangerous assumption as many times CONST_INTs are
2026 : created and used with garbage in the bits outside of the
2027 : precision of the implied mode of the const_int. */
2028 64 : op_mode = MAX_MODE_INT;
2029 : }
2030 :
2031 7400 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2032 :
2033 : /* Avoid the folding if flag_signaling_nans is on and
2034 : operand is a signaling NaN. */
2035 7400 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2036 : return 0;
2037 :
2038 7400 : d = real_value_truncate (mode, d);
2039 :
2040 : /* Avoid the folding if flag_rounding_math is on and the
2041 : conversion is not exact. */
2042 7400 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2043 : {
2044 1011 : bool fail = false;
2045 1011 : wide_int w = real_to_integer (&d, &fail,
2046 : GET_MODE_PRECISION
2047 1011 : (as_a <scalar_int_mode> (op_mode)));
2048 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2049 905 : return 0;
2050 1011 : }
2051 :
2052 6495 : return const_double_from_real_value (d, mode);
2053 : }
2054 26932163 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2055 : {
2056 2139 : REAL_VALUE_TYPE d;
2057 :
2058 2139 : if (op_mode == VOIDmode)
2059 : {
2060 : /* CONST_INT have VOIDmode as the mode. We assume that all
2061 : the bits of the constant are significant, though, this is
2062 : a dangerous assumption as many times CONST_INTs are
2063 : created and used with garbage in the bits outside of the
2064 : precision of the implied mode of the const_int. */
2065 8 : op_mode = MAX_MODE_INT;
2066 : }
2067 :
2068 2139 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2069 :
2070 : /* Avoid the folding if flag_signaling_nans is on and
2071 : operand is a signaling NaN. */
2072 2139 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2073 : return 0;
2074 :
2075 2139 : d = real_value_truncate (mode, d);
2076 :
2077 : /* Avoid the folding if flag_rounding_math is on and the
2078 : conversion is not exact. */
2079 2139 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2080 : {
2081 16 : bool fail = false;
2082 16 : wide_int w = real_to_integer (&d, &fail,
2083 : GET_MODE_PRECISION
2084 16 : (as_a <scalar_int_mode> (op_mode)));
2085 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2086 16 : return 0;
2087 16 : }
2088 :
2089 2123 : return const_double_from_real_value (d, mode);
2090 : }
2091 :
2092 26930024 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2093 : {
2094 3639250 : unsigned int width = GET_MODE_PRECISION (result_mode);
2095 3639250 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2096 : return 0;
2097 :
2098 3639250 : wide_int result;
2099 3639250 : scalar_int_mode imode = (op_mode == VOIDmode
2100 3639250 : ? result_mode
2101 3639026 : : as_a <scalar_int_mode> (op_mode));
2102 3639250 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2103 3639250 : int int_value;
2104 :
2105 : #if TARGET_SUPPORTS_WIDE_INT == 0
2106 : /* This assert keeps the simplification from producing a result
2107 : that cannot be represented in a CONST_DOUBLE but a lot of
2108 : upstream callers expect that this function never fails to
2109 : simplify something and so you if you added this to the test
2110 : above the code would die later anyway. If this assert
2111 : happens, you just need to make the port support wide int. */
2112 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2113 : #endif
2114 :
2115 3639250 : switch (code)
2116 : {
2117 176797 : case NOT:
2118 176797 : result = wi::bit_not (op0);
2119 176797 : break;
2120 :
2121 1856541 : case NEG:
2122 1856541 : result = wi::neg (op0);
2123 1856541 : break;
2124 :
2125 7062 : case ABS:
2126 7062 : result = wi::abs (op0);
2127 7062 : break;
2128 :
2129 0 : case FFS:
2130 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2131 0 : break;
2132 :
2133 168 : case CLZ:
2134 168 : if (wi::ne_p (op0, 0))
2135 38 : int_value = wi::clz (op0);
2136 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2137 : return NULL_RTX;
2138 38 : result = wi::shwi (int_value, result_mode);
2139 38 : break;
2140 :
2141 0 : case CLRSB:
2142 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2143 0 : break;
2144 :
2145 0 : case CTZ:
2146 0 : if (wi::ne_p (op0, 0))
2147 0 : int_value = wi::ctz (op0);
2148 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2149 : return NULL_RTX;
2150 0 : result = wi::shwi (int_value, result_mode);
2151 0 : break;
2152 :
2153 160 : case POPCOUNT:
2154 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2155 160 : break;
2156 :
2157 0 : case PARITY:
2158 0 : result = wi::shwi (wi::parity (op0), result_mode);
2159 0 : break;
2160 :
2161 1765 : case BSWAP:
2162 1765 : result = wi::bswap (op0);
2163 1765 : break;
2164 :
2165 0 : case BITREVERSE:
2166 0 : result = wi::bitreverse (op0);
2167 0 : break;
2168 :
2169 1418646 : case TRUNCATE:
2170 1418646 : case ZERO_EXTEND:
2171 1418646 : result = wide_int::from (op0, width, UNSIGNED);
2172 1418646 : break;
2173 :
2174 14342 : case US_TRUNCATE:
2175 14342 : case SS_TRUNCATE:
2176 14342 : {
2177 14342 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2178 14342 : wide_int nmax
2179 14342 : = wide_int::from (wi::max_value (width, sgn),
2180 28684 : GET_MODE_PRECISION (imode), sgn);
2181 14342 : wide_int nmin
2182 14342 : = wide_int::from (wi::min_value (width, sgn),
2183 28684 : GET_MODE_PRECISION (imode), sgn);
2184 14342 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2185 14342 : result = wide_int::from (result, width, sgn);
2186 14342 : break;
2187 14342 : }
2188 163769 : case SIGN_EXTEND:
2189 163769 : result = wide_int::from (op0, width, SIGNED);
2190 163769 : break;
2191 :
2192 0 : case SS_NEG:
2193 0 : if (wi::only_sign_bit_p (op0))
2194 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2195 : else
2196 0 : result = wi::neg (op0);
2197 : break;
2198 :
2199 0 : case SS_ABS:
2200 0 : if (wi::only_sign_bit_p (op0))
2201 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2202 : else
2203 0 : result = wi::abs (op0);
2204 : break;
2205 :
2206 : case SQRT:
2207 : default:
2208 : return 0;
2209 : }
2210 :
2211 3639120 : return immed_wide_int_const (result, result_mode);
2212 3639250 : }
2213 :
2214 23290774 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2215 417629 : && SCALAR_FLOAT_MODE_P (mode)
2216 415596 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2217 : {
2218 415596 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2219 415596 : switch (code)
2220 : {
2221 : case SQRT:
2222 : return 0;
2223 350 : case ABS:
2224 350 : d = real_value_abs (&d);
2225 350 : break;
2226 15707 : case NEG:
2227 15707 : d = real_value_negate (&d);
2228 15707 : break;
2229 2284 : case FLOAT_TRUNCATE:
2230 : /* Don't perform the operation if flag_signaling_nans is on
2231 : and the operand is a signaling NaN. */
2232 2284 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2233 : return NULL_RTX;
2234 : /* Or if flag_rounding_math is on and the truncation is not
2235 : exact. */
2236 2284 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2237 2284 : && !exact_real_truncate (mode, &d))
2238 231 : return NULL_RTX;
2239 2053 : d = real_value_truncate (mode, d);
2240 2053 : break;
2241 390779 : case FLOAT_EXTEND:
2242 : /* Don't perform the operation if flag_signaling_nans is on
2243 : and the operand is a signaling NaN. */
2244 390779 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2245 : return NULL_RTX;
2246 : /* All this does is change the mode, unless changing
2247 : mode class. */
2248 390777 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2249 0 : real_convert (&d, mode, &d);
2250 : break;
2251 0 : case FIX:
2252 : /* Don't perform the operation if flag_signaling_nans is on
2253 : and the operand is a signaling NaN. */
2254 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2255 : return NULL_RTX;
2256 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2257 0 : break;
2258 5871 : case NOT:
2259 5871 : {
2260 5871 : long tmp[4];
2261 5871 : int i;
2262 :
2263 5871 : real_to_target (tmp, &d, GET_MODE (op));
2264 29355 : for (i = 0; i < 4; i++)
2265 23484 : tmp[i] = ~tmp[i];
2266 5871 : real_from_target (&d, tmp, mode);
2267 5871 : break;
2268 : }
2269 0 : default:
2270 0 : gcc_unreachable ();
2271 : }
2272 414758 : return const_double_from_real_value (d, mode);
2273 : }
2274 2033 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2275 2033 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2276 22877211 : && is_int_mode (mode, &result_mode))
2277 : {
2278 2033 : unsigned int width = GET_MODE_PRECISION (result_mode);
2279 2033 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2280 : return 0;
2281 :
2282 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2283 : operators are intentionally left unspecified (to ease implementation
2284 : by target backends), for consistency, this routine implements the
2285 : same semantics for constant folding as used by the middle-end. */
2286 :
2287 : /* This was formerly used only for non-IEEE float.
2288 : eggert@twinsun.com says it is safe for IEEE also. */
2289 2033 : REAL_VALUE_TYPE t;
2290 2033 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2291 2033 : wide_int wmax, wmin;
2292 : /* This is part of the abi to real_to_integer, but we check
2293 : things before making this call. */
2294 2033 : bool fail;
2295 :
2296 2033 : switch (code)
2297 : {
2298 2025 : case FIX:
2299 : /* According to IEEE standard, for conversions from floating point to
2300 : integer. When a NaN or infinite operand cannot be represented in
2301 : the destination format and this cannot otherwise be indicated, the
2302 : invalid operation exception shall be signaled. When a numeric
2303 : operand would convert to an integer outside the range of the
2304 : destination format, the invalid operation exception shall be
2305 : signaled if this situation cannot otherwise be indicated. */
2306 2025 : if (REAL_VALUE_ISNAN (*x))
2307 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2308 :
2309 1070 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2310 : return NULL_RTX;
2311 :
2312 : /* Test against the signed upper bound. */
2313 110 : wmax = wi::max_value (width, SIGNED);
2314 110 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2315 110 : if (real_less (&t, x))
2316 3 : return (flag_trapping_math
2317 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2318 :
2319 : /* Test against the signed lower bound. */
2320 107 : wmin = wi::min_value (width, SIGNED);
2321 107 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2322 107 : if (real_less (x, &t))
2323 8 : return immed_wide_int_const (wmin, mode);
2324 :
2325 99 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2326 : mode);
2327 :
2328 8 : case UNSIGNED_FIX:
2329 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2330 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2331 :
2332 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2333 : return NULL_RTX;
2334 :
2335 : /* Test against the unsigned upper bound. */
2336 0 : wmax = wi::max_value (width, UNSIGNED);
2337 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2338 0 : if (real_less (&t, x))
2339 0 : return (flag_trapping_math
2340 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2341 :
2342 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2343 : mode);
2344 :
2345 0 : default:
2346 0 : gcc_unreachable ();
2347 : }
2348 2033 : }
2349 :
2350 : /* Handle polynomial integers. */
2351 : else if (CONST_POLY_INT_P (op))
2352 : {
2353 : poly_wide_int result;
2354 : switch (code)
2355 : {
2356 : case NEG:
2357 : result = -const_poly_int_value (op);
2358 : break;
2359 :
2360 : case NOT:
2361 : result = ~const_poly_int_value (op);
2362 : break;
2363 :
2364 : default:
2365 : return NULL_RTX;
2366 : }
2367 : return immed_wide_int_const (result, mode);
2368 : }
2369 :
2370 : return NULL_RTX;
2371 : }
2372 :
2373 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2374 : CODE that can commute with byte swapping, with result mode MODE and
2375 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2376 : Return zero if no simplification or canonicalization is possible. */
2377 :
2378 : rtx
2379 36684869 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2380 : machine_mode mode,
2381 : rtx op0, rtx op1)
2382 : {
2383 36684869 : rtx tem;
2384 :
2385 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2386 36684869 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2387 : {
2388 254 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2389 : simplify_gen_unary (BSWAP, mode, op1, mode));
2390 254 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2391 : }
2392 :
2393 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2394 36684615 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2395 : {
2396 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2397 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2398 : }
2399 :
2400 : return NULL_RTX;
2401 : }
2402 :
2403 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2404 : associative binary operation CODE with result mode MODE, operating
2405 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2406 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2407 : canonicalization is possible. */
2408 :
2409 : rtx
2410 46573138 : simplify_context::simplify_associative_operation (rtx_code code,
2411 : machine_mode mode,
2412 : rtx op0, rtx op1)
2413 : {
2414 46573138 : rtx tem;
2415 :
2416 : /* Normally expressions simplified by simplify-rtx.cc are combined
2417 : at most from a few machine instructions and therefore the
2418 : expressions should be fairly small. During var-tracking
2419 : we can see arbitrarily large expressions though and reassociating
2420 : those can be quadratic, so punt after encountering max_assoc_count
2421 : simplify_associative_operation calls during outermost simplify_*
2422 : call. */
2423 46573138 : if (++assoc_count >= max_assoc_count)
2424 : return NULL_RTX;
2425 :
2426 : /* Linearize the operator to the left. */
2427 46569287 : if (GET_CODE (op1) == code)
2428 : {
2429 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2430 18472 : if (GET_CODE (op0) == code)
2431 : {
2432 4759 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2433 4759 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2434 : }
2435 :
2436 : /* "a op (b op c)" becomes "(b op c) op a". */
2437 13713 : if (! swap_commutative_operands_p (op1, op0))
2438 13713 : return simplify_gen_binary (code, mode, op1, op0);
2439 :
2440 : std::swap (op0, op1);
2441 : }
2442 :
2443 46550815 : if (GET_CODE (op0) == code)
2444 : {
2445 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2446 1282013 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2447 : {
2448 262016 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2449 262016 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2450 : }
2451 :
2452 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2453 1019997 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2454 1019997 : if (tem != 0)
2455 76185 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2456 :
2457 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2458 943812 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2459 943812 : if (tem != 0)
2460 30419 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2461 : }
2462 :
2463 : return 0;
2464 : }
2465 :
2466 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2467 : that represents it (8 if it includes <, 4 if it includes > and 2
2468 : if it includes ==). Return 0 otherwise. */
2469 : static int
2470 18906 : unsigned_comparison_to_mask (rtx_code comparison)
2471 : {
2472 0 : switch (comparison)
2473 : {
2474 : case LTU:
2475 : return 8;
2476 : case GTU:
2477 : return 4;
2478 : case EQ:
2479 : return 2;
2480 :
2481 : case LEU:
2482 : return 10;
2483 : case GEU:
2484 : return 6;
2485 :
2486 : case NE:
2487 : return 12;
2488 :
2489 : default:
2490 : return 0;
2491 : }
2492 : }
2493 :
2494 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2495 : to comparisons. */
2496 : static rtx_code
2497 6616 : mask_to_unsigned_comparison (int mask)
2498 : {
2499 6616 : switch (mask)
2500 : {
2501 : case 8:
2502 : return LTU;
2503 160 : case 4:
2504 160 : return GTU;
2505 2593 : case 2:
2506 2593 : return EQ;
2507 :
2508 160 : case 10:
2509 160 : return LEU;
2510 160 : case 6:
2511 160 : return GEU;
2512 :
2513 3383 : case 12:
2514 3383 : return NE;
2515 :
2516 0 : default:
2517 0 : gcc_unreachable ();
2518 : }
2519 : }
2520 :
2521 : /* Return a mask describing the COMPARISON. */
2522 : static int
2523 2666 : comparison_to_mask (enum rtx_code comparison)
2524 : {
2525 2666 : switch (comparison)
2526 : {
2527 : case LT:
2528 : return 8;
2529 472 : case GT:
2530 472 : return 4;
2531 419 : case EQ:
2532 419 : return 2;
2533 19 : case UNORDERED:
2534 19 : return 1;
2535 :
2536 0 : case LTGT:
2537 0 : return 12;
2538 441 : case LE:
2539 441 : return 10;
2540 441 : case GE:
2541 441 : return 6;
2542 0 : case UNLT:
2543 0 : return 9;
2544 0 : case UNGT:
2545 0 : return 5;
2546 0 : case UNEQ:
2547 0 : return 3;
2548 :
2549 0 : case ORDERED:
2550 0 : return 14;
2551 400 : case NE:
2552 400 : return 13;
2553 0 : case UNLE:
2554 0 : return 11;
2555 0 : case UNGE:
2556 0 : return 7;
2557 :
2558 0 : default:
2559 0 : gcc_unreachable ();
2560 : }
2561 : }
2562 :
2563 : /* Return a comparison corresponding to the MASK. */
2564 : static enum rtx_code
2565 1014 : mask_to_comparison (int mask)
2566 : {
2567 1014 : switch (mask)
2568 : {
2569 : case 8:
2570 : return LT;
2571 : case 4:
2572 : return GT;
2573 : case 2:
2574 : return EQ;
2575 : case 1:
2576 : return UNORDERED;
2577 :
2578 : case 12:
2579 : return LTGT;
2580 : case 10:
2581 : return LE;
2582 : case 6:
2583 : return GE;
2584 : case 9:
2585 : return UNLT;
2586 : case 5:
2587 : return UNGT;
2588 : case 3:
2589 : return UNEQ;
2590 :
2591 : case 14:
2592 : return ORDERED;
2593 : case 13:
2594 : return NE;
2595 : case 11:
2596 : return UNLE;
2597 : case 7:
2598 : return UNGE;
2599 :
2600 0 : default:
2601 0 : gcc_unreachable ();
2602 : }
2603 : }
2604 :
2605 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2606 : false/true value of comparison with MODE where comparison operands
2607 : have CMP_MODE. */
2608 :
2609 : static rtx
2610 779211 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2611 : {
2612 779211 : if (SCALAR_FLOAT_MODE_P (mode))
2613 : {
2614 197 : if (res == const0_rtx)
2615 193 : return CONST0_RTX (mode);
2616 : #ifdef FLOAT_STORE_FLAG_VALUE
2617 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2618 : return const_double_from_real_value (val, mode);
2619 : #else
2620 : return NULL_RTX;
2621 : #endif
2622 : }
2623 779014 : if (VECTOR_MODE_P (mode))
2624 : {
2625 377 : if (res == const0_rtx)
2626 63 : return CONST0_RTX (mode);
2627 : #ifdef VECTOR_STORE_FLAG_VALUE
2628 314 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2629 304 : if (val == NULL_RTX)
2630 : return NULL_RTX;
2631 304 : if (val == const1_rtx)
2632 0 : return CONST1_RTX (mode);
2633 :
2634 304 : return gen_const_vec_duplicate (mode, val);
2635 : #else
2636 : return NULL_RTX;
2637 : #endif
2638 : }
2639 : /* For vector comparison with scalar int result, it is unknown
2640 : if the target means here a comparison into an integral bitmask,
2641 : or comparison where all comparisons true mean const_true_rtx
2642 : whole result, or where any comparisons true mean const_true_rtx
2643 : whole result. For const0_rtx all the cases are the same. */
2644 778637 : if (VECTOR_MODE_P (cmp_mode)
2645 0 : && SCALAR_INT_MODE_P (mode)
2646 0 : && res == const_true_rtx)
2647 0 : return NULL_RTX;
2648 :
2649 : return res;
2650 : }
2651 :
2652 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2653 : and OP1, in the case where both are relational operations. Assume that
2654 : OP0 is inverted if INVERT0_P is true.
2655 :
2656 : Return 0 if no such simplification is possible. */
2657 : rtx
2658 13170527 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2659 : machine_mode mode,
2660 : rtx op0, rtx op1,
2661 : bool invert0_p)
2662 : {
2663 13170527 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2664 : return 0;
2665 :
2666 21457 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2667 9879 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2668 2125 : return 0;
2669 :
2670 9453 : if (side_effects_p (op0))
2671 : return 0;
2672 :
2673 9453 : enum rtx_code code0 = GET_CODE (op0);
2674 9453 : enum rtx_code code1 = GET_CODE (op1);
2675 9453 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2676 9453 : if (cmp_mode == VOIDmode)
2677 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2678 :
2679 : /* Assume at first that the comparisons are on integers, and that the
2680 : operands are therefore ordered. */
2681 9453 : int all = 14;
2682 9453 : int mask0 = unsigned_comparison_to_mask (code0);
2683 9453 : int mask1 = unsigned_comparison_to_mask (code1);
2684 18906 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2685 9453 : || IN_RANGE (mask1 & 12, 4, 8));
2686 1333 : if (unsigned_p)
2687 : {
2688 : /* We only reach here when comparing integers. Reject mixtures of signed
2689 : and unsigned comparisons. */
2690 8120 : if (mask0 == 0 || mask1 == 0)
2691 : return 0;
2692 : }
2693 : else
2694 : {
2695 : /* See whether the operands might be unordered. Assume that all
2696 : results are possible for CC modes, and punt later if we don't get an
2697 : always-true or always-false answer. */
2698 1333 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2699 : all = 15;
2700 1333 : mask0 = comparison_to_mask (code0) & all;
2701 1333 : mask1 = comparison_to_mask (code1) & all;
2702 : }
2703 :
2704 8173 : if (invert0_p)
2705 4661 : mask0 = mask0 ^ all;
2706 :
2707 8173 : int mask;
2708 8173 : if (code == AND)
2709 960 : mask = mask0 & mask1;
2710 7213 : else if (code == IOR)
2711 948 : mask = mask0 | mask1;
2712 6265 : else if (code == XOR)
2713 6265 : mask = mask0 ^ mask1;
2714 : else
2715 : return 0;
2716 :
2717 8173 : if (mask == all)
2718 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2719 :
2720 7941 : if (mask == 0)
2721 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2722 :
2723 7709 : if (unsigned_p)
2724 6616 : code = mask_to_unsigned_comparison (mask);
2725 : else
2726 : {
2727 1093 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2728 : return 0;
2729 :
2730 1014 : code = mask_to_comparison (mask);
2731 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2732 : with NE being the canonical choice. */
2733 1014 : if (code == LTGT && all == 14)
2734 184 : code = NE;
2735 : }
2736 :
2737 7630 : op0 = XEXP (op1, 0);
2738 7630 : op1 = XEXP (op1, 1);
2739 :
2740 7630 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2741 : }
2742 :
2743 : /* We are going to IOR together OP0/OP1. If there is a common term in OP0/OP1
2744 : then we may be able to simplify the expression. We're primarily trying to
2745 : simplify down to IOR/XOR expression right now, but there may be other
2746 : simplifications we can do in the future.
2747 :
2748 : Return the simplified expression or NULL_RTX if no simplification was
2749 : possible. */
2750 : rtx
2751 26862535 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
2752 : {
2753 : /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
2754 : X and C have no bits in common. */
2755 26862535 : if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
2756 228920 : && rtx_equal_p (op0, XEXP (op1, 0))
2757 8318 : && ((nonzero_bits (op0, GET_MODE (op0))
2758 8318 : & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
2759 26862535 : && !side_effects_p (op1))
2760 0 : return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
2761 :
2762 : /* (ior (and A C1) (and (not A) C2)) can be converted
2763 : into (and (xor A C2) (C1 + C2)) when there are no bits
2764 : in common between C1 and C2. */
2765 26862535 : if (GET_CODE (op0) == AND
2766 3945552 : && GET_CODE (op1) == AND
2767 392057 : && GET_CODE (XEXP (op1, 0)) == NOT
2768 24167 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2769 751 : && CONST_INT_P (XEXP (op0, 1))
2770 93 : && CONST_INT_P (XEXP (op1, 1))
2771 26862628 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2772 : {
2773 93 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2774 :
2775 93 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2776 93 : if (tem)
2777 : {
2778 93 : tem = simplify_gen_binary (AND, mode, tem, c);
2779 :
2780 93 : if (tem)
2781 : return tem;
2782 : }
2783 : }
2784 :
2785 : /* Another variant seen on some target particularly those with
2786 : sub-word operations.
2787 :
2788 : (ior (and A C1) (plus (and A C2) C2)) can be simplified into
2789 : (and (xor (A C2) (C1 + C2).
2790 :
2791 : Where C2 is the sign bit for A's mode. So 0x80 for QI,
2792 : 0x8000 for HI, etc. In this case we know there is no carry
2793 : from the PLUS into relevant bits of the output. */
2794 26862442 : if (GET_CODE (op0) == AND
2795 3945459 : && GET_CODE (op1) == PLUS
2796 5797 : && GET_CODE (XEXP (op1, 0)) == AND
2797 288 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2798 276 : && CONST_INT_P (XEXP (op0, 1))
2799 276 : && CONST_INT_P (XEXP (op1, 1))
2800 276 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
2801 276 : && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
2802 72 : && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
2803 144 : && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
2804 144 : == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
2805 26862442 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2806 : {
2807 0 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2808 :
2809 0 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2810 0 : if (tem)
2811 : {
2812 0 : tem = simplify_gen_binary (AND, mode, tem, c);
2813 0 : if (tem)
2814 : return tem;
2815 : }
2816 : }
2817 : return NULL_RTX;
2818 : }
2819 :
2820 :
2821 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2822 : and OP1. Return 0 if no simplification is possible.
2823 :
2824 : Don't use this for relational operations such as EQ or LT.
2825 : Use simplify_relational_operation instead. */
2826 : rtx
2827 475808628 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2828 : rtx op0, rtx op1)
2829 : {
2830 475808628 : rtx trueop0, trueop1;
2831 475808628 : rtx tem;
2832 :
2833 : /* Relational operations don't work here. We must know the mode
2834 : of the operands in order to do the comparison correctly.
2835 : Assuming a full word can give incorrect results.
2836 : Consider comparing 128 with -128 in QImode. */
2837 475808628 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2838 475808628 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2839 :
2840 : /* Make sure the constant is second. */
2841 475808628 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2842 475808628 : && swap_commutative_operands_p (op0, op1))
2843 : std::swap (op0, op1);
2844 :
2845 475808628 : trueop0 = avoid_constant_pool_reference (op0);
2846 475808628 : trueop1 = avoid_constant_pool_reference (op1);
2847 :
2848 475808628 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2849 475808628 : if (tem)
2850 : return tem;
2851 446429538 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2852 :
2853 446429538 : if (tem)
2854 : return tem;
2855 :
2856 : /* If the above steps did not result in a simplification and op0 or op1
2857 : were constant pool references, use the referenced constants directly. */
2858 383468086 : if (trueop0 != op0 || trueop1 != op1)
2859 584665 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2860 :
2861 : return NULL_RTX;
2862 : }
2863 :
2864 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2865 : which OP0 and OP1 are both vector series or vector duplicates
2866 : (which are really just series with a step of 0). If so, try to
2867 : form a new series by applying CODE to the bases and to the steps.
2868 : Return null if no simplification is possible.
2869 :
2870 : MODE is the mode of the operation and is known to be a vector
2871 : integer mode. */
2872 :
2873 : rtx
2874 2482626 : simplify_context::simplify_binary_operation_series (rtx_code code,
2875 : machine_mode mode,
2876 : rtx op0, rtx op1)
2877 : {
2878 2482626 : rtx base0, step0;
2879 2482626 : if (vec_duplicate_p (op0, &base0))
2880 71116 : step0 = const0_rtx;
2881 2411510 : else if (!vec_series_p (op0, &base0, &step0))
2882 : return NULL_RTX;
2883 :
2884 71834 : rtx base1, step1;
2885 71834 : if (vec_duplicate_p (op1, &base1))
2886 421 : step1 = const0_rtx;
2887 71413 : else if (!vec_series_p (op1, &base1, &step1))
2888 : return NULL_RTX;
2889 :
2890 : /* Only create a new series if we can simplify both parts. In other
2891 : cases this isn't really a simplification, and it's not necessarily
2892 : a win to replace a vector operation with a scalar operation. */
2893 5657 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2894 5657 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2895 5657 : if (!new_base)
2896 : return NULL_RTX;
2897 :
2898 4719 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2899 4719 : if (!new_step)
2900 : return NULL_RTX;
2901 :
2902 4719 : return gen_vec_series (mode, new_base, new_step);
2903 : }
2904 :
2905 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2906 : operation CODE with result mode MODE, operating on OP0 and OP1.
2907 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2908 : Returns NULL_RTX if no simplification is possible. */
2909 :
2910 : rtx
2911 1315310 : simplify_context::simplify_distributive_operation (rtx_code code,
2912 : machine_mode mode,
2913 : rtx op0, rtx op1)
2914 : {
2915 1315310 : enum rtx_code op = GET_CODE (op0);
2916 1315310 : gcc_assert (GET_CODE (op1) == op);
2917 :
2918 1315310 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2919 1315310 : && ! side_effects_p (XEXP (op0, 1)))
2920 339243 : return simplify_gen_binary (op, mode,
2921 : simplify_gen_binary (code, mode,
2922 : XEXP (op0, 0),
2923 : XEXP (op1, 0)),
2924 339243 : XEXP (op0, 1));
2925 :
2926 976067 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2927 : {
2928 957303 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2929 957303 : && ! side_effects_p (XEXP (op0, 0)))
2930 470610 : return simplify_gen_binary (op, mode,
2931 : simplify_gen_binary (code, mode,
2932 : XEXP (op0, 1),
2933 : XEXP (op1, 1)),
2934 470610 : XEXP (op0, 0));
2935 486693 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2936 486693 : && ! side_effects_p (XEXP (op0, 0)))
2937 55 : return simplify_gen_binary (op, mode,
2938 : simplify_gen_binary (code, mode,
2939 : XEXP (op0, 1),
2940 : XEXP (op1, 0)),
2941 55 : XEXP (op0, 0));
2942 486638 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2943 486638 : && ! side_effects_p (XEXP (op0, 1)))
2944 246314 : return simplify_gen_binary (op, mode,
2945 : simplify_gen_binary (code, mode,
2946 : XEXP (op0, 0),
2947 : XEXP (op1, 1)),
2948 246314 : XEXP (op0, 1));
2949 : }
2950 :
2951 : return NULL_RTX;
2952 : }
2953 :
2954 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2955 : should be reversed.
2956 :
2957 : If the rotate should not be reversed, return FALSE.
2958 :
2959 : LEFT indicates if this is a rotate left or a rotate right. */
2960 :
2961 : bool
2962 136012 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2963 : {
2964 136012 : if (!CONST_INT_P (op1))
2965 : return false;
2966 :
2967 : /* Some targets may only be able to rotate by a constant
2968 : in one direction. So we need to query the optab interface
2969 : to see what is possible. */
2970 104470 : optab binoptab = left ? rotl_optab : rotr_optab;
2971 45580 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2972 104470 : enum insn_code icode = optab_handler (binoptab, mode);
2973 104470 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2974 :
2975 : /* If the target can not support the reversed optab, then there
2976 : is nothing to do. */
2977 104470 : if (re_icode == CODE_FOR_nothing)
2978 : return false;
2979 :
2980 : /* If the target does not support the requested rotate-by-immediate,
2981 : then we want to try reversing the rotate. We also want to try
2982 : reversing to minimize the count. */
2983 102012 : if ((icode == CODE_FOR_nothing)
2984 102012 : || (!insn_operand_matches (icode, 2, op1))
2985 510060 : || (IN_RANGE (INTVAL (op1),
2986 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
2987 : GET_MODE_UNIT_PRECISION (mode) - 1)))
2988 14289 : return (insn_operand_matches (re_icode, 2, op1));
2989 : return false;
2990 : }
2991 :
2992 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
2993 : and return the expression to be shifted in SHIFT_OPND and the shift amount
2994 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
2995 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
2996 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
2997 :
2998 : static bool
2999 529406151 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
3000 : {
3001 529406151 : if (GET_CODE (x) == ASHIFT)
3002 : {
3003 13721580 : *shift_opnd = XEXP (x, 0);
3004 13721580 : *shift_amnt = XEXP (x, 1);
3005 13721580 : return true;
3006 : }
3007 515684571 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
3008 : {
3009 11687 : *shift_opnd = XEXP (x, 0);
3010 11687 : *shift_amnt = CONST1_RTX (GET_MODE (x));
3011 11687 : return true;
3012 : }
3013 515672884 : *shift_opnd = NULL_RTX;
3014 515672884 : *shift_amnt = NULL_RTX;
3015 515672884 : return false;
3016 : }
3017 :
3018 : /* OP0 and OP1 are combined under an operation of mode MODE that can
3019 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
3020 : and return the resulting ROTATE expression if so. Return NULL otherwise.
3021 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
3022 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
3023 : (X << C1) and (C >> C2) would be OP0 and OP1. */
3024 :
3025 : static rtx
3026 267255590 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
3027 : {
3028 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3029 : mode size to (rotate A CX). */
3030 :
3031 267255590 : rtx opleft = op0;
3032 267255590 : rtx opright = op1;
3033 267255590 : rtx ashift_opnd, ashift_amnt;
3034 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
3035 : the relevant operands here. */
3036 267255590 : bool ashift_op_p
3037 267255590 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
3038 :
3039 267255590 : if (ashift_op_p
3040 265640581 : || GET_CODE (op1) == SUBREG)
3041 : {
3042 : opleft = op1;
3043 : opright = op0;
3044 : }
3045 : else
3046 : {
3047 262150561 : opright = op1;
3048 262150561 : opleft = op0;
3049 262150561 : ashift_op_p
3050 262150561 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
3051 : }
3052 :
3053 13733267 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
3054 265678044 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
3055 : {
3056 9423 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
3057 9423 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
3058 :
3059 5611 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
3060 15034 : && (INTVAL (leftcst) + INTVAL (rightcst)
3061 5611 : == GET_MODE_UNIT_PRECISION (mode)))
3062 5084 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
3063 : }
3064 :
3065 : /* Same, but for ashift that has been "simplified" to a wider mode
3066 : by simplify_shift_const. */
3067 267250506 : scalar_int_mode int_mode, inner_mode;
3068 :
3069 267250506 : if (GET_CODE (opleft) == SUBREG
3070 272177565 : && is_a <scalar_int_mode> (mode, &int_mode)
3071 4921975 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3072 : &inner_mode)
3073 4890787 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3074 163890 : && GET_CODE (opright) == LSHIFTRT
3075 1105 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3076 237 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3077 470 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3078 221 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3079 221 : SUBREG_REG (XEXP (opright, 0)))
3080 5 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3081 5 : && CONST_INT_P (XEXP (opright, 1))
3082 267250506 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3083 5 : + INTVAL (XEXP (opright, 1))
3084 5 : == GET_MODE_PRECISION (int_mode)))
3085 1 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3086 : XEXP (SUBREG_REG (opleft), 1));
3087 : return NULL_RTX;
3088 : }
3089 :
3090 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3091 : and the pattern can be simplified (there are no side effects). */
3092 :
3093 : static bool
3094 38703036 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3095 : {
3096 : /* Remove SUBREG from OP0 and OP1, if needed. */
3097 38703036 : if (GET_CODE (op0) == SUBREG
3098 7150842 : && GET_CODE (op1) == SUBREG
3099 306695 : && subreg_lowpart_p (op0)
3100 39008327 : && subreg_lowpart_p (op1))
3101 : {
3102 305282 : op0 = XEXP (op0, 0);
3103 305282 : op1 = XEXP (op1, 0);
3104 : }
3105 :
3106 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3107 38703036 : if (((GET_CODE (op1) == NEG
3108 3744 : && GET_CODE (op0) == PLUS
3109 2199 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3110 38702378 : || (GET_CODE (op0) == NEG
3111 80410 : && GET_CODE (op1) == PLUS
3112 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3113 658 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3114 38703038 : && !side_effects_p (XEXP (op0, 0)))
3115 : return true;
3116 : return false;
3117 : }
3118 :
3119 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3120 : non-paradoxical. */
3121 :
3122 : static bool
3123 73372018 : non_paradoxical_subreg_not_p (rtx op)
3124 : {
3125 73372018 : return GET_CODE (op) == SUBREG
3126 8676402 : && !paradoxical_subreg_p (op)
3127 76282896 : && GET_CODE (SUBREG_REG (op)) == NOT;
3128 : }
3129 :
3130 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3131 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3132 : opportunities to combine another binary logical operation with NOT. */
3133 :
3134 : static rtx
3135 36687181 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3136 : {
3137 36687181 : rtx opn = NULL_RTX;
3138 36687181 : if (non_paradoxical_subreg_not_p (op0))
3139 : opn = op0;
3140 36684837 : else if (non_paradoxical_subreg_not_p (op1))
3141 : opn = op1;
3142 :
3143 2367 : if (opn == NULL_RTX)
3144 : return NULL_RTX;
3145 :
3146 4734 : rtx new_subreg = simplify_gen_subreg (mode,
3147 : XEXP (SUBREG_REG (opn), 0),
3148 2367 : GET_MODE (SUBREG_REG (opn)),
3149 2367 : SUBREG_BYTE (opn));
3150 :
3151 2367 : if (!new_subreg)
3152 : return NULL_RTX;
3153 :
3154 2312 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3155 2312 : if (opn == op0)
3156 2289 : return simplify_gen_binary (binop, mode, new_not, op1);
3157 : else
3158 23 : return simplify_gen_binary (binop, mode, op0, new_not);
3159 : }
3160 :
3161 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3162 : static bool
3163 6592322 : negated_ops_p (rtx nop, rtx op)
3164 : {
3165 : /* Explicit negation. */
3166 6592322 : if (GET_CODE (nop) == NOT
3167 6592322 : && rtx_equal_p (XEXP (nop, 0), op))
3168 : return true;
3169 6588948 : if (GET_CODE (op) == NOT
3170 6588948 : && rtx_equal_p (XEXP (op, 0), nop))
3171 : return true;
3172 :
3173 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3174 6588362 : if (GET_CODE (op) == ASHIFT
3175 1392745 : && GET_CODE (nop) == ROTATE
3176 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3177 0 : && CONST_INT_P (XEXP (nop, 0))
3178 0 : && INTVAL (XEXP (nop, 0)) == -2
3179 6588362 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3180 : return true;
3181 6588362 : if (GET_CODE (nop) == ASHIFT
3182 156842 : && GET_CODE (op) == ROTATE
3183 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3184 0 : && CONST_INT_P (XEXP (nop, 0))
3185 0 : && INTVAL (XEXP (nop, 0)) == -2
3186 6588362 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3187 : return true;
3188 :
3189 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3190 :
3191 : return false;
3192 : }
3193 :
3194 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3195 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3196 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3197 : actual constants. */
3198 :
3199 : rtx
3200 446429538 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3201 : machine_mode mode,
3202 : rtx op0, rtx op1,
3203 : rtx trueop0, rtx trueop1)
3204 : {
3205 446429538 : rtx tem, reversed, elt0, elt1;
3206 446429538 : HOST_WIDE_INT val;
3207 446429538 : scalar_int_mode int_mode, inner_mode;
3208 446429538 : poly_int64 offset;
3209 :
3210 : /* Even if we can't compute a constant result,
3211 : there are some cases worth simplifying. */
3212 :
3213 446429538 : switch (code)
3214 : {
3215 257246637 : case PLUS:
3216 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3217 : when x is NaN, infinite, or finite and nonzero. They aren't
3218 : when x is -0 and the rounding mode is not towards -infinity,
3219 : since (-0) + 0 is then 0. */
3220 510591408 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3221 510591396 : && trueop1 == CONST0_RTX (mode))
3222 : return op0;
3223 :
3224 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3225 : transformations are safe even for IEEE. */
3226 255784005 : if (GET_CODE (op0) == NEG)
3227 55583 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3228 255728422 : else if (GET_CODE (op1) == NEG)
3229 7542 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3230 :
3231 : /* (~a) + 1 -> -a */
3232 255720880 : if (INTEGRAL_MODE_P (mode)
3233 250911701 : && GET_CODE (op0) == NOT
3234 1169401 : && trueop1 == const1_rtx)
3235 3803 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3236 :
3237 : /* Handle both-operands-constant cases. We can only add
3238 : CONST_INTs to constants since the sum of relocatable symbols
3239 : can't be handled by most assemblers. Don't add CONST_INT
3240 : to CONST_INT since overflow won't be computed properly if wider
3241 : than HOST_BITS_PER_WIDE_INT. */
3242 :
3243 255717077 : if ((GET_CODE (op0) == CONST
3244 255717077 : || GET_CODE (op0) == SYMBOL_REF
3245 253133889 : || GET_CODE (op0) == LABEL_REF)
3246 255717077 : && poly_int_rtx_p (op1, &offset))
3247 2582219 : return plus_constant (mode, op0, offset);
3248 253134858 : else if ((GET_CODE (op1) == CONST
3249 253134858 : || GET_CODE (op1) == SYMBOL_REF
3250 248897384 : || GET_CODE (op1) == LABEL_REF)
3251 253134858 : && poly_int_rtx_p (op0, &offset))
3252 0 : return plus_constant (mode, op1, offset);
3253 :
3254 : /* See if this is something like X * C - X or vice versa or
3255 : if the multiplication is written as a shift. If so, we can
3256 : distribute and make a new multiply, shift, or maybe just
3257 : have X (if C is 2 in the example above). But don't make
3258 : something more expensive than we had before. */
3259 :
3260 253134858 : if (is_a <scalar_int_mode> (mode, &int_mode))
3261 : {
3262 246162011 : rtx lhs = op0, rhs = op1;
3263 :
3264 246162011 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3265 246162011 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3266 :
3267 246162011 : if (GET_CODE (lhs) == NEG)
3268 : {
3269 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3270 0 : lhs = XEXP (lhs, 0);
3271 : }
3272 246162011 : else if (GET_CODE (lhs) == MULT
3273 9818289 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3274 : {
3275 8710721 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3276 8710721 : lhs = XEXP (lhs, 0);
3277 : }
3278 237451290 : else if (GET_CODE (lhs) == ASHIFT
3279 11086791 : && CONST_INT_P (XEXP (lhs, 1))
3280 11015040 : && INTVAL (XEXP (lhs, 1)) >= 0
3281 248466318 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3282 : {
3283 11015028 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3284 22030056 : GET_MODE_PRECISION (int_mode));
3285 11015028 : lhs = XEXP (lhs, 0);
3286 : }
3287 :
3288 246162011 : if (GET_CODE (rhs) == NEG)
3289 : {
3290 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3291 0 : rhs = XEXP (rhs, 0);
3292 : }
3293 246162011 : else if (GET_CODE (rhs) == MULT
3294 294478 : && CONST_INT_P (XEXP (rhs, 1)))
3295 : {
3296 190015 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3297 190015 : rhs = XEXP (rhs, 0);
3298 : }
3299 245971996 : else if (GET_CODE (rhs) == ASHIFT
3300 532273 : && CONST_INT_P (XEXP (rhs, 1))
3301 522496 : && INTVAL (XEXP (rhs, 1)) >= 0
3302 246494492 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3303 : {
3304 522496 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3305 1044992 : GET_MODE_PRECISION (int_mode));
3306 522496 : rhs = XEXP (rhs, 0);
3307 : }
3308 :
3309 : /* Keep PLUS of 2 volatile memory references. */
3310 246162011 : if (rtx_equal_p (lhs, rhs)
3311 246162011 : && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
3312 : {
3313 821538 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3314 821538 : rtx coeff;
3315 821538 : bool speed = optimize_function_for_speed_p (cfun);
3316 :
3317 821538 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3318 :
3319 821538 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3320 821538 : return (set_src_cost (tem, int_mode, speed)
3321 821538 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3322 : }
3323 :
3324 : /* Optimize (X - 1) * Y + Y to X * Y. */
3325 245340473 : lhs = op0;
3326 245340473 : rhs = op1;
3327 245340473 : if (GET_CODE (op0) == MULT)
3328 : {
3329 9764659 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3330 644231 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3331 9720428 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3332 53525 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3333 9808890 : && rtx_equal_p (XEXP (op0, 1), op1))
3334 46 : lhs = XEXP (XEXP (op0, 0), 0);
3335 9764613 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3336 1342 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3337 9764547 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3338 339 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3339 9764679 : && rtx_equal_p (XEXP (op0, 0), op1))
3340 0 : lhs = XEXP (XEXP (op0, 1), 0);
3341 : }
3342 235575814 : else if (GET_CODE (op1) == MULT)
3343 : {
3344 122591 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3345 46 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3346 122587 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3347 27 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3348 122595 : && rtx_equal_p (XEXP (op1, 1), op0))
3349 0 : rhs = XEXP (XEXP (op1, 0), 0);
3350 122591 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3351 0 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3352 122591 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3353 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3354 122591 : && rtx_equal_p (XEXP (op1, 0), op0))
3355 0 : rhs = XEXP (XEXP (op1, 1), 0);
3356 : }
3357 245340473 : if (lhs != op0 || rhs != op1)
3358 46 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3359 246162011 : }
3360 :
3361 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3362 252313274 : if (CONST_SCALAR_INT_P (op1)
3363 191450020 : && GET_CODE (op0) == XOR
3364 18653 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3365 252323429 : && mode_signbit_p (mode, op1))
3366 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3367 : simplify_gen_binary (XOR, mode, op1,
3368 121 : XEXP (op0, 1)));
3369 :
3370 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3371 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3372 252313153 : if (CONST_SCALAR_INT_P (op1)
3373 191449899 : && GET_CODE (op0) == XOR
3374 18532 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3375 10034 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3376 189 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3377 252313153 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3378 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3379 : simplify_gen_binary (XOR, mode, op1,
3380 0 : XEXP (op0, 1)));
3381 :
3382 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3383 252313153 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3384 252310673 : && GET_CODE (op0) == MULT
3385 262445892 : && GET_CODE (XEXP (op0, 0)) == NEG)
3386 : {
3387 5538 : rtx in1, in2;
3388 :
3389 5538 : in1 = XEXP (XEXP (op0, 0), 0);
3390 5538 : in2 = XEXP (op0, 1);
3391 5538 : return simplify_gen_binary (MINUS, mode, op1,
3392 : simplify_gen_binary (MULT, mode,
3393 5538 : in1, in2));
3394 : }
3395 :
3396 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3397 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3398 : is 1. */
3399 252307615 : if (COMPARISON_P (op0)
3400 1248507 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3401 1248507 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3402 252364337 : && (reversed = reversed_comparison (op0, mode)))
3403 56373 : return
3404 56373 : simplify_gen_unary (NEG, mode, reversed, mode);
3405 :
3406 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3407 : mode size to (rotate A CX). */
3408 252251242 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3409 : return tem;
3410 :
3411 : /* If one of the operands is a PLUS or a MINUS, see if we can
3412 : simplify this by the associative law.
3413 : Don't use the associative law for floating point.
3414 : The inaccuracy makes it nonassociative,
3415 : and subtle programs can break if operations are associated. */
3416 :
3417 252249772 : if (INTEGRAL_MODE_P (mode)
3418 247440642 : && (plus_minus_operand_p (op0)
3419 213764988 : || plus_minus_operand_p (op1))
3420 34778982 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3421 : return tem;
3422 :
3423 : /* Reassociate floating point addition only when the user
3424 : specifies associative math operations. */
3425 218184747 : if (FLOAT_MODE_P (mode)
3426 4809130 : && flag_associative_math)
3427 : {
3428 907263 : tem = simplify_associative_operation (code, mode, op0, op1);
3429 907263 : if (tem)
3430 : return tem;
3431 : }
3432 :
3433 : /* Handle vector series. */
3434 218170914 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3435 : {
3436 1998407 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3437 1998407 : if (tem)
3438 : return tem;
3439 : }
3440 : break;
3441 :
3442 : case COMPARE:
3443 : break;
3444 :
3445 42998041 : case MINUS:
3446 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3447 : but since it is zero except in very strange circumstances, we
3448 : will treat it as zero with -ffinite-math-only. */
3449 42998041 : if (rtx_equal_p (trueop0, trueop1)
3450 217204 : && ! side_effects_p (op0)
3451 43214003 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3452 213507 : return CONST0_RTX (mode);
3453 :
3454 : /* Change subtraction from zero into negation. (0 - x) is the
3455 : same as -x when x is NaN, infinite, or finite and nonzero.
3456 : But if the mode has signed zeros, and does not round towards
3457 : -infinity, then 0 - 0 is 0, not -0. */
3458 42784534 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3459 339767 : return simplify_gen_unary (NEG, mode, op1, mode);
3460 :
3461 : /* (-1 - a) is ~a, unless the expression contains symbolic
3462 : constants, in which case not retaining additions and
3463 : subtractions could cause invalid assembly to be produced. */
3464 42444767 : if (trueop0 == CONSTM1_RTX (mode)
3465 42444767 : && !contains_symbolic_reference_p (op1))
3466 542373 : return simplify_gen_unary (NOT, mode, op1, mode);
3467 :
3468 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3469 : or has signed zeros and supports rounding towards -infinity.
3470 : In such a case, 0 - 0 is -0. */
3471 42629754 : if (!(HONOR_SIGNED_ZEROS (mode)
3472 727360 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3473 41901244 : && !HONOR_SNANS (mode)
3474 83803602 : && trueop1 == CONST0_RTX (mode))
3475 : return op0;
3476 :
3477 : /* See if this is something like X * C - X or vice versa or
3478 : if the multiplication is written as a shift. If so, we can
3479 : distribute and make a new multiply, shift, or maybe just
3480 : have X (if C is 2 in the example above). But don't make
3481 : something more expensive than we had before. */
3482 :
3483 40958008 : if (is_a <scalar_int_mode> (mode, &int_mode))
3484 : {
3485 39602765 : rtx lhs = op0, rhs = op1;
3486 :
3487 39602765 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3488 39602765 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3489 :
3490 39602765 : if (GET_CODE (lhs) == NEG)
3491 : {
3492 70587 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3493 70587 : lhs = XEXP (lhs, 0);
3494 : }
3495 39532178 : else if (GET_CODE (lhs) == MULT
3496 192123 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3497 : {
3498 73016 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3499 73016 : lhs = XEXP (lhs, 0);
3500 : }
3501 39459162 : else if (GET_CODE (lhs) == ASHIFT
3502 333708 : && CONST_INT_P (XEXP (lhs, 1))
3503 330506 : && INTVAL (XEXP (lhs, 1)) >= 0
3504 39789647 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3505 : {
3506 330485 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3507 660970 : GET_MODE_PRECISION (int_mode));
3508 330485 : lhs = XEXP (lhs, 0);
3509 : }
3510 :
3511 39602765 : if (GET_CODE (rhs) == NEG)
3512 : {
3513 11068 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3514 11068 : rhs = XEXP (rhs, 0);
3515 : }
3516 39591697 : else if (GET_CODE (rhs) == MULT
3517 150758 : && CONST_INT_P (XEXP (rhs, 1)))
3518 : {
3519 97543 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3520 97543 : rhs = XEXP (rhs, 0);
3521 : }
3522 39494154 : else if (GET_CODE (rhs) == ASHIFT
3523 381931 : && CONST_INT_P (XEXP (rhs, 1))
3524 381424 : && INTVAL (XEXP (rhs, 1)) >= 0
3525 39875578 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3526 : {
3527 381424 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3528 762848 : GET_MODE_PRECISION (int_mode));
3529 381424 : negcoeff1 = -negcoeff1;
3530 381424 : rhs = XEXP (rhs, 0);
3531 : }
3532 :
3533 39602765 : if (rtx_equal_p (lhs, rhs))
3534 : {
3535 101656 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3536 101656 : rtx coeff;
3537 101656 : bool speed = optimize_function_for_speed_p (cfun);
3538 :
3539 101656 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3540 :
3541 101656 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3542 101656 : return (set_src_cost (tem, int_mode, speed)
3543 101656 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3544 : }
3545 :
3546 : /* Optimize (X + 1) * Y - Y to X * Y. */
3547 39501109 : lhs = op0;
3548 39501109 : if (GET_CODE (op0) == MULT)
3549 : {
3550 191649 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3551 4821 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3552 190101 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3553 1641 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3554 193197 : && rtx_equal_p (XEXP (op0, 1), op1))
3555 2 : lhs = XEXP (XEXP (op0, 0), 0);
3556 191647 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3557 30 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3558 191641 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3559 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3560 191653 : && rtx_equal_p (XEXP (op0, 0), op1))
3561 0 : lhs = XEXP (XEXP (op0, 1), 0);
3562 : }
3563 39501109 : if (lhs != op0)
3564 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3565 39602765 : }
3566 :
3567 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3568 40856350 : if (GET_CODE (op1) == NEG)
3569 11030 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3570 :
3571 : /* (-x - c) may be simplified as (-c - x). */
3572 40845320 : if (GET_CODE (op0) == NEG
3573 74713 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3574 : {
3575 617 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3576 617 : if (tem)
3577 617 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3578 : }
3579 :
3580 40844703 : if ((GET_CODE (op0) == CONST
3581 40844703 : || GET_CODE (op0) == SYMBOL_REF
3582 35887771 : || GET_CODE (op0) == LABEL_REF)
3583 40844703 : && poly_int_rtx_p (op1, &offset))
3584 51522 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3585 :
3586 : /* Don't let a relocatable value get a negative coeff. */
3587 40793181 : if (is_a <scalar_int_mode> (mode)
3588 39437969 : && poly_int_rtx_p (op1)
3589 47711249 : && GET_MODE (op0) != VOIDmode)
3590 6918068 : return simplify_gen_binary (PLUS, mode,
3591 : op0,
3592 6918068 : neg_poly_int_rtx (mode, op1));
3593 :
3594 : /* (x - (x & y)) -> (x & ~y) */
3595 33875113 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3596 : {
3597 264829 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3598 : {
3599 512 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3600 256 : GET_MODE (XEXP (op1, 1)));
3601 256 : return simplify_gen_binary (AND, mode, op0, tem);
3602 : }
3603 264573 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3604 : {
3605 2266 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3606 1133 : GET_MODE (XEXP (op1, 0)));
3607 1133 : return simplify_gen_binary (AND, mode, op0, tem);
3608 : }
3609 : }
3610 :
3611 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3612 : by reversing the comparison code if valid. */
3613 33873724 : if (STORE_FLAG_VALUE == 1
3614 33873724 : && trueop0 == const1_rtx
3615 1114639 : && COMPARISON_P (op1)
3616 33979575 : && (reversed = reversed_comparison (op1, mode)))
3617 : return reversed;
3618 :
3619 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3620 33767896 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3621 33766545 : && GET_CODE (op1) == MULT
3622 34018362 : && GET_CODE (XEXP (op1, 0)) == NEG)
3623 : {
3624 165 : rtx in1, in2;
3625 :
3626 165 : in1 = XEXP (XEXP (op1, 0), 0);
3627 165 : in2 = XEXP (op1, 1);
3628 165 : return simplify_gen_binary (PLUS, mode,
3629 : simplify_gen_binary (MULT, mode,
3630 : in1, in2),
3631 165 : op0);
3632 : }
3633 :
3634 : /* Canonicalize (minus (neg A) (mult B C)) to
3635 : (minus (mult (neg B) C) A). */
3636 33767731 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3637 33766380 : && GET_CODE (op1) == MULT
3638 34018032 : && GET_CODE (op0) == NEG)
3639 : {
3640 663 : rtx in1, in2;
3641 :
3642 663 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3643 663 : in2 = XEXP (op1, 1);
3644 663 : return simplify_gen_binary (MINUS, mode,
3645 : simplify_gen_binary (MULT, mode,
3646 : in1, in2),
3647 663 : XEXP (op0, 0));
3648 : }
3649 :
3650 : /* If one of the operands is a PLUS or a MINUS, see if we can
3651 : simplify this by the associative law. This will, for example,
3652 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3653 : Don't use the associative law for floating point.
3654 : The inaccuracy makes it nonassociative,
3655 : and subtle programs can break if operations are associated. */
3656 :
3657 33767068 : if (INTEGRAL_MODE_P (mode)
3658 32919173 : && (plus_minus_operand_p (op0)
3659 30153942 : || plus_minus_operand_p (op1))
3660 3960445 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3661 : return tem;
3662 :
3663 : /* Handle vector series. */
3664 29952065 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3665 : {
3666 484219 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3667 484219 : if (tem)
3668 : return tem;
3669 : }
3670 : break;
3671 :
3672 12195858 : case MULT:
3673 12195858 : if (trueop1 == constm1_rtx)
3674 33372 : return simplify_gen_unary (NEG, mode, op0, mode);
3675 :
3676 12162486 : if (GET_CODE (op0) == NEG)
3677 : {
3678 34322 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3679 : /* If op1 is a MULT as well and simplify_unary_operation
3680 : just moved the NEG to the second operand, simplify_gen_binary
3681 : below could through simplify_associative_operation move
3682 : the NEG around again and recurse endlessly. */
3683 34322 : if (temp
3684 2547 : && GET_CODE (op1) == MULT
3685 0 : && GET_CODE (temp) == MULT
3686 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3687 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3688 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3689 : temp = NULL_RTX;
3690 : if (temp)
3691 2547 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3692 : }
3693 12159939 : if (GET_CODE (op1) == NEG)
3694 : {
3695 904 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3696 : /* If op0 is a MULT as well and simplify_unary_operation
3697 : just moved the NEG to the second operand, simplify_gen_binary
3698 : below could through simplify_associative_operation move
3699 : the NEG around again and recurse endlessly. */
3700 904 : if (temp
3701 419 : && GET_CODE (op0) == MULT
3702 301 : && GET_CODE (temp) == MULT
3703 301 : && XEXP (op0, 0) == XEXP (temp, 0)
3704 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3705 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3706 : temp = NULL_RTX;
3707 : if (temp)
3708 414 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3709 : }
3710 :
3711 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3712 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3713 : when the mode has signed zeros, since multiplying a negative
3714 : number by 0 will give -0, not 0. */
3715 12159525 : if (!HONOR_NANS (mode)
3716 11198703 : && !HONOR_SIGNED_ZEROS (mode)
3717 11198260 : && trueop1 == CONST0_RTX (mode)
3718 12201486 : && ! side_effects_p (op0))
3719 : return op1;
3720 :
3721 : /* In IEEE floating point, x*1 is not equivalent to x for
3722 : signalling NaNs. */
3723 12118808 : if (!HONOR_SNANS (mode)
3724 12118808 : && trueop1 == CONST1_RTX (mode))
3725 : return op0;
3726 :
3727 : /* Convert multiply by constant power of two into shift. */
3728 11603024 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3729 : {
3730 6280258 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3731 6280258 : if (val >= 0)
3732 3000758 : return simplify_gen_binary (ASHIFT, mode, op0,
3733 3000758 : gen_int_shift_amount (mode, val));
3734 : }
3735 :
3736 : /* x*2 is x+x and x*(-1) is -x */
3737 8602266 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3738 167876 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3739 167876 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3740 167592 : && GET_MODE (op0) == mode)
3741 : {
3742 167592 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3743 :
3744 167592 : if (real_equal (d1, &dconst2))
3745 624 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3746 :
3747 166968 : if (!HONOR_SNANS (mode)
3748 166968 : && real_equal (d1, &dconstm1))
3749 24 : return simplify_gen_unary (NEG, mode, op0, mode);
3750 : }
3751 :
3752 : /* Optimize -x * -x as x * x. */
3753 8601618 : if (FLOAT_MODE_P (mode)
3754 1379490 : && GET_CODE (op0) == NEG
3755 7986 : && GET_CODE (op1) == NEG
3756 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3757 0 : && !side_effects_p (XEXP (op0, 0)))
3758 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3759 :
3760 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3761 8601618 : if (SCALAR_FLOAT_MODE_P (mode)
3762 1089954 : && GET_CODE (op0) == ABS
3763 1293 : && GET_CODE (op1) == ABS
3764 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3765 8601618 : && !side_effects_p (XEXP (op0, 0)))
3766 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3767 :
3768 : /* Reassociate multiplication, but for floating point MULTs
3769 : only when the user specifies unsafe math optimizations. */
3770 8601618 : if (! FLOAT_MODE_P (mode)
3771 1379490 : || flag_unsafe_math_optimizations)
3772 : {
3773 7641918 : tem = simplify_associative_operation (code, mode, op0, op1);
3774 7641918 : if (tem)
3775 : return tem;
3776 : }
3777 : break;
3778 :
3779 14836433 : case IOR:
3780 14836433 : if (trueop1 == CONST0_RTX (mode))
3781 : return op0;
3782 14052571 : if (INTEGRAL_MODE_P (mode)
3783 13777935 : && trueop1 == CONSTM1_RTX (mode)
3784 9608 : && !side_effects_p (op0))
3785 : return op1;
3786 14042963 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3787 : return op0;
3788 : /* A | (~A) -> -1 */
3789 74585 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3790 14024316 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3791 11 : && ! side_effects_p (op0)
3792 14024338 : && GET_MODE_CLASS (mode) != MODE_CC)
3793 11 : return CONSTM1_RTX (mode);
3794 :
3795 : /* IOR of two single bit bitfields extracted from the same object.
3796 : Bitfields are represented as an AND based extraction */
3797 14024316 : if (GET_CODE (op0) == AND
3798 3972655 : && GET_CODE (op1) == AND
3799 : /* Verify both AND operands are logical right shifts. */
3800 283799 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3801 1588 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3802 : /* Verify both bitfields are extracted from the same object. */
3803 54 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3804 : /* Verify both fields are a single bit (could be generalized). */
3805 54 : && XEXP (op0, 1) == CONST1_RTX (mode)
3806 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3807 : /* Verify bit positions (for cases with variable bit position). */
3808 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3809 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3810 : {
3811 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3812 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3813 0 : unsigned HOST_WIDE_INT mask
3814 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3815 :
3816 0 : rtx m = GEN_INT (mask);
3817 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3818 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3819 0 : return t;
3820 : }
3821 :
3822 : /* IOR of multiple single bit bitfields extracted from the same object
3823 : (building on previous case).
3824 : First bitfield is represented as an AND based extraction, as done
3825 : above. Second represented as NE based extraction, from
3826 : output above. */
3827 14024316 : if (GET_CODE (op0) == AND
3828 3972655 : && GET_CODE (op1) == NE
3829 : /* Verify AND operand is logical right shift. */
3830 3953 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3831 : /* Verify NE operand is an AND (based on output above). */
3832 86 : && GET_CODE (XEXP (op1, 0)) == AND
3833 : /* Verify both bitfields are extracted from the same object. */
3834 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3835 : /* Verify masking is with a single bit and that we have a NE 0
3836 : comparison for the other operand. */
3837 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3838 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3839 : /* Verify bit position. */
3840 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3841 : {
3842 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3843 0 : unsigned HOST_WIDE_INT mask
3844 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3845 :
3846 0 : rtx m = GEN_INT (mask);
3847 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3848 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3849 0 : return t;
3850 : }
3851 :
3852 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3853 14024316 : if (match_plus_neg_pattern (op0, op1, mode))
3854 0 : return CONSTM1_RTX (mode);
3855 :
3856 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3857 14024316 : if (CONST_INT_P (op1)
3858 3470196 : && HWI_COMPUTABLE_MODE_P (mode)
3859 3416602 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3860 14389191 : && !side_effects_p (op0))
3861 : return op1;
3862 :
3863 : /* Canonicalize (X & C1) | C2. */
3864 13659441 : if (GET_CODE (op0) == AND
3865 3964051 : && CONST_INT_P (trueop1)
3866 654995 : && CONST_INT_P (XEXP (op0, 1)))
3867 : {
3868 487465 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3869 487465 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3870 487465 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3871 :
3872 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3873 487465 : if ((c1 & c2) == c1
3874 487465 : && !side_effects_p (XEXP (op0, 0)))
3875 : return trueop1;
3876 :
3877 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3878 487445 : if (((c1|c2) & mask) == mask)
3879 70760 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3880 :
3881 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3882 : when split it'll match a single bit clear style insn.
3883 :
3884 : This could have been done with a target dependent splitter, but
3885 : then every target with single bit manipulation insns would need
3886 : to implement such splitters. */
3887 416685 : if (exact_log2 (~(c1 | c2)) >= 0)
3888 : {
3889 59461 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3890 59461 : temp = gen_rtx_IOR (mode, temp, trueop1);
3891 59461 : return temp;
3892 : }
3893 : }
3894 :
3895 : /* Convert (A & B) | A to A. */
3896 13529200 : if (GET_CODE (op0) == AND
3897 3833810 : && (rtx_equal_p (XEXP (op0, 0), op1)
3898 3833699 : || rtx_equal_p (XEXP (op0, 1), op1))
3899 3787 : && ! side_effects_p (XEXP (op0, 0))
3900 13532987 : && ! side_effects_p (XEXP (op0, 1)))
3901 : return op1;
3902 :
3903 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3904 : mode size to (rotate A CX). */
3905 13525413 : tem = simplify_rotate_op (op0, op1, mode);
3906 13525413 : if (tem)
3907 : return tem;
3908 :
3909 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3910 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3911 : the PLUS does not affect any of the bits in OP1: then we can do
3912 : the IOR as a PLUS and we can associate. This is valid if OP1
3913 : can be safely shifted left C bits. */
3914 13523178 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3915 6153 : && GET_CODE (XEXP (op0, 0)) == PLUS
3916 141 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3917 87 : && CONST_INT_P (XEXP (op0, 1))
3918 87 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3919 : {
3920 87 : int count = INTVAL (XEXP (op0, 1));
3921 87 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3922 :
3923 87 : if (mask >> count == INTVAL (trueop1)
3924 80 : && trunc_int_for_mode (mask, mode) == mask
3925 154 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3926 0 : return simplify_gen_binary (ASHIFTRT, mode,
3927 : plus_constant (mode, XEXP (op0, 0),
3928 0 : mask),
3929 : XEXP (op0, 1));
3930 : }
3931 :
3932 : /* The following happens with bitfield merging.
3933 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3934 13523178 : if (GET_CODE (op0) == AND
3935 3830023 : && GET_CODE (op1) == AND
3936 283799 : && CONST_INT_P (XEXP (op0, 1))
3937 117023 : && CONST_INT_P (XEXP (op1, 1))
3938 111590 : && (INTVAL (XEXP (op0, 1))
3939 111590 : == ~INTVAL (XEXP (op1, 1))))
3940 : {
3941 : /* The IOR/XOR may be on both sides. */
3942 32105 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3943 32105 : if (GET_CODE (XEXP (op1, 0)) == IOR
3944 32105 : || GET_CODE (XEXP (op1, 0)) == XOR)
3945 : top0 = op0, top1 = op1;
3946 31986 : else if (GET_CODE (XEXP (op0, 0)) == IOR
3947 31986 : || GET_CODE (XEXP (op0, 0)) == XOR)
3948 3 : top0 = op1, top1 = op0;
3949 32105 : if (top0 && top1)
3950 : {
3951 : /* X may be on either side of the inner IOR/XOR. */
3952 122 : rtx tem = NULL_RTX;
3953 122 : if (rtx_equal_p (XEXP (top0, 0),
3954 122 : XEXP (XEXP (top1, 0), 0)))
3955 76 : tem = XEXP (XEXP (top1, 0), 1);
3956 46 : else if (rtx_equal_p (XEXP (top0, 0),
3957 46 : XEXP (XEXP (top1, 0), 1)))
3958 13 : tem = XEXP (XEXP (top1, 0), 0);
3959 89 : if (tem)
3960 89 : return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
3961 : mode, XEXP (top0, 0),
3962 : simplify_gen_binary
3963 89 : (AND, mode, tem, XEXP (top1, 1)));
3964 : }
3965 : }
3966 :
3967 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3968 13523089 : if (GET_CODE (op0) == GET_CODE (op1)
3969 3364999 : && (GET_CODE (op0) == AND
3970 : || GET_CODE (op0) == IOR
3971 3364999 : || GET_CODE (op0) == LSHIFTRT
3972 3080341 : || GET_CODE (op0) == ASHIFTRT
3973 3080211 : || GET_CODE (op0) == ASHIFT
3974 3063132 : || GET_CODE (op0) == ROTATE
3975 3063132 : || GET_CODE (op0) == ROTATERT))
3976 : {
3977 301867 : tem = simplify_distributive_operation (code, mode, op0, op1);
3978 301867 : if (tem)
3979 : return tem;
3980 : }
3981 :
3982 : /* Convert (ior (and (not A) B) A) into A | B. */
3983 13435256 : if (GET_CODE (op0) == AND
3984 13435256 : && negated_ops_p (XEXP (op0, 0), op1))
3985 3942 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
3986 :
3987 : /* op0/op1 may have a common term which in turn may allow simplification
3988 : of the the outer IOR. There are likely other cases we should
3989 : handle for the outer code as well as the form of the operands. */
3990 13431314 : tem = simplify_ior_with_common_term (mode, op0, op1);
3991 13431314 : if (tem)
3992 : return tem;
3993 :
3994 : /* IOR is commutative and we can't rely on canonicalization at this point,
3995 : so try again to simplify with the operands reversed. */
3996 13431221 : tem = simplify_ior_with_common_term (mode, op1, op0);
3997 13431221 : if (tem)
3998 : return tem;
3999 :
4000 13431221 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4001 13431221 : if (tem)
4002 : return tem;
4003 :
4004 13431216 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4005 13431216 : if (tem)
4006 : return tem;
4007 :
4008 13431183 : tem = simplify_associative_operation (code, mode, op0, op1);
4009 13431183 : if (tem)
4010 : return tem;
4011 :
4012 13160488 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
4013 13160488 : if (tem)
4014 : return tem;
4015 : break;
4016 :
4017 1751404 : case XOR:
4018 1751404 : if (trueop1 == CONST0_RTX (mode))
4019 : return op0;
4020 1695105 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4021 25046 : return simplify_gen_unary (NOT, mode, op0, mode);
4022 1670059 : if (rtx_equal_p (trueop0, trueop1)
4023 2483 : && ! side_effects_p (op0)
4024 1672538 : && GET_MODE_CLASS (mode) != MODE_CC)
4025 2479 : return CONST0_RTX (mode);
4026 :
4027 : /* Canonicalize XOR of the most significant bit to PLUS. */
4028 1667580 : if (CONST_SCALAR_INT_P (op1)
4029 1667580 : && mode_signbit_p (mode, op1))
4030 40030 : return simplify_gen_binary (PLUS, mode, op0, op1);
4031 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
4032 1627550 : if (CONST_SCALAR_INT_P (op1)
4033 486869 : && GET_CODE (op0) == PLUS
4034 2509 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
4035 1629144 : && mode_signbit_p (mode, XEXP (op0, 1)))
4036 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
4037 : simplify_gen_binary (XOR, mode, op1,
4038 189 : XEXP (op0, 1)));
4039 :
4040 : /* If we are XORing two things that have no bits in common,
4041 : convert them into an IOR. This helps to detect rotation encoded
4042 : using those methods and possibly other simplifications. */
4043 :
4044 1627361 : if (HWI_COMPUTABLE_MODE_P (mode)
4045 1334627 : && (nonzero_bits (op0, mode)
4046 1334627 : & nonzero_bits (op1, mode)) == 0)
4047 10901 : return (simplify_gen_binary (IOR, mode, op0, op1));
4048 :
4049 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
4050 1616460 : if (match_plus_neg_pattern (op0, op1, mode))
4051 0 : return CONSTM1_RTX (mode);
4052 :
4053 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
4054 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
4055 : (NOT y). */
4056 1616460 : {
4057 1616460 : int num_negated = 0;
4058 :
4059 1616460 : if (GET_CODE (op0) == NOT)
4060 888 : num_negated++, op0 = XEXP (op0, 0);
4061 1616460 : if (GET_CODE (op1) == NOT)
4062 64 : num_negated++, op1 = XEXP (op1, 0);
4063 :
4064 64 : if (num_negated == 2)
4065 0 : return simplify_gen_binary (XOR, mode, op0, op1);
4066 1616460 : else if (num_negated == 1)
4067 952 : return simplify_gen_unary (NOT, mode,
4068 : simplify_gen_binary (XOR, mode, op0, op1),
4069 952 : mode);
4070 : }
4071 :
4072 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
4073 : correspond to a machine insn or result in further simplifications
4074 : if B is a constant. */
4075 :
4076 1615508 : if (GET_CODE (op0) == AND
4077 173617 : && rtx_equal_p (XEXP (op0, 1), op1)
4078 1640139 : && ! side_effects_p (op1))
4079 24631 : return simplify_gen_binary (AND, mode,
4080 : simplify_gen_unary (NOT, mode,
4081 : XEXP (op0, 0), mode),
4082 24631 : op1);
4083 :
4084 1590877 : else if (GET_CODE (op0) == AND
4085 148986 : && rtx_equal_p (XEXP (op0, 0), op1)
4086 1592134 : && ! side_effects_p (op1))
4087 1257 : return simplify_gen_binary (AND, mode,
4088 : simplify_gen_unary (NOT, mode,
4089 : XEXP (op0, 1), mode),
4090 1257 : op1);
4091 :
4092 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
4093 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
4094 : out bits inverted twice and not set by C. Similarly, given
4095 : (xor (and (xor A B) C) D), simplify without inverting C in
4096 : the xor operand: (xor (and A C) (B&C)^D).
4097 : */
4098 1589620 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
4099 168543 : && GET_CODE (XEXP (op0, 0)) == XOR
4100 7181 : && CONST_INT_P (op1)
4101 212 : && CONST_INT_P (XEXP (op0, 1))
4102 158 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4103 : {
4104 38 : enum rtx_code op = GET_CODE (op0);
4105 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4106 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4107 38 : rtx c = XEXP (op0, 1);
4108 38 : rtx d = op1;
4109 38 : HOST_WIDE_INT bval = INTVAL (b);
4110 38 : HOST_WIDE_INT cval = INTVAL (c);
4111 38 : HOST_WIDE_INT dval = INTVAL (d);
4112 38 : HOST_WIDE_INT xcval;
4113 :
4114 38 : if (op == IOR)
4115 8 : xcval = ~cval;
4116 : else
4117 : xcval = cval;
4118 :
4119 38 : return simplify_gen_binary (XOR, mode,
4120 : simplify_gen_binary (op, mode, a, c),
4121 38 : gen_int_mode ((bval & xcval) ^ dval,
4122 : mode));
4123 : }
4124 :
4125 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4126 : we can transform like this:
4127 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4128 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4129 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4130 : Attempt a few simplifications when B and C are both constants. */
4131 1589582 : if (GET_CODE (op0) == AND
4132 147699 : && CONST_INT_P (op1)
4133 13011 : && CONST_INT_P (XEXP (op0, 1)))
4134 : {
4135 11241 : rtx a = XEXP (op0, 0);
4136 11241 : rtx b = XEXP (op0, 1);
4137 11241 : rtx c = op1;
4138 11241 : HOST_WIDE_INT bval = INTVAL (b);
4139 11241 : HOST_WIDE_INT cval = INTVAL (c);
4140 :
4141 : /* Instead of computing ~A&C, we compute its negated value,
4142 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4143 : optimize for sure. If it does not simplify, we still try
4144 : to compute ~A&C below, but since that always allocates
4145 : RTL, we don't try that before committing to returning a
4146 : simplified expression. */
4147 11241 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4148 : GEN_INT (~cval));
4149 :
4150 11241 : if ((~cval & bval) == 0)
4151 : {
4152 620 : rtx na_c = NULL_RTX;
4153 620 : if (n_na_c)
4154 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4155 : else
4156 : {
4157 : /* If ~A does not simplify, don't bother: we don't
4158 : want to simplify 2 operations into 3, and if na_c
4159 : were to simplify with na, n_na_c would have
4160 : simplified as well. */
4161 620 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4162 620 : if (na)
4163 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4164 : }
4165 :
4166 : /* Try to simplify ~A&C | ~B&C. */
4167 0 : if (na_c != NULL_RTX)
4168 0 : return simplify_gen_binary (IOR, mode, na_c,
4169 0 : gen_int_mode (~bval & cval, mode));
4170 : }
4171 : else
4172 : {
4173 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4174 10621 : if (n_na_c == CONSTM1_RTX (mode))
4175 : {
4176 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4177 0 : gen_int_mode (~cval & bval,
4178 : mode));
4179 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4180 0 : gen_int_mode (~bval & cval,
4181 : mode));
4182 : }
4183 : }
4184 : }
4185 :
4186 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4187 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4188 : machines, and also has shorter instruction path length. */
4189 1589582 : if (GET_CODE (op0) == AND
4190 147699 : && GET_CODE (XEXP (op0, 0)) == XOR
4191 6693 : && CONST_INT_P (XEXP (op0, 1))
4192 1593026 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4193 : {
4194 7 : rtx a = trueop1;
4195 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4196 7 : rtx c = XEXP (op0, 1);
4197 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4198 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4199 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4200 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4201 : }
4202 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4203 1589575 : else if (GET_CODE (op0) == AND
4204 147692 : && GET_CODE (XEXP (op0, 0)) == XOR
4205 6686 : && CONST_INT_P (XEXP (op0, 1))
4206 1593012 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4207 : {
4208 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4209 8 : rtx b = trueop1;
4210 8 : rtx c = XEXP (op0, 1);
4211 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4212 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4213 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4214 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4215 : }
4216 :
4217 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4218 : comparison if STORE_FLAG_VALUE is 1. */
4219 1589567 : if (STORE_FLAG_VALUE == 1
4220 1589567 : && trueop1 == const1_rtx
4221 200786 : && COMPARISON_P (op0)
4222 1595837 : && (reversed = reversed_comparison (op0, mode)))
4223 : return reversed;
4224 :
4225 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4226 : is (lt foo (const_int 0)), so we can perform the above
4227 : simplification if STORE_FLAG_VALUE is 1. */
4228 :
4229 1583305 : if (is_a <scalar_int_mode> (mode, &int_mode)
4230 : && STORE_FLAG_VALUE == 1
4231 1294958 : && trueop1 == const1_rtx
4232 194524 : && GET_CODE (op0) == LSHIFTRT
4233 35348 : && CONST_INT_P (XEXP (op0, 1))
4234 35348 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4235 34509 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4236 :
4237 : /* (xor (comparison foo bar) (const_int sign-bit))
4238 : when STORE_FLAG_VALUE is the sign bit. */
4239 1548796 : if (is_a <scalar_int_mode> (mode, &int_mode)
4240 1260449 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4241 0 : && trueop1 == const_true_rtx
4242 0 : && COMPARISON_P (op0)
4243 0 : && (reversed = reversed_comparison (op0, int_mode)))
4244 : return reversed;
4245 :
4246 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4247 1548796 : if (GET_CODE (op0) == GET_CODE (op1)
4248 540178 : && (GET_CODE (op0) == AND
4249 540178 : || GET_CODE (op0) == LSHIFTRT
4250 467700 : || GET_CODE (op0) == ASHIFTRT
4251 467604 : || GET_CODE (op0) == ASHIFT
4252 467470 : || GET_CODE (op0) == ROTATE
4253 467363 : || GET_CODE (op0) == ROTATERT))
4254 : {
4255 73355 : tem = simplify_distributive_operation (code, mode, op0, op1);
4256 73355 : if (tem)
4257 : return tem;
4258 : }
4259 :
4260 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4261 : mode size to (rotate A CX). */
4262 1478935 : tem = simplify_rotate_op (op0, op1, mode);
4263 1478935 : if (tem)
4264 : return tem;
4265 :
4266 : /* Convert (xor (and (not A) B) A) into A | B. */
4267 1477555 : if (GET_CODE (op0) == AND
4268 1477555 : && negated_ops_p (XEXP (op0, 0), op1))
4269 1 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4270 :
4271 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4272 : into B | (1 << A). */
4273 1477554 : if (SHIFT_COUNT_TRUNCATED
4274 : && GET_CODE (op0) == AND
4275 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4276 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4277 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4278 : && GET_CODE (op1) == ASHIFT
4279 : && CONST_INT_P (XEXP (op1, 0))
4280 : && INTVAL (XEXP (op1, 0)) == 1
4281 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4282 : && !side_effects_p (XEXP (op1, 1)))
4283 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4284 :
4285 1477554 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4286 1477554 : if (tem)
4287 : return tem;
4288 :
4289 1477553 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4290 1477553 : if (tem)
4291 : return tem;
4292 :
4293 1477553 : tem = simplify_associative_operation (code, mode, op0, op1);
4294 1477553 : if (tem)
4295 : return tem;
4296 : break;
4297 :
4298 24099028 : case AND:
4299 24099028 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4300 : return trueop1;
4301 23854999 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4302 : return op0;
4303 23471487 : if (HWI_COMPUTABLE_MODE_P (mode))
4304 : {
4305 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4306 : nonzero bits in WORD_MODE rather than MODE. */
4307 20583883 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4308 20583883 : if (WORD_REGISTER_OPERATIONS
4309 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4310 : tmode = word_mode;
4311 20583883 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4312 20583883 : HOST_WIDE_INT nzop1;
4313 20583883 : if (CONST_INT_P (trueop1))
4314 : {
4315 17576378 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4316 : /* If we are turning off bits already known off in OP0, we need
4317 : not do an AND. */
4318 17576378 : if ((nzop0 & ~val1) == 0)
4319 401947 : return op0;
4320 :
4321 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4322 : (and (lshiftrt (subreg X) shift) mask).
4323 :
4324 : Keeps shift and AND in the same mode, improving recognition.
4325 : Only applied when subreg is a lowpart, shift is valid,
4326 : and no precision is lost. */
4327 17258714 : if (SUBREG_P (op0)
4328 6184029 : && subreg_lowpart_p (op0)
4329 6167113 : && !paradoxical_subreg_p (op0)
4330 915909 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4331 : /* simplify_subreg asserts the object being accessed is not
4332 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4333 : is not simplified and the source operand is a constant,
4334 : and thus VOIDmode. Guard against that. */
4335 113811 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4336 113761 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4337 113761 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4338 113761 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4339 93576 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4340 93576 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4341 17352289 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4342 93575 : + floor_log2 (val1))
4343 17258714 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4344 : {
4345 10590 : tem = XEXP (XEXP (op0, 0), 0);
4346 10590 : if (SUBREG_P (tem))
4347 : {
4348 265 : if (subreg_lowpart_p (tem))
4349 265 : tem = SUBREG_REG (tem);
4350 : else
4351 : tem = NULL_RTX;
4352 : }
4353 265 : if (tem != NULL_RTX)
4354 : {
4355 10590 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4356 10590 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4357 10590 : offset);
4358 10590 : if (tem)
4359 : {
4360 10590 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4361 10590 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4362 10590 : shiftamt);
4363 10590 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4364 : shiftamtrtx);
4365 10590 : return simplify_gen_binary (AND, mode, op0, op1);
4366 : }
4367 : }
4368 : }
4369 : }
4370 20255629 : nzop1 = nonzero_bits (trueop1, mode);
4371 : /* If we are clearing all the nonzero bits, the result is zero. */
4372 20255629 : if ((nzop1 & nzop0) == 0
4373 20255629 : && !side_effects_p (op0) && !side_effects_p (op1))
4374 73693 : return CONST0_RTX (mode);
4375 : }
4376 23072888 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4377 23072884 : && GET_MODE_CLASS (mode) != MODE_CC)
4378 : return op0;
4379 : /* A & (~A) -> 0 */
4380 624189 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4381 23062305 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4382 3937 : && ! side_effects_p (op0)
4383 23070132 : && GET_MODE_CLASS (mode) != MODE_CC)
4384 3936 : return CONST0_RTX (mode);
4385 :
4386 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4387 23062260 : if (match_plus_neg_pattern (op0, op1, mode))
4388 2 : return CONST0_RTX (mode);
4389 :
4390 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4391 : there are no nonzero bits of C outside of X's mode. */
4392 46124516 : if ((GET_CODE (op0) == SIGN_EXTEND
4393 23062258 : || GET_CODE (op0) == ZERO_EXTEND)
4394 93862 : && CONST_SCALAR_INT_P (trueop1)
4395 79885 : && is_a <scalar_int_mode> (mode, &int_mode)
4396 79885 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4397 23142143 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4398 79885 : GET_MODE_PRECISION (int_mode))
4399 23142143 : & rtx_mode_t (trueop1, mode)) == 0)
4400 : {
4401 78041 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4402 78041 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4403 78041 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4404 78041 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4405 : }
4406 :
4407 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4408 : we might be able to further simplify the AND with X and potentially
4409 : remove the truncation altogether. */
4410 22984217 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4411 : {
4412 6 : rtx x = XEXP (op0, 0);
4413 6 : machine_mode xmode = GET_MODE (x);
4414 6 : tem = simplify_gen_binary (AND, xmode, x,
4415 6 : gen_int_mode (INTVAL (trueop1), xmode));
4416 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4417 : }
4418 :
4419 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4420 22984211 : if (GET_CODE (op0) == IOR
4421 1386090 : && CONST_INT_P (trueop1)
4422 216974 : && CONST_INT_P (XEXP (op0, 1)))
4423 : {
4424 133909 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4425 133909 : return simplify_gen_binary (IOR, mode,
4426 : simplify_gen_binary (AND, mode,
4427 : XEXP (op0, 0), op1),
4428 133909 : gen_int_mode (tmp, mode));
4429 : }
4430 :
4431 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4432 : insn (and may simplify more). */
4433 22850302 : if (GET_CODE (op0) == XOR
4434 138991 : && rtx_equal_p (XEXP (op0, 0), op1)
4435 22851743 : && ! side_effects_p (op1))
4436 1441 : return simplify_gen_binary (AND, mode,
4437 : simplify_gen_unary (NOT, mode,
4438 : XEXP (op0, 1), mode),
4439 1441 : op1);
4440 :
4441 22848861 : if (GET_CODE (op0) == XOR
4442 137550 : && rtx_equal_p (XEXP (op0, 1), op1)
4443 22851882 : && ! side_effects_p (op1))
4444 3021 : return simplify_gen_binary (AND, mode,
4445 : simplify_gen_unary (NOT, mode,
4446 : XEXP (op0, 0), mode),
4447 3021 : op1);
4448 :
4449 : /* Similarly for (~(A ^ B)) & A. */
4450 22845840 : if (GET_CODE (op0) == NOT
4451 620299 : && GET_CODE (XEXP (op0, 0)) == XOR
4452 3491 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4453 22845894 : && ! side_effects_p (op1))
4454 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4455 :
4456 22845786 : if (GET_CODE (op0) == NOT
4457 620245 : && GET_CODE (XEXP (op0, 0)) == XOR
4458 3437 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4459 22845823 : && ! side_effects_p (op1))
4460 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4461 :
4462 : /* Convert (A | B) & A to A. */
4463 22845749 : if (GET_CODE (op0) == IOR
4464 1252181 : && (rtx_equal_p (XEXP (op0, 0), op1)
4465 1251656 : || rtx_equal_p (XEXP (op0, 1), op1))
4466 726 : && ! side_effects_p (XEXP (op0, 0))
4467 22846475 : && ! side_effects_p (XEXP (op0, 1)))
4468 : return op1;
4469 :
4470 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4471 : ((A & N) + B) & M -> (A + B) & M
4472 : Similarly if (N & M) == 0,
4473 : ((A | N) + B) & M -> (A + B) & M
4474 : and for - instead of + and/or ^ instead of |.
4475 : Also, if (N & M) == 0, then
4476 : (A +- N) & M -> A & M. */
4477 22845023 : if (CONST_INT_P (trueop1)
4478 17055615 : && HWI_COMPUTABLE_MODE_P (mode)
4479 17034666 : && ~UINTVAL (trueop1)
4480 17034666 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4481 33833482 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4482 : {
4483 968198 : rtx pmop[2];
4484 968198 : int which;
4485 :
4486 968198 : pmop[0] = XEXP (op0, 0);
4487 968198 : pmop[1] = XEXP (op0, 1);
4488 :
4489 968198 : if (CONST_INT_P (pmop[1])
4490 511710 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4491 167981 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4492 :
4493 2423820 : for (which = 0; which < 2; which++)
4494 : {
4495 1615880 : tem = pmop[which];
4496 1615880 : switch (GET_CODE (tem))
4497 : {
4498 11626 : case AND:
4499 11626 : if (CONST_INT_P (XEXP (tem, 1))
4500 10116 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4501 : == UINTVAL (trueop1))
4502 7584 : pmop[which] = XEXP (tem, 0);
4503 : break;
4504 1728 : case IOR:
4505 1728 : case XOR:
4506 1728 : if (CONST_INT_P (XEXP (tem, 1))
4507 699 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4508 139 : pmop[which] = XEXP (tem, 0);
4509 : break;
4510 : default:
4511 : break;
4512 : }
4513 : }
4514 :
4515 807940 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4516 : {
4517 7723 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4518 : pmop[0], pmop[1]);
4519 7723 : return simplify_gen_binary (code, mode, tem, op1);
4520 : }
4521 : }
4522 :
4523 : /* (and X (ior (not X) Y) -> (and X Y) */
4524 22677042 : if (GET_CODE (op1) == IOR
4525 940441 : && GET_CODE (XEXP (op1, 0)) == NOT
4526 22682392 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4527 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4528 :
4529 : /* (and (ior (not X) Y) X) -> (and X Y) */
4530 22677042 : if (GET_CODE (op0) == IOR
4531 1251455 : && GET_CODE (XEXP (op0, 0)) == NOT
4532 22727628 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4533 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4534 :
4535 : /* (and X (ior Y (not X)) -> (and X Y) */
4536 22677036 : if (GET_CODE (op1) == IOR
4537 940441 : && GET_CODE (XEXP (op1, 1)) == NOT
4538 22677375 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4539 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4540 :
4541 : /* (and (ior Y (not X)) X) -> (and X Y) */
4542 22677036 : if (GET_CODE (op0) == IOR
4543 1251449 : && GET_CODE (XEXP (op0, 1)) == NOT
4544 22685862 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4545 43 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4546 :
4547 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4548 22676993 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4549 22676993 : && negated_ops_p (op1, XEXP (op0, 1)))
4550 13 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4551 : simplify_gen_unary (NOT, mode,
4552 : XEXP (op0, 1),
4553 13 : mode));
4554 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4555 22676980 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4556 22676980 : && negated_ops_p (op1, XEXP (op0, 0)))
4557 4 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4558 : simplify_gen_unary (NOT, mode,
4559 : XEXP (op0, 0),
4560 4 : mode));
4561 :
4562 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4563 22676976 : if (GET_CODE (op0) == GET_CODE (op1)
4564 2147630 : && (GET_CODE (op0) == AND
4565 : || GET_CODE (op0) == IOR
4566 2147630 : || GET_CODE (op0) == LSHIFTRT
4567 1207861 : || GET_CODE (op0) == ASHIFTRT
4568 1207711 : || GET_CODE (op0) == ASHIFT
4569 1207542 : || GET_CODE (op0) == ROTATE
4570 1207542 : || GET_CODE (op0) == ROTATERT))
4571 : {
4572 940088 : tem = simplify_distributive_operation (code, mode, op0, op1);
4573 940088 : if (tem)
4574 : return tem;
4575 : }
4576 :
4577 : /* (and:v4si
4578 : (ashiftrt:v4si A 16)
4579 : (const_vector: 0xffff x4))
4580 : is just (lshiftrt:v4si A 16). */
4581 21778448 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4582 4618 : && (CONST_INT_P (XEXP (op0, 1))
4583 1948 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4584 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4585 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4586 2670 : && GET_CODE (op1) == CONST_VECTOR
4587 21778473 : && const_vec_duplicate_p (op1)
4588 21778515 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4589 : {
4590 130 : unsigned HOST_WIDE_INT shift_count
4591 : = (CONST_INT_P (XEXP (op0, 1))
4592 65 : ? UINTVAL (XEXP (op0, 1))
4593 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4594 65 : unsigned HOST_WIDE_INT inner_prec
4595 130 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4596 :
4597 : /* Avoid UD shift count. */
4598 65 : if (shift_count < inner_prec
4599 59 : && (UINTVAL (XVECEXP (op1, 0, 0))
4600 59 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4601 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4602 : }
4603 :
4604 21778406 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4605 21778406 : if (tem)
4606 : return tem;
4607 :
4608 21776100 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4609 21776100 : if (tem)
4610 : return tem;
4611 :
4612 21775879 : tem = simplify_associative_operation (code, mode, op0, op1);
4613 21775879 : if (tem)
4614 : return tem;
4615 : break;
4616 :
4617 891326 : case UDIV:
4618 : /* 0/x is 0 (or x&0 if x has side-effects). */
4619 891326 : if (trueop0 == CONST0_RTX (mode)
4620 272 : && !cfun->can_throw_non_call_exceptions)
4621 : {
4622 272 : if (side_effects_p (op1))
4623 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4624 : return trueop0;
4625 : }
4626 : /* x/1 is x. */
4627 891054 : if (trueop1 == CONST1_RTX (mode))
4628 : {
4629 239059 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4630 239059 : if (tem)
4631 : return tem;
4632 : }
4633 : /* Convert divide by power of two into shift. */
4634 651995 : if (CONST_INT_P (trueop1)
4635 974535 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4636 322540 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4637 322540 : gen_int_shift_amount (mode, val));
4638 : break;
4639 :
4640 1199636 : case DIV:
4641 : /* Handle floating point and integers separately. */
4642 1199636 : if (SCALAR_FLOAT_MODE_P (mode))
4643 : {
4644 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4645 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4646 : NaN rather than 0.0. Nor is it safe for modes with signed
4647 : zeros, since dividing 0 by a negative number gives -0.0 */
4648 324910 : if (trueop0 == CONST0_RTX (mode)
4649 2800 : && !HONOR_NANS (mode)
4650 14 : && !HONOR_SIGNED_ZEROS (mode)
4651 324924 : && ! side_effects_p (op1))
4652 : return op0;
4653 : /* x/1.0 is x. */
4654 324896 : if (trueop1 == CONST1_RTX (mode)
4655 324896 : && !HONOR_SNANS (mode))
4656 : return op0;
4657 :
4658 324891 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4659 26569 : && trueop1 != CONST0_RTX (mode))
4660 : {
4661 20469 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4662 :
4663 : /* x/-1.0 is -x. */
4664 20469 : if (real_equal (d1, &dconstm1)
4665 20469 : && !HONOR_SNANS (mode))
4666 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4667 :
4668 : /* Change FP division by a constant into multiplication.
4669 : Only do this with -freciprocal-math. */
4670 20469 : if (flag_reciprocal_math
4671 20469 : && !real_equal (d1, &dconst0))
4672 : {
4673 7 : REAL_VALUE_TYPE d;
4674 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4675 7 : tem = const_double_from_real_value (d, mode);
4676 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4677 : }
4678 : }
4679 : }
4680 874726 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4681 : {
4682 : /* 0/x is 0 (or x&0 if x has side-effects). */
4683 852366 : if (trueop0 == CONST0_RTX (mode)
4684 979 : && !cfun->can_throw_non_call_exceptions)
4685 : {
4686 925 : if (side_effects_p (op1))
4687 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4688 : return trueop0;
4689 : }
4690 : /* x/1 is x. */
4691 851441 : if (trueop1 == CONST1_RTX (mode))
4692 : {
4693 894 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4694 894 : if (tem)
4695 : return tem;
4696 : }
4697 : /* x/-1 is -x. */
4698 850547 : if (trueop1 == CONSTM1_RTX (mode))
4699 : {
4700 503 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4701 503 : if (x)
4702 503 : return simplify_gen_unary (NEG, mode, x, mode);
4703 : }
4704 : }
4705 : break;
4706 :
4707 913446 : case UMOD:
4708 : /* 0%x is 0 (or x&0 if x has side-effects). */
4709 913446 : if (trueop0 == CONST0_RTX (mode))
4710 : {
4711 774 : if (side_effects_p (op1))
4712 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4713 : return trueop0;
4714 : }
4715 : /* x%1 is 0 (of x&0 if x has side-effects). */
4716 912672 : if (trueop1 == CONST1_RTX (mode))
4717 : {
4718 272644 : if (side_effects_p (op0))
4719 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4720 272644 : return CONST0_RTX (mode);
4721 : }
4722 : /* Implement modulus by power of two as AND. */
4723 640028 : if (CONST_INT_P (trueop1)
4724 946187 : && exact_log2 (UINTVAL (trueop1)) > 0)
4725 306159 : return simplify_gen_binary (AND, mode, op0,
4726 306159 : gen_int_mode (UINTVAL (trueop1) - 1,
4727 : mode));
4728 : break;
4729 :
4730 366371 : case MOD:
4731 : /* 0%x is 0 (or x&0 if x has side-effects). */
4732 366371 : if (trueop0 == CONST0_RTX (mode))
4733 : {
4734 1205 : if (side_effects_p (op1))
4735 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4736 : return trueop0;
4737 : }
4738 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4739 365166 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4740 : {
4741 744 : if (side_effects_p (op0))
4742 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4743 744 : return CONST0_RTX (mode);
4744 : }
4745 : break;
4746 :
4747 128166 : case ROTATERT:
4748 128166 : case ROTATE:
4749 128166 : if (trueop1 == CONST0_RTX (mode))
4750 : return op0;
4751 : /* Canonicalize rotates by constant amount. If the condition of
4752 : reversing direction is met, then reverse the direction. */
4753 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4754 128076 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4755 : {
4756 11299 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4757 11299 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4758 11843 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4759 : mode, op0, new_amount_rtx);
4760 : }
4761 : #endif
4762 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4763 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4764 : semantics. */
4765 116777 : tem = unwrap_const_vec_duplicate (trueop1);
4766 116777 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4767 116777 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4768 504 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4769 :
4770 : /* FALLTHRU */
4771 5248344 : case ASHIFTRT:
4772 5248344 : if (trueop1 == CONST0_RTX (mode))
4773 : return op0;
4774 5246324 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4775 : return op0;
4776 : /* Rotating ~0 always results in ~0. */
4777 5246152 : if (CONST_INT_P (trueop0)
4778 15044 : && HWI_COMPUTABLE_MODE_P (mode)
4779 15016 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4780 5246152 : && ! side_effects_p (op1))
4781 : return op0;
4782 :
4783 31137817 : canonicalize_shift:
4784 : /* Given:
4785 : scalar modes M1, M2
4786 : scalar constants c1, c2
4787 : size (M2) > size (M1)
4788 : c1 == size (M2) - size (M1)
4789 : optimize:
4790 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4791 : <low_part>)
4792 : (const_int <c2>))
4793 : to:
4794 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4795 : <low_part>). */
4796 31137817 : if ((code == ASHIFTRT || code == LSHIFTRT)
4797 11787453 : && is_a <scalar_int_mode> (mode, &int_mode)
4798 10995918 : && SUBREG_P (op0)
4799 1157367 : && CONST_INT_P (op1)
4800 1155147 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4801 18537 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4802 : &inner_mode)
4803 18537 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4804 36768 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4805 18384 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4806 36768 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4807 31155964 : && subreg_lowpart_p (op0))
4808 : {
4809 18147 : rtx tmp = gen_int_shift_amount
4810 18147 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4811 :
4812 : /* Combine would usually zero out the value when combining two
4813 : local shifts and the range becomes larger or equal to the mode.
4814 : However since we fold away one of the shifts here combine won't
4815 : see it so we should immediately zero the result if it's out of
4816 : range. */
4817 18147 : if (code == LSHIFTRT
4818 32788 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4819 0 : tmp = const0_rtx;
4820 : else
4821 18147 : tmp = simplify_gen_binary (code,
4822 : inner_mode,
4823 18147 : XEXP (SUBREG_REG (op0), 0),
4824 : tmp);
4825 :
4826 18147 : return lowpart_subreg (int_mode, tmp, inner_mode);
4827 : }
4828 :
4829 31119670 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4830 : {
4831 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4832 : if (val != INTVAL (op1))
4833 : return simplify_gen_binary (code, mode, op0,
4834 : gen_int_shift_amount (mode, val));
4835 : }
4836 :
4837 : /* Simplify:
4838 :
4839 : (code:M1
4840 : (subreg:M1
4841 : ([al]shiftrt:M2
4842 : (subreg:M2
4843 : (ashift:M1 X C1))
4844 : C2))
4845 : C3)
4846 :
4847 : to:
4848 :
4849 : (code:M1
4850 : ([al]shiftrt:M1
4851 : (ashift:M1 X C1+N)
4852 : C2+N)
4853 : C3)
4854 :
4855 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4856 : directly would be arithmetically correct, but restricting the
4857 : simplification to shifts by constants is more conservative,
4858 : since it is more likely to lead to further simplifications. */
4859 31119670 : if (is_a<scalar_int_mode> (mode, &int_mode)
4860 5496108 : && paradoxical_subreg_p (op0)
4861 5061309 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4862 5061223 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4863 5061223 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4864 141760 : && CONST_INT_P (op1))
4865 : {
4866 141760 : auto xcode = GET_CODE (SUBREG_REG (op0));
4867 141760 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4868 141760 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4869 141760 : if (SUBREG_P (xop0)
4870 10724 : && GET_MODE (SUBREG_REG (xop0)) == mode
4871 10637 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4872 594 : && CONST_INT_P (xop1)
4873 142354 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4874 : {
4875 594 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4876 594 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4877 594 : if (CONST_INT_P (yop1)
4878 594 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4879 : {
4880 1188 : auto bias = (GET_MODE_BITSIZE (int_mode)
4881 594 : - GET_MODE_BITSIZE (inner_mode));
4882 594 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4883 594 : GEN_INT (INTVAL (yop1) + bias));
4884 594 : tem = simplify_gen_binary (xcode, mode, tem,
4885 594 : GEN_INT (INTVAL (xop1) + bias));
4886 594 : return simplify_gen_binary (code, mode, tem, op1);
4887 : }
4888 : }
4889 : }
4890 : break;
4891 :
4892 0 : case SS_ASHIFT:
4893 0 : if (CONST_INT_P (trueop0)
4894 0 : && HWI_COMPUTABLE_MODE_P (mode)
4895 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4896 0 : || mode_signbit_p (mode, trueop0))
4897 0 : && ! side_effects_p (op1))
4898 : return op0;
4899 0 : goto simplify_ashift;
4900 :
4901 0 : case US_ASHIFT:
4902 0 : if (CONST_INT_P (trueop0)
4903 0 : && HWI_COMPUTABLE_MODE_P (mode)
4904 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4905 0 : && ! side_effects_p (op1))
4906 : return op0;
4907 : /* FALLTHRU */
4908 :
4909 19657728 : case ASHIFT:
4910 19657728 : simplify_ashift:
4911 19657728 : if (trueop1 == CONST0_RTX (mode))
4912 : return op0;
4913 19498614 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4914 : return op0;
4915 19469443 : if (mem_depth
4916 235321 : && code == ASHIFT
4917 235321 : && CONST_INT_P (trueop1)
4918 235313 : && is_a <scalar_int_mode> (mode, &int_mode)
4919 19704744 : && IN_RANGE (UINTVAL (trueop1),
4920 : 1, GET_MODE_PRECISION (int_mode) - 1))
4921 : {
4922 235301 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4923 235301 : << UINTVAL (trueop1));
4924 235301 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4925 235301 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4926 235301 : }
4927 :
4928 : /* If we're shifting left a signed bitfield extraction and the
4929 : shift count + bitfield size is a natural integral mode and
4930 : the field starts at offset 0 (counting from the LSB), then
4931 : this can be simplified to a sign extension of a left shift.
4932 :
4933 : Some ISAs (RISC-V 64-bit) have inherent support for such
4934 : instructions and it's better for various optimizations to
4935 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4936 19234142 : if (GET_CODE (op0) == SIGN_EXTRACT
4937 28 : && REG_P (XEXP (op0, 0))
4938 : /* The size of the bitfield, the location of the bitfield and
4939 : shift count must be CONST_INTs. */
4940 22 : && CONST_INT_P (op1)
4941 22 : && CONST_INT_P (XEXP (op0, 1))
4942 22 : && CONST_INT_P (XEXP (op0, 2)))
4943 : {
4944 22 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4945 22 : machine_mode smaller_mode;
4946 : /* Now we need to verify the size of the bitfield plus the shift
4947 : count is an integral mode and smaller than MODE. This is
4948 : requirement for using SIGN_EXTEND. We also need to verify the
4949 : field starts at bit location 0 and that the subreg lowpart also
4950 : starts at zero. */
4951 22 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4952 3 : && mode > smaller_mode
4953 22 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
4954 3 : == UINTVAL (XEXP (op0, 2)))
4955 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
4956 : {
4957 : /* Everything passed. So we just need to get the subreg of the
4958 : original input, shift it and sign extend the result. */
4959 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
4960 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
4961 1 : return gen_rtx_SIGN_EXTEND (mode, x);
4962 : }
4963 : }
4964 19234141 : goto canonicalize_shift;
4965 :
4966 8467954 : case LSHIFTRT:
4967 8467954 : if (trueop1 == CONST0_RTX (mode))
4968 : return op0;
4969 6659014 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4970 : return op0;
4971 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4972 6657524 : if (GET_CODE (op0) == CLZ
4973 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4974 0 : && CONST_INT_P (trueop1)
4975 : && STORE_FLAG_VALUE == 1
4976 6657524 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4977 : {
4978 0 : unsigned HOST_WIDE_INT zero_val = 0;
4979 :
4980 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4981 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
4982 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
4983 0 : return simplify_gen_relational (EQ, mode, inner_mode,
4984 0 : XEXP (op0, 0), const0_rtx);
4985 : }
4986 6657524 : goto canonicalize_shift;
4987 :
4988 240943 : case SMIN:
4989 240943 : if (HWI_COMPUTABLE_MODE_P (mode)
4990 220193 : && mode_signbit_p (mode, trueop1)
4991 0 : && ! side_effects_p (op0))
4992 : return op1;
4993 240943 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4994 : return op0;
4995 240787 : tem = simplify_associative_operation (code, mode, op0, op1);
4996 240787 : if (tem)
4997 : return tem;
4998 : break;
4999 :
5000 494419 : case SMAX:
5001 494419 : if (HWI_COMPUTABLE_MODE_P (mode)
5002 467193 : && CONST_INT_P (trueop1)
5003 434849 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
5004 0 : && ! side_effects_p (op0))
5005 : return op1;
5006 494419 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5007 : return op0;
5008 494312 : tem = simplify_associative_operation (code, mode, op0, op1);
5009 494312 : if (tem)
5010 : return tem;
5011 : break;
5012 :
5013 329016 : case UMIN:
5014 329016 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
5015 : return op1;
5016 329004 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5017 : return op0;
5018 328886 : tem = simplify_associative_operation (code, mode, op0, op1);
5019 328886 : if (tem)
5020 : return tem;
5021 : break;
5022 :
5023 275447 : case UMAX:
5024 275447 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
5025 : return op1;
5026 275447 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5027 : return op0;
5028 275357 : tem = simplify_associative_operation (code, mode, op0, op1);
5029 275357 : if (tem)
5030 : return tem;
5031 : break;
5032 :
5033 11994 : case SS_PLUS:
5034 11994 : case US_PLUS:
5035 11994 : case SS_MINUS:
5036 11994 : case US_MINUS:
5037 : /* Simplify x +/- 0 to x, if possible. */
5038 11994 : if (trueop1 == CONST0_RTX (mode))
5039 : return op0;
5040 : return 0;
5041 :
5042 0 : case SS_MULT:
5043 0 : case US_MULT:
5044 : /* Simplify x * 0 to 0, if possible. */
5045 0 : if (trueop1 == CONST0_RTX (mode)
5046 0 : && !side_effects_p (op0))
5047 : return op1;
5048 :
5049 : /* Simplify x * 1 to x, if possible. */
5050 0 : if (trueop1 == CONST1_RTX (mode))
5051 : return op0;
5052 : return 0;
5053 :
5054 463627 : case SMUL_HIGHPART:
5055 463627 : case UMUL_HIGHPART:
5056 : /* Simplify x * 0 to 0, if possible. */
5057 463627 : if (trueop1 == CONST0_RTX (mode)
5058 463627 : && !side_effects_p (op0))
5059 : return op1;
5060 : return 0;
5061 :
5062 0 : case SS_DIV:
5063 0 : case US_DIV:
5064 : /* Simplify x / 1 to x, if possible. */
5065 0 : if (trueop1 == CONST1_RTX (mode))
5066 : return op0;
5067 : return 0;
5068 :
5069 0 : case COPYSIGN:
5070 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5071 : return op0;
5072 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
5073 : {
5074 0 : REAL_VALUE_TYPE f1;
5075 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
5076 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
5077 0 : if (REAL_VALUE_NEGATIVE (f1))
5078 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
5079 0 : return tmp;
5080 : }
5081 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
5082 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5083 0 : if (GET_CODE (op1) == ABS
5084 0 : && ! side_effects_p (op1))
5085 0 : return simplify_gen_unary (ABS, mode, op0, mode);
5086 0 : if (GET_CODE (op0) == COPYSIGN
5087 0 : && ! side_effects_p (XEXP (op0, 1)))
5088 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5089 0 : if (GET_CODE (op1) == COPYSIGN
5090 0 : && ! side_effects_p (XEXP (op1, 0)))
5091 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
5092 : return 0;
5093 :
5094 1118 : case VEC_SERIES:
5095 2236 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
5096 92 : return gen_vec_duplicate (mode, op0);
5097 1026 : if (valid_for_const_vector_p (mode, op0)
5098 1026 : && valid_for_const_vector_p (mode, op1))
5099 93 : return gen_const_vec_series (mode, op0, op1);
5100 : return 0;
5101 :
5102 3452378 : case VEC_SELECT:
5103 3452378 : if (!VECTOR_MODE_P (mode))
5104 : {
5105 951151 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5106 1902302 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5107 951151 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5108 951151 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5109 :
5110 : /* We can't reason about selections made at runtime. */
5111 951151 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5112 446429538 : return 0;
5113 :
5114 951151 : if (vec_duplicate_p (trueop0, &elt0))
5115 2081 : return elt0;
5116 :
5117 949070 : if (GET_CODE (trueop0) == CONST_VECTOR)
5118 7220 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5119 : (trueop1, 0, 0)));
5120 :
5121 : /* Extract a scalar element from a nested VEC_SELECT expression
5122 : (with optional nested VEC_CONCAT expression). Some targets
5123 : (i386) extract scalar element from a vector using chain of
5124 : nested VEC_SELECT expressions. When input operand is a memory
5125 : operand, this operation can be simplified to a simple scalar
5126 : load from an offsetted memory address. */
5127 941850 : int n_elts;
5128 941850 : if (GET_CODE (trueop0) == VEC_SELECT
5129 1012650 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5130 70800 : .is_constant (&n_elts)))
5131 : {
5132 70800 : rtx op0 = XEXP (trueop0, 0);
5133 70800 : rtx op1 = XEXP (trueop0, 1);
5134 :
5135 70800 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5136 70800 : int elem;
5137 :
5138 70800 : rtvec vec;
5139 70800 : rtx tmp_op, tmp;
5140 :
5141 70800 : gcc_assert (GET_CODE (op1) == PARALLEL);
5142 70800 : gcc_assert (i < XVECLEN (op1, 0));
5143 :
5144 : /* Select element, pointed by nested selector. */
5145 70800 : elem = INTVAL (XVECEXP (op1, 0, i));
5146 :
5147 70800 : gcc_assert (elem < n_elts);
5148 :
5149 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5150 70800 : if (GET_CODE (op0) == VEC_CONCAT)
5151 : {
5152 28625 : rtx op00 = XEXP (op0, 0);
5153 28625 : rtx op01 = XEXP (op0, 1);
5154 :
5155 28625 : machine_mode mode00, mode01;
5156 28625 : int n_elts00, n_elts01;
5157 :
5158 28625 : mode00 = GET_MODE (op00);
5159 28625 : mode01 = GET_MODE (op01);
5160 :
5161 : /* Find out the number of elements of each operand.
5162 : Since the concatenated result has a constant number
5163 : of elements, the operands must too. */
5164 28625 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5165 28625 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5166 :
5167 28625 : gcc_assert (n_elts == n_elts00 + n_elts01);
5168 :
5169 : /* Select correct operand of VEC_CONCAT
5170 : and adjust selector. */
5171 28625 : if (elem < n_elts01)
5172 : tmp_op = op00;
5173 : else
5174 : {
5175 45 : tmp_op = op01;
5176 45 : elem -= n_elts00;
5177 : }
5178 : }
5179 : else
5180 : tmp_op = op0;
5181 :
5182 70800 : vec = rtvec_alloc (1);
5183 70800 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5184 :
5185 70800 : tmp = gen_rtx_fmt_ee (code, mode,
5186 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5187 70800 : return tmp;
5188 : }
5189 : }
5190 : else
5191 : {
5192 2501227 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5193 7503681 : gcc_assert (GET_MODE_INNER (mode)
5194 : == GET_MODE_INNER (GET_MODE (trueop0)));
5195 2501227 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5196 :
5197 2501227 : if (vec_duplicate_p (trueop0, &elt0))
5198 : /* It doesn't matter which elements are selected by trueop1,
5199 : because they are all the same. */
5200 15984 : return gen_vec_duplicate (mode, elt0);
5201 :
5202 2485243 : if (GET_CODE (trueop0) == CONST_VECTOR)
5203 : {
5204 17259 : unsigned n_elts = XVECLEN (trueop1, 0);
5205 17259 : rtvec v = rtvec_alloc (n_elts);
5206 17259 : unsigned int i;
5207 :
5208 34518 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5209 80333 : for (i = 0; i < n_elts; i++)
5210 : {
5211 63074 : rtx x = XVECEXP (trueop1, 0, i);
5212 :
5213 63074 : if (!CONST_INT_P (x))
5214 : return 0;
5215 :
5216 63074 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5217 : INTVAL (x));
5218 : }
5219 :
5220 17259 : return gen_rtx_CONST_VECTOR (mode, v);
5221 : }
5222 :
5223 : /* Recognize the identity. */
5224 2467984 : if (GET_MODE (trueop0) == mode)
5225 : {
5226 586001 : bool maybe_ident = true;
5227 586001 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5228 : {
5229 585595 : rtx j = XVECEXP (trueop1, 0, i);
5230 585595 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5231 : {
5232 : maybe_ident = false;
5233 : break;
5234 : }
5235 : }
5236 359168 : if (maybe_ident)
5237 : return trueop0;
5238 : }
5239 :
5240 : /* If we select a low-part subreg, return that. */
5241 2467578 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5242 : {
5243 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5244 0 : GET_MODE (trueop0));
5245 0 : if (new_rtx != NULL_RTX)
5246 : return new_rtx;
5247 : }
5248 :
5249 : /* If we build {a,b} then permute it, build the result directly. */
5250 2467578 : if (XVECLEN (trueop1, 0) == 2
5251 594097 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5252 594097 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5253 594097 : && GET_CODE (trueop0) == VEC_CONCAT
5254 177857 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5255 81 : && GET_MODE (XEXP (trueop0, 0)) == mode
5256 81 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5257 55 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5258 : {
5259 55 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5260 55 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5261 55 : rtx subop0, subop1;
5262 :
5263 55 : gcc_assert (i0 < 4 && i1 < 4);
5264 55 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5265 55 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5266 :
5267 55 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5268 : }
5269 :
5270 2467523 : if (XVECLEN (trueop1, 0) == 2
5271 594042 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5272 594042 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5273 594042 : && GET_CODE (trueop0) == VEC_CONCAT
5274 177802 : && GET_MODE (trueop0) == mode)
5275 : {
5276 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5277 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5278 2 : rtx subop0, subop1;
5279 :
5280 2 : gcc_assert (i0 < 2 && i1 < 2);
5281 2 : subop0 = XEXP (trueop0, i0);
5282 2 : subop1 = XEXP (trueop0, i1);
5283 :
5284 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5285 : }
5286 :
5287 : /* If we select one half of a vec_concat, return that. */
5288 2467521 : int l0, l1;
5289 2467521 : if (GET_CODE (trueop0) == VEC_CONCAT
5290 3061480 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5291 1530740 : .is_constant (&l0))
5292 3061480 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5293 1530740 : .is_constant (&l1))
5294 3998261 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5295 : {
5296 1530740 : rtx subop0 = XEXP (trueop0, 0);
5297 1530740 : rtx subop1 = XEXP (trueop0, 1);
5298 1530740 : machine_mode mode0 = GET_MODE (subop0);
5299 1530740 : machine_mode mode1 = GET_MODE (subop1);
5300 1530740 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5301 1530740 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5302 : {
5303 973786 : bool success = true;
5304 973786 : for (int i = 1; i < l0; ++i)
5305 : {
5306 973457 : rtx j = XVECEXP (trueop1, 0, i);
5307 973457 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5308 : {
5309 : success = false;
5310 : break;
5311 : }
5312 : }
5313 890362 : if (success)
5314 : return subop0;
5315 : }
5316 1530411 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5317 : {
5318 590 : bool success = true;
5319 590 : for (int i = 1; i < l1; ++i)
5320 : {
5321 543 : rtx j = XVECEXP (trueop1, 0, i);
5322 543 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5323 : {
5324 : success = false;
5325 : break;
5326 : }
5327 : }
5328 76 : if (success)
5329 : return subop1;
5330 : }
5331 : }
5332 :
5333 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5334 : when X has same component mode as vec_select. */
5335 2467145 : unsigned HOST_WIDE_INT subreg_offset = 0;
5336 2467145 : if (GET_CODE (trueop0) == SUBREG
5337 364927 : && GET_MODE_INNER (mode)
5338 729854 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5339 29586 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5340 2832072 : && constant_multiple_p (subreg_memory_offset (trueop0),
5341 29586 : GET_MODE_UNIT_BITSIZE (mode),
5342 : &subreg_offset))
5343 : {
5344 14793 : poly_uint64 nunits
5345 29586 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5346 14793 : bool success = true;
5347 91529 : for (int i = 0; i != l1; i++)
5348 : {
5349 87085 : rtx idx = XVECEXP (trueop1, 0, i);
5350 87085 : if (!CONST_INT_P (idx)
5351 87085 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5352 : {
5353 : success = false;
5354 : break;
5355 : }
5356 : }
5357 :
5358 14793 : if (success)
5359 : {
5360 4444 : rtx par = trueop1;
5361 4444 : if (subreg_offset)
5362 : {
5363 0 : rtvec vec = rtvec_alloc (l1);
5364 0 : for (int i = 0; i < l1; i++)
5365 0 : RTVEC_ELT (vec, i)
5366 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5367 : + subreg_offset);
5368 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5369 : }
5370 4444 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5371 : }
5372 : }
5373 : }
5374 :
5375 3333751 : if (XVECLEN (trueop1, 0) == 1
5376 871134 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5377 871134 : && GET_CODE (trueop0) == VEC_CONCAT)
5378 : {
5379 1288 : rtx vec = trueop0;
5380 2576 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5381 :
5382 : /* Try to find the element in the VEC_CONCAT. */
5383 1288 : while (GET_MODE (vec) != mode
5384 2576 : && GET_CODE (vec) == VEC_CONCAT)
5385 : {
5386 1288 : poly_int64 vec_size;
5387 :
5388 1288 : if (CONST_INT_P (XEXP (vec, 0)))
5389 : {
5390 : /* vec_concat of two const_ints doesn't make sense with
5391 : respect to modes. */
5392 3 : if (CONST_INT_P (XEXP (vec, 1)))
5393 382781702 : return 0;
5394 :
5395 3 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5396 9 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5397 : }
5398 : else
5399 2570 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5400 :
5401 1288 : if (known_lt (offset, vec_size))
5402 : vec = XEXP (vec, 0);
5403 228 : else if (known_ge (offset, vec_size))
5404 : {
5405 228 : offset -= vec_size;
5406 228 : vec = XEXP (vec, 1);
5407 : }
5408 : else
5409 : break;
5410 1288 : vec = avoid_constant_pool_reference (vec);
5411 : }
5412 :
5413 1288 : if (GET_MODE (vec) == mode)
5414 : return vec;
5415 : }
5416 :
5417 : /* If we select elements in a vec_merge that all come from the same
5418 : operand, select from that operand directly. */
5419 3332643 : if (GET_CODE (op0) == VEC_MERGE)
5420 : {
5421 9821 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5422 9821 : if (CONST_INT_P (trueop02))
5423 : {
5424 3003 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5425 3003 : bool all_operand0 = true;
5426 3003 : bool all_operand1 = true;
5427 10933 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5428 : {
5429 7930 : rtx j = XVECEXP (trueop1, 0, i);
5430 7930 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5431 : all_operand1 = false;
5432 : else
5433 3560 : all_operand0 = false;
5434 : }
5435 3003 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5436 1458 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5437 1545 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5438 47 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5439 : }
5440 : }
5441 :
5442 : /* If we have two nested selects that are inverses of each
5443 : other, replace them with the source operand. */
5444 3331138 : if (GET_CODE (trueop0) == VEC_SELECT
5445 69276 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5446 : {
5447 1030 : rtx op0_subop1 = XEXP (trueop0, 1);
5448 1030 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5449 2060 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5450 : bool identical_p = true;
5451 :
5452 : /* Apply the outer ordering vector to the inner one. (The inner
5453 : ordering vector is expressly permitted to be of a different
5454 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5455 : then the two VEC_SELECTs cancel. */
5456 8946 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5457 : {
5458 7916 : rtx x = XVECEXP (trueop1, 0, i);
5459 7916 : if (!CONST_INT_P (x))
5460 : return 0;
5461 7916 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5462 7916 : if (!CONST_INT_P (y))
5463 : return 0;
5464 7916 : if (i != INTVAL (y))
5465 5854 : identical_p = false;
5466 : }
5467 1030 : if (identical_p)
5468 : return XEXP (trueop0, 0);
5469 :
5470 : /* Otherwise a permutation of a permutation is a permutation. */
5471 1030 : int len = XVECLEN (trueop1, 0);
5472 1030 : rtvec vec = rtvec_alloc (len);
5473 8946 : for (int i = 0; i < len; ++i)
5474 : {
5475 7916 : rtx x = XVECEXP (trueop1, 0, i);
5476 7916 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5477 7916 : RTVEC_ELT (vec, i) = y;
5478 : }
5479 1030 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5480 : gen_rtx_PARALLEL (VOIDmode, vec));
5481 : }
5482 :
5483 : return 0;
5484 4116678 : case VEC_CONCAT:
5485 4116678 : {
5486 4116678 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5487 4116678 : ? GET_MODE (trueop0)
5488 4116678 : : GET_MODE_INNER (mode));
5489 4116678 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5490 4116678 : ? GET_MODE (trueop1)
5491 4116678 : : GET_MODE_INNER (mode));
5492 :
5493 4116678 : gcc_assert (VECTOR_MODE_P (mode));
5494 16466712 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5495 : + GET_MODE_SIZE (op1_mode),
5496 : GET_MODE_SIZE (mode)));
5497 :
5498 4116678 : if (VECTOR_MODE_P (op0_mode))
5499 5729694 : gcc_assert (GET_MODE_INNER (mode)
5500 : == GET_MODE_INNER (op0_mode));
5501 : else
5502 4413560 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5503 :
5504 4116678 : if (VECTOR_MODE_P (op1_mode))
5505 5729694 : gcc_assert (GET_MODE_INNER (mode)
5506 : == GET_MODE_INNER (op1_mode));
5507 : else
5508 4413560 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5509 :
5510 4116678 : unsigned int n_elts, in_n_elts;
5511 4116678 : if ((GET_CODE (trueop0) == CONST_VECTOR
5512 4116678 : || CONST_SCALAR_INT_P (trueop0)
5513 3957106 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5514 161232 : && (GET_CODE (trueop1) == CONST_VECTOR
5515 161232 : || CONST_SCALAR_INT_P (trueop1)
5516 161232 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5517 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5518 4116678 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5519 : {
5520 0 : rtvec v = rtvec_alloc (n_elts);
5521 0 : unsigned int i;
5522 0 : for (i = 0; i < n_elts; i++)
5523 : {
5524 0 : if (i < in_n_elts)
5525 : {
5526 0 : if (!VECTOR_MODE_P (op0_mode))
5527 0 : RTVEC_ELT (v, i) = trueop0;
5528 : else
5529 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5530 : }
5531 : else
5532 : {
5533 0 : if (!VECTOR_MODE_P (op1_mode))
5534 0 : RTVEC_ELT (v, i) = trueop1;
5535 : else
5536 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5537 : i - in_n_elts);
5538 : }
5539 : }
5540 :
5541 0 : return gen_rtx_CONST_VECTOR (mode, v);
5542 : }
5543 :
5544 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5545 : Restrict the transformation to avoid generating a VEC_SELECT with a
5546 : mode unrelated to its operand. */
5547 4116678 : if (GET_CODE (trueop0) == VEC_SELECT
5548 132141 : && GET_CODE (trueop1) == VEC_SELECT
5549 28565 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5550 4132751 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5551 32146 : == GET_MODE_INNER(mode))
5552 : {
5553 16073 : rtx par0 = XEXP (trueop0, 1);
5554 16073 : rtx par1 = XEXP (trueop1, 1);
5555 16073 : int len0 = XVECLEN (par0, 0);
5556 16073 : int len1 = XVECLEN (par1, 0);
5557 16073 : rtvec vec = rtvec_alloc (len0 + len1);
5558 99290 : for (int i = 0; i < len0; i++)
5559 83217 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5560 99290 : for (int i = 0; i < len1; i++)
5561 83217 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5562 16073 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5563 16073 : gen_rtx_PARALLEL (VOIDmode, vec));
5564 : }
5565 : /* (vec_concat:
5566 : (subreg_lowpart:N OP)
5567 : (vec_select:N OP P)) --> OP when P selects the high half
5568 : of the OP. */
5569 4100605 : if (GET_CODE (trueop0) == SUBREG
5570 491278 : && subreg_lowpart_p (trueop0)
5571 491071 : && GET_CODE (trueop1) == VEC_SELECT
5572 3 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
5573 0 : && !side_effects_p (XEXP (trueop1, 0))
5574 4100605 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
5575 0 : return XEXP (trueop1, 0);
5576 : }
5577 : return 0;
5578 :
5579 0 : default:
5580 0 : gcc_unreachable ();
5581 : }
5582 :
5583 374874485 : if (mode == GET_MODE (op0)
5584 322149681 : && mode == GET_MODE (op1)
5585 101934190 : && vec_duplicate_p (op0, &elt0)
5586 374994420 : && vec_duplicate_p (op1, &elt1))
5587 : {
5588 : /* Try applying the operator to ELT and see if that simplifies.
5589 : We can duplicate the result if so.
5590 :
5591 : The reason we don't use simplify_gen_binary is that it isn't
5592 : necessarily a win to convert things like:
5593 :
5594 : (plus:V (vec_duplicate:V (reg:S R1))
5595 : (vec_duplicate:V (reg:S R2)))
5596 :
5597 : to:
5598 :
5599 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5600 :
5601 : The first might be done entirely in vector registers while the
5602 : second might need a move between register files. */
5603 128 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5604 : elt0, elt1);
5605 64 : if (tem)
5606 2 : return gen_vec_duplicate (mode, tem);
5607 : }
5608 :
5609 : return 0;
5610 : }
5611 :
5612 : /* Return true if binary operation OP distributes over addition in operand
5613 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5614 :
5615 : static bool
5616 7408 : distributes_over_addition_p (rtx_code op, int opno)
5617 : {
5618 0 : switch (op)
5619 : {
5620 : case PLUS:
5621 : case MINUS:
5622 : case MULT:
5623 : return true;
5624 :
5625 0 : case ASHIFT:
5626 0 : return opno == 1;
5627 :
5628 0 : default:
5629 0 : return false;
5630 : }
5631 : }
5632 :
5633 : rtx
5634 479517780 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5635 : rtx op0, rtx op1)
5636 : {
5637 479517780 : if (VECTOR_MODE_P (mode)
5638 14984391 : && code != VEC_CONCAT
5639 10855237 : && GET_CODE (op0) == CONST_VECTOR
5640 171517 : && GET_CODE (op1) == CONST_VECTOR)
5641 : {
5642 8116 : bool step_ok_p;
5643 8116 : if (CONST_VECTOR_STEPPED_P (op0)
5644 8116 : && CONST_VECTOR_STEPPED_P (op1))
5645 : /* We can operate directly on the encoding if:
5646 :
5647 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5648 : implies
5649 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5650 :
5651 : Addition and subtraction are the supported operators
5652 : for which this is true. */
5653 708 : step_ok_p = (code == PLUS || code == MINUS);
5654 7408 : else if (CONST_VECTOR_STEPPED_P (op0))
5655 : /* We can operate directly on stepped encodings if:
5656 :
5657 : a3 - a2 == a2 - a1
5658 : implies:
5659 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5660 :
5661 : which is true if (x -> x op c) distributes over addition. */
5662 1280 : step_ok_p = distributes_over_addition_p (code, 1);
5663 : else
5664 : /* Similarly in reverse. */
5665 6128 : step_ok_p = distributes_over_addition_p (code, 2);
5666 8116 : rtx_vector_builder builder;
5667 8116 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5668 : return 0;
5669 :
5670 8116 : unsigned int count = builder.encoded_nelts ();
5671 52331 : for (unsigned int i = 0; i < count; i++)
5672 : {
5673 88530 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5674 : CONST_VECTOR_ELT (op0, i),
5675 44265 : CONST_VECTOR_ELT (op1, i));
5676 44265 : if (!x || !valid_for_const_vector_p (mode, x))
5677 50 : return 0;
5678 44215 : builder.quick_push (x);
5679 : }
5680 8066 : return builder.build ();
5681 8116 : }
5682 :
5683 479509664 : if (VECTOR_MODE_P (mode)
5684 14976275 : && code == VEC_CONCAT
5685 4129154 : && (CONST_SCALAR_INT_P (op0)
5686 3979367 : || CONST_FIXED_P (op0)
5687 3979367 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5688 3975533 : || CONST_VECTOR_P (op0))
5689 173708 : && (CONST_SCALAR_INT_P (op1)
5690 171036 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5691 168862 : || CONST_FIXED_P (op1)
5692 168862 : || CONST_VECTOR_P (op1)))
5693 : {
5694 : /* Both inputs have a constant number of elements, so the result
5695 : must too. */
5696 12476 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5697 12476 : rtvec v = rtvec_alloc (n_elts);
5698 :
5699 12476 : gcc_assert (n_elts >= 2);
5700 12476 : if (n_elts == 2)
5701 : {
5702 4846 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5703 4846 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5704 :
5705 4846 : RTVEC_ELT (v, 0) = op0;
5706 4846 : RTVEC_ELT (v, 1) = op1;
5707 : }
5708 : else
5709 : {
5710 7630 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5711 7630 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5712 7630 : unsigned i;
5713 :
5714 7630 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5715 7630 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5716 7630 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5717 :
5718 48844 : for (i = 0; i < op0_n_elts; ++i)
5719 41214 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5720 49036 : for (i = 0; i < op1_n_elts; ++i)
5721 41406 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5722 : }
5723 :
5724 12476 : return gen_rtx_CONST_VECTOR (mode, v);
5725 : }
5726 :
5727 467790250 : if (VECTOR_MODE_P (mode)
5728 14963799 : && GET_CODE (op0) == CONST_VECTOR
5729 175858 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5730 479497188 : && (CONST_VECTOR_DUPLICATE_P (op0)
5731 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5732 : {
5733 116071 : switch (code)
5734 : {
5735 116071 : case PLUS:
5736 116071 : case MINUS:
5737 116071 : case MULT:
5738 116071 : case DIV:
5739 116071 : case MOD:
5740 116071 : case UDIV:
5741 116071 : case UMOD:
5742 116071 : case AND:
5743 116071 : case IOR:
5744 116071 : case XOR:
5745 116071 : case SMIN:
5746 116071 : case SMAX:
5747 116071 : case UMIN:
5748 116071 : case UMAX:
5749 116071 : case LSHIFTRT:
5750 116071 : case ASHIFTRT:
5751 116071 : case ASHIFT:
5752 116071 : case ROTATE:
5753 116071 : case ROTATERT:
5754 116071 : case SS_PLUS:
5755 116071 : case US_PLUS:
5756 116071 : case SS_MINUS:
5757 116071 : case US_MINUS:
5758 116071 : case SS_ASHIFT:
5759 116071 : case US_ASHIFT:
5760 116071 : case COPYSIGN:
5761 116071 : break;
5762 : default:
5763 : return NULL_RTX;
5764 : }
5765 :
5766 116071 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5767 116071 : ? CONST_VECTOR_NPATTERNS (op0)
5768 123838 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5769 116071 : rtx_vector_builder builder (mode, npatterns, 1);
5770 245237 : for (unsigned i = 0; i < npatterns; i++)
5771 : {
5772 258332 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5773 129166 : CONST_VECTOR_ELT (op0, i), op1);
5774 129166 : if (!x || !valid_for_const_vector_p (mode, x))
5775 0 : return 0;
5776 129166 : builder.quick_push (x);
5777 : }
5778 116071 : return builder.build ();
5779 : }
5780 :
5781 479381117 : if (SCALAR_FLOAT_MODE_P (mode)
5782 6406618 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5783 75593 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5784 11520 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5785 : {
5786 11520 : if (code == AND
5787 : || code == IOR
5788 11520 : || code == XOR)
5789 : {
5790 2515 : long tmp0[4];
5791 2515 : long tmp1[4];
5792 2515 : REAL_VALUE_TYPE r;
5793 2515 : int i;
5794 :
5795 2515 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5796 2515 : GET_MODE (op0));
5797 2515 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5798 2515 : GET_MODE (op1));
5799 12575 : for (i = 0; i < 4; i++)
5800 : {
5801 10060 : switch (code)
5802 : {
5803 5268 : case AND:
5804 5268 : tmp0[i] &= tmp1[i];
5805 5268 : break;
5806 2512 : case IOR:
5807 2512 : tmp0[i] |= tmp1[i];
5808 2512 : break;
5809 2280 : case XOR:
5810 2280 : tmp0[i] ^= tmp1[i];
5811 2280 : break;
5812 : default:
5813 : gcc_unreachable ();
5814 : }
5815 : }
5816 2515 : real_from_target (&r, tmp0, mode);
5817 2515 : return const_double_from_real_value (r, mode);
5818 : }
5819 9005 : else if (code == COPYSIGN)
5820 : {
5821 0 : REAL_VALUE_TYPE f0, f1;
5822 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5823 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5824 0 : real_copysign (&f0, &f1);
5825 0 : return const_double_from_real_value (f0, mode);
5826 : }
5827 : else
5828 : {
5829 9005 : REAL_VALUE_TYPE f0, f1, value, result;
5830 9005 : const REAL_VALUE_TYPE *opr0, *opr1;
5831 9005 : bool inexact;
5832 :
5833 9005 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5834 9005 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5835 :
5836 9005 : if (HONOR_SNANS (mode)
5837 9005 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5838 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5839 10 : return 0;
5840 :
5841 8995 : real_convert (&f0, mode, opr0);
5842 8995 : real_convert (&f1, mode, opr1);
5843 :
5844 8995 : if (code == DIV
5845 4088 : && real_equal (&f1, &dconst0)
5846 12619 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5847 3620 : return 0;
5848 :
5849 26774 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5850 5283 : && flag_trapping_math
5851 5205 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5852 : {
5853 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5854 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5855 :
5856 9 : switch (code)
5857 : {
5858 0 : case PLUS:
5859 : /* Inf + -Inf = NaN plus exception. */
5860 0 : if (s0 != s1)
5861 : return 0;
5862 : break;
5863 0 : case MINUS:
5864 : /* Inf - Inf = NaN plus exception. */
5865 0 : if (s0 == s1)
5866 : return 0;
5867 : break;
5868 : case DIV:
5869 : /* Inf / Inf = NaN plus exception. */
5870 : return 0;
5871 : default:
5872 : break;
5873 : }
5874 : }
5875 :
5876 7968 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5877 1958 : && flag_trapping_math
5878 7276 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5879 1902 : || (REAL_VALUE_ISINF (f1)
5880 10 : && real_equal (&f0, &dconst0))))
5881 : /* Inf * 0 = NaN plus exception. */
5882 18 : return 0;
5883 :
5884 5348 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5885 : &f0, &f1);
5886 5348 : real_convert (&result, mode, &value);
5887 :
5888 : /* Don't constant fold this floating point operation if
5889 : the result has overflowed and flag_trapping_math. */
5890 :
5891 5348 : if (flag_trapping_math
5892 20712 : && MODE_HAS_INFINITIES (mode)
5893 5178 : && REAL_VALUE_ISINF (result)
5894 1104 : && !REAL_VALUE_ISINF (f0)
5895 6438 : && !REAL_VALUE_ISINF (f1))
5896 : /* Overflow plus exception. */
5897 1090 : return 0;
5898 :
5899 : /* Don't constant fold this floating point operation if the
5900 : result may dependent upon the run-time rounding mode and
5901 : flag_rounding_math is set, or if GCC's software emulation
5902 : is unable to accurately represent the result. */
5903 :
5904 4258 : if ((flag_rounding_math
5905 27125 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5906 4258 : && (inexact || !real_identical (&result, &value)))
5907 378 : return NULL_RTX;
5908 :
5909 3880 : return const_double_from_real_value (result, mode);
5910 : }
5911 : }
5912 :
5913 : /* We can fold some multi-word operations. */
5914 479369597 : scalar_int_mode int_mode;
5915 479369597 : if (is_a <scalar_int_mode> (mode, &int_mode)
5916 410966938 : && CONST_SCALAR_INT_P (op0)
5917 39700277 : && CONST_SCALAR_INT_P (op1)
5918 32947663 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5919 : {
5920 32947663 : wide_int result;
5921 32947663 : wi::overflow_type overflow;
5922 32947663 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5923 32947663 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5924 :
5925 : #if TARGET_SUPPORTS_WIDE_INT == 0
5926 : /* This assert keeps the simplification from producing a result
5927 : that cannot be represented in a CONST_DOUBLE but a lot of
5928 : upstream callers expect that this function never fails to
5929 : simplify something and so you if you added this to the test
5930 : above the code would die later anyway. If this assert
5931 : happens, you just need to make the port support wide int. */
5932 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5933 : #endif
5934 32947663 : switch (code)
5935 : {
5936 1078291 : case MINUS:
5937 1078291 : result = wi::sub (pop0, pop1);
5938 1078291 : break;
5939 :
5940 25694893 : case PLUS:
5941 25694893 : result = wi::add (pop0, pop1);
5942 25694893 : break;
5943 :
5944 320599 : case MULT:
5945 320599 : result = wi::mul (pop0, pop1);
5946 320599 : break;
5947 :
5948 6927 : case DIV:
5949 6927 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5950 6927 : if (overflow)
5951 : return NULL_RTX;
5952 : break;
5953 :
5954 1220 : case MOD:
5955 1220 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5956 1220 : if (overflow)
5957 : return NULL_RTX;
5958 : break;
5959 :
5960 6131 : case UDIV:
5961 6131 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5962 6131 : if (overflow)
5963 : return NULL_RTX;
5964 : break;
5965 :
5966 15350 : case UMOD:
5967 15350 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5968 15350 : if (overflow)
5969 : return NULL_RTX;
5970 : break;
5971 :
5972 696248 : case AND:
5973 696248 : result = wi::bit_and (pop0, pop1);
5974 696248 : break;
5975 :
5976 275220 : case IOR:
5977 275220 : result = wi::bit_or (pop0, pop1);
5978 275220 : break;
5979 :
5980 56371 : case XOR:
5981 56371 : result = wi::bit_xor (pop0, pop1);
5982 56371 : break;
5983 :
5984 1761 : case SMIN:
5985 1761 : result = wi::smin (pop0, pop1);
5986 1761 : break;
5987 :
5988 1982 : case SMAX:
5989 1982 : result = wi::smax (pop0, pop1);
5990 1982 : break;
5991 :
5992 3193 : case UMIN:
5993 3193 : result = wi::umin (pop0, pop1);
5994 3193 : break;
5995 :
5996 2850 : case UMAX:
5997 2850 : result = wi::umax (pop0, pop1);
5998 2850 : break;
5999 :
6000 4748085 : case LSHIFTRT:
6001 4748085 : case ASHIFTRT:
6002 4748085 : case ASHIFT:
6003 4748085 : case SS_ASHIFT:
6004 4748085 : case US_ASHIFT:
6005 4748085 : {
6006 : /* The shift count might be in SImode while int_mode might
6007 : be narrower. On IA-64 it is even DImode. If the shift
6008 : count is too large and doesn't fit into int_mode, we'd
6009 : ICE. So, if int_mode is narrower than
6010 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6011 4748085 : if (GET_MODE (op1) == VOIDmode
6012 4748085 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6013 1789852 : pop1 = rtx_mode_t (op1, DImode);
6014 :
6015 4748085 : wide_int wop1 = pop1;
6016 4748085 : if (SHIFT_COUNT_TRUNCATED)
6017 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
6018 4748085 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
6019 132 : return NULL_RTX;
6020 :
6021 4747953 : switch (code)
6022 : {
6023 2743525 : case LSHIFTRT:
6024 2743525 : result = wi::lrshift (pop0, wop1);
6025 2743525 : break;
6026 :
6027 73936 : case ASHIFTRT:
6028 73936 : result = wi::arshift (pop0, wop1);
6029 73936 : break;
6030 :
6031 1930492 : case ASHIFT:
6032 1930492 : result = wi::lshift (pop0, wop1);
6033 1930492 : break;
6034 :
6035 0 : case SS_ASHIFT:
6036 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
6037 0 : result = wi::lshift (pop0, wop1);
6038 0 : else if (wi::neg_p (pop0))
6039 0 : result = wi::min_value (int_mode, SIGNED);
6040 : else
6041 0 : result = wi::max_value (int_mode, SIGNED);
6042 : break;
6043 :
6044 0 : case US_ASHIFT:
6045 0 : if (wi::eq_p (pop0, 0))
6046 0 : result = pop0;
6047 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
6048 0 : result = wi::lshift (pop0, wop1);
6049 : else
6050 0 : result = wi::max_value (int_mode, UNSIGNED);
6051 : break;
6052 :
6053 0 : default:
6054 0 : gcc_unreachable ();
6055 : }
6056 4747953 : break;
6057 4748085 : }
6058 29978 : case ROTATE:
6059 29978 : case ROTATERT:
6060 29978 : {
6061 : /* The rotate count might be in SImode while int_mode might
6062 : be narrower. On IA-64 it is even DImode. If the shift
6063 : count is too large and doesn't fit into int_mode, we'd
6064 : ICE. So, if int_mode is narrower than
6065 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6066 29978 : if (GET_MODE (op1) == VOIDmode
6067 29978 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6068 23634 : pop1 = rtx_mode_t (op1, DImode);
6069 :
6070 29978 : if (wi::neg_p (pop1))
6071 : return NULL_RTX;
6072 :
6073 29878 : switch (code)
6074 : {
6075 10343 : case ROTATE:
6076 10343 : result = wi::lrotate (pop0, pop1);
6077 10343 : break;
6078 :
6079 19535 : case ROTATERT:
6080 19535 : result = wi::rrotate (pop0, pop1);
6081 19535 : break;
6082 :
6083 0 : default:
6084 0 : gcc_unreachable ();
6085 : }
6086 : break;
6087 : }
6088 :
6089 2270 : case SS_PLUS:
6090 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
6091 4484 : clamp_signed_saturation:
6092 4484 : if (overflow == wi::OVF_OVERFLOW)
6093 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
6094 4170 : else if (overflow == wi::OVF_UNDERFLOW)
6095 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
6096 3892 : else if (overflow != wi::OVF_NONE)
6097 : return NULL_RTX;
6098 : break;
6099 :
6100 2220 : case US_PLUS:
6101 2220 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6102 2220 : clamp_unsigned_saturation:
6103 2220 : if (overflow != wi::OVF_NONE)
6104 461 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6105 : break;
6106 :
6107 2214 : case SS_MINUS:
6108 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6109 2214 : goto clamp_signed_saturation;
6110 :
6111 1852 : case US_MINUS:
6112 1852 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6113 1852 : if (overflow != wi::OVF_NONE)
6114 1203 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6115 : break;
6116 :
6117 0 : case SS_MULT:
6118 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6119 0 : goto clamp_signed_saturation;
6120 :
6121 0 : case US_MULT:
6122 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6123 0 : goto clamp_unsigned_saturation;
6124 :
6125 8 : case SMUL_HIGHPART:
6126 8 : result = wi::mul_high (pop0, pop1, SIGNED);
6127 8 : break;
6128 :
6129 0 : case UMUL_HIGHPART:
6130 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6131 0 : break;
6132 :
6133 : default:
6134 : return NULL_RTX;
6135 : }
6136 32945234 : return immed_wide_int_const (result, int_mode);
6137 32947663 : }
6138 :
6139 : /* Handle polynomial integers. */
6140 : if (NUM_POLY_INT_COEFFS > 1
6141 : && is_a <scalar_int_mode> (mode, &int_mode)
6142 : && poly_int_rtx_p (op0)
6143 : && poly_int_rtx_p (op1))
6144 : {
6145 : poly_wide_int result;
6146 : switch (code)
6147 : {
6148 : case PLUS:
6149 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6150 : break;
6151 :
6152 : case MINUS:
6153 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6154 : break;
6155 :
6156 : case MULT:
6157 : if (CONST_SCALAR_INT_P (op1))
6158 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6159 : else
6160 : return NULL_RTX;
6161 : break;
6162 :
6163 : case ASHIFT:
6164 : if (CONST_SCALAR_INT_P (op1))
6165 : {
6166 : wide_int shift
6167 : = rtx_mode_t (op1,
6168 : GET_MODE (op1) == VOIDmode
6169 : && (GET_MODE_PRECISION (int_mode)
6170 : < HOST_BITS_PER_WIDE_INT)
6171 : ? DImode : mode);
6172 : if (SHIFT_COUNT_TRUNCATED)
6173 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6174 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6175 : return NULL_RTX;
6176 : result = wi::to_poly_wide (op0, mode) << shift;
6177 : }
6178 : else
6179 : return NULL_RTX;
6180 : break;
6181 :
6182 : case IOR:
6183 : if (!CONST_SCALAR_INT_P (op1)
6184 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6185 : rtx_mode_t (op1, mode), &result))
6186 : return NULL_RTX;
6187 : break;
6188 :
6189 : default:
6190 : return NULL_RTX;
6191 : }
6192 : return immed_wide_int_const (result, int_mode);
6193 : }
6194 :
6195 : return NULL_RTX;
6196 : }
6197 :
6198 :
6199 :
6200 : /* Return a positive integer if X should sort after Y. The value
6201 : returned is 1 if and only if X and Y are both regs. */
6202 :
6203 : static int
6204 115192931 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6205 : {
6206 115192931 : int result;
6207 :
6208 115192931 : result = (commutative_operand_precedence (y)
6209 115192931 : - commutative_operand_precedence (x));
6210 115192931 : if (result)
6211 81051942 : return result + result;
6212 :
6213 : /* Group together equal REGs to do more simplification. */
6214 34140989 : if (REG_P (x) && REG_P (y))
6215 8638652 : return REGNO (x) > REGNO (y);
6216 :
6217 : return 0;
6218 : }
6219 :
6220 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6221 : operands may be another PLUS or MINUS.
6222 :
6223 : Rather than test for specific case, we do this by a brute-force method
6224 : and do all possible simplifications until no more changes occur. Then
6225 : we rebuild the operation.
6226 :
6227 : May return NULL_RTX when no changes were made. */
6228 :
6229 : rtx
6230 38739427 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6231 : rtx op0, rtx op1)
6232 : {
6233 38739427 : struct simplify_plus_minus_op_data
6234 : {
6235 : rtx op;
6236 : short neg;
6237 : } ops[16];
6238 38739427 : rtx result, tem;
6239 38739427 : int n_ops = 2;
6240 38739427 : int changed, n_constants, canonicalized = 0;
6241 38739427 : int i, j;
6242 :
6243 38739427 : memset (ops, 0, sizeof ops);
6244 :
6245 : /* Set up the two operands and then expand them until nothing has been
6246 : changed. If we run out of room in our array, give up; this should
6247 : almost never happen. */
6248 :
6249 38739427 : ops[0].op = op0;
6250 38739427 : ops[0].neg = 0;
6251 38739427 : ops[1].op = op1;
6252 38739427 : ops[1].neg = (code == MINUS);
6253 :
6254 78846195 : do
6255 : {
6256 78846195 : changed = 0;
6257 78846195 : n_constants = 0;
6258 :
6259 319303023 : for (i = 0; i < n_ops; i++)
6260 : {
6261 240456843 : rtx this_op = ops[i].op;
6262 240456843 : int this_neg = ops[i].neg;
6263 240456843 : enum rtx_code this_code = GET_CODE (this_op);
6264 :
6265 240456843 : switch (this_code)
6266 : {
6267 39132815 : case PLUS:
6268 39132815 : case MINUS:
6269 39132815 : if (n_ops == ARRAY_SIZE (ops))
6270 : return NULL_RTX;
6271 :
6272 39132800 : ops[n_ops].op = XEXP (this_op, 1);
6273 39132800 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6274 39132800 : n_ops++;
6275 :
6276 39132800 : ops[i].op = XEXP (this_op, 0);
6277 39132800 : changed = 1;
6278 : /* If this operand was negated then we will potentially
6279 : canonicalize the expression. Similarly if we don't
6280 : place the operands adjacent we're re-ordering the
6281 : expression and thus might be performing a
6282 : canonicalization. Ignore register re-ordering.
6283 : ??? It might be better to shuffle the ops array here,
6284 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6285 : be seen as non-canonical. */
6286 39132800 : if (this_neg
6287 38437848 : || (i != n_ops - 2
6288 37755638 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6289 240456828 : canonicalized = 1;
6290 : break;
6291 :
6292 1713 : case NEG:
6293 1713 : ops[i].op = XEXP (this_op, 0);
6294 1713 : ops[i].neg = ! this_neg;
6295 1713 : changed = 1;
6296 1713 : canonicalized = 1;
6297 1713 : break;
6298 :
6299 1609758 : case CONST:
6300 1609758 : if (n_ops != ARRAY_SIZE (ops)
6301 1609758 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6302 1475555 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6303 1454761 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6304 : {
6305 1454761 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6306 1454761 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6307 1454761 : ops[n_ops].neg = this_neg;
6308 1454761 : n_ops++;
6309 1454761 : changed = 1;
6310 1454761 : canonicalized = 1;
6311 : }
6312 : break;
6313 :
6314 57871 : case NOT:
6315 : /* ~a -> (-a - 1) */
6316 57871 : if (n_ops != ARRAY_SIZE (ops))
6317 : {
6318 57871 : ops[n_ops].op = CONSTM1_RTX (mode);
6319 57871 : ops[n_ops++].neg = this_neg;
6320 57871 : ops[i].op = XEXP (this_op, 0);
6321 57871 : ops[i].neg = !this_neg;
6322 57871 : changed = 1;
6323 57871 : canonicalized = 1;
6324 : }
6325 : break;
6326 :
6327 119046590 : CASE_CONST_SCALAR_INT:
6328 119046590 : case CONST_POLY_INT:
6329 119046590 : n_constants++;
6330 119046590 : if (this_neg)
6331 : {
6332 1174968 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6333 1174968 : ops[i].neg = 0;
6334 1174968 : changed = 1;
6335 1174968 : canonicalized = 1;
6336 : }
6337 : break;
6338 :
6339 : default:
6340 : break;
6341 : }
6342 : }
6343 : }
6344 78846180 : while (changed);
6345 :
6346 38739412 : if (n_constants > 1)
6347 23298596 : canonicalized = 1;
6348 :
6349 38739412 : gcc_assert (n_ops >= 2);
6350 :
6351 : /* If we only have two operands, we can avoid the loops. */
6352 38739412 : if (n_ops == 2)
6353 : {
6354 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6355 0 : rtx lhs, rhs;
6356 :
6357 : /* Get the two operands. Be careful with the order, especially for
6358 : the cases where code == MINUS. */
6359 0 : if (ops[0].neg && ops[1].neg)
6360 : {
6361 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6362 0 : rhs = ops[1].op;
6363 : }
6364 0 : else if (ops[0].neg)
6365 : {
6366 0 : lhs = ops[1].op;
6367 0 : rhs = ops[0].op;
6368 : }
6369 : else
6370 : {
6371 0 : lhs = ops[0].op;
6372 0 : rhs = ops[1].op;
6373 : }
6374 :
6375 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6376 : }
6377 :
6378 : /* Now simplify each pair of operands until nothing changes. */
6379 62985579 : while (1)
6380 : {
6381 : /* Insertion sort is good enough for a small array. */
6382 167140270 : for (i = 1; i < n_ops; i++)
6383 : {
6384 104154691 : struct simplify_plus_minus_op_data save;
6385 104154691 : int cmp;
6386 :
6387 104154691 : j = i - 1;
6388 104154691 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6389 104154691 : if (cmp <= 0)
6390 91168399 : continue;
6391 : /* Just swapping registers doesn't count as canonicalization. */
6392 12986292 : if (cmp != 1)
6393 9993320 : canonicalized = 1;
6394 :
6395 12986292 : save = ops[i];
6396 15399636 : do
6397 15399636 : ops[j + 1] = ops[j];
6398 15399636 : while (j--
6399 28385928 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6400 12986292 : ops[j + 1] = save;
6401 : }
6402 :
6403 62985579 : changed = 0;
6404 167140270 : for (i = n_ops - 1; i > 0; i--)
6405 250147795 : for (j = i - 1; j >= 0; j--)
6406 : {
6407 146920398 : rtx lhs = ops[j].op, rhs = ops[i].op;
6408 146920398 : int lneg = ops[j].neg, rneg = ops[i].neg;
6409 :
6410 146920398 : if (lhs != 0 && rhs != 0)
6411 : {
6412 121821590 : enum rtx_code ncode = PLUS;
6413 :
6414 121821590 : if (lneg != rneg)
6415 : {
6416 11059594 : ncode = MINUS;
6417 11059594 : if (lneg)
6418 7002344 : std::swap (lhs, rhs);
6419 : }
6420 110761996 : else if (swap_commutative_operands_p (lhs, rhs))
6421 363172 : std::swap (lhs, rhs);
6422 :
6423 121821590 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6424 27968529 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6425 : {
6426 23449016 : rtx tem_lhs, tem_rhs;
6427 :
6428 23449016 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6429 23449016 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6430 23449016 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6431 : tem_rhs);
6432 :
6433 23449016 : if (tem && !CONSTANT_P (tem))
6434 1758 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6435 : }
6436 : else
6437 98372574 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6438 :
6439 98374332 : if (tem)
6440 : {
6441 : /* Reject "simplifications" that just wrap the two
6442 : arguments in a CONST. Failure to do so can result
6443 : in infinite recursion with simplify_binary_operation
6444 : when it calls us to simplify CONST operations.
6445 : Also, if we find such a simplification, don't try
6446 : any more combinations with this rhs: We must have
6447 : something like symbol+offset, ie. one of the
6448 : trivial CONST expressions we handle later. */
6449 25629448 : if (GET_CODE (tem) == CONST
6450 929052 : && GET_CODE (XEXP (tem, 0)) == ncode
6451 928500 : && XEXP (XEXP (tem, 0), 0) == lhs
6452 927294 : && XEXP (XEXP (tem, 0), 1) == rhs)
6453 : break;
6454 24702154 : lneg &= rneg;
6455 24702154 : if (GET_CODE (tem) == NEG)
6456 45412 : tem = XEXP (tem, 0), lneg = !lneg;
6457 24702154 : if (poly_int_rtx_p (tem) && lneg)
6458 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6459 :
6460 24702154 : ops[i].op = tem;
6461 24702154 : ops[i].neg = lneg;
6462 24702154 : ops[j].op = NULL_RTX;
6463 24702154 : changed = 1;
6464 24702154 : canonicalized = 1;
6465 : }
6466 : }
6467 : }
6468 :
6469 62985579 : if (!changed)
6470 : break;
6471 :
6472 : /* Pack all the operands to the lower-numbered entries. */
6473 97964545 : for (i = 0, j = 0; j < n_ops; j++)
6474 73718378 : if (ops[j].op)
6475 : {
6476 49016224 : ops[i] = ops[j];
6477 49016224 : i++;
6478 : }
6479 : n_ops = i;
6480 : }
6481 :
6482 : /* If nothing changed, check that rematerialization of rtl instructions
6483 : is still required. */
6484 38739412 : if (!canonicalized)
6485 : {
6486 : /* Perform rematerialization if only all operands are registers and
6487 : all operations are PLUS. */
6488 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6489 : around rs6000 and how it uses the CA register. See PR67145. */
6490 5133408 : for (i = 0; i < n_ops; i++)
6491 4142371 : if (ops[i].neg
6492 3858398 : || !REG_P (ops[i].op)
6493 7425358 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6494 324239 : && fixed_regs[REGNO (ops[i].op)]
6495 251 : && !global_regs[REGNO (ops[i].op)]
6496 251 : && ops[i].op != frame_pointer_rtx
6497 165 : && ops[i].op != arg_pointer_rtx
6498 149 : && ops[i].op != stack_pointer_rtx))
6499 : return NULL_RTX;
6500 991037 : goto gen_result;
6501 : }
6502 :
6503 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6504 36888991 : if (n_ops == 2
6505 22553212 : && CONST_INT_P (ops[1].op)
6506 21937493 : && CONSTANT_P (ops[0].op)
6507 160 : && ops[0].neg)
6508 54 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6509 :
6510 : /* We suppressed creation of trivial CONST expressions in the
6511 : combination loop to avoid recursion. Create one manually now.
6512 : The combination loop should have ensured that there is exactly
6513 : one CONST_INT, and the sort will have ensured that it is last
6514 : in the array and that any other constant will be next-to-last. */
6515 :
6516 36888937 : if (n_ops > 1
6517 36373397 : && poly_int_rtx_p (ops[n_ops - 1].op)
6518 70681844 : && CONSTANT_P (ops[n_ops - 2].op))
6519 : {
6520 1522748 : rtx value = ops[n_ops - 1].op;
6521 1522748 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6522 681428 : value = neg_poly_int_rtx (mode, value);
6523 1522748 : if (CONST_INT_P (value))
6524 : {
6525 3045496 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6526 1522748 : INTVAL (value));
6527 1522748 : n_ops--;
6528 : }
6529 : }
6530 :
6531 : /* Put a non-negated operand first, if possible. */
6532 :
6533 38573259 : for (i = 0; i < n_ops && ops[i].neg; i++)
6534 1684322 : continue;
6535 36888937 : if (i == n_ops)
6536 8996 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6537 36879941 : else if (i != 0)
6538 : {
6539 1581964 : tem = ops[0].op;
6540 1581964 : ops[0] = ops[i];
6541 1581964 : ops[i].op = tem;
6542 1581964 : ops[i].neg = 1;
6543 : }
6544 :
6545 : /* Now make the result by performing the requested operations. */
6546 35297977 : gen_result:
6547 37879974 : result = ops[0].op;
6548 89318879 : for (i = 1; i < n_ops; i++)
6549 102877810 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6550 : mode, result, ops[i].op);
6551 :
6552 : return result;
6553 1684322 : }
6554 :
6555 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6556 : static bool
6557 524278745 : plus_minus_operand_p (const_rtx x)
6558 : {
6559 524278745 : return GET_CODE (x) == PLUS
6560 524278745 : || GET_CODE (x) == MINUS
6561 524278745 : || (GET_CODE (x) == CONST
6562 1966580 : && GET_CODE (XEXP (x, 0)) == PLUS
6563 1343535 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6564 1269590 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6565 : }
6566 :
6567 : /* Like simplify_binary_operation except used for relational operators.
6568 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6569 : not also be VOIDmode.
6570 :
6571 : CMP_MODE specifies in which mode the comparison is done in, so it is
6572 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6573 : the operands or, if both are VOIDmode, the operands are compared in
6574 : "infinite precision". */
6575 : rtx
6576 127336321 : simplify_context::simplify_relational_operation (rtx_code code,
6577 : machine_mode mode,
6578 : machine_mode cmp_mode,
6579 : rtx op0, rtx op1)
6580 : {
6581 127336321 : rtx tem, trueop0, trueop1;
6582 :
6583 127336321 : if (cmp_mode == VOIDmode)
6584 28083317 : cmp_mode = GET_MODE (op0);
6585 28083317 : if (cmp_mode == VOIDmode)
6586 264566 : cmp_mode = GET_MODE (op1);
6587 :
6588 127336321 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6589 127336321 : if (tem)
6590 778747 : return relational_result (mode, cmp_mode, tem);
6591 :
6592 : /* For the following tests, ensure const0_rtx is op1. */
6593 126557574 : if (swap_commutative_operands_p (op0, op1)
6594 126557574 : || (op0 == const0_rtx && op1 != const0_rtx))
6595 2607365 : std::swap (op0, op1), code = swap_condition (code);
6596 :
6597 : /* If op0 is a compare, extract the comparison arguments from it. */
6598 126557574 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6599 13791132 : return simplify_gen_relational (code, mode, VOIDmode,
6600 13791132 : XEXP (op0, 0), XEXP (op0, 1));
6601 :
6602 112766442 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6603 : return NULL_RTX;
6604 :
6605 82961673 : trueop0 = avoid_constant_pool_reference (op0);
6606 82961673 : trueop1 = avoid_constant_pool_reference (op1);
6607 82961673 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6608 82961673 : trueop0, trueop1);
6609 : }
6610 :
6611 : /* This part of simplify_relational_operation is only used when CMP_MODE
6612 : is not in class MODE_CC (i.e. it is a real comparison).
6613 :
6614 : MODE is the mode of the result, while CMP_MODE specifies in which
6615 : mode the comparison is done in, so it is the mode of the operands. */
6616 :
6617 : rtx
6618 82961673 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6619 : machine_mode mode,
6620 : machine_mode cmp_mode,
6621 : rtx op0, rtx op1)
6622 : {
6623 82961673 : enum rtx_code op0code = GET_CODE (op0);
6624 :
6625 82961673 : if (op1 == const0_rtx && COMPARISON_P (op0))
6626 : {
6627 : /* If op0 is a comparison, extract the comparison arguments
6628 : from it. */
6629 267380 : if (code == NE)
6630 : {
6631 118924 : if (GET_MODE (op0) == mode)
6632 187 : return simplify_rtx (op0);
6633 : else
6634 118737 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6635 118737 : XEXP (op0, 0), XEXP (op0, 1));
6636 : }
6637 148456 : else if (code == EQ)
6638 : {
6639 116944 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6640 116944 : if (new_code != UNKNOWN)
6641 116627 : return simplify_gen_relational (new_code, mode, VOIDmode,
6642 116627 : XEXP (op0, 0), XEXP (op0, 1));
6643 : }
6644 : }
6645 :
6646 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6647 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6648 82726122 : if ((code == LTU || code == GEU)
6649 5155639 : && GET_CODE (op0) == PLUS
6650 694915 : && CONST_INT_P (XEXP (op0, 1))
6651 472647 : && (rtx_equal_p (op1, XEXP (op0, 0))
6652 335157 : || rtx_equal_p (op1, XEXP (op0, 1)))
6653 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6654 82929366 : && XEXP (op0, 1) != const0_rtx)
6655 : {
6656 203244 : rtx new_cmp
6657 203244 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6658 204775 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6659 203244 : cmp_mode, XEXP (op0, 0), new_cmp);
6660 : }
6661 :
6662 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6663 : transformed into (LTU a -C). */
6664 82522878 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6665 330545 : && CONST_INT_P (XEXP (op0, 1))
6666 260544 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6667 26643 : && XEXP (op0, 1) != const0_rtx)
6668 : {
6669 26643 : rtx new_cmp
6670 26643 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6671 26643 : return simplify_gen_relational (LTU, mode, cmp_mode,
6672 26643 : XEXP (op0, 0), new_cmp);
6673 : }
6674 :
6675 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6676 82496235 : if ((code == LTU || code == GEU)
6677 4952395 : && GET_CODE (op0) == PLUS
6678 491671 : && rtx_equal_p (op1, XEXP (op0, 1))
6679 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6680 82501652 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6681 5417 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6682 5417 : copy_rtx (XEXP (op0, 0)));
6683 :
6684 82490818 : if (op1 == const0_rtx)
6685 : {
6686 : /* Canonicalize (GTU x 0) as (NE x 0). */
6687 36744392 : if (code == GTU)
6688 75465 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6689 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6690 36668927 : if (code == LEU)
6691 32890 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6692 :
6693 36636037 : if ((code == NE || code == EQ)
6694 : /* Verify op0 is IOR */
6695 32936540 : && GET_CODE (op0) == IOR
6696 : /* only enters if op1 is 0 */
6697 : /* Verify IOR operand is NE */
6698 544937 : && GET_CODE (XEXP (op0, 0)) == NE
6699 16473 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6700 : /* Verify second NE operand is 0 */
6701 105 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6702 : {
6703 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6704 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6705 31 : return t;
6706 : }
6707 :
6708 : }
6709 45746426 : else if (op1 == const1_rtx)
6710 : {
6711 3031078 : switch (code)
6712 : {
6713 8594 : case GE:
6714 : /* Canonicalize (GE x 1) as (GT x 0). */
6715 8594 : return simplify_gen_relational (GT, mode, cmp_mode,
6716 8594 : op0, const0_rtx);
6717 195840 : case GEU:
6718 : /* Canonicalize (GEU x 1) as (NE x 0). */
6719 195840 : return simplify_gen_relational (NE, mode, cmp_mode,
6720 195840 : op0, const0_rtx);
6721 10388 : case LT:
6722 : /* Canonicalize (LT x 1) as (LE x 0). */
6723 10388 : return simplify_gen_relational (LE, mode, cmp_mode,
6724 10388 : op0, const0_rtx);
6725 51218 : case LTU:
6726 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6727 51218 : return simplify_gen_relational (EQ, mode, cmp_mode,
6728 51218 : op0, const0_rtx);
6729 : default:
6730 : break;
6731 : }
6732 : }
6733 42715348 : else if (op1 == constm1_rtx)
6734 : {
6735 : /* Canonicalize (LE x -1) as (LT x 0). */
6736 991730 : if (code == LE)
6737 1568 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6738 : /* Canonicalize (GT x -1) as (GE x 0). */
6739 990162 : if (code == GT)
6740 5186 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6741 : }
6742 :
6743 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6744 78410141 : if ((code == EQ || code == NE)
6745 61177412 : && (op0code == PLUS || op0code == MINUS)
6746 2407042 : && CONSTANT_P (op1)
6747 884437 : && CONSTANT_P (XEXP (op0, 1))
6748 497736 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6749 : {
6750 497703 : rtx x = XEXP (op0, 0);
6751 497703 : rtx c = XEXP (op0, 1);
6752 497703 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6753 497703 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6754 :
6755 : /* Detect an infinite recursive condition, where we oscillate at this
6756 : simplification case between:
6757 : A + B == C <---> C - B == A,
6758 : where A, B, and C are all constants with non-simplifiable expressions,
6759 : usually SYMBOL_REFs. */
6760 497703 : if (GET_CODE (tem) == invcode
6761 57 : && CONSTANT_P (x)
6762 497721 : && rtx_equal_p (c, XEXP (tem, 1)))
6763 : return NULL_RTX;
6764 :
6765 497685 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6766 : }
6767 :
6768 : /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0). */
6769 60679709 : if ((code == EQ || code == NE)
6770 60679709 : && op0code == PLUS
6771 1585240 : && rtx_equal_p (XEXP (op0, 1), op1)
6772 3578 : && !side_effects_p (op1)
6773 3578 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6774 3566 : return simplify_gen_relational (code, mode, cmp_mode,
6775 3566 : XEXP (op0, 0), CONST0_RTX (cmp_mode));
6776 :
6777 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6778 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6779 81608369 : scalar_int_mode int_mode, int_cmp_mode;
6780 81608369 : if (code == NE
6781 32254111 : && op1 == const0_rtx
6782 2195220 : && is_int_mode (mode, &int_mode)
6783 83729823 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6784 : /* ??? Work-around BImode bugs in the ia64 backend. */
6785 2195220 : && int_mode != BImode
6786 2195196 : && int_cmp_mode != BImode
6787 2195196 : && nonzero_bits (op0, int_cmp_mode) == 1
6788 81608369 : && STORE_FLAG_VALUE == 1)
6789 147532 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6790 73766 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6791 18153 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6792 :
6793 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6794 81534603 : if ((code == EQ || code == NE)
6795 60602377 : && op1 == const0_rtx
6796 32791066 : && op0code == XOR)
6797 13028 : return simplify_gen_relational (code, mode, cmp_mode,
6798 13028 : XEXP (op0, 0), XEXP (op0, 1));
6799 :
6800 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6801 60589349 : if ((code == EQ || code == NE)
6802 60589349 : && op0code == XOR
6803 4735 : && rtx_equal_p (XEXP (op0, 0), op1)
6804 6 : && !side_effects_p (XEXP (op0, 0)))
6805 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6806 0 : CONST0_RTX (mode));
6807 :
6808 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6809 81521575 : if ((code == EQ || code == NE)
6810 60589349 : && op0code == XOR
6811 4735 : && rtx_equal_p (XEXP (op0, 1), op1)
6812 81521729 : && !side_effects_p (XEXP (op0, 1)))
6813 154 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6814 154 : CONST0_RTX (mode));
6815 :
6816 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6817 81521421 : if ((code == EQ || code == NE)
6818 60589195 : && op0code == XOR
6819 4581 : && CONST_SCALAR_INT_P (op1)
6820 970 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6821 437 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6822 : simplify_gen_binary (XOR, cmp_mode,
6823 437 : XEXP (op0, 1), op1));
6824 :
6825 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6826 : constant folding if x/y is a constant. */
6827 60588758 : if ((code == EQ || code == NE)
6828 60588758 : && (op0code == AND || op0code == IOR)
6829 3684449 : && !side_effects_p (op1)
6830 3684343 : && op1 != CONST0_RTX (cmp_mode))
6831 : {
6832 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6833 : (eq/ne (and (not y) x) 0). */
6834 403569 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6835 808833 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6836 : {
6837 24916 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6838 : cmp_mode);
6839 24916 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6840 :
6841 24916 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6842 24916 : CONST0_RTX (cmp_mode));
6843 : }
6844 :
6845 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6846 : (eq/ne (and (not x) y) 0). */
6847 378728 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6848 741343 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6849 : {
6850 42596 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6851 : cmp_mode);
6852 42596 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6853 :
6854 42596 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6855 42596 : CONST0_RTX (cmp_mode));
6856 : }
6857 : }
6858 :
6859 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6860 : relationship. */
6861 81453472 : if ((op0code == AND || op0code == IOR)
6862 3797305 : && CONST_INT_P (op1)
6863 3621844 : && CONST_INT_P (XEXP (op0, 1)))
6864 : {
6865 2434644 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6866 2434644 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6867 :
6868 : /* For AND operations:
6869 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6870 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6871 : - (x & c1) >= c2 when c1 is less than c2 -> false
6872 : - (x & c1) < c2 when c1 is less than c2 -> true
6873 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6874 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6875 :
6876 : For IOR operations:
6877 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6878 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6879 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6880 : - (x | c1) > c2 when c1 is greater than c2 -> true
6881 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6882 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6883 2434644 : if ((op0code == AND
6884 2430402 : && ((code == EQ && (c1 & c2) != c2)
6885 2430389 : || (code == GEU && c1 < c2)
6886 2430389 : || (code == GTU && c1 <= c2)))
6887 2434631 : || ((op0code == IOR
6888 4242 : && ((code == EQ && (c1 & c2) != c1)
6889 4238 : || (code == LEU && c1 > c2)
6890 4238 : || (code == LTU && c1 >= c2)))))
6891 17 : return const0_rtx;
6892 :
6893 2434627 : if ((op0code == AND
6894 2430389 : && ((code == NE && (c1 & c2) != c2)
6895 2430314 : || (code == LTU && c1 < c2)
6896 2430314 : || (code == LEU && c1 <= c2)))
6897 2434552 : || ((op0code == IOR
6898 4238 : && ((code == NE && (c1 & c2) != c1)
6899 4178 : || (code == GTU && c1 > c2)
6900 4178 : || (code == GEU && c1 >= c2)))))
6901 135 : return const_true_rtx;
6902 : }
6903 :
6904 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6905 81453320 : if ((code == EQ || code == NE)
6906 60521094 : && GET_CODE (op0) == BSWAP
6907 324 : && CONST_SCALAR_INT_P (op1))
6908 93 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6909 : simplify_gen_unary (BSWAP, cmp_mode,
6910 93 : op1, cmp_mode));
6911 :
6912 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6913 60521001 : if ((code == EQ || code == NE)
6914 60521001 : && GET_CODE (op0) == BSWAP
6915 231 : && GET_CODE (op1) == BSWAP)
6916 18 : return simplify_gen_relational (code, mode, cmp_mode,
6917 18 : XEXP (op0, 0), XEXP (op1, 0));
6918 :
6919 81453209 : if (op0code == POPCOUNT && op1 == const0_rtx)
6920 0 : switch (code)
6921 : {
6922 0 : case EQ:
6923 0 : case LE:
6924 0 : case LEU:
6925 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6926 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6927 : XEXP (op0, 0),
6928 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6929 :
6930 0 : case NE:
6931 0 : case GT:
6932 0 : case GTU:
6933 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6934 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6935 : XEXP (op0, 0),
6936 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6937 :
6938 : default:
6939 : break;
6940 : }
6941 :
6942 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6943 81453209 : if (code == NE
6944 32139366 : && op1 == const0_rtx
6945 16528376 : && (op0code == TRUNCATE
6946 149842 : || (partial_subreg_p (op0)
6947 149098 : && subreg_lowpart_p (op0)))
6948 125843 : && SCALAR_INT_MODE_P (mode)
6949 81453209 : && STORE_FLAG_VALUE == 1)
6950 : {
6951 30841 : rtx tmp = XEXP (op0, 0);
6952 30841 : if (GET_CODE (tmp) == ASHIFT
6953 2440 : && GET_MODE (tmp) == mode
6954 229 : && CONST_INT_P (XEXP (tmp, 1))
6955 229 : && is_int_mode (GET_MODE (op0), &int_mode)
6956 31070 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6957 229 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6958 : }
6959 :
6960 : /* For two unsigned booleans A and B:
6961 :
6962 : A > B == ~B & A
6963 : A >= B == ~B | A
6964 : A < B == ~A & B
6965 : A <= B == ~A | B
6966 : A == B == ~A ^ B (== ~B ^ A)
6967 : A != B == A ^ B
6968 :
6969 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
6970 : with the rules above applying for positive STORE_FLAG_VALUE and with
6971 : the relations reversed for negative STORE_FLAG_VALUE. */
6972 81452980 : if (is_a<scalar_int_mode> (cmp_mode)
6973 78806349 : && COMPARISON_P (op0)
6974 81565691 : && COMPARISON_P (op1))
6975 : {
6976 10039 : rtx t = NULL_RTX;
6977 10039 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
6978 755 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
6979 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
6980 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
6981 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
6982 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
6983 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
6984 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
6985 : else if (code == EQ)
6986 3252 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
6987 : else if (code == NE)
6988 3872 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
6989 10039 : if (t)
6990 : return t;
6991 : }
6992 :
6993 : return NULL_RTX;
6994 : }
6995 :
6996 : enum
6997 : {
6998 : CMP_EQ = 1,
6999 : CMP_LT = 2,
7000 : CMP_GT = 4,
7001 : CMP_LTU = 8,
7002 : CMP_GTU = 16
7003 : };
7004 :
7005 :
7006 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
7007 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
7008 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
7009 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
7010 : For floating-point comparisons, assume that the operands were ordered. */
7011 :
7012 : static rtx
7013 711165 : comparison_result (enum rtx_code code, int known_results)
7014 : {
7015 711165 : switch (code)
7016 : {
7017 130806 : case EQ:
7018 130806 : case UNEQ:
7019 130806 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
7020 443717 : case NE:
7021 443717 : case LTGT:
7022 443717 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
7023 :
7024 9480 : case LT:
7025 9480 : case UNLT:
7026 9480 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
7027 8616 : case GE:
7028 8616 : case UNGE:
7029 8616 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
7030 :
7031 12724 : case GT:
7032 12724 : case UNGT:
7033 12724 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
7034 14713 : case LE:
7035 14713 : case UNLE:
7036 14713 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
7037 :
7038 23956 : case LTU:
7039 23956 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
7040 8832 : case GEU:
7041 8832 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
7042 :
7043 47806 : case GTU:
7044 47806 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
7045 10507 : case LEU:
7046 10507 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
7047 :
7048 0 : case ORDERED:
7049 0 : return const_true_rtx;
7050 8 : case UNORDERED:
7051 8 : return const0_rtx;
7052 0 : default:
7053 0 : gcc_unreachable ();
7054 : }
7055 : }
7056 :
7057 : /* Check if the given comparison (done in the given MODE) is actually
7058 : a tautology or a contradiction. If the mode is VOIDmode, the
7059 : comparison is done in "infinite precision". If no simplification
7060 : is possible, this function returns zero. Otherwise, it returns
7061 : either const_true_rtx or const0_rtx. */
7062 :
7063 : rtx
7064 127426465 : simplify_const_relational_operation (enum rtx_code code,
7065 : machine_mode mode,
7066 : rtx op0, rtx op1)
7067 : {
7068 134126556 : rtx tem;
7069 134126556 : rtx trueop0;
7070 134126556 : rtx trueop1;
7071 :
7072 134126556 : gcc_assert (mode != VOIDmode
7073 : || (GET_MODE (op0) == VOIDmode
7074 : && GET_MODE (op1) == VOIDmode));
7075 :
7076 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
7077 134126556 : if (GET_MODE_CLASS (mode) == MODE_CC
7078 43601665 : && (op1 != const0_rtx
7079 43601665 : || GET_CODE (op0) != COMPARE))
7080 : return NULL_RTX;
7081 :
7082 : /* If op0 is a compare, extract the comparison arguments from it. */
7083 104321787 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
7084 : {
7085 13796896 : op1 = XEXP (op0, 1);
7086 13796896 : op0 = XEXP (op0, 0);
7087 :
7088 13796896 : if (GET_MODE (op0) != VOIDmode)
7089 13653580 : mode = GET_MODE (op0);
7090 143316 : else if (GET_MODE (op1) != VOIDmode)
7091 111229 : mode = GET_MODE (op1);
7092 : else
7093 : return 0;
7094 : }
7095 :
7096 : /* We can't simplify MODE_CC values since we don't know what the
7097 : actual comparison is. */
7098 104289700 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
7099 : return 0;
7100 :
7101 : /* Make sure the constant is second. */
7102 104289700 : if (swap_commutative_operands_p (op0, op1))
7103 : {
7104 2995986 : std::swap (op0, op1);
7105 2995986 : code = swap_condition (code);
7106 : }
7107 :
7108 104289700 : trueop0 = avoid_constant_pool_reference (op0);
7109 104289700 : trueop1 = avoid_constant_pool_reference (op1);
7110 :
7111 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7112 : then simplify a comparison of that with zero. If A and B are both either
7113 : a register or a CONST_INT, this can't help; testing for these cases will
7114 : prevent infinite recursion here and speed things up.
7115 :
7116 : We can only do this for EQ and NE comparisons as otherwise we may
7117 : lose or introduce overflow which we cannot disregard as undefined as
7118 : we do not know the signedness of the operation on either the left or
7119 : the right hand side of the comparison. */
7120 :
7121 104289700 : if (INTEGRAL_MODE_P (mode)
7122 101659522 : && trueop1 != CONST0_RTX (mode)
7123 51729464 : && (code == EQ || code == NE)
7124 32682814 : && ! ((REG_P (op0)
7125 9570983 : || CONST_SCALAR_INT_P (trueop0)
7126 9542931 : || CONST_VECTOR_P (trueop0))
7127 23139903 : && (REG_P (op1)
7128 13832725 : || CONST_SCALAR_INT_P (trueop1)
7129 3308239 : || CONST_VECTOR_P (trueop1)))
7130 12848970 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7131 : /* We cannot do this if tem is a nonzero address. */
7132 6700093 : && ! nonzero_address_p (tem))
7133 6700091 : return simplify_const_relational_operation (signed_condition (code),
7134 6700091 : mode, tem, CONST0_RTX (mode));
7135 :
7136 97589609 : if (! HONOR_NANS (mode) && code == ORDERED)
7137 0 : return const_true_rtx;
7138 :
7139 97589609 : if (! HONOR_NANS (mode) && code == UNORDERED)
7140 8 : return const0_rtx;
7141 :
7142 : /* For modes without NaNs, if the two operands are equal, we know the
7143 : result except if they have side-effects. Even with NaNs we know
7144 : the result of unordered comparisons and, if signaling NaNs are
7145 : irrelevant, also the result of LT/GT/LTGT. */
7146 97589601 : if ((! HONOR_NANS (trueop0)
7147 2140407 : || code == UNEQ || code == UNLE || code == UNGE
7148 : || ((code == LT || code == GT || code == LTGT)
7149 885434 : && ! HONOR_SNANS (trueop0)))
7150 96439605 : && rtx_equal_p (trueop0, trueop1)
7151 98097238 : && ! side_effects_p (trueop0))
7152 507548 : return comparison_result (code, CMP_EQ);
7153 :
7154 : /* If the operands are floating-point constants, see if we can fold
7155 : the result. */
7156 97082053 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7157 1293 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7158 1293 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7159 : {
7160 1293 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7161 1293 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7162 :
7163 : /* Comparisons are unordered iff at least one of the values is NaN. */
7164 1293 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7165 174 : switch (code)
7166 : {
7167 0 : case UNEQ:
7168 0 : case UNLT:
7169 0 : case UNGT:
7170 0 : case UNLE:
7171 0 : case UNGE:
7172 0 : case NE:
7173 0 : case UNORDERED:
7174 0 : return const_true_rtx;
7175 174 : case EQ:
7176 174 : case LT:
7177 174 : case GT:
7178 174 : case LE:
7179 174 : case GE:
7180 174 : case LTGT:
7181 174 : case ORDERED:
7182 174 : return const0_rtx;
7183 : default:
7184 : return 0;
7185 : }
7186 :
7187 1204 : return comparison_result (code,
7188 1204 : (real_equal (d0, d1) ? CMP_EQ :
7189 1204 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7190 : }
7191 :
7192 : /* Otherwise, see if the operands are both integers. */
7193 97080760 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7194 94032938 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7195 : {
7196 : /* It would be nice if we really had a mode here. However, the
7197 : largest int representable on the target is as good as
7198 : infinite. */
7199 202498 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7200 202498 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7201 202498 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7202 :
7203 202498 : if (wi::eq_p (ptrueop0, ptrueop1))
7204 0 : return comparison_result (code, CMP_EQ);
7205 : else
7206 : {
7207 202498 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7208 202498 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7209 202498 : return comparison_result (code, cr);
7210 : }
7211 : }
7212 :
7213 : /* Optimize comparisons with upper and lower bounds. */
7214 96878262 : scalar_int_mode int_mode;
7215 96878262 : if (CONST_INT_P (trueop1)
7216 67603699 : && is_a <scalar_int_mode> (mode, &int_mode)
7217 67603699 : && HWI_COMPUTABLE_MODE_P (int_mode)
7218 164038006 : && !side_effects_p (trueop0))
7219 : {
7220 67009440 : int sign;
7221 67009440 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7222 67009440 : HOST_WIDE_INT val = INTVAL (trueop1);
7223 67009440 : HOST_WIDE_INT mmin, mmax;
7224 :
7225 67009440 : if (code == GEU
7226 67009440 : || code == LEU
7227 63840006 : || code == GTU
7228 63840006 : || code == LTU)
7229 : sign = 0;
7230 : else
7231 67009440 : sign = 1;
7232 :
7233 : /* Get a reduced range if the sign bit is zero. */
7234 67009440 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7235 : {
7236 6280569 : mmin = 0;
7237 6280569 : mmax = nonzero;
7238 : }
7239 : else
7240 : {
7241 60728871 : rtx mmin_rtx, mmax_rtx;
7242 60728871 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7243 :
7244 60728871 : mmin = INTVAL (mmin_rtx);
7245 60728871 : mmax = INTVAL (mmax_rtx);
7246 60728871 : if (sign)
7247 : {
7248 55008147 : unsigned int sign_copies
7249 55008147 : = num_sign_bit_copies (trueop0, int_mode);
7250 :
7251 55008147 : mmin >>= (sign_copies - 1);
7252 55008147 : mmax >>= (sign_copies - 1);
7253 : }
7254 : }
7255 :
7256 67009440 : switch (code)
7257 : {
7258 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7259 549677 : case GEU:
7260 549677 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7261 11262 : return const_true_rtx;
7262 538415 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7263 50 : return const0_rtx;
7264 : break;
7265 944527 : case GE:
7266 944527 : if (val <= mmin)
7267 2062 : return const_true_rtx;
7268 942465 : if (val > mmax)
7269 0 : return const0_rtx;
7270 : break;
7271 :
7272 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7273 2619757 : case LEU:
7274 2619757 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7275 14576 : return const_true_rtx;
7276 2605181 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7277 0 : return const0_rtx;
7278 : break;
7279 2344054 : case LE:
7280 2344054 : if (val >= mmax)
7281 460 : return const_true_rtx;
7282 2343594 : if (val < mmin)
7283 0 : return const0_rtx;
7284 : break;
7285 :
7286 24961991 : case EQ:
7287 : /* x == y is always false for y out of range. */
7288 24961991 : if (val < mmin || val > mmax)
7289 441 : return const0_rtx;
7290 : break;
7291 :
7292 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7293 2155846 : case GTU:
7294 2155846 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7295 39150 : return const0_rtx;
7296 2116696 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7297 0 : return const_true_rtx;
7298 : break;
7299 1803118 : case GT:
7300 1803118 : if (val >= mmax)
7301 332 : return const0_rtx;
7302 1802786 : if (val < mmin)
7303 5 : return const_true_rtx;
7304 : break;
7305 :
7306 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7307 782824 : case LTU:
7308 782824 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7309 2997 : return const0_rtx;
7310 779827 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7311 79942 : return const_true_rtx;
7312 : break;
7313 1116854 : case LT:
7314 1116854 : if (val <= mmin)
7315 2304 : return const0_rtx;
7316 1114550 : if (val > mmax)
7317 3099 : return const_true_rtx;
7318 : break;
7319 :
7320 29730792 : case NE:
7321 : /* x != y is always true for y out of range. */
7322 29730792 : if (val < mmin || val > mmax)
7323 120 : return const_true_rtx;
7324 : break;
7325 :
7326 : default:
7327 : break;
7328 : }
7329 : }
7330 :
7331 : /* Optimize integer comparisons with zero. */
7332 96721462 : if (is_a <scalar_int_mode> (mode, &int_mode)
7333 93716721 : && trueop1 == const0_rtx
7334 49202072 : && !side_effects_p (trueop0))
7335 : {
7336 : /* Some addresses are known to be nonzero. We don't know
7337 : their sign, but equality comparisons are known. */
7338 49049613 : if (nonzero_address_p (trueop0))
7339 : {
7340 540 : if (code == EQ || code == LEU)
7341 278 : return const0_rtx;
7342 262 : if (code == NE || code == GTU)
7343 262 : return const_true_rtx;
7344 : }
7345 :
7346 : /* See if the first operand is an IOR with a constant. If so, we
7347 : may be able to determine the result of this comparison. */
7348 49049073 : if (GET_CODE (op0) == IOR)
7349 : {
7350 627419 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7351 627419 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7352 : {
7353 288 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7354 576 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7355 288 : && (UINTVAL (inner_const)
7356 288 : & (HOST_WIDE_INT_1U
7357 : << sign_bitnum)));
7358 :
7359 288 : switch (code)
7360 : {
7361 : case EQ:
7362 : case LEU:
7363 : return const0_rtx;
7364 4 : case NE:
7365 4 : case GTU:
7366 4 : return const_true_rtx;
7367 70 : case LT:
7368 70 : case LE:
7369 70 : if (has_sign)
7370 2 : return const_true_rtx;
7371 : break;
7372 208 : case GT:
7373 208 : case GE:
7374 208 : if (has_sign)
7375 : return const0_rtx;
7376 : break;
7377 : default:
7378 : break;
7379 : }
7380 : }
7381 : }
7382 : }
7383 :
7384 : /* Optimize comparison of ABS with zero. */
7385 49535859 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7386 146103805 : && (GET_CODE (trueop0) == ABS
7387 49382504 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7388 38 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7389 : {
7390 583 : switch (code)
7391 : {
7392 60 : case LT:
7393 : /* Optimize abs(x) < 0.0. */
7394 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7395 0 : return const0_rtx;
7396 : break;
7397 :
7398 42 : case GE:
7399 : /* Optimize abs(x) >= 0.0. */
7400 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7401 0 : return const_true_rtx;
7402 : break;
7403 :
7404 0 : case UNGE:
7405 : /* Optimize ! (abs(x) < 0.0). */
7406 0 : return const_true_rtx;
7407 :
7408 : default:
7409 : break;
7410 : }
7411 : }
7412 :
7413 : return 0;
7414 : }
7415 :
7416 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7417 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7418 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7419 : can be simplified to that or NULL_RTX if not.
7420 : Assume X is compared against zero with CMP_CODE and the true
7421 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7422 :
7423 : rtx
7424 30390013 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7425 : rtx true_val, rtx false_val)
7426 : {
7427 30390013 : if (cmp_code != EQ && cmp_code != NE)
7428 : return NULL_RTX;
7429 :
7430 : /* Result on X == 0 and X !=0 respectively. */
7431 21943142 : rtx on_zero, on_nonzero;
7432 21943142 : if (cmp_code == EQ)
7433 : {
7434 : on_zero = true_val;
7435 : on_nonzero = false_val;
7436 : }
7437 : else
7438 : {
7439 11791208 : on_zero = false_val;
7440 11791208 : on_nonzero = true_val;
7441 : }
7442 :
7443 21943142 : rtx_code op_code = GET_CODE (on_nonzero);
7444 21943142 : if ((op_code != CLZ && op_code != CTZ)
7445 1972 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7446 21944173 : || !CONST_INT_P (on_zero))
7447 21942838 : return NULL_RTX;
7448 :
7449 304 : HOST_WIDE_INT op_val;
7450 304 : scalar_int_mode mode ATTRIBUTE_UNUSED
7451 304 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7452 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7453 608 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7454 328 : && op_val == INTVAL (on_zero))
7455 : return on_nonzero;
7456 :
7457 : return NULL_RTX;
7458 : }
7459 :
7460 : /* Try to simplify X given that it appears within operand OP of a
7461 : VEC_MERGE operation whose mask is MASK. X need not use the same
7462 : vector mode as the VEC_MERGE, but it must have the same number of
7463 : elements.
7464 :
7465 : Return the simplified X on success, otherwise return NULL_RTX. */
7466 :
7467 : rtx
7468 1647504 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7469 : {
7470 1647504 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7471 3295008 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7472 1647504 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7473 : {
7474 5491 : if (side_effects_p (XEXP (x, 1 - op)))
7475 : return NULL_RTX;
7476 :
7477 5267 : return XEXP (x, op);
7478 : }
7479 1642013 : if (UNARY_P (x)
7480 194093 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7481 1699721 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7482 : {
7483 24247 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7484 24247 : if (top0)
7485 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7486 448 : GET_MODE (XEXP (x, 0)));
7487 : }
7488 1641565 : if (BINARY_P (x)
7489 207136 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7490 413742 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7491 181291 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7492 1929739 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7493 : {
7494 144087 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7495 144087 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7496 144087 : if (top0 || top1)
7497 : {
7498 952 : if (COMPARISON_P (x))
7499 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7500 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7501 : ? GET_MODE (XEXP (x, 0))
7502 0 : : GET_MODE (XEXP (x, 1)),
7503 : top0 ? top0 : XEXP (x, 0),
7504 0 : top1 ? top1 : XEXP (x, 1));
7505 : else
7506 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7507 : top0 ? top0 : XEXP (x, 0),
7508 952 : top1 ? top1 : XEXP (x, 1));
7509 : }
7510 : }
7511 1640613 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7512 34869 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7513 69738 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7514 34869 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7515 69738 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7516 34869 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7517 1657097 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7518 : {
7519 8242 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7520 8242 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7521 8242 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7522 8242 : if (top0 || top1 || top2)
7523 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7524 448 : GET_MODE (XEXP (x, 0)),
7525 : top0 ? top0 : XEXP (x, 0),
7526 : top1 ? top1 : XEXP (x, 1),
7527 448 : top2 ? top2 : XEXP (x, 2));
7528 : }
7529 : return NULL_RTX;
7530 : }
7531 :
7532 :
7533 : /* Simplify CODE, an operation with result mode MODE and three operands,
7534 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7535 : a constant. Return 0 if no simplifications is possible. */
7536 :
7537 : rtx
7538 41968082 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7539 : machine_mode op0_mode,
7540 : rtx op0, rtx op1, rtx op2)
7541 : {
7542 41968082 : bool any_change = false;
7543 41968082 : rtx tem, trueop2;
7544 41968082 : scalar_int_mode int_mode, int_op0_mode;
7545 41968082 : unsigned int n_elts;
7546 :
7547 41968082 : switch (code)
7548 : {
7549 338663 : case FMA:
7550 : /* Simplify negations around the multiplication. */
7551 : /* -a * -b + c => a * b + c. */
7552 338663 : if (GET_CODE (op0) == NEG)
7553 : {
7554 82421 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7555 82421 : if (tem)
7556 271 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7557 : }
7558 256242 : else if (GET_CODE (op1) == NEG)
7559 : {
7560 1060 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7561 1060 : if (tem)
7562 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7563 : }
7564 :
7565 : /* Canonicalize the two multiplication operands. */
7566 : /* a * -b + c => -b * a + c. */
7567 338663 : if (swap_commutative_operands_p (op0, op1))
7568 : std::swap (op0, op1), any_change = true;
7569 :
7570 309879 : if (any_change)
7571 29046 : return gen_rtx_FMA (mode, op0, op1, op2);
7572 : return NULL_RTX;
7573 :
7574 651224 : case SIGN_EXTRACT:
7575 651224 : case ZERO_EXTRACT:
7576 651224 : if (CONST_INT_P (op0)
7577 17469 : && CONST_INT_P (op1)
7578 17469 : && CONST_INT_P (op2)
7579 41968114 : && is_a <scalar_int_mode> (mode, &int_mode)
7580 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7581 651256 : && HWI_COMPUTABLE_MODE_P (int_mode))
7582 : {
7583 : /* Extracting a bit-field from a constant */
7584 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7585 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7586 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7587 32 : if (!BITS_BIG_ENDIAN)
7588 32 : val >>= op2val;
7589 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7590 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7591 : else
7592 : /* Not enough information to calculate the bit position. */
7593 : break;
7594 :
7595 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7596 : {
7597 : /* First zero-extend. */
7598 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7599 : /* If desired, propagate sign bit. */
7600 29 : if (code == SIGN_EXTRACT
7601 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7602 5 : != 0)
7603 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7604 : }
7605 :
7606 32 : return gen_int_mode (val, int_mode);
7607 : }
7608 : break;
7609 :
7610 40183440 : case IF_THEN_ELSE:
7611 40183440 : if (CONST_INT_P (op0))
7612 289996 : return op0 != const0_rtx ? op1 : op2;
7613 :
7614 : /* Convert c ? a : a into "a". */
7615 39986504 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7616 : return op1;
7617 :
7618 : /* Convert a != b ? a : b into "a". */
7619 39983364 : if (GET_CODE (op0) == NE
7620 15492194 : && ! side_effects_p (op0)
7621 15450377 : && ! HONOR_NANS (mode)
7622 15444402 : && ! HONOR_SIGNED_ZEROS (mode)
7623 55427766 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7624 117227 : && rtx_equal_p (XEXP (op0, 1), op2))
7625 15444078 : || (rtx_equal_p (XEXP (op0, 0), op2)
7626 4433 : && rtx_equal_p (XEXP (op0, 1), op1))))
7627 533 : return op1;
7628 :
7629 : /* Convert a == b ? a : b into "b". */
7630 39982831 : if (GET_CODE (op0) == EQ
7631 12588268 : && ! side_effects_p (op0)
7632 12562549 : && ! HONOR_NANS (mode)
7633 12425216 : && ! HONOR_SIGNED_ZEROS (mode)
7634 52408047 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7635 14920 : && rtx_equal_p (XEXP (op0, 1), op2))
7636 12425205 : || (rtx_equal_p (XEXP (op0, 0), op2)
7637 7450 : && rtx_equal_p (XEXP (op0, 1), op1))))
7638 27 : return op2;
7639 :
7640 : /* Convert a != 0 ? -a : 0 into "-a". */
7641 39982804 : if (GET_CODE (op0) == NE
7642 15491661 : && ! side_effects_p (op0)
7643 15449844 : && ! HONOR_NANS (mode)
7644 15443869 : && ! HONOR_SIGNED_ZEROS (mode)
7645 15443869 : && XEXP (op0, 1) == CONST0_RTX (mode)
7646 11785101 : && op2 == CONST0_RTX (mode)
7647 174100 : && GET_CODE (op1) == NEG
7648 39982862 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7649 : return op1;
7650 :
7651 : /* Convert a == 0 ? 0 : -a into "-a". */
7652 39982795 : if (GET_CODE (op0) == EQ
7653 12588241 : && ! side_effects_p (op0)
7654 12562522 : && ! HONOR_NANS (mode)
7655 12425189 : && ! HONOR_SIGNED_ZEROS (mode)
7656 12425189 : && op1 == CONST0_RTX (mode)
7657 30927 : && XEXP (op0, 1) == CONST0_RTX (mode)
7658 13550 : && GET_CODE (op2) == NEG
7659 39982801 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7660 : return op2;
7661 :
7662 : /* Convert (!c) != {0,...,0} ? a : b into
7663 : c != {0,...,0} ? b : a for vector modes. */
7664 39982789 : if (VECTOR_MODE_P (GET_MODE (op1))
7665 14811 : && GET_CODE (op0) == NE
7666 468 : && GET_CODE (XEXP (op0, 0)) == NOT
7667 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7668 : {
7669 0 : rtx cv = XEXP (op0, 1);
7670 0 : int nunits;
7671 0 : bool ok = true;
7672 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7673 : ok = false;
7674 : else
7675 0 : for (int i = 0; i < nunits; ++i)
7676 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7677 : {
7678 : ok = false;
7679 : break;
7680 : }
7681 0 : if (ok)
7682 : {
7683 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7684 : XEXP (XEXP (op0, 0), 0),
7685 : XEXP (op0, 1));
7686 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7687 0 : return retval;
7688 : }
7689 : }
7690 :
7691 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7692 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7693 : Similarly for ctz (x). */
7694 39981791 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7695 79864140 : && XEXP (op0, 1) == const0_rtx)
7696 : {
7697 30390013 : rtx simplified
7698 30390013 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7699 : op1, op2);
7700 30390013 : if (simplified)
7701 : return simplified;
7702 : }
7703 :
7704 39982789 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7705 : {
7706 79853400 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7707 39881351 : ? GET_MODE (XEXP (op0, 1))
7708 : : GET_MODE (XEXP (op0, 0)));
7709 39881351 : rtx temp;
7710 :
7711 : /* Look for happy constants in op1 and op2. */
7712 39881351 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7713 : {
7714 211401 : HOST_WIDE_INT t = INTVAL (op1);
7715 211401 : HOST_WIDE_INT f = INTVAL (op2);
7716 :
7717 211401 : if (t == STORE_FLAG_VALUE && f == 0)
7718 52630 : code = GET_CODE (op0);
7719 158771 : else if (t == 0 && f == STORE_FLAG_VALUE)
7720 : {
7721 31398 : enum rtx_code tmp;
7722 31398 : tmp = reversed_comparison_code (op0, NULL);
7723 31398 : if (tmp == UNKNOWN)
7724 : break;
7725 : code = tmp;
7726 : }
7727 : else
7728 : break;
7729 :
7730 78639 : return simplify_gen_relational (code, mode, cmp_mode,
7731 78639 : XEXP (op0, 0), XEXP (op0, 1));
7732 : }
7733 :
7734 39669950 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7735 : cmp_mode, XEXP (op0, 0),
7736 : XEXP (op0, 1));
7737 :
7738 : /* See if any simplifications were possible. */
7739 39669950 : if (temp)
7740 : {
7741 6975 : if (CONST_INT_P (temp))
7742 872 : return temp == const0_rtx ? op2 : op1;
7743 6148 : else if (temp)
7744 6148 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7745 : }
7746 : }
7747 : break;
7748 :
7749 794755 : case VEC_MERGE:
7750 794755 : gcc_assert (GET_MODE (op0) == mode);
7751 794755 : gcc_assert (GET_MODE (op1) == mode);
7752 794755 : gcc_assert (VECTOR_MODE_P (mode));
7753 794755 : trueop2 = avoid_constant_pool_reference (op2);
7754 794755 : if (CONST_INT_P (trueop2)
7755 1268587 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7756 : {
7757 473832 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7758 473832 : unsigned HOST_WIDE_INT mask;
7759 473832 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7760 : mask = -1;
7761 : else
7762 471375 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7763 :
7764 473832 : if (!(sel & mask) && !side_effects_p (op0))
7765 : return op1;
7766 473395 : if ((sel & mask) == mask && !side_effects_p (op1))
7767 : return op0;
7768 :
7769 462644 : rtx trueop0 = avoid_constant_pool_reference (op0);
7770 462644 : rtx trueop1 = avoid_constant_pool_reference (op1);
7771 462644 : if (GET_CODE (trueop0) == CONST_VECTOR
7772 10028 : && GET_CODE (trueop1) == CONST_VECTOR)
7773 : {
7774 5572 : rtvec v = rtvec_alloc (n_elts);
7775 5572 : unsigned int i;
7776 :
7777 58894 : for (i = 0; i < n_elts; i++)
7778 47750 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7779 47750 : ? CONST_VECTOR_ELT (trueop0, i)
7780 27384 : : CONST_VECTOR_ELT (trueop1, i));
7781 5572 : return gen_rtx_CONST_VECTOR (mode, v);
7782 : }
7783 :
7784 457072 : if (swap_commutative_operands_p (op0, op1)
7785 : /* Two operands have same precedence, then first bit of mask
7786 : select first operand. */
7787 457072 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7788 31384 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7789 62768 : GEN_INT (~sel & mask));
7790 :
7791 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7792 : if no element from a appears in the result. */
7793 425688 : if (GET_CODE (op0) == VEC_MERGE)
7794 : {
7795 17218 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7796 17218 : if (CONST_INT_P (tem))
7797 : {
7798 1475 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7799 1475 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7800 104 : return simplify_gen_ternary (code, mode, mode,
7801 104 : XEXP (op0, 1), op1, op2);
7802 1371 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7803 834 : return simplify_gen_ternary (code, mode, mode,
7804 834 : XEXP (op0, 0), op1, op2);
7805 : }
7806 : }
7807 424750 : if (GET_CODE (op1) == VEC_MERGE)
7808 : {
7809 588 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7810 588 : if (CONST_INT_P (tem))
7811 : {
7812 557 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7813 557 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7814 526 : return simplify_gen_ternary (code, mode, mode,
7815 526 : op0, XEXP (op1, 1), op2);
7816 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7817 4 : return simplify_gen_ternary (code, mode, mode,
7818 4 : op0, XEXP (op1, 0), op2);
7819 : }
7820 : }
7821 :
7822 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7823 : with a. */
7824 424220 : if (GET_CODE (op0) == VEC_DUPLICATE
7825 142927 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7826 640 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7827 425500 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7828 : {
7829 572 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7830 572 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7831 : {
7832 572 : if (XEXP (XEXP (op0, 0), 0) == op1
7833 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7834 : return op1;
7835 : }
7836 : }
7837 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7838 : (const_int N))
7839 : with (vec_concat (X) (B)) if N == 1 or
7840 : (vec_concat (A) (X)) if N == 2. */
7841 424218 : if (GET_CODE (op0) == VEC_DUPLICATE
7842 142925 : && GET_CODE (op1) == CONST_VECTOR
7843 151500 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7844 2366 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7845 425401 : && IN_RANGE (sel, 1, 2))
7846 : {
7847 1181 : rtx newop0 = XEXP (op0, 0);
7848 1181 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
7849 1181 : if (sel == 2)
7850 123 : std::swap (newop0, newop1);
7851 1181 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7852 : }
7853 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7854 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7855 : Only applies for vectors of two elements. */
7856 423037 : if (GET_CODE (op0) == VEC_DUPLICATE
7857 141744 : && GET_CODE (op1) == VEC_CONCAT
7858 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7859 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7860 423037 : && IN_RANGE (sel, 1, 2))
7861 : {
7862 0 : rtx newop0 = XEXP (op0, 0);
7863 0 : rtx newop1 = XEXP (op1, 2 - sel);
7864 0 : rtx otherop = XEXP (op1, sel - 1);
7865 0 : if (sel == 2)
7866 0 : std::swap (newop0, newop1);
7867 : /* Don't want to throw away the other part of the vec_concat if
7868 : it has side-effects. */
7869 0 : if (!side_effects_p (otherop))
7870 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7871 : }
7872 :
7873 : /* Replace:
7874 :
7875 : (vec_merge:outer (vec_duplicate:outer x:inner)
7876 : (subreg:outer y:inner 0)
7877 : (const_int N))
7878 :
7879 : with (vec_concat:outer x:inner y:inner) if N == 1,
7880 : or (vec_concat:outer y:inner x:inner) if N == 2.
7881 :
7882 : Implicitly, this means we have a paradoxical subreg, but such
7883 : a check is cheap, so make it anyway.
7884 :
7885 : Only applies for vectors of two elements. */
7886 423037 : if (GET_CODE (op0) == VEC_DUPLICATE
7887 141744 : && GET_CODE (op1) == SUBREG
7888 44336 : && GET_MODE (op1) == GET_MODE (op0)
7889 44336 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
7890 0 : && paradoxical_subreg_p (op1)
7891 0 : && subreg_lowpart_p (op1)
7892 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7893 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7894 423037 : && IN_RANGE (sel, 1, 2))
7895 : {
7896 0 : rtx newop0 = XEXP (op0, 0);
7897 0 : rtx newop1 = SUBREG_REG (op1);
7898 0 : if (sel == 2)
7899 0 : std::swap (newop0, newop1);
7900 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7901 : }
7902 :
7903 : /* Same as above but with switched operands:
7904 : Replace (vec_merge:outer (subreg:outer x:inner 0)
7905 : (vec_duplicate:outer y:inner)
7906 : (const_int N))
7907 :
7908 : with (vec_concat:outer x:inner y:inner) if N == 1,
7909 : or (vec_concat:outer y:inner x:inner) if N == 2. */
7910 423037 : if (GET_CODE (op1) == VEC_DUPLICATE
7911 29716 : && GET_CODE (op0) == SUBREG
7912 26567 : && GET_MODE (op0) == GET_MODE (op1)
7913 26567 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
7914 0 : && paradoxical_subreg_p (op0)
7915 0 : && subreg_lowpart_p (op0)
7916 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7917 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7918 423037 : && IN_RANGE (sel, 1, 2))
7919 : {
7920 0 : rtx newop0 = SUBREG_REG (op0);
7921 0 : rtx newop1 = XEXP (op1, 0);
7922 0 : if (sel == 2)
7923 0 : std::swap (newop0, newop1);
7924 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7925 : }
7926 :
7927 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7928 : (const_int n))
7929 : with (vec_concat x y) or (vec_concat y x) depending on value
7930 : of N. */
7931 423037 : if (GET_CODE (op0) == VEC_DUPLICATE
7932 141744 : && GET_CODE (op1) == VEC_DUPLICATE
7933 198 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7934 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7935 423037 : && IN_RANGE (sel, 1, 2))
7936 : {
7937 0 : rtx newop0 = XEXP (op0, 0);
7938 0 : rtx newop1 = XEXP (op1, 0);
7939 0 : if (sel == 2)
7940 0 : std::swap (newop0, newop1);
7941 :
7942 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7943 : }
7944 : }
7945 :
7946 743960 : if (rtx_equal_p (op0, op1)
7947 743960 : && !side_effects_p (op2) && !side_effects_p (op1))
7948 : return op0;
7949 :
7950 743667 : if (!side_effects_p (op2))
7951 : {
7952 739989 : rtx top0
7953 739989 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
7954 739989 : rtx top1
7955 739989 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
7956 739989 : if (top0 || top1)
7957 998 : return simplify_gen_ternary (code, mode, mode,
7958 : top0 ? top0 : op0,
7959 819 : top1 ? top1 : op1, op2);
7960 : }
7961 :
7962 : break;
7963 :
7964 0 : default:
7965 0 : gcc_unreachable ();
7966 : }
7967 :
7968 : return 0;
7969 : }
7970 :
7971 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
7972 : starting at byte FIRST_BYTE. Return true on success and add the
7973 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
7974 : that the bytes follow target memory order. Leave BYTES unmodified
7975 : on failure.
7976 :
7977 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
7978 : BYTES before calling this function. */
7979 :
7980 : bool
7981 13511635 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
7982 : unsigned int first_byte, unsigned int num_bytes)
7983 : {
7984 : /* Check the mode is sensible. */
7985 13511635 : gcc_assert (GET_MODE (x) == VOIDmode
7986 : ? is_a <scalar_int_mode> (mode)
7987 : : mode == GET_MODE (x));
7988 :
7989 13511635 : if (GET_CODE (x) == CONST_VECTOR)
7990 : {
7991 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7992 : is necessary. The only complication is that MODE_VECTOR_BOOL
7993 : vectors can have several elements per byte. */
7994 1051852 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7995 : GET_MODE_NUNITS (mode));
7996 525926 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
7997 525926 : if (elt_bits < BITS_PER_UNIT)
7998 : {
7999 : /* This is the only case in which elements can be smaller than
8000 : a byte. */
8001 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8002 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
8003 0 : for (unsigned int i = 0; i < num_bytes; ++i)
8004 : {
8005 0 : target_unit value = 0;
8006 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
8007 : {
8008 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
8009 0 : value |= mask << j;
8010 0 : elt += 1;
8011 : }
8012 0 : bytes.quick_push (value);
8013 : }
8014 : return true;
8015 : }
8016 :
8017 525926 : unsigned int start = bytes.length ();
8018 525926 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
8019 : /* Make FIRST_BYTE relative to ELT. */
8020 525926 : first_byte %= elt_bytes;
8021 2681423 : while (num_bytes > 0)
8022 : {
8023 : /* Work out how many bytes we want from element ELT. */
8024 2155497 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
8025 4310994 : if (!native_encode_rtx (GET_MODE_INNER (mode),
8026 : CONST_VECTOR_ELT (x, elt), bytes,
8027 : first_byte, chunk_bytes))
8028 : {
8029 0 : bytes.truncate (start);
8030 0 : return false;
8031 : }
8032 2155497 : elt += 1;
8033 2155497 : first_byte = 0;
8034 2155497 : num_bytes -= chunk_bytes;
8035 : }
8036 : return true;
8037 : }
8038 :
8039 : /* All subsequent cases are limited to scalars. */
8040 12985709 : scalar_mode smode;
8041 13016627 : if (!is_a <scalar_mode> (mode, &smode))
8042 : return false;
8043 :
8044 : /* Make sure that the region is in range. */
8045 12985709 : unsigned int end_byte = first_byte + num_bytes;
8046 12985709 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8047 12985709 : gcc_assert (end_byte <= mode_bytes);
8048 :
8049 12985709 : if (CONST_SCALAR_INT_P (x))
8050 : {
8051 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
8052 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
8053 : position of each byte. */
8054 12310015 : rtx_mode_t value (x, smode);
8055 12310015 : wide_int_ref value_wi (value);
8056 52728259 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8057 : {
8058 : /* Always constant because the inputs are. */
8059 40418244 : unsigned int lsb
8060 40418244 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8061 : /* Operate directly on the encoding rather than using
8062 : wi::extract_uhwi, so that we preserve the sign or zero
8063 : extension for modes that are not a whole number of bits in
8064 : size. (Zero extension is only used for the combination of
8065 : innermode == BImode && STORE_FLAG_VALUE == 1). */
8066 40418244 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
8067 40418244 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
8068 40418244 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
8069 40418244 : bytes.quick_push (uhwi >> shift);
8070 : }
8071 12310015 : return true;
8072 : }
8073 :
8074 675694 : if (CONST_DOUBLE_P (x))
8075 : {
8076 : /* real_to_target produces an array of integers in target memory order.
8077 : All integers before the last one have 32 bits; the last one may
8078 : have 32 bits or fewer, depending on whether the mode bitsize
8079 : is divisible by 32. Each of these integers is then laid out
8080 : in target memory as any other integer would be. */
8081 644776 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8082 644776 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
8083 :
8084 : /* The (maximum) number of target bytes per element of el32. */
8085 644776 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8086 644776 : gcc_assert (bytes_per_el32 != 0);
8087 :
8088 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
8089 : handling above. */
8090 4406058 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8091 : {
8092 3761282 : unsigned int index = byte / bytes_per_el32;
8093 3761282 : unsigned int subbyte = byte % bytes_per_el32;
8094 3761282 : unsigned int int_bytes = MIN (bytes_per_el32,
8095 : mode_bytes - index * bytes_per_el32);
8096 : /* Always constant because the inputs are. */
8097 3761282 : unsigned int lsb
8098 3761282 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8099 3761282 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
8100 : }
8101 644776 : return true;
8102 : }
8103 :
8104 30918 : if (GET_CODE (x) == CONST_FIXED)
8105 : {
8106 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8107 : {
8108 : /* Always constant because the inputs are. */
8109 0 : unsigned int lsb
8110 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8111 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8112 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8113 : {
8114 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8115 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8116 : }
8117 0 : bytes.quick_push (piece >> lsb);
8118 : }
8119 : return true;
8120 : }
8121 :
8122 : return false;
8123 : }
8124 :
8125 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8126 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8127 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8128 : and BYTES is known to have enough bytes to supply NPATTERNS *
8129 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8130 : BITS_PER_UNIT bits and the bytes are in target memory order.
8131 :
8132 : Return the vector on success, otherwise return NULL_RTX. */
8133 :
8134 : rtx
8135 265625 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8136 : unsigned int first_byte, unsigned int npatterns,
8137 : unsigned int nelts_per_pattern)
8138 : {
8139 265625 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8140 :
8141 531250 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8142 : GET_MODE_NUNITS (mode));
8143 265625 : if (elt_bits < BITS_PER_UNIT)
8144 : {
8145 : /* This is the only case in which elements can be smaller than a byte.
8146 : Element 0 is always in the lsb of the containing byte. */
8147 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8148 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8149 : {
8150 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8151 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8152 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8153 0 : unsigned int value = bytes[byte_index] >> lsb;
8154 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8155 : }
8156 : }
8157 : else
8158 : {
8159 1053458 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8160 : {
8161 1575666 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8162 787833 : if (!x)
8163 0 : return NULL_RTX;
8164 787833 : builder.quick_push (x);
8165 787833 : first_byte += elt_bits / BITS_PER_UNIT;
8166 : }
8167 : }
8168 265625 : return builder.build ();
8169 265625 : }
8170 :
8171 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8172 : of target memory image BYTES. */
8173 :
8174 : wide_int
8175 11381619 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8176 : unsigned int size, unsigned int precision)
8177 : {
8178 : /* Pull the bytes msb first, so that we can use simple
8179 : shift-and-insert wide_int operations. */
8180 11381619 : wide_int result (wi::zero (precision));
8181 52803392 : for (unsigned int i = 0; i < size; ++i)
8182 : {
8183 41421773 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8184 : /* Always constant because the inputs are. */
8185 41421773 : unsigned int subbyte
8186 41421773 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8187 41421773 : result <<= BITS_PER_UNIT;
8188 41421773 : result |= bytes[first_byte + subbyte];
8189 : }
8190 11381619 : return result;
8191 : }
8192 :
8193 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8194 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8195 : bits and the bytes are in target memory order. The image has enough
8196 : values to specify all bytes of MODE.
8197 :
8198 : Return the rtx on success, otherwise return NULL_RTX. */
8199 :
8200 : rtx
8201 11714490 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8202 : unsigned int first_byte)
8203 : {
8204 11714490 : if (VECTOR_MODE_P (mode))
8205 : {
8206 : /* If we know at compile time how many elements there are,
8207 : pull each element directly from BYTES. */
8208 90061 : unsigned int nelts;
8209 180122 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8210 90061 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8211 : return NULL_RTX;
8212 : }
8213 :
8214 11624429 : scalar_int_mode imode;
8215 11624429 : if (is_a <scalar_int_mode> (mode, &imode)
8216 11381619 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8217 : {
8218 11381619 : auto result = native_decode_int (bytes, first_byte,
8219 11381619 : GET_MODE_SIZE (imode),
8220 22763238 : GET_MODE_PRECISION (imode));
8221 11381619 : return immed_wide_int_const (result, imode);
8222 11381619 : }
8223 :
8224 242810 : scalar_float_mode fmode;
8225 242810 : if (is_a <scalar_float_mode> (mode, &fmode))
8226 : {
8227 : /* We need to build an array of integers in target memory order.
8228 : All integers before the last one have 32 bits; the last one may
8229 : have 32 bits or fewer, depending on whether the mode bitsize
8230 : is divisible by 32. */
8231 242780 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8232 242780 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8233 242780 : memset (el32, 0, num_el32 * sizeof (long));
8234 :
8235 : /* The (maximum) number of target bytes per element of el32. */
8236 242780 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8237 242780 : gcc_assert (bytes_per_el32 != 0);
8238 :
8239 242780 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8240 1683588 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8241 : {
8242 1440808 : unsigned int index = byte / bytes_per_el32;
8243 1440808 : unsigned int subbyte = byte % bytes_per_el32;
8244 1440808 : unsigned int int_bytes = MIN (bytes_per_el32,
8245 : mode_bytes - index * bytes_per_el32);
8246 : /* Always constant because the inputs are. */
8247 1440808 : unsigned int lsb
8248 1440808 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8249 1440808 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8250 : }
8251 242780 : REAL_VALUE_TYPE r;
8252 242780 : real_from_target (&r, el32, fmode);
8253 242780 : return const_double_from_real_value (r, fmode);
8254 : }
8255 :
8256 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8257 : {
8258 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8259 0 : FIXED_VALUE_TYPE f;
8260 0 : f.data.low = 0;
8261 0 : f.data.high = 0;
8262 0 : f.mode = smode;
8263 :
8264 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8265 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8266 : {
8267 : /* Always constant because the inputs are. */
8268 0 : unsigned int lsb
8269 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8270 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8271 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8272 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8273 : else
8274 0 : f.data.low |= unit << lsb;
8275 : }
8276 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8277 : }
8278 :
8279 : return NULL_RTX;
8280 : }
8281 :
8282 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8283 : is to convert a runtime BYTE value into a constant one. */
8284 :
8285 : static poly_uint64
8286 318506 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8287 : {
8288 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8289 318506 : machine_mode mode = GET_MODE (x);
8290 637012 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8291 : GET_MODE_NUNITS (mode));
8292 : /* The number of bits needed to encode one element from each pattern. */
8293 318506 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8294 :
8295 : /* Identify the start point in terms of a sequence number and a byte offset
8296 : within that sequence. */
8297 318506 : poly_uint64 first_sequence;
8298 318506 : unsigned HOST_WIDE_INT subbit;
8299 318506 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8300 : &first_sequence, &subbit))
8301 : {
8302 318506 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8303 318506 : if (nelts_per_pattern == 1)
8304 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8305 : doesn't matter. */
8306 239786 : byte = subbit / BITS_PER_UNIT;
8307 78720 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8308 : {
8309 : /* The subreg drops the first element from each pattern and
8310 : only uses the second element. Find the first sequence
8311 : that starts on a byte boundary. */
8312 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8313 5568 : byte = subbit / BITS_PER_UNIT;
8314 : }
8315 : }
8316 318506 : return byte;
8317 : }
8318 :
8319 : /* Subroutine of simplify_subreg in which:
8320 :
8321 : - X is known to be a CONST_VECTOR
8322 : - OUTERMODE is known to be a vector mode
8323 :
8324 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8325 : rather than on each individual element of the CONST_VECTOR.
8326 :
8327 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8328 :
8329 : static rtx
8330 183491 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8331 : machine_mode innermode, unsigned int first_byte)
8332 : {
8333 : /* Paradoxical subregs of vectors have dubious semantics. */
8334 183491 : if (paradoxical_subreg_p (outermode, innermode))
8335 : return NULL_RTX;
8336 :
8337 : /* We can only preserve the semantics of a stepped pattern if the new
8338 : vector element is the same as the original one. */
8339 183345 : if (CONST_VECTOR_STEPPED_P (x)
8340 204131 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8341 : return NULL_RTX;
8342 :
8343 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8344 175564 : unsigned int x_elt_bits
8345 175564 : = vector_element_size (GET_MODE_PRECISION (innermode),
8346 : GET_MODE_NUNITS (innermode));
8347 175564 : unsigned int out_elt_bits
8348 175564 : = vector_element_size (GET_MODE_PRECISION (outermode),
8349 : GET_MODE_NUNITS (outermode));
8350 :
8351 : /* The number of bits needed to encode one element from every pattern
8352 : of the original vector. */
8353 175564 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8354 :
8355 : /* The number of bits needed to encode one element from every pattern
8356 : of the result. */
8357 175564 : unsigned int out_sequence_bits
8358 175564 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8359 :
8360 : /* Work out the number of interleaved patterns in the output vector
8361 : and the number of encoded elements per pattern. */
8362 175564 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8363 175564 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8364 :
8365 : /* The encoding scheme requires the number of elements to be a multiple
8366 : of the number of patterns, so that each pattern appears at least once
8367 : and so that the same number of elements appear from each pattern. */
8368 351128 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8369 175564 : unsigned int const_nunits;
8370 351128 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8371 175564 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8372 : {
8373 : /* Either the encoding is invalid, or applying it would give us
8374 : more elements than we need. Just encode each element directly. */
8375 : out_npatterns = const_nunits;
8376 : nelts_per_pattern = 1;
8377 : }
8378 : else if (!ok_p)
8379 : return NULL_RTX;
8380 :
8381 : /* Get enough bytes of X to form the new encoding. */
8382 175564 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8383 175564 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8384 175564 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8385 175564 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8386 : return NULL_RTX;
8387 :
8388 : /* Re-encode the bytes as OUTERMODE. */
8389 175564 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8390 175564 : nelts_per_pattern);
8391 175564 : }
8392 :
8393 : /* Try to simplify a subreg of a constant by encoding the subreg region
8394 : as a sequence of target bytes and reading them back in the new mode.
8395 : Return the new value on success, otherwise return null.
8396 :
8397 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8398 : and byte offset FIRST_BYTE. */
8399 :
8400 : static rtx
8401 10654656 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8402 : machine_mode innermode, unsigned int first_byte)
8403 : {
8404 10654656 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8405 10654656 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8406 :
8407 : /* Some ports misuse CCmode. */
8408 10654656 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8409 : return x;
8410 :
8411 : /* Paradoxical subregs read undefined values for bytes outside of the
8412 : inner value. However, we have traditionally always sign-extended
8413 : integer constants and zero-extended others. */
8414 10652640 : unsigned int inner_bytes = buffer_bytes;
8415 10652640 : if (paradoxical_subreg_p (outermode, innermode))
8416 : {
8417 962740 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8418 0 : return NULL_RTX;
8419 :
8420 481370 : target_unit filler = 0;
8421 481370 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8422 43813 : filler = -1;
8423 :
8424 : /* Add any leading bytes due to big-endian layout. The number of
8425 : bytes must be constant because both modes have constant size. */
8426 481370 : unsigned int leading_bytes
8427 481370 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8428 481370 : for (unsigned int i = 0; i < leading_bytes; ++i)
8429 0 : buffer.quick_push (filler);
8430 :
8431 481370 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8432 0 : return NULL_RTX;
8433 :
8434 : /* Add any trailing bytes due to little-endian layout. */
8435 6306272 : while (buffer.length () < buffer_bytes)
8436 2671766 : buffer.quick_push (filler);
8437 : }
8438 10171270 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8439 : return NULL_RTX;
8440 10652640 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8441 10652640 : if (ret && FLOAT_MODE_P (outermode))
8442 : {
8443 127478 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8444 127478 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8445 : return NULL_RTX;
8446 1406797 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8447 1279354 : if (buffer[i] != buffer2[i])
8448 : return NULL_RTX;
8449 127478 : }
8450 : return ret;
8451 10654656 : }
8452 :
8453 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8454 : Return 0 if no simplifications are possible. */
8455 : rtx
8456 70189178 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8457 : machine_mode innermode, poly_uint64 byte)
8458 : {
8459 : /* Little bit of sanity checking. */
8460 70189178 : gcc_assert (innermode != VOIDmode);
8461 70189178 : gcc_assert (outermode != VOIDmode);
8462 70189178 : gcc_assert (innermode != BLKmode);
8463 70189178 : gcc_assert (outermode != BLKmode);
8464 :
8465 70189178 : gcc_assert (GET_MODE (op) == innermode
8466 : || GET_MODE (op) == VOIDmode);
8467 :
8468 140378356 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8469 70189178 : if (!multiple_p (byte, outersize))
8470 : return NULL_RTX;
8471 :
8472 140378316 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8473 70189158 : if (maybe_ge (byte, innersize))
8474 : return NULL_RTX;
8475 :
8476 70189158 : if (outermode == innermode && known_eq (byte, 0U))
8477 4543222 : return op;
8478 :
8479 65645936 : if (GET_CODE (op) == CONST_VECTOR)
8480 318506 : byte = simplify_const_vector_byte_offset (op, byte);
8481 :
8482 131291872 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8483 : {
8484 59899734 : rtx elt;
8485 :
8486 51216684 : if (VECTOR_MODE_P (outermode)
8487 26049150 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8488 61618400 : && vec_duplicate_p (op, &elt))
8489 12118 : return gen_vec_duplicate (outermode, elt);
8490 :
8491 59895979 : if (outermode == GET_MODE_INNER (innermode)
8492 59895979 : && vec_duplicate_p (op, &elt))
8493 8363 : return elt;
8494 : }
8495 :
8496 65633818 : if (CONST_SCALAR_INT_P (op)
8497 55172376 : || CONST_DOUBLE_AS_FLOAT_P (op)
8498 55115276 : || CONST_FIXED_P (op)
8499 55115276 : || GET_CODE (op) == CONST_VECTOR)
8500 : {
8501 10830220 : unsigned HOST_WIDE_INT cbyte;
8502 10830220 : if (byte.is_constant (&cbyte))
8503 : {
8504 10830220 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8505 : {
8506 183491 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8507 : innermode, cbyte);
8508 183491 : if (tmp)
8509 10830220 : return tmp;
8510 : }
8511 :
8512 10654656 : fixed_size_mode fs_outermode;
8513 10654656 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8514 10654656 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8515 : }
8516 : }
8517 :
8518 : /* Changing mode twice with SUBREG => just change it once,
8519 : or not at all if changing back op starting mode. */
8520 54803598 : if (GET_CODE (op) == SUBREG)
8521 : {
8522 1319109 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8523 2638218 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8524 1319109 : rtx newx;
8525 :
8526 : /* Make sure that the relationship between the two subregs is
8527 : known at compile time. */
8528 1319109 : if (!ordered_p (outersize, innermostsize))
8529 : return NULL_RTX;
8530 :
8531 1319109 : if (outermode == innermostmode
8532 753612 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8533 2072714 : && known_eq (SUBREG_BYTE (op),
8534 : subreg_lowpart_offset (innermode, innermostmode)))
8535 753605 : return SUBREG_REG (op);
8536 :
8537 : /* Work out the memory offset of the final OUTERMODE value relative
8538 : to the inner value of OP. */
8539 565504 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8540 : innermode, byte);
8541 565504 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8542 565504 : poly_int64 final_offset = mem_offset + op_mem_offset;
8543 :
8544 : /* See whether resulting subreg will be paradoxical. */
8545 565504 : if (!paradoxical_subreg_p (outermode, innermostmode))
8546 : {
8547 : /* Bail out in case resulting subreg would be incorrect. */
8548 921154 : if (maybe_lt (final_offset, 0)
8549 921139 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8550 921147 : || !multiple_p (final_offset, outersize))
8551 15 : return NULL_RTX;
8552 : }
8553 : else
8554 : {
8555 104927 : poly_int64 required_offset = subreg_memory_offset (outermode,
8556 : innermostmode, 0);
8557 104927 : if (maybe_ne (final_offset, required_offset))
8558 0 : return NULL_RTX;
8559 : /* Paradoxical subregs always have byte offset 0. */
8560 104927 : final_offset = 0;
8561 : }
8562 :
8563 : /* Recurse for further possible simplifications. */
8564 565489 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8565 565489 : final_offset);
8566 565489 : if (newx)
8567 : return newx;
8568 565111 : if (validate_subreg (outermode, innermostmode,
8569 565111 : SUBREG_REG (op), final_offset))
8570 : {
8571 506212 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8572 506212 : if (SUBREG_PROMOTED_VAR_P (op)
8573 610 : && SUBREG_PROMOTED_SIGN (op) >= 0
8574 610 : && GET_MODE_CLASS (outermode) == MODE_INT
8575 606 : && known_ge (outersize, innersize)
8576 392 : && known_le (outersize, innermostsize)
8577 506222 : && subreg_lowpart_p (newx))
8578 : {
8579 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8580 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8581 : }
8582 506212 : return newx;
8583 : }
8584 : return NULL_RTX;
8585 : }
8586 :
8587 : /* SUBREG of a hard register => just change the register number
8588 : and/or mode. If the hard register is not valid in that mode,
8589 : suppress this simplification. If the hard register is the stack,
8590 : frame, or argument pointer, leave this as a SUBREG. */
8591 :
8592 53484489 : if (REG_P (op) && HARD_REGISTER_P (op))
8593 : {
8594 10639637 : unsigned int regno, final_regno;
8595 :
8596 10639637 : regno = REGNO (op);
8597 10639637 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8598 10639637 : if (HARD_REGISTER_NUM_P (final_regno))
8599 : {
8600 10614498 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8601 : subreg_memory_offset (outermode,
8602 : innermode, byte));
8603 :
8604 : /* Propagate original regno. We don't have any way to specify
8605 : the offset inside original regno, so do so only for lowpart.
8606 : The information is used only by alias analysis that cannot
8607 : grog partial register anyway. */
8608 :
8609 10614498 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8610 7946358 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8611 10614498 : return x;
8612 : }
8613 : }
8614 :
8615 : /* If we have a SUBREG of a register that we are replacing and we are
8616 : replacing it with a MEM, make a new MEM and try replacing the
8617 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8618 : or if we would be widening it. */
8619 :
8620 42869991 : if (MEM_P (op)
8621 1695774 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8622 : /* Allow splitting of volatile memory references in case we don't
8623 : have instruction to move the whole thing. */
8624 1695771 : && (! MEM_VOLATILE_P (op)
8625 44331 : || ! have_insn_for (SET, innermode))
8626 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8627 44521431 : && known_le (outersize, innersize))
8628 808568 : return adjust_address_nv (op, outermode, byte);
8629 :
8630 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8631 : of two parts. */
8632 42061423 : if (GET_CODE (op) == CONCAT
8633 42061423 : || GET_CODE (op) == VEC_CONCAT)
8634 : {
8635 203591 : poly_uint64 final_offset;
8636 203591 : rtx part, res;
8637 :
8638 203591 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8639 203591 : if (part_mode == VOIDmode)
8640 11 : part_mode = GET_MODE_INNER (GET_MODE (op));
8641 407182 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8642 203591 : if (known_lt (byte, part_size))
8643 : {
8644 202047 : part = XEXP (op, 0);
8645 202047 : final_offset = byte;
8646 : }
8647 1544 : else if (known_ge (byte, part_size))
8648 : {
8649 1544 : part = XEXP (op, 1);
8650 1544 : final_offset = byte - part_size;
8651 : }
8652 : else
8653 : return NULL_RTX;
8654 :
8655 203591 : if (maybe_gt (final_offset + outersize, part_size))
8656 : return NULL_RTX;
8657 :
8658 128689 : part_mode = GET_MODE (part);
8659 128689 : if (part_mode == VOIDmode)
8660 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8661 128689 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8662 128689 : if (res)
8663 : return res;
8664 295 : if (GET_MODE (part) != VOIDmode
8665 295 : && validate_subreg (outermode, part_mode, part, final_offset))
8666 295 : return gen_rtx_SUBREG (outermode, part, final_offset);
8667 0 : return NULL_RTX;
8668 : }
8669 :
8670 : /* Simplify
8671 : (subreg (vec_merge (X)
8672 : (vector)
8673 : (const_int ((1 << N) | M)))
8674 : (N * sizeof (outermode)))
8675 : to
8676 : (subreg (X) (N * sizeof (outermode)))
8677 : */
8678 41857832 : unsigned int idx;
8679 83715664 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8680 41857832 : && idx < HOST_BITS_PER_WIDE_INT
8681 41857832 : && GET_CODE (op) == VEC_MERGE
8682 633146 : && GET_MODE_INNER (innermode) == outermode
8683 4873 : && CONST_INT_P (XEXP (op, 2))
8684 41862123 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8685 4282 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8686 :
8687 : /* A SUBREG resulting from a zero extension may fold to zero if
8688 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8689 41853550 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8690 : {
8691 221138 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8692 221138 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8693 55095 : return CONST0_RTX (outermode);
8694 : }
8695 :
8696 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8697 41798455 : if (GET_CODE (op) == ASHIFT
8698 900718 : && SCALAR_INT_MODE_P (innermode)
8699 873246 : && CONST_INT_P (XEXP (op, 1))
8700 794021 : && INTVAL (XEXP (op, 1)) > 0
8701 43493144 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8702 : {
8703 793971 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8704 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8705 793971 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8706 1551322 : && known_le (GET_MODE_BITSIZE (outermode), val))
8707 191224 : return CONST0_RTX (outermode);
8708 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8709 636822 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8710 34842 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8711 69370 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8712 68150 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8713 671664 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8714 34075 : return XEXP (XEXP (op, 0), 0);
8715 : }
8716 :
8717 43139158 : auto distribute_subreg = [&](rtx op)
8718 : {
8719 1531927 : return simplify_subreg (outermode, op, innermode, byte);
8720 41607231 : };
8721 :
8722 : /* Try distributing the subreg through logic operations, if that
8723 : leads to all subexpressions being simplified. For example,
8724 : distributing the outer subreg in:
8725 :
8726 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8727 :
8728 : gives:
8729 :
8730 : (not:SI (reg:SI X))
8731 :
8732 : This should be a win if the outermode is word_mode, since logical
8733 : operations on word_mode should (a) be no more expensive than logical
8734 : operations on subword modes and (b) are likely to be cheaper than
8735 : logical operations on multiword modes.
8736 :
8737 : Otherwise, handle the case where the subreg is non-narrowing and does
8738 : not change the number of words. The non-narrowing condition ensures
8739 : that we don't convert word_mode operations to subword operations. */
8740 41607231 : scalar_int_mode int_outermode, int_innermode;
8741 41607231 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8742 34728505 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8743 75116883 : && (outermode == word_mode
8744 19789603 : || ((GET_MODE_PRECISION (int_outermode)
8745 19789603 : >= GET_MODE_PRECISION (int_innermode))
8746 4261425 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8747 4174388 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8748 17835076 : switch (GET_CODE (op))
8749 : {
8750 31723 : case NOT:
8751 31723 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8752 1925 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8753 : break;
8754 :
8755 461386 : case AND:
8756 461386 : case IOR:
8757 461386 : case XOR:
8758 461386 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8759 202966 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8760 198178 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8761 : break;
8762 :
8763 : default:
8764 : break;
8765 : }
8766 :
8767 41407128 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8768 34528402 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8769 75935530 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8770 : {
8771 : /* Handle polynomial integers. The upper bits of a paradoxical
8772 : subreg are undefined, so this is safe regardless of whether
8773 : we're truncating or extending. */
8774 31197847 : if (CONST_POLY_INT_P (op))
8775 : {
8776 : poly_wide_int val
8777 : = poly_wide_int::from (const_poly_int_value (op),
8778 : GET_MODE_PRECISION (int_outermode),
8779 : SIGNED);
8780 : return immed_wide_int_const (val, int_outermode);
8781 : }
8782 :
8783 31197847 : if (GET_MODE_PRECISION (int_outermode)
8784 31197847 : < GET_MODE_PRECISION (int_innermode))
8785 : {
8786 18766316 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8787 18766316 : if (tem)
8788 : return tem;
8789 : }
8790 : }
8791 :
8792 : /* If the outer mode is not integral, try taking a subreg with the equivalent
8793 : integer outer mode and then bitcasting the result.
8794 : Other simplifications rely on integer to integer subregs and we'd
8795 : potentially miss out on optimizations otherwise. */
8796 80093134 : if (known_gt (GET_MODE_SIZE (innermode),
8797 : GET_MODE_SIZE (outermode))
8798 20772175 : && SCALAR_INT_MODE_P (innermode)
8799 19605571 : && !SCALAR_INT_MODE_P (outermode)
8800 60994970 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8801 88114 : 0).exists (&int_outermode))
8802 : {
8803 88114 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8804 88114 : if (tem)
8805 1993 : return lowpart_subreg (outermode, tem, int_outermode);
8806 : }
8807 :
8808 : /* If OP is a vector comparison and the subreg is not changing the
8809 : number of elements or the size of the elements, change the result
8810 : of the comparison to the new mode. */
8811 40044574 : if (COMPARISON_P (op)
8812 286375 : && VECTOR_MODE_P (outermode)
8813 198658 : && VECTOR_MODE_P (innermode)
8814 595950 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8815 40416505 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8816 : GET_MODE_UNIT_SIZE (innermode)))
8817 123633 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8818 123633 : XEXP (op, 0), XEXP (op, 1));
8819 :
8820 : /* Distribute non-paradoxical subregs through logic ops in cases where
8821 : one term disappears.
8822 :
8823 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8824 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8825 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8826 :
8827 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8828 :
8829 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8830 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8831 :
8832 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8833 39920941 : if (known_ge (innersize, outersize)
8834 27000963 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8835 24911754 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8836 41548783 : && CONSTANT_P (XEXP (op, 1)))
8837 : {
8838 828652 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8839 828652 : if (op1_subreg == CONSTM1_RTX (outermode))
8840 : {
8841 117368 : if (GET_CODE (op) == IOR)
8842 : return op1_subreg;
8843 117134 : rtx op0 = XEXP (op, 0);
8844 117134 : if (GET_CODE (op) == XOR)
8845 901 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8846 117134 : return simplify_gen_subreg (outermode, op0, innermode, byte);
8847 : }
8848 :
8849 711284 : if (op1_subreg == CONST0_RTX (outermode))
8850 12162 : return (GET_CODE (op) == AND
8851 12162 : ? op1_subreg
8852 7200 : : distribute_subreg (XEXP (op, 0)));
8853 : }
8854 :
8855 : return NULL_RTX;
8856 : }
8857 :
8858 : /* Make a SUBREG operation or equivalent if it folds. */
8859 :
8860 : rtx
8861 43701731 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
8862 : machine_mode innermode,
8863 : poly_uint64 byte)
8864 : {
8865 43701731 : rtx newx;
8866 :
8867 43701731 : newx = simplify_subreg (outermode, op, innermode, byte);
8868 43701731 : if (newx)
8869 : return newx;
8870 :
8871 20580921 : if (GET_CODE (op) == SUBREG
8872 20580921 : || GET_CODE (op) == CONCAT
8873 20546243 : || CONST_SCALAR_INT_P (op)
8874 20546217 : || CONST_DOUBLE_AS_FLOAT_P (op)
8875 20546217 : || CONST_FIXED_P (op)
8876 20546217 : || GET_CODE (op) == CONST_VECTOR)
8877 : return NULL_RTX;
8878 :
8879 20546207 : if (validate_subreg (outermode, innermode, op, byte))
8880 20514915 : return gen_rtx_SUBREG (outermode, op, byte);
8881 :
8882 : return NULL_RTX;
8883 : }
8884 :
8885 : /* Generates a subreg to get the least significant part of EXPR (in mode
8886 : INNER_MODE) to OUTER_MODE. */
8887 :
8888 : rtx
8889 32425695 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
8890 : machine_mode inner_mode)
8891 : {
8892 32425695 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
8893 32425695 : subreg_lowpart_offset (outer_mode, inner_mode));
8894 : }
8895 :
8896 : /* Generate RTX to select element at INDEX out of vector OP. */
8897 :
8898 : rtx
8899 643961 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
8900 : {
8901 643961 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
8902 :
8903 643961 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
8904 :
8905 1287922 : if (known_eq (index * GET_MODE_SIZE (imode),
8906 : subreg_lowpart_offset (imode, GET_MODE (op))))
8907 : {
8908 643811 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
8909 643811 : if (res)
8910 : return res;
8911 : }
8912 :
8913 472 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
8914 472 : return gen_rtx_VEC_SELECT (imode, op, tmp);
8915 : }
8916 :
8917 :
8918 : /* Simplify X, an rtx expression.
8919 :
8920 : Return the simplified expression or NULL if no simplifications
8921 : were possible.
8922 :
8923 : This is the preferred entry point into the simplification routines;
8924 : however, we still allow passes to call the more specific routines.
8925 :
8926 : Right now GCC has three (yes, three) major bodies of RTL simplification
8927 : code that need to be unified.
8928 :
8929 : 1. fold_rtx in cse.cc. This code uses various CSE specific
8930 : information to aid in RTL simplification.
8931 :
8932 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
8933 : it uses combine specific information to aid in RTL
8934 : simplification.
8935 :
8936 : 3. The routines in this file.
8937 :
8938 :
8939 : Long term we want to only have one body of simplification code; to
8940 : get to that state I recommend the following steps:
8941 :
8942 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
8943 : which are not pass dependent state into these routines.
8944 :
8945 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
8946 : use this routine whenever possible.
8947 :
8948 : 3. Allow for pass dependent state to be provided to these
8949 : routines and add simplifications based on the pass dependent
8950 : state. Remove code from cse.cc & combine.cc that becomes
8951 : redundant/dead.
8952 :
8953 : It will take time, but ultimately the compiler will be easier to
8954 : maintain and improve. It's totally silly that when we add a
8955 : simplification that it needs to be added to 4 places (3 for RTL
8956 : simplification and 1 for tree simplification. */
8957 :
8958 : rtx
8959 45960778 : simplify_rtx (const_rtx x)
8960 : {
8961 45960778 : const enum rtx_code code = GET_CODE (x);
8962 45960778 : const machine_mode mode = GET_MODE (x);
8963 :
8964 45960778 : switch (GET_RTX_CLASS (code))
8965 : {
8966 848111 : case RTX_UNARY:
8967 1696222 : return simplify_unary_operation (code, mode,
8968 848111 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
8969 26510468 : case RTX_COMM_ARITH:
8970 26510468 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
8971 530844 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
8972 :
8973 : /* Fall through. */
8974 :
8975 31982801 : case RTX_BIN_ARITH:
8976 31982801 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
8977 :
8978 95817 : case RTX_TERNARY:
8979 95817 : case RTX_BITFIELD_OPS:
8980 95817 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
8981 95817 : XEXP (x, 0), XEXP (x, 1),
8982 95817 : XEXP (x, 2));
8983 :
8984 202931 : case RTX_COMPARE:
8985 202931 : case RTX_COMM_COMPARE:
8986 202931 : return simplify_relational_operation (code, mode,
8987 202931 : ((GET_MODE (XEXP (x, 0))
8988 : != VOIDmode)
8989 : ? GET_MODE (XEXP (x, 0))
8990 284 : : GET_MODE (XEXP (x, 1))),
8991 202931 : XEXP (x, 0),
8992 405862 : XEXP (x, 1));
8993 :
8994 230439 : case RTX_EXTRA:
8995 230439 : if (code == SUBREG)
8996 2446 : return simplify_subreg (mode, SUBREG_REG (x),
8997 2446 : GET_MODE (SUBREG_REG (x)),
8998 2446 : SUBREG_BYTE (x));
8999 : break;
9000 :
9001 6369671 : case RTX_OBJ:
9002 6369671 : if (code == LO_SUM)
9003 : {
9004 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
9005 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
9006 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
9007 0 : return XEXP (x, 1);
9008 : }
9009 : break;
9010 :
9011 : default:
9012 : break;
9013 : }
9014 : return NULL;
9015 : }
9016 :
9017 : #if CHECKING_P
9018 :
9019 : namespace selftest {
9020 :
9021 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
9022 :
9023 : static rtx
9024 2672 : make_test_reg (machine_mode mode)
9025 : {
9026 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
9027 :
9028 2672 : return gen_rtx_REG (mode, test_reg_num++);
9029 : }
9030 :
9031 : static void
9032 40 : test_scalar_int_ops (machine_mode mode)
9033 : {
9034 40 : rtx op0 = make_test_reg (mode);
9035 40 : rtx op1 = make_test_reg (mode);
9036 40 : rtx six = GEN_INT (6);
9037 :
9038 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
9039 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
9040 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
9041 :
9042 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
9043 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
9044 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
9045 :
9046 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
9047 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
9048 :
9049 : /* Test some binary identities. */
9050 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
9051 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
9052 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
9053 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
9054 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
9055 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
9056 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
9057 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
9058 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
9059 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
9060 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
9061 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
9062 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
9063 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
9064 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
9065 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
9066 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
9067 :
9068 : /* Test some self-inverse operations. */
9069 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
9070 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
9071 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
9072 :
9073 : /* Test some reflexive operations. */
9074 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
9075 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
9076 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
9077 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
9078 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
9079 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
9080 :
9081 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
9082 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
9083 :
9084 : /* Test simplify_distributive_operation. */
9085 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
9086 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
9087 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
9088 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
9089 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
9090 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
9091 :
9092 : /* Test useless extensions are eliminated. */
9093 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
9094 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
9095 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
9096 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
9097 40 : }
9098 :
9099 : /* Verify some simplifications of integer extension/truncation.
9100 : Machine mode BMODE is the guaranteed wider than SMODE. */
9101 :
9102 : static void
9103 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
9104 : {
9105 24 : rtx sreg = make_test_reg (smode);
9106 :
9107 : /* Check truncation of extension. */
9108 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9109 : simplify_gen_unary (ZERO_EXTEND, bmode,
9110 : sreg, smode),
9111 : bmode),
9112 : sreg);
9113 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9114 : simplify_gen_unary (SIGN_EXTEND, bmode,
9115 : sreg, smode),
9116 : bmode),
9117 : sreg);
9118 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9119 : lowpart_subreg (bmode, sreg, smode),
9120 : bmode),
9121 : sreg);
9122 :
9123 : /* Test extensions, followed by logic ops, followed by truncations. */
9124 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9125 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9126 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9127 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9128 : simplify_gen_binary (AND, bmode,
9129 : bsubreg, smask),
9130 : bmode),
9131 : sreg);
9132 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9133 : simplify_gen_binary (AND, bmode,
9134 : bsubreg, inv_smask),
9135 : bmode),
9136 : const0_rtx);
9137 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9138 : simplify_gen_binary (IOR, bmode,
9139 : bsubreg, smask),
9140 : bmode),
9141 : constm1_rtx);
9142 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9143 : simplify_gen_binary (IOR, bmode,
9144 : bsubreg, inv_smask),
9145 : bmode),
9146 : sreg);
9147 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9148 : simplify_gen_binary (XOR, bmode,
9149 : bsubreg, smask),
9150 : bmode),
9151 : lowpart_subreg (smode,
9152 : gen_rtx_NOT (bmode, bsubreg),
9153 : bmode));
9154 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9155 : simplify_gen_binary (XOR, bmode,
9156 : bsubreg, inv_smask),
9157 : bmode),
9158 : sreg);
9159 :
9160 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9161 : {
9162 24 : rtx breg1 = make_test_reg (bmode);
9163 24 : rtx breg2 = make_test_reg (bmode);
9164 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9165 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9166 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9167 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9168 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9169 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9170 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9171 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9172 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9173 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9174 : gen_rtx_NOT (bmode, breg1));
9175 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9176 : gen_rtx_AND (bmode, breg1, breg2));
9177 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9178 : gen_rtx_IOR (bmode, breg1, breg2));
9179 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9180 : gen_rtx_XOR (bmode, breg1, breg2));
9181 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9182 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9183 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9184 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9185 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9186 : gen_rtx_XOR (bmode,
9187 : gen_rtx_XOR (bmode, breg1, breg2),
9188 : const1_rtx));
9189 : }
9190 24 : }
9191 :
9192 : /* Verify more simplifications of integer extension/truncation.
9193 : BMODE is wider than MMODE which is wider than SMODE. */
9194 :
9195 : static void
9196 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9197 : machine_mode smode)
9198 : {
9199 16 : rtx breg = make_test_reg (bmode);
9200 16 : rtx mreg = make_test_reg (mmode);
9201 16 : rtx sreg = make_test_reg (smode);
9202 :
9203 : /* Check truncate of truncate. */
9204 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9205 : simplify_gen_unary (TRUNCATE, mmode,
9206 : breg, bmode),
9207 : mmode),
9208 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9209 :
9210 : /* Check extension of extension. */
9211 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9212 : simplify_gen_unary (ZERO_EXTEND, mmode,
9213 : sreg, smode),
9214 : mmode),
9215 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9216 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9217 : simplify_gen_unary (SIGN_EXTEND, mmode,
9218 : sreg, smode),
9219 : mmode),
9220 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9221 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9222 : simplify_gen_unary (ZERO_EXTEND, mmode,
9223 : sreg, smode),
9224 : mmode),
9225 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9226 :
9227 : /* Check truncation of extension. */
9228 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9229 : simplify_gen_unary (ZERO_EXTEND, bmode,
9230 : mreg, mmode),
9231 : bmode),
9232 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9233 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9234 : simplify_gen_unary (SIGN_EXTEND, bmode,
9235 : mreg, mmode),
9236 : bmode),
9237 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9238 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9239 : lowpart_subreg (bmode, mreg, mmode),
9240 : bmode),
9241 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9242 16 : }
9243 :
9244 : /* Test comparisons of comparisons, with the inner comparisons being
9245 : between values of mode MODE2 and producing results of mode MODE1,
9246 : and with the outer comparisons producing results of mode MODE0. */
9247 :
9248 : static void
9249 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9250 : {
9251 4 : rtx reg0 = make_test_reg (mode2);
9252 4 : rtx reg1 = make_test_reg (mode2);
9253 :
9254 4 : static const rtx_code codes[] = {
9255 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9256 : };
9257 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9258 4 : rtx cmps[num_codes];
9259 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9260 :
9261 44 : for (unsigned int i = 0; i < num_codes; ++i)
9262 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9263 :
9264 44 : for (auto code : codes)
9265 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9266 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9267 : {
9268 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9269 : cmps[i0], cmps[i1]);
9270 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9271 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9272 : else
9273 : {
9274 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9275 : && (CONSTANT_P (cmp_res)
9276 : || (COMPARISON_P (cmp_res)
9277 : && GET_MODE (cmp_res) == mode0
9278 : && REG_P (XEXP (cmp_res, 0))
9279 : && REG_P (XEXP (cmp_res, 1)))));
9280 10880 : for (rtx reg0_val : vals)
9281 32640 : for (rtx reg1_val : vals)
9282 : {
9283 24480 : rtx val0 = simplify_const_relational_operation
9284 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9285 24480 : rtx val1 = simplify_const_relational_operation
9286 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9287 24480 : rtx val = simplify_const_relational_operation
9288 24480 : (code, mode0, val0, val1);
9289 24480 : rtx folded = cmp_res;
9290 24480 : if (COMPARISON_P (cmp_res))
9291 16704 : folded = simplify_const_relational_operation
9292 16704 : (GET_CODE (cmp_res), mode0,
9293 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9294 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9295 24480 : ASSERT_RTX_EQ (val, folded);
9296 : }
9297 : }
9298 : }
9299 4 : }
9300 :
9301 :
9302 : /* Verify some simplifications involving scalar expressions. */
9303 :
9304 : static void
9305 4 : test_scalar_ops ()
9306 : {
9307 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9308 : {
9309 496 : machine_mode mode = (machine_mode) i;
9310 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9311 40 : test_scalar_int_ops (mode);
9312 : }
9313 :
9314 4 : test_scalar_int_ext_ops (HImode, QImode);
9315 4 : test_scalar_int_ext_ops (SImode, QImode);
9316 4 : test_scalar_int_ext_ops (SImode, HImode);
9317 4 : test_scalar_int_ext_ops (DImode, QImode);
9318 4 : test_scalar_int_ext_ops (DImode, HImode);
9319 4 : test_scalar_int_ext_ops (DImode, SImode);
9320 :
9321 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9322 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9323 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9324 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9325 :
9326 4 : test_comparisons (QImode, HImode, SImode);
9327 4 : }
9328 :
9329 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9330 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9331 : register that holds one element of MODE. */
9332 :
9333 : static void
9334 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9335 : {
9336 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9337 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9338 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9339 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9340 : {
9341 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9342 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9343 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9344 124 : ASSERT_RTX_EQ (duplicate,
9345 : simplify_unary_operation (NOT, mode,
9346 : duplicate_not, mode));
9347 :
9348 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9349 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9350 124 : ASSERT_RTX_EQ (duplicate,
9351 : simplify_unary_operation (NEG, mode,
9352 : duplicate_neg, mode));
9353 :
9354 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9355 124 : ASSERT_RTX_EQ (duplicate,
9356 : simplify_binary_operation (PLUS, mode, duplicate,
9357 : CONST0_RTX (mode)));
9358 :
9359 124 : ASSERT_RTX_EQ (duplicate,
9360 : simplify_binary_operation (MINUS, mode, duplicate,
9361 : CONST0_RTX (mode)));
9362 :
9363 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9364 : simplify_binary_operation (MINUS, mode, duplicate,
9365 : duplicate));
9366 : }
9367 :
9368 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9369 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9370 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9371 : simplify_binary_operation (VEC_SELECT, inner_mode,
9372 : duplicate, zero_par));
9373 :
9374 224 : unsigned HOST_WIDE_INT const_nunits;
9375 224 : if (nunits.is_constant (&const_nunits))
9376 : {
9377 : /* And again with the final element. */
9378 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9379 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9380 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9381 : simplify_binary_operation (VEC_SELECT, inner_mode,
9382 : duplicate, last_par));
9383 :
9384 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9385 : /* Skip this test for vectors of booleans, because offset is in bytes,
9386 : while vec_merge indices are in elements (usually bits). */
9387 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9388 : {
9389 224 : rtx vector_reg = make_test_reg (mode);
9390 3508 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9391 : {
9392 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9393 : break;
9394 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9395 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9396 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9397 :
9398 3284 : ASSERT_RTX_EQ (scalar_reg,
9399 : simplify_gen_subreg (inner_mode, vm,
9400 : mode, offset));
9401 : }
9402 : }
9403 : }
9404 :
9405 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9406 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9407 224 : ASSERT_RTX_EQ (scalar_reg,
9408 : simplify_gen_subreg (inner_mode, duplicate,
9409 : mode, offset));
9410 :
9411 224 : machine_mode narrower_mode;
9412 224 : if (maybe_ne (nunits, 2U)
9413 184 : && multiple_p (nunits, 2)
9414 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9415 396 : && VECTOR_MODE_P (narrower_mode))
9416 : {
9417 : /* Test VEC_DUPLICATE of a vector. */
9418 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9419 172 : nbuilder.quick_push (const0_rtx);
9420 172 : nbuilder.quick_push (const1_rtx);
9421 172 : rtx_vector_builder builder (mode, 2, 1);
9422 172 : builder.quick_push (const0_rtx);
9423 172 : builder.quick_push (const1_rtx);
9424 172 : ASSERT_RTX_EQ (builder.build (),
9425 : simplify_unary_operation (VEC_DUPLICATE, mode,
9426 : nbuilder.build (),
9427 : narrower_mode));
9428 :
9429 : /* Test VEC_SELECT of a vector. */
9430 172 : rtx vec_par
9431 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9432 172 : rtx narrower_duplicate
9433 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9434 172 : ASSERT_RTX_EQ (narrower_duplicate,
9435 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9436 : duplicate, vec_par));
9437 :
9438 : /* Test a vector subreg of a VEC_DUPLICATE. */
9439 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9440 172 : ASSERT_RTX_EQ (narrower_duplicate,
9441 : simplify_gen_subreg (narrower_mode, duplicate,
9442 : mode, offset));
9443 172 : }
9444 224 : }
9445 :
9446 : /* Test vector simplifications involving VEC_SERIES in which the
9447 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9448 : register that holds one element of MODE. */
9449 :
9450 : static void
9451 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9452 : {
9453 : /* Test unary cases with VEC_SERIES arguments. */
9454 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9455 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9456 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9457 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9458 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9459 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9460 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9461 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9462 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9463 : neg_scalar_reg);
9464 92 : ASSERT_RTX_EQ (series_0_r,
9465 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9466 92 : ASSERT_RTX_EQ (series_r_m1,
9467 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9468 92 : ASSERT_RTX_EQ (series_r_r,
9469 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9470 :
9471 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9472 92 : ASSERT_RTX_EQ (duplicate,
9473 : simplify_binary_operation (VEC_SERIES, mode,
9474 : scalar_reg, const0_rtx));
9475 :
9476 : /* Test PLUS and MINUS with VEC_SERIES. */
9477 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9478 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9479 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9480 92 : ASSERT_RTX_EQ (series_r_r,
9481 : simplify_binary_operation (PLUS, mode, series_0_r,
9482 : duplicate));
9483 92 : ASSERT_RTX_EQ (series_r_1,
9484 : simplify_binary_operation (PLUS, mode, duplicate,
9485 : series_0_1));
9486 92 : ASSERT_RTX_EQ (series_r_m1,
9487 : simplify_binary_operation (PLUS, mode, duplicate,
9488 : series_0_m1));
9489 92 : ASSERT_RTX_EQ (series_0_r,
9490 : simplify_binary_operation (MINUS, mode, series_r_r,
9491 : duplicate));
9492 92 : ASSERT_RTX_EQ (series_r_m1,
9493 : simplify_binary_operation (MINUS, mode, duplicate,
9494 : series_0_1));
9495 92 : ASSERT_RTX_EQ (series_r_1,
9496 : simplify_binary_operation (MINUS, mode, duplicate,
9497 : series_0_m1));
9498 92 : ASSERT_RTX_EQ (series_0_m1,
9499 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9500 : constm1_rtx));
9501 :
9502 : /* Test NEG on constant vector series. */
9503 92 : ASSERT_RTX_EQ (series_0_m1,
9504 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9505 92 : ASSERT_RTX_EQ (series_0_1,
9506 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9507 :
9508 : /* Test PLUS and MINUS on constant vector series. */
9509 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9510 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9511 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9512 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9513 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9514 92 : ASSERT_RTX_EQ (series_1_1,
9515 : simplify_binary_operation (PLUS, mode, series_0_1,
9516 : CONST1_RTX (mode)));
9517 92 : ASSERT_RTX_EQ (series_0_m1,
9518 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9519 : series_0_m1));
9520 92 : ASSERT_RTX_EQ (series_1_3,
9521 : simplify_binary_operation (PLUS, mode, series_1_1,
9522 : series_0_2));
9523 92 : ASSERT_RTX_EQ (series_0_1,
9524 : simplify_binary_operation (MINUS, mode, series_1_1,
9525 : CONST1_RTX (mode)));
9526 92 : ASSERT_RTX_EQ (series_1_1,
9527 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9528 : series_0_m1));
9529 92 : ASSERT_RTX_EQ (series_1_1,
9530 : simplify_binary_operation (MINUS, mode, series_1_3,
9531 : series_0_2));
9532 :
9533 : /* Test MULT between constant vectors. */
9534 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9535 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9536 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9537 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9538 92 : ASSERT_RTX_EQ (series_0_2,
9539 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9540 92 : ASSERT_RTX_EQ (series_3_9,
9541 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9542 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9543 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9544 : series_0_1));
9545 :
9546 : /* Test ASHIFT between constant vectors. */
9547 92 : ASSERT_RTX_EQ (series_0_2,
9548 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9549 : CONST1_RTX (mode)));
9550 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9551 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9552 : series_0_1));
9553 92 : }
9554 :
9555 : static rtx
9556 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9557 : {
9558 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9559 : }
9560 :
9561 : /* Verify simplify_merge_mask works correctly. */
9562 :
9563 : static void
9564 224 : test_vec_merge (machine_mode mode)
9565 : {
9566 224 : rtx op0 = make_test_reg (mode);
9567 224 : rtx op1 = make_test_reg (mode);
9568 224 : rtx op2 = make_test_reg (mode);
9569 224 : rtx op3 = make_test_reg (mode);
9570 224 : rtx op4 = make_test_reg (mode);
9571 224 : rtx op5 = make_test_reg (mode);
9572 224 : rtx mask1 = make_test_reg (SImode);
9573 224 : rtx mask2 = make_test_reg (SImode);
9574 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9575 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9576 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9577 :
9578 : /* Simple vec_merge. */
9579 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9580 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9581 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9582 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9583 :
9584 : /* Nested vec_merge.
9585 : It's tempting to make this simplify right down to opN, but we don't
9586 : because all the simplify_* functions assume that the operands have
9587 : already been simplified. */
9588 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9589 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9590 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9591 :
9592 : /* Intermediate unary op. */
9593 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9594 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9595 : simplify_merge_mask (unop, mask1, 0));
9596 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9597 : simplify_merge_mask (unop, mask1, 1));
9598 :
9599 : /* Intermediate binary op. */
9600 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9601 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9602 : simplify_merge_mask (binop, mask1, 0));
9603 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9604 : simplify_merge_mask (binop, mask1, 1));
9605 :
9606 : /* Intermediate ternary op. */
9607 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9608 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9609 : simplify_merge_mask (tenop, mask1, 0));
9610 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9611 : simplify_merge_mask (tenop, mask1, 1));
9612 :
9613 : /* Side effects. */
9614 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9615 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9616 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9617 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9618 :
9619 : /* Called indirectly. */
9620 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9621 : simplify_rtx (nvm));
9622 224 : }
9623 :
9624 : /* Test that vector rotate formation works at RTL level. Try various
9625 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9626 :
9627 : static void
9628 92 : test_vector_rotate (rtx reg)
9629 : {
9630 92 : machine_mode mode = GET_MODE (reg);
9631 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9632 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9633 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9634 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9635 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9636 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9637 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9638 92 : ASSERT_RTX_EQ (rotate_rtx,
9639 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9640 92 : ASSERT_RTX_EQ (rotate_rtx,
9641 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9642 92 : ASSERT_RTX_EQ (rotate_rtx,
9643 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9644 :
9645 : /* Don't go through every possible rotate amount to save execution time.
9646 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9647 : other bswap operations sometimes. Go through just the odd amounts. */
9648 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9649 : {
9650 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9651 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9652 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9653 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9654 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9655 1288 : ASSERT_RTX_EQ (rotate_rtx,
9656 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9657 1288 : ASSERT_RTX_EQ (rotate_rtx,
9658 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9659 1288 : ASSERT_RTX_EQ (rotate_rtx,
9660 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9661 : }
9662 92 : }
9663 :
9664 : /* Test subregs of integer vector constant X, trying elements in
9665 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9666 : where NELTS is the number of elements in X. Subregs involving
9667 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9668 :
9669 : static void
9670 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9671 : unsigned int first_valid = 0)
9672 : {
9673 276 : machine_mode inner_mode = GET_MODE (x);
9674 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9675 :
9676 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9677 : {
9678 34224 : machine_mode outer_mode = (machine_mode) modei;
9679 34224 : if (!VECTOR_MODE_P (outer_mode))
9680 18768 : continue;
9681 :
9682 15456 : unsigned int outer_nunits;
9683 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9684 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9685 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9686 : {
9687 : /* Test subregs in which the outer mode is a smaller,
9688 : constant-sized vector of the same element type. */
9689 1092 : unsigned int limit
9690 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9691 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9692 : {
9693 6936 : rtx expected = NULL_RTX;
9694 6936 : if (elt >= first_valid)
9695 : {
9696 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9697 39768 : for (unsigned int i = 0; i < outer_nunits; ++i)
9698 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9699 6936 : expected = builder.build ();
9700 6936 : }
9701 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9702 6936 : ASSERT_RTX_EQ (expected,
9703 : simplify_subreg (outer_mode, x,
9704 : inner_mode, byte));
9705 : }
9706 : }
9707 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9708 : GET_MODE_SIZE (inner_mode))
9709 2040 : && known_eq (elt_bias, 0U)
9710 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9711 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9712 : GET_MODE_NUNITS (outer_mode)))
9713 2040 : && (!FLOAT_MODE_P (outer_mode)
9714 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9715 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9716 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9717 : || !CONST_VECTOR_STEPPED_P (x)))
9718 : {
9719 : /* Try converting to OUTER_MODE and back. */
9720 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9721 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9722 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9723 : outer_mode, 0));
9724 : }
9725 : }
9726 :
9727 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9728 : {
9729 : /* Test each byte in the element range. */
9730 276 : unsigned int limit
9731 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9732 14604 : for (unsigned int i = 0; i < limit; ++i)
9733 : {
9734 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9735 14328 : rtx expected = NULL_RTX;
9736 14328 : if (elt >= first_valid)
9737 : {
9738 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9739 14328 : if (BYTES_BIG_ENDIAN)
9740 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9741 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9742 14328 : wide_int shifted_elt
9743 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9744 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9745 14328 : }
9746 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9747 14328 : ASSERT_RTX_EQ (expected,
9748 : simplify_subreg (QImode, x, inner_mode, byte));
9749 : }
9750 : }
9751 276 : }
9752 :
9753 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9754 : element per pattern. */
9755 :
9756 : static void
9757 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9758 : {
9759 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9760 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9761 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9762 92 : unsigned int count = gcd (min_nunits, 8);
9763 :
9764 92 : rtx_vector_builder builder (inner_mode, count, 1);
9765 684 : for (unsigned int i = 0; i < count; ++i)
9766 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9767 92 : rtx x = builder.build ();
9768 :
9769 92 : test_vector_subregs_modes (x);
9770 92 : if (!nunits.is_constant ())
9771 : test_vector_subregs_modes (x, nunits - min_nunits);
9772 92 : }
9773 :
9774 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9775 : elements per pattern. */
9776 :
9777 : static void
9778 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9779 : {
9780 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9781 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9782 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9783 92 : unsigned int count = gcd (min_nunits, 4);
9784 :
9785 92 : rtx_vector_builder builder (inner_mode, count, 2);
9786 444 : for (unsigned int i = 0; i < count; ++i)
9787 352 : builder.quick_push (gen_int_mode (i, int_mode));
9788 444 : for (unsigned int i = 0; i < count; ++i)
9789 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9790 92 : rtx x = builder.build ();
9791 :
9792 92 : test_vector_subregs_modes (x);
9793 92 : if (!nunits.is_constant ())
9794 : test_vector_subregs_modes (x, nunits - min_nunits, count);
9795 92 : }
9796 :
9797 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9798 : elements per pattern. */
9799 :
9800 : static void
9801 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9802 : {
9803 : /* Build { 0, 1, 2, 3, ... }. */
9804 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9805 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9806 368 : for (unsigned int i = 0; i < 3; ++i)
9807 276 : builder.quick_push (gen_int_mode (i, int_mode));
9808 92 : rtx x = builder.build ();
9809 :
9810 92 : test_vector_subregs_modes (x);
9811 92 : }
9812 :
9813 : /* Test constant subregs of integer vector mode INNER_MODE. */
9814 :
9815 : static void
9816 92 : test_vector_subregs (machine_mode inner_mode)
9817 : {
9818 92 : test_vector_subregs_repeating (inner_mode);
9819 92 : test_vector_subregs_fore_back (inner_mode);
9820 92 : test_vector_subregs_stepped (inner_mode);
9821 92 : }
9822 :
9823 : /* Verify some simplifications involving vectors. */
9824 :
9825 : static void
9826 4 : test_vector_ops ()
9827 : {
9828 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9829 : {
9830 496 : machine_mode mode = (machine_mode) i;
9831 496 : if (VECTOR_MODE_P (mode))
9832 : {
9833 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9834 224 : test_vector_ops_duplicate (mode, scalar_reg);
9835 224 : rtx vector_reg = make_test_reg (mode);
9836 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9837 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9838 : {
9839 92 : test_vector_ops_series (mode, scalar_reg);
9840 92 : test_vector_subregs (mode);
9841 92 : test_vector_rotate (vector_reg);
9842 : }
9843 224 : test_vec_merge (mode);
9844 : }
9845 : }
9846 4 : }
9847 :
9848 : template<unsigned int N>
9849 : struct simplify_const_poly_int_tests
9850 : {
9851 : static void run ();
9852 : };
9853 :
9854 : template<>
9855 : struct simplify_const_poly_int_tests<1>
9856 : {
9857 : static void run () {}
9858 : };
9859 :
9860 : /* Test various CONST_POLY_INT properties. */
9861 :
9862 : template<unsigned int N>
9863 : void
9864 : simplify_const_poly_int_tests<N>::run ()
9865 : {
9866 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
9867 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
9868 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
9869 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
9870 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
9871 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
9872 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
9873 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
9874 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
9875 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
9876 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
9877 : rtx two = GEN_INT (2);
9878 : rtx six = GEN_INT (6);
9879 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
9880 :
9881 : /* These tests only try limited operation combinations. Fuller arithmetic
9882 : testing is done directly on poly_ints. */
9883 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
9884 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
9885 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
9886 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
9887 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
9888 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
9889 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
9890 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
9891 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
9892 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
9893 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
9894 : }
9895 :
9896 : /* Run all of the selftests within this file. */
9897 :
9898 : void
9899 4 : simplify_rtx_cc_tests ()
9900 : {
9901 4 : test_scalar_ops ();
9902 4 : test_vector_ops ();
9903 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
9904 4 : }
9905 :
9906 : } // namespace selftest
9907 :
9908 : #endif /* CHECKING_P */
|