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 8809138 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 8809138 : 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 6163994 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6163994 : unsigned HOST_WIDE_INT val;
67 6163994 : unsigned int width;
68 6163994 : scalar_int_mode int_mode;
69 :
70 6163994 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6163986 : width = GET_MODE_PRECISION (int_mode);
74 6163986 : if (width == 0)
75 : return false;
76 :
77 6163986 : if (width <= HOST_BITS_PER_WIDE_INT
78 6162456 : && CONST_INT_P (x))
79 6014009 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 149977 : else if (CONST_WIDE_INT_P (x))
82 : {
83 474 : unsigned int i;
84 474 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 474 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : return false;
87 888 : for (i = 0; i < elts - 1; i++)
88 474 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : return false;
90 414 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 414 : width %= HOST_BITS_PER_WIDE_INT;
92 414 : 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 6014009 : if (width < HOST_BITS_PER_WIDE_INT)
109 5454887 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6014423 : 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 3518587 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3518587 : unsigned int width;
121 3518587 : scalar_int_mode int_mode;
122 :
123 3518587 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3518551 : width = GET_MODE_PRECISION (int_mode);
127 3518551 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3513923 : val &= GET_MODE_MASK (int_mode);
131 3513923 : 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 2603810 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2603810 : unsigned int width;
140 :
141 2603810 : scalar_int_mode int_mode;
142 2603810 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2570572 : width = GET_MODE_PRECISION (int_mode);
146 2570572 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2570572 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2570572 : 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 7430092 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7430092 : unsigned int width;
159 :
160 7430092 : scalar_int_mode int_mode;
161 7430092 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7117677 : width = GET_MODE_PRECISION (int_mode);
165 7117677 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7006950 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7006950 : 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 116809656 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 116809656 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 116809656 : tem = simplify_binary_operation (code, mode, op0, op1);
183 116809656 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 74036605 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 74036605 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 74036605 : 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 2704836430 : avoid_constant_pool_reference (rtx x)
198 : {
199 2704836430 : rtx c, tmp, addr;
200 2704836430 : machine_mode cmode;
201 2704836430 : poly_int64 offset = 0;
202 :
203 2704836430 : switch (GET_CODE (x))
204 : {
205 256904561 : case MEM:
206 256904561 : break;
207 :
208 914989 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 914989 : tmp = XEXP (x, 0);
211 914989 : c = avoid_constant_pool_reference (tmp);
212 914989 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 122502 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 122502 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 256904561 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 252882558 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 252882558 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 252882558 : addr = strip_offset (addr, &offset);
231 :
232 252882558 : 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 252882558 : if (GET_CODE (addr) == SYMBOL_REF
238 252882558 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5281247 : c = get_pool_constant (addr);
241 5281247 : 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 5281247 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 23202 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 11601 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 11601 : 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 3513788783 : 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 3513788783 : if (MEM_P (x)
269 61874507 : && MEM_EXPR (x)
270 3551722942 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 35069073 : tree decl = MEM_EXPR (x);
273 35069073 : machine_mode mode = GET_MODE (x);
274 35069073 : poly_int64 offset = 0;
275 :
276 35069073 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 10061449 : case ARRAY_REF:
286 10061449 : case ARRAY_RANGE_REF:
287 10061449 : case COMPONENT_REF:
288 10061449 : case BIT_FIELD_REF:
289 10061449 : case REALPART_EXPR:
290 10061449 : case IMAGPART_EXPR:
291 10061449 : case VIEW_CONVERT_EXPR:
292 10061449 : {
293 10061449 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 10061449 : tree toffset;
295 10061449 : int unsignedp, reversep, volatilep = 0;
296 :
297 10061449 : decl
298 10061449 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 20122898 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10346991 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 19686514 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9339523 : offset += bytepos + toffset_val;
306 10061449 : break;
307 : }
308 : }
309 :
310 721926 : if (decl
311 20654779 : && mode == GET_MODE (x)
312 20384629 : && VAR_P (decl)
313 13215191 : && (TREE_STATIC (decl)
314 11985755 : || DECL_THREAD_LOCAL_P (decl))
315 1265531 : && DECL_RTL_SET_P (decl)
316 10604554 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1265031 : rtx newx;
319 :
320 1265031 : offset += MEM_OFFSET (x);
321 :
322 1265031 : newx = DECL_RTL (decl);
323 :
324 1265031 : if (MEM_P (newx))
325 : {
326 1265031 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1265031 : 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 1265031 : n = strip_offset (n, &n_offset);
336 1265031 : o = strip_offset (o, &o_offset);
337 2502407 : if (!(known_eq (o_offset, n_offset + offset)
338 1237376 : && rtx_equal_p (o, n)))
339 211449 : 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 3513788783 : 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 5175229 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 5175229 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 5175229 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 2004516 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2213592 : 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 2213592 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2213592 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 1968722 : 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 21168319 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 21168319 : rtx tem;
392 :
393 21168319 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 18990969 : 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 479134713 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 479134713 : enum rtx_code code = GET_CODE (x);
410 479134713 : machine_mode mode = GET_MODE (x);
411 479134713 : machine_mode op_mode;
412 479134713 : const char *fmt;
413 479134713 : rtx op0, op1, op2, newx, op;
414 479134713 : rtvec vec, newvec;
415 479134713 : int i, j;
416 :
417 479134713 : if (UNLIKELY (fn != NULL))
418 : {
419 416681103 : newx = fn (x, old_rtx, data);
420 416681103 : if (newx)
421 : return newx;
422 : }
423 62453610 : else if (rtx_equal_p (x, old_rtx))
424 5168024 : return copy_rtx ((rtx) data);
425 :
426 376336272 : switch (GET_RTX_CLASS (code))
427 : {
428 1976180 : case RTX_UNARY:
429 1976180 : op0 = XEXP (x, 0);
430 1976180 : op_mode = GET_MODE (op0);
431 1976180 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 1976180 : if (op0 == XEXP (x, 0))
433 : return x;
434 647439 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 74089716 : case RTX_BIN_ARITH:
437 74089716 : case RTX_COMM_ARITH:
438 74089716 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 74089716 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 74089716 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 22740211 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 9671437 : case RTX_COMPARE:
445 9671437 : case RTX_COMM_COMPARE:
446 9671437 : op0 = XEXP (x, 0);
447 9671437 : op1 = XEXP (x, 1);
448 9671437 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 9671437 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 9671437 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 9671437 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2336144 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 5697384 : case RTX_TERNARY:
456 5697384 : case RTX_BITFIELD_OPS:
457 5697384 : op0 = XEXP (x, 0);
458 5697384 : op_mode = GET_MODE (op0);
459 5697384 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 5697384 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 5697384 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 5697384 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 1644892 : if (op_mode == VOIDmode)
465 1624070 : op_mode = GET_MODE (op0);
466 1644892 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 82376603 : case RTX_EXTRA:
469 82376603 : if (code == SUBREG)
470 : {
471 622809 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 622809 : if (op0 == SUBREG_REG (x))
473 : return x;
474 130670 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 65335 : GET_MODE (SUBREG_REG (x)),
476 65335 : SUBREG_BYTE (x));
477 65335 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 60905101 : case RTX_OBJ:
482 60905101 : if (code == MEM)
483 : {
484 10786585 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10786585 : if (op0 == XEXP (x, 0))
486 : return x;
487 159406 : return replace_equiv_address_nv (x, op0);
488 : }
489 50118516 : 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 273492161 : newx = x;
515 273492161 : fmt = GET_RTX_FORMAT (code);
516 590401177 : for (i = 0; fmt[i]; i++)
517 316909016 : switch (fmt[i])
518 : {
519 3043603 : case 'E':
520 3043603 : vec = XVEC (x, i);
521 3043603 : newvec = XVEC (newx, i);
522 12529319 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 9485716 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 9485716 : if (op != RTVEC_ELT (vec, j))
527 : {
528 342365 : if (newvec == vec)
529 : {
530 331910 : newvec = shallow_copy_rtvec (vec);
531 331910 : if (x == newx)
532 331910 : newx = shallow_copy_rtx (x);
533 331910 : XVEC (newx, i) = newvec;
534 : }
535 342365 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 74668571 : case 'e':
541 74668571 : if (XEXP (x, i))
542 : {
543 74668571 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 74668571 : if (op != XEXP (x, i))
545 : {
546 4198360 : if (x == newx)
547 4195094 : newx = shallow_copy_rtx (x);
548 4198360 : 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 12863538 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 12863538 : 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 17622441 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 17622441 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 17622441 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 17622441 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 17622441 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 17622441 : if (GET_CODE (op) == ZERO_EXTEND
624 17622441 : || 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 274892 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 274892 : if (mode == origmode)
634 : return XEXP (op, 0);
635 20968 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 7692 : return simplify_gen_unary (TRUNCATE, mode,
637 7692 : XEXP (op, 0), origmode);
638 : else
639 2792 : return simplify_gen_unary (GET_CODE (op), mode,
640 2792 : 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 17347549 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 17347549 : || GET_CODE (op) == MULT))
651 : {
652 734188 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 734188 : if (op0)
654 : {
655 734188 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 734188 : if (op1)
657 734188 : 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 16613361 : if ((GET_CODE (op) == LSHIFTRT
665 16613361 : || 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 1576420 : && 2 * precision <= op_precision
671 1576420 : && CONST_INT_P (XEXP (op, 1))
672 1480654 : && 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 16613337 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1576396 : && CONST_INT_P (XEXP (op, 1))
684 1480630 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 773 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 773 : && UINTVAL (XEXP (op, 1)) < precision)
687 763 : return simplify_gen_binary (LSHIFTRT, mode,
688 763 : 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 16612574 : if (GET_CODE (op) == ASHIFT
694 443240 : && CONST_INT_P (XEXP (op, 1))
695 383428 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 383428 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 665 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 652 : && UINTVAL (XEXP (op, 1)) < precision)
699 644 : return simplify_gen_binary (ASHIFT, mode,
700 644 : 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 16611930 : if (GET_CODE (op) == AND
706 638769 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 638769 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 31157 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 31045 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 31045 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 31045 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 31045 : rtx mask_op = XEXP (op, 1);
714 31045 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 31045 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 31045 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 17820 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 17820 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 3184 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 34229 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 3184 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 3184 : 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 16608746 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 366858 : && REG_P (XEXP (op, 0))
735 253014 : && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 252104 : && CONST_INT_P (XEXP (op, 1))
737 252104 : && CONST_INT_P (XEXP (op, 2)))
738 : {
739 220445 : rtx op0 = XEXP (op, 0);
740 220445 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 220445 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 220445 : 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 220445 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
753 : {
754 7675 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 7675 : if (op0)
756 7675 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 7675 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 16601071 : if ((GET_CODE (op) == LSHIFTRT
763 16601071 : || GET_CODE (op) == ASHIFTRT)
764 1575633 : && SCALAR_INT_MODE_P (mode)
765 1572489 : && SCALAR_INT_MODE_P (op_mode)
766 1707389 : && precision >= BITS_PER_WORD
767 60197 : && 2 * precision <= op_precision
768 60197 : && CONST_INT_P (XEXP (op, 1))
769 51973 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 1857 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 1857 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 1857 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 1857 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 1857 : ? byte - shifted_bytes
777 1857 : : 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 16599214 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1570632 : && is_a <scalar_int_mode> (mode, &int_mode)
786 18168622 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1570632 : && MEM_P (XEXP (op, 0))
788 11480 : && CONST_INT_P (XEXP (op, 1))
789 21318 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 1267 : && INTVAL (XEXP (op, 1)) > 0
791 2534 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 1267 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 1267 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 1267 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 16599214 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 1224 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 1224 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 1224 : 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 16597990 : if ((GET_CODE (op) == ABS
809 16597990 : || 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 16597989 : if (GET_CODE (op) == SUBREG
818 16598166 : && is_a <scalar_int_mode> (mode, &int_mode)
819 27961 : && SCALAR_INT_MODE_P (op_mode)
820 27961 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 16625810 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 27818 : 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 27818 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 27818 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 27818 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 27818 : if (int_op_prec > subreg_prec)
845 : {
846 1520 : 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 26298 : else if (int_op_prec < subreg_prec
855 26298 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 26298 : return simplify_gen_unary (TRUNCATE, int_mode,
857 26298 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 16570205 : 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 16570205 : if (GET_CODE (op) == IOR
869 34868 : && SCALAR_INT_MODE_P (mode)
870 34868 : && SCALAR_INT_MODE_P (op_mode)
871 34868 : && CONST_INT_P (XEXP (op, 1))
872 16578971 : && 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 26762775 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 26762775 : rtx trueop, tem;
886 :
887 26762775 : trueop = avoid_constant_pool_reference (op);
888 :
889 26762775 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 26762775 : if (tem)
891 : return tem;
892 :
893 21879867 : 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 2694 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2694 : 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 2694 : if (op0_mode == VOIDmode)
906 : return false;
907 5386 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2693 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2693 : int in_bits = in_prec;
910 2693 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2603 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2603 : if (GET_CODE (op) == FLOAT)
914 2479 : 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 2603 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2693 : 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 21879867 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 21879867 : enum rtx_code reversed;
931 21879867 : rtx temp, elt, base, step;
932 21879867 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 21879867 : switch (code)
935 : {
936 1775265 : case NOT:
937 : /* (not (not X)) == X. */
938 1775265 : if (GET_CODE (op) == NOT)
939 3325 : 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 1771940 : if (COMPARISON_P (op)
944 13742 : && (mode == BImode || STORE_FLAG_VALUE == -1)
945 1771940 : && ((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 1771940 : if (GET_CODE (op) == PLUS
951 287403 : && XEXP (op, 1) == constm1_rtx)
952 4451 : 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 1767489 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 71479 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 71479 : CONSTM1_RTX (mode));
960 :
961 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 1696010 : if (GET_CODE (op) == XOR
963 15827 : && CONST_INT_P (XEXP (op, 1))
964 1699829 : && (temp = simplify_unary_operation (NOT, mode,
965 : XEXP (op, 1), mode)) != 0)
966 3819 : 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 1692191 : if (GET_CODE (op) == PLUS
970 282952 : && CONST_INT_P (XEXP (op, 1))
971 165533 : && mode_signbit_p (mode, XEXP (op, 1))
972 1695886 : && (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 1688496 : if (GET_CODE (op) == ASHIFT
983 36741 : && XEXP (op, 0) == const1_rtx)
984 : {
985 1043 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 1043 : 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 1687453 : 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 1687453 : if (partial_subreg_p (op)
1002 69820 : && subreg_lowpart_p (op)
1003 69508 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 89467 : && 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 1687290 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1023 : {
1024 12152 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 12152 : machine_mode op_mode;
1026 :
1027 12152 : op_mode = GET_MODE (in1);
1028 12152 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1029 :
1030 12152 : op_mode = GET_MODE (in2);
1031 12152 : if (op_mode == VOIDmode)
1032 5372 : op_mode = mode;
1033 12152 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1034 :
1035 12152 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 : std::swap (in1, in2);
1037 :
1038 24304 : 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 1675138 : 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 1672117 : case NEG:
1051 : /* (neg (neg X)) == X. */
1052 1672117 : if (GET_CODE (op) == NEG)
1053 6266 : 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 1665851 : if (GET_CODE (op) == IF_THEN_ELSE)
1059 : {
1060 3171 : rtx cond = XEXP (op, 0);
1061 3171 : rtx true_rtx = XEXP (op, 1);
1062 3171 : rtx false_rtx = XEXP (op, 2);
1063 :
1064 3171 : if ((GET_CODE (true_rtx) == NEG
1065 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 3171 : || (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 1665851 : if (GET_CODE (op) == PLUS
1083 135707 : && XEXP (op, 1) == const1_rtx)
1084 54116 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1085 :
1086 : /* Similarly, (neg (not X)) is (plus X 1). */
1087 1611735 : if (GET_CODE (op) == NOT)
1088 362 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 362 : 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 1611373 : if (GET_CODE (op) == MINUS
1097 23518 : && !HONOR_SIGNED_ZEROS (mode)
1098 1633513 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 22140 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1100 :
1101 1589233 : if (GET_CODE (op) == PLUS
1102 81591 : && !HONOR_SIGNED_ZEROS (mode)
1103 1670400 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1104 : {
1105 : /* (neg (plus A C)) is simplified to (minus -C A). */
1106 81167 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 4794 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1108 : {
1109 76373 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 76373 : if (temp)
1111 76373 : 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 4794 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 4794 : 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 1508066 : if (GET_CODE (op) == MULT
1122 1508066 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 : {
1124 20096 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 20096 : 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 1487970 : if (GET_CODE (op) == ASHIFT)
1132 : {
1133 54214 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 54214 : if (temp)
1135 13013 : 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 1474957 : if (GET_CODE (op) == ASHIFTRT
1141 27916 : && CONST_INT_P (XEXP (op, 1))
1142 1530693 : && 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 1474266 : if (GET_CODE (op) == LSHIFTRT
1149 7742 : && CONST_INT_P (XEXP (op, 1))
1150 1489582 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 2350 : return simplify_gen_binary (ASHIFTRT, mode,
1152 2350 : 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 1471916 : if (GET_CODE (op) == XOR
1156 10354 : && XEXP (op, 1) == const1_rtx
1157 1472028 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 33 : 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 1471883 : if (GET_CODE (op) == LT
1163 2529 : && XEXP (op, 1) == const0_rtx
1164 1473624 : && 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 1471528 : 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 1218852 : case TRUNCATE:
1210 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 : with the umulXi3_highpart patterns. */
1212 1218852 : if (GET_CODE (op) == LSHIFTRT
1213 18477 : && GET_CODE (XEXP (op, 0)) == MULT)
1214 : break;
1215 :
1216 1211602 : 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 1211590 : if (GET_MODE (op) != VOIDmode)
1231 : {
1232 1211590 : temp = simplify_truncation (mode, op, GET_MODE (op));
1233 1211590 : 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 1095703 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 1095703 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 0 : || truncated_to_mode (mode, op)))
1242 : {
1243 1083040 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 1083040 : 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 12853 : if (HWI_COMPUTABLE_MODE_P (mode)
1253 190 : && COMPARISON_P (op)
1254 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 12853 : && 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 12853 : if (GET_CODE (op) == MEM
1265 313 : && !VECTOR_MODE_P (mode)
1266 188 : && !MEM_VOLATILE_P (op)
1267 13035 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1268 : {
1269 182 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 182 : if (temp)
1271 : return temp;
1272 : }
1273 :
1274 : /* Check for useless truncation. */
1275 12853 : if (GET_MODE (op) == mode)
1276 : return op;
1277 : break;
1278 :
1279 172533 : case FLOAT_TRUNCATE:
1280 : /* Check for useless truncation. */
1281 172533 : if (GET_MODE (op) == mode)
1282 : return op;
1283 :
1284 172533 : if (DECIMAL_FLOAT_MODE_P (mode))
1285 : break;
1286 :
1287 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 172379 : 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 172377 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 145 : && flag_unsafe_math_optimizations)
1303 172373 : || 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 172370 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 172370 : && (flag_unsafe_math_optimizations
1313 1413 : || exact_int_to_float_conversion_p (op)))
1314 1412 : return simplify_gen_unary (GET_CODE (op), mode,
1315 : XEXP (op, 0),
1316 1412 : 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 170958 : if ((GET_CODE (op) == ABS
1321 170958 : || 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 170930 : if (GET_CODE (op) == SUBREG
1330 317 : && subreg_lowpart_p (op)
1331 171244 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 : return SUBREG_REG (op);
1333 : break;
1334 :
1335 590349 : case FLOAT_EXTEND:
1336 : /* Check for useless extension. */
1337 590349 : if (GET_MODE (op) == mode)
1338 : return op;
1339 :
1340 590349 : 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 590246 : if (GET_CODE (op) == FLOAT_EXTEND
1349 590246 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 1281 : && exact_int_to_float_conversion_p (op)))
1351 563 : return simplify_gen_unary (GET_CODE (op), mode,
1352 : XEXP (op, 0),
1353 563 : GET_MODE (XEXP (op, 0)));
1354 :
1355 : break;
1356 :
1357 266095 : case ABS:
1358 : /* (abs (neg <foo>)) -> (abs <foo>) */
1359 266095 : 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 266066 : if (GET_MODE (op) == VOIDmode)
1366 : break;
1367 :
1368 : /* If operand is something known to be positive, ignore the ABS. */
1369 266066 : 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 265848 : 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 265848 : && 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 265848 : if (is_a <scalar_int_mode> (mode, &int_mode)
1400 35540 : && (num_sign_bit_copies (op, int_mode)
1401 35540 : == 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 3449 : case POPCOUNT:
1419 3449 : 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 31172 : case BSWAP:
1481 : /* (bswap (bswap x)) -> x. */
1482 31172 : 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 898668 : case FLOAT:
1493 : /* (float (sign_extend <X>)) = (float <X>). */
1494 898668 : 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 2994890 : case SIGN_EXTEND:
1500 : /* Check for useless extension. */
1501 2994890 : 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 2994850 : 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 2994850 : if (GET_CODE (op) == MULT)
1518 : {
1519 67102 : rtx lhs = XEXP (op, 0);
1520 67102 : rtx rhs = XEXP (op, 1);
1521 67102 : enum rtx_code lcode = GET_CODE (lhs);
1522 67102 : 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 67102 : if ((lcode == SIGN_EXTEND
1527 66953 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1528 881 : && (rcode == SIGN_EXTEND
1529 837 : || (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 2994742 : if (GET_CODE (op) == SUBREG
1563 149287 : && SUBREG_PROMOTED_VAR_P (op)
1564 3000409 : && 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 2994742 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1591 : {
1592 19881 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1593 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1594 6627 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1595 6627 : 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 2988115 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1604 88327 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1605 2990612 : && is_a <scalar_int_mode> (mode, &int_mode)
1606 5143 : && CONST_INT_P (XEXP (op, 1))
1607 5143 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1608 2993134 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1609 5019 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1610 : {
1611 5019 : scalar_int_mode tmode;
1612 5019 : gcc_assert (GET_MODE_PRECISION (int_mode)
1613 : > GET_MODE_PRECISION (op_mode));
1614 5019 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1615 7392 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1616 : {
1617 2646 : rtx inner =
1618 2646 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1619 2646 : if (inner)
1620 2646 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1621 : ? SIGN_EXTEND : ZERO_EXTEND,
1622 2646 : 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 2985469 : if (GET_CODE (op) == LSHIFTRT
1629 183 : && CONST_INT_P (XEXP (op, 1))
1630 183 : && XEXP (op, 1) != const0_rtx)
1631 183 : 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 2985286 : 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 2985286 : if (val_signbit_known_clear_p (GET_MODE (op),
1668 2985286 : nonzero_bits (op, GET_MODE (op))))
1669 37676 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1670 :
1671 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1672 2947610 : if (GET_CODE (op) == SUBREG
1673 149041 : && subreg_lowpart_p (op)
1674 148944 : && GET_MODE (SUBREG_REG (op)) == mode
1675 3076325 : && is_a <scalar_int_mode> (mode, &int_mode)
1676 135493 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1677 135493 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1678 133686 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1679 3081296 : && (nonzero_bits (SUBREG_REG (op), mode)
1680 133686 : & ~(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 2940832 : 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 11382082 : case ZERO_EXTEND:
1708 : /* Check for useless extension. */
1709 11382082 : 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 11382040 : if (GET_CODE (op) == AND
1715 111938 : && CONST_INT_P (XEXP (op, 1))
1716 89280 : && INTVAL (XEXP (op, 1)) > 0)
1717 : {
1718 84497 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1719 84497 : if (tem)
1720 68372 : 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 11313668 : if (GET_CODE (op) == SUBREG
1727 1531178 : && SUBREG_PROMOTED_VAR_P (op)
1728 11314125 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1729 : {
1730 457 : rtx subreg = SUBREG_REG (op);
1731 457 : machine_mode subreg_mode = GET_MODE (subreg);
1732 457 : if (!paradoxical_subreg_p (mode, subreg_mode))
1733 : {
1734 299 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1735 299 : if (temp)
1736 : {
1737 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1738 299 : if (partial_subreg_p (temp))
1739 : {
1740 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1741 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1742 : }
1743 299 : return temp;
1744 : }
1745 : }
1746 : else
1747 : /* Zero-extending a zero-extended subreg. */
1748 158 : return simplify_gen_unary (ZERO_EXTEND, mode,
1749 158 : subreg, subreg_mode);
1750 : }
1751 :
1752 : /* Extending a widening multiplication should be canonicalized to
1753 : a wider widening multiplication. */
1754 11313211 : if (GET_CODE (op) == MULT)
1755 : {
1756 165424 : rtx lhs = XEXP (op, 0);
1757 165424 : rtx rhs = XEXP (op, 1);
1758 165424 : enum rtx_code lcode = GET_CODE (lhs);
1759 165424 : 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 165424 : if ((lcode == ZERO_EXTEND
1764 164652 : || (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 11313099 : if (GET_CODE (op) == ZERO_EXTEND)
1798 21662 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1799 21662 : 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 11291437 : if (GET_CODE (op) == LSHIFTRT
1805 70426 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1806 11291460 : && 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 11291437 : && (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 11291437 : if (partial_subreg_p (op)
1830 12784456 : && is_a <scalar_int_mode> (mode, &int_mode)
1831 1512079 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1832 1511493 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1833 1198173 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1834 1176332 : && subreg_lowpart_p (op)
1835 2373464 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1836 842743 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1837 : {
1838 19060 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1839 11968 : return SUBREG_REG (op);
1840 7092 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1841 7092 : op0_mode);
1842 : }
1843 :
1844 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1845 11272377 : if (GET_CODE (op) == SUBREG
1846 1511661 : && subreg_lowpart_p (op)
1847 926745 : && GET_MODE (SUBREG_REG (op)) == mode
1848 12109318 : && is_a <scalar_int_mode> (mode, &int_mode)
1849 836941 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1850 836941 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1851 775744 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1852 12048121 : && (nonzero_bits (SUBREG_REG (op), mode)
1853 775744 : & ~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 11272377 : if (partial_subreg_p (op)
1865 1493019 : && GET_CODE (XEXP (op, 0)) == NOT
1866 1446 : && GET_MODE (XEXP (op, 0)) == mode
1867 1425 : && subreg_lowpart_p (op)
1868 11272781 : && HWI_COMPUTABLE_MODE_P (mode)
1869 411 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1870 1512072 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1871 411 : & ~GET_MODE_MASK (op_mode)) == 0)
1872 : {
1873 7 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1874 14 : return simplify_gen_binary (XOR, mode,
1875 7 : XEXP (XEXP (op, 0), 0),
1876 7 : 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 11272370 : if (target_default_pointer_address_modes_p ()
1884 : && POINTERS_EXTEND_UNSIGNED > 0
1885 12671147 : && 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 11272391 : && !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 : default:
1904 : break;
1905 : }
1906 :
1907 18687584 : if (VECTOR_MODE_P (mode)
1908 1516838 : && vec_duplicate_p (op, &elt)
1909 20210178 : && code != VEC_DUPLICATE)
1910 : {
1911 5752 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1912 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1913 : operations by promoting VEC_DUPLICATE to the root of the expression
1914 : (as far as possible). */
1915 4696 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1916 9392 : elt, GET_MODE_INNER (GET_MODE (op)));
1917 : else
1918 : /* Try applying the operator to ELT and see if that simplifies.
1919 : We can duplicate the result if so.
1920 :
1921 : The reason we traditionally haven't used simplify_gen_unary
1922 : for these codes is that it didn't necessarily seem to be a
1923 : win to convert things like:
1924 :
1925 : (neg:V (vec_duplicate:V (reg:S R)))
1926 :
1927 : to:
1928 :
1929 : (vec_duplicate:V (neg:S (reg:S R)))
1930 :
1931 : The first might be done entirely in vector registers while the
1932 : second might need a move between register files.
1933 :
1934 : However, there also cases where promoting the vec_duplicate is
1935 : more efficient, and there is definite value in having a canonical
1936 : form when matching instruction patterns. We should consider
1937 : extending the simplify_gen_unary code above to more cases. */
1938 1056 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1939 2112 : elt, GET_MODE_INNER (GET_MODE (op)));
1940 5752 : if (temp)
1941 5276 : return gen_vec_duplicate (mode, temp);
1942 : }
1943 :
1944 : return 0;
1945 : }
1946 :
1947 : /* Try to compute the value of a unary operation CODE whose output mode is to
1948 : be MODE with input operand OP whose mode was originally OP_MODE.
1949 : Return zero if the value cannot be computed. */
1950 : rtx
1951 26763662 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1952 : rtx op, machine_mode op_mode)
1953 : {
1954 26763662 : scalar_int_mode result_mode;
1955 :
1956 26763662 : if (code == VEC_DUPLICATE)
1957 : {
1958 1622627 : gcc_assert (VECTOR_MODE_P (mode));
1959 1622627 : if (GET_MODE (op) != VOIDmode)
1960 : {
1961 543282 : if (!VECTOR_MODE_P (GET_MODE (op)))
1962 1073276 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1963 : else
1964 19932 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1965 : (GET_MODE (op)));
1966 : }
1967 1622627 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1968 1116811 : return gen_const_vec_duplicate (mode, op);
1969 505816 : if (GET_CODE (op) == CONST_VECTOR
1970 505816 : && (CONST_VECTOR_DUPLICATE_P (op)
1971 : || CONST_VECTOR_NUNITS (op).is_constant ()))
1972 : {
1973 755 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1974 755 : ? CONST_VECTOR_NPATTERNS (op)
1975 1509 : : CONST_VECTOR_NUNITS (op).to_constant ());
1976 2265 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1977 755 : rtx_vector_builder builder (mode, npatterns, 1);
1978 3130 : for (unsigned i = 0; i < npatterns; i++)
1979 2375 : builder.quick_push (CONST_VECTOR_ELT (op, i));
1980 755 : return builder.build ();
1981 755 : }
1982 : }
1983 :
1984 24405375 : if (VECTOR_MODE_P (mode)
1985 1557581 : && GET_CODE (op) == CONST_VECTOR
1986 25746278 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1987 : {
1988 33394 : gcc_assert (GET_MODE (op) == op_mode);
1989 :
1990 33394 : rtx_vector_builder builder;
1991 33394 : if (!builder.new_unary_operation (mode, op, false))
1992 : return 0;
1993 :
1994 33394 : unsigned int count = builder.encoded_nelts ();
1995 148682 : for (unsigned int i = 0; i < count; i++)
1996 : {
1997 231614 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1998 : CONST_VECTOR_ELT (op, i),
1999 231614 : GET_MODE_INNER (op_mode));
2000 115807 : if (!x || !valid_for_const_vector_p (mode, x))
2001 519 : return 0;
2002 115288 : builder.quick_push (x);
2003 : }
2004 32875 : return builder.build ();
2005 33394 : }
2006 :
2007 : /* The order of these tests is critical so that, for example, we don't
2008 : check the wrong mode (input vs. output) for a conversion operation,
2009 : such as FIX. At some point, this should be simplified. */
2010 :
2011 25612702 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2012 : {
2013 7354 : REAL_VALUE_TYPE d;
2014 :
2015 7354 : if (op_mode == VOIDmode)
2016 : {
2017 : /* CONST_INT have VOIDmode as the mode. We assume that all
2018 : the bits of the constant are significant, though, this is
2019 : a dangerous assumption as many times CONST_INTs are
2020 : created and used with garbage in the bits outside of the
2021 : precision of the implied mode of the const_int. */
2022 64 : op_mode = MAX_MODE_INT;
2023 : }
2024 :
2025 7354 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2026 :
2027 : /* Avoid the folding if flag_signaling_nans is on and
2028 : operand is a signaling NaN. */
2029 7354 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2030 : return 0;
2031 :
2032 7354 : d = real_value_truncate (mode, d);
2033 :
2034 : /* Avoid the folding if flag_rounding_math is on and the
2035 : conversion is not exact. */
2036 7354 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2037 : {
2038 1011 : bool fail = false;
2039 1011 : wide_int w = real_to_integer (&d, &fail,
2040 : GET_MODE_PRECISION
2041 1011 : (as_a <scalar_int_mode> (op_mode)));
2042 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2043 905 : return 0;
2044 1011 : }
2045 :
2046 6449 : return const_double_from_real_value (d, mode);
2047 : }
2048 25605348 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2049 : {
2050 2139 : REAL_VALUE_TYPE d;
2051 :
2052 2139 : if (op_mode == VOIDmode)
2053 : {
2054 : /* CONST_INT have VOIDmode as the mode. We assume that all
2055 : the bits of the constant are significant, though, this is
2056 : a dangerous assumption as many times CONST_INTs are
2057 : created and used with garbage in the bits outside of the
2058 : precision of the implied mode of the const_int. */
2059 8 : op_mode = MAX_MODE_INT;
2060 : }
2061 :
2062 2139 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2063 :
2064 : /* Avoid the folding if flag_signaling_nans is on and
2065 : operand is a signaling NaN. */
2066 2139 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2067 : return 0;
2068 :
2069 2139 : d = real_value_truncate (mode, d);
2070 :
2071 : /* Avoid the folding if flag_rounding_math is on and the
2072 : conversion is not exact. */
2073 2139 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2074 : {
2075 16 : bool fail = false;
2076 16 : wide_int w = real_to_integer (&d, &fail,
2077 : GET_MODE_PRECISION
2078 16 : (as_a <scalar_int_mode> (op_mode)));
2079 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2080 16 : return 0;
2081 16 : }
2082 :
2083 2123 : return const_double_from_real_value (d, mode);
2084 : }
2085 :
2086 25603209 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2087 : {
2088 3313398 : unsigned int width = GET_MODE_PRECISION (result_mode);
2089 3313398 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2090 : return 0;
2091 :
2092 3313398 : wide_int result;
2093 3313398 : scalar_int_mode imode = (op_mode == VOIDmode
2094 3313398 : ? result_mode
2095 3313182 : : as_a <scalar_int_mode> (op_mode));
2096 3313398 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2097 3313398 : int int_value;
2098 :
2099 : #if TARGET_SUPPORTS_WIDE_INT == 0
2100 : /* This assert keeps the simplification from producing a result
2101 : that cannot be represented in a CONST_DOUBLE but a lot of
2102 : upstream callers expect that this function never fails to
2103 : simplify something and so you if you added this to the test
2104 : above the code would die later anyway. If this assert
2105 : happens, you just need to make the port support wide int. */
2106 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2107 : #endif
2108 :
2109 3313398 : switch (code)
2110 : {
2111 179192 : case NOT:
2112 179192 : result = wi::bit_not (op0);
2113 179192 : break;
2114 :
2115 1856082 : case NEG:
2116 1856082 : result = wi::neg (op0);
2117 1856082 : break;
2118 :
2119 7435 : case ABS:
2120 7435 : result = wi::abs (op0);
2121 7435 : break;
2122 :
2123 0 : case FFS:
2124 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2125 0 : break;
2126 :
2127 168 : case CLZ:
2128 168 : if (wi::ne_p (op0, 0))
2129 38 : int_value = wi::clz (op0);
2130 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2131 : return NULL_RTX;
2132 38 : result = wi::shwi (int_value, result_mode);
2133 38 : break;
2134 :
2135 0 : case CLRSB:
2136 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2137 0 : break;
2138 :
2139 0 : case CTZ:
2140 0 : if (wi::ne_p (op0, 0))
2141 0 : int_value = wi::ctz (op0);
2142 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2143 : return NULL_RTX;
2144 0 : result = wi::shwi (int_value, result_mode);
2145 0 : break;
2146 :
2147 160 : case POPCOUNT:
2148 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2149 160 : break;
2150 :
2151 0 : case PARITY:
2152 0 : result = wi::shwi (wi::parity (op0), result_mode);
2153 0 : break;
2154 :
2155 2017 : case BSWAP:
2156 2017 : result = wi::bswap (op0);
2157 2017 : break;
2158 :
2159 0 : case BITREVERSE:
2160 0 : result = wi::bitreverse (op0);
2161 0 : break;
2162 :
2163 1090662 : case TRUNCATE:
2164 1090662 : case ZERO_EXTEND:
2165 1090662 : result = wide_int::from (op0, width, UNSIGNED);
2166 1090662 : break;
2167 :
2168 14342 : case US_TRUNCATE:
2169 14342 : case SS_TRUNCATE:
2170 14342 : {
2171 14342 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2172 14342 : wide_int nmax
2173 14342 : = wide_int::from (wi::max_value (width, sgn),
2174 28684 : GET_MODE_PRECISION (imode), sgn);
2175 14342 : wide_int nmin
2176 14342 : = wide_int::from (wi::min_value (width, sgn),
2177 28684 : GET_MODE_PRECISION (imode), sgn);
2178 14342 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2179 14342 : result = wide_int::from (result, width, sgn);
2180 14342 : break;
2181 14342 : }
2182 163340 : case SIGN_EXTEND:
2183 163340 : result = wide_int::from (op0, width, SIGNED);
2184 163340 : break;
2185 :
2186 0 : case SS_NEG:
2187 0 : if (wi::only_sign_bit_p (op0))
2188 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2189 : else
2190 0 : result = wi::neg (op0);
2191 : break;
2192 :
2193 0 : case SS_ABS:
2194 0 : if (wi::only_sign_bit_p (op0))
2195 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2196 : else
2197 0 : result = wi::abs (op0);
2198 : break;
2199 :
2200 : case SQRT:
2201 : default:
2202 : return 0;
2203 : }
2204 :
2205 3313268 : return immed_wide_int_const (result, result_mode);
2206 3313398 : }
2207 :
2208 22289811 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2209 414277 : && SCALAR_FLOAT_MODE_P (mode)
2210 412249 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2211 : {
2212 412249 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2213 412249 : switch (code)
2214 : {
2215 : case SQRT:
2216 : return 0;
2217 350 : case ABS:
2218 350 : d = real_value_abs (&d);
2219 350 : break;
2220 15711 : case NEG:
2221 15711 : d = real_value_negate (&d);
2222 15711 : break;
2223 2286 : case FLOAT_TRUNCATE:
2224 : /* Don't perform the operation if flag_signaling_nans is on
2225 : and the operand is a signaling NaN. */
2226 2286 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2227 : return NULL_RTX;
2228 : /* Or if flag_rounding_math is on and the truncation is not
2229 : exact. */
2230 2286 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2231 2286 : && !exact_real_truncate (mode, &d))
2232 231 : return NULL_RTX;
2233 2055 : d = real_value_truncate (mode, d);
2234 2055 : break;
2235 387387 : case FLOAT_EXTEND:
2236 : /* Don't perform the operation if flag_signaling_nans is on
2237 : and the operand is a signaling NaN. */
2238 387387 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2239 : return NULL_RTX;
2240 : /* All this does is change the mode, unless changing
2241 : mode class. */
2242 387385 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2243 0 : real_convert (&d, mode, &d);
2244 : break;
2245 0 : case FIX:
2246 : /* Don't perform the operation if flag_signaling_nans is on
2247 : and the operand is a signaling NaN. */
2248 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2249 : return NULL_RTX;
2250 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2251 0 : break;
2252 5910 : case NOT:
2253 5910 : {
2254 5910 : long tmp[4];
2255 5910 : int i;
2256 :
2257 5910 : real_to_target (tmp, &d, GET_MODE (op));
2258 29550 : for (i = 0; i < 4; i++)
2259 23640 : tmp[i] = ~tmp[i];
2260 5910 : real_from_target (&d, tmp, mode);
2261 5910 : break;
2262 : }
2263 0 : default:
2264 0 : gcc_unreachable ();
2265 : }
2266 411411 : return const_double_from_real_value (d, mode);
2267 : }
2268 2028 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2269 2028 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2270 21879590 : && is_int_mode (mode, &result_mode))
2271 : {
2272 2028 : unsigned int width = GET_MODE_PRECISION (result_mode);
2273 2028 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2274 : return 0;
2275 :
2276 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2277 : operators are intentionally left unspecified (to ease implementation
2278 : by target backends), for consistency, this routine implements the
2279 : same semantics for constant folding as used by the middle-end. */
2280 :
2281 : /* This was formerly used only for non-IEEE float.
2282 : eggert@twinsun.com says it is safe for IEEE also. */
2283 2028 : REAL_VALUE_TYPE t;
2284 2028 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2285 2028 : wide_int wmax, wmin;
2286 : /* This is part of the abi to real_to_integer, but we check
2287 : things before making this call. */
2288 2028 : bool fail;
2289 :
2290 2028 : switch (code)
2291 : {
2292 2020 : case FIX:
2293 : /* According to IEEE standard, for conversions from floating point to
2294 : integer. When a NaN or infinite operand cannot be represented in
2295 : the destination format and this cannot otherwise be indicated, the
2296 : invalid operation exception shall be signaled. When a numeric
2297 : operand would convert to an integer outside the range of the
2298 : destination format, the invalid operation exception shall be
2299 : signaled if this situation cannot otherwise be indicated. */
2300 2020 : if (REAL_VALUE_ISNAN (*x))
2301 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2302 :
2303 1065 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2304 : return NULL_RTX;
2305 :
2306 : /* Test against the signed upper bound. */
2307 105 : wmax = wi::max_value (width, SIGNED);
2308 105 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2309 105 : if (real_less (&t, x))
2310 3 : return (flag_trapping_math
2311 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2312 :
2313 : /* Test against the signed lower bound. */
2314 102 : wmin = wi::min_value (width, SIGNED);
2315 102 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2316 102 : if (real_less (x, &t))
2317 8 : return immed_wide_int_const (wmin, mode);
2318 :
2319 94 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2320 : mode);
2321 :
2322 8 : case UNSIGNED_FIX:
2323 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2324 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2325 :
2326 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2327 : return NULL_RTX;
2328 :
2329 : /* Test against the unsigned upper bound. */
2330 0 : wmax = wi::max_value (width, UNSIGNED);
2331 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2332 0 : if (real_less (&t, x))
2333 0 : return (flag_trapping_math
2334 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2335 :
2336 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2337 : mode);
2338 :
2339 0 : default:
2340 0 : gcc_unreachable ();
2341 : }
2342 2028 : }
2343 :
2344 : /* Handle polynomial integers. */
2345 : else if (CONST_POLY_INT_P (op))
2346 : {
2347 : poly_wide_int result;
2348 : switch (code)
2349 : {
2350 : case NEG:
2351 : result = -const_poly_int_value (op);
2352 : break;
2353 :
2354 : case NOT:
2355 : result = ~const_poly_int_value (op);
2356 : break;
2357 :
2358 : default:
2359 : return NULL_RTX;
2360 : }
2361 : return immed_wide_int_const (result, mode);
2362 : }
2363 :
2364 : return NULL_RTX;
2365 : }
2366 :
2367 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2368 : CODE that can commute with byte swapping, with result mode MODE and
2369 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2370 : Return zero if no simplification or canonicalization is possible. */
2371 :
2372 : rtx
2373 36397313 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2374 : machine_mode mode,
2375 : rtx op0, rtx op1)
2376 : {
2377 36397313 : rtx tem;
2378 :
2379 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2380 36397313 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2381 : {
2382 506 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2383 : simplify_gen_unary (BSWAP, mode, op1, mode));
2384 506 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2385 : }
2386 :
2387 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2388 36396807 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2389 : {
2390 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2391 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2392 : }
2393 :
2394 : return NULL_RTX;
2395 : }
2396 :
2397 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2398 : associative binary operation CODE with result mode MODE, operating
2399 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2400 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2401 : canonicalization is possible. */
2402 :
2403 : rtx
2404 46269060 : simplify_context::simplify_associative_operation (rtx_code code,
2405 : machine_mode mode,
2406 : rtx op0, rtx op1)
2407 : {
2408 46269060 : rtx tem;
2409 :
2410 : /* Normally expressions simplified by simplify-rtx.cc are combined
2411 : at most from a few machine instructions and therefore the
2412 : expressions should be fairly small. During var-tracking
2413 : we can see arbitrarily large expressions though and reassociating
2414 : those can be quadratic, so punt after encountering max_assoc_count
2415 : simplify_associative_operation calls during outermost simplify_*
2416 : call. */
2417 46269060 : if (++assoc_count >= max_assoc_count)
2418 : return NULL_RTX;
2419 :
2420 : /* Linearize the operator to the left. */
2421 46265270 : if (GET_CODE (op1) == code)
2422 : {
2423 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2424 18504 : if (GET_CODE (op0) == code)
2425 : {
2426 4813 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2427 4813 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2428 : }
2429 :
2430 : /* "a op (b op c)" becomes "(b op c) op a". */
2431 13691 : if (! swap_commutative_operands_p (op1, op0))
2432 13691 : return simplify_gen_binary (code, mode, op1, op0);
2433 :
2434 : std::swap (op0, op1);
2435 : }
2436 :
2437 46246766 : if (GET_CODE (op0) == code)
2438 : {
2439 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2440 1283388 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2441 : {
2442 261444 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2443 261444 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2444 : }
2445 :
2446 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2447 1021944 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2448 1021944 : if (tem != 0)
2449 77072 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2450 :
2451 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2452 944872 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2453 944872 : if (tem != 0)
2454 29888 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2455 : }
2456 :
2457 : return 0;
2458 : }
2459 :
2460 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2461 : that represents it (8 if it includes <, 4 if it includes > and 2
2462 : if it includes ==). Return 0 otherwise. */
2463 : static int
2464 18842 : unsigned_comparison_to_mask (rtx_code comparison)
2465 : {
2466 0 : switch (comparison)
2467 : {
2468 : case LTU:
2469 : return 8;
2470 : case GTU:
2471 : return 4;
2472 : case EQ:
2473 : return 2;
2474 :
2475 : case LEU:
2476 : return 10;
2477 : case GEU:
2478 : return 6;
2479 :
2480 : case NE:
2481 : return 12;
2482 :
2483 : default:
2484 : return 0;
2485 : }
2486 : }
2487 :
2488 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2489 : to comparisons. */
2490 : static rtx_code
2491 6584 : mask_to_unsigned_comparison (int mask)
2492 : {
2493 6584 : switch (mask)
2494 : {
2495 : case 8:
2496 : return LTU;
2497 160 : case 4:
2498 160 : return GTU;
2499 2582 : case 2:
2500 2582 : return EQ;
2501 :
2502 160 : case 10:
2503 160 : return LEU;
2504 160 : case 6:
2505 160 : return GEU;
2506 :
2507 3362 : case 12:
2508 3362 : return NE;
2509 :
2510 0 : default:
2511 0 : gcc_unreachable ();
2512 : }
2513 : }
2514 :
2515 : /* Return a mask describing the COMPARISON. */
2516 : static int
2517 2666 : comparison_to_mask (enum rtx_code comparison)
2518 : {
2519 2666 : switch (comparison)
2520 : {
2521 : case LT:
2522 : return 8;
2523 472 : case GT:
2524 472 : return 4;
2525 419 : case EQ:
2526 419 : return 2;
2527 19 : case UNORDERED:
2528 19 : return 1;
2529 :
2530 0 : case LTGT:
2531 0 : return 12;
2532 441 : case LE:
2533 441 : return 10;
2534 441 : case GE:
2535 441 : return 6;
2536 0 : case UNLT:
2537 0 : return 9;
2538 0 : case UNGT:
2539 0 : return 5;
2540 0 : case UNEQ:
2541 0 : return 3;
2542 :
2543 0 : case ORDERED:
2544 0 : return 14;
2545 400 : case NE:
2546 400 : return 13;
2547 0 : case UNLE:
2548 0 : return 11;
2549 0 : case UNGE:
2550 0 : return 7;
2551 :
2552 0 : default:
2553 0 : gcc_unreachable ();
2554 : }
2555 : }
2556 :
2557 : /* Return a comparison corresponding to the MASK. */
2558 : static enum rtx_code
2559 1014 : mask_to_comparison (int mask)
2560 : {
2561 1014 : switch (mask)
2562 : {
2563 : case 8:
2564 : return LT;
2565 : case 4:
2566 : return GT;
2567 : case 2:
2568 : return EQ;
2569 : case 1:
2570 : return UNORDERED;
2571 :
2572 : case 12:
2573 : return LTGT;
2574 : case 10:
2575 : return LE;
2576 : case 6:
2577 : return GE;
2578 : case 9:
2579 : return UNLT;
2580 : case 5:
2581 : return UNGT;
2582 : case 3:
2583 : return UNEQ;
2584 :
2585 : case 14:
2586 : return ORDERED;
2587 : case 13:
2588 : return NE;
2589 : case 11:
2590 : return UNLE;
2591 : case 7:
2592 : return UNGE;
2593 :
2594 0 : default:
2595 0 : gcc_unreachable ();
2596 : }
2597 : }
2598 :
2599 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2600 : false/true value of comparison with MODE where comparison operands
2601 : have CMP_MODE. */
2602 :
2603 : static rtx
2604 783977 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2605 : {
2606 783977 : if (SCALAR_FLOAT_MODE_P (mode))
2607 : {
2608 197 : if (res == const0_rtx)
2609 193 : return CONST0_RTX (mode);
2610 : #ifdef FLOAT_STORE_FLAG_VALUE
2611 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2612 : return const_double_from_real_value (val, mode);
2613 : #else
2614 : return NULL_RTX;
2615 : #endif
2616 : }
2617 783780 : if (VECTOR_MODE_P (mode))
2618 : {
2619 377 : if (res == const0_rtx)
2620 63 : return CONST0_RTX (mode);
2621 : #ifdef VECTOR_STORE_FLAG_VALUE
2622 314 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2623 304 : if (val == NULL_RTX)
2624 : return NULL_RTX;
2625 304 : if (val == const1_rtx)
2626 0 : return CONST1_RTX (mode);
2627 :
2628 304 : return gen_const_vec_duplicate (mode, val);
2629 : #else
2630 : return NULL_RTX;
2631 : #endif
2632 : }
2633 : /* For vector comparison with scalar int result, it is unknown
2634 : if the target means here a comparison into an integral bitmask,
2635 : or comparison where all comparisons true mean const_true_rtx
2636 : whole result, or where any comparisons true mean const_true_rtx
2637 : whole result. For const0_rtx all the cases are the same. */
2638 783403 : if (VECTOR_MODE_P (cmp_mode)
2639 0 : && SCALAR_INT_MODE_P (mode)
2640 0 : && res == const_true_rtx)
2641 0 : return NULL_RTX;
2642 :
2643 : return res;
2644 : }
2645 :
2646 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2647 : and OP1, in the case where both are relational operations. Assume that
2648 : OP0 is inverted if INVERT0_P is true.
2649 :
2650 : Return 0 if no such simplification is possible. */
2651 : rtx
2652 13201961 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2653 : machine_mode mode,
2654 : rtx op0, rtx op1,
2655 : bool invert0_p)
2656 : {
2657 13201961 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2658 : return 0;
2659 :
2660 21396 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2661 9847 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2662 2128 : return 0;
2663 :
2664 9421 : if (side_effects_p (op0))
2665 : return 0;
2666 :
2667 9421 : enum rtx_code code0 = GET_CODE (op0);
2668 9421 : enum rtx_code code1 = GET_CODE (op1);
2669 9421 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2670 9421 : if (cmp_mode == VOIDmode)
2671 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2672 :
2673 : /* Assume at first that the comparisons are on integers, and that the
2674 : operands are therefore ordered. */
2675 9421 : int all = 14;
2676 9421 : int mask0 = unsigned_comparison_to_mask (code0);
2677 9421 : int mask1 = unsigned_comparison_to_mask (code1);
2678 18842 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2679 9421 : || IN_RANGE (mask1 & 12, 4, 8));
2680 1333 : if (unsigned_p)
2681 : {
2682 : /* We only reach here when comparing integers. Reject mixtures of signed
2683 : and unsigned comparisons. */
2684 8088 : if (mask0 == 0 || mask1 == 0)
2685 : return 0;
2686 : }
2687 : else
2688 : {
2689 : /* See whether the operands might be unordered. Assume that all
2690 : results are possible for CC modes, and punt later if we don't get an
2691 : always-true or always-false answer. */
2692 1333 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2693 : all = 15;
2694 1333 : mask0 = comparison_to_mask (code0) & all;
2695 1333 : mask1 = comparison_to_mask (code1) & all;
2696 : }
2697 :
2698 8141 : if (invert0_p)
2699 4650 : mask0 = mask0 ^ all;
2700 :
2701 8141 : int mask;
2702 8141 : if (code == AND)
2703 960 : mask = mask0 & mask1;
2704 7181 : else if (code == IOR)
2705 948 : mask = mask0 | mask1;
2706 6233 : else if (code == XOR)
2707 6233 : mask = mask0 ^ mask1;
2708 : else
2709 : return 0;
2710 :
2711 8141 : if (mask == all)
2712 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2713 :
2714 7909 : if (mask == 0)
2715 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2716 :
2717 7677 : if (unsigned_p)
2718 6584 : code = mask_to_unsigned_comparison (mask);
2719 : else
2720 : {
2721 1093 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2722 : return 0;
2723 :
2724 1014 : code = mask_to_comparison (mask);
2725 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2726 : with NE being the canonical choice. */
2727 1014 : if (code == LTGT && all == 14)
2728 184 : code = NE;
2729 : }
2730 :
2731 7598 : op0 = XEXP (op1, 0);
2732 7598 : op1 = XEXP (op1, 1);
2733 :
2734 7598 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2735 : }
2736 :
2737 : /* We are going to IOR together OP0/OP1. If there is a common term in OP0/OP1
2738 : then we may be able to simplify the expression. We're primarily trying to
2739 : simplify down to IOR/XOR expression right now, but there may be other
2740 : simplifications we can do in the future.
2741 :
2742 : Return the simpified expression or NULL_RTX if no simpification was
2743 : possible. */
2744 : rtx
2745 26925209 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
2746 : {
2747 : /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
2748 : X and C have no bits in common. */
2749 26925209 : if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
2750 228073 : && rtx_equal_p (op0, XEXP (op1, 0))
2751 8318 : && ((nonzero_bits (op0, GET_MODE (op0))
2752 8318 : & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
2753 26925209 : && !side_effects_p (op1))
2754 0 : return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
2755 :
2756 : /* (ior (and A C1) (and (not A) C2)) can be converted
2757 : into (and (xor A C2) (C1 + C2)) when there are no bits
2758 : in common between C1 and C2. */
2759 26925209 : if (GET_CODE (op0) == AND
2760 3993643 : && GET_CODE (op1) == AND
2761 441505 : && GET_CODE (XEXP (op1, 0)) == NOT
2762 24131 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2763 753 : && CONST_INT_P (XEXP (op0, 1))
2764 93 : && CONST_INT_P (XEXP (op1, 1))
2765 26925302 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2766 : {
2767 93 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2768 :
2769 93 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2770 93 : if (tem)
2771 : {
2772 93 : tem = simplify_gen_binary (AND, mode, tem, c);
2773 :
2774 93 : if (tem)
2775 : return tem;
2776 : }
2777 : }
2778 :
2779 : /* Another variant seen on some target particularly those with
2780 : sub-word operations.
2781 :
2782 : (ior (and A C1) (plus (and A C2) C2)) can be simplified into
2783 : (and (xor (A C2) (C1 + C2).
2784 :
2785 : Where C2 is the sign bit for A's mode. So 0x80 for QI,
2786 : 0x8000 for HI, etc. In this case we know there is no carry
2787 : from the PLUS into relevant bits of the output. */
2788 26925116 : if (GET_CODE (op0) == AND
2789 3993550 : && GET_CODE (op1) == PLUS
2790 5793 : && GET_CODE (XEXP (op1, 0)) == AND
2791 288 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2792 276 : && CONST_INT_P (XEXP (op0, 1))
2793 276 : && CONST_INT_P (XEXP (op1, 1))
2794 276 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
2795 276 : && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
2796 72 : && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
2797 144 : && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
2798 144 : == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
2799 26925116 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2800 : {
2801 0 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2802 :
2803 0 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2804 0 : if (tem)
2805 : {
2806 0 : tem = simplify_gen_binary (AND, mode, tem, c);
2807 0 : if (tem)
2808 : return tem;
2809 : }
2810 : }
2811 : return NULL_RTX;
2812 : }
2813 :
2814 :
2815 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2816 : and OP1. Return 0 if no simplification is possible.
2817 :
2818 : Don't use this for relational operations such as EQ or LT.
2819 : Use simplify_relational_operation instead. */
2820 : rtx
2821 474851178 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2822 : rtx op0, rtx op1)
2823 : {
2824 474851178 : rtx trueop0, trueop1;
2825 474851178 : rtx tem;
2826 :
2827 : /* Relational operations don't work here. We must know the mode
2828 : of the operands in order to do the comparison correctly.
2829 : Assuming a full word can give incorrect results.
2830 : Consider comparing 128 with -128 in QImode. */
2831 474851178 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2832 474851178 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2833 :
2834 : /* Make sure the constant is second. */
2835 474851178 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2836 474851178 : && swap_commutative_operands_p (op0, op1))
2837 : std::swap (op0, op1);
2838 :
2839 474851178 : trueop0 = avoid_constant_pool_reference (op0);
2840 474851178 : trueop1 = avoid_constant_pool_reference (op1);
2841 :
2842 474851178 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2843 474851178 : if (tem)
2844 : return tem;
2845 445212661 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2846 :
2847 445212661 : if (tem)
2848 : return tem;
2849 :
2850 : /* If the above steps did not result in a simplification and op0 or op1
2851 : were constant pool references, use the referenced constants directly. */
2852 382550591 : if (trueop0 != op0 || trueop1 != op1)
2853 574058 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2854 :
2855 : return NULL_RTX;
2856 : }
2857 :
2858 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2859 : which OP0 and OP1 are both vector series or vector duplicates
2860 : (which are really just series with a step of 0). If so, try to
2861 : form a new series by applying CODE to the bases and to the steps.
2862 : Return null if no simplification is possible.
2863 :
2864 : MODE is the mode of the operation and is known to be a vector
2865 : integer mode. */
2866 :
2867 : rtx
2868 2344046 : simplify_context::simplify_binary_operation_series (rtx_code code,
2869 : machine_mode mode,
2870 : rtx op0, rtx op1)
2871 : {
2872 2344046 : rtx base0, step0;
2873 2344046 : if (vec_duplicate_p (op0, &base0))
2874 64585 : step0 = const0_rtx;
2875 2279461 : else if (!vec_series_p (op0, &base0, &step0))
2876 : return NULL_RTX;
2877 :
2878 65096 : rtx base1, step1;
2879 65096 : if (vec_duplicate_p (op1, &base1))
2880 417 : step1 = const0_rtx;
2881 64679 : else if (!vec_series_p (op1, &base1, &step1))
2882 : return NULL_RTX;
2883 :
2884 : /* Only create a new series if we can simplify both parts. In other
2885 : cases this isn't really a simplification, and it's not necessarily
2886 : a win to replace a vector operation with a scalar operation. */
2887 3088 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2888 3088 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2889 3088 : if (!new_base)
2890 : return NULL_RTX;
2891 :
2892 2786 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2893 2786 : if (!new_step)
2894 : return NULL_RTX;
2895 :
2896 2786 : return gen_vec_series (mode, new_base, new_step);
2897 : }
2898 :
2899 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2900 : operation CODE with result mode MODE, operating on OP0 and OP1.
2901 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2902 : Returns NULL_RTX if no simplification is possible. */
2903 :
2904 : rtx
2905 1348285 : simplify_context::simplify_distributive_operation (rtx_code code,
2906 : machine_mode mode,
2907 : rtx op0, rtx op1)
2908 : {
2909 1348285 : enum rtx_code op = GET_CODE (op0);
2910 1348285 : gcc_assert (GET_CODE (op1) == op);
2911 :
2912 1348285 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2913 1348285 : && ! side_effects_p (XEXP (op0, 1)))
2914 335783 : return simplify_gen_binary (op, mode,
2915 : simplify_gen_binary (code, mode,
2916 : XEXP (op0, 0),
2917 : XEXP (op1, 0)),
2918 335783 : XEXP (op0, 1));
2919 :
2920 1012502 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2921 : {
2922 993682 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2923 993682 : && ! side_effects_p (XEXP (op0, 0)))
2924 477130 : return simplify_gen_binary (op, mode,
2925 : simplify_gen_binary (code, mode,
2926 : XEXP (op0, 1),
2927 : XEXP (op1, 1)),
2928 477130 : XEXP (op0, 0));
2929 516552 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2930 516552 : && ! side_effects_p (XEXP (op0, 0)))
2931 55 : return simplify_gen_binary (op, mode,
2932 : simplify_gen_binary (code, mode,
2933 : XEXP (op0, 1),
2934 : XEXP (op1, 0)),
2935 55 : XEXP (op0, 0));
2936 516497 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2937 516497 : && ! side_effects_p (XEXP (op0, 1)))
2938 251005 : return simplify_gen_binary (op, mode,
2939 : simplify_gen_binary (code, mode,
2940 : XEXP (op0, 0),
2941 : XEXP (op1, 1)),
2942 251005 : XEXP (op0, 1));
2943 : }
2944 :
2945 : return NULL_RTX;
2946 : }
2947 :
2948 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2949 : should be reversed.
2950 :
2951 : If the rotate should not be reversed, return FALSE.
2952 :
2953 : LEFT indicates if this is a rotate left or a rotate right. */
2954 :
2955 : bool
2956 145559 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2957 : {
2958 145559 : if (!CONST_INT_P (op1))
2959 : return false;
2960 :
2961 : /* Some targets may only be able to rotate by a constant
2962 : in one direction. So we need to query the optab interface
2963 : to see what is possible. */
2964 113664 : optab binoptab = left ? rotl_optab : rotr_optab;
2965 47569 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2966 113664 : enum insn_code icode = optab_handler (binoptab, mode);
2967 113664 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2968 :
2969 : /* If the target can not support the reversed optab, then there
2970 : is nothing to do. */
2971 113664 : if (re_icode == CODE_FOR_nothing)
2972 : return false;
2973 :
2974 : /* If the target does not support the requested rotate-by-immediate,
2975 : then we want to try reversing the rotate. We also want to try
2976 : reversing to minimize the count. */
2977 111206 : if ((icode == CODE_FOR_nothing)
2978 111206 : || (!insn_operand_matches (icode, 2, op1))
2979 556030 : || (IN_RANGE (INTVAL (op1),
2980 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
2981 : GET_MODE_UNIT_PRECISION (mode) - 1)))
2982 14770 : return (insn_operand_matches (re_icode, 2, op1));
2983 : return false;
2984 : }
2985 :
2986 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
2987 : and return the expression to be shifted in SHIFT_OPND and the shift amount
2988 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
2989 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
2990 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
2991 :
2992 : static bool
2993 531581317 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
2994 : {
2995 531581317 : if (GET_CODE (x) == ASHIFT)
2996 : {
2997 13652699 : *shift_opnd = XEXP (x, 0);
2998 13652699 : *shift_amnt = XEXP (x, 1);
2999 13652699 : return true;
3000 : }
3001 517928618 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
3002 : {
3003 13114 : *shift_opnd = XEXP (x, 0);
3004 13114 : *shift_amnt = CONST1_RTX (GET_MODE (x));
3005 13114 : return true;
3006 : }
3007 517915504 : *shift_opnd = NULL_RTX;
3008 517915504 : *shift_amnt = NULL_RTX;
3009 517915504 : return false;
3010 : }
3011 :
3012 : /* OP0 and OP1 are combined under an operation of mode MODE that can
3013 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
3014 : and return the resulting ROTATE expression if so. Return NULL otherwise.
3015 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
3016 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
3017 : (X << C1) and (C >> C2) would be OP0 and OP1. */
3018 :
3019 : static rtx
3020 267873031 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
3021 : {
3022 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3023 : mode size to (rotate A CX). */
3024 :
3025 267873031 : rtx opleft = op0;
3026 267873031 : rtx opright = op1;
3027 267873031 : rtx ashift_opnd, ashift_amnt;
3028 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
3029 : the relevant operands here. */
3030 267873031 : bool ashift_op_p
3031 267873031 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
3032 :
3033 267873031 : if (ashift_op_p
3034 266265556 : || GET_CODE (op1) == SUBREG)
3035 : {
3036 : opleft = op1;
3037 : opright = op0;
3038 : }
3039 : else
3040 : {
3041 263708286 : opright = op1;
3042 263708286 : opleft = op0;
3043 263708286 : ashift_op_p
3044 263708286 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
3045 : }
3046 :
3047 13665813 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
3048 266309009 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
3049 : {
3050 9707 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
3051 9707 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
3052 :
3053 5889 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
3054 15596 : && (INTVAL (leftcst) + INTVAL (rightcst)
3055 5889 : == GET_MODE_UNIT_PRECISION (mode)))
3056 5362 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
3057 : }
3058 :
3059 : /* Same, but for ashift that has been "simplified" to a wider mode
3060 : by simplify_shift_const. */
3061 267867669 : scalar_int_mode int_mode, inner_mode;
3062 :
3063 267867669 : if (GET_CODE (opleft) == SUBREG
3064 271388090 : && is_a <scalar_int_mode> (mode, &int_mode)
3065 3515059 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3066 : &inner_mode)
3067 3483849 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3068 101133 : && GET_CODE (opright) == LSHIFTRT
3069 1108 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3070 251 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3071 498 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3072 235 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3073 235 : SUBREG_REG (XEXP (opright, 0)))
3074 19 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3075 19 : && CONST_INT_P (XEXP (opright, 1))
3076 267867669 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3077 19 : + INTVAL (XEXP (opright, 1))
3078 19 : == GET_MODE_PRECISION (int_mode)))
3079 15 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3080 : XEXP (SUBREG_REG (opleft), 1));
3081 : return NULL_RTX;
3082 : }
3083 :
3084 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3085 : and the pattern can be simplified (there are no side effects). */
3086 :
3087 : static bool
3088 38418880 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3089 : {
3090 : /* Remove SUBREG from OP0 and OP1, if needed. */
3091 38418880 : if (GET_CODE (op0) == SUBREG
3092 6920858 : && GET_CODE (op1) == SUBREG
3093 311012 : && subreg_lowpart_p (op0)
3094 38728492 : && subreg_lowpart_p (op1))
3095 : {
3096 309603 : op0 = XEXP (op0, 0);
3097 309603 : op1 = XEXP (op1, 0);
3098 : }
3099 :
3100 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3101 38418880 : if (((GET_CODE (op1) == NEG
3102 3721 : && GET_CODE (op0) == PLUS
3103 2204 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3104 38418218 : || (GET_CODE (op0) == NEG
3105 79944 : && GET_CODE (op1) == PLUS
3106 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3107 662 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3108 38418882 : && !side_effects_p (XEXP (op0, 0)))
3109 : return true;
3110 : return false;
3111 : }
3112 :
3113 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3114 : non-paradoxical. */
3115 :
3116 : static bool
3117 72796912 : non_paradoxical_subreg_not_p (rtx op)
3118 : {
3119 72796912 : return GET_CODE (op) == SUBREG
3120 8451821 : && !paradoxical_subreg_p (op)
3121 75721961 : && GET_CODE (SUBREG_REG (op)) == NOT;
3122 : }
3123 :
3124 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3125 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3126 : opportunities to combine another binary logical operation with NOT. */
3127 :
3128 : static rtx
3129 36399631 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3130 : {
3131 36399631 : rtx opn = NULL_RTX;
3132 36399631 : if (non_paradoxical_subreg_not_p (op0))
3133 : opn = op0;
3134 36397281 : else if (non_paradoxical_subreg_not_p (op1))
3135 : opn = op1;
3136 :
3137 2373 : if (opn == NULL_RTX)
3138 : return NULL_RTX;
3139 :
3140 4746 : rtx new_subreg = simplify_gen_subreg (mode,
3141 : XEXP (SUBREG_REG (opn), 0),
3142 2373 : GET_MODE (SUBREG_REG (opn)),
3143 2373 : SUBREG_BYTE (opn));
3144 :
3145 2373 : if (!new_subreg)
3146 : return NULL_RTX;
3147 :
3148 2318 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3149 2318 : if (opn == op0)
3150 2295 : return simplify_gen_binary (binop, mode, new_not, op1);
3151 : else
3152 23 : return simplify_gen_binary (binop, mode, op0, new_not);
3153 : }
3154 :
3155 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3156 : static bool
3157 6647554 : negated_ops_p (rtx nop, rtx op)
3158 : {
3159 : /* Explicit negation. */
3160 6647554 : if (GET_CODE (nop) == NOT
3161 6647554 : && rtx_equal_p (XEXP (nop, 0), op))
3162 : return true;
3163 6644202 : if (GET_CODE (op) == NOT
3164 6644202 : && rtx_equal_p (XEXP (op, 0), nop))
3165 : return true;
3166 :
3167 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3168 6643616 : if (GET_CODE (op) == ASHIFT
3169 1376121 : && GET_CODE (nop) == ROTATE
3170 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3171 0 : && CONST_INT_P (XEXP (nop, 0))
3172 0 : && INTVAL (XEXP (nop, 0)) == -2
3173 6643616 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3174 : return true;
3175 6643616 : if (GET_CODE (nop) == ASHIFT
3176 167338 : && GET_CODE (op) == ROTATE
3177 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3178 0 : && CONST_INT_P (XEXP (nop, 0))
3179 0 : && INTVAL (XEXP (nop, 0)) == -2
3180 6643616 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3181 : return true;
3182 :
3183 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3184 :
3185 : return false;
3186 : }
3187 :
3188 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3189 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3190 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3191 : actual constants. */
3192 :
3193 : rtx
3194 445212661 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3195 : machine_mode mode,
3196 : rtx op0, rtx op1,
3197 : rtx trueop0, rtx trueop1)
3198 : {
3199 445212661 : rtx tem, reversed, elt0, elt1;
3200 445212661 : HOST_WIDE_INT val;
3201 445212661 : scalar_int_mode int_mode, inner_mode;
3202 445212661 : poly_int64 offset;
3203 :
3204 : /* Even if we can't compute a constant result,
3205 : there are some cases worth simplifying. */
3206 :
3207 445212661 : switch (code)
3208 : {
3209 257710285 : case PLUS:
3210 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3211 : when x is NaN, infinite, or finite and nonzero. They aren't
3212 : when x is -0 and the rounding mode is not towards -infinity,
3213 : since (-0) + 0 is then 0. */
3214 511522987 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3215 511522975 : && trueop1 == CONST0_RTX (mode))
3216 : return op0;
3217 :
3218 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3219 : transformations are safe even for IEEE. */
3220 256417198 : if (GET_CODE (op0) == NEG)
3221 26000 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3222 256391198 : else if (GET_CODE (op1) == NEG)
3223 7461 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3224 :
3225 : /* (~a) + 1 -> -a */
3226 256383737 : if (INTEGRAL_MODE_P (mode)
3227 251583464 : && GET_CODE (op0) == NOT
3228 622846 : && trueop1 == const1_rtx)
3229 3912 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3230 :
3231 : /* Handle both-operands-constant cases. We can only add
3232 : CONST_INTs to constants since the sum of relocatable symbols
3233 : can't be handled by most assemblers. Don't add CONST_INT
3234 : to CONST_INT since overflow won't be computed properly if wider
3235 : than HOST_BITS_PER_WIDE_INT. */
3236 :
3237 256379825 : if ((GET_CODE (op0) == CONST
3238 256379825 : || GET_CODE (op0) == SYMBOL_REF
3239 253740900 : || GET_CODE (op0) == LABEL_REF)
3240 256379825 : && poly_int_rtx_p (op1, &offset))
3241 2637956 : return plus_constant (mode, op0, offset);
3242 253741869 : else if ((GET_CODE (op1) == CONST
3243 253741869 : || GET_CODE (op1) == SYMBOL_REF
3244 249442416 : || GET_CODE (op1) == LABEL_REF)
3245 253741869 : && poly_int_rtx_p (op0, &offset))
3246 0 : return plus_constant (mode, op1, offset);
3247 :
3248 : /* See if this is something like X * C - X or vice versa or
3249 : if the multiplication is written as a shift. If so, we can
3250 : distribute and make a new multiply, shift, or maybe just
3251 : have X (if C is 2 in the example above). But don't make
3252 : something more expensive than we had before. */
3253 :
3254 253741869 : if (is_a <scalar_int_mode> (mode, &int_mode))
3255 : {
3256 246851251 : rtx lhs = op0, rhs = op1;
3257 :
3258 246851251 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3259 246851251 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3260 :
3261 246851251 : if (GET_CODE (lhs) == NEG)
3262 : {
3263 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3264 0 : lhs = XEXP (lhs, 0);
3265 : }
3266 246851251 : else if (GET_CODE (lhs) == MULT
3267 9809747 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3268 : {
3269 8707054 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3270 8707054 : lhs = XEXP (lhs, 0);
3271 : }
3272 238144197 : else if (GET_CODE (lhs) == ASHIFT
3273 11030492 : && CONST_INT_P (XEXP (lhs, 1))
3274 10958765 : && INTVAL (XEXP (lhs, 1)) >= 0
3275 249102950 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3276 : {
3277 10958753 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3278 21917506 : GET_MODE_PRECISION (int_mode));
3279 10958753 : lhs = XEXP (lhs, 0);
3280 : }
3281 :
3282 246851251 : if (GET_CODE (rhs) == NEG)
3283 : {
3284 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3285 0 : rhs = XEXP (rhs, 0);
3286 : }
3287 246851251 : else if (GET_CODE (rhs) == MULT
3288 304431 : && CONST_INT_P (XEXP (rhs, 1)))
3289 : {
3290 193824 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3291 193824 : rhs = XEXP (rhs, 0);
3292 : }
3293 246657427 : else if (GET_CODE (rhs) == ASHIFT
3294 541752 : && CONST_INT_P (XEXP (rhs, 1))
3295 531971 : && INTVAL (XEXP (rhs, 1)) >= 0
3296 247189398 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3297 : {
3298 531971 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3299 1063942 : GET_MODE_PRECISION (int_mode));
3300 531971 : rhs = XEXP (rhs, 0);
3301 : }
3302 :
3303 : /* Keep PLUS of 2 volatile memory references. */
3304 246851251 : if (rtx_equal_p (lhs, rhs)
3305 246851251 : && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
3306 : {
3307 835394 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3308 835394 : rtx coeff;
3309 835394 : bool speed = optimize_function_for_speed_p (cfun);
3310 :
3311 835394 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3312 :
3313 835394 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3314 835394 : return (set_src_cost (tem, int_mode, speed)
3315 835394 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3316 : }
3317 :
3318 : /* Optimize (X - 1) * Y + Y to X * Y. */
3319 246015857 : lhs = op0;
3320 246015857 : rhs = op1;
3321 246015857 : if (GET_CODE (op0) == MULT)
3322 : {
3323 9756206 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3324 639879 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3325 9713416 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3326 51614 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3327 9798996 : && rtx_equal_p (XEXP (op0, 1), op1))
3328 94 : lhs = XEXP (XEXP (op0, 0), 0);
3329 9756112 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3330 1287 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3331 9756078 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3332 339 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3333 9756146 : && rtx_equal_p (XEXP (op0, 0), op1))
3334 0 : lhs = XEXP (XEXP (op0, 1), 0);
3335 : }
3336 236259651 : else if (GET_CODE (op1) == MULT)
3337 : {
3338 136985 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3339 47 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3340 136980 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3341 27 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3342 136990 : && rtx_equal_p (XEXP (op1, 1), op0))
3343 0 : rhs = XEXP (XEXP (op1, 0), 0);
3344 136985 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3345 0 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3346 136985 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3347 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3348 136985 : && rtx_equal_p (XEXP (op1, 0), op0))
3349 0 : rhs = XEXP (XEXP (op1, 1), 0);
3350 : }
3351 246015857 : if (lhs != op0 || rhs != op1)
3352 94 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3353 246851251 : }
3354 :
3355 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3356 252906381 : if (CONST_SCALAR_INT_P (op1)
3357 192583052 : && GET_CODE (op0) == XOR
3358 18726 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3359 252916611 : && mode_signbit_p (mode, op1))
3360 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3361 : simplify_gen_binary (XOR, mode, op1,
3362 121 : XEXP (op0, 1)));
3363 :
3364 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3365 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3366 252906260 : if (CONST_SCALAR_INT_P (op1)
3367 192582931 : && GET_CODE (op0) == XOR
3368 18605 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3369 10109 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3370 191 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3371 252906260 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3372 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3373 : simplify_gen_binary (XOR, mode, op1,
3374 0 : XEXP (op0, 1)));
3375 :
3376 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3377 252906260 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3378 252903780 : && GET_CODE (op0) == MULT
3379 263027220 : && GET_CODE (XEXP (op0, 0)) == NEG)
3380 : {
3381 5660 : rtx in1, in2;
3382 :
3383 5660 : in1 = XEXP (XEXP (op0, 0), 0);
3384 5660 : in2 = XEXP (op0, 1);
3385 5660 : return simplify_gen_binary (MINUS, mode, op1,
3386 : simplify_gen_binary (MULT, mode,
3387 5660 : in1, in2));
3388 : }
3389 :
3390 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3391 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3392 : is 1. */
3393 252900600 : if (COMPARISON_P (op0)
3394 1247437 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3395 1247437 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3396 252956611 : && (reversed = reversed_comparison (op0, mode)))
3397 55662 : return
3398 55662 : simplify_gen_unary (NEG, mode, reversed, mode);
3399 :
3400 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3401 : mode size to (rotate A CX). */
3402 252844938 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3403 : return tem;
3404 :
3405 : /* If one of the operands is a PLUS or a MINUS, see if we can
3406 : simplify this by the associative law.
3407 : Don't use the associative law for floating point.
3408 : The inaccuracy makes it nonassociative,
3409 : and subtle programs can break if operations are associated. */
3410 :
3411 252843468 : if (INTEGRAL_MODE_P (mode)
3412 248043244 : && (plus_minus_operand_p (op0)
3413 214132714 : || plus_minus_operand_p (op1))
3414 35023667 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3415 : return tem;
3416 :
3417 : /* Reassociate floating point addition only when the user
3418 : specifies associative math operations. */
3419 218532723 : if (FLOAT_MODE_P (mode)
3420 4800224 : && flag_associative_math)
3421 : {
3422 902621 : tem = simplify_associative_operation (code, mode, op0, op1);
3423 902621 : if (tem)
3424 : return tem;
3425 : }
3426 :
3427 : /* Handle vector series. */
3428 218519162 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3429 : {
3430 1924915 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3431 1924915 : if (tem)
3432 : return tem;
3433 : }
3434 : break;
3435 :
3436 : case COMPARE:
3437 : break;
3438 :
3439 41466800 : case MINUS:
3440 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3441 : but since it is zero except in very strange circumstances, we
3442 : will treat it as zero with -ffinite-math-only. */
3443 41466800 : if (rtx_equal_p (trueop0, trueop1)
3444 215076 : && ! side_effects_p (op0)
3445 41680639 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3446 211381 : return CONST0_RTX (mode);
3447 :
3448 : /* Change subtraction from zero into negation. (0 - x) is the
3449 : same as -x when x is NaN, infinite, or finite and nonzero.
3450 : But if the mode has signed zeros, and does not round towards
3451 : -infinity, then 0 - 0 is 0, not -0. */
3452 41255419 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3453 309844 : return simplify_gen_unary (NEG, mode, op1, mode);
3454 :
3455 : /* (-1 - a) is ~a, unless the expression contains symbolic
3456 : constants, in which case not retaining additions and
3457 : subtractions could cause invalid assembly to be produced. */
3458 40945575 : if (trueop0 == CONSTM1_RTX (mode)
3459 40945575 : && !contains_symbolic_reference_p (op1))
3460 348819 : return simplify_gen_unary (NOT, mode, op1, mode);
3461 :
3462 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3463 : or has signed zeros and supports rounding towards -infinity.
3464 : In such a case, 0 - 0 is -0. */
3465 41291347 : if (!(HONOR_SIGNED_ZEROS (mode)
3466 694591 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3467 40595550 : && !HONOR_SNANS (mode)
3468 81192270 : && trueop1 == CONST0_RTX (mode))
3469 : return op0;
3470 :
3471 : /* See if this is something like X * C - X or vice versa or
3472 : if the multiplication is written as a shift. If so, we can
3473 : distribute and make a new multiply, shift, or maybe just
3474 : have X (if C is 2 in the example above). But don't make
3475 : something more expensive than we had before. */
3476 :
3477 39652190 : if (is_a <scalar_int_mode> (mode, &int_mode))
3478 : {
3479 38398028 : rtx lhs = op0, rhs = op1;
3480 :
3481 38398028 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3482 38398028 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3483 :
3484 38398028 : if (GET_CODE (lhs) == NEG)
3485 : {
3486 70198 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3487 70198 : lhs = XEXP (lhs, 0);
3488 : }
3489 38327830 : else if (GET_CODE (lhs) == MULT
3490 226890 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3491 : {
3492 81183 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3493 81183 : lhs = XEXP (lhs, 0);
3494 : }
3495 38246647 : else if (GET_CODE (lhs) == ASHIFT
3496 326842 : && CONST_INT_P (XEXP (lhs, 1))
3497 323591 : && INTVAL (XEXP (lhs, 1)) >= 0
3498 38570217 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3499 : {
3500 323570 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3501 647140 : GET_MODE_PRECISION (int_mode));
3502 323570 : lhs = XEXP (lhs, 0);
3503 : }
3504 :
3505 38398028 : if (GET_CODE (rhs) == NEG)
3506 : {
3507 11163 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3508 11163 : rhs = XEXP (rhs, 0);
3509 : }
3510 38386865 : else if (GET_CODE (rhs) == MULT
3511 121175 : && CONST_INT_P (XEXP (rhs, 1)))
3512 : {
3513 87773 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3514 87773 : rhs = XEXP (rhs, 0);
3515 : }
3516 38299092 : else if (GET_CODE (rhs) == ASHIFT
3517 376868 : && CONST_INT_P (XEXP (rhs, 1))
3518 376359 : && INTVAL (XEXP (rhs, 1)) >= 0
3519 38675451 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3520 : {
3521 376359 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3522 752718 : GET_MODE_PRECISION (int_mode));
3523 376359 : negcoeff1 = -negcoeff1;
3524 376359 : rhs = XEXP (rhs, 0);
3525 : }
3526 :
3527 38398028 : if (rtx_equal_p (lhs, rhs))
3528 : {
3529 100983 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3530 100983 : rtx coeff;
3531 100983 : bool speed = optimize_function_for_speed_p (cfun);
3532 :
3533 100983 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3534 :
3535 100983 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3536 100983 : return (set_src_cost (tem, int_mode, speed)
3537 100983 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3538 : }
3539 :
3540 : /* Optimize (X + 1) * Y - Y to X * Y. */
3541 38297045 : lhs = op0;
3542 38297045 : if (GET_CODE (op0) == MULT)
3543 : {
3544 226450 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3545 4795 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3546 224868 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3547 1811 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3548 228032 : && rtx_equal_p (XEXP (op0, 1), op1))
3549 2 : lhs = XEXP (XEXP (op0, 0), 0);
3550 226448 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3551 26 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3552 226442 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3553 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3554 226454 : && rtx_equal_p (XEXP (op0, 0), op1))
3555 0 : lhs = XEXP (XEXP (op0, 1), 0);
3556 : }
3557 38297045 : if (lhs != op0)
3558 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3559 38398028 : }
3560 :
3561 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3562 39551205 : if (GET_CODE (op1) == NEG)
3563 11125 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3564 :
3565 : /* (-x - c) may be simplified as (-c - x). */
3566 39540080 : if (GET_CODE (op0) == NEG
3567 74337 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3568 : {
3569 619 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3570 619 : if (tem)
3571 619 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3572 : }
3573 :
3574 39539461 : if ((GET_CODE (op0) == CONST
3575 39539461 : || GET_CODE (op0) == SYMBOL_REF
3576 34556270 : || GET_CODE (op0) == LABEL_REF)
3577 39539461 : && poly_int_rtx_p (op1, &offset))
3578 50505 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3579 :
3580 : /* Don't let a relocatable value get a negative coeff. */
3581 39488956 : if (is_a <scalar_int_mode> (mode)
3582 38234825 : && poly_int_rtx_p (op1)
3583 46447149 : && GET_MODE (op0) != VOIDmode)
3584 6958193 : return simplify_gen_binary (PLUS, mode,
3585 : op0,
3586 6958193 : neg_poly_int_rtx (mode, op1));
3587 :
3588 : /* (x - (x & y)) -> (x & ~y) */
3589 32530763 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3590 : {
3591 264417 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3592 : {
3593 496 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3594 248 : GET_MODE (XEXP (op1, 1)));
3595 248 : return simplify_gen_binary (AND, mode, op0, tem);
3596 : }
3597 264169 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3598 : {
3599 2236 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3600 1118 : GET_MODE (XEXP (op1, 0)));
3601 1118 : return simplify_gen_binary (AND, mode, op0, tem);
3602 : }
3603 : }
3604 :
3605 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3606 : by reversing the comparison code if valid. */
3607 32529397 : if (STORE_FLAG_VALUE == 1
3608 32529397 : && trueop0 == const1_rtx
3609 1112761 : && COMPARISON_P (op1)
3610 32634628 : && (reversed = reversed_comparison (op1, mode)))
3611 : return reversed;
3612 :
3613 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3614 32424189 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3615 32422782 : && GET_CODE (op1) == MULT
3616 32644694 : && GET_CODE (XEXP (op1, 0)) == NEG)
3617 : {
3618 165 : rtx in1, in2;
3619 :
3620 165 : in1 = XEXP (XEXP (op1, 0), 0);
3621 165 : in2 = XEXP (op1, 1);
3622 165 : return simplify_gen_binary (PLUS, mode,
3623 : simplify_gen_binary (MULT, mode,
3624 : in1, in2),
3625 165 : op0);
3626 : }
3627 :
3628 : /* Canonicalize (minus (neg A) (mult B C)) to
3629 : (minus (mult (neg B) C) A). */
3630 32424024 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3631 32422617 : && GET_CODE (op1) == MULT
3632 32644364 : && GET_CODE (op0) == NEG)
3633 : {
3634 655 : rtx in1, in2;
3635 :
3636 655 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3637 655 : in2 = XEXP (op1, 1);
3638 655 : return simplify_gen_binary (MINUS, mode,
3639 : simplify_gen_binary (MULT, mode,
3640 : in1, in2),
3641 655 : XEXP (op0, 0));
3642 : }
3643 :
3644 : /* If one of the operands is a PLUS or a MINUS, see if we can
3645 : simplify this by the associative law. This will, for example,
3646 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3647 : Don't use the associative law for floating point.
3648 : The inaccuracy makes it nonassociative,
3649 : and subtle programs can break if operations are associated. */
3650 :
3651 32423369 : if (INTEGRAL_MODE_P (mode)
3652 31609177 : && (plus_minus_operand_p (op0)
3653 29033755 : || plus_minus_operand_p (op1))
3654 3758892 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3655 : return tem;
3656 :
3657 : /* Handle vector series. */
3658 28799070 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3659 : {
3660 419131 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3661 419131 : if (tem)
3662 : return tem;
3663 : }
3664 : break;
3665 :
3666 12129875 : case MULT:
3667 12129875 : if (trueop1 == constm1_rtx)
3668 33060 : return simplify_gen_unary (NEG, mode, op0, mode);
3669 :
3670 12096815 : if (GET_CODE (op0) == NEG)
3671 : {
3672 33204 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3673 : /* If op1 is a MULT as well and simplify_unary_operation
3674 : just moved the NEG to the second operand, simplify_gen_binary
3675 : below could through simplify_associative_operation move
3676 : the NEG around again and recurse endlessly. */
3677 33204 : if (temp
3678 1564 : && GET_CODE (op1) == MULT
3679 0 : && GET_CODE (temp) == MULT
3680 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3681 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3682 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3683 : temp = NULL_RTX;
3684 : if (temp)
3685 1564 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3686 : }
3687 12095251 : if (GET_CODE (op1) == NEG)
3688 : {
3689 887 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3690 : /* If op0 is a MULT as well and simplify_unary_operation
3691 : just moved the NEG to the second operand, simplify_gen_binary
3692 : below could through simplify_associative_operation move
3693 : the NEG around again and recurse endlessly. */
3694 887 : if (temp
3695 421 : && GET_CODE (op0) == MULT
3696 300 : && GET_CODE (temp) == MULT
3697 300 : && XEXP (op0, 0) == XEXP (temp, 0)
3698 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3699 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3700 : temp = NULL_RTX;
3701 : if (temp)
3702 416 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3703 : }
3704 :
3705 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3706 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3707 : when the mode has signed zeros, since multiplying a negative
3708 : number by 0 will give -0, not 0. */
3709 12094835 : if (!HONOR_NANS (mode)
3710 11143898 : && !HONOR_SIGNED_ZEROS (mode)
3711 11143455 : && trueop1 == CONST0_RTX (mode)
3712 12136665 : && ! side_effects_p (op0))
3713 : return op1;
3714 :
3715 : /* In IEEE floating point, x*1 is not equivalent to x for
3716 : signalling NaNs. */
3717 12054244 : if (!HONOR_SNANS (mode)
3718 12054244 : && trueop1 == CONST1_RTX (mode))
3719 : return op0;
3720 :
3721 : /* Convert multiply by constant power of two into shift. */
3722 11539593 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3723 : {
3724 6274282 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3725 6274282 : if (val >= 0)
3726 2998427 : return simplify_gen_binary (ASHIFT, mode, op0,
3727 2998427 : gen_int_shift_amount (mode, val));
3728 : }
3729 :
3730 : /* x*2 is x+x and x*(-1) is -x */
3731 8541166 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3732 165731 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3733 165731 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3734 165447 : && GET_MODE (op0) == mode)
3735 : {
3736 165447 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3737 :
3738 165447 : if (real_equal (d1, &dconst2))
3739 615 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3740 :
3741 164832 : if (!HONOR_SNANS (mode)
3742 164832 : && real_equal (d1, &dconstm1))
3743 24 : return simplify_gen_unary (NEG, mode, op0, mode);
3744 : }
3745 :
3746 : /* Optimize -x * -x as x * x. */
3747 8540527 : if (FLOAT_MODE_P (mode)
3748 1368741 : && GET_CODE (op0) == NEG
3749 7905 : && GET_CODE (op1) == NEG
3750 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3751 0 : && !side_effects_p (XEXP (op0, 0)))
3752 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3753 :
3754 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3755 8540527 : if (SCALAR_FLOAT_MODE_P (mode)
3756 1082735 : && GET_CODE (op0) == ABS
3757 1329 : && GET_CODE (op1) == ABS
3758 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3759 8540527 : && !side_effects_p (XEXP (op0, 0)))
3760 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3761 :
3762 : /* Reassociate multiplication, but for floating point MULTs
3763 : only when the user specifies unsafe math optimizations. */
3764 8540527 : if (! FLOAT_MODE_P (mode)
3765 1368741 : || flag_unsafe_math_optimizations)
3766 : {
3767 7590700 : tem = simplify_associative_operation (code, mode, op0, op1);
3768 7590700 : if (tem)
3769 : return tem;
3770 : }
3771 : break;
3772 :
3773 14868935 : case IOR:
3774 14868935 : if (trueop1 == CONST0_RTX (mode))
3775 : return op0;
3776 14087384 : if (INTEGRAL_MODE_P (mode)
3777 13812676 : && trueop1 == CONSTM1_RTX (mode)
3778 9612 : && !side_effects_p (op0))
3779 : return op1;
3780 14077772 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3781 : return op0;
3782 : /* A | (~A) -> -1 */
3783 74987 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3784 14058896 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3785 11 : && ! side_effects_p (op0)
3786 14058918 : && GET_MODE_CLASS (mode) != MODE_CC)
3787 11 : return CONSTM1_RTX (mode);
3788 :
3789 : /* IOR of two single bit bitfields extracted from the same object.
3790 : Bitfields are represented as an AND based extraction */
3791 14058896 : if (GET_CODE (op0) == AND
3792 3998235 : && GET_CODE (op1) == AND
3793 : /* Verify both AND operands are logical right shifts. */
3794 311996 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3795 5161 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3796 : /* Verify both bitfields are extracted from the same object. */
3797 54 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3798 : /* Verify both fields are a single bit (could be generalized). */
3799 54 : && XEXP (op0, 1) == CONST1_RTX (mode)
3800 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3801 : /* Verify bit positions (for cases with variable bit position). */
3802 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3803 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3804 : {
3805 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3806 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3807 0 : unsigned HOST_WIDE_INT mask
3808 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3809 :
3810 0 : rtx m = GEN_INT (mask);
3811 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3812 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3813 0 : return t;
3814 : }
3815 :
3816 : /* IOR of multiple single bit bitfields extracted from the same object
3817 : (building on previous case).
3818 : First bitfield is represented as an AND based extraction, as done
3819 : above. Second represented as NE based extraction, from
3820 : output above. */
3821 14058896 : if (GET_CODE (op0) == AND
3822 3998235 : && GET_CODE (op1) == NE
3823 : /* Verify AND operand is logical right shift. */
3824 4586 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3825 : /* Verify NE operand is an AND (based on output above). */
3826 86 : && GET_CODE (XEXP (op1, 0)) == AND
3827 : /* Verify both bitfields are extracted from the same object. */
3828 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3829 : /* Verify masking is with a single bit and that we have a NE 0
3830 : comparison for the other operand. */
3831 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3832 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3833 : /* Verify bit position. */
3834 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3835 : {
3836 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3837 0 : unsigned HOST_WIDE_INT mask
3838 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3839 :
3840 0 : rtx m = GEN_INT (mask);
3841 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3842 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3843 0 : return t;
3844 : }
3845 :
3846 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3847 14058896 : if (match_plus_neg_pattern (op0, op1, mode))
3848 0 : return CONSTM1_RTX (mode);
3849 :
3850 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3851 14058896 : if (CONST_INT_P (op1)
3852 3443927 : && HWI_COMPUTABLE_MODE_P (mode)
3853 3386371 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3854 14424931 : && !side_effects_p (op0))
3855 : return op1;
3856 :
3857 : /* Canonicalize (X & C1) | C2. */
3858 13692861 : if (GET_CODE (op0) == AND
3859 3989666 : && CONST_INT_P (trueop1)
3860 654356 : && CONST_INT_P (XEXP (op0, 1)))
3861 : {
3862 495768 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3863 495768 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3864 495768 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3865 :
3866 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3867 495768 : if ((c1 & c2) == c1
3868 495768 : && !side_effects_p (XEXP (op0, 0)))
3869 : return trueop1;
3870 :
3871 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3872 495748 : if (((c1|c2) & mask) == mask)
3873 70076 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3874 :
3875 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3876 : when split it'll match a single bit clear style insn.
3877 :
3878 : This could have been done with a target dependent splitter, but
3879 : then every target with single bit manipulation insns would need
3880 : to implement such splitters. */
3881 425672 : if (exact_log2 (~(c1 | c2)) >= 0)
3882 : {
3883 58511 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3884 58511 : temp = gen_rtx_IOR (mode, temp, trueop1);
3885 58511 : return temp;
3886 : }
3887 : }
3888 :
3889 : /* Convert (A & B) | A to A. */
3890 13564254 : if (GET_CODE (op0) == AND
3891 3861059 : && (rtx_equal_p (XEXP (op0, 0), op1)
3892 3860948 : || rtx_equal_p (XEXP (op0, 1), op1))
3893 3765 : && ! side_effects_p (XEXP (op0, 0))
3894 13568019 : && ! side_effects_p (XEXP (op0, 1)))
3895 : return op1;
3896 :
3897 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3898 : mode size to (rotate A CX). */
3899 13560489 : tem = simplify_rotate_op (op0, op1, mode);
3900 13560489 : if (tem)
3901 : return tem;
3902 :
3903 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3904 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3905 : the PLUS does not affect any of the bits in OP1: then we can do
3906 : the IOR as a PLUS and we can associate. This is valid if OP1
3907 : can be safely shifted left C bits. */
3908 13557962 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3909 6273 : && GET_CODE (XEXP (op0, 0)) == PLUS
3910 141 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3911 87 : && CONST_INT_P (XEXP (op0, 1))
3912 87 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3913 : {
3914 87 : int count = INTVAL (XEXP (op0, 1));
3915 87 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3916 :
3917 87 : if (mask >> count == INTVAL (trueop1)
3918 80 : && trunc_int_for_mode (mask, mode) == mask
3919 154 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3920 0 : return simplify_gen_binary (ASHIFTRT, mode,
3921 : plus_constant (mode, XEXP (op0, 0),
3922 0 : mask),
3923 : XEXP (op0, 1));
3924 : }
3925 :
3926 : /* The following happens with bitfield merging.
3927 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3928 13557962 : if (GET_CODE (op0) == AND
3929 3857294 : && GET_CODE (op1) == AND
3930 311996 : && CONST_INT_P (XEXP (op0, 1))
3931 143539 : && CONST_INT_P (XEXP (op1, 1))
3932 138123 : && (INTVAL (XEXP (op0, 1))
3933 138123 : == ~INTVAL (XEXP (op1, 1))))
3934 : {
3935 : /* The IOR/XOR may be on both sides. */
3936 31954 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3937 31954 : if (GET_CODE (XEXP (op1, 0)) == IOR
3938 31954 : || GET_CODE (XEXP (op1, 0)) == XOR)
3939 : top0 = op0, top1 = op1;
3940 31835 : else if (GET_CODE (XEXP (op0, 0)) == IOR
3941 31835 : || GET_CODE (XEXP (op0, 0)) == XOR)
3942 3 : top0 = op1, top1 = op0;
3943 31954 : if (top0 && top1)
3944 : {
3945 : /* X may be on either side of the inner IOR/XOR. */
3946 122 : rtx tem = NULL_RTX;
3947 122 : if (rtx_equal_p (XEXP (top0, 0),
3948 122 : XEXP (XEXP (top1, 0), 0)))
3949 76 : tem = XEXP (XEXP (top1, 0), 1);
3950 46 : else if (rtx_equal_p (XEXP (top0, 0),
3951 46 : XEXP (XEXP (top1, 0), 1)))
3952 13 : tem = XEXP (XEXP (top1, 0), 0);
3953 89 : if (tem)
3954 89 : return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
3955 : mode, XEXP (top0, 0),
3956 : simplify_gen_binary
3957 89 : (AND, mode, tem, XEXP (top1, 1)));
3958 : }
3959 : }
3960 :
3961 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3962 13557873 : if (GET_CODE (op0) == GET_CODE (op1)
3963 3408884 : && (GET_CODE (op0) == AND
3964 : || GET_CODE (op0) == IOR
3965 3408884 : || GET_CODE (op0) == LSHIFTRT
3966 3095994 : || GET_CODE (op0) == ASHIFTRT
3967 3095864 : || GET_CODE (op0) == ASHIFT
3968 3078708 : || GET_CODE (op0) == ROTATE
3969 3078708 : || GET_CODE (op0) == ROTATERT))
3970 : {
3971 330176 : tem = simplify_distributive_operation (code, mode, op0, op1);
3972 330176 : if (tem)
3973 : return tem;
3974 : }
3975 :
3976 : /* Convert (ior (and (not A) B) A) into A | B. */
3977 13466571 : if (GET_CODE (op0) == AND
3978 13466571 : && negated_ops_p (XEXP (op0, 0), op1))
3979 3920 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
3980 :
3981 : /* op0/op1 may have a common term which in turn may allow simplification
3982 : of the the outer IOR. There are likely other cases we should
3983 : handle for the outer code as well as the form of the operands. */
3984 13462651 : tem = simplify_ior_with_common_term (mode, op0, op1);
3985 13462651 : if (tem)
3986 : return tem;
3987 :
3988 : /* IOR is commutative and we can't rely on canonicalization at this point,
3989 : so try again to simplify with the operands reversed. */
3990 13462558 : tem = simplify_ior_with_common_term (mode, op1, op0);
3991 13462558 : if (tem)
3992 : return tem;
3993 :
3994 13462558 : tem = simplify_with_subreg_not (code, mode, op0, op1);
3995 13462558 : if (tem)
3996 : return tem;
3997 :
3998 13462553 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3999 13462553 : if (tem)
4000 : return tem;
4001 :
4002 13462520 : tem = simplify_associative_operation (code, mode, op0, op1);
4003 13462520 : if (tem)
4004 : return tem;
4005 :
4006 13191954 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
4007 13191954 : if (tem)
4008 : return tem;
4009 : break;
4010 :
4011 1736916 : case XOR:
4012 1736916 : if (trueop1 == CONST0_RTX (mode))
4013 : return op0;
4014 1681016 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4015 24667 : return simplify_gen_unary (NOT, mode, op0, mode);
4016 1656349 : if (rtx_equal_p (trueop0, trueop1)
4017 2404 : && ! side_effects_p (op0)
4018 1658749 : && GET_MODE_CLASS (mode) != MODE_CC)
4019 2400 : return CONST0_RTX (mode);
4020 :
4021 : /* Canonicalize XOR of the most significant bit to PLUS. */
4022 1653949 : if (CONST_SCALAR_INT_P (op1)
4023 1653949 : && mode_signbit_p (mode, op1))
4024 40252 : return simplify_gen_binary (PLUS, mode, op0, op1);
4025 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
4026 1613697 : if (CONST_SCALAR_INT_P (op1)
4027 486791 : && GET_CODE (op0) == PLUS
4028 2512 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
4029 1615293 : && mode_signbit_p (mode, XEXP (op0, 1)))
4030 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
4031 : simplify_gen_binary (XOR, mode, op1,
4032 189 : XEXP (op0, 1)));
4033 :
4034 : /* If we are XORing two things that have no bits in common,
4035 : convert them into an IOR. This helps to detect rotation encoded
4036 : using those methods and possibly other simplifications. */
4037 :
4038 1613508 : if (HWI_COMPUTABLE_MODE_P (mode)
4039 1321873 : && (nonzero_bits (op0, mode)
4040 1321873 : & nonzero_bits (op1, mode)) == 0)
4041 10691 : return (simplify_gen_binary (IOR, mode, op0, op1));
4042 :
4043 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
4044 1602817 : if (match_plus_neg_pattern (op0, op1, mode))
4045 0 : return CONSTM1_RTX (mode);
4046 :
4047 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
4048 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
4049 : (NOT y). */
4050 1602817 : {
4051 1602817 : int num_negated = 0;
4052 :
4053 1602817 : if (GET_CODE (op0) == NOT)
4054 887 : num_negated++, op0 = XEXP (op0, 0);
4055 1602817 : if (GET_CODE (op1) == NOT)
4056 62 : num_negated++, op1 = XEXP (op1, 0);
4057 :
4058 62 : if (num_negated == 2)
4059 0 : return simplify_gen_binary (XOR, mode, op0, op1);
4060 1602817 : else if (num_negated == 1)
4061 949 : return simplify_gen_unary (NOT, mode,
4062 : simplify_gen_binary (XOR, mode, op0, op1),
4063 949 : mode);
4064 : }
4065 :
4066 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
4067 : correspond to a machine insn or result in further simplifications
4068 : if B is a constant. */
4069 :
4070 1601868 : if (GET_CODE (op0) == AND
4071 173767 : && rtx_equal_p (XEXP (op0, 1), op1)
4072 1626351 : && ! side_effects_p (op1))
4073 24483 : return simplify_gen_binary (AND, mode,
4074 : simplify_gen_unary (NOT, mode,
4075 : XEXP (op0, 0), mode),
4076 24483 : op1);
4077 :
4078 1577385 : else if (GET_CODE (op0) == AND
4079 149284 : && rtx_equal_p (XEXP (op0, 0), op1)
4080 1578650 : && ! side_effects_p (op1))
4081 1265 : return simplify_gen_binary (AND, mode,
4082 : simplify_gen_unary (NOT, mode,
4083 : XEXP (op0, 1), mode),
4084 1265 : op1);
4085 :
4086 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
4087 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
4088 : out bits inverted twice and not set by C. Similarly, given
4089 : (xor (and (xor A B) C) D), simplify without inverting C in
4090 : the xor operand: (xor (and A C) (B&C)^D).
4091 : */
4092 1576120 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
4093 169681 : && GET_CODE (XEXP (op0, 0)) == XOR
4094 7294 : && CONST_INT_P (op1)
4095 331 : && CONST_INT_P (XEXP (op0, 1))
4096 286 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4097 : {
4098 38 : enum rtx_code op = GET_CODE (op0);
4099 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4100 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4101 38 : rtx c = XEXP (op0, 1);
4102 38 : rtx d = op1;
4103 38 : HOST_WIDE_INT bval = INTVAL (b);
4104 38 : HOST_WIDE_INT cval = INTVAL (c);
4105 38 : HOST_WIDE_INT dval = INTVAL (d);
4106 38 : HOST_WIDE_INT xcval;
4107 :
4108 38 : if (op == IOR)
4109 8 : xcval = ~cval;
4110 : else
4111 : xcval = cval;
4112 :
4113 38 : return simplify_gen_binary (XOR, mode,
4114 : simplify_gen_binary (op, mode, a, c),
4115 38 : gen_int_mode ((bval & xcval) ^ dval,
4116 : mode));
4117 : }
4118 :
4119 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4120 : we can transform like this:
4121 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4122 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4123 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4124 : Attempt a few simplifications when B and C are both constants. */
4125 1576082 : if (GET_CODE (op0) == AND
4126 147989 : && CONST_INT_P (op1)
4127 13346 : && CONST_INT_P (XEXP (op0, 1)))
4128 : {
4129 11614 : rtx a = XEXP (op0, 0);
4130 11614 : rtx b = XEXP (op0, 1);
4131 11614 : rtx c = op1;
4132 11614 : HOST_WIDE_INT bval = INTVAL (b);
4133 11614 : HOST_WIDE_INT cval = INTVAL (c);
4134 :
4135 : /* Instead of computing ~A&C, we compute its negated value,
4136 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4137 : optimize for sure. If it does not simplify, we still try
4138 : to compute ~A&C below, but since that always allocates
4139 : RTL, we don't try that before committing to returning a
4140 : simplified expression. */
4141 11614 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4142 : GEN_INT (~cval));
4143 :
4144 11614 : if ((~cval & bval) == 0)
4145 : {
4146 518 : rtx na_c = NULL_RTX;
4147 518 : if (n_na_c)
4148 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4149 : else
4150 : {
4151 : /* If ~A does not simplify, don't bother: we don't
4152 : want to simplify 2 operations into 3, and if na_c
4153 : were to simplify with na, n_na_c would have
4154 : simplified as well. */
4155 518 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4156 518 : if (na)
4157 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4158 : }
4159 :
4160 : /* Try to simplify ~A&C | ~B&C. */
4161 0 : if (na_c != NULL_RTX)
4162 0 : return simplify_gen_binary (IOR, mode, na_c,
4163 0 : gen_int_mode (~bval & cval, mode));
4164 : }
4165 : else
4166 : {
4167 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4168 11096 : if (n_na_c == CONSTM1_RTX (mode))
4169 : {
4170 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4171 0 : gen_int_mode (~cval & bval,
4172 : mode));
4173 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4174 0 : gen_int_mode (~bval & cval,
4175 : mode));
4176 : }
4177 : }
4178 : }
4179 :
4180 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4181 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4182 : machines, and also has shorter instruction path length. */
4183 1576082 : if (GET_CODE (op0) == AND
4184 147989 : && GET_CODE (XEXP (op0, 0)) == XOR
4185 6809 : && CONST_INT_P (XEXP (op0, 1))
4186 1579618 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4187 : {
4188 7 : rtx a = trueop1;
4189 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4190 7 : rtx c = XEXP (op0, 1);
4191 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4192 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4193 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4194 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4195 : }
4196 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4197 1576075 : else if (GET_CODE (op0) == AND
4198 147982 : && GET_CODE (XEXP (op0, 0)) == XOR
4199 6802 : && CONST_INT_P (XEXP (op0, 1))
4200 1579604 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4201 : {
4202 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4203 8 : rtx b = trueop1;
4204 8 : rtx c = XEXP (op0, 1);
4205 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4206 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4207 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4208 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4209 : }
4210 :
4211 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4212 : comparison if STORE_FLAG_VALUE is 1. */
4213 1576067 : if (STORE_FLAG_VALUE == 1
4214 1576067 : && trueop1 == const1_rtx
4215 201065 : && COMPARISON_P (op0)
4216 1582245 : && (reversed = reversed_comparison (op0, mode)))
4217 : return reversed;
4218 :
4219 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4220 : is (lt foo (const_int 0)), so we can perform the above
4221 : simplification if STORE_FLAG_VALUE is 1. */
4222 :
4223 1569897 : if (is_a <scalar_int_mode> (mode, &int_mode)
4224 : && STORE_FLAG_VALUE == 1
4225 1282427 : && trueop1 == const1_rtx
4226 194895 : && GET_CODE (op0) == LSHIFTRT
4227 35165 : && CONST_INT_P (XEXP (op0, 1))
4228 35165 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4229 34262 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4230 :
4231 : /* (xor (comparison foo bar) (const_int sign-bit))
4232 : when STORE_FLAG_VALUE is the sign bit. */
4233 1535635 : if (is_a <scalar_int_mode> (mode, &int_mode)
4234 1248165 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4235 0 : && trueop1 == const_true_rtx
4236 0 : && COMPARISON_P (op0)
4237 0 : && (reversed = reversed_comparison (op0, int_mode)))
4238 : return reversed;
4239 :
4240 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4241 1535635 : if (GET_CODE (op0) == GET_CODE (op1)
4242 531380 : && (GET_CODE (op0) == AND
4243 531380 : || GET_CODE (op0) == LSHIFTRT
4244 459714 : || GET_CODE (op0) == ASHIFTRT
4245 459614 : || GET_CODE (op0) == ASHIFT
4246 459480 : || GET_CODE (op0) == ROTATE
4247 459372 : || GET_CODE (op0) == ROTATERT))
4248 : {
4249 72542 : tem = simplify_distributive_operation (code, mode, op0, op1);
4250 72542 : if (tem)
4251 : return tem;
4252 : }
4253 :
4254 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4255 : mode size to (rotate A CX). */
4256 1467604 : tem = simplify_rotate_op (op0, op1, mode);
4257 1467604 : if (tem)
4258 : return tem;
4259 :
4260 : /* Convert (xor (and (not A) B) A) into A | B. */
4261 1466224 : if (GET_CODE (op0) == AND
4262 1466224 : && negated_ops_p (XEXP (op0, 0), op1))
4263 1 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4264 :
4265 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4266 : into B | (1 << A). */
4267 1466223 : if (SHIFT_COUNT_TRUNCATED
4268 : && GET_CODE (op0) == AND
4269 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4270 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4271 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4272 : && GET_CODE (op1) == ASHIFT
4273 : && CONST_INT_P (XEXP (op1, 0))
4274 : && INTVAL (XEXP (op1, 0)) == 1
4275 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4276 : && !side_effects_p (XEXP (op1, 1)))
4277 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4278 :
4279 1466223 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4280 1466223 : if (tem)
4281 : return tem;
4282 :
4283 1466222 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4284 1466222 : if (tem)
4285 : return tem;
4286 :
4287 1466222 : tem = simplify_associative_operation (code, mode, op0, op1);
4288 1466222 : if (tem)
4289 : return tem;
4290 : break;
4291 :
4292 23792043 : case AND:
4293 23792043 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4294 : return trueop1;
4295 23550397 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4296 : return op0;
4297 23166061 : if (HWI_COMPUTABLE_MODE_P (mode))
4298 : {
4299 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4300 : nonzero bits in WORD_MODE rather than MODE. */
4301 20312215 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4302 20312215 : if (WORD_REGISTER_OPERATIONS
4303 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4304 : tmode = word_mode;
4305 20312215 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4306 20312215 : HOST_WIDE_INT nzop1;
4307 20312215 : if (CONST_INT_P (trueop1))
4308 : {
4309 17300099 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4310 : /* If we are turning off bits already known off in OP0, we need
4311 : not do an AND. */
4312 17300099 : if ((nzop0 & ~val1) == 0)
4313 401641 : return op0;
4314 :
4315 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4316 : (and (lshiftrt (subreg X) shift) mask).
4317 :
4318 : Keeps shift and AND in the same mode, improving recognition.
4319 : Only applied when subreg is a lowpart, shift is valid,
4320 : and no precision is lost. */
4321 16981546 : if (SUBREG_P (op0)
4322 5948373 : && subreg_lowpart_p (op0)
4323 5932467 : && !paradoxical_subreg_p (op0)
4324 933750 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4325 : /* simplify_subreg asserts the object being accessed is not
4326 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4327 : is not simplified and the source operand is a constant,
4328 : and thus VOIDmode. Guard against that. */
4329 115441 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4330 115391 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4331 115391 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4332 115391 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4333 95682 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4334 95682 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4335 17077227 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4336 95681 : + floor_log2 (val1))
4337 16981546 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4338 : {
4339 10502 : tem = XEXP (XEXP (op0, 0), 0);
4340 10502 : if (SUBREG_P (tem))
4341 : {
4342 265 : if (subreg_lowpart_p (tem))
4343 265 : tem = SUBREG_REG (tem);
4344 : else
4345 : tem = NULL_RTX;
4346 : }
4347 265 : if (tem != NULL_RTX)
4348 : {
4349 10502 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4350 10502 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4351 10502 : offset);
4352 10502 : if (tem)
4353 : {
4354 10502 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4355 10502 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4356 10502 : shiftamt);
4357 10502 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4358 : shiftamtrtx);
4359 10502 : return simplify_gen_binary (AND, mode, op0, op1);
4360 : }
4361 : }
4362 : }
4363 : }
4364 19983160 : nzop1 = nonzero_bits (trueop1, mode);
4365 : /* If we are clearing all the nonzero bits, the result is zero. */
4366 19983160 : if ((nzop1 & nzop0) == 0
4367 19983160 : && !side_effects_p (op0) && !side_effects_p (op1))
4368 72586 : return CONST0_RTX (mode);
4369 : }
4370 22767741 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4371 22767737 : && GET_MODE_CLASS (mode) != MODE_CC)
4372 : return op0;
4373 : /* A & (~A) -> 0 */
4374 623566 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4375 22757212 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4376 3937 : && ! side_effects_p (op0)
4377 22765039 : && GET_MODE_CLASS (mode) != MODE_CC)
4378 3936 : return CONST0_RTX (mode);
4379 :
4380 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4381 22757167 : if (match_plus_neg_pattern (op0, op1, mode))
4382 2 : return CONST0_RTX (mode);
4383 :
4384 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4385 : there are no nonzero bits of C outside of X's mode. */
4386 45514330 : if ((GET_CODE (op0) == SIGN_EXTEND
4387 22757165 : || GET_CODE (op0) == ZERO_EXTEND)
4388 92920 : && CONST_SCALAR_INT_P (trueop1)
4389 78955 : && is_a <scalar_int_mode> (mode, &int_mode)
4390 78955 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4391 22836120 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4392 78955 : GET_MODE_PRECISION (int_mode))
4393 22836120 : & rtx_mode_t (trueop1, mode)) == 0)
4394 : {
4395 77077 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4396 77077 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4397 77077 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4398 77077 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4399 : }
4400 :
4401 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4402 : we might be able to further simplify the AND with X and potentially
4403 : remove the truncation altogether. */
4404 22680088 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4405 : {
4406 6 : rtx x = XEXP (op0, 0);
4407 6 : machine_mode xmode = GET_MODE (x);
4408 6 : tem = simplify_gen_binary (AND, xmode, x,
4409 6 : gen_int_mode (INTVAL (trueop1), xmode));
4410 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4411 : }
4412 :
4413 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4414 22680082 : if (GET_CODE (op0) == IOR
4415 1400747 : && CONST_INT_P (trueop1)
4416 222873 : && CONST_INT_P (XEXP (op0, 1)))
4417 : {
4418 131617 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4419 131617 : return simplify_gen_binary (IOR, mode,
4420 : simplify_gen_binary (AND, mode,
4421 : XEXP (op0, 0), op1),
4422 131617 : gen_int_mode (tmp, mode));
4423 : }
4424 :
4425 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4426 : insn (and may simplify more). */
4427 22548465 : if (GET_CODE (op0) == XOR
4428 136637 : && rtx_equal_p (XEXP (op0, 0), op1)
4429 22549906 : && ! side_effects_p (op1))
4430 1441 : return simplify_gen_binary (AND, mode,
4431 : simplify_gen_unary (NOT, mode,
4432 : XEXP (op0, 1), mode),
4433 1441 : op1);
4434 :
4435 22547024 : if (GET_CODE (op0) == XOR
4436 135196 : && rtx_equal_p (XEXP (op0, 1), op1)
4437 22549978 : && ! side_effects_p (op1))
4438 2954 : return simplify_gen_binary (AND, mode,
4439 : simplify_gen_unary (NOT, mode,
4440 : XEXP (op0, 0), mode),
4441 2954 : op1);
4442 :
4443 : /* Similarly for (~(A ^ B)) & A. */
4444 22544070 : if (GET_CODE (op0) == NOT
4445 619676 : && GET_CODE (XEXP (op0, 0)) == XOR
4446 3464 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4447 22544124 : && ! side_effects_p (op1))
4448 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4449 :
4450 22544016 : if (GET_CODE (op0) == NOT
4451 619622 : && GET_CODE (XEXP (op0, 0)) == XOR
4452 3410 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4453 22544053 : && ! side_effects_p (op1))
4454 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4455 :
4456 : /* Convert (A | B) & A to A. */
4457 22543979 : if (GET_CODE (op0) == IOR
4458 1269130 : && (rtx_equal_p (XEXP (op0, 0), op1)
4459 1268605 : || rtx_equal_p (XEXP (op0, 1), op1))
4460 732 : && ! side_effects_p (XEXP (op0, 0))
4461 22544711 : && ! side_effects_p (XEXP (op0, 1)))
4462 : return op1;
4463 :
4464 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4465 : ((A & N) + B) & M -> (A + B) & M
4466 : Similarly if (N & M) == 0,
4467 : ((A | N) + B) & M -> (A + B) & M
4468 : and for - instead of + and/or ^ instead of |.
4469 : Also, if (N & M) == 0, then
4470 : (A +- N) & M -> A & M. */
4471 22543247 : if (CONST_INT_P (trueop1)
4472 16782512 : && HWI_COMPUTABLE_MODE_P (mode)
4473 16761006 : && ~UINTVAL (trueop1)
4474 16761006 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4475 33288755 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4476 : {
4477 970497 : rtx pmop[2];
4478 970497 : int which;
4479 :
4480 970497 : pmop[0] = XEXP (op0, 0);
4481 970497 : pmop[1] = XEXP (op0, 1);
4482 :
4483 970497 : if (CONST_INT_P (pmop[1])
4484 515341 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4485 167649 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4486 :
4487 2431647 : for (which = 0; which < 2; which++)
4488 : {
4489 1621098 : tem = pmop[which];
4490 1621098 : switch (GET_CODE (tem))
4491 : {
4492 11934 : case AND:
4493 11934 : if (CONST_INT_P (XEXP (tem, 1))
4494 10420 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4495 : == UINTVAL (trueop1))
4496 7562 : pmop[which] = XEXP (tem, 0);
4497 : break;
4498 1728 : case IOR:
4499 1728 : case XOR:
4500 1728 : if (CONST_INT_P (XEXP (tem, 1))
4501 699 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4502 139 : pmop[which] = XEXP (tem, 0);
4503 : break;
4504 : default:
4505 : break;
4506 : }
4507 : }
4508 :
4509 810549 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4510 : {
4511 7701 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4512 : pmop[0], pmop[1]);
4513 7701 : return simplify_gen_binary (code, mode, tem, op1);
4514 : }
4515 : }
4516 :
4517 : /* (and X (ior (not X) Y) -> (and X Y) */
4518 22375598 : if (GET_CODE (op1) == IOR
4519 945919 : && GET_CODE (XEXP (op1, 0)) == NOT
4520 22380929 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4521 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4522 :
4523 : /* (and (ior (not X) Y) X) -> (and X Y) */
4524 22375598 : if (GET_CODE (op0) == IOR
4525 1268398 : && GET_CODE (XEXP (op0, 0)) == NOT
4526 22426093 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4527 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4528 :
4529 : /* (and X (ior Y (not X)) -> (and X Y) */
4530 22375592 : if (GET_CODE (op1) == IOR
4531 945919 : && GET_CODE (XEXP (op1, 1)) == NOT
4532 22375931 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4533 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4534 :
4535 : /* (and (ior Y (not X)) X) -> (and X Y) */
4536 22375592 : if (GET_CODE (op0) == IOR
4537 1268392 : && GET_CODE (XEXP (op0, 1)) == NOT
4538 22384383 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4539 43 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4540 :
4541 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4542 22375549 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4543 22375549 : && negated_ops_p (op1, XEXP (op0, 1)))
4544 13 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4545 : simplify_gen_unary (NOT, mode,
4546 : XEXP (op0, 1),
4547 13 : mode));
4548 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4549 22375536 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4550 22375536 : && negated_ops_p (op1, XEXP (op0, 0)))
4551 4 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4552 : simplify_gen_unary (NOT, mode,
4553 : XEXP (op0, 0),
4554 4 : mode));
4555 :
4556 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4557 22375532 : if (GET_CODE (op0) == GET_CODE (op1)
4558 2141180 : && (GET_CODE (op0) == AND
4559 : || GET_CODE (op0) == IOR
4560 2141180 : || GET_CODE (op0) == LSHIFTRT
4561 1195932 : || GET_CODE (op0) == ASHIFTRT
4562 1195782 : || GET_CODE (op0) == ASHIFT
4563 1195613 : || GET_CODE (op0) == ROTATE
4564 1195613 : || GET_CODE (op0) == ROTATERT))
4565 : {
4566 945567 : tem = simplify_distributive_operation (code, mode, op0, op1);
4567 945567 : if (tem)
4568 : return tem;
4569 : }
4570 :
4571 : /* (and:v4si
4572 : (ashiftrt:v4si A 16)
4573 : (const_vector: 0xffff x4))
4574 : is just (lshiftrt:v4si A 16). */
4575 21470892 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4576 4489 : && (CONST_INT_P (XEXP (op0, 1))
4577 1948 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4578 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4579 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4580 2541 : && GET_CODE (op1) == CONST_VECTOR
4581 21470917 : && const_vec_duplicate_p (op1)
4582 21470959 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4583 : {
4584 130 : unsigned HOST_WIDE_INT shift_count
4585 : = (CONST_INT_P (XEXP (op0, 1))
4586 65 : ? UINTVAL (XEXP (op0, 1))
4587 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4588 65 : unsigned HOST_WIDE_INT inner_prec
4589 130 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4590 :
4591 : /* Avoid UD shift count. */
4592 65 : if (shift_count < inner_prec
4593 59 : && (UINTVAL (XVECEXP (op1, 0, 0))
4594 59 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4595 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4596 : }
4597 :
4598 21470850 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4599 21470850 : if (tem)
4600 : return tem;
4601 :
4602 21468538 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4603 21468538 : if (tem)
4604 : return tem;
4605 :
4606 21468065 : tem = simplify_associative_operation (code, mode, op0, op1);
4607 21468065 : if (tem)
4608 : return tem;
4609 : break;
4610 :
4611 895687 : case UDIV:
4612 : /* 0/x is 0 (or x&0 if x has side-effects). */
4613 895687 : if (trueop0 == CONST0_RTX (mode)
4614 273 : && !cfun->can_throw_non_call_exceptions)
4615 : {
4616 273 : if (side_effects_p (op1))
4617 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4618 : return trueop0;
4619 : }
4620 : /* x/1 is x. */
4621 895414 : if (trueop1 == CONST1_RTX (mode))
4622 : {
4623 241232 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4624 241232 : if (tem)
4625 : return tem;
4626 : }
4627 : /* Convert divide by power of two into shift. */
4628 654182 : if (CONST_INT_P (trueop1)
4629 976912 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4630 322730 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4631 322730 : gen_int_shift_amount (mode, val));
4632 : break;
4633 :
4634 1173893 : case DIV:
4635 : /* Handle floating point and integers separately. */
4636 1173893 : if (SCALAR_FLOAT_MODE_P (mode))
4637 : {
4638 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4639 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4640 : NaN rather than 0.0. Nor is it safe for modes with signed
4641 : zeros, since dividing 0 by a negative number gives -0.0 */
4642 325268 : if (trueop0 == CONST0_RTX (mode)
4643 2800 : && !HONOR_NANS (mode)
4644 14 : && !HONOR_SIGNED_ZEROS (mode)
4645 325282 : && ! side_effects_p (op1))
4646 : return op0;
4647 : /* x/1.0 is x. */
4648 325254 : if (trueop1 == CONST1_RTX (mode)
4649 325254 : && !HONOR_SNANS (mode))
4650 : return op0;
4651 :
4652 325249 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4653 26866 : && trueop1 != CONST0_RTX (mode))
4654 : {
4655 20746 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4656 :
4657 : /* x/-1.0 is -x. */
4658 20746 : if (real_equal (d1, &dconstm1)
4659 20746 : && !HONOR_SNANS (mode))
4660 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4661 :
4662 : /* Change FP division by a constant into multiplication.
4663 : Only do this with -freciprocal-math. */
4664 20746 : if (flag_reciprocal_math
4665 20746 : && !real_equal (d1, &dconst0))
4666 : {
4667 7 : REAL_VALUE_TYPE d;
4668 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4669 7 : tem = const_double_from_real_value (d, mode);
4670 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4671 : }
4672 : }
4673 : }
4674 848625 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4675 : {
4676 : /* 0/x is 0 (or x&0 if x has side-effects). */
4677 826649 : if (trueop0 == CONST0_RTX (mode)
4678 979 : && !cfun->can_throw_non_call_exceptions)
4679 : {
4680 925 : if (side_effects_p (op1))
4681 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4682 : return trueop0;
4683 : }
4684 : /* x/1 is x. */
4685 825724 : if (trueop1 == CONST1_RTX (mode))
4686 : {
4687 882 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4688 882 : if (tem)
4689 : return tem;
4690 : }
4691 : /* x/-1 is -x. */
4692 824842 : if (trueop1 == CONSTM1_RTX (mode))
4693 : {
4694 503 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4695 503 : if (x)
4696 503 : return simplify_gen_unary (NEG, mode, x, mode);
4697 : }
4698 : }
4699 : break;
4700 :
4701 923374 : case UMOD:
4702 : /* 0%x is 0 (or x&0 if x has side-effects). */
4703 923374 : if (trueop0 == CONST0_RTX (mode))
4704 : {
4705 775 : if (side_effects_p (op1))
4706 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4707 : return trueop0;
4708 : }
4709 : /* x%1 is 0 (of x&0 if x has side-effects). */
4710 922599 : if (trueop1 == CONST1_RTX (mode))
4711 : {
4712 275392 : if (side_effects_p (op0))
4713 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4714 275392 : return CONST0_RTX (mode);
4715 : }
4716 : /* Implement modulus by power of two as AND. */
4717 647207 : if (CONST_INT_P (trueop1)
4718 957633 : && exact_log2 (UINTVAL (trueop1)) > 0)
4719 310426 : return simplify_gen_binary (AND, mode, op0,
4720 310426 : gen_int_mode (UINTVAL (trueop1) - 1,
4721 : mode));
4722 : break;
4723 :
4724 363472 : case MOD:
4725 : /* 0%x is 0 (or x&0 if x has side-effects). */
4726 363472 : if (trueop0 == CONST0_RTX (mode))
4727 : {
4728 1205 : if (side_effects_p (op1))
4729 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4730 : return trueop0;
4731 : }
4732 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4733 362267 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4734 : {
4735 740 : if (side_effects_p (op0))
4736 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4737 740 : return CONST0_RTX (mode);
4738 : }
4739 : break;
4740 :
4741 137646 : case ROTATERT:
4742 137646 : case ROTATE:
4743 137646 : if (trueop1 == CONST0_RTX (mode))
4744 : return op0;
4745 : /* Canonicalize rotates by constant amount. If the condition of
4746 : reversing direction is met, then reverse the direction. */
4747 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4748 137556 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4749 : {
4750 11743 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4751 11743 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4752 12287 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4753 : mode, op0, new_amount_rtx);
4754 : }
4755 : #endif
4756 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4757 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4758 : semantics. */
4759 125813 : tem = unwrap_const_vec_duplicate (trueop1);
4760 125813 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4761 125813 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4762 599 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4763 :
4764 : /* FALLTHRU */
4765 5169282 : case ASHIFTRT:
4766 5169282 : if (trueop1 == CONST0_RTX (mode))
4767 : return op0;
4768 5167248 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4769 : return op0;
4770 : /* Rotating ~0 always results in ~0. */
4771 5167076 : if (CONST_INT_P (trueop0)
4772 14695 : && HWI_COMPUTABLE_MODE_P (mode)
4773 14667 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4774 5167076 : && ! side_effects_p (op1))
4775 : return op0;
4776 :
4777 30960019 : canonicalize_shift:
4778 : /* Given:
4779 : scalar modes M1, M2
4780 : scalar constants c1, c2
4781 : size (M2) > size (M1)
4782 : c1 == size (M2) - size (M1)
4783 : optimize:
4784 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4785 : <low_part>)
4786 : (const_int <c2>))
4787 : to:
4788 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4789 : <low_part>). */
4790 30960019 : if ((code == ASHIFTRT || code == LSHIFTRT)
4791 11666084 : && is_a <scalar_int_mode> (mode, &int_mode)
4792 10875867 : && SUBREG_P (op0)
4793 1149721 : && CONST_INT_P (op1)
4794 1147500 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4795 18549 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4796 : &inner_mode)
4797 18549 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4798 36792 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4799 18396 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4800 36792 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4801 30978178 : && subreg_lowpart_p (op0))
4802 : {
4803 18159 : rtx tmp = gen_int_shift_amount
4804 18159 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4805 :
4806 : /* Combine would usually zero out the value when combining two
4807 : local shifts and the range becomes larger or equal to the mode.
4808 : However since we fold away one of the shifts here combine won't
4809 : see it so we should immediately zero the result if it's out of
4810 : range. */
4811 18159 : if (code == LSHIFTRT
4812 32824 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4813 0 : tmp = const0_rtx;
4814 : else
4815 18159 : tmp = simplify_gen_binary (code,
4816 : inner_mode,
4817 18159 : XEXP (SUBREG_REG (op0), 0),
4818 : tmp);
4819 :
4820 18159 : return lowpart_subreg (int_mode, tmp, inner_mode);
4821 : }
4822 :
4823 30941860 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4824 : {
4825 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4826 : if (val != INTVAL (op1))
4827 : return simplify_gen_binary (code, mode, op0,
4828 : gen_int_shift_amount (mode, val));
4829 : }
4830 :
4831 : /* Simplify:
4832 :
4833 : (code:M1
4834 : (subreg:M1
4835 : ([al]shiftrt:M2
4836 : (subreg:M2
4837 : (ashift:M1 X C1))
4838 : C2))
4839 : C3)
4840 :
4841 : to:
4842 :
4843 : (code:M1
4844 : ([al]shiftrt:M1
4845 : (ashift:M1 X C1+N)
4846 : C2+N)
4847 : C3)
4848 :
4849 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4850 : directly would be arithmetically correct, but restricting the
4851 : simplification to shifts by constants is more conservative,
4852 : since it is more likely to lead to further simplifications. */
4853 30941860 : if (is_a<scalar_int_mode> (mode, &int_mode)
4854 5448373 : && paradoxical_subreg_p (op0)
4855 5008267 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4856 5008181 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4857 5008181 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4858 142933 : && CONST_INT_P (op1))
4859 : {
4860 142933 : auto xcode = GET_CODE (SUBREG_REG (op0));
4861 142933 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4862 142933 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4863 142933 : if (SUBREG_P (xop0)
4864 10736 : && GET_MODE (SUBREG_REG (xop0)) == mode
4865 10650 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4866 604 : && CONST_INT_P (xop1)
4867 143537 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4868 : {
4869 604 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4870 604 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4871 604 : if (CONST_INT_P (yop1)
4872 604 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4873 : {
4874 1208 : auto bias = (GET_MODE_BITSIZE (int_mode)
4875 604 : - GET_MODE_BITSIZE (inner_mode));
4876 604 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4877 604 : GEN_INT (INTVAL (yop1) + bias));
4878 604 : tem = simplify_gen_binary (xcode, mode, tem,
4879 604 : GEN_INT (INTVAL (xop1) + bias));
4880 604 : return simplify_gen_binary (code, mode, tem, op1);
4881 : }
4882 : }
4883 : }
4884 : break;
4885 :
4886 0 : case SS_ASHIFT:
4887 0 : if (CONST_INT_P (trueop0)
4888 0 : && HWI_COMPUTABLE_MODE_P (mode)
4889 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4890 0 : || mode_signbit_p (mode, trueop0))
4891 0 : && ! side_effects_p (op1))
4892 : return op0;
4893 0 : goto simplify_ashift;
4894 :
4895 0 : case US_ASHIFT:
4896 0 : if (CONST_INT_P (trueop0)
4897 0 : && HWI_COMPUTABLE_MODE_P (mode)
4898 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4899 0 : && ! side_effects_p (op1))
4900 : return op0;
4901 : /* FALLTHRU */
4902 :
4903 19590338 : case ASHIFT:
4904 19590338 : simplify_ashift:
4905 19590338 : if (trueop1 == CONST0_RTX (mode))
4906 : return op0;
4907 19433221 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4908 : return op0;
4909 19404034 : if (mem_depth
4910 235282 : && code == ASHIFT
4911 235282 : && CONST_INT_P (trueop1)
4912 235274 : && is_a <scalar_int_mode> (mode, &int_mode)
4913 19639296 : && IN_RANGE (UINTVAL (trueop1),
4914 : 1, GET_MODE_PRECISION (int_mode) - 1))
4915 : {
4916 235262 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4917 235262 : << UINTVAL (trueop1));
4918 235262 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4919 235262 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4920 235262 : }
4921 :
4922 : /* If we're shifting left a signed bitfield extraction and the
4923 : shift count + bitfield size is a natural integral mode and
4924 : the field starts at offset 0 (counting from the LSB), then
4925 : this can be simplified to a sign extension of a left shift.
4926 :
4927 : Some ISAs (RISC-V 64-bit) have inherent support for such
4928 : instructions and it's better for various optimizations to
4929 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4930 19168772 : if (GET_CODE (op0) == SIGN_EXTRACT
4931 28 : && REG_P (XEXP (op0, 0))
4932 : /* The size of the bitfield, the location of the bitfield and
4933 : shift count must be CONST_INTs. */
4934 22 : && CONST_INT_P (op1)
4935 22 : && CONST_INT_P (XEXP (op0, 1))
4936 22 : && CONST_INT_P (XEXP (op0, 2)))
4937 : {
4938 22 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4939 22 : machine_mode smaller_mode;
4940 : /* Now we need to verify the size of the bitfield plus the shift
4941 : count is an integral mode and smaller than MODE. This is
4942 : requirement for using SIGN_EXTEND. We also need to verify the
4943 : field starts at bit location 0 and that the subreg lowpart also
4944 : starts at zero. */
4945 22 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4946 3 : && mode > smaller_mode
4947 22 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
4948 3 : == UINTVAL (XEXP (op0, 2)))
4949 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
4950 : {
4951 : /* Everything passed. So we just need to get the subreg of the
4952 : original input, shift it and sign extend the result. */
4953 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
4954 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
4955 1 : return gen_rtx_SIGN_EXTEND (mode, x);
4956 : }
4957 : }
4958 19168771 : goto canonicalize_shift;
4959 :
4960 8402170 : case LSHIFTRT:
4961 8402170 : if (trueop1 == CONST0_RTX (mode))
4962 : return op0;
4963 6625662 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4964 : return op0;
4965 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4966 6624172 : if (GET_CODE (op0) == CLZ
4967 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4968 0 : && CONST_INT_P (trueop1)
4969 : && STORE_FLAG_VALUE == 1
4970 6624172 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4971 : {
4972 0 : unsigned HOST_WIDE_INT zero_val = 0;
4973 :
4974 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4975 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
4976 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
4977 0 : return simplify_gen_relational (EQ, mode, inner_mode,
4978 0 : XEXP (op0, 0), const0_rtx);
4979 : }
4980 6624172 : goto canonicalize_shift;
4981 :
4982 235681 : case SMIN:
4983 235681 : if (HWI_COMPUTABLE_MODE_P (mode)
4984 214794 : && mode_signbit_p (mode, trueop1)
4985 0 : && ! side_effects_p (op0))
4986 : return op1;
4987 235681 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4988 : return op0;
4989 235525 : tem = simplify_associative_operation (code, mode, op0, op1);
4990 235525 : if (tem)
4991 : return tem;
4992 : break;
4993 :
4994 489119 : case SMAX:
4995 489119 : if (HWI_COMPUTABLE_MODE_P (mode)
4996 461953 : && CONST_INT_P (trueop1)
4997 429617 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4998 0 : && ! side_effects_p (op0))
4999 : return op1;
5000 489119 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5001 : return op0;
5002 489014 : tem = simplify_associative_operation (code, mode, op0, op1);
5003 489014 : if (tem)
5004 : return tem;
5005 : break;
5006 :
5007 337041 : case UMIN:
5008 337041 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
5009 : return op1;
5010 337028 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5011 : return op0;
5012 336910 : tem = simplify_associative_operation (code, mode, op0, op1);
5013 336910 : if (tem)
5014 : return tem;
5015 : break;
5016 :
5017 317573 : case UMAX:
5018 317573 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
5019 : return op1;
5020 317573 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5021 : return op0;
5022 317483 : tem = simplify_associative_operation (code, mode, op0, op1);
5023 317483 : if (tem)
5024 : return tem;
5025 : break;
5026 :
5027 11689 : case SS_PLUS:
5028 11689 : case US_PLUS:
5029 11689 : case SS_MINUS:
5030 11689 : case US_MINUS:
5031 : /* Simplify x +/- 0 to x, if possible. */
5032 11689 : if (trueop1 == CONST0_RTX (mode))
5033 : return op0;
5034 : return 0;
5035 :
5036 0 : case SS_MULT:
5037 0 : case US_MULT:
5038 : /* Simplify x * 0 to 0, if possible. */
5039 0 : if (trueop1 == CONST0_RTX (mode)
5040 0 : && !side_effects_p (op0))
5041 : return op1;
5042 :
5043 : /* Simplify x * 1 to x, if possible. */
5044 0 : if (trueop1 == CONST1_RTX (mode))
5045 : return op0;
5046 : return 0;
5047 :
5048 463891 : case SMUL_HIGHPART:
5049 463891 : case UMUL_HIGHPART:
5050 : /* Simplify x * 0 to 0, if possible. */
5051 463891 : if (trueop1 == CONST0_RTX (mode)
5052 463891 : && !side_effects_p (op0))
5053 : return op1;
5054 : return 0;
5055 :
5056 0 : case SS_DIV:
5057 0 : case US_DIV:
5058 : /* Simplify x / 1 to x, if possible. */
5059 0 : if (trueop1 == CONST1_RTX (mode))
5060 : return op0;
5061 : return 0;
5062 :
5063 0 : case COPYSIGN:
5064 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5065 : return op0;
5066 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
5067 : {
5068 0 : REAL_VALUE_TYPE f1;
5069 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
5070 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
5071 0 : if (REAL_VALUE_NEGATIVE (f1))
5072 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
5073 0 : return tmp;
5074 : }
5075 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
5076 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5077 0 : if (GET_CODE (op1) == ABS
5078 0 : && ! side_effects_p (op1))
5079 0 : return simplify_gen_unary (ABS, mode, op0, mode);
5080 0 : if (GET_CODE (op0) == COPYSIGN
5081 0 : && ! side_effects_p (XEXP (op0, 1)))
5082 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5083 0 : if (GET_CODE (op1) == COPYSIGN
5084 0 : && ! side_effects_p (XEXP (op1, 0)))
5085 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
5086 : return 0;
5087 :
5088 1117 : case VEC_SERIES:
5089 2234 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
5090 92 : return gen_vec_duplicate (mode, op0);
5091 1025 : if (valid_for_const_vector_p (mode, op0)
5092 1025 : && valid_for_const_vector_p (mode, op1))
5093 93 : return gen_const_vec_series (mode, op0, op1);
5094 : return 0;
5095 :
5096 3412505 : case VEC_SELECT:
5097 3412505 : if (!VECTOR_MODE_P (mode))
5098 : {
5099 938085 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5100 1876170 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5101 938085 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5102 938085 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5103 :
5104 : /* We can't reason about selections made at runtime. */
5105 938085 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5106 445212661 : return 0;
5107 :
5108 938085 : if (vec_duplicate_p (trueop0, &elt0))
5109 2077 : return elt0;
5110 :
5111 936008 : if (GET_CODE (trueop0) == CONST_VECTOR)
5112 7242 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5113 : (trueop1, 0, 0)));
5114 :
5115 : /* Extract a scalar element from a nested VEC_SELECT expression
5116 : (with optional nested VEC_CONCAT expression). Some targets
5117 : (i386) extract scalar element from a vector using chain of
5118 : nested VEC_SELECT expressions. When input operand is a memory
5119 : operand, this operation can be simplified to a simple scalar
5120 : load from an offseted memory address. */
5121 928766 : int n_elts;
5122 928766 : if (GET_CODE (trueop0) == VEC_SELECT
5123 1001051 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5124 72285 : .is_constant (&n_elts)))
5125 : {
5126 72285 : rtx op0 = XEXP (trueop0, 0);
5127 72285 : rtx op1 = XEXP (trueop0, 1);
5128 :
5129 72285 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5130 72285 : int elem;
5131 :
5132 72285 : rtvec vec;
5133 72285 : rtx tmp_op, tmp;
5134 :
5135 72285 : gcc_assert (GET_CODE (op1) == PARALLEL);
5136 72285 : gcc_assert (i < XVECLEN (op1, 0));
5137 :
5138 : /* Select element, pointed by nested selector. */
5139 72285 : elem = INTVAL (XVECEXP (op1, 0, i));
5140 :
5141 72285 : gcc_assert (elem < n_elts);
5142 :
5143 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5144 72285 : if (GET_CODE (op0) == VEC_CONCAT)
5145 : {
5146 29129 : rtx op00 = XEXP (op0, 0);
5147 29129 : rtx op01 = XEXP (op0, 1);
5148 :
5149 29129 : machine_mode mode00, mode01;
5150 29129 : int n_elts00, n_elts01;
5151 :
5152 29129 : mode00 = GET_MODE (op00);
5153 29129 : mode01 = GET_MODE (op01);
5154 :
5155 : /* Find out the number of elements of each operand.
5156 : Since the concatenated result has a constant number
5157 : of elements, the operands must too. */
5158 29129 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5159 29129 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5160 :
5161 29129 : gcc_assert (n_elts == n_elts00 + n_elts01);
5162 :
5163 : /* Select correct operand of VEC_CONCAT
5164 : and adjust selector. */
5165 29129 : if (elem < n_elts01)
5166 : tmp_op = op00;
5167 : else
5168 : {
5169 41 : tmp_op = op01;
5170 41 : elem -= n_elts00;
5171 : }
5172 : }
5173 : else
5174 : tmp_op = op0;
5175 :
5176 72285 : vec = rtvec_alloc (1);
5177 72285 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5178 :
5179 72285 : tmp = gen_rtx_fmt_ee (code, mode,
5180 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5181 72285 : return tmp;
5182 : }
5183 : }
5184 : else
5185 : {
5186 2474420 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5187 7423260 : gcc_assert (GET_MODE_INNER (mode)
5188 : == GET_MODE_INNER (GET_MODE (trueop0)));
5189 2474420 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5190 :
5191 2474420 : if (vec_duplicate_p (trueop0, &elt0))
5192 : /* It doesn't matter which elements are selected by trueop1,
5193 : because they are all the same. */
5194 15476 : return gen_vec_duplicate (mode, elt0);
5195 :
5196 2458944 : if (GET_CODE (trueop0) == CONST_VECTOR)
5197 : {
5198 17216 : unsigned n_elts = XVECLEN (trueop1, 0);
5199 17216 : rtvec v = rtvec_alloc (n_elts);
5200 17216 : unsigned int i;
5201 :
5202 34432 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5203 80184 : for (i = 0; i < n_elts; i++)
5204 : {
5205 62968 : rtx x = XVECEXP (trueop1, 0, i);
5206 :
5207 62968 : if (!CONST_INT_P (x))
5208 : return 0;
5209 :
5210 62968 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5211 : INTVAL (x));
5212 : }
5213 :
5214 17216 : return gen_rtx_CONST_VECTOR (mode, v);
5215 : }
5216 :
5217 : /* Recognize the identity. */
5218 2441728 : if (GET_MODE (trueop0) == mode)
5219 : {
5220 582444 : bool maybe_ident = true;
5221 582444 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5222 : {
5223 582038 : rtx j = XVECEXP (trueop1, 0, i);
5224 582038 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5225 : {
5226 : maybe_ident = false;
5227 : break;
5228 : }
5229 : }
5230 357403 : if (maybe_ident)
5231 : return trueop0;
5232 : }
5233 :
5234 : /* If we select a low-part subreg, return that. */
5235 2441322 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5236 : {
5237 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5238 0 : GET_MODE (trueop0));
5239 0 : if (new_rtx != NULL_RTX)
5240 : return new_rtx;
5241 : }
5242 :
5243 : /* If we build {a,b} then permute it, build the result directly. */
5244 2441322 : if (XVECLEN (trueop1, 0) == 2
5245 592049 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5246 592049 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5247 592049 : && GET_CODE (trueop0) == VEC_CONCAT
5248 178075 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5249 78 : && GET_MODE (XEXP (trueop0, 0)) == mode
5250 78 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5251 54 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5252 : {
5253 54 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5254 54 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5255 54 : rtx subop0, subop1;
5256 :
5257 54 : gcc_assert (i0 < 4 && i1 < 4);
5258 54 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5259 54 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5260 :
5261 54 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5262 : }
5263 :
5264 2441268 : if (XVECLEN (trueop1, 0) == 2
5265 591995 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5266 591995 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5267 591995 : && GET_CODE (trueop0) == VEC_CONCAT
5268 178021 : && GET_MODE (trueop0) == mode)
5269 : {
5270 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5271 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5272 2 : rtx subop0, subop1;
5273 :
5274 2 : gcc_assert (i0 < 2 && i1 < 2);
5275 2 : subop0 = XEXP (trueop0, i0);
5276 2 : subop1 = XEXP (trueop0, i1);
5277 :
5278 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5279 : }
5280 :
5281 : /* If we select one half of a vec_concat, return that. */
5282 2441266 : int l0, l1;
5283 2441266 : if (GET_CODE (trueop0) == VEC_CONCAT
5284 3021334 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5285 1510667 : .is_constant (&l0))
5286 3021334 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5287 1510667 : .is_constant (&l1))
5288 3951933 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5289 : {
5290 1510667 : rtx subop0 = XEXP (trueop0, 0);
5291 1510667 : rtx subop1 = XEXP (trueop0, 1);
5292 1510667 : machine_mode mode0 = GET_MODE (subop0);
5293 1510667 : machine_mode mode1 = GET_MODE (subop1);
5294 1510667 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5295 1510667 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5296 : {
5297 963013 : bool success = true;
5298 963013 : for (int i = 1; i < l0; ++i)
5299 : {
5300 962684 : rtx j = XVECEXP (trueop1, 0, i);
5301 962684 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5302 : {
5303 : success = false;
5304 : break;
5305 : }
5306 : }
5307 880017 : if (success)
5308 : return subop0;
5309 : }
5310 1510338 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5311 : {
5312 590 : bool success = true;
5313 590 : for (int i = 1; i < l1; ++i)
5314 : {
5315 543 : rtx j = XVECEXP (trueop1, 0, i);
5316 543 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5317 : {
5318 : success = false;
5319 : break;
5320 : }
5321 : }
5322 76 : if (success)
5323 : return subop1;
5324 : }
5325 : }
5326 :
5327 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5328 : when X has same component mode as vec_select. */
5329 2440890 : unsigned HOST_WIDE_INT subreg_offset = 0;
5330 2440890 : if (GET_CODE (trueop0) == SUBREG
5331 364738 : && GET_MODE_INNER (mode)
5332 729476 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5333 29584 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5334 2805628 : && constant_multiple_p (subreg_memory_offset (trueop0),
5335 29584 : GET_MODE_UNIT_BITSIZE (mode),
5336 : &subreg_offset))
5337 : {
5338 14792 : poly_uint64 nunits
5339 29584 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5340 14792 : bool success = true;
5341 91526 : for (int i = 0; i != l1; i++)
5342 : {
5343 87083 : rtx idx = XVECEXP (trueop1, 0, i);
5344 87083 : if (!CONST_INT_P (idx)
5345 87083 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5346 : {
5347 : success = false;
5348 : break;
5349 : }
5350 : }
5351 :
5352 14792 : if (success)
5353 : {
5354 4443 : rtx par = trueop1;
5355 4443 : if (subreg_offset)
5356 : {
5357 0 : rtvec vec = rtvec_alloc (l1);
5358 0 : for (int i = 0; i < l1; i++)
5359 0 : RTVEC_ELT (vec, i)
5360 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5361 : + subreg_offset);
5362 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5363 : }
5364 4443 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5365 : }
5366 : }
5367 : }
5368 :
5369 3292928 : if (XVECLEN (trueop1, 0) == 1
5370 856565 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5371 856565 : && GET_CODE (trueop0) == VEC_CONCAT)
5372 : {
5373 1291 : rtx vec = trueop0;
5374 2582 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5375 :
5376 : /* Try to find the element in the VEC_CONCAT. */
5377 1291 : while (GET_MODE (vec) != mode
5378 2582 : && GET_CODE (vec) == VEC_CONCAT)
5379 : {
5380 1291 : poly_int64 vec_size;
5381 :
5382 1291 : if (CONST_INT_P (XEXP (vec, 0)))
5383 : {
5384 : /* vec_concat of two const_ints doesn't make sense with
5385 : respect to modes. */
5386 3 : if (CONST_INT_P (XEXP (vec, 1)))
5387 381859210 : return 0;
5388 :
5389 3 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5390 9 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5391 : }
5392 : else
5393 2576 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5394 :
5395 1291 : if (known_lt (offset, vec_size))
5396 : vec = XEXP (vec, 0);
5397 230 : else if (known_ge (offset, vec_size))
5398 : {
5399 230 : offset -= vec_size;
5400 230 : vec = XEXP (vec, 1);
5401 : }
5402 : else
5403 : break;
5404 1291 : vec = avoid_constant_pool_reference (vec);
5405 : }
5406 :
5407 1291 : if (GET_MODE (vec) == mode)
5408 : return vec;
5409 : }
5410 :
5411 : /* If we select elements in a vec_merge that all come from the same
5412 : operand, select from that operand directly. */
5413 3291817 : if (GET_CODE (op0) == VEC_MERGE)
5414 : {
5415 9771 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5416 9771 : if (CONST_INT_P (trueop02))
5417 : {
5418 3003 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5419 3003 : bool all_operand0 = true;
5420 3003 : bool all_operand1 = true;
5421 10931 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5422 : {
5423 7928 : rtx j = XVECEXP (trueop1, 0, i);
5424 7928 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5425 : all_operand1 = false;
5426 : else
5427 3562 : all_operand0 = false;
5428 : }
5429 3003 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5430 1464 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5431 1539 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5432 47 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5433 : }
5434 : }
5435 :
5436 : /* If we have two nested selects that are inverses of each
5437 : other, replace them with the source operand. */
5438 3290306 : if (GET_CODE (trueop0) == VEC_SELECT
5439 68494 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5440 : {
5441 1030 : rtx op0_subop1 = XEXP (trueop0, 1);
5442 1030 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5443 2060 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5444 : bool identical_p = true;
5445 :
5446 : /* Apply the outer ordering vector to the inner one. (The inner
5447 : ordering vector is expressly permitted to be of a different
5448 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5449 : then the two VEC_SELECTs cancel. */
5450 8946 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5451 : {
5452 7916 : rtx x = XVECEXP (trueop1, 0, i);
5453 7916 : if (!CONST_INT_P (x))
5454 : return 0;
5455 7916 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5456 7916 : if (!CONST_INT_P (y))
5457 : return 0;
5458 7916 : if (i != INTVAL (y))
5459 5854 : identical_p = false;
5460 : }
5461 1030 : if (identical_p)
5462 : return XEXP (trueop0, 0);
5463 :
5464 : /* Otherwise a permutation of a permutation is a permutation. */
5465 1030 : int len = XVECLEN (trueop1, 0);
5466 1030 : rtvec vec = rtvec_alloc (len);
5467 8946 : for (int i = 0; i < len; ++i)
5468 : {
5469 7916 : rtx x = XVECEXP (trueop1, 0, i);
5470 7916 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5471 7916 : RTVEC_ELT (vec, i) = y;
5472 : }
5473 1030 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5474 : gen_rtx_PARALLEL (VOIDmode, vec));
5475 : }
5476 :
5477 : return 0;
5478 4088405 : case VEC_CONCAT:
5479 4088405 : {
5480 4088405 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5481 4088405 : ? GET_MODE (trueop0)
5482 4088405 : : GET_MODE_INNER (mode));
5483 4088405 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5484 4088405 : ? GET_MODE (trueop1)
5485 4088405 : : GET_MODE_INNER (mode));
5486 :
5487 4088405 : gcc_assert (VECTOR_MODE_P (mode));
5488 16353620 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5489 : + GET_MODE_SIZE (op1_mode),
5490 : GET_MODE_SIZE (mode)));
5491 :
5492 4088405 : if (VECTOR_MODE_P (op0_mode))
5493 5656467 : gcc_assert (GET_MODE_INNER (mode)
5494 : == GET_MODE_INNER (op0_mode));
5495 : else
5496 4405832 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5497 :
5498 4088405 : if (VECTOR_MODE_P (op1_mode))
5499 5656467 : gcc_assert (GET_MODE_INNER (mode)
5500 : == GET_MODE_INNER (op1_mode));
5501 : else
5502 4405832 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5503 :
5504 4088405 : unsigned int n_elts, in_n_elts;
5505 4088405 : if ((GET_CODE (trueop0) == CONST_VECTOR
5506 4088405 : || CONST_SCALAR_INT_P (trueop0)
5507 3936088 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5508 153886 : && (GET_CODE (trueop1) == CONST_VECTOR
5509 153886 : || CONST_SCALAR_INT_P (trueop1)
5510 153886 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5511 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5512 4088405 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5513 : {
5514 0 : rtvec v = rtvec_alloc (n_elts);
5515 0 : unsigned int i;
5516 0 : for (i = 0; i < n_elts; i++)
5517 : {
5518 0 : if (i < in_n_elts)
5519 : {
5520 0 : if (!VECTOR_MODE_P (op0_mode))
5521 0 : RTVEC_ELT (v, i) = trueop0;
5522 : else
5523 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5524 : }
5525 : else
5526 : {
5527 0 : if (!VECTOR_MODE_P (op1_mode))
5528 0 : RTVEC_ELT (v, i) = trueop1;
5529 : else
5530 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5531 : i - in_n_elts);
5532 : }
5533 : }
5534 :
5535 0 : return gen_rtx_CONST_VECTOR (mode, v);
5536 : }
5537 :
5538 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5539 : Restrict the transformation to avoid generating a VEC_SELECT with a
5540 : mode unrelated to its operand. */
5541 4088405 : if (GET_CODE (trueop0) == VEC_SELECT
5542 131551 : && GET_CODE (trueop1) == VEC_SELECT
5543 28448 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5544 4104394 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5545 31978 : == GET_MODE_INNER(mode))
5546 : {
5547 15989 : rtx par0 = XEXP (trueop0, 1);
5548 15989 : rtx par1 = XEXP (trueop1, 1);
5549 15989 : int len0 = XVECLEN (par0, 0);
5550 15989 : int len1 = XVECLEN (par1, 0);
5551 15989 : rtvec vec = rtvec_alloc (len0 + len1);
5552 98806 : for (int i = 0; i < len0; i++)
5553 82817 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5554 98806 : for (int i = 0; i < len1; i++)
5555 82817 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5556 15989 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5557 15989 : gen_rtx_PARALLEL (VOIDmode, vec));
5558 : }
5559 : /* (vec_concat:
5560 : (subreg_lowpart:N OP)
5561 : (vec_select:N OP P)) --> OP when P selects the high half
5562 : of the OP. */
5563 4072416 : if (GET_CODE (trueop0) == SUBREG
5564 482790 : && subreg_lowpart_p (trueop0)
5565 482583 : && GET_CODE (trueop1) == VEC_SELECT
5566 3 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
5567 0 : && !side_effects_p (XEXP (trueop1, 0))
5568 4072416 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
5569 0 : return XEXP (trueop1, 0);
5570 : }
5571 : return 0;
5572 :
5573 0 : default:
5574 0 : gcc_unreachable ();
5575 : }
5576 :
5577 374021056 : if (mode == GET_MODE (op0)
5578 320965273 : && mode == GET_MODE (op1)
5579 100336849 : && vec_duplicate_p (op0, &elt0)
5580 374136408 : && vec_duplicate_p (op1, &elt1))
5581 : {
5582 : /* Try applying the operator to ELT and see if that simplifies.
5583 : We can duplicate the result if so.
5584 :
5585 : The reason we don't use simplify_gen_binary is that it isn't
5586 : necessarily a win to convert things like:
5587 :
5588 : (plus:V (vec_duplicate:V (reg:S R1))
5589 : (vec_duplicate:V (reg:S R2)))
5590 :
5591 : to:
5592 :
5593 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5594 :
5595 : The first might be done entirely in vector registers while the
5596 : second might need a move between register files. */
5597 120 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5598 : elt0, elt1);
5599 60 : if (tem)
5600 2 : return gen_vec_duplicate (mode, tem);
5601 : }
5602 :
5603 : return 0;
5604 : }
5605 :
5606 : /* Return true if binary operation OP distributes over addition in operand
5607 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5608 :
5609 : static bool
5610 7341 : distributes_over_addition_p (rtx_code op, int opno)
5611 : {
5612 0 : switch (op)
5613 : {
5614 : case PLUS:
5615 : case MINUS:
5616 : case MULT:
5617 : return true;
5618 :
5619 0 : case ASHIFT:
5620 0 : return opno == 1;
5621 :
5622 0 : default:
5623 0 : return false;
5624 : }
5625 : }
5626 :
5627 : rtx
5628 478529114 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5629 : rtx op0, rtx op1)
5630 : {
5631 478529114 : if (VECTOR_MODE_P (mode)
5632 14776212 : && code != VEC_CONCAT
5633 10676520 : && GET_CODE (op0) == CONST_VECTOR
5634 192522 : && GET_CODE (op1) == CONST_VECTOR)
5635 : {
5636 8052 : bool step_ok_p;
5637 8052 : if (CONST_VECTOR_STEPPED_P (op0)
5638 8052 : && CONST_VECTOR_STEPPED_P (op1))
5639 : /* We can operate directly on the encoding if:
5640 :
5641 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5642 : implies
5643 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5644 :
5645 : Addition and subtraction are the supported operators
5646 : for which this is true. */
5647 711 : step_ok_p = (code == PLUS || code == MINUS);
5648 7341 : else if (CONST_VECTOR_STEPPED_P (op0))
5649 : /* We can operate directly on stepped encodings if:
5650 :
5651 : a3 - a2 == a2 - a1
5652 : implies:
5653 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5654 :
5655 : which is true if (x -> x op c) distributes over addition. */
5656 1009 : step_ok_p = distributes_over_addition_p (code, 1);
5657 : else
5658 : /* Similarly in reverse. */
5659 6332 : step_ok_p = distributes_over_addition_p (code, 2);
5660 8052 : rtx_vector_builder builder;
5661 8052 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5662 : return 0;
5663 :
5664 8052 : unsigned int count = builder.encoded_nelts ();
5665 51662 : for (unsigned int i = 0; i < count; i++)
5666 : {
5667 87320 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5668 : CONST_VECTOR_ELT (op0, i),
5669 43660 : CONST_VECTOR_ELT (op1, i));
5670 43660 : if (!x || !valid_for_const_vector_p (mode, x))
5671 50 : return 0;
5672 43610 : builder.quick_push (x);
5673 : }
5674 8002 : return builder.build ();
5675 8052 : }
5676 :
5677 478521062 : if (VECTOR_MODE_P (mode)
5678 14768160 : && code == VEC_CONCAT
5679 4099692 : && (CONST_SCALAR_INT_P (op0)
5680 3957065 : || CONST_FIXED_P (op0)
5681 3957065 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5682 3954126 : || CONST_VECTOR_P (op0))
5683 165173 : && (CONST_SCALAR_INT_P (op1)
5684 162489 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5685 161119 : || CONST_FIXED_P (op1)
5686 161119 : || CONST_VECTOR_P (op1)))
5687 : {
5688 : /* Both inputs have a constant number of elements, so the result
5689 : must too. */
5690 11287 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5691 11287 : rtvec v = rtvec_alloc (n_elts);
5692 :
5693 11287 : gcc_assert (n_elts >= 2);
5694 11287 : if (n_elts == 2)
5695 : {
5696 4054 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5697 4054 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5698 :
5699 4054 : RTVEC_ELT (v, 0) = op0;
5700 4054 : RTVEC_ELT (v, 1) = op1;
5701 : }
5702 : else
5703 : {
5704 7233 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5705 7233 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5706 7233 : unsigned i;
5707 :
5708 7233 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5709 7233 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5710 7233 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5711 :
5712 47593 : for (i = 0; i < op0_n_elts; ++i)
5713 40360 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5714 47785 : for (i = 0; i < op1_n_elts; ++i)
5715 40552 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5716 : }
5717 :
5718 11287 : return gen_rtx_CONST_VECTOR (mode, v);
5719 : }
5720 :
5721 466964273 : if (VECTOR_MODE_P (mode)
5722 14756873 : && GET_CODE (op0) == CONST_VECTOR
5723 196844 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5724 478509775 : && (CONST_VECTOR_DUPLICATE_P (op0)
5725 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5726 : {
5727 140917 : switch (code)
5728 : {
5729 140917 : case PLUS:
5730 140917 : case MINUS:
5731 140917 : case MULT:
5732 140917 : case DIV:
5733 140917 : case MOD:
5734 140917 : case UDIV:
5735 140917 : case UMOD:
5736 140917 : case AND:
5737 140917 : case IOR:
5738 140917 : case XOR:
5739 140917 : case SMIN:
5740 140917 : case SMAX:
5741 140917 : case UMIN:
5742 140917 : case UMAX:
5743 140917 : case LSHIFTRT:
5744 140917 : case ASHIFTRT:
5745 140917 : case ASHIFT:
5746 140917 : case ROTATE:
5747 140917 : case ROTATERT:
5748 140917 : case SS_PLUS:
5749 140917 : case US_PLUS:
5750 140917 : case SS_MINUS:
5751 140917 : case US_MINUS:
5752 140917 : case SS_ASHIFT:
5753 140917 : case US_ASHIFT:
5754 140917 : case COPYSIGN:
5755 140917 : break;
5756 : default:
5757 : return NULL_RTX;
5758 : }
5759 :
5760 140917 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5761 140917 : ? CONST_VECTOR_NPATTERNS (op0)
5762 148650 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5763 140917 : rtx_vector_builder builder (mode, npatterns, 1);
5764 294905 : for (unsigned i = 0; i < npatterns; i++)
5765 : {
5766 307976 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5767 153988 : CONST_VECTOR_ELT (op0, i), op1);
5768 153988 : if (!x || !valid_for_const_vector_p (mode, x))
5769 0 : return 0;
5770 153988 : builder.quick_push (x);
5771 : }
5772 140917 : return builder.build ();
5773 : }
5774 :
5775 478368858 : if (SCALAR_FLOAT_MODE_P (mode)
5776 6365419 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5777 75670 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5778 11530 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5779 : {
5780 11530 : if (code == AND
5781 : || code == IOR
5782 11530 : || code == XOR)
5783 : {
5784 2515 : long tmp0[4];
5785 2515 : long tmp1[4];
5786 2515 : REAL_VALUE_TYPE r;
5787 2515 : int i;
5788 :
5789 2515 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5790 2515 : GET_MODE (op0));
5791 2515 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5792 2515 : GET_MODE (op1));
5793 12575 : for (i = 0; i < 4; i++)
5794 : {
5795 10060 : switch (code)
5796 : {
5797 5268 : case AND:
5798 5268 : tmp0[i] &= tmp1[i];
5799 5268 : break;
5800 2512 : case IOR:
5801 2512 : tmp0[i] |= tmp1[i];
5802 2512 : break;
5803 2280 : case XOR:
5804 2280 : tmp0[i] ^= tmp1[i];
5805 2280 : break;
5806 : default:
5807 : gcc_unreachable ();
5808 : }
5809 : }
5810 2515 : real_from_target (&r, tmp0, mode);
5811 2515 : return const_double_from_real_value (r, mode);
5812 : }
5813 9015 : else if (code == COPYSIGN)
5814 : {
5815 0 : REAL_VALUE_TYPE f0, f1;
5816 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5817 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5818 0 : real_copysign (&f0, &f1);
5819 0 : return const_double_from_real_value (f0, mode);
5820 : }
5821 : else
5822 : {
5823 9015 : REAL_VALUE_TYPE f0, f1, value, result;
5824 9015 : const REAL_VALUE_TYPE *opr0, *opr1;
5825 9015 : bool inexact;
5826 :
5827 9015 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5828 9015 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5829 :
5830 9015 : if (HONOR_SNANS (mode)
5831 9015 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5832 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5833 10 : return 0;
5834 :
5835 9005 : real_convert (&f0, mode, opr0);
5836 9005 : real_convert (&f1, mode, opr1);
5837 :
5838 9005 : if (code == DIV
5839 4108 : && real_equal (&f1, &dconst0)
5840 12649 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5841 3640 : return 0;
5842 :
5843 26724 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5844 5273 : && flag_trapping_math
5845 5197 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5846 : {
5847 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5848 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5849 :
5850 9 : switch (code)
5851 : {
5852 0 : case PLUS:
5853 : /* Inf + -Inf = NaN plus exception. */
5854 0 : if (s0 != s1)
5855 : return 0;
5856 : break;
5857 0 : case MINUS:
5858 : /* Inf - Inf = NaN plus exception. */
5859 0 : if (s0 == s1)
5860 : return 0;
5861 : break;
5862 : case DIV:
5863 : /* Inf / Inf = NaN plus exception. */
5864 : return 0;
5865 : default:
5866 : break;
5867 : }
5868 : }
5869 :
5870 7944 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5871 1952 : && flag_trapping_math
5872 7262 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5873 1898 : || (REAL_VALUE_ISINF (f1)
5874 10 : && real_equal (&f0, &dconst0))))
5875 : /* Inf * 0 = NaN plus exception. */
5876 18 : return 0;
5877 :
5878 5338 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5879 : &f0, &f1);
5880 5338 : real_convert (&result, mode, &value);
5881 :
5882 : /* Don't constant fold this floating point operation if
5883 : the result has overflowed and flag_trapping_math. */
5884 :
5885 5338 : if (flag_trapping_math
5886 20680 : && MODE_HAS_INFINITIES (mode)
5887 5170 : && REAL_VALUE_ISINF (result)
5888 1104 : && !REAL_VALUE_ISINF (f0)
5889 6428 : && !REAL_VALUE_ISINF (f1))
5890 : /* Overflow plus exception. */
5891 1090 : return 0;
5892 :
5893 : /* Don't constant fold this floating point operation if the
5894 : result may dependent upon the run-time rounding mode and
5895 : flag_rounding_math is set, or if GCC's software emulation
5896 : is unable to accurately represent the result. */
5897 :
5898 4248 : if ((flag_rounding_math
5899 27055 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5900 4248 : && (inexact || !real_identical (&result, &value)))
5901 378 : return NULL_RTX;
5902 :
5903 3870 : return const_double_from_real_value (result, mode);
5904 : }
5905 : }
5906 :
5907 : /* We can fold some multi-word operations. */
5908 478357328 : scalar_int_mode int_mode;
5909 478357328 : if (is_a <scalar_int_mode> (mode, &int_mode)
5910 409767331 : && CONST_SCALAR_INT_P (op0)
5911 39538176 : && CONST_SCALAR_INT_P (op1)
5912 33152290 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5913 : {
5914 33152290 : wide_int result;
5915 33152290 : wi::overflow_type overflow;
5916 33152290 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5917 33152290 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5918 :
5919 : #if TARGET_SUPPORTS_WIDE_INT == 0
5920 : /* This assert keeps the simplification from producing a result
5921 : that cannot be represented in a CONST_DOUBLE but a lot of
5922 : upstream callers expect that this function never fails to
5923 : simplify something and so you if you added this to the test
5924 : above the code would die later anyway. If this assert
5925 : happens, you just need to make the port support wide int. */
5926 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5927 : #endif
5928 33152290 : switch (code)
5929 : {
5930 1086198 : case MINUS:
5931 1086198 : result = wi::sub (pop0, pop1);
5932 1086198 : break;
5933 :
5934 25903084 : case PLUS:
5935 25903084 : result = wi::add (pop0, pop1);
5936 25903084 : break;
5937 :
5938 319435 : case MULT:
5939 319435 : result = wi::mul (pop0, pop1);
5940 319435 : break;
5941 :
5942 7051 : case DIV:
5943 7051 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5944 7051 : if (overflow)
5945 : return NULL_RTX;
5946 : break;
5947 :
5948 1220 : case MOD:
5949 1220 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5950 1220 : if (overflow)
5951 : return NULL_RTX;
5952 : break;
5953 :
5954 6415 : case UDIV:
5955 6415 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5956 6415 : if (overflow)
5957 : return NULL_RTX;
5958 : break;
5959 :
5960 15996 : case UMOD:
5961 15996 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5962 15996 : if (overflow)
5963 : return NULL_RTX;
5964 : break;
5965 :
5966 696658 : case AND:
5967 696658 : result = wi::bit_and (pop0, pop1);
5968 696658 : break;
5969 :
5970 270712 : case IOR:
5971 270712 : result = wi::bit_or (pop0, pop1);
5972 270712 : break;
5973 :
5974 56318 : case XOR:
5975 56318 : result = wi::bit_xor (pop0, pop1);
5976 56318 : break;
5977 :
5978 1761 : case SMIN:
5979 1761 : result = wi::smin (pop0, pop1);
5980 1761 : break;
5981 :
5982 1849 : case SMAX:
5983 1849 : result = wi::smax (pop0, pop1);
5984 1849 : break;
5985 :
5986 3400 : case UMIN:
5987 3400 : result = wi::umin (pop0, pop1);
5988 3400 : break;
5989 :
5990 2998 : case UMAX:
5991 2998 : result = wi::umax (pop0, pop1);
5992 2998 : break;
5993 :
5994 4736118 : case LSHIFTRT:
5995 4736118 : case ASHIFTRT:
5996 4736118 : case ASHIFT:
5997 4736118 : case SS_ASHIFT:
5998 4736118 : case US_ASHIFT:
5999 4736118 : {
6000 : /* The shift count might be in SImode while int_mode might
6001 : be narrower. On IA-64 it is even DImode. If the shift
6002 : count is too large and doesn't fit into int_mode, we'd
6003 : ICE. So, if int_mode is narrower than
6004 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6005 4736118 : if (GET_MODE (op1) == VOIDmode
6006 4736118 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6007 1829297 : pop1 = rtx_mode_t (op1, DImode);
6008 :
6009 4736118 : wide_int wop1 = pop1;
6010 4736118 : if (SHIFT_COUNT_TRUNCATED)
6011 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
6012 4736118 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
6013 132 : return NULL_RTX;
6014 :
6015 4735986 : switch (code)
6016 : {
6017 2742060 : case LSHIFTRT:
6018 2742060 : result = wi::lrshift (pop0, wop1);
6019 2742060 : break;
6020 :
6021 71402 : case ASHIFTRT:
6022 71402 : result = wi::arshift (pop0, wop1);
6023 71402 : break;
6024 :
6025 1922524 : case ASHIFT:
6026 1922524 : result = wi::lshift (pop0, wop1);
6027 1922524 : break;
6028 :
6029 0 : case SS_ASHIFT:
6030 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
6031 0 : result = wi::lshift (pop0, wop1);
6032 0 : else if (wi::neg_p (pop0))
6033 0 : result = wi::min_value (int_mode, SIGNED);
6034 : else
6035 0 : result = wi::max_value (int_mode, SIGNED);
6036 : break;
6037 :
6038 0 : case US_ASHIFT:
6039 0 : if (wi::eq_p (pop0, 0))
6040 0 : result = pop0;
6041 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
6042 0 : result = wi::lshift (pop0, wop1);
6043 : else
6044 0 : result = wi::max_value (int_mode, UNSIGNED);
6045 : break;
6046 :
6047 0 : default:
6048 0 : gcc_unreachable ();
6049 : }
6050 4735986 : break;
6051 4736118 : }
6052 34513 : case ROTATE:
6053 34513 : case ROTATERT:
6054 34513 : {
6055 : /* The rotate count might be in SImode while int_mode might
6056 : be narrower. On IA-64 it is even DImode. If the shift
6057 : count is too large and doesn't fit into int_mode, we'd
6058 : ICE. So, if int_mode is narrower than
6059 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6060 34513 : if (GET_MODE (op1) == VOIDmode
6061 34513 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6062 27541 : pop1 = rtx_mode_t (op1, DImode);
6063 :
6064 34513 : if (wi::neg_p (pop1))
6065 : return NULL_RTX;
6066 :
6067 34413 : switch (code)
6068 : {
6069 11605 : case ROTATE:
6070 11605 : result = wi::lrotate (pop0, pop1);
6071 11605 : break;
6072 :
6073 22808 : case ROTATERT:
6074 22808 : result = wi::rrotate (pop0, pop1);
6075 22808 : break;
6076 :
6077 0 : default:
6078 0 : gcc_unreachable ();
6079 : }
6080 : break;
6081 : }
6082 :
6083 2270 : case SS_PLUS:
6084 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
6085 4484 : clamp_signed_saturation:
6086 4484 : if (overflow == wi::OVF_OVERFLOW)
6087 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
6088 4170 : else if (overflow == wi::OVF_UNDERFLOW)
6089 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
6090 3892 : else if (overflow != wi::OVF_NONE)
6091 : return NULL_RTX;
6092 : break;
6093 :
6094 2220 : case US_PLUS:
6095 2220 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6096 2220 : clamp_unsigned_saturation:
6097 2220 : if (overflow != wi::OVF_NONE)
6098 461 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6099 : break;
6100 :
6101 2214 : case SS_MINUS:
6102 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6103 2214 : goto clamp_signed_saturation;
6104 :
6105 1852 : case US_MINUS:
6106 1852 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6107 1852 : if (overflow != wi::OVF_NONE)
6108 1203 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6109 : break;
6110 :
6111 0 : case SS_MULT:
6112 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6113 0 : goto clamp_signed_saturation;
6114 :
6115 0 : case US_MULT:
6116 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6117 0 : goto clamp_unsigned_saturation;
6118 :
6119 8 : case SMUL_HIGHPART:
6120 8 : result = wi::mul_high (pop0, pop1, SIGNED);
6121 8 : break;
6122 :
6123 0 : case UMUL_HIGHPART:
6124 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6125 0 : break;
6126 :
6127 : default:
6128 : return NULL_RTX;
6129 : }
6130 33149862 : return immed_wide_int_const (result, int_mode);
6131 33152290 : }
6132 :
6133 : /* Handle polynomial integers. */
6134 : if (NUM_POLY_INT_COEFFS > 1
6135 : && is_a <scalar_int_mode> (mode, &int_mode)
6136 : && poly_int_rtx_p (op0)
6137 : && poly_int_rtx_p (op1))
6138 : {
6139 : poly_wide_int result;
6140 : switch (code)
6141 : {
6142 : case PLUS:
6143 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6144 : break;
6145 :
6146 : case MINUS:
6147 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6148 : break;
6149 :
6150 : case MULT:
6151 : if (CONST_SCALAR_INT_P (op1))
6152 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6153 : else
6154 : return NULL_RTX;
6155 : break;
6156 :
6157 : case ASHIFT:
6158 : if (CONST_SCALAR_INT_P (op1))
6159 : {
6160 : wide_int shift
6161 : = rtx_mode_t (op1,
6162 : GET_MODE (op1) == VOIDmode
6163 : && (GET_MODE_PRECISION (int_mode)
6164 : < HOST_BITS_PER_WIDE_INT)
6165 : ? DImode : mode);
6166 : if (SHIFT_COUNT_TRUNCATED)
6167 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6168 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6169 : return NULL_RTX;
6170 : result = wi::to_poly_wide (op0, mode) << shift;
6171 : }
6172 : else
6173 : return NULL_RTX;
6174 : break;
6175 :
6176 : case IOR:
6177 : if (!CONST_SCALAR_INT_P (op1)
6178 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6179 : rtx_mode_t (op1, mode), &result))
6180 : return NULL_RTX;
6181 : break;
6182 :
6183 : default:
6184 : return NULL_RTX;
6185 : }
6186 : return immed_wide_int_const (result, int_mode);
6187 : }
6188 :
6189 : return NULL_RTX;
6190 : }
6191 :
6192 :
6193 :
6194 : /* Return a positive integer if X should sort after Y. The value
6195 : returned is 1 if and only if X and Y are both regs. */
6196 :
6197 : static int
6198 115528938 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6199 : {
6200 115528938 : int result;
6201 :
6202 115528938 : result = (commutative_operand_precedence (y)
6203 115528938 : - commutative_operand_precedence (x));
6204 115528938 : if (result)
6205 81690527 : return result + result;
6206 :
6207 : /* Group together equal REGs to do more simplification. */
6208 33838411 : if (REG_P (x) && REG_P (y))
6209 8587179 : return REGNO (x) > REGNO (y);
6210 :
6211 : return 0;
6212 : }
6213 :
6214 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6215 : operands may be another PLUS or MINUS.
6216 :
6217 : Rather than test for specific case, we do this by a brute-force method
6218 : and do all possible simplifications until no more changes occur. Then
6219 : we rebuild the operation.
6220 :
6221 : May return NULL_RTX when no changes were made. */
6222 :
6223 : rtx
6224 38782559 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6225 : rtx op0, rtx op1)
6226 : {
6227 38782559 : struct simplify_plus_minus_op_data
6228 : {
6229 : rtx op;
6230 : short neg;
6231 : } ops[16];
6232 38782559 : rtx result, tem;
6233 38782559 : int n_ops = 2;
6234 38782559 : int changed, n_constants, canonicalized = 0;
6235 38782559 : int i, j;
6236 :
6237 38782559 : memset (ops, 0, sizeof ops);
6238 :
6239 : /* Set up the two operands and then expand them until nothing has been
6240 : changed. If we run out of room in our array, give up; this should
6241 : almost never happen. */
6242 :
6243 38782559 : ops[0].op = op0;
6244 38782559 : ops[0].neg = 0;
6245 38782559 : ops[1].op = op1;
6246 38782559 : ops[1].neg = (code == MINUS);
6247 :
6248 78958200 : do
6249 : {
6250 78958200 : changed = 0;
6251 78958200 : n_constants = 0;
6252 :
6253 319818188 : for (i = 0; i < n_ops; i++)
6254 : {
6255 240860003 : rtx this_op = ops[i].op;
6256 240860003 : int this_neg = ops[i].neg;
6257 240860003 : enum rtx_code this_code = GET_CODE (this_op);
6258 :
6259 240860003 : switch (this_code)
6260 : {
6261 39209540 : case PLUS:
6262 39209540 : case MINUS:
6263 39209540 : if (n_ops == ARRAY_SIZE (ops))
6264 : return NULL_RTX;
6265 :
6266 39209525 : ops[n_ops].op = XEXP (this_op, 1);
6267 39209525 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6268 39209525 : n_ops++;
6269 :
6270 39209525 : ops[i].op = XEXP (this_op, 0);
6271 39209525 : changed = 1;
6272 : /* If this operand was negated then we will potentially
6273 : canonicalize the expression. Similarly if we don't
6274 : place the operands adjacent we're re-ordering the
6275 : expression and thus might be performing a
6276 : canonicalization. Ignore register re-ordering.
6277 : ??? It might be better to shuffle the ops array here,
6278 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6279 : be seen as non-canonical. */
6280 39209525 : if (this_neg
6281 38528520 : || (i != n_ops - 2
6282 37841912 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6283 240859988 : canonicalized = 1;
6284 : break;
6285 :
6286 1696 : case NEG:
6287 1696 : ops[i].op = XEXP (this_op, 0);
6288 1696 : ops[i].neg = ! this_neg;
6289 1696 : changed = 1;
6290 1696 : canonicalized = 1;
6291 1696 : break;
6292 :
6293 1623762 : case CONST:
6294 1623762 : if (n_ops != ARRAY_SIZE (ops)
6295 1623762 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6296 1490446 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6297 1469687 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6298 : {
6299 1469687 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6300 1469687 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6301 1469687 : ops[n_ops].neg = this_neg;
6302 1469687 : n_ops++;
6303 1469687 : changed = 1;
6304 1469687 : canonicalized = 1;
6305 : }
6306 : break;
6307 :
6308 40427 : case NOT:
6309 : /* ~a -> (-a - 1) */
6310 40427 : if (n_ops != ARRAY_SIZE (ops))
6311 : {
6312 40427 : ops[n_ops].op = CONSTM1_RTX (mode);
6313 40427 : ops[n_ops++].neg = this_neg;
6314 40427 : ops[i].op = XEXP (this_op, 0);
6315 40427 : ops[i].neg = !this_neg;
6316 40427 : changed = 1;
6317 40427 : canonicalized = 1;
6318 : }
6319 : break;
6320 :
6321 120002136 : CASE_CONST_SCALAR_INT:
6322 120002136 : case CONST_POLY_INT:
6323 120002136 : n_constants++;
6324 120002136 : if (this_neg)
6325 : {
6326 1168559 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6327 1168559 : ops[i].neg = 0;
6328 1168559 : changed = 1;
6329 1168559 : canonicalized = 1;
6330 : }
6331 : break;
6332 :
6333 : default:
6334 : break;
6335 : }
6336 : }
6337 : }
6338 78958185 : while (changed);
6339 :
6340 38782544 : if (n_constants > 1)
6341 23483415 : canonicalized = 1;
6342 :
6343 38782544 : gcc_assert (n_ops >= 2);
6344 :
6345 : /* If we only have two operands, we can avoid the loops. */
6346 38782544 : if (n_ops == 2)
6347 : {
6348 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6349 0 : rtx lhs, rhs;
6350 :
6351 : /* Get the two operands. Be careful with the order, especially for
6352 : the cases where code == MINUS. */
6353 0 : if (ops[0].neg && ops[1].neg)
6354 : {
6355 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6356 0 : rhs = ops[1].op;
6357 : }
6358 0 : else if (ops[0].neg)
6359 : {
6360 0 : lhs = ops[1].op;
6361 0 : rhs = ops[0].op;
6362 : }
6363 : else
6364 : {
6365 0 : lhs = ops[0].op;
6366 0 : rhs = ops[1].op;
6367 : }
6368 :
6369 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6370 : }
6371 :
6372 : /* Now simplify each pair of operands until nothing changes. */
6373 63042138 : while (1)
6374 : {
6375 : /* Insertion sort is good enough for a small array. */
6376 167344453 : for (i = 1; i < n_ops; i++)
6377 : {
6378 104302315 : struct simplify_plus_minus_op_data save;
6379 104302315 : int cmp;
6380 :
6381 104302315 : j = i - 1;
6382 104302315 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6383 104302315 : if (cmp <= 0)
6384 91353045 : continue;
6385 : /* Just swapping registers doesn't count as canonicalization. */
6386 12949270 : if (cmp != 1)
6387 9983702 : canonicalized = 1;
6388 :
6389 12949270 : save = ops[i];
6390 15386423 : do
6391 15386423 : ops[j + 1] = ops[j];
6392 15386423 : while (j--
6393 28335693 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6394 12949270 : ops[j + 1] = save;
6395 : }
6396 :
6397 63042138 : changed = 0;
6398 167344453 : for (i = n_ops - 1; i > 0; i--)
6399 250526007 : for (j = i - 1; j >= 0; j--)
6400 : {
6401 147167685 : rtx lhs = ops[j].op, rhs = ops[i].op;
6402 147167685 : int lneg = ops[j].neg, rneg = ops[i].neg;
6403 :
6404 147167685 : if (lhs != 0 && rhs != 0)
6405 : {
6406 122025184 : enum rtx_code ncode = PLUS;
6407 :
6408 122025184 : if (lneg != rneg)
6409 : {
6410 10384288 : ncode = MINUS;
6411 10384288 : if (lneg)
6412 6653169 : std::swap (lhs, rhs);
6413 : }
6414 111640896 : else if (swap_commutative_operands_p (lhs, rhs))
6415 211768 : std::swap (lhs, rhs);
6416 :
6417 122025184 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6418 27952525 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6419 : {
6420 23632562 : rtx tem_lhs, tem_rhs;
6421 :
6422 23632562 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6423 23632562 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6424 23632562 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6425 : tem_rhs);
6426 :
6427 23632562 : if (tem && !CONSTANT_P (tem))
6428 1757 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6429 : }
6430 : else
6431 98392622 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6432 :
6433 98394379 : if (tem)
6434 : {
6435 : /* Reject "simplifications" that just wrap the two
6436 : arguments in a CONST. Failure to do so can result
6437 : in infinite recursion with simplify_binary_operation
6438 : when it calls us to simplify CONST operations.
6439 : Also, if we find such a simplification, don't try
6440 : any more combinations with this rhs: We must have
6441 : something like symbol+offset, ie. one of the
6442 : trivial CONST expressions we handle later. */
6443 25664262 : if (GET_CODE (tem) == CONST
6444 945750 : && GET_CODE (XEXP (tem, 0)) == ncode
6445 945198 : && XEXP (XEXP (tem, 0), 0) == lhs
6446 943993 : && XEXP (XEXP (tem, 0), 1) == rhs)
6447 : break;
6448 24720269 : lneg &= rneg;
6449 24720269 : if (GET_CODE (tem) == NEG)
6450 45617 : tem = XEXP (tem, 0), lneg = !lneg;
6451 24720269 : if (poly_int_rtx_p (tem) && lneg)
6452 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6453 :
6454 24720269 : ops[i].op = tem;
6455 24720269 : ops[i].neg = lneg;
6456 24720269 : ops[j].op = NULL_RTX;
6457 24720269 : changed = 1;
6458 24720269 : canonicalized = 1;
6459 : }
6460 : }
6461 : }
6462 :
6463 63042138 : if (!changed)
6464 : break;
6465 :
6466 : /* Pack all the operands to the lower-numbered entries. */
6467 98039799 : for (i = 0, j = 0; j < n_ops; j++)
6468 73780205 : if (ops[j].op)
6469 : {
6470 49059936 : ops[i] = ops[j];
6471 49059936 : i++;
6472 : }
6473 : n_ops = i;
6474 : }
6475 :
6476 : /* If nothing changed, check that rematerialization of rtl instructions
6477 : is still required. */
6478 38782544 : if (!canonicalized)
6479 : {
6480 : /* Perform rematerialization if only all operands are registers and
6481 : all operations are PLUS. */
6482 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6483 : around rs6000 and how it uses the CA register. See PR67145. */
6484 5092823 : for (i = 0; i < n_ops; i++)
6485 4107597 : if (ops[i].neg
6486 3837861 : || !REG_P (ops[i].op)
6487 7367694 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6488 312911 : && fixed_regs[REGNO (ops[i].op)]
6489 189 : && !global_regs[REGNO (ops[i].op)]
6490 189 : && ops[i].op != frame_pointer_rtx
6491 101 : && ops[i].op != arg_pointer_rtx
6492 88 : && ops[i].op != stack_pointer_rtx))
6493 : return NULL_RTX;
6494 985226 : goto gen_result;
6495 : }
6496 :
6497 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6498 36949818 : if (n_ops == 2
6499 22548572 : && CONST_INT_P (ops[1].op)
6500 22087750 : && CONSTANT_P (ops[0].op)
6501 162 : && ops[0].neg)
6502 56 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6503 :
6504 : /* We suppressed creation of trivial CONST expressions in the
6505 : combination loop to avoid recursion. Create one manually now.
6506 : The combination loop should have ensured that there is exactly
6507 : one CONST_INT, and the sort will have ensured that it is last
6508 : in the array and that any other constant will be next-to-last. */
6509 :
6510 36949762 : if (n_ops > 1
6511 36433312 : && poly_int_rtx_p (ops[n_ops - 1].op)
6512 71158478 : && CONSTANT_P (ops[n_ops - 2].op))
6513 : {
6514 1541048 : rtx value = ops[n_ops - 1].op;
6515 1541048 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6516 682386 : value = neg_poly_int_rtx (mode, value);
6517 1541048 : if (CONST_INT_P (value))
6518 : {
6519 3082096 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6520 1541048 : INTVAL (value));
6521 1541048 : n_ops--;
6522 : }
6523 : }
6524 :
6525 : /* Put a non-negated operand first, if possible. */
6526 :
6527 38616351 : for (i = 0; i < n_ops && ops[i].neg; i++)
6528 1666589 : continue;
6529 36949762 : if (i == n_ops)
6530 9532 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6531 36940230 : else if (i != 0)
6532 : {
6533 1564822 : tem = ops[0].op;
6534 1564822 : ops[0] = ops[i];
6535 1564822 : ops[i].op = tem;
6536 1564822 : ops[i].neg = 1;
6537 : }
6538 :
6539 : /* Now make the result by performing the requested operations. */
6540 35375408 : gen_result:
6541 37934988 : result = ops[0].op;
6542 89478682 : for (i = 1; i < n_ops; i++)
6543 103087388 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6544 : mode, result, ops[i].op);
6545 :
6546 : return result;
6547 1666589 : }
6548 :
6549 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6550 : static bool
6551 522818890 : plus_minus_operand_p (const_rtx x)
6552 : {
6553 522818890 : return GET_CODE (x) == PLUS
6554 522818890 : || GET_CODE (x) == MINUS
6555 522818890 : || (GET_CODE (x) == CONST
6556 1974932 : && GET_CODE (XEXP (x, 0)) == PLUS
6557 1352389 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6558 1278549 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6559 : }
6560 :
6561 : /* Like simplify_binary_operation except used for relational operators.
6562 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6563 : not also be VOIDmode.
6564 :
6565 : CMP_MODE specifies in which mode the comparison is done in, so it is
6566 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6567 : the operands or, if both are VOIDmode, the operands are compared in
6568 : "infinite precision". */
6569 : rtx
6570 128274908 : simplify_context::simplify_relational_operation (rtx_code code,
6571 : machine_mode mode,
6572 : machine_mode cmp_mode,
6573 : rtx op0, rtx op1)
6574 : {
6575 128274908 : rtx tem, trueop0, trueop1;
6576 :
6577 128274908 : if (cmp_mode == VOIDmode)
6578 28147955 : cmp_mode = GET_MODE (op0);
6579 28147955 : if (cmp_mode == VOIDmode)
6580 282498 : cmp_mode = GET_MODE (op1);
6581 :
6582 128274908 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6583 128274908 : if (tem)
6584 783513 : return relational_result (mode, cmp_mode, tem);
6585 :
6586 : /* For the following tests, ensure const0_rtx is op1. */
6587 127491395 : if (swap_commutative_operands_p (op0, op1)
6588 127491395 : || (op0 == const0_rtx && op1 != const0_rtx))
6589 2613452 : std::swap (op0, op1), code = swap_condition (code);
6590 :
6591 : /* If op0 is a compare, extract the comparison arguments from it. */
6592 127491395 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6593 13845246 : return simplify_gen_relational (code, mode, VOIDmode,
6594 13845246 : XEXP (op0, 0), XEXP (op0, 1));
6595 :
6596 113646149 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6597 : return NULL_RTX;
6598 :
6599 83659670 : trueop0 = avoid_constant_pool_reference (op0);
6600 83659670 : trueop1 = avoid_constant_pool_reference (op1);
6601 83659670 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6602 83659670 : trueop0, trueop1);
6603 : }
6604 :
6605 : /* This part of simplify_relational_operation is only used when CMP_MODE
6606 : is not in class MODE_CC (i.e. it is a real comparison).
6607 :
6608 : MODE is the mode of the result, while CMP_MODE specifies in which
6609 : mode the comparison is done in, so it is the mode of the operands. */
6610 :
6611 : rtx
6612 83659670 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6613 : machine_mode mode,
6614 : machine_mode cmp_mode,
6615 : rtx op0, rtx op1)
6616 : {
6617 83659670 : enum rtx_code op0code = GET_CODE (op0);
6618 :
6619 83659670 : if (op1 == const0_rtx && COMPARISON_P (op0))
6620 : {
6621 : /* If op0 is a comparison, extract the comparison arguments
6622 : from it. */
6623 266345 : if (code == NE)
6624 : {
6625 118682 : if (GET_MODE (op0) == mode)
6626 187 : return simplify_rtx (op0);
6627 : else
6628 118495 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6629 118495 : XEXP (op0, 0), XEXP (op0, 1));
6630 : }
6631 147663 : else if (code == EQ)
6632 : {
6633 116123 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6634 116123 : if (new_code != UNKNOWN)
6635 115806 : return simplify_gen_relational (new_code, mode, VOIDmode,
6636 115806 : XEXP (op0, 0), XEXP (op0, 1));
6637 : }
6638 : }
6639 :
6640 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6641 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6642 83425182 : if ((code == LTU || code == GEU)
6643 5159985 : && GET_CODE (op0) == PLUS
6644 713899 : && CONST_INT_P (XEXP (op0, 1))
6645 489229 : && (rtx_equal_p (op1, XEXP (op0, 0))
6646 351803 : || rtx_equal_p (op1, XEXP (op0, 1)))
6647 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6648 83629541 : && XEXP (op0, 1) != const0_rtx)
6649 : {
6650 204359 : rtx new_cmp
6651 204359 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6652 205877 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6653 204359 : cmp_mode, XEXP (op0, 0), new_cmp);
6654 : }
6655 :
6656 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6657 : transformed into (LTU a -C). */
6658 83220823 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6659 339329 : && CONST_INT_P (XEXP (op0, 1))
6660 261310 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6661 28874 : && XEXP (op0, 1) != const0_rtx)
6662 : {
6663 28874 : rtx new_cmp
6664 28874 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6665 28874 : return simplify_gen_relational (LTU, mode, cmp_mode,
6666 28874 : XEXP (op0, 0), new_cmp);
6667 : }
6668 :
6669 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6670 83191949 : if ((code == LTU || code == GEU)
6671 4955626 : && GET_CODE (op0) == PLUS
6672 509540 : && rtx_equal_p (op1, XEXP (op0, 1))
6673 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6674 83197352 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6675 5403 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6676 5403 : copy_rtx (XEXP (op0, 0)));
6677 :
6678 83186546 : if (op1 == const0_rtx)
6679 : {
6680 : /* Canonicalize (GTU x 0) as (NE x 0). */
6681 36942529 : if (code == GTU)
6682 75962 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6683 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6684 36866567 : if (code == LEU)
6685 32741 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6686 :
6687 36833826 : if ((code == NE || code == EQ)
6688 : /* Verify op0 is IOR */
6689 33188886 : && GET_CODE (op0) == IOR
6690 : /* only enters if op1 is 0 */
6691 : /* Verify IOR operand is NE */
6692 543108 : && GET_CODE (XEXP (op0, 0)) == NE
6693 16449 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6694 : /* Verify second NE operand is 0 */
6695 110 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6696 : {
6697 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6698 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6699 31 : return t;
6700 : }
6701 :
6702 : }
6703 46244017 : else if (op1 == const1_rtx)
6704 : {
6705 3077277 : switch (code)
6706 : {
6707 8329 : case GE:
6708 : /* Canonicalize (GE x 1) as (GT x 0). */
6709 8329 : return simplify_gen_relational (GT, mode, cmp_mode,
6710 8329 : op0, const0_rtx);
6711 197302 : case GEU:
6712 : /* Canonicalize (GEU x 1) as (NE x 0). */
6713 197302 : return simplify_gen_relational (NE, mode, cmp_mode,
6714 197302 : op0, const0_rtx);
6715 10161 : case LT:
6716 : /* Canonicalize (LT x 1) as (LE x 0). */
6717 10161 : return simplify_gen_relational (LE, mode, cmp_mode,
6718 10161 : op0, const0_rtx);
6719 51887 : case LTU:
6720 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6721 51887 : return simplify_gen_relational (EQ, mode, cmp_mode,
6722 51887 : op0, const0_rtx);
6723 : default:
6724 : break;
6725 : }
6726 : }
6727 43166740 : else if (op1 == constm1_rtx)
6728 : {
6729 : /* Canonicalize (LE x -1) as (LT x 0). */
6730 999840 : if (code == LE)
6731 1568 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6732 : /* Canonicalize (GT x -1) as (GE x 0). */
6733 998272 : if (code == GT)
6734 5178 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6735 : }
6736 :
6737 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6738 79158447 : if ((code == EQ || code == NE)
6739 61817371 : && (op0code == PLUS || op0code == MINUS)
6740 2449525 : && CONSTANT_P (op1)
6741 894787 : && CONSTANT_P (XEXP (op0, 1))
6742 504600 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6743 : {
6744 504567 : rtx x = XEXP (op0, 0);
6745 504567 : rtx c = XEXP (op0, 1);
6746 504567 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6747 504567 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6748 :
6749 : /* Detect an infinite recursive condition, where we oscillate at this
6750 : simplification case between:
6751 : A + B == C <---> C - B == A,
6752 : where A, B, and C are all constants with non-simplifiable expressions,
6753 : usually SYMBOL_REFs. */
6754 504567 : if (GET_CODE (tem) == invcode
6755 46 : && CONSTANT_P (x)
6756 504585 : && rtx_equal_p (c, XEXP (tem, 1)))
6757 : return NULL_RTX;
6758 :
6759 504549 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6760 : }
6761 :
6762 : /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0). */
6763 61312804 : if ((code == EQ || code == NE)
6764 61312804 : && op0code == PLUS
6765 1612743 : && rtx_equal_p (XEXP (op0, 1), op1)
6766 3611 : && !side_effects_p (op1)
6767 3611 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6768 3599 : return simplify_gen_relational (code, mode, cmp_mode,
6769 3599 : XEXP (op0, 0), CONST0_RTX (cmp_mode));
6770 :
6771 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6772 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6773 82295221 : scalar_int_mode int_mode, int_cmp_mode;
6774 82295221 : if (code == NE
6775 32413603 : && op1 == const0_rtx
6776 2186447 : && is_int_mode (mode, &int_mode)
6777 84408034 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6778 : /* ??? Work-around BImode bugs in the ia64 backend. */
6779 2186447 : && int_mode != BImode
6780 2186423 : && int_cmp_mode != BImode
6781 2186423 : && nonzero_bits (op0, int_cmp_mode) == 1
6782 82295221 : && STORE_FLAG_VALUE == 1)
6783 147268 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6784 73634 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6785 18139 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6786 :
6787 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6788 82221587 : if ((code == EQ || code == NE)
6789 61235571 : && op1 == const0_rtx
6790 33042420 : && op0code == XOR)
6791 13294 : return simplify_gen_relational (code, mode, cmp_mode,
6792 13294 : XEXP (op0, 0), XEXP (op0, 1));
6793 :
6794 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6795 61222277 : if ((code == EQ || code == NE)
6796 61222277 : && op0code == XOR
6797 4468 : && rtx_equal_p (XEXP (op0, 0), op1)
6798 6 : && !side_effects_p (XEXP (op0, 0)))
6799 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6800 0 : CONST0_RTX (mode));
6801 :
6802 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6803 82208293 : if ((code == EQ || code == NE)
6804 61222277 : && op0code == XOR
6805 4468 : && rtx_equal_p (XEXP (op0, 1), op1)
6806 82208446 : && !side_effects_p (XEXP (op0, 1)))
6807 153 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6808 153 : CONST0_RTX (mode));
6809 :
6810 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6811 82208140 : if ((code == EQ || code == NE)
6812 61222124 : && op0code == XOR
6813 4315 : && CONST_SCALAR_INT_P (op1)
6814 975 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6815 437 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6816 : simplify_gen_binary (XOR, cmp_mode,
6817 437 : XEXP (op0, 1), op1));
6818 :
6819 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6820 : constant folding if x/y is a constant. */
6821 61221687 : if ((code == EQ || code == NE)
6822 61221687 : && (op0code == AND || op0code == IOR)
6823 3747177 : && !side_effects_p (op1)
6824 3747071 : && op1 != CONST0_RTX (cmp_mode))
6825 : {
6826 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6827 : (eq/ne (and (not y) x) 0). */
6828 401138 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6829 804323 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6830 : {
6831 24893 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6832 : cmp_mode);
6833 24893 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6834 :
6835 24893 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6836 24893 : CONST0_RTX (cmp_mode));
6837 : }
6838 :
6839 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6840 : (eq/ne (and (not x) y) 0). */
6841 376322 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6842 737074 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6843 : {
6844 42376 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6845 : cmp_mode);
6846 42376 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6847 :
6848 42376 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6849 42376 : CONST0_RTX (cmp_mode));
6850 : }
6851 : }
6852 :
6853 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6854 : relationship. */
6855 82140434 : if ((op0code == AND || op0code == IOR)
6856 3861068 : && CONST_INT_P (op1)
6857 3683682 : && CONST_INT_P (XEXP (op0, 1)))
6858 : {
6859 2501210 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6860 2501210 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6861 :
6862 : /* For AND operations:
6863 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6864 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6865 : - (x & c1) >= c2 when c1 is less than c2 -> false
6866 : - (x & c1) < c2 when c1 is less than c2 -> true
6867 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6868 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6869 :
6870 : For IOR operations:
6871 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6872 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6873 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6874 : - (x | c1) > c2 when c1 is greater than c2 -> true
6875 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6876 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6877 2501210 : if ((op0code == AND
6878 2496968 : && ((code == EQ && (c1 & c2) != c2)
6879 2496955 : || (code == GEU && c1 < c2)
6880 2496955 : || (code == GTU && c1 <= c2)))
6881 2501197 : || ((op0code == IOR
6882 4242 : && ((code == EQ && (c1 & c2) != c1)
6883 4238 : || (code == LEU && c1 > c2)
6884 4238 : || (code == LTU && c1 >= c2)))))
6885 17 : return const0_rtx;
6886 :
6887 2501193 : if ((op0code == AND
6888 2496955 : && ((code == NE && (c1 & c2) != c2)
6889 2496880 : || (code == LTU && c1 < c2)
6890 2496880 : || (code == LEU && c1 <= c2)))
6891 2501118 : || ((op0code == IOR
6892 4238 : && ((code == NE && (c1 & c2) != c1)
6893 4178 : || (code == GTU && c1 > c2)
6894 4178 : || (code == GEU && c1 >= c2)))))
6895 135 : return const_true_rtx;
6896 : }
6897 :
6898 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6899 82140282 : if ((code == EQ || code == NE)
6900 61154266 : && GET_CODE (op0) == BSWAP
6901 324 : && CONST_SCALAR_INT_P (op1))
6902 93 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6903 : simplify_gen_unary (BSWAP, cmp_mode,
6904 93 : op1, cmp_mode));
6905 :
6906 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6907 61154173 : if ((code == EQ || code == NE)
6908 61154173 : && GET_CODE (op0) == BSWAP
6909 231 : && GET_CODE (op1) == BSWAP)
6910 18 : return simplify_gen_relational (code, mode, cmp_mode,
6911 18 : XEXP (op0, 0), XEXP (op1, 0));
6912 :
6913 82140171 : if (op0code == POPCOUNT && op1 == const0_rtx)
6914 0 : switch (code)
6915 : {
6916 0 : case EQ:
6917 0 : case LE:
6918 0 : case LEU:
6919 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6920 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6921 : XEXP (op0, 0),
6922 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6923 :
6924 0 : case NE:
6925 0 : case GT:
6926 0 : case GTU:
6927 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6928 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6929 : XEXP (op0, 0),
6930 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6931 :
6932 : default:
6933 : break;
6934 : }
6935 :
6936 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6937 82140171 : if (code == NE
6938 32298987 : && op1 == const0_rtx
6939 16484261 : && (op0code == TRUNCATE
6940 147413 : || (partial_subreg_p (op0)
6941 146669 : && subreg_lowpart_p (op0)))
6942 123265 : && SCALAR_INT_MODE_P (mode)
6943 82140171 : && STORE_FLAG_VALUE == 1)
6944 : {
6945 30781 : rtx tmp = XEXP (op0, 0);
6946 30781 : if (GET_CODE (tmp) == ASHIFT
6947 2440 : && GET_MODE (tmp) == mode
6948 229 : && CONST_INT_P (XEXP (tmp, 1))
6949 229 : && is_int_mode (GET_MODE (op0), &int_mode)
6950 31010 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6951 229 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6952 : }
6953 :
6954 : /* For two unsigned booleans A and B:
6955 :
6956 : A > B == ~B & A
6957 : A >= B == ~B | A
6958 : A < B == ~A & B
6959 : A <= B == ~A | B
6960 : A == B == ~A ^ B (== ~B ^ A)
6961 : A != B == A ^ B
6962 :
6963 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
6964 : with the rules above applying for positive STORE_FLAG_VALUE and with
6965 : the relations reversed for negative STORE_FLAG_VALUE. */
6966 82139942 : if (is_a<scalar_int_mode> (cmp_mode)
6967 79550003 : && COMPARISON_P (op0)
6968 82252514 : && COMPARISON_P (op1))
6969 : {
6970 10007 : rtx t = NULL_RTX;
6971 10007 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
6972 755 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
6973 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
6974 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
6975 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
6976 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
6977 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
6978 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
6979 : else if (code == EQ)
6980 3241 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
6981 : else if (code == NE)
6982 3851 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
6983 10007 : if (t)
6984 : return t;
6985 : }
6986 :
6987 : return NULL_RTX;
6988 : }
6989 :
6990 : enum
6991 : {
6992 : CMP_EQ = 1,
6993 : CMP_LT = 2,
6994 : CMP_GT = 4,
6995 : CMP_LTU = 8,
6996 : CMP_GTU = 16
6997 : };
6998 :
6999 :
7000 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
7001 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
7002 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
7003 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
7004 : For floating-point comparisons, assume that the operands were ordered. */
7005 :
7006 : static rtx
7007 713544 : comparison_result (enum rtx_code code, int known_results)
7008 : {
7009 713544 : switch (code)
7010 : {
7011 131018 : case EQ:
7012 131018 : case UNEQ:
7013 131018 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
7014 445322 : case NE:
7015 445322 : case LTGT:
7016 445322 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
7017 :
7018 9498 : case LT:
7019 9498 : case UNLT:
7020 9498 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
7021 8621 : case GE:
7022 8621 : case UNGE:
7023 8621 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
7024 :
7025 12711 : case GT:
7026 12711 : case UNGT:
7027 12711 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
7028 14693 : case LE:
7029 14693 : case UNLE:
7030 14693 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
7031 :
7032 24320 : case LTU:
7033 24320 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
7034 8831 : case GEU:
7035 8831 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
7036 :
7037 47991 : case GTU:
7038 47991 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
7039 10531 : case LEU:
7040 10531 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
7041 :
7042 0 : case ORDERED:
7043 0 : return const_true_rtx;
7044 8 : case UNORDERED:
7045 8 : return const0_rtx;
7046 0 : default:
7047 0 : gcc_unreachable ();
7048 : }
7049 : }
7050 :
7051 : /* Check if the given comparison (done in the given MODE) is actually
7052 : a tautology or a contradiction. If the mode is VOIDmode, the
7053 : comparison is done in "infinite precision". If no simplification
7054 : is possible, this function returns zero. Otherwise, it returns
7055 : either const_true_rtx or const0_rtx. */
7056 :
7057 : rtx
7058 128365052 : simplify_const_relational_operation (enum rtx_code code,
7059 : machine_mode mode,
7060 : rtx op0, rtx op1)
7061 : {
7062 135129561 : rtx tem;
7063 135129561 : rtx trueop0;
7064 135129561 : rtx trueop1;
7065 :
7066 135129561 : gcc_assert (mode != VOIDmode
7067 : || (GET_MODE (op0) == VOIDmode
7068 : && GET_MODE (op1) == VOIDmode));
7069 :
7070 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
7071 135129561 : if (GET_MODE_CLASS (mode) == MODE_CC
7072 43837760 : && (op1 != const0_rtx
7073 43837760 : || GET_CODE (op0) != COMPARE))
7074 : return NULL_RTX;
7075 :
7076 : /* If op0 is a compare, extract the comparison arguments from it. */
7077 105143082 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
7078 : {
7079 13851281 : op1 = XEXP (op0, 1);
7080 13851281 : op0 = XEXP (op0, 0);
7081 :
7082 13851281 : if (GET_MODE (op0) != VOIDmode)
7083 13694922 : mode = GET_MODE (op0);
7084 156359 : else if (GET_MODE (op1) != VOIDmode)
7085 124582 : mode = GET_MODE (op1);
7086 : else
7087 : return 0;
7088 : }
7089 :
7090 : /* We can't simplify MODE_CC values since we don't know what the
7091 : actual comparison is. */
7092 105111305 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
7093 : return 0;
7094 :
7095 : /* Make sure the constant is second. */
7096 105111305 : if (swap_commutative_operands_p (op0, op1))
7097 : {
7098 3003114 : std::swap (op0, op1);
7099 3003114 : code = swap_condition (code);
7100 : }
7101 :
7102 105111305 : trueop0 = avoid_constant_pool_reference (op0);
7103 105111305 : trueop1 = avoid_constant_pool_reference (op1);
7104 :
7105 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7106 : then simplify a comparison of that with zero. If A and B are both either
7107 : a register or a CONST_INT, this can't help; testing for these cases will
7108 : prevent infinite recursion here and speed things up.
7109 :
7110 : We can only do this for EQ and NE comparisons as otherwise we may
7111 : lose or introduce overflow which we cannot disregard as undefined as
7112 : we do not know the signedness of the operation on either the left or
7113 : the right hand side of the comparison. */
7114 :
7115 105111305 : if (INTEGRAL_MODE_P (mode)
7116 102542883 : && trueop1 != CONST0_RTX (mode)
7117 52332997 : && (code == EQ || code == NE)
7118 33122488 : && ! ((REG_P (op0)
7119 9725624 : || CONST_SCALAR_INT_P (trueop0)
7120 9696813 : || CONST_VECTOR_P (trueop0))
7121 23425695 : && (REG_P (op1)
7122 13959232 : || CONST_SCALAR_INT_P (trueop1)
7123 3315000 : || CONST_VECTOR_P (trueop1)))
7124 13009571 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7125 : /* We cannot do this if tem is a nonzero address. */
7126 6764511 : && ! nonzero_address_p (tem))
7127 6764509 : return simplify_const_relational_operation (signed_condition (code),
7128 6764509 : mode, tem, CONST0_RTX (mode));
7129 :
7130 98346796 : if (! HONOR_NANS (mode) && code == ORDERED)
7131 0 : return const_true_rtx;
7132 :
7133 98346796 : if (! HONOR_NANS (mode) && code == UNORDERED)
7134 8 : return const0_rtx;
7135 :
7136 : /* For modes without NaNs, if the two operands are equal, we know the
7137 : result except if they have side-effects. Even with NaNs we know
7138 : the result of unordered comparisons and, if signaling NaNs are
7139 : irrelevant, also the result of LT/GT/LTGT. */
7140 98346788 : if ((! HONOR_NANS (trueop0)
7141 2082711 : || code == UNEQ || code == UNLE || code == UNGE
7142 : || ((code == LT || code == GT || code == LTGT)
7143 830224 : && ! HONOR_SNANS (trueop0)))
7144 97199158 : && rtx_equal_p (trueop0, trueop1)
7145 98856213 : && ! side_effects_p (trueop0))
7146 509336 : return comparison_result (code, CMP_EQ);
7147 :
7148 : /* If the operands are floating-point constants, see if we can fold
7149 : the result. */
7150 97837452 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7151 1290 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7152 1290 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7153 : {
7154 1290 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7155 1290 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7156 :
7157 : /* Comparisons are unordered iff at least one of the values is NaN. */
7158 1290 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7159 174 : switch (code)
7160 : {
7161 0 : case UNEQ:
7162 0 : case UNLT:
7163 0 : case UNGT:
7164 0 : case UNLE:
7165 0 : case UNGE:
7166 0 : case NE:
7167 0 : case UNORDERED:
7168 0 : return const_true_rtx;
7169 174 : case EQ:
7170 174 : case LT:
7171 174 : case GT:
7172 174 : case LE:
7173 174 : case GE:
7174 174 : case LTGT:
7175 174 : case ORDERED:
7176 174 : return const0_rtx;
7177 : default:
7178 : return 0;
7179 : }
7180 :
7181 1201 : return comparison_result (code,
7182 1201 : (real_equal (d0, d1) ? CMP_EQ :
7183 1201 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7184 : }
7185 :
7186 : /* Otherwise, see if the operands are both integers. */
7187 97836162 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7188 94854193 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7189 : {
7190 : /* It would be nice if we really had a mode here. However, the
7191 : largest int representable on the target is as good as
7192 : infinite. */
7193 203092 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7194 203092 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7195 203092 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7196 :
7197 203092 : if (wi::eq_p (ptrueop0, ptrueop1))
7198 0 : return comparison_result (code, CMP_EQ);
7199 : else
7200 : {
7201 203092 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7202 203092 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7203 203092 : return comparison_result (code, cr);
7204 : }
7205 : }
7206 :
7207 : /* Optimize comparisons with upper and lower bounds. */
7208 97633070 : scalar_int_mode int_mode;
7209 97633070 : if (CONST_INT_P (trueop1)
7210 68373854 : && is_a <scalar_int_mode> (mode, &int_mode)
7211 68373854 : && HWI_COMPUTABLE_MODE_P (int_mode)
7212 165565950 : && !side_effects_p (trueop0))
7213 : {
7214 67782549 : int sign;
7215 67782549 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7216 67782549 : HOST_WIDE_INT val = INTVAL (trueop1);
7217 67782549 : HOST_WIDE_INT mmin, mmax;
7218 :
7219 67782549 : if (code == GEU
7220 67782549 : || code == LEU
7221 64449839 : || code == GTU
7222 64449839 : || code == LTU)
7223 : sign = 0;
7224 : else
7225 67782549 : sign = 1;
7226 :
7227 : /* Get a reduced range if the sign bit is zero. */
7228 67782549 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7229 : {
7230 6387998 : mmin = 0;
7231 6387998 : mmax = nonzero;
7232 : }
7233 : else
7234 : {
7235 61394551 : rtx mmin_rtx, mmax_rtx;
7236 61394551 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7237 :
7238 61394551 : mmin = INTVAL (mmin_rtx);
7239 61394551 : mmax = INTVAL (mmax_rtx);
7240 61394551 : if (sign)
7241 : {
7242 55258369 : unsigned int sign_copies
7243 55258369 : = num_sign_bit_copies (trueop0, int_mode);
7244 :
7245 55258369 : mmin >>= (sign_copies - 1);
7246 55258369 : mmax >>= (sign_copies - 1);
7247 : }
7248 : }
7249 :
7250 67782549 : switch (code)
7251 : {
7252 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7253 611944 : case GEU:
7254 611944 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7255 12750 : return const_true_rtx;
7256 599194 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7257 50 : return const0_rtx;
7258 : break;
7259 920868 : case GE:
7260 920868 : if (val <= mmin)
7261 2069 : return const_true_rtx;
7262 918799 : if (val > mmax)
7263 0 : return const0_rtx;
7264 : break;
7265 :
7266 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7267 2720766 : case LEU:
7268 2720766 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7269 14582 : return const_true_rtx;
7270 2706184 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7271 0 : return const0_rtx;
7272 : break;
7273 2286602 : case LE:
7274 2286602 : if (val >= mmax)
7275 469 : return const_true_rtx;
7276 2286133 : if (val < mmin)
7277 0 : return const0_rtx;
7278 : break;
7279 :
7280 25351621 : case EQ:
7281 : /* x == y is always false for y out of range. */
7282 25351621 : if (val < mmin || val > mmax)
7283 435 : return const0_rtx;
7284 : break;
7285 :
7286 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7287 2367763 : case GTU:
7288 2367763 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7289 39154 : return const0_rtx;
7290 2328609 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7291 0 : return const_true_rtx;
7292 : break;
7293 1787041 : case GT:
7294 1787041 : if (val >= mmax)
7295 336 : return const0_rtx;
7296 1786705 : if (val < mmin)
7297 5 : return const_true_rtx;
7298 : break;
7299 :
7300 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7301 827903 : case LTU:
7302 827903 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7303 2974 : return const0_rtx;
7304 824929 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7305 80692 : return const_true_rtx;
7306 : break;
7307 1104640 : case LT:
7308 1104640 : if (val <= mmin)
7309 2306 : return const0_rtx;
7310 1102334 : if (val > mmax)
7311 3250 : return const_true_rtx;
7312 : break;
7313 :
7314 29803401 : case NE:
7315 : /* x != y is always true for y out of range. */
7316 29803401 : if (val < mmin || val > mmax)
7317 123 : return const_true_rtx;
7318 : break;
7319 :
7320 : default:
7321 : break;
7322 : }
7323 : }
7324 :
7325 : /* Optimize integer comparisons with zero. */
7326 97473875 : if (is_a <scalar_int_mode> (mode, &int_mode)
7327 94534987 : && trueop1 == const0_rtx
7328 49481337 : && !side_effects_p (trueop0))
7329 : {
7330 : /* Some addresses are known to be nonzero. We don't know
7331 : their sign, but equality comparisons are known. */
7332 49328934 : if (nonzero_address_p (trueop0))
7333 : {
7334 532 : if (code == EQ || code == LEU)
7335 251 : return const0_rtx;
7336 281 : if (code == NE || code == GTU)
7337 281 : return const_true_rtx;
7338 : }
7339 :
7340 : /* See if the first operand is an IOR with a constant. If so, we
7341 : may be able to determine the result of this comparison. */
7342 49328402 : if (GET_CODE (op0) == IOR)
7343 : {
7344 625371 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7345 625371 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7346 : {
7347 288 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7348 576 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7349 288 : && (UINTVAL (inner_const)
7350 288 : & (HOST_WIDE_INT_1U
7351 : << sign_bitnum)));
7352 :
7353 288 : switch (code)
7354 : {
7355 : case EQ:
7356 : case LEU:
7357 : return const0_rtx;
7358 4 : case NE:
7359 4 : case GTU:
7360 4 : return const_true_rtx;
7361 70 : case LT:
7362 70 : case LE:
7363 70 : if (has_sign)
7364 2 : return const_true_rtx;
7365 : break;
7366 208 : case GT:
7367 208 : case GE:
7368 208 : if (has_sign)
7369 : return const0_rtx;
7370 : break;
7371 : default:
7372 : break;
7373 : }
7374 : }
7375 : }
7376 : }
7377 :
7378 : /* Optimize comparison of ABS with zero. */
7379 49810201 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7380 147130624 : && (GET_CODE (trueop0) == ABS
7381 49656902 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7382 38 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7383 : {
7384 583 : switch (code)
7385 : {
7386 60 : case LT:
7387 : /* Optimize abs(x) < 0.0. */
7388 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7389 0 : return const0_rtx;
7390 : break;
7391 :
7392 42 : case GE:
7393 : /* Optimize abs(x) >= 0.0. */
7394 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7395 0 : return const_true_rtx;
7396 : break;
7397 :
7398 0 : case UNGE:
7399 : /* Optimize ! (abs(x) < 0.0). */
7400 0 : return const_true_rtx;
7401 :
7402 : default:
7403 : break;
7404 : }
7405 : }
7406 :
7407 : return 0;
7408 : }
7409 :
7410 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7411 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7412 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7413 : can be simplified to that or NULL_RTX if not.
7414 : Assume X is compared against zero with CMP_CODE and the true
7415 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7416 :
7417 : rtx
7418 30632996 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7419 : rtx true_val, rtx false_val)
7420 : {
7421 30632996 : if (cmp_code != EQ && cmp_code != NE)
7422 : return NULL_RTX;
7423 :
7424 : /* Result on X == 0 and X !=0 respectively. */
7425 22118309 : rtx on_zero, on_nonzero;
7426 22118309 : if (cmp_code == EQ)
7427 : {
7428 : on_zero = true_val;
7429 : on_nonzero = false_val;
7430 : }
7431 : else
7432 : {
7433 11818304 : on_zero = false_val;
7434 11818304 : on_nonzero = true_val;
7435 : }
7436 :
7437 22118309 : rtx_code op_code = GET_CODE (on_nonzero);
7438 22118309 : if ((op_code != CLZ && op_code != CTZ)
7439 1961 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7440 22119335 : || !CONST_INT_P (on_zero))
7441 22118007 : return NULL_RTX;
7442 :
7443 302 : HOST_WIDE_INT op_val;
7444 302 : scalar_int_mode mode ATTRIBUTE_UNUSED
7445 302 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7446 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7447 604 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7448 326 : && op_val == INTVAL (on_zero))
7449 : return on_nonzero;
7450 :
7451 : return NULL_RTX;
7452 : }
7453 :
7454 : /* Try to simplify X given that it appears within operand OP of a
7455 : VEC_MERGE operation whose mask is MASK. X need not use the same
7456 : vector mode as the VEC_MERGE, but it must have the same number of
7457 : elements.
7458 :
7459 : Return the simplified X on success, otherwise return NULL_RTX. */
7460 :
7461 : rtx
7462 1638219 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7463 : {
7464 1638219 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7465 3276438 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7466 1638219 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7467 : {
7468 5486 : if (side_effects_p (XEXP (x, 1 - op)))
7469 : return NULL_RTX;
7470 :
7471 5262 : return XEXP (x, op);
7472 : }
7473 1632733 : if (UNARY_P (x)
7474 194276 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7475 1690621 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7476 : {
7477 24337 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7478 24337 : if (top0)
7479 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7480 448 : GET_MODE (XEXP (x, 0)));
7481 : }
7482 1632285 : if (BINARY_P (x)
7483 203566 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7484 406826 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7485 178121 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7486 1914323 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7487 : {
7488 141019 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7489 141019 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7490 141019 : if (top0 || top1)
7491 : {
7492 952 : if (COMPARISON_P (x))
7493 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7494 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7495 : ? GET_MODE (XEXP (x, 0))
7496 0 : : GET_MODE (XEXP (x, 1)),
7497 : top0 ? top0 : XEXP (x, 0),
7498 0 : top1 ? top1 : XEXP (x, 1));
7499 : else
7500 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7501 : top0 ? top0 : XEXP (x, 0),
7502 952 : top1 ? top1 : XEXP (x, 1));
7503 : }
7504 : }
7505 1631333 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7506 35322 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7507 70644 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7508 35322 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7509 70644 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7510 35322 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7511 1648773 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7512 : {
7513 8720 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7514 8720 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7515 8720 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7516 8720 : if (top0 || top1 || top2)
7517 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7518 448 : GET_MODE (XEXP (x, 0)),
7519 : top0 ? top0 : XEXP (x, 0),
7520 : top1 ? top1 : XEXP (x, 1),
7521 448 : top2 ? top2 : XEXP (x, 2));
7522 : }
7523 : return NULL_RTX;
7524 : }
7525 :
7526 :
7527 : /* Simplify CODE, an operation with result mode MODE and three operands,
7528 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7529 : a constant. Return 0 if no simplifications is possible. */
7530 :
7531 : rtx
7532 42266692 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7533 : machine_mode op0_mode,
7534 : rtx op0, rtx op1, rtx op2)
7535 : {
7536 42266692 : bool any_change = false;
7537 42266692 : rtx tem, trueop2;
7538 42266692 : scalar_int_mode int_mode, int_op0_mode;
7539 42266692 : unsigned int n_elts;
7540 :
7541 42266692 : switch (code)
7542 : {
7543 334172 : case FMA:
7544 : /* Simplify negations around the multiplication. */
7545 : /* -a * -b + c => a * b + c. */
7546 334172 : if (GET_CODE (op0) == NEG)
7547 : {
7548 80586 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7549 80586 : if (tem)
7550 271 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7551 : }
7552 253586 : else if (GET_CODE (op1) == NEG)
7553 : {
7554 1064 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7555 1064 : if (tem)
7556 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7557 : }
7558 :
7559 : /* Canonicalize the two multiplication operands. */
7560 : /* a * -b + c => -b * a + c. */
7561 334172 : if (swap_commutative_operands_p (op0, op1))
7562 : std::swap (op0, op1), any_change = true;
7563 :
7564 305997 : if (any_change)
7565 28437 : return gen_rtx_FMA (mode, op0, op1, op2);
7566 : return NULL_RTX;
7567 :
7568 655656 : case SIGN_EXTRACT:
7569 655656 : case ZERO_EXTRACT:
7570 655656 : if (CONST_INT_P (op0)
7571 17473 : && CONST_INT_P (op1)
7572 17473 : && CONST_INT_P (op2)
7573 42266724 : && is_a <scalar_int_mode> (mode, &int_mode)
7574 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7575 655688 : && HWI_COMPUTABLE_MODE_P (int_mode))
7576 : {
7577 : /* Extracting a bit-field from a constant */
7578 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7579 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7580 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7581 32 : if (!BITS_BIG_ENDIAN)
7582 32 : val >>= op2val;
7583 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7584 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7585 : else
7586 : /* Not enough information to calculate the bit position. */
7587 : break;
7588 :
7589 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7590 : {
7591 : /* First zero-extend. */
7592 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7593 : /* If desired, propagate sign bit. */
7594 29 : if (code == SIGN_EXTRACT
7595 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7596 5 : != 0)
7597 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7598 : }
7599 :
7600 32 : return gen_int_mode (val, int_mode);
7601 : }
7602 : break;
7603 :
7604 40485511 : case IF_THEN_ELSE:
7605 40485511 : if (CONST_INT_P (op0))
7606 292104 : return op0 != const0_rtx ? op1 : op2;
7607 :
7608 : /* Convert c ? a : a into "a". */
7609 40287551 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7610 : return op1;
7611 :
7612 : /* Convert a != b ? a : b into "a". */
7613 40284393 : if (GET_CODE (op0) == NE
7614 15563455 : && ! side_effects_p (op0)
7615 15522080 : && ! HONOR_NANS (mode)
7616 15516112 : && ! HONOR_SIGNED_ZEROS (mode)
7617 55800505 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7618 103419 : && rtx_equal_p (XEXP (op0, 1), op2))
7619 15515790 : || (rtx_equal_p (XEXP (op0, 0), op2)
7620 4302 : && rtx_equal_p (XEXP (op0, 1), op1))))
7621 524 : return op1;
7622 :
7623 : /* Convert a == b ? a : b into "b". */
7624 40283869 : if (GET_CODE (op0) == EQ
7625 12788679 : && ! side_effects_p (op0)
7626 12762539 : && ! HONOR_NANS (mode)
7627 12625165 : && ! HONOR_SIGNED_ZEROS (mode)
7628 52909034 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7629 14876 : && rtx_equal_p (XEXP (op0, 1), op2))
7630 12625155 : || (rtx_equal_p (XEXP (op0, 0), op2)
7631 6905 : && rtx_equal_p (XEXP (op0, 1), op1))))
7632 26 : return op2;
7633 :
7634 : /* Convert a != 0 ? -a : 0 into "-a". */
7635 40283843 : if (GET_CODE (op0) == NE
7636 15562931 : && ! side_effects_p (op0)
7637 15521556 : && ! HONOR_NANS (mode)
7638 15515588 : && ! HONOR_SIGNED_ZEROS (mode)
7639 15515588 : && XEXP (op0, 1) == CONST0_RTX (mode)
7640 11812234 : && op2 == CONST0_RTX (mode)
7641 172663 : && GET_CODE (op1) == NEG
7642 40283895 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7643 : return op1;
7644 :
7645 : /* Convert a == 0 ? 0 : -a into "-a". */
7646 40283834 : if (GET_CODE (op0) == EQ
7647 12788653 : && ! side_effects_p (op0)
7648 12762513 : && ! HONOR_NANS (mode)
7649 12625139 : && ! HONOR_SIGNED_ZEROS (mode)
7650 12625139 : && op1 == CONST0_RTX (mode)
7651 30874 : && XEXP (op0, 1) == CONST0_RTX (mode)
7652 13386 : && GET_CODE (op2) == NEG
7653 40283840 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7654 : return op2;
7655 :
7656 : /* Convert (!c) != {0,...,0} ? a : b into
7657 : c != {0,...,0} ? b : a for vector modes. */
7658 40283828 : if (VECTOR_MODE_P (GET_MODE (op1))
7659 14905 : && GET_CODE (op0) == NE
7660 460 : && GET_CODE (XEXP (op0, 0)) == NOT
7661 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7662 : {
7663 0 : rtx cv = XEXP (op0, 1);
7664 0 : int nunits;
7665 0 : bool ok = true;
7666 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7667 : ok = false;
7668 : else
7669 0 : for (int i = 0; i < nunits; ++i)
7670 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7671 : {
7672 : ok = false;
7673 : break;
7674 : }
7675 0 : if (ok)
7676 : {
7677 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7678 : XEXP (XEXP (op0, 0), 0),
7679 : XEXP (op0, 1));
7680 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7681 0 : return retval;
7682 : }
7683 : }
7684 :
7685 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7686 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7687 : Similarly for ctz (x). */
7688 40282831 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7689 80466212 : && XEXP (op0, 1) == const0_rtx)
7690 : {
7691 30632996 : rtx simplified
7692 30632996 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7693 : op1, op2);
7694 30632996 : if (simplified)
7695 : return simplified;
7696 : }
7697 :
7698 40283828 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7699 : {
7700 80463601 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7701 40182384 : ? GET_MODE (XEXP (op0, 1))
7702 : : GET_MODE (XEXP (op0, 0)));
7703 40182384 : rtx temp;
7704 :
7705 : /* Look for happy constants in op1 and op2. */
7706 40182384 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7707 : {
7708 205521 : HOST_WIDE_INT t = INTVAL (op1);
7709 205521 : HOST_WIDE_INT f = INTVAL (op2);
7710 :
7711 205521 : if (t == STORE_FLAG_VALUE && f == 0)
7712 52424 : code = GET_CODE (op0);
7713 153097 : else if (t == 0 && f == STORE_FLAG_VALUE)
7714 : {
7715 31183 : enum rtx_code tmp;
7716 31183 : tmp = reversed_comparison_code (op0, NULL);
7717 31183 : if (tmp == UNKNOWN)
7718 : break;
7719 : code = tmp;
7720 : }
7721 : else
7722 : break;
7723 :
7724 78226 : return simplify_gen_relational (code, mode, cmp_mode,
7725 78226 : XEXP (op0, 0), XEXP (op0, 1));
7726 : }
7727 :
7728 39976863 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7729 : cmp_mode, XEXP (op0, 0),
7730 : XEXP (op0, 1));
7731 :
7732 : /* See if any simplifications were possible. */
7733 39976863 : if (temp)
7734 : {
7735 6929 : if (CONST_INT_P (temp))
7736 872 : return temp == const0_rtx ? op2 : op1;
7737 6102 : else if (temp)
7738 6102 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7739 : }
7740 : }
7741 : break;
7742 :
7743 791353 : case VEC_MERGE:
7744 791353 : gcc_assert (GET_MODE (op0) == mode);
7745 791353 : gcc_assert (GET_MODE (op1) == mode);
7746 791353 : gcc_assert (VECTOR_MODE_P (mode));
7747 791353 : trueop2 = avoid_constant_pool_reference (op2);
7748 791353 : if (CONST_INT_P (trueop2)
7749 1262151 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7750 : {
7751 470798 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7752 470798 : unsigned HOST_WIDE_INT mask;
7753 470798 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7754 : mask = -1;
7755 : else
7756 468341 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7757 :
7758 470798 : if (!(sel & mask) && !side_effects_p (op0))
7759 : return op1;
7760 470361 : if ((sel & mask) == mask && !side_effects_p (op1))
7761 : return op0;
7762 :
7763 459610 : rtx trueop0 = avoid_constant_pool_reference (op0);
7764 459610 : rtx trueop1 = avoid_constant_pool_reference (op1);
7765 459610 : if (GET_CODE (trueop0) == CONST_VECTOR
7766 9425 : && GET_CODE (trueop1) == CONST_VECTOR)
7767 : {
7768 4951 : rtvec v = rtvec_alloc (n_elts);
7769 4951 : unsigned int i;
7770 :
7771 55168 : for (i = 0; i < n_elts; i++)
7772 45266 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7773 45266 : ? CONST_VECTOR_ELT (trueop0, i)
7774 25521 : : CONST_VECTOR_ELT (trueop1, i));
7775 4951 : return gen_rtx_CONST_VECTOR (mode, v);
7776 : }
7777 :
7778 454659 : if (swap_commutative_operands_p (op0, op1)
7779 : /* Two operands have same precedence, then first bit of mask
7780 : select first operand. */
7781 454659 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7782 31627 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7783 63254 : GEN_INT (~sel & mask));
7784 :
7785 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7786 : if no element from a appears in the result. */
7787 423032 : if (GET_CODE (op0) == VEC_MERGE)
7788 : {
7789 17218 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7790 17218 : if (CONST_INT_P (tem))
7791 : {
7792 1475 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7793 1475 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7794 104 : return simplify_gen_ternary (code, mode, mode,
7795 104 : XEXP (op0, 1), op1, op2);
7796 1371 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7797 834 : return simplify_gen_ternary (code, mode, mode,
7798 834 : XEXP (op0, 0), op1, op2);
7799 : }
7800 : }
7801 422094 : if (GET_CODE (op1) == VEC_MERGE)
7802 : {
7803 588 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7804 588 : if (CONST_INT_P (tem))
7805 : {
7806 557 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7807 557 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7808 526 : return simplify_gen_ternary (code, mode, mode,
7809 526 : op0, XEXP (op1, 1), op2);
7810 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7811 4 : return simplify_gen_ternary (code, mode, mode,
7812 4 : op0, XEXP (op1, 0), op2);
7813 : }
7814 : }
7815 :
7816 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7817 : with a. */
7818 421564 : if (GET_CODE (op0) == VEC_DUPLICATE
7819 143079 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7820 640 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7821 422844 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7822 : {
7823 572 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7824 572 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7825 : {
7826 572 : if (XEXP (XEXP (op0, 0), 0) == op1
7827 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7828 : return op1;
7829 : }
7830 : }
7831 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7832 : (const_int N))
7833 : with (vec_concat (X) (B)) if N == 1 or
7834 : (vec_concat (A) (X)) if N == 2. */
7835 421562 : if (GET_CODE (op0) == VEC_DUPLICATE
7836 143077 : && GET_CODE (op1) == CONST_VECTOR
7837 151600 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7838 2346 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7839 422735 : && IN_RANGE (sel, 1, 2))
7840 : {
7841 1171 : rtx newop0 = XEXP (op0, 0);
7842 1171 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
7843 1171 : if (sel == 2)
7844 123 : std::swap (newop0, newop1);
7845 1171 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7846 : }
7847 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7848 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7849 : Only applies for vectors of two elements. */
7850 420391 : if (GET_CODE (op0) == VEC_DUPLICATE
7851 141906 : && GET_CODE (op1) == VEC_CONCAT
7852 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7853 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7854 420391 : && IN_RANGE (sel, 1, 2))
7855 : {
7856 0 : rtx newop0 = XEXP (op0, 0);
7857 0 : rtx newop1 = XEXP (op1, 2 - sel);
7858 0 : rtx otherop = XEXP (op1, sel - 1);
7859 0 : if (sel == 2)
7860 0 : std::swap (newop0, newop1);
7861 : /* Don't want to throw away the other part of the vec_concat if
7862 : it has side-effects. */
7863 0 : if (!side_effects_p (otherop))
7864 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7865 : }
7866 :
7867 : /* Replace:
7868 :
7869 : (vec_merge:outer (vec_duplicate:outer x:inner)
7870 : (subreg:outer y:inner 0)
7871 : (const_int N))
7872 :
7873 : with (vec_concat:outer x:inner y:inner) if N == 1,
7874 : or (vec_concat:outer y:inner x:inner) if N == 2.
7875 :
7876 : Implicitly, this means we have a paradoxical subreg, but such
7877 : a check is cheap, so make it anyway.
7878 :
7879 : Only applies for vectors of two elements. */
7880 420391 : if (GET_CODE (op0) == VEC_DUPLICATE
7881 141906 : && GET_CODE (op1) == SUBREG
7882 44336 : && GET_MODE (op1) == GET_MODE (op0)
7883 44336 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
7884 0 : && paradoxical_subreg_p (op1)
7885 0 : && subreg_lowpart_p (op1)
7886 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7887 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7888 420391 : && IN_RANGE (sel, 1, 2))
7889 : {
7890 0 : rtx newop0 = XEXP (op0, 0);
7891 0 : rtx newop1 = SUBREG_REG (op1);
7892 0 : if (sel == 2)
7893 0 : std::swap (newop0, newop1);
7894 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7895 : }
7896 :
7897 : /* Same as above but with switched operands:
7898 : Replace (vec_merge:outer (subreg:outer x:inner 0)
7899 : (vec_duplicate:outer y:inner)
7900 : (const_int N))
7901 :
7902 : with (vec_concat:outer x:inner y:inner) if N == 1,
7903 : or (vec_concat:outer y:inner x:inner) if N == 2. */
7904 420391 : if (GET_CODE (op1) == VEC_DUPLICATE
7905 29726 : && GET_CODE (op0) == SUBREG
7906 26567 : && GET_MODE (op0) == GET_MODE (op1)
7907 26567 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
7908 0 : && paradoxical_subreg_p (op0)
7909 0 : && subreg_lowpart_p (op0)
7910 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7911 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7912 420391 : && IN_RANGE (sel, 1, 2))
7913 : {
7914 0 : rtx newop0 = SUBREG_REG (op0);
7915 0 : rtx newop1 = XEXP (op1, 0);
7916 0 : if (sel == 2)
7917 0 : std::swap (newop0, newop1);
7918 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7919 : }
7920 :
7921 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7922 : (const_int n))
7923 : with (vec_concat x y) or (vec_concat y x) depending on value
7924 : of N. */
7925 420391 : if (GET_CODE (op0) == VEC_DUPLICATE
7926 141906 : && GET_CODE (op1) == VEC_DUPLICATE
7927 198 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7928 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7929 420391 : && IN_RANGE (sel, 1, 2))
7930 : {
7931 0 : rtx newop0 = XEXP (op0, 0);
7932 0 : rtx newop1 = XEXP (op1, 0);
7933 0 : if (sel == 2)
7934 0 : std::swap (newop0, newop1);
7935 :
7936 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7937 : }
7938 : }
7939 :
7940 740946 : if (rtx_equal_p (op0, op1)
7941 740946 : && !side_effects_p (op2) && !side_effects_p (op1))
7942 : return op0;
7943 :
7944 740653 : if (!side_effects_p (op2))
7945 : {
7946 736975 : rtx top0
7947 736975 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
7948 736975 : rtx top1
7949 736975 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
7950 736975 : if (top0 || top1)
7951 988 : return simplify_gen_ternary (code, mode, mode,
7952 : top0 ? top0 : op0,
7953 814 : top1 ? top1 : op1, op2);
7954 : }
7955 :
7956 : break;
7957 :
7958 0 : default:
7959 0 : gcc_unreachable ();
7960 : }
7961 :
7962 : return 0;
7963 : }
7964 :
7965 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
7966 : starting at byte FIRST_BYTE. Return true on success and add the
7967 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
7968 : that the bytes follow target memory order. Leave BYTES unmodified
7969 : on failure.
7970 :
7971 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
7972 : BYTES before calling this function. */
7973 :
7974 : bool
7975 13141777 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
7976 : unsigned int first_byte, unsigned int num_bytes)
7977 : {
7978 : /* Check the mode is sensible. */
7979 13141777 : gcc_assert (GET_MODE (x) == VOIDmode
7980 : ? is_a <scalar_int_mode> (mode)
7981 : : mode == GET_MODE (x));
7982 :
7983 13141777 : if (GET_CODE (x) == CONST_VECTOR)
7984 : {
7985 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7986 : is necessary. The only complication is that MODE_VECTOR_BOOL
7987 : vectors can have several elements per byte. */
7988 1046436 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7989 : GET_MODE_NUNITS (mode));
7990 523218 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
7991 523218 : if (elt_bits < BITS_PER_UNIT)
7992 : {
7993 : /* This is the only case in which elements can be smaller than
7994 : a byte. */
7995 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7996 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
7997 0 : for (unsigned int i = 0; i < num_bytes; ++i)
7998 : {
7999 0 : target_unit value = 0;
8000 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
8001 : {
8002 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
8003 0 : value |= mask << j;
8004 0 : elt += 1;
8005 : }
8006 0 : bytes.quick_push (value);
8007 : }
8008 : return true;
8009 : }
8010 :
8011 523218 : unsigned int start = bytes.length ();
8012 523218 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
8013 : /* Make FIRST_BYTE relative to ELT. */
8014 523218 : first_byte %= elt_bytes;
8015 2675153 : while (num_bytes > 0)
8016 : {
8017 : /* Work out how many bytes we want from element ELT. */
8018 2151935 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
8019 4303870 : if (!native_encode_rtx (GET_MODE_INNER (mode),
8020 : CONST_VECTOR_ELT (x, elt), bytes,
8021 : first_byte, chunk_bytes))
8022 : {
8023 0 : bytes.truncate (start);
8024 0 : return false;
8025 : }
8026 2151935 : elt += 1;
8027 2151935 : first_byte = 0;
8028 2151935 : num_bytes -= chunk_bytes;
8029 : }
8030 : return true;
8031 : }
8032 :
8033 : /* All subsequent cases are limited to scalars. */
8034 12618559 : scalar_mode smode;
8035 12649343 : if (!is_a <scalar_mode> (mode, &smode))
8036 : return false;
8037 :
8038 : /* Make sure that the region is in range. */
8039 12618559 : unsigned int end_byte = first_byte + num_bytes;
8040 12618559 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8041 12618559 : gcc_assert (end_byte <= mode_bytes);
8042 :
8043 12618559 : if (CONST_SCALAR_INT_P (x))
8044 : {
8045 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
8046 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
8047 : position of each byte. */
8048 11948352 : rtx_mode_t value (x, smode);
8049 11948352 : wide_int_ref value_wi (value);
8050 51009239 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8051 : {
8052 : /* Always constant because the inputs are. */
8053 39060887 : unsigned int lsb
8054 39060887 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8055 : /* Operate directly on the encoding rather than using
8056 : wi::extract_uhwi, so that we preserve the sign or zero
8057 : extension for modes that are not a whole number of bits in
8058 : size. (Zero extension is only used for the combination of
8059 : innermode == BImode && STORE_FLAG_VALUE == 1). */
8060 39060887 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
8061 39060887 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
8062 39060887 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
8063 39060887 : bytes.quick_push (uhwi >> shift);
8064 : }
8065 11948352 : return true;
8066 : }
8067 :
8068 670207 : if (CONST_DOUBLE_P (x))
8069 : {
8070 : /* real_to_target produces an array of integers in target memory order.
8071 : All integers before the last one have 32 bits; the last one may
8072 : have 32 bits or fewer, depending on whether the mode bitsize
8073 : is divisible by 32. Each of these integers is then laid out
8074 : in target memory as any other integer would be. */
8075 639423 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8076 639423 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
8077 :
8078 : /* The (maximum) number of target bytes per element of el32. */
8079 639423 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8080 639423 : gcc_assert (bytes_per_el32 != 0);
8081 :
8082 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
8083 : handling above. */
8084 4365843 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8085 : {
8086 3726420 : unsigned int index = byte / bytes_per_el32;
8087 3726420 : unsigned int subbyte = byte % bytes_per_el32;
8088 3726420 : unsigned int int_bytes = MIN (bytes_per_el32,
8089 : mode_bytes - index * bytes_per_el32);
8090 : /* Always constant because the inputs are. */
8091 3726420 : unsigned int lsb
8092 3726420 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8093 3726420 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
8094 : }
8095 639423 : return true;
8096 : }
8097 :
8098 30784 : if (GET_CODE (x) == CONST_FIXED)
8099 : {
8100 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8101 : {
8102 : /* Always constant because the inputs are. */
8103 0 : unsigned int lsb
8104 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8105 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8106 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8107 : {
8108 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8109 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8110 : }
8111 0 : bytes.quick_push (piece >> lsb);
8112 : }
8113 : return true;
8114 : }
8115 :
8116 : return false;
8117 : }
8118 :
8119 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8120 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8121 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8122 : and BYTES is known to have enough bytes to supply NPATTERNS *
8123 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8124 : BITS_PER_UNIT bits and the bytes are in target memory order.
8125 :
8126 : Return the vector on success, otherwise return NULL_RTX. */
8127 :
8128 : rtx
8129 265298 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8130 : unsigned int first_byte, unsigned int npatterns,
8131 : unsigned int nelts_per_pattern)
8132 : {
8133 265298 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8134 :
8135 530596 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8136 : GET_MODE_NUNITS (mode));
8137 265298 : if (elt_bits < BITS_PER_UNIT)
8138 : {
8139 : /* This is the only case in which elements can be smaller than a byte.
8140 : Element 0 is always in the lsb of the containing byte. */
8141 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8142 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8143 : {
8144 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8145 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8146 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8147 0 : unsigned int value = bytes[byte_index] >> lsb;
8148 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8149 : }
8150 : }
8151 : else
8152 : {
8153 1050890 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8154 : {
8155 1571184 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8156 785592 : if (!x)
8157 0 : return NULL_RTX;
8158 785592 : builder.quick_push (x);
8159 785592 : first_byte += elt_bits / BITS_PER_UNIT;
8160 : }
8161 : }
8162 265298 : return builder.build ();
8163 265298 : }
8164 :
8165 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8166 : of target memory image BYTES. */
8167 :
8168 : wide_int
8169 11030371 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8170 : unsigned int size, unsigned int precision)
8171 : {
8172 : /* Pull the bytes msb first, so that we can use simple
8173 : shift-and-insert wide_int operations. */
8174 11030371 : wide_int result (wi::zero (precision));
8175 51150164 : for (unsigned int i = 0; i < size; ++i)
8176 : {
8177 40119793 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8178 : /* Always constant because the inputs are. */
8179 40119793 : unsigned int subbyte
8180 40119793 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8181 40119793 : result <<= BITS_PER_UNIT;
8182 40119793 : result |= bytes[first_byte + subbyte];
8183 : }
8184 11030371 : return result;
8185 : }
8186 :
8187 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8188 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8189 : bits and the bytes are in target memory order. The image has enough
8190 : values to specify all bytes of MODE.
8191 :
8192 : Return the rtx on success, otherwise return NULL_RTX. */
8193 :
8194 : rtx
8195 11361797 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8196 : unsigned int first_byte)
8197 : {
8198 11361797 : if (VECTOR_MODE_P (mode))
8199 : {
8200 : /* If we know at compile time how many elements there are,
8201 : pull each element directly from BYTES. */
8202 90896 : unsigned int nelts;
8203 181792 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8204 90896 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8205 : return NULL_RTX;
8206 : }
8207 :
8208 11270901 : scalar_int_mode imode;
8209 11270901 : if (is_a <scalar_int_mode> (mode, &imode)
8210 11030371 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8211 : {
8212 11030371 : auto result = native_decode_int (bytes, first_byte,
8213 11030371 : GET_MODE_SIZE (imode),
8214 22060742 : GET_MODE_PRECISION (imode));
8215 11030371 : return immed_wide_int_const (result, imode);
8216 11030371 : }
8217 :
8218 240530 : scalar_float_mode fmode;
8219 240530 : if (is_a <scalar_float_mode> (mode, &fmode))
8220 : {
8221 : /* We need to build an array of integers in target memory order.
8222 : All integers before the last one have 32 bits; the last one may
8223 : have 32 bits or fewer, depending on whether the mode bitsize
8224 : is divisible by 32. */
8225 240500 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8226 240500 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8227 240500 : memset (el32, 0, num_el32 * sizeof (long));
8228 :
8229 : /* The (maximum) number of target bytes per element of el32. */
8230 240500 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8231 240500 : gcc_assert (bytes_per_el32 != 0);
8232 :
8233 240500 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8234 1667636 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8235 : {
8236 1427136 : unsigned int index = byte / bytes_per_el32;
8237 1427136 : unsigned int subbyte = byte % bytes_per_el32;
8238 1427136 : unsigned int int_bytes = MIN (bytes_per_el32,
8239 : mode_bytes - index * bytes_per_el32);
8240 : /* Always constant because the inputs are. */
8241 1427136 : unsigned int lsb
8242 1427136 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8243 1427136 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8244 : }
8245 240500 : REAL_VALUE_TYPE r;
8246 240500 : real_from_target (&r, el32, fmode);
8247 240500 : return const_double_from_real_value (r, fmode);
8248 : }
8249 :
8250 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8251 : {
8252 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8253 0 : FIXED_VALUE_TYPE f;
8254 0 : f.data.low = 0;
8255 0 : f.data.high = 0;
8256 0 : f.mode = smode;
8257 :
8258 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8259 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8260 : {
8261 : /* Always constant because the inputs are. */
8262 0 : unsigned int lsb
8263 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8264 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8265 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8266 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8267 : else
8268 0 : f.data.low |= unit << lsb;
8269 : }
8270 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8271 : }
8272 :
8273 : return NULL_RTX;
8274 : }
8275 :
8276 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8277 : is to convert a runtime BYTE value into a constant one. */
8278 :
8279 : static poly_uint64
8280 316014 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8281 : {
8282 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8283 316014 : machine_mode mode = GET_MODE (x);
8284 632028 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8285 : GET_MODE_NUNITS (mode));
8286 : /* The number of bits needed to encode one element from each pattern. */
8287 316014 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8288 :
8289 : /* Identify the start point in terms of a sequence number and a byte offset
8290 : within that sequence. */
8291 316014 : poly_uint64 first_sequence;
8292 316014 : unsigned HOST_WIDE_INT subbit;
8293 316014 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8294 : &first_sequence, &subbit))
8295 : {
8296 316014 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8297 316014 : if (nelts_per_pattern == 1)
8298 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8299 : doesn't matter. */
8300 238645 : byte = subbit / BITS_PER_UNIT;
8301 77369 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8302 : {
8303 : /* The subreg drops the first element from each pattern and
8304 : only uses the second element. Find the first sequence
8305 : that starts on a byte boundary. */
8306 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8307 5568 : byte = subbit / BITS_PER_UNIT;
8308 : }
8309 : }
8310 316014 : return byte;
8311 : }
8312 :
8313 : /* Subroutine of simplify_subreg in which:
8314 :
8315 : - X is known to be a CONST_VECTOR
8316 : - OUTERMODE is known to be a vector mode
8317 :
8318 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8319 : rather than on each individual element of the CONST_VECTOR.
8320 :
8321 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8322 :
8323 : static rtx
8324 182248 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8325 : machine_mode innermode, unsigned int first_byte)
8326 : {
8327 : /* Paradoxical subregs of vectors have dubious semantics. */
8328 182248 : if (paradoxical_subreg_p (outermode, innermode))
8329 : return NULL_RTX;
8330 :
8331 : /* We can only preserve the semantics of a stepped pattern if the new
8332 : vector element is the same as the original one. */
8333 182102 : if (CONST_VECTOR_STEPPED_P (x)
8334 202726 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8335 : return NULL_RTX;
8336 :
8337 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8338 174402 : unsigned int x_elt_bits
8339 174402 : = vector_element_size (GET_MODE_PRECISION (innermode),
8340 : GET_MODE_NUNITS (innermode));
8341 174402 : unsigned int out_elt_bits
8342 174402 : = vector_element_size (GET_MODE_PRECISION (outermode),
8343 : GET_MODE_NUNITS (outermode));
8344 :
8345 : /* The number of bits needed to encode one element from every pattern
8346 : of the original vector. */
8347 174402 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8348 :
8349 : /* The number of bits needed to encode one element from every pattern
8350 : of the result. */
8351 174402 : unsigned int out_sequence_bits
8352 174402 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8353 :
8354 : /* Work out the number of interleaved patterns in the output vector
8355 : and the number of encoded elements per pattern. */
8356 174402 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8357 174402 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8358 :
8359 : /* The encoding scheme requires the number of elements to be a multiple
8360 : of the number of patterns, so that each pattern appears at least once
8361 : and so that the same number of elements appear from each pattern. */
8362 348804 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8363 174402 : unsigned int const_nunits;
8364 348804 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8365 174402 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8366 : {
8367 : /* Either the encoding is invalid, or applying it would give us
8368 : more elements than we need. Just encode each element directly. */
8369 : out_npatterns = const_nunits;
8370 : nelts_per_pattern = 1;
8371 : }
8372 : else if (!ok_p)
8373 : return NULL_RTX;
8374 :
8375 : /* Get enough bytes of X to form the new encoding. */
8376 174402 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8377 174402 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8378 174402 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8379 174402 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8380 : return NULL_RTX;
8381 :
8382 : /* Reencode the bytes as OUTERMODE. */
8383 174402 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8384 174402 : nelts_per_pattern);
8385 174402 : }
8386 :
8387 : /* Try to simplify a subreg of a constant by encoding the subreg region
8388 : as a sequence of target bytes and reading them back in the new mode.
8389 : Return the new value on success, otherwise return null.
8390 :
8391 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8392 : and byte offset FIRST_BYTE. */
8393 :
8394 : static rtx
8395 10292765 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8396 : machine_mode innermode, unsigned int first_byte)
8397 : {
8398 10292765 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8399 10292765 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8400 :
8401 : /* Some ports misuse CCmode. */
8402 10292765 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8403 : return x;
8404 :
8405 : /* Paradoxical subregs read undefined values for bytes outside of the
8406 : inner value. However, we have traditionally always sign-extended
8407 : integer constants and zero-extended others. */
8408 10290769 : unsigned int inner_bytes = buffer_bytes;
8409 10290769 : if (paradoxical_subreg_p (outermode, innermode))
8410 : {
8411 965650 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8412 0 : return NULL_RTX;
8413 :
8414 482825 : target_unit filler = 0;
8415 482825 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8416 43441 : filler = -1;
8417 :
8418 : /* Add any leading bytes due to big-endian layout. The number of
8419 : bytes must be constant because both modes have constant size. */
8420 482825 : unsigned int leading_bytes
8421 482825 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8422 482825 : for (unsigned int i = 0; i < leading_bytes; ++i)
8423 0 : buffer.quick_push (filler);
8424 :
8425 482825 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8426 0 : return NULL_RTX;
8427 :
8428 : /* Add any trailing bytes due to little-endian layout. */
8429 6314804 : while (buffer.length () < buffer_bytes)
8430 2674577 : buffer.quick_push (filler);
8431 : }
8432 9807944 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8433 : return NULL_RTX;
8434 10290769 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8435 10290769 : if (ret && FLOAT_MODE_P (outermode))
8436 : {
8437 125395 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8438 125395 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8439 : return NULL_RTX;
8440 1391794 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8441 1266434 : if (buffer[i] != buffer2[i])
8442 : return NULL_RTX;
8443 125395 : }
8444 : return ret;
8445 10292765 : }
8446 :
8447 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8448 : Return 0 if no simplifications are possible. */
8449 : rtx
8450 67110012 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8451 : machine_mode innermode, poly_uint64 byte)
8452 : {
8453 : /* Little bit of sanity checking. */
8454 67110012 : gcc_assert (innermode != VOIDmode);
8455 67110012 : gcc_assert (outermode != VOIDmode);
8456 67110012 : gcc_assert (innermode != BLKmode);
8457 67110012 : gcc_assert (outermode != BLKmode);
8458 :
8459 67110012 : gcc_assert (GET_MODE (op) == innermode
8460 : || GET_MODE (op) == VOIDmode);
8461 :
8462 134220024 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8463 67110012 : if (!multiple_p (byte, outersize))
8464 : return NULL_RTX;
8465 :
8466 134219984 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8467 67109992 : if (maybe_ge (byte, innersize))
8468 : return NULL_RTX;
8469 :
8470 67109992 : if (outermode == innermode && known_eq (byte, 0U))
8471 4557427 : return op;
8472 :
8473 62552565 : if (GET_CODE (op) == CONST_VECTOR)
8474 316014 : byte = simplify_const_vector_byte_offset (op, byte);
8475 :
8476 125105130 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8477 : {
8478 56831035 : rtx elt;
8479 :
8480 48196650 : if (VECTOR_MODE_P (outermode)
8481 25903155 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8482 58544266 : && vec_duplicate_p (op, &elt))
8483 12084 : return gen_vec_duplicate (outermode, elt);
8484 :
8485 56827293 : if (outermode == GET_MODE_INNER (innermode)
8486 56827293 : && vec_duplicate_p (op, &elt))
8487 8342 : return elt;
8488 : }
8489 :
8490 62540481 : if (CONST_SCALAR_INT_P (op)
8491 52439492 : || CONST_DOUBLE_AS_FLOAT_P (op)
8492 52382531 : || CONST_FIXED_P (op)
8493 52382531 : || GET_CODE (op) == CONST_VECTOR)
8494 : {
8495 10467167 : unsigned HOST_WIDE_INT cbyte;
8496 10467167 : if (byte.is_constant (&cbyte))
8497 : {
8498 10467167 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8499 : {
8500 182248 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8501 : innermode, cbyte);
8502 182248 : if (tmp)
8503 10467167 : return tmp;
8504 : }
8505 :
8506 10292765 : fixed_size_mode fs_outermode;
8507 10292765 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8508 10292765 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8509 : }
8510 : }
8511 :
8512 : /* Changing mode twice with SUBREG => just change it once,
8513 : or not at all if changing back op starting mode. */
8514 52073314 : if (GET_CODE (op) == SUBREG)
8515 : {
8516 1328977 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8517 2657954 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8518 1328977 : rtx newx;
8519 :
8520 : /* Make sure that the relationship between the two subregs is
8521 : known at compile time. */
8522 1328977 : if (!ordered_p (outersize, innermostsize))
8523 : return NULL_RTX;
8524 :
8525 1328977 : if (outermode == innermostmode
8526 764546 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8527 2093522 : && known_eq (SUBREG_BYTE (op),
8528 : subreg_lowpart_offset (innermode, innermostmode)))
8529 764545 : return SUBREG_REG (op);
8530 :
8531 : /* Work out the memory offset of the final OUTERMODE value relative
8532 : to the inner value of OP. */
8533 564432 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8534 : innermode, byte);
8535 564432 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8536 564432 : poly_int64 final_offset = mem_offset + op_mem_offset;
8537 :
8538 : /* See whether resulting subreg will be paradoxical. */
8539 564432 : if (!paradoxical_subreg_p (outermode, innermostmode))
8540 : {
8541 : /* Bail out in case resulting subreg would be incorrect. */
8542 917270 : if (maybe_lt (final_offset, 0)
8543 917261 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8544 917269 : || !multiple_p (final_offset, outersize))
8545 9 : return NULL_RTX;
8546 : }
8547 : else
8548 : {
8549 105797 : poly_int64 required_offset = subreg_memory_offset (outermode,
8550 : innermostmode, 0);
8551 105797 : if (maybe_ne (final_offset, required_offset))
8552 0 : return NULL_RTX;
8553 : /* Paradoxical subregs always have byte offset 0. */
8554 105797 : final_offset = 0;
8555 : }
8556 :
8557 : /* Recurse for further possible simplifications. */
8558 564423 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8559 564423 : final_offset);
8560 564423 : if (newx)
8561 : return newx;
8562 564044 : if (validate_subreg (outermode, innermostmode,
8563 564044 : SUBREG_REG (op), final_offset))
8564 : {
8565 505509 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8566 505509 : if (SUBREG_PROMOTED_VAR_P (op)
8567 610 : && SUBREG_PROMOTED_SIGN (op) >= 0
8568 610 : && GET_MODE_CLASS (outermode) == MODE_INT
8569 606 : && known_ge (outersize, innersize)
8570 392 : && known_le (outersize, innermostsize)
8571 505519 : && subreg_lowpart_p (newx))
8572 : {
8573 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8574 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8575 : }
8576 505509 : return newx;
8577 : }
8578 : return NULL_RTX;
8579 : }
8580 :
8581 : /* SUBREG of a hard register => just change the register number
8582 : and/or mode. If the hard register is not valid in that mode,
8583 : suppress this simplification. If the hard register is the stack,
8584 : frame, or argument pointer, leave this as a SUBREG. */
8585 :
8586 50744337 : if (REG_P (op) && HARD_REGISTER_P (op))
8587 : {
8588 10608303 : unsigned int regno, final_regno;
8589 :
8590 10608303 : regno = REGNO (op);
8591 10608303 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8592 10608303 : if (HARD_REGISTER_NUM_P (final_regno))
8593 : {
8594 10583277 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8595 : subreg_memory_offset (outermode,
8596 : innermode, byte));
8597 :
8598 : /* Propagate original regno. We don't have any way to specify
8599 : the offset inside original regno, so do so only for lowpart.
8600 : The information is used only by alias analysis that cannot
8601 : grog partial register anyway. */
8602 :
8603 10583277 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8604 7925468 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8605 10583277 : return x;
8606 : }
8607 : }
8608 :
8609 : /* If we have a SUBREG of a register that we are replacing and we are
8610 : replacing it with a MEM, make a new MEM and try replacing the
8611 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8612 : or if we would be widening it. */
8613 :
8614 40161060 : if (MEM_P (op)
8615 1694669 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8616 : /* Allow splitting of volatile memory references in case we don't
8617 : have instruction to move the whole thing. */
8618 1694666 : && (! MEM_VOLATILE_P (op)
8619 44331 : || ! have_insn_for (SET, innermode))
8620 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8621 41811395 : && known_le (outersize, innersize))
8622 810390 : return adjust_address_nv (op, outermode, byte);
8623 :
8624 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8625 : of two parts. */
8626 39350670 : if (GET_CODE (op) == CONCAT
8627 39350670 : || GET_CODE (op) == VEC_CONCAT)
8628 : {
8629 195856 : poly_uint64 final_offset;
8630 195856 : rtx part, res;
8631 :
8632 195856 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8633 195856 : if (part_mode == VOIDmode)
8634 11 : part_mode = GET_MODE_INNER (GET_MODE (op));
8635 391712 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8636 195856 : if (known_lt (byte, part_size))
8637 : {
8638 194306 : part = XEXP (op, 0);
8639 194306 : final_offset = byte;
8640 : }
8641 1550 : else if (known_ge (byte, part_size))
8642 : {
8643 1550 : part = XEXP (op, 1);
8644 1550 : final_offset = byte - part_size;
8645 : }
8646 : else
8647 : return NULL_RTX;
8648 :
8649 195856 : if (maybe_gt (final_offset + outersize, part_size))
8650 : return NULL_RTX;
8651 :
8652 128617 : part_mode = GET_MODE (part);
8653 128617 : if (part_mode == VOIDmode)
8654 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8655 128617 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8656 128617 : if (res)
8657 : return res;
8658 295 : if (GET_MODE (part) != VOIDmode
8659 295 : && validate_subreg (outermode, part_mode, part, final_offset))
8660 295 : return gen_rtx_SUBREG (outermode, part, final_offset);
8661 0 : return NULL_RTX;
8662 : }
8663 :
8664 : /* Simplify
8665 : (subreg (vec_merge (X)
8666 : (vector)
8667 : (const_int ((1 << N) | M)))
8668 : (N * sizeof (outermode)))
8669 : to
8670 : (subreg (X) (N * sizeof (outermode)))
8671 : */
8672 39154814 : unsigned int idx;
8673 78309628 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8674 39154814 : && idx < HOST_BITS_PER_WIDE_INT
8675 39154814 : && GET_CODE (op) == VEC_MERGE
8676 632796 : && GET_MODE_INNER (innermode) == outermode
8677 4887 : && CONST_INT_P (XEXP (op, 2))
8678 39159119 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8679 4296 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8680 :
8681 : /* A SUBREG resulting from a zero extension may fold to zero if
8682 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8683 39150518 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8684 : {
8685 219944 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8686 219944 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8687 53906 : return CONST0_RTX (outermode);
8688 : }
8689 :
8690 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8691 39096612 : if (GET_CODE (op) == ASHIFT
8692 701684 : && SCALAR_INT_MODE_P (innermode)
8693 674296 : && CONST_INT_P (XEXP (op, 1))
8694 594926 : && INTVAL (XEXP (op, 1)) > 0
8695 40393172 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8696 : {
8697 594876 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8698 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8699 594876 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8700 1153235 : && known_le (GET_MODE_BITSIZE (outermode), val))
8701 188831 : return CONST0_RTX (outermode);
8702 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8703 440039 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8704 34693 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8705 69072 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8706 67988 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8707 474732 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8708 33994 : return XEXP (XEXP (op, 0), 0);
8709 : }
8710 :
8711 40333785 : auto distribute_subreg = [&](rtx op)
8712 : {
8713 1426004 : return simplify_subreg (outermode, op, innermode, byte);
8714 38907781 : };
8715 :
8716 : /* Try distributing the subreg through logic operations, if that
8717 : leads to all subexpressions being simplified. For example,
8718 : distributing the outer subreg in:
8719 :
8720 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8721 :
8722 : gives:
8723 :
8724 : (not:SI (reg:SI X))
8725 :
8726 : This should be a win if the outermode is word_mode, since logical
8727 : operations on word_mode should (a) be no more expensive than logical
8728 : operations on subword modes and (b) are likely to be cheaper than
8729 : logical operations on multiword modes.
8730 :
8731 : Otherwise, handle the case where the subreg is non-narrowing and does
8732 : not change the number of words. The non-narrowing condition ensures
8733 : that we don't convert word_mode operations to subword operations. */
8734 38907781 : scalar_int_mode int_outermode, int_innermode;
8735 38907781 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8736 32061048 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8737 69778828 : && (outermode == word_mode
8738 17411843 : || ((GET_MODE_PRECISION (int_outermode)
8739 17411843 : >= GET_MODE_PRECISION (int_innermode))
8740 4241524 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8741 4153028 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8742 17553075 : switch (GET_CODE (op))
8743 : {
8744 31932 : case NOT:
8745 31932 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8746 1910 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8747 : break;
8748 :
8749 453819 : case AND:
8750 453819 : case IOR:
8751 453819 : case XOR:
8752 453819 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8753 200476 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8754 195427 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8755 : break;
8756 :
8757 : default:
8758 : break;
8759 : }
8760 :
8761 38710444 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8762 31863711 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8763 70574155 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8764 : {
8765 : /* Handle polynomial integers. The upper bits of a paradoxical
8766 : subreg are undefined, so this is safe regardless of whether
8767 : we're truncating or extending. */
8768 28573573 : if (CONST_POLY_INT_P (op))
8769 : {
8770 : poly_wide_int val
8771 : = poly_wide_int::from (const_poly_int_value (op),
8772 : GET_MODE_PRECISION (int_outermode),
8773 : SIGNED);
8774 : return immed_wide_int_const (val, int_outermode);
8775 : }
8776 :
8777 28573573 : if (GET_MODE_PRECISION (int_outermode)
8778 28573573 : < GET_MODE_PRECISION (int_innermode))
8779 : {
8780 16410851 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8781 16410851 : if (tem)
8782 : return tem;
8783 : }
8784 : }
8785 :
8786 : /* If the outer mode is not integral, try taking a subreg with the equivalent
8787 : integer outer mode and then bitcasting the result.
8788 : Other simplifications rely on integer to integer subregs and we'd
8789 : potentially miss out on optimizations otherwise. */
8790 75548106 : if (known_gt (GET_MODE_SIZE (innermode),
8791 : GET_MODE_SIZE (outermode))
8792 18819387 : && SCALAR_INT_MODE_P (innermode)
8793 17662652 : && !SCALAR_INT_MODE_P (outermode)
8794 56769550 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8795 88055 : 0).exists (&int_outermode))
8796 : {
8797 88055 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8798 88055 : if (tem)
8799 1984 : return lowpart_subreg (outermode, tem, int_outermode);
8800 : }
8801 :
8802 : /* If OP is a vector comparison and the subreg is not changing the
8803 : number of elements or the size of the elements, change the result
8804 : of the comparison to the new mode. */
8805 37772069 : if (COMPARISON_P (op)
8806 272234 : && VECTOR_MODE_P (outermode)
8807 199143 : && VECTOR_MODE_P (innermode)
8808 597405 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8809 38143343 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8810 : GET_MODE_UNIT_SIZE (innermode)))
8811 123414 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8812 123414 : XEXP (op, 0), XEXP (op, 1));
8813 :
8814 : /* Distribute non-paradoxical subregs through logic ops in cases where
8815 : one term disappears.
8816 :
8817 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8818 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8819 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8820 :
8821 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8822 :
8823 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8824 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8825 :
8826 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8827 37648655 : if (known_ge (innersize, outersize)
8828 24995136 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8829 22938411 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8830 39171078 : && CONSTANT_P (XEXP (op, 1)))
8831 : {
8832 732575 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8833 732575 : if (op1_subreg == CONSTM1_RTX (outermode))
8834 : {
8835 115110 : if (GET_CODE (op) == IOR)
8836 : return op1_subreg;
8837 114876 : rtx op0 = XEXP (op, 0);
8838 114876 : if (GET_CODE (op) == XOR)
8839 893 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8840 114876 : return simplify_gen_subreg (outermode, op0, innermode, byte);
8841 : }
8842 :
8843 617465 : if (op1_subreg == CONST0_RTX (outermode))
8844 12165 : return (GET_CODE (op) == AND
8845 12165 : ? op1_subreg
8846 7202 : : distribute_subreg (XEXP (op, 0)));
8847 : }
8848 :
8849 : return NULL_RTX;
8850 : }
8851 :
8852 : /* Make a SUBREG operation or equivalent if it folds. */
8853 :
8854 : rtx
8855 41950181 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
8856 : machine_mode innermode,
8857 : poly_uint64 byte)
8858 : {
8859 41950181 : rtx newx;
8860 :
8861 41950181 : newx = simplify_subreg (outermode, op, innermode, byte);
8862 41950181 : if (newx)
8863 : return newx;
8864 :
8865 19491783 : if (GET_CODE (op) == SUBREG
8866 19491783 : || GET_CODE (op) == CONCAT
8867 19457121 : || CONST_SCALAR_INT_P (op)
8868 19457095 : || CONST_DOUBLE_AS_FLOAT_P (op)
8869 19457095 : || CONST_FIXED_P (op)
8870 19457095 : || GET_CODE (op) == CONST_VECTOR)
8871 : return NULL_RTX;
8872 :
8873 19457085 : if (validate_subreg (outermode, innermode, op, byte))
8874 19425859 : return gen_rtx_SUBREG (outermode, op, byte);
8875 :
8876 : return NULL_RTX;
8877 : }
8878 :
8879 : /* Generates a subreg to get the least significant part of EXPR (in mode
8880 : INNER_MODE) to OUTER_MODE. */
8881 :
8882 : rtx
8883 31033223 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
8884 : machine_mode inner_mode)
8885 : {
8886 31033223 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
8887 31033223 : subreg_lowpart_offset (outer_mode, inner_mode));
8888 : }
8889 :
8890 : /* Generate RTX to select element at INDEX out of vector OP. */
8891 :
8892 : rtx
8893 639728 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
8894 : {
8895 639728 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
8896 :
8897 639728 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
8898 :
8899 1279456 : if (known_eq (index * GET_MODE_SIZE (imode),
8900 : subreg_lowpart_offset (imode, GET_MODE (op))))
8901 : {
8902 639578 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
8903 639578 : if (res)
8904 : return res;
8905 : }
8906 :
8907 472 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
8908 472 : return gen_rtx_VEC_SELECT (imode, op, tmp);
8909 : }
8910 :
8911 :
8912 : /* Simplify X, an rtx expression.
8913 :
8914 : Return the simplified expression or NULL if no simplifications
8915 : were possible.
8916 :
8917 : This is the preferred entry point into the simplification routines;
8918 : however, we still allow passes to call the more specific routines.
8919 :
8920 : Right now GCC has three (yes, three) major bodies of RTL simplification
8921 : code that need to be unified.
8922 :
8923 : 1. fold_rtx in cse.cc. This code uses various CSE specific
8924 : information to aid in RTL simplification.
8925 :
8926 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
8927 : it uses combine specific information to aid in RTL
8928 : simplification.
8929 :
8930 : 3. The routines in this file.
8931 :
8932 :
8933 : Long term we want to only have one body of simplification code; to
8934 : get to that state I recommend the following steps:
8935 :
8936 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
8937 : which are not pass dependent state into these routines.
8938 :
8939 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
8940 : use this routine whenever possible.
8941 :
8942 : 3. Allow for pass dependent state to be provided to these
8943 : routines and add simplifications based on the pass dependent
8944 : state. Remove code from cse.cc & combine.cc that becomes
8945 : redundant/dead.
8946 :
8947 : It will take time, but ultimately the compiler will be easier to
8948 : maintain and improve. It's totally silly that when we add a
8949 : simplification that it needs to be added to 4 places (3 for RTL
8950 : simplification and 1 for tree simplification. */
8951 :
8952 : rtx
8953 46104824 : simplify_rtx (const_rtx x)
8954 : {
8955 46104824 : const enum rtx_code code = GET_CODE (x);
8956 46104824 : const machine_mode mode = GET_MODE (x);
8957 :
8958 46104824 : switch (GET_RTX_CLASS (code))
8959 : {
8960 876289 : case RTX_UNARY:
8961 1752578 : return simplify_unary_operation (code, mode,
8962 876289 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
8963 26681972 : case RTX_COMM_ARITH:
8964 26681972 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
8965 538232 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
8966 :
8967 : /* Fall through. */
8968 :
8969 32103242 : case RTX_BIN_ARITH:
8970 32103242 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
8971 :
8972 68924 : case RTX_TERNARY:
8973 68924 : case RTX_BITFIELD_OPS:
8974 68924 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
8975 68924 : XEXP (x, 0), XEXP (x, 1),
8976 68924 : XEXP (x, 2));
8977 :
8978 176045 : case RTX_COMPARE:
8979 176045 : case RTX_COMM_COMPARE:
8980 176045 : return simplify_relational_operation (code, mode,
8981 176045 : ((GET_MODE (XEXP (x, 0))
8982 : != VOIDmode)
8983 : ? GET_MODE (XEXP (x, 0))
8984 279 : : GET_MODE (XEXP (x, 1))),
8985 176045 : XEXP (x, 0),
8986 352090 : XEXP (x, 1));
8987 :
8988 230894 : case RTX_EXTRA:
8989 230894 : if (code == SUBREG)
8990 2447 : return simplify_subreg (mode, SUBREG_REG (x),
8991 2447 : GET_MODE (SUBREG_REG (x)),
8992 2447 : SUBREG_BYTE (x));
8993 : break;
8994 :
8995 6413396 : case RTX_OBJ:
8996 6413396 : if (code == LO_SUM)
8997 : {
8998 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
8999 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
9000 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
9001 0 : return XEXP (x, 1);
9002 : }
9003 : break;
9004 :
9005 : default:
9006 : break;
9007 : }
9008 : return NULL;
9009 : }
9010 :
9011 : #if CHECKING_P
9012 :
9013 : namespace selftest {
9014 :
9015 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
9016 :
9017 : static rtx
9018 2672 : make_test_reg (machine_mode mode)
9019 : {
9020 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
9021 :
9022 2672 : return gen_rtx_REG (mode, test_reg_num++);
9023 : }
9024 :
9025 : static void
9026 40 : test_scalar_int_ops (machine_mode mode)
9027 : {
9028 40 : rtx op0 = make_test_reg (mode);
9029 40 : rtx op1 = make_test_reg (mode);
9030 40 : rtx six = GEN_INT (6);
9031 :
9032 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
9033 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
9034 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
9035 :
9036 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
9037 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
9038 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
9039 :
9040 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
9041 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
9042 :
9043 : /* Test some binary identities. */
9044 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
9045 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
9046 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
9047 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
9048 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
9049 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
9050 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
9051 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
9052 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
9053 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
9054 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
9055 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
9056 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
9057 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
9058 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
9059 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
9060 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
9061 :
9062 : /* Test some self-inverse operations. */
9063 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
9064 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
9065 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
9066 :
9067 : /* Test some reflexive operations. */
9068 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
9069 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
9070 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
9071 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
9072 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
9073 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
9074 :
9075 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
9076 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
9077 :
9078 : /* Test simplify_distributive_operation. */
9079 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
9080 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
9081 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
9082 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
9083 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
9084 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
9085 :
9086 : /* Test useless extensions are eliminated. */
9087 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
9088 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
9089 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
9090 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
9091 40 : }
9092 :
9093 : /* Verify some simplifications of integer extension/truncation.
9094 : Machine mode BMODE is the guaranteed wider than SMODE. */
9095 :
9096 : static void
9097 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
9098 : {
9099 24 : rtx sreg = make_test_reg (smode);
9100 :
9101 : /* Check truncation of extension. */
9102 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9103 : simplify_gen_unary (ZERO_EXTEND, bmode,
9104 : sreg, smode),
9105 : bmode),
9106 : sreg);
9107 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9108 : simplify_gen_unary (SIGN_EXTEND, bmode,
9109 : sreg, smode),
9110 : bmode),
9111 : sreg);
9112 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9113 : lowpart_subreg (bmode, sreg, smode),
9114 : bmode),
9115 : sreg);
9116 :
9117 : /* Test extensions, followed by logic ops, followed by truncations. */
9118 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9119 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9120 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9121 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9122 : simplify_gen_binary (AND, bmode,
9123 : bsubreg, smask),
9124 : bmode),
9125 : sreg);
9126 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9127 : simplify_gen_binary (AND, bmode,
9128 : bsubreg, inv_smask),
9129 : bmode),
9130 : const0_rtx);
9131 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9132 : simplify_gen_binary (IOR, bmode,
9133 : bsubreg, smask),
9134 : bmode),
9135 : constm1_rtx);
9136 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9137 : simplify_gen_binary (IOR, bmode,
9138 : bsubreg, inv_smask),
9139 : bmode),
9140 : sreg);
9141 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9142 : simplify_gen_binary (XOR, bmode,
9143 : bsubreg, smask),
9144 : bmode),
9145 : lowpart_subreg (smode,
9146 : gen_rtx_NOT (bmode, bsubreg),
9147 : bmode));
9148 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9149 : simplify_gen_binary (XOR, bmode,
9150 : bsubreg, inv_smask),
9151 : bmode),
9152 : sreg);
9153 :
9154 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9155 : {
9156 24 : rtx breg1 = make_test_reg (bmode);
9157 24 : rtx breg2 = make_test_reg (bmode);
9158 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9159 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9160 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9161 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9162 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9163 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9164 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9165 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9166 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9167 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9168 : gen_rtx_NOT (bmode, breg1));
9169 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9170 : gen_rtx_AND (bmode, breg1, breg2));
9171 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9172 : gen_rtx_IOR (bmode, breg1, breg2));
9173 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9174 : gen_rtx_XOR (bmode, breg1, breg2));
9175 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9176 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9177 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9178 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9179 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9180 : gen_rtx_XOR (bmode,
9181 : gen_rtx_XOR (bmode, breg1, breg2),
9182 : const1_rtx));
9183 : }
9184 24 : }
9185 :
9186 : /* Verify more simplifications of integer extension/truncation.
9187 : BMODE is wider than MMODE which is wider than SMODE. */
9188 :
9189 : static void
9190 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9191 : machine_mode smode)
9192 : {
9193 16 : rtx breg = make_test_reg (bmode);
9194 16 : rtx mreg = make_test_reg (mmode);
9195 16 : rtx sreg = make_test_reg (smode);
9196 :
9197 : /* Check truncate of truncate. */
9198 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9199 : simplify_gen_unary (TRUNCATE, mmode,
9200 : breg, bmode),
9201 : mmode),
9202 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9203 :
9204 : /* Check extension of extension. */
9205 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9206 : simplify_gen_unary (ZERO_EXTEND, mmode,
9207 : sreg, smode),
9208 : mmode),
9209 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9210 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9211 : simplify_gen_unary (SIGN_EXTEND, mmode,
9212 : sreg, smode),
9213 : mmode),
9214 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9215 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9216 : simplify_gen_unary (ZERO_EXTEND, mmode,
9217 : sreg, smode),
9218 : mmode),
9219 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9220 :
9221 : /* Check truncation of extension. */
9222 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9223 : simplify_gen_unary (ZERO_EXTEND, bmode,
9224 : mreg, mmode),
9225 : bmode),
9226 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9227 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9228 : simplify_gen_unary (SIGN_EXTEND, bmode,
9229 : mreg, mmode),
9230 : bmode),
9231 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9232 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9233 : lowpart_subreg (bmode, mreg, mmode),
9234 : bmode),
9235 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9236 16 : }
9237 :
9238 : /* Test comparisons of comparisons, with the inner comparisons being
9239 : between values of mode MODE2 and producing results of mode MODE1,
9240 : and with the outer comparisons producing results of mode MODE0. */
9241 :
9242 : static void
9243 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9244 : {
9245 4 : rtx reg0 = make_test_reg (mode2);
9246 4 : rtx reg1 = make_test_reg (mode2);
9247 :
9248 4 : static const rtx_code codes[] = {
9249 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9250 : };
9251 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9252 4 : rtx cmps[num_codes];
9253 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9254 :
9255 44 : for (unsigned int i = 0; i < num_codes; ++i)
9256 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9257 :
9258 44 : for (auto code : codes)
9259 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9260 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9261 : {
9262 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9263 : cmps[i0], cmps[i1]);
9264 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9265 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9266 : else
9267 : {
9268 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9269 : && (CONSTANT_P (cmp_res)
9270 : || (COMPARISON_P (cmp_res)
9271 : && GET_MODE (cmp_res) == mode0
9272 : && REG_P (XEXP (cmp_res, 0))
9273 : && REG_P (XEXP (cmp_res, 1)))));
9274 10880 : for (rtx reg0_val : vals)
9275 32640 : for (rtx reg1_val : vals)
9276 : {
9277 24480 : rtx val0 = simplify_const_relational_operation
9278 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9279 24480 : rtx val1 = simplify_const_relational_operation
9280 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9281 24480 : rtx val = simplify_const_relational_operation
9282 24480 : (code, mode0, val0, val1);
9283 24480 : rtx folded = cmp_res;
9284 24480 : if (COMPARISON_P (cmp_res))
9285 16704 : folded = simplify_const_relational_operation
9286 16704 : (GET_CODE (cmp_res), mode0,
9287 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9288 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9289 24480 : ASSERT_RTX_EQ (val, folded);
9290 : }
9291 : }
9292 : }
9293 4 : }
9294 :
9295 :
9296 : /* Verify some simplifications involving scalar expressions. */
9297 :
9298 : static void
9299 4 : test_scalar_ops ()
9300 : {
9301 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9302 : {
9303 496 : machine_mode mode = (machine_mode) i;
9304 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9305 40 : test_scalar_int_ops (mode);
9306 : }
9307 :
9308 4 : test_scalar_int_ext_ops (HImode, QImode);
9309 4 : test_scalar_int_ext_ops (SImode, QImode);
9310 4 : test_scalar_int_ext_ops (SImode, HImode);
9311 4 : test_scalar_int_ext_ops (DImode, QImode);
9312 4 : test_scalar_int_ext_ops (DImode, HImode);
9313 4 : test_scalar_int_ext_ops (DImode, SImode);
9314 :
9315 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9316 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9317 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9318 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9319 :
9320 4 : test_comparisons (QImode, HImode, SImode);
9321 4 : }
9322 :
9323 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9324 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9325 : register that holds one element of MODE. */
9326 :
9327 : static void
9328 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9329 : {
9330 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9331 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9332 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9333 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9334 : {
9335 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9336 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9337 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9338 124 : ASSERT_RTX_EQ (duplicate,
9339 : simplify_unary_operation (NOT, mode,
9340 : duplicate_not, mode));
9341 :
9342 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9343 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9344 124 : ASSERT_RTX_EQ (duplicate,
9345 : simplify_unary_operation (NEG, mode,
9346 : duplicate_neg, mode));
9347 :
9348 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9349 124 : ASSERT_RTX_EQ (duplicate,
9350 : simplify_binary_operation (PLUS, mode, duplicate,
9351 : CONST0_RTX (mode)));
9352 :
9353 124 : ASSERT_RTX_EQ (duplicate,
9354 : simplify_binary_operation (MINUS, mode, duplicate,
9355 : CONST0_RTX (mode)));
9356 :
9357 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9358 : simplify_binary_operation (MINUS, mode, duplicate,
9359 : duplicate));
9360 : }
9361 :
9362 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9363 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9364 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9365 : simplify_binary_operation (VEC_SELECT, inner_mode,
9366 : duplicate, zero_par));
9367 :
9368 224 : unsigned HOST_WIDE_INT const_nunits;
9369 224 : if (nunits.is_constant (&const_nunits))
9370 : {
9371 : /* And again with the final element. */
9372 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9373 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9374 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9375 : simplify_binary_operation (VEC_SELECT, inner_mode,
9376 : duplicate, last_par));
9377 :
9378 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9379 : /* Skip this test for vectors of booleans, because offset is in bytes,
9380 : while vec_merge indices are in elements (usually bits). */
9381 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9382 : {
9383 224 : rtx vector_reg = make_test_reg (mode);
9384 3508 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9385 : {
9386 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9387 : break;
9388 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9389 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9390 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9391 :
9392 3284 : ASSERT_RTX_EQ (scalar_reg,
9393 : simplify_gen_subreg (inner_mode, vm,
9394 : mode, offset));
9395 : }
9396 : }
9397 : }
9398 :
9399 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9400 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9401 224 : ASSERT_RTX_EQ (scalar_reg,
9402 : simplify_gen_subreg (inner_mode, duplicate,
9403 : mode, offset));
9404 :
9405 224 : machine_mode narrower_mode;
9406 224 : if (maybe_ne (nunits, 2U)
9407 184 : && multiple_p (nunits, 2)
9408 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9409 396 : && VECTOR_MODE_P (narrower_mode))
9410 : {
9411 : /* Test VEC_DUPLICATE of a vector. */
9412 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9413 172 : nbuilder.quick_push (const0_rtx);
9414 172 : nbuilder.quick_push (const1_rtx);
9415 172 : rtx_vector_builder builder (mode, 2, 1);
9416 172 : builder.quick_push (const0_rtx);
9417 172 : builder.quick_push (const1_rtx);
9418 172 : ASSERT_RTX_EQ (builder.build (),
9419 : simplify_unary_operation (VEC_DUPLICATE, mode,
9420 : nbuilder.build (),
9421 : narrower_mode));
9422 :
9423 : /* Test VEC_SELECT of a vector. */
9424 172 : rtx vec_par
9425 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9426 172 : rtx narrower_duplicate
9427 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9428 172 : ASSERT_RTX_EQ (narrower_duplicate,
9429 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9430 : duplicate, vec_par));
9431 :
9432 : /* Test a vector subreg of a VEC_DUPLICATE. */
9433 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9434 172 : ASSERT_RTX_EQ (narrower_duplicate,
9435 : simplify_gen_subreg (narrower_mode, duplicate,
9436 : mode, offset));
9437 172 : }
9438 224 : }
9439 :
9440 : /* Test vector simplifications involving VEC_SERIES in which the
9441 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9442 : register that holds one element of MODE. */
9443 :
9444 : static void
9445 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9446 : {
9447 : /* Test unary cases with VEC_SERIES arguments. */
9448 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9449 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9450 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9451 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9452 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9453 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9454 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9455 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9456 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9457 : neg_scalar_reg);
9458 92 : ASSERT_RTX_EQ (series_0_r,
9459 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9460 92 : ASSERT_RTX_EQ (series_r_m1,
9461 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9462 92 : ASSERT_RTX_EQ (series_r_r,
9463 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9464 :
9465 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9466 92 : ASSERT_RTX_EQ (duplicate,
9467 : simplify_binary_operation (VEC_SERIES, mode,
9468 : scalar_reg, const0_rtx));
9469 :
9470 : /* Test PLUS and MINUS with VEC_SERIES. */
9471 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9472 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9473 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9474 92 : ASSERT_RTX_EQ (series_r_r,
9475 : simplify_binary_operation (PLUS, mode, series_0_r,
9476 : duplicate));
9477 92 : ASSERT_RTX_EQ (series_r_1,
9478 : simplify_binary_operation (PLUS, mode, duplicate,
9479 : series_0_1));
9480 92 : ASSERT_RTX_EQ (series_r_m1,
9481 : simplify_binary_operation (PLUS, mode, duplicate,
9482 : series_0_m1));
9483 92 : ASSERT_RTX_EQ (series_0_r,
9484 : simplify_binary_operation (MINUS, mode, series_r_r,
9485 : duplicate));
9486 92 : ASSERT_RTX_EQ (series_r_m1,
9487 : simplify_binary_operation (MINUS, mode, duplicate,
9488 : series_0_1));
9489 92 : ASSERT_RTX_EQ (series_r_1,
9490 : simplify_binary_operation (MINUS, mode, duplicate,
9491 : series_0_m1));
9492 92 : ASSERT_RTX_EQ (series_0_m1,
9493 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9494 : constm1_rtx));
9495 :
9496 : /* Test NEG on constant vector series. */
9497 92 : ASSERT_RTX_EQ (series_0_m1,
9498 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9499 92 : ASSERT_RTX_EQ (series_0_1,
9500 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9501 :
9502 : /* Test PLUS and MINUS on constant vector series. */
9503 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9504 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9505 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9506 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9507 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9508 92 : ASSERT_RTX_EQ (series_1_1,
9509 : simplify_binary_operation (PLUS, mode, series_0_1,
9510 : CONST1_RTX (mode)));
9511 92 : ASSERT_RTX_EQ (series_0_m1,
9512 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9513 : series_0_m1));
9514 92 : ASSERT_RTX_EQ (series_1_3,
9515 : simplify_binary_operation (PLUS, mode, series_1_1,
9516 : series_0_2));
9517 92 : ASSERT_RTX_EQ (series_0_1,
9518 : simplify_binary_operation (MINUS, mode, series_1_1,
9519 : CONST1_RTX (mode)));
9520 92 : ASSERT_RTX_EQ (series_1_1,
9521 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9522 : series_0_m1));
9523 92 : ASSERT_RTX_EQ (series_1_1,
9524 : simplify_binary_operation (MINUS, mode, series_1_3,
9525 : series_0_2));
9526 :
9527 : /* Test MULT between constant vectors. */
9528 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9529 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9530 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9531 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9532 92 : ASSERT_RTX_EQ (series_0_2,
9533 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9534 92 : ASSERT_RTX_EQ (series_3_9,
9535 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9536 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9537 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9538 : series_0_1));
9539 :
9540 : /* Test ASHIFT between constant vectors. */
9541 92 : ASSERT_RTX_EQ (series_0_2,
9542 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9543 : CONST1_RTX (mode)));
9544 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9545 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9546 : series_0_1));
9547 92 : }
9548 :
9549 : static rtx
9550 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9551 : {
9552 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9553 : }
9554 :
9555 : /* Verify simplify_merge_mask works correctly. */
9556 :
9557 : static void
9558 224 : test_vec_merge (machine_mode mode)
9559 : {
9560 224 : rtx op0 = make_test_reg (mode);
9561 224 : rtx op1 = make_test_reg (mode);
9562 224 : rtx op2 = make_test_reg (mode);
9563 224 : rtx op3 = make_test_reg (mode);
9564 224 : rtx op4 = make_test_reg (mode);
9565 224 : rtx op5 = make_test_reg (mode);
9566 224 : rtx mask1 = make_test_reg (SImode);
9567 224 : rtx mask2 = make_test_reg (SImode);
9568 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9569 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9570 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9571 :
9572 : /* Simple vec_merge. */
9573 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9574 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9575 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9576 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9577 :
9578 : /* Nested vec_merge.
9579 : It's tempting to make this simplify right down to opN, but we don't
9580 : because all the simplify_* functions assume that the operands have
9581 : already been simplified. */
9582 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9583 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9584 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9585 :
9586 : /* Intermediate unary op. */
9587 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9588 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9589 : simplify_merge_mask (unop, mask1, 0));
9590 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9591 : simplify_merge_mask (unop, mask1, 1));
9592 :
9593 : /* Intermediate binary op. */
9594 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9595 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9596 : simplify_merge_mask (binop, mask1, 0));
9597 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9598 : simplify_merge_mask (binop, mask1, 1));
9599 :
9600 : /* Intermediate ternary op. */
9601 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9602 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9603 : simplify_merge_mask (tenop, mask1, 0));
9604 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9605 : simplify_merge_mask (tenop, mask1, 1));
9606 :
9607 : /* Side effects. */
9608 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9609 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9610 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9611 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9612 :
9613 : /* Called indirectly. */
9614 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9615 : simplify_rtx (nvm));
9616 224 : }
9617 :
9618 : /* Test that vector rotate formation works at RTL level. Try various
9619 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9620 :
9621 : static void
9622 92 : test_vector_rotate (rtx reg)
9623 : {
9624 92 : machine_mode mode = GET_MODE (reg);
9625 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9626 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9627 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9628 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9629 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9630 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9631 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9632 92 : ASSERT_RTX_EQ (rotate_rtx,
9633 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9634 92 : ASSERT_RTX_EQ (rotate_rtx,
9635 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9636 92 : ASSERT_RTX_EQ (rotate_rtx,
9637 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9638 :
9639 : /* Don't go through every possible rotate amount to save execution time.
9640 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9641 : other bswap operations sometimes. Go through just the odd amounts. */
9642 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9643 : {
9644 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9645 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9646 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9647 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9648 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9649 1288 : ASSERT_RTX_EQ (rotate_rtx,
9650 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9651 1288 : ASSERT_RTX_EQ (rotate_rtx,
9652 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9653 1288 : ASSERT_RTX_EQ (rotate_rtx,
9654 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9655 : }
9656 92 : }
9657 :
9658 : /* Test subregs of integer vector constant X, trying elements in
9659 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9660 : where NELTS is the number of elements in X. Subregs involving
9661 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9662 :
9663 : static void
9664 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9665 : unsigned int first_valid = 0)
9666 : {
9667 276 : machine_mode inner_mode = GET_MODE (x);
9668 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9669 :
9670 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9671 : {
9672 34224 : machine_mode outer_mode = (machine_mode) modei;
9673 34224 : if (!VECTOR_MODE_P (outer_mode))
9674 18768 : continue;
9675 :
9676 15456 : unsigned int outer_nunits;
9677 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9678 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9679 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9680 : {
9681 : /* Test subregs in which the outer mode is a smaller,
9682 : constant-sized vector of the same element type. */
9683 1092 : unsigned int limit
9684 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9685 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9686 : {
9687 6936 : rtx expected = NULL_RTX;
9688 6936 : if (elt >= first_valid)
9689 : {
9690 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9691 39768 : for (unsigned int i = 0; i < outer_nunits; ++i)
9692 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9693 6936 : expected = builder.build ();
9694 6936 : }
9695 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9696 6936 : ASSERT_RTX_EQ (expected,
9697 : simplify_subreg (outer_mode, x,
9698 : inner_mode, byte));
9699 : }
9700 : }
9701 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9702 : GET_MODE_SIZE (inner_mode))
9703 2040 : && known_eq (elt_bias, 0U)
9704 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9705 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9706 : GET_MODE_NUNITS (outer_mode)))
9707 2040 : && (!FLOAT_MODE_P (outer_mode)
9708 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9709 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9710 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9711 : || !CONST_VECTOR_STEPPED_P (x)))
9712 : {
9713 : /* Try converting to OUTER_MODE and back. */
9714 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9715 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9716 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9717 : outer_mode, 0));
9718 : }
9719 : }
9720 :
9721 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9722 : {
9723 : /* Test each byte in the element range. */
9724 276 : unsigned int limit
9725 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9726 14604 : for (unsigned int i = 0; i < limit; ++i)
9727 : {
9728 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9729 14328 : rtx expected = NULL_RTX;
9730 14328 : if (elt >= first_valid)
9731 : {
9732 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9733 14328 : if (BYTES_BIG_ENDIAN)
9734 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9735 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9736 14328 : wide_int shifted_elt
9737 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9738 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9739 14328 : }
9740 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9741 14328 : ASSERT_RTX_EQ (expected,
9742 : simplify_subreg (QImode, x, inner_mode, byte));
9743 : }
9744 : }
9745 276 : }
9746 :
9747 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9748 : element per pattern. */
9749 :
9750 : static void
9751 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9752 : {
9753 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9754 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9755 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9756 92 : unsigned int count = gcd (min_nunits, 8);
9757 :
9758 92 : rtx_vector_builder builder (inner_mode, count, 1);
9759 684 : for (unsigned int i = 0; i < count; ++i)
9760 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9761 92 : rtx x = builder.build ();
9762 :
9763 92 : test_vector_subregs_modes (x);
9764 92 : if (!nunits.is_constant ())
9765 : test_vector_subregs_modes (x, nunits - min_nunits);
9766 92 : }
9767 :
9768 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9769 : elements per pattern. */
9770 :
9771 : static void
9772 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9773 : {
9774 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9775 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9776 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9777 92 : unsigned int count = gcd (min_nunits, 4);
9778 :
9779 92 : rtx_vector_builder builder (inner_mode, count, 2);
9780 444 : for (unsigned int i = 0; i < count; ++i)
9781 352 : builder.quick_push (gen_int_mode (i, int_mode));
9782 444 : for (unsigned int i = 0; i < count; ++i)
9783 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9784 92 : rtx x = builder.build ();
9785 :
9786 92 : test_vector_subregs_modes (x);
9787 92 : if (!nunits.is_constant ())
9788 : test_vector_subregs_modes (x, nunits - min_nunits, count);
9789 92 : }
9790 :
9791 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9792 : elements per pattern. */
9793 :
9794 : static void
9795 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9796 : {
9797 : /* Build { 0, 1, 2, 3, ... }. */
9798 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9799 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9800 368 : for (unsigned int i = 0; i < 3; ++i)
9801 276 : builder.quick_push (gen_int_mode (i, int_mode));
9802 92 : rtx x = builder.build ();
9803 :
9804 92 : test_vector_subregs_modes (x);
9805 92 : }
9806 :
9807 : /* Test constant subregs of integer vector mode INNER_MODE. */
9808 :
9809 : static void
9810 92 : test_vector_subregs (machine_mode inner_mode)
9811 : {
9812 92 : test_vector_subregs_repeating (inner_mode);
9813 92 : test_vector_subregs_fore_back (inner_mode);
9814 92 : test_vector_subregs_stepped (inner_mode);
9815 92 : }
9816 :
9817 : /* Verify some simplifications involving vectors. */
9818 :
9819 : static void
9820 4 : test_vector_ops ()
9821 : {
9822 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9823 : {
9824 496 : machine_mode mode = (machine_mode) i;
9825 496 : if (VECTOR_MODE_P (mode))
9826 : {
9827 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9828 224 : test_vector_ops_duplicate (mode, scalar_reg);
9829 224 : rtx vector_reg = make_test_reg (mode);
9830 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9831 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9832 : {
9833 92 : test_vector_ops_series (mode, scalar_reg);
9834 92 : test_vector_subregs (mode);
9835 92 : test_vector_rotate (vector_reg);
9836 : }
9837 224 : test_vec_merge (mode);
9838 : }
9839 : }
9840 4 : }
9841 :
9842 : template<unsigned int N>
9843 : struct simplify_const_poly_int_tests
9844 : {
9845 : static void run ();
9846 : };
9847 :
9848 : template<>
9849 : struct simplify_const_poly_int_tests<1>
9850 : {
9851 : static void run () {}
9852 : };
9853 :
9854 : /* Test various CONST_POLY_INT properties. */
9855 :
9856 : template<unsigned int N>
9857 : void
9858 : simplify_const_poly_int_tests<N>::run ()
9859 : {
9860 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
9861 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
9862 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
9863 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
9864 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
9865 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
9866 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
9867 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
9868 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
9869 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
9870 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
9871 : rtx two = GEN_INT (2);
9872 : rtx six = GEN_INT (6);
9873 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
9874 :
9875 : /* These tests only try limited operation combinations. Fuller arithmetic
9876 : testing is done directly on poly_ints. */
9877 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
9878 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
9879 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
9880 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
9881 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
9882 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
9883 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
9884 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
9885 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
9886 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
9887 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
9888 : }
9889 :
9890 : /* Run all of the selftests within this file. */
9891 :
9892 : void
9893 4 : simplify_rtx_cc_tests ()
9894 : {
9895 4 : test_scalar_ops ();
9896 4 : test_vector_ops ();
9897 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
9898 4 : }
9899 :
9900 : } // namespace selftest
9901 :
9902 : #endif /* CHECKING_P */
|